From c33587d595e4c8d9bc5465dca1a693562dfc5a90 Mon Sep 17 00:00:00 2001
From: Ricardo Lafuente <r@manufacturaindependente.org>
Date: Jan 22 2024 11:21:45 +0000
Subject: [PATCH 1/17] Update pages translation file


---

diff --git a/website/i18n/en/pages.po b/website/i18n/en/pages.po
index 98049a8..611f796 100644
--- a/website/i18n/en/pages.po
+++ b/website/i18n/en/pages.po
@@ -3970,179 +3970,6 @@ msgid ""
 "countermeasures."
 msgstr ""
 
-#: ../content/pages/unit_tests.md:block 1 (paragraph)
-msgid "Title: Instructions on how to run unit tests"
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 2 (header)
-msgid "on Linux"
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 3 (ordered list)
-msgid "Install [NodeJS](https://nodejs.org)."
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 3 (ordered list)
-msgid "Install `jq` and another necessary tools (e.g. `sed`)."
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 3 (ordered list)
-msgid "Open Terminal."
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 3 (ordered list)
-msgid "Run `npm install`."
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 3 (ordered list)
-msgid "Run `npm test`."
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 4 (header)
-msgid "on Windows"
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 5 (ordered list)
-msgid ""
-"Convert EOL in the script *./start_unit_tests.sh* from Windows (CR LF) to "
-"Unix (LF) - you can use the tool `dos2unix` in WSL to convert CR LF to LF."
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 5 (ordered list)
-msgid ""
-"Follow the instructions for Linux. Install NodeJS and run the following "
-"commands in WSL."
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 6 (header)
-msgid "Developer documentation"
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 7 (header)
-msgid "The framework"
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 8 (paragraph)
-msgid ""
-"The test cases are based on top of Jasmine framework. `start_unit_tests.sh` "
-"preprocesses the files using shell commands. Use `bash` if in doubt. Patches"
-" for other shells might be accepted but will probably not be supported by "
-"the core team."
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 9 (header)
-msgid "Structure"
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 10 (paragraph)
-msgid ""
-"The test cases are stored in the `tests` directory. The file names typically"
-" mirror the tested files in the `common` webextension directory with the "
-"suffix `_tests.js`. Each file and its requirements needs to be registered in"
-" `config/global.json` file."
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 11 (paragraph)
-msgid "The configuration file stores for each test:"
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 13 (unordered list)
-msgid "`name` represents the tested file name (no `_tests.js` suffix)"
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 13 (unordered list)
-msgid ""
-"`remove_custom_namespace` modifies the source file to remove the IIFE to "
-"make its internals global. This is typically necessary to test wrappers that"
-" commonly create IIFE."
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 13 (unordered list)
-msgid ""
-"`let_to_var` allows transforming all let variables to var variables. This "
-"might be necessary to transform inner variables but might modify the "
-"behaviour. Set to `false` unless you have good reason for the modification."
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 13 (unordered list)
-msgid ""
-"`src_script_requirements` allows specifying dependencies of the file under "
-"test (the file used by the webextension)."
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 13 (unordered list)
-msgid ""
-"`test_script_requirements` allows specifying dependencies of the file with "
-"test cases (the file with the `_tests.js` suffix)."
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 13 (unordered list)
-msgid ""
-"`extra_exports` appends export line to the file under test and imports these"
-" objects to the file with the test cases."
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 13 (unordered list)
-msgid ""
-"`replace_in_src` allows replacing lines in the file under test with a "
-"different code, use with caution as this modifies the behaviour."
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 13 (unordered list)
-msgid ""
-"`inject_code_to_src` allows injecting additional code to the file under "
-"test. Currently only inserting to `begin` (first line) and `end` (last line)"
-" are supported."
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 14 (paragraph)
-msgid ""
-"Note that the preprocessor (`start_unit_tests.sh`) modifies the files under "
-"test and the file with test cases according to the instuctions in "
-"`global.json`. The files are temporarily stored in the `tmp` directory."
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 15 (header)
-msgid "Add new unit tests if a test set already exists"
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 16 (paragraph)
-msgid ""
-"If a test set already exists for the target modul (e.g. a test set "
-"*background_tests.js* for the *background.js* file), you can add your own "
-"tests to the test script (e.g. to the *background_tests.js* file)."
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 17 (paragraph)
-msgid ""
-"You may need to update the requirements in the global configuration "
-"(*./config/global.json* file). Open the global configuration file for "
-"editing and find the configuration of the target script (according to the "
-"`name` property). Add the necessary requirements to the "
-"`src_script_requirements` and `test_script_requirements` sections."
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 18 (header)
-msgid "Add new unit tests if a test set does not already exists"
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 19 (paragraph)
-msgid ""
-"If a test set does not already exists for the target modul (e.g. a test set "
-"*background_tests.js* for the *background.js* file), create new file (e.g. "
-"*background_tests.js* file) in the *./tests* directory. It is recommended to"
-" create a new test script by copying any existing test script, deleting its "
-"tests, and creating new ones."
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 20 (paragraph)
-msgid ""
-"When a new test script is created, add a new entry to the global "
-"configuration (*./config/global.json* file). The new entry must be created "
-"according to the example (*./config/global-example.json* file) and schema "
-"(*./config/global-schema.json* file)."
-msgstr ""
-
 #: ../content/pages/versions.md:block 1 (header)
 msgid "title: Release history"
 msgstr ""
@@ -5555,3 +5382,176 @@ msgstr ""
 #: ../content/pages/versions.md:block 101 (unordered list)
 msgid "Initial public version"
 msgstr ""
+
+#: ../content/pages/unit_tests.md:block 1 (paragraph)
+msgid "Title: Instructions on how to run unit tests"
+msgstr ""
+
+#: ../content/pages/unit_tests.md:block 2 (header)
+msgid "on Linux"
+msgstr ""
+
+#: ../content/pages/unit_tests.md:block 3 (ordered list)
+msgid "Install [NodeJS](https://nodejs.org)."
+msgstr ""
+
+#: ../content/pages/unit_tests.md:block 3 (ordered list)
+msgid "Install `jq` and another necessary tools (e.g. `sed`)."
+msgstr ""
+
+#: ../content/pages/unit_tests.md:block 3 (ordered list)
+msgid "Open Terminal."
+msgstr ""
+
+#: ../content/pages/unit_tests.md:block 3 (ordered list)
+msgid "Run `npm install`."
+msgstr ""
+
+#: ../content/pages/unit_tests.md:block 3 (ordered list)
+msgid "Run `npm test`."
+msgstr ""
+
+#: ../content/pages/unit_tests.md:block 4 (header)
+msgid "on Windows"
+msgstr ""
+
+#: ../content/pages/unit_tests.md:block 5 (ordered list)
+msgid ""
+"Convert EOL in the script *./start_unit_tests.sh* from Windows (CR LF) to "
+"Unix (LF) - you can use the tool `dos2unix` in WSL to convert CR LF to LF."
+msgstr ""
+
+#: ../content/pages/unit_tests.md:block 5 (ordered list)
+msgid ""
+"Follow the instructions for Linux. Install NodeJS and run the following "
+"commands in WSL."
+msgstr ""
+
+#: ../content/pages/unit_tests.md:block 6 (header)
+msgid "Developer documentation"
+msgstr ""
+
+#: ../content/pages/unit_tests.md:block 7 (header)
+msgid "The framework"
+msgstr ""
+
+#: ../content/pages/unit_tests.md:block 8 (paragraph)
+msgid ""
+"The test cases are based on top of Jasmine framework. `start_unit_tests.sh` "
+"preprocesses the files using shell commands. Use `bash` if in doubt. Patches"
+" for other shells might be accepted but will probably not be supported by "
+"the core team."
+msgstr ""
+
+#: ../content/pages/unit_tests.md:block 9 (header)
+msgid "Structure"
+msgstr ""
+
+#: ../content/pages/unit_tests.md:block 10 (paragraph)
+msgid ""
+"The test cases are stored in the `tests` directory. The file names typically"
+" mirror the tested files in the `common` webextension directory with the "
+"suffix `_tests.js`. Each file and its requirements needs to be registered in"
+" `config/global.json` file."
+msgstr ""
+
+#: ../content/pages/unit_tests.md:block 11 (paragraph)
+msgid "The configuration file stores for each test:"
+msgstr ""
+
+#: ../content/pages/unit_tests.md:block 13 (unordered list)
+msgid "`name` represents the tested file name (no `_tests.js` suffix)"
+msgstr ""
+
+#: ../content/pages/unit_tests.md:block 13 (unordered list)
+msgid ""
+"`remove_custom_namespace` modifies the source file to remove the IIFE to "
+"make its internals global. This is typically necessary to test wrappers that"
+" commonly create IIFE."
+msgstr ""
+
+#: ../content/pages/unit_tests.md:block 13 (unordered list)
+msgid ""
+"`let_to_var` allows transforming all let variables to var variables. This "
+"might be necessary to transform inner variables but might modify the "
+"behaviour. Set to `false` unless you have good reason for the modification."
+msgstr ""
+
+#: ../content/pages/unit_tests.md:block 13 (unordered list)
+msgid ""
+"`src_script_requirements` allows specifying dependencies of the file under "
+"test (the file used by the webextension)."
+msgstr ""
+
+#: ../content/pages/unit_tests.md:block 13 (unordered list)
+msgid ""
+"`test_script_requirements` allows specifying dependencies of the file with "
+"test cases (the file with the `_tests.js` suffix)."
+msgstr ""
+
+#: ../content/pages/unit_tests.md:block 13 (unordered list)
+msgid ""
+"`extra_exports` appends export line to the file under test and imports these"
+" objects to the file with the test cases."
+msgstr ""
+
+#: ../content/pages/unit_tests.md:block 13 (unordered list)
+msgid ""
+"`replace_in_src` allows replacing lines in the file under test with a "
+"different code, use with caution as this modifies the behaviour."
+msgstr ""
+
+#: ../content/pages/unit_tests.md:block 13 (unordered list)
+msgid ""
+"`inject_code_to_src` allows injecting additional code to the file under "
+"test. Currently only inserting to `begin` (first line) and `end` (last line)"
+" are supported."
+msgstr ""
+
+#: ../content/pages/unit_tests.md:block 14 (paragraph)
+msgid ""
+"Note that the preprocessor (`start_unit_tests.sh`) modifies the files under "
+"test and the file with test cases according to the instuctions in "
+"`global.json`. The files are temporarily stored in the `tmp` directory."
+msgstr ""
+
+#: ../content/pages/unit_tests.md:block 15 (header)
+msgid "Add new unit tests if a test set already exists"
+msgstr ""
+
+#: ../content/pages/unit_tests.md:block 16 (paragraph)
+msgid ""
+"If a test set already exists for the target modul (e.g. a test set "
+"*background_tests.js* for the *background.js* file), you can add your own "
+"tests to the test script (e.g. to the *background_tests.js* file)."
+msgstr ""
+
+#: ../content/pages/unit_tests.md:block 17 (paragraph)
+msgid ""
+"You may need to update the requirements in the global configuration "
+"(*./config/global.json* file). Open the global configuration file for "
+"editing and find the configuration of the target script (according to the "
+"`name` property). Add the necessary requirements to the "
+"`src_script_requirements` and `test_script_requirements` sections."
+msgstr ""
+
+#: ../content/pages/unit_tests.md:block 18 (header)
+msgid "Add new unit tests if a test set does not already exists"
+msgstr ""
+
+#: ../content/pages/unit_tests.md:block 19 (paragraph)
+msgid ""
+"If a test set does not already exists for the target modul (e.g. a test set "
+"*background_tests.js* for the *background.js* file), create new file (e.g. "
+"*background_tests.js* file) in the *./tests* directory. It is recommended to"
+" create a new test script by copying any existing test script, deleting its "
+"tests, and creating new ones."
+msgstr ""
+
+#: ../content/pages/unit_tests.md:block 20 (paragraph)
+msgid ""
+"When a new test script is created, add a new entry to the global "
+"configuration (*./config/global.json* file). The new entry must be created "
+"according to the example (*./config/global-example.json* file) and schema "
+"(*./config/global-schema.json* file)."
+msgstr ""

From 3c0cd8c099211a066ffd9ec3b121c7aacacf8e65 Mon Sep 17 00:00:00 2001
From: Ricardo Lafuente <r@manufacturaindependente.org>
Date: Jan 22 2024 11:22:24 +0000
Subject: [PATCH 2/17] Merge branch 'main' into website-i18n


---

diff --git a/common/common.css b/common/common.css
index 32cfb74..2e764d0 100644
--- a/common/common.css
+++ b/common/common.css
@@ -13,7 +13,7 @@
 	--light-logo-contrast: #333333; /* Very dark grey */
 	--dark-logo: #e76f51; /* Logo dark red */
 	--dark-logo-contrast: white;
-	--help-icon-color: white;  
+	--help-icon-color: white;
 	--help-icon-background: blue;
 	--title-color: var(--dark-logo);
 	--good-news: darkgreen; /* Combine with background color */
@@ -22,6 +22,7 @@
 	--button-text-color: black;
 	--button-background-active-color: var(--light-logo);
 	--button-text-active-color: black;
+	--button-text-disabled-color: #888;
 	--button-background-hover-color: #c9c9c9; /* low dark grey */
 	--button-text-hover-color: black;
 	--menu-color: blue;
@@ -29,6 +30,7 @@
 	--attention-color: var(--dark-logo-contrast);
 	--attention-background: var(--dark-logo);
 	--slider-bg-color: white;
+	--slider-text-color: black;
 	--slider-off-color: gray;
 	--slider-on-color: var(--light-logo);
 	--slider-text-color: black;
@@ -39,7 +41,7 @@
 		--text-color: #e8e6e3; /* Almost white */
 		--background-color: #181a1b; /* Very very dark grey */
 		--background-color-input: var(--background-color);
-		--help-icon-color: blue;  
+		--help-icon-color: blue;
 		--help-icon-background: white;
 		--title-color: var(--light-logo);
 		--good-news: lightgreen;
@@ -72,7 +74,11 @@ button {
 	color: var(--button-text-color);
 }
 
-button:hover {
+button:disabled {
+	color: var(--button-text-disabled-color);
+}
+
+button:hover:not(:disabled) {
 	cursor: pointer;
 	background-color: var(--button-background-hover-color);
 	color: var(--button-text-hover-color);
@@ -181,7 +187,7 @@ a:hover, a:active {
 	background-color: var(--slider-bg-color);
 	-webkit-transition: .4s;
 	transition: .4s;
-	color: var(--off-color);
+	color: var(--slider-text-color);
 	content:"__MSG_ShieldOffSlider__";
 }
 
diff --git a/tests/integration_tests/testing/web_browser.py b/tests/integration_tests/testing/web_browser.py
index 7831b3b..0989f6c 100644
--- a/tests/integration_tests/testing/web_browser.py
+++ b/tests/integration_tests/testing/web_browser.py
@@ -96,15 +96,23 @@ class Browser:
                     self._jsr_options_page = elem.text.split(',')[2].split('=')[1][:-1] + "options.html"
         if self.type == BrowserType.CHROME:
             self.driver.get('chrome://system/')
-            WebDriverWait(self.driver, 10).until(
-                ec.presence_of_element_located((By.ID, 'expandAll'))
-            )
-            self.driver.find_element(By.ID, 'expandAll').click()
+            try:
+                WebDriverWait(self.driver, 2).until(
+                    ec.presence_of_element_located((By.ID, 'expandAll'))
+                )
+                self.driver.find_element(By.ID, 'expandAll').click()
+            except:
+                self.driver.find_elements(By.TAG_NAME, 'system-app')[0].shadow_root.find_elements(By.CSS_SELECTOR, 'button')[0].click()
             sleep(1)
             try:
                 extensions = self.driver.find_element(By.ID, 'div-extensions-value')
             except NoSuchElementException:
-                extensions = self.driver.find_element(By.ID, 'extensions-value')
+                try:
+                    extensions = self.driver.find_element(By.ID, 'extensions-value')
+                except NoSuchElementException:
+                    system_app = self.driver.find_elements(By.TAG_NAME, 'system-app')[0].shadow_root
+                    log_entry = system_app.find_elements(By.CSS_SELECTOR, 'log-entry')[5].shadow_root
+                    extensions = log_entry.find_elements(By.CLASS_NAME, 'stat-value')[0]
             for elem in extensions.text.splitlines():
                 if 'JShelter' in elem:
                     self._jsr_options_page = "chrome-extension://" + elem.split(':')[0][:-1] + "/options.html"

From bc2ad4f66f41c1713cb368a135a93e4a36395991 Mon Sep 17 00:00:00 2001
From: Ricardo Lafuente <r@manufacturaindependente.org>
Date: Jan 22 2024 15:30:24 +0000
Subject: [PATCH 3/17] Fix markup that was erroring everything


---

diff --git a/tests/unit_tests/README.md b/tests/unit_tests/README.md
index 2fe916e..95d3f5b 100644
--- a/tests/unit_tests/README.md
+++ b/tests/unit_tests/README.md
@@ -2,7 +2,7 @@ Title: Instructions on how to run unit tests
 
 #### on Linux
 
-1. Install NodeJS ([https://nodejs.org]()).
+1. Install [NodeJS](https://nodejs.org).
 2. Install `jq` and another necessary tools (e.g. `sed`).
 3. Open Terminal.
 4. Run `npm install`.

From edafbd73504505403bbe97aeb050f83610fb272b Mon Sep 17 00:00:00 2001
From: Ricardo Lafuente <r@manufacturaindependente.org>
Date: Jan 22 2024 15:30:47 +0000
Subject: [PATCH 4/17] Detect wrongly marked up frontmatter


---

diff --git a/website/i18n/postprocess.py b/website/i18n/postprocess.py
index e4cb856..6d232b4 100755
--- a/website/i18n/postprocess.py
+++ b/website/i18n/postprocess.py
@@ -20,6 +20,14 @@ for line in lines:
         break
     raw_frontmatter += line.strip() + ' '
 
+# remove header markup if present
+if raw_frontmatter.startswith('# '):
+    raw_frontmatter = raw_frontmatter.replace('# ', '', 1)
+if raw_frontmatter.startswith('## '):
+    raw_frontmatter = raw_frontmatter.replace('## ', '', 1)
+if raw_frontmatter.startswith('### '):
+    raw_frontmatter = raw_frontmatter.replace('### ', '', 1)
+
 # second pass: break lines on field names
 output = raw_frontmatter
 for name in FIELDNAMES:

From 2f8d7df88680a633a6fe5b0fa2bf5dd0392b5888 Mon Sep 17 00:00:00 2001
From: Ricardo Lafuente <r@manufacturaindependente.org>
Date: Jan 22 2024 15:39:02 +0000
Subject: [PATCH 5/17] Don't download en source files


---

diff --git a/website/i18n/download.sh b/website/i18n/download.sh
index e28ff80..543bd70 100755
--- a/website/i18n/download.sh
+++ b/website/i18n/download.sh
@@ -3,7 +3,7 @@
 # Updates the local translation files with the most recent Weblate versions.
 #
 
-for lang in `ls -d */ | sed 's/\///'`; do
+for lang in `ls -d */ | sed 's/\///' | grep -v '^en$'`; do
   echo $lang
   wlc download jshelter/website/$lang >| $lang/pages.po
   wlc download jshelter/website-posts/$lang >| $lang/posts.po
diff --git a/website/i18n/translate_content.sh b/website/i18n/translate_content.sh
index 2a5aba2..4033099 100755
--- a/website/i18n/translate_content.sh
+++ b/website/i18n/translate_content.sh
@@ -7,6 +7,7 @@ for lang in `ls -d */ | sed 's/\///' | grep -v '^en$'`; do
     mkdir -p ../content/$section/$lang # /content/pages/pt
     echo "Translating $section for language $lang..."
     for f in `ls ../content/$section/*.md`; do
+       # echo $f
        po2md $f -p $lang/$section.po >| ${f/$section/$section\/$lang}
     done
   done

From 668cb9911ac8112f31253d64793ea01aae2e627c Mon Sep 17 00:00:00 2001
From: Ricardo Lafuente <r@manufacturaindependente.org>
Date: Jan 22 2024 15:39:24 +0000
Subject: [PATCH 6/17] Add translate directive to Makefile


---

diff --git a/website/Makefile b/website/Makefile
index 04b93bd..976dc35 100644
--- a/website/Makefile
+++ b/website/Makefile
@@ -52,7 +52,10 @@ install:
 extract:
 	$(ACTIVATE); python extract_comments.py
 
-html: extract
+translate:
+	$(ACTIVATE); cd i18n; ./download.sh; ./translate_content.sh; for f in `ls ../content/posts/pt/*.md`; do ./postprocess.py $$f; done
+
+html: extract translate
 	cp ../tests/integration_tests/README.md content/pages/integration_tests.md
 	cp ../tests/unit_tests/README.md content/pages/unit_tests.md
 	mkdir -p output/ output/.well-known/
@@ -61,10 +64,13 @@ html: extract
 	$(ACTIVATE); python extract_comments.py
 	$(PELICAN) "$(INPUTDIR)" -o "$(OUTPUTDIR)" -s "$(CONFFILE)" $(PELICANOPTS)
 	# fix translated indexes to address a Pelican bug
-	cd content/pages; for lang in */; do mv ../../output/$$lang/$$lang/index.html ../../output/$$lang; rm -f ../../output/$$lang/$$lang/index.html; done
+	# cd content/pages; for lang in */; do mv ../../output/$$lang/$$lang/index.html ../../output/$$lang; rm -f ../../output/$$lang/$$lang/index.html; done
 
 clean:
 	[ ! -d "$(OUTPUTDIR)" ] || rm -rf "$(OUTPUTDIR)"
+	rm -fr content/pages/pt
+	rm -fr content/posts/pt
+	rm -fr content/wrappers/pt
 
 regenerate:
 	$(PELICAN) -r "$(INPUTDIR)" -o "$(OUTPUTDIR)" -s "$(CONFFILE)" $(PELICANOPTS)

From 2920fbcae59df3392ad08fff2c844c783aceec35 Mon Sep 17 00:00:00 2001
From: Ricardo Lafuente <r@manufacturaindependente.org>
Date: Jan 22 2024 15:48:00 +0000
Subject: [PATCH 7/17] Don't track autogenerated translation files


---

diff --git a/website/.gitignore b/website/.gitignore
index 84d354e..5ff575d 100644
--- a/website/.gitignore
+++ b/website/.gitignore
@@ -1,4 +1,5 @@
 # ignore auto-generated translations
-content/pages/*/*.md
-content/posts/*/*.md
-content/wrappers/*/*.md
+content/pages/*/*
+content/posts/*/*
+content/wrappers/*/*
+i18n/*/
diff --git a/website/content/posts/pt/crawling.md b/website/content/posts/pt/crawling.md
deleted file mode 100644
index aa4106e..0000000
--- a/website/content/posts/pt/crawling.md
+++ /dev/null
@@ -1,148 +0,0 @@
-Title: Measurement of JavaScript API usage on the web Date: 2021-03-30 14:00
-Series: JavaScript API usage
-
-The world wide web is a complex environment. Web pages can access many APIs
-ranging from text formatting to access to nearby Bluetooth devices. While many
-APIs are used for legitimate purposes, some are misused to track and identify
-their users without their knowledge. In this paper, we propose a methodology to
-measure the usage of JavaScript APIs on the public web. The methodology consists
-of an automated visit of several thousand websites and intercepting JavaScript
-calls performed by the pages. We also provide a design and architecture of a
-measurement platform that can be used for an automated visit of a list of
-websites. The proposed platform is based on OpenWPM. The browser is instrumented
-by OpenWPM and a customized Web API Manager extension is responsible for
-capturing JavaScript API calls.
-
-### Introduction
-
-Web browsers offer a wide range of possibilities. on the surface they *just*
-display web pages, but under the hood, web browsers provide a bridge between
-a viewed page and the host operating system. A web browser allows a web page to
-access information like values from sensors, information about battery status,
-installed fonts, and much more. The advertisement industry often takes advantage
-of the wide range of information provided by web browsers to create a web
-browser [fingerprint](https://amiunique.org/links). Most commonly, the
-fingeprinters misuse Web APIs (also called JavaScript APIs).
-
-This blog post is mainly concerned with user tracking and fingerprinting. For
-example Battery Status API implementation on Mozilla Firefox revealed very
-precise value allowing the trackers to identify the user for a [period of
-time](https://petsymposium.org/2017/papers/hotpets/batterystatus-not-included.pdf).
-As the Battery Status API was used heavily for fingerprinting, it has been
-removed from Mozilla Firefox in 2017. Other examples of JavaScript APIs that are
-used often for fingerprinting are [Canvas
-API](http://cseweb.ucsd.edu/~hovav/papers/ms12.html), [Audio
-API](https://senglehardt.com/papers/princeton_phd_dissertation_englehardt.pdf),
-[Permissions API](https://arxiv.org/abs/2008.04480) or [APIs for device
-sensors](https://dl.acm.org/doi/10.1145/3243734.3243860).
-
-In our work, we aim to measure the JavaScript APIs usage by popular websites. In
-this article, we present core technologies to accomplish these measurements. The
-stack of technologies is based on [OpenWPM](https://github.com/mozilla/OpenWPM)
-enriched by a browser extension, that allows us to intercept JavaScript calls of
-different APIs. This browser extension is based on Proxy objects.
-
-Our work is based on work of [Peter Snyders et
-al.](https://www3.cs.uic.edu/pub/Bits/PeterSnyder/Browser_Feature_Usage_on_the_Modern_Web.pdf)
-carried in 2016. Since then many new APIs were specified and implemented in web
-browsers, see the figure below (based on data from [Can I Use?
-website](https://caniuse.com/)).
-
-![Progress of Web APIs amount implemented in distinct browsers in
-time.]({attach}/images/crawling-apis.png)
-
-### Methodology proposal
-
-This section describes the methodology that we plan to use. This methodology is
-based on As it is based on the work of Peter Snyders, it is already validated.
-Moreover, using a methodology that is very close to the original one should show
-us a difference in the usage of the JavaScript APIs in 2016 and 2021.
-
-The main idea of the measurement is to visit several thousands of the most
-[popular pages](https://tranco-list.eu/#aboutus) on the internet and intercept
-as many JavaScript calls as possible.
-
-Visiting websites will be performed through Mozilla Firefox with an extension
-that intercepts and logs the JavaScript calls. We will visit not only the
-landing page but also the subset of subpages of each website. From the landing
-page, we will extract three links that point to a subpage of a given page. From
-each of these three subpages, we will get another three subpage links resulting
-in up to 13 pages of a given website being visited. This amount of pages should
-be high enough to catch the most of JavaScript calls. We will wait and intercept
-JavaScript calls for 30 seconds on each page to wait of API calls performed
-during the page load.
-
-Results of our measurements should also provide information about the JavaScript
-APIs, that were probably used in a manner, that is not necessary for a page to
-be working and is very likely used in a way, that the user would not find
-useful. To achieve this,
-
-We will run our measurements on every page in two different modes. Firstly, we
-will visit the page using the a browser withou adblocker. Later, we will also
-employ an adblocker. Hence, the study will show the difference API usage of
-regular pages and trackers.
-
-#### The original study
-
-The Snyders' study suggests that some of the JavaScript APIs are extremely
-popular and they are used on more than 90% of measured pages (e.g. a well known
-`Document.createElement` method from DOM API). On the other hand, there are many
-APIs that are used by a minority of measured pages. That being said, almost 50%
-of JavaScript APIs implemented in the browser at the time were not used by any
-of the measured pages.
-
-The study also suggests that there is no direct connection between the
-implementation date of a given JavaScript API in the browser (or by its
-specification date by some of the specifications vendors) and its popularity in
-using by websites. Concretely, there are some old JavaScript APIs, such as
-`XMLHttpRequest` that are still very popular. However, there are also quite new
-JavaScript APIs, that are used very frequently (i.e., `Selectors API Level 1`).
-
-The conducted study also measured the pages in two ways - with the ad blocker and
-without any ad blocking extension. Results of measurements showed that the
-blocking of different JavaScript APIs is not uniform and some APIs are blocked
-more often than others. Specifically, 10% of JavaScript APIs were blocked in 90%
-of cases resulting in a fact that 83% of APIs were used on less than 1% of
-websites when the page was visited with active blocking extension.
-
-#### Web API Manager
-
-Web API Manager is a browser extension, that aims to block explicitly defined
-JavaScript APIs. It has been developed by Snyders in 2016 and used in several
-studies conducted by [Snyders et
-al.](https://www.peteresnyder.com/https://www.peteresnyder.com/).
-
-The original purpose of the Web API Manager is to block explicitly defined
-JavaScript APIs. However, in our measurements, we just need to intercept the API
-calls, log these calls and delegate the calls to original receivers.
-
-The main principle of Web API Manager is based on Proxy objects. This
-metaprogramming technique allows intercepting calls performed on objects. While
-the main goal of the Web API Manager extension is to block the calls performed
-on objects that belong to particular JavaScript APIs, our goal is only to
-intercept these operations and delegate them to their original receivers. We
-will use the Log Aggregator interface to log the API calls.
-
-To provide a Web API Manager the list of JavaScript APIs members we need a list
-of supported APIs. The APIs implemented in Mozilla Firefox are available as [IDL
-files](https://searchfox.org/mozilla-central/source/dom/webidl).
-
-#### Measurement tools
-
-The figure below shows a simplified illustration of the measurement platform.
-There is OpenWPM in the middle of the architecture. OpenWPM orchestrates
-Selenium and Mozilla Firefox with the proxy-based intercepting Web API Manager.
-
-![image]({attach}/images/crawling-architecture.png)
-
-### The impact on JShelter
-
-Once we have data from our crawling study, we will compare the data with [another
-recent
-study](https://github.com/uiowa-irl/FP-Inspector/blob/master/Data/potential_fingerprinting_APIs.md).
-As already mentioned, we want to develop a fingerprinting detection based on
-counting the number of different APIs employed by a page, especially APIs that
-are not frequently used for benign purposes. When a fingerprinting attempt is
-identified, we want to (1) inform the user, (2) prevent uploading of the
-fingerprint to the server, (3) prevent storing the fingerprint for later usage.
-
diff --git a/website/content/posts/pt/localportscanning.md b/website/content/posts/pt/localportscanning.md
deleted file mode 100644
index 4d95b3f..0000000
--- a/website/content/posts/pt/localportscanning.md
+++ /dev/null
@@ -1,143 +0,0 @@
-Title: How JShelter prevents other parties from sniffing on your local
-applications? Date: 2021-06-15 09:00
-
-We recently found a [blog
-post](https://blog.nem.ec/2020/05/24/ebay-port-scanning/) about ThreatMetrix
-Inc. (a part of LexisNexis) scanning locally open ports for about 30,000 web
-sites, including eBay. The figure below shows that a browser tries to connect to
-ports commonly used for remote access to the computer (e.g., RDesktop, VNC,
-TeamViewer) and other applications.
-
-![A screenshot of the browser being used as a proxy to scan locally open
-ports]({attach}/images/portscan-1_captured_traffic.png)
-
-The obvious question is, what is the reason for such behaviour? The simple answer
-is security. See additional links to [Security
-Boulevard](https://securityboulevard.com/2020/05/is-ebay-port-scanning-your-pc-probably/),
-[Avast](https://blog.avast.com/why-is-ebay-port-scanning-my-computer-avast), and
-[The register](https://www.theregister.com/2020/05/26/ebay_port_scans_your_pc/).
-
-One possibility is that ThreatMetrix creates a
-[fingerprint](https://arxiv.org/pdf/1905.01051.pdf), and locally running
-applications are a part of the fingerprint. Consequently, the authentication
-algorithm stores attributes about your device(s) and compare them during each
-log in with the previous values. Seeing that you are logging in using a
-previously seen device, the algorithm can let you in with just a password
-without additional proves. However, should you use a new device, the algorithm
-might decide that additional authentication steps are required and send you an
-SMS.
-
-Another option is that ThreatMetrix knows that many fraudulent activities occur
-on devices with specific ports open. Recall that the ports being checked concern
-remote desktop access. Having a remote desktop port open means that the computer
-may be used by an adversary that does not sit near the computer but is connected
-remotely. Consequently, the authentication algorithm might decide that
-additional proves about the user identity should be checked.
-
-We do not know what the real reason behind the scanning is. It might be one of
-the above, both, or a similar reason.
-
-### Ethical and legal issues
-
-Although it could be that the underlying intentions are benign and users actually
-do benefit from the scanning, the scanning raises some ethical issues.
-
-Very often, security and privacy are interconnected. But sometimes, one might
-increase security by revealing something private. In this case, ThreatMetrix
-learns information about the running device that is not obvious to the device
-owner (a user or a company). Typically, the owner of the device does not even
-know that such information can leak. If the information stays with ThreatMetrix,
-then the benefits could appear to be greater than the disadvantages. However,
-adversaries could stole information from ThreatMetrix (see for example the
-[Ecquifax breach](https://en.wikipedia.org/wiki/2017_Equifax_data_breach)) or
-the company can start to
-[sell](https://www.vice.com/en/article/qjdkq7/avast-antivirus-sells-user-browsing-data-investigation)
-the
-[information](https://www.pcmag.com/news/the-cost-of-avasts-free-antivirus-companies-can-spy-on-your-clicks)
-or even [share with others](https://brave.com/rtb-evidence/).
-
-So is the scanning and data collecting legal? As some of our developers and users
-are based in the EU, we will dig into the EU perspective. You might want to
-consult your local laws if you are outside the EU. Moreover, as we are not
-lawyers, you might want to consult one even in the EU.
-
-[EU ePrivacy Directive](https://eur-lex.europa.eu/legal-content/EN/ALL/?
-uri=CELEX:32002L0058) applies. However, as [WP29
-clarified](https://ec.europa.eu/justice/article-29/documentation/opinion-recommendation/files/2014/wp224_en.pdf)
-(use case 7.5), user-centric security can be viewed as strictly necessary to
-provide the service. So it seems likely that port scanning for security reasons
-would trigger the ePrivacy exception and user consent is not necessary.
-
-As the port scanning is a part of the login mechanism, open ports are personal
-data without doubts. So GDPR also applies. GDPR also list security as a possible
-legitimate interest of a data controller (e.g. eBay), see recital 49.
-Nevertheless, if such a scan is proportionate is an open question; it is
-possible that the legitimate interests of data controllers (such as eBay) are
-overriden by the interests or fundamental rights and freedoms of the data
-subject (you), see Article(6)(1)(f). The Court of Justice of EU (CJEU) decided
-several issues that concerned legitimate interests and the necessity of
-processing, e.g. [C-13/16, point 30 that also points to other related
-cases](https://curia.europa.eu/juris/liste.jsf?num=C-13/16) or [C-708/18 points
-40–45](https://curia.europa.eu/juris/liste.jsf?num=C-708/18). It might be
-possible that it is strictly necessary for eBay to perform local port scanning.
-
-Nevertheless, Article 12-14 of GDPR lists requirements on the information that a
-data controller should reveal to each data subject before the data processing
-starts or in a reasonable time afterwards. Hence, each controller employing
-ThreatMetrix should reveal, for example, in the privacy policy, what categories
-of data it is using and for which purposes. From the
-[linked](https://blog.avast.com/why-is-ebay-port-scanning-my-computer-avast)
-[articles](https://www.theregister.com/2020/05/26/ebay_port_scans_your_pc/), it
-seems that ThreatMetrix and eBay are secretive about data being collected.
-
-Another GDPR issue might be data transfers to third countries. Data transfers of
-open ports may not be compatible with GDPR in the light of the [CJEU
-C-311/18](https://curia.europa.eu/juris/liste.jsf?num=C-311/18) decision if the
-information leaves EEA.
-
-### Why is not my browser protecting me from remote servers accessing local
-information?
-
-OK, so even though the scanning could be legal, one can disagree that others
-should be allowed to sniff on local applications. So why does a browser leak the
-information?
-
-Well, the browser employs so called [same origin
-policy](https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy)
-(SOP) that in abstract theory should prevent websites from the scans in
-question. As your local computer is of a different origin from the remote
-website, your computer should be protected by SOP. Nevertheless, SOP has its
-limitations. First of all, some [cross-origin resource
-sharing](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) is beneficial,
-so the browser cannot block outgoing requests to other origins. Such behaviour
-opens possibilities for
-[side-channels](https://www.forcepoint.com/sites/default/files/resources/files/report-attacking-internal-network-en_0.pdf)
-to be identified. So even though the web page cannot communicate with
-applications on your computer (or in your network) without the cooperation of
-these applications, it can observe the behaviour and make some conclusions based
-on the observed errors, timing, etc.
-
-An (ad) blocker can prevent you from the activity. As the blockers typically
-leverage blocklists, such a port scanning script URL needs to match a rule in a
-block list. Once information about a misbehaving script becomes public, a rule
-can be added to a block list. However, this could take some time. Additional
-techniques like [DNS
-de-cloaking](https://blog.lukaszolejnik.com/large-scale-analysis-of-dns-based-tracking-evasion-broad-data-leaks-included/)
-need to be applied in this case.
-
-### Network Boundary Shield to the rescue
-
-JShelter contains a Network Boundary Shield (NBS) that blocks outgoing browser
-requests based on the observed behaviour, i.e. a page hosted on public internet
-tries to access local URLs. NBS just works and cannot be fooled by changes in
-the URL path, DNS cloaking or other techniques.
-
-![JShelter blocks the scan]({attach}/images/portscan-2_request_blocked.png)
-
-Firefox contains DNS API, so NBS works flawlessly. In Chromium-based browsers,
-the exact blocking behaviour depends on how quickly a scanning script can fire
-the requests and the precise destination (IP address or a domain name).
-Depending on the interaction with DNS, NBS can be side-stepped on Chrome. In
-this case, ThreatMetrix does not try any evasion technique, so NBS just works in
-the case of eBay and ThreatMetrix.
-
diff --git a/website/content/posts/pt/support.md b/website/content/posts/pt/support.md
deleted file mode 100644
index 84e64ae..0000000
--- a/website/content/posts/pt/support.md
+++ /dev/null
@@ -1,66 +0,0 @@
-Title: We received support from NGI0 PET Fund Date: 2021-03-30 09:00 Series:
-JShelter background
-
-We are very happy to announce that the <a
-href="https://nlnet.nl/project/JSRestrictor/">JavaScript Restrictor received
-support from NGI0 PET Fund</a>, a fund established by NLnet with financial
-support from the European Commission's Next Generation Internet programme, under
-the aegis of DG Communications Networks, Content and Technology under grant
-agreement No 825310.
-
-We are very excited to improve the extension further. We will focus on the
-following main goals:
-
-### 1. Investigate fingerprinting scripts and prepare wrappers
-
-Review the previously identified APIs suitable for fingerprinting. Select APIs
-suitable for JShelter and add wrappers for these APIs. This work has already
-started, see issue #66. Additionally, we want to focus on identification of
-methods used for fingeprinting such as those identified by Iqbal et al., see
-https://uiowa-irl.github.io/FP-Inspector/
-
-### 2. Prevent unique identification of a device
-
-It is hard, if not impossible, to both prevent fingerprinting and still provide
-customized environment for the user. Hence, we want to identify fingerprinting
-attempts by counting the number of different APIs employed by a page, especially
-APIs that are not frequently used for benign purposes. When a fingerprinting
-attempt is identified, we want to (1) inform the user, (2) prevent uploading of
-the fingerprint to the server, (3) prevent storing the fingerprint for later
-usage.
-
-### 3. Code ported from Chrome Zero
-
-In version 0.3, we integrated features of Chrome Zero 7 as it is no longer
-maintained. By integrating the functionality to JShelter, we want to keep the
-counter-meassures available in a maintained extension. However, we do not have
-sufficient tests for the functionality.
-
-### 4. Evaluation and porting of code from Brave
-
-Brave browser currently implements anti-fingerprinting techniques that aim at
-providing little lies about the browser environment. We want to evaluate the
-messures and select techniques that are suitable for JShelter.
-
-### 5. Fixing known bugs
-
-We want to focus on the proposed changes and found bugs that are reported in the
-GitHub bug tracker.
-
-* We already closed issues #53, #62, and #72 as a part of this project. The fixes
-are already available as a part of the 0.4 subversions.
-* We want to also deal with issues #56 and #71 that are crucial for the success
-of the extension.
-* We will focus on other identified bugs in the wrappers or developped techniques.
-
-### 6. Cooperation with the Privacy Shield project
-
-We are also excited to announce that we found other partners that are willing to
-work on our code base through the NGI0 PET Fund, <a
-href="https://nlnet.nl/project/JavascriptShield/">Privacy Shield project run by
-Free Software Foundation</a>. Expect inclusion of code that will help to defend
-your freedoms and provide anti-malware protections. This cooperation should also
-improve the GUI of the extension and create explenatory web pages explaining the
-functionality and its risks. It is possible that the project will be rebranded
-as a result of the cooperation.
-
diff --git a/website/i18n/en/pages.po b/website/i18n/en/pages.po
deleted file mode 100644
index 611f796..0000000
--- a/website/i18n/en/pages.po
+++ /dev/null
@@ -1,5557 +0,0 @@
-#
-msgid ""
-msgstr "Content-Type: text/plain; charset=utf-8\n"
-
-#: ../content/pages/build.md:block 1 (paragraph)
-msgid "Title: Building from scratch"
-msgstr ""
-
-#: ../content/pages/build.md:block 2 (header)
-msgid "GNU/Linux and Mac OS"
-msgstr ""
-
-#: ../content/pages/build.md:block 3 (ordered list)
-msgid ""
-"Go to the project repository: <https://pagure.io/JShelter/webextension>."
-msgstr ""
-
-#: ../content/pages/build.md:block 3 (ordered list)
-msgid "Download the desired branch, e.g. as zip archive."
-msgstr ""
-
-#: ../content/pages/build.md:block 3 (ordered list)
-msgid "Unpack the zip archive."
-msgstr ""
-
-#: ../content/pages/build.md:block 3 (ordered list)
-msgid "Run `make`."
-msgstr ""
-
-#: ../content/pages/build.md:block 3 (ordered list)
-msgid ""
-"You will need common software, such as `zip`, `wget`, `bash`, `awk`, `sed`."
-msgstr ""
-
-#: ../content/pages/build.md:block 3 (ordered list)
-msgid ""
-"Note that running `make` removes all `console.debug` calls. If you want to "
-"keep such calls, run `make debug`."
-msgstr ""
-
-#: ../content/pages/build.md:block 3 (ordered list)
-msgid "Import the extension to the browser."
-msgstr ""
-
-#: ../content/pages/build.md:block 3 (ordered list)
-msgid ""
-"[Firefox](https://developer.mozilla.org/en-US/docs/Mozilla/Add-"
-"ons/WebExtensions/Your_first_WebExtension#installing)"
-msgstr ""
-
-#: ../content/pages/build.md:block 3 (ordered list)
-msgid "Open `about:debugging`."
-msgstr ""
-
-#: ../content/pages/build.md:block 3 (ordered list)
-msgid "Click the *This Firefox* option"
-msgstr ""
-
-#: ../content/pages/build.md:block 3 (ordered list)
-msgid "Click the *Load Temporary Add-on* button"
-msgstr ""
-
-#: ../content/pages/build.md:block 3 (ordered list)
-msgid "Select the file `jshelter_firefox.zip` created by `make`."
-msgstr ""
-
-#: ../content/pages/build.md:block 3 (ordered list)
-msgid "Chromium-based browsers:"
-msgstr ""
-
-#: ../content/pages/build.md:block 3 (ordered list)
-msgid "Open `chrome://extensions`."
-msgstr ""
-
-#: ../content/pages/build.md:block 3 (ordered list)
-msgid "Enable developper mode."
-msgstr ""
-
-#: ../content/pages/build.md:block 3 (ordered list)
-msgid "Click `Load unpacked`."
-msgstr ""
-
-#: ../content/pages/build.md:block 3 (ordered list)
-msgid "Import the `jshelter_chrome/` directory created by `make`."
-msgstr ""
-
-#: ../content/pages/build.md:block 4 (header)
-msgid "Windows"
-msgstr ""
-
-#: ../content/pages/build.md:block 5 (ordered list)
-msgid ""
-"Install Windows Subsystem for Linux (WSL): <https://docs.microsoft.com/en-"
-"us/windows/wsl/install-win10>."
-msgstr ""
-
-#: ../content/pages/build.md:block 5 (ordered list)
-msgid "Open the JShelter project folder in WSL, run `make`."
-msgstr ""
-
-#: ../content/pages/build.md:block 5 (ordered list)
-msgid "Make sure that `zip` and all other necessary tools are installed."
-msgstr ""
-
-#: ../content/pages/build.md:block 5 (ordered list)
-msgid ""
-"Note that EOL in `fix_manifest.sh` must be set to `LF` (you can use the tool"
-" `dos2unix` in WSL to convert `CR LF` to `LF`)."
-msgstr ""
-
-#: ../content/pages/build.md:block 5 (ordered list)
-msgid ""
-"On Windows, import the extension to the browser according to the "
-"instructions for Linux (above)."
-msgstr ""
-
-#: ../content/pages/coding-style.md:block 1 (paragraph)
-msgid "Title: Coding style"
-msgstr ""
-
-#: ../content/pages/coding-style.md:block 2 (header)
-msgid "General guidelines"
-msgstr ""
-
-#: ../content/pages/coding-style.md:block 3 (unordered list)
-msgid ""
-"Use **tabulators** for indentation, and avoid spaces/tabs at the end of the "
-"line."
-msgstr ""
-
-#: ../content/pages/coding-style.md:block 3 (unordered list)
-msgid ""
-"Functions, methods, classes, ifs, cycles etc. have opening braces at the "
-"same line."
-msgstr ""
-
-#: ../content/pages/coding-style.md:block 3 (unordered list)
-msgid ""
-"Text width preferred less than 80 characters, maximum 100 characters. It is "
-"better having readable code than pursuing this limit."
-msgstr ""
-
-#: ../content/pages/coding-style.md:block 3 (unordered list)
-msgid "Always enclose blocks of expressions into brackets."
-msgstr ""
-
-#: ../content/pages/coding-style.md:block 3 (unordered list)
-msgid ""
-"Names are lower case and preferably explain the purpose of the variable, "
-"class, etc."
-msgstr ""
-
-#: ../content/pages/coding-style.md:block 3 (unordered list)
-msgid ""
-"Comment classes, functions, etc. in Doxygen style. Use `make doc` to "
-"generate documentation."
-msgstr ""
-
-#: ../content/pages/coding-style.md:block 4 (header)
-msgid "Code examples"
-msgstr ""
-
-#: ../content/pages/coding-style.md:block 5 (paragraph)
-msgid "Correct code example:"
-msgstr ""
-
-#: ../content/pages/coding-style.md:block 7 (paragraph)
-msgid "Bad code example:"
-msgstr ""
-
-#: ../content/pages/coding-style.md:block 9 (header)
-msgid "Version control workflow"
-msgstr ""
-
-#: ../content/pages/coding-style.md:block 10 (unordered list)
-msgid ""
-"Do not provide commits dealing with bad coding style. The only exception is "
-"if you want to improve code that does not follow the coding style rules. "
-"Preferably provide one commit that fixes the issues and another (others) "
-"that improve the code, add new functionality etc."
-msgstr ""
-
-#: ../content/pages/coding-style.md:block 10 (unordered list)
-msgid ""
-"Atomic commits are useful, see [this "
-"page](https://www.freshconsulting.com/atomic-commits/) for help."
-msgstr ""
-
-#: ../content/pages/coding-style.md:block 10 (unordered list)
-msgid ""
-"A commit should not contain adding missing semicolons, changes in generated "
-"code, a bugfix, and addition of a new functionality. Each of these changes "
-"should go to a separate commit with a message explaining why is the change "
-"necessary (if it is not obvious like in the case of missing semicolons)."
-msgstr ""
-
-#: ../content/pages/coding-style.md:block 10 (unordered list)
-msgid ""
-"Provide meaningful commit messages. For help, see points 1, 2 and 7 of [this"
-" guide](https://chris.beams.io/posts/git-commit/)"
-msgstr ""
-
-#: ../content/pages/coding-style.md:block 10 (unordered list)
-msgid ""
-"Do not fear changing commits that are not public, yet. If you create a bug "
-"and find it before merge, it is better to fix the bug in the original "
-"commit. Available Git operations for this are `rebase (-i)`, `fixup`, "
-"`squash` and `push --force`."
-msgstr ""
-
-#: ../content/pages/coding-style.md:block 10 (unordered list)
-msgid ""
-"This pull request (FIXME: need to find link) contains an example of big "
-"commits that needed to be refactored."
-msgstr ""
-
-#: ../content/pages/coding-style.md:block 10 (unordered list)
-msgid ""
-"Provide merge request more often rather than commiting big changes. If you "
-"fix Makefile or other scripts, provide the change and do not wait. Create "
-"code that is understandable and does not repeat itself. If possible, use "
-"variables instead of copying the same code."
-msgstr ""
-
-#: ../content/pages/credits.md:block 1 (paragraph)
-msgid "Title: Credits"
-msgstr ""
-
-#: ../content/pages/credits.md:block 2 (paragraph)
-msgid "[TOC]"
-msgstr ""
-
-#: ../content/pages/credits.md:block 3 (header)
-msgid "Developers"
-msgstr ""
-
-#: ../content/pages/credits.md:block 4 (paragraph)
-msgid ""
-"**[Libor Polčák](https://www.fit.vutbr.cz/~polcak)** was behind an idea to "
-"implement a webextension that works as a firewall for JavaScript APIs. He is"
-" the current main maintainer. He received support for this project through "
-"the <a href=\"https://nlnet.nl/project/JSRestrictor/\">JavaScript "
-"Restrictor</a> project of NGI0 PET Fund, a fund established by NLnet with "
-"financial support from the European Commission's Next Generation Internet "
-"programme, under the aegis of DG Communications Networks, Content and "
-"Technology under grant agreement No 825310. He supervised/supervises diploma"
-" theses that improve the web extension."
-msgstr ""
-
-#: ../content/pages/credits.md:block 5 (paragraph)
-msgid ""
-"**Giorgio Maone** is working on the extension as a part of the [JS Shield "
-"project](https://nlnet.nl/project/JavascriptShield/), for example, he is "
-"working on cross-browser support, improvements on code injection and the "
-"compatibility between the global JS environment, Workers, and iframes."
-msgstr ""
-
-#: ../content/pages/credits.md:block 6 (paragraph)
-msgid ""
-"**Zbyněk Červinka** developed a [proof-of-concept "
-"version](https://github.com/cervinka-zbynek/masters-thesis) of this "
-"extension as a part of his [master's "
-"thesis](https://www.fit.vut.cz/study/thesis/21274/) (in Czech)."
-msgstr ""
-
-#: ../content/pages/credits.md:block 7 (paragraph)
-msgid ""
-"**Martin Timko** developed first public versions upto "
-"[0.2.1](https://pagure.io/JShelter/webextension/archive/0.2.1/webextension-0.2.1.zip)"
-" as a part of his [master's "
-"thesis](https://www.fit.vut.cz/study/thesis/21824/). He also ported the "
-"extension to Chrome and Opera."
-msgstr ""
-
-#: ../content/pages/credits.md:block 8 (paragraph)
-msgid ""
-"**Martin Bednář** developed test suites of the extension as a part of his "
-"[master's thesis](https://www.fit.vut.cz/study/thesis/22376/) and continued "
-"to work on the extension for some time afterwards. He also fixed some bugs "
-"found during the testing."
-msgstr ""
-
-#: ../content/pages/credits.md:block 9 (paragraph)
-msgid ""
-"**Pavel Pohner** developed the Network Boundary Scanner as a part of his "
-"[master's thesis](https://www.fit.vut.cz/study/thesis/22377/)."
-msgstr ""
-
-#: ../content/pages/credits.md:block 10 (paragraph)
-msgid ""
-"**Pater Horňák** ported functionality from [Chrome "
-"Zero](https://github.com/IAIK/ChromeZero) as a part of his [bachelor "
-"thesis](https://www.fit.vut.cz/study/thesis/22374/). He also provided "
-"several small fixes to the code base."
-msgstr ""
-
-#: ../content/pages/credits.md:block 11 (paragraph)
-msgid ""
-"**Matúš Švancár** ported Farbling anti-fingerprinting measures from the "
-"Brave browser as a part of his [master's "
-"thesis](https://www.fit.vut.cz/study/thesis/23310/)."
-msgstr ""
-
-#: ../content/pages/credits.md:block 12 (paragraph)
-msgid ""
-"**Marek Saloň** created Fingerprint Detector as a part of his [master's "
-"thesis](https://www.fit.vut.cz/study/thesis/23645/) and later improved the "
-"detector."
-msgstr ""
-
-#: ../content/pages/credits.md:block 13 (paragraph)
-msgid "**Radek Hranický** created sensor API wrappers."
-msgstr ""
-
-#: ../content/pages/credits.md:block 14 (paragraph)
-msgid ""
-"**Martin Zmitko** improved performance of the extension as a part of his "
-"bachelor thesis. He fixed some bugs during the process."
-msgstr ""
-
-#: ../content/pages/credits.md:block 15 (paragraph)
-msgid ""
-"We thank all other minor contributors of the project that are not listed in "
-"this section."
-msgstr ""
-
-#: ../content/pages/credits.md:block 16 (header)
-msgid "Key ideas"
-msgstr ""
-
-#: ../content/pages/credits.md:block 17 (paragraph)
-msgid ""
-"The development of this extension is influenced by the paper [JavaScript "
-"Zero: Real JavaScript and Zero Side-Channel "
-"Attacks](https://graz.pure.elsevier.com/de/publications/javascript-zero-"
-"real-javascript-and-zero-side-channel-attacks). It appeared during the work "
-"of Zbyněk Červinka and provided basically the same approach to restrict APIs"
-" as was at the time developed by Zbyněk Červinka."
-msgstr ""
-
-#: ../content/pages/credits.md:block 18 (paragraph)
-msgid ""
-"The [Force Point "
-"report](https://www.forcepoint.com/sites/default/files/resources/files/report-"
-"attacking-internal-network-en_0.pdf) was a key inspiration for the "
-"development of the Network Boundary Shield."
-msgstr ""
-
-#: ../content/pages/credits.md:block 19 (paragraph)
-msgid ""
-"Some of the fingerprinting counter-measures are inspired by [Farbling of the"
-" Brave browser](blogarticles/farbling.md)."
-msgstr ""
-
-#: ../content/pages/credits.md:block 20 (header)
-msgid "Borrowed code"
-msgstr ""
-
-#: ../content/pages/credits.md:block 21 (paragraph)
-msgid "We borrowed code from other free software projects:"
-msgstr ""
-
-#: ../content/pages/credits.md:block 22 (unordered list)
-msgid "[Chrome Zero](https://github.com/IAIK/ChromeZero)"
-msgstr ""
-
-#: ../content/pages/credits.md:block 22 (unordered list)
-msgid "[Brave Farbling](https://github.com/brave/brave-browser/issues/8787)"
-msgstr ""
-
-#: ../content/pages/credits.md:block 22 (unordered list)
-msgid "[NoScript Common Library](https://github.com/hackademix/nscl/)"
-msgstr ""
-
-#: ../content/pages/credits.md:block 22 (unordered list)
-msgid ""
-"[Typed array "
-"polyfill](https://github.com/inexorabletash/polyfill/blob/master/typedarray.js),"
-" Copyright (c) 2010, Linden Research, Inc., Copyright (c) 2014, Joshua Bell"
-msgstr ""
-
-#: ../content/pages/credits.md:block 22 (unordered list)
-msgid ""
-"[PRNG Alea](https://github.com/nquinlan/better-random-numbers-for-"
-"javascript-mirror) by (C) 2010 Johannes Baagøe"
-msgstr ""
-
-#: ../content/pages/credits.md:block 22 (unordered list)
-msgid "[JS-sha256](https://github.com/emn178/js-sha256) by (C) Chen, Yi-Cyuan"
-msgstr ""
-
-#: ../content/pages/faq.md:block 1 (paragraph)
-msgid "Title: Frequently Asked Questions Slug: faq [TOC]"
-msgstr ""
-
-#: ../content/pages/faq.md:block 2 (header)
-msgid "Project information"
-msgstr ""
-
-#: ../content/pages/faq.md:block 3 (header)
-msgid "How can I get active and participate?"
-msgstr ""
-
-#: ../content/pages/faq.md:block 4 (paragraph)
-msgid ""
-"Start using JShelter and tell your friends. You can fill an issue on our "
-"[bug tracker](https://pagure.io/JShelter/webextension/issues) "
-"([alternative](https://github.com/polcak/jsrestrictor/issues)) or pick up an"
-" issue and start working on JShelter. You can track the development in our "
-"[repository](https://pagure.io/JShelter/webextension) "
-"([alternative](https://github.com/polcak/jsrestrictor)). Please let us know "
-"before you start implementing, preferably directly in the issue. You can "
-"contact us by [e-mail](mailto:jshelter@gnu.org) to privately report issues "
-"or if you do not have a forge account. Join our [mailing "
-"list](https://lists.nongnu.org/archive/html/js-shield/) to follow updates "
-"and join in our discussions."
-msgstr ""
-
-#: ../content/pages/faq.md:block 5 (header)
-msgid "Can I translate the extension to a new language?"
-msgstr ""
-
-#: ../content/pages/faq.md:block 6 (paragraph)
-msgid ""
-"Yes. Please see [instructions](/i18n/), go to "
-"[Weblate](https://hosted.weblate.org/projects/jshelter/), or translate the "
-"extension in the JSON files. If you want to start translating a new "
-"language, let us know. For example, you can open an issue in the [issue "
-"tracker](https://pagure.io/JShelter/webextension/issues) or send us "
-"[e-mail](mailto:jshelter@gnu.org). If you are in doubt about how to "
-"translate a string or do not understand its meaning, let us know in an "
-"[issue](https://pagure.io/JShelter/webextension/issues) or send us "
-"[e-mail](mailto:jshelter@gnu.org)."
-msgstr ""
-
-#: ../content/pages/faq.md:block 7 (header)
-msgid ""
-"What is the current JShelter status? Is it ready, or is it still a work in "
-"progress?"
-msgstr ""
-
-#: ../content/pages/faq.md:block 8 (paragraph)
-msgid ""
-"We think that JShelter is ready to be used for everyday browsing. We believe"
-" that JShelter in the current state fulfills the goal of giving you control "
-"over your browser and the APIs available for the web page."
-msgstr ""
-
-#: ../content/pages/faq.md:block 9 (paragraph)
-msgid ""
-"We believe that the `Recommended` level changes your fingerprint, so typical"
-" fingerprinting scripts will fail to correlate your cross-origin activities "
-"and activities on the same origin during different browser sessions. See the"
-" [threat model](/threatmodel/), the questions in the [browser fingerprinting"
-" section](#browser-fingerprinting), and [the section on interaction with "
-"other tools](#interactions-between-jshelter-and-other-similar-tools) for "
-"possible caveats."
-msgstr ""
-
-#: ../content/pages/faq.md:block 10 (paragraph)
-msgid ""
-"Test your browser on common fingerprinting testers. Then, use the `Strict` "
-"level and test again to see that it considerably lowers the information "
-"about your computer:"
-msgstr ""
-
-#: ../content/pages/faq.md:block 11 (unordered list)
-msgid "[EFF Cover your tracks](https://coveryourtracks.eff.org/)"
-msgstr ""
-
-#: ../content/pages/faq.md:block 11 (unordered list)
-msgid "[Am I unique?](https://amiunique.org/)"
-msgstr ""
-
-#: ../content/pages/faq.md:block 11 (unordered list)
-msgid "[Audio and font fingerprinting](https://audiofingerprint.openwpm.com/)"
-msgstr ""
-
-#: ../content/pages/faq.md:block 11 (unordered list)
-msgid "[Device info](https://www.deviceinfo.me/)"
-msgstr ""
-
-#: ../content/pages/faq.md:block 11 (unordered list)
-msgid "[Bromite](https://www.bromite.org/detect)"
-msgstr ""
-
-#: ../content/pages/faq.md:block 11 (unordered list)
-msgid "[Browser leaks](https://browserleaks.com/)"
-msgstr ""
-
-#: ../content/pages/faq.md:block 11 (unordered list)
-msgid ""
-"[JShelter test page](https://polcak.github.io/jsrestrictor/test/test.html)"
-msgstr ""
-
-#: ../content/pages/faq.md:block 12 (paragraph)
-msgid ""
-"At the same time, we are aware of several JShelter [bugs and "
-"issues](https://pagure.io/JShelter/webextension/issues/). We are working on "
-"making JShelter bug-free. We do not want to break benign pages. Fixing some "
-"issues takes time. Other issues need balancing between several options. "
-"JShelter is meant to be used with (ad)blockers like [uBlock "
-"Origin](https://github.com/gorhill/uBlock#ublock-origin). Using a blocker "
-"will make your online activities considerably safer. At the same time, it "
-"will make JShelter break fewer sites."
-msgstr ""
-
-#: ../content/pages/faq.md:block 13 (paragraph)
-msgid ""
-"Right now, JShelter will need more interaction from you than we would "
-"prefer. Some protection needs improvements. Some functionality needs to be "
-"included. When we achieve the state of fixing the bugs and making JShelter "
-"easy to manage, we will release version 1.0. If you are unwilling to tweak "
-"JShelter occasionally, consider returning once we release version 1.0. "
-"Otherwise, try [other options](/fingerprinting/)."
-msgstr ""
-
-#: ../content/pages/faq.md:block 14 (header)
-msgid "What is the best source of information about JShelter?"
-msgstr ""
-
-#: ../content/pages/faq.md:block 15 (paragraph)
-msgid ""
-"The best sources for JShelter information can be found on [our "
-"website](https://jshelter.org/) and our "
-"[paper](https://arxiv.org/abs/2204.01392)."
-msgstr ""
-
-#: ../content/pages/faq.md:block 16 (header)
-msgid "What is the threat model?"
-msgstr ""
-
-#: ../content/pages/faq.md:block 17 (paragraph)
-msgid ""
-"We created a [dedicated page describing the threat model](/threatmodel/) of "
-"JShelter. You should read the page before you install the extension. Make "
-"sure that JShelter aligns with the threats you see on the web."
-msgstr ""
-
-#: ../content/pages/faq.md:block 18 (header)
-msgid "JShelter broke a page, what should I do?"
-msgstr ""
-
-#: ../content/pages/faq.md:block 19 (paragraph)
-msgid ""
-"This happens from time to time. We want to eliminate such pages, but "
-"[JShelter is not there yet](#what-is-the-current-jshelter-status-is-it-"
-"ready-or-is-it-still-a-work-in-progress)."
-msgstr ""
-
-#: ../content/pages/faq.md:block 20 (paragraph)
-msgid ""
-"Your page might be broken because [Network Boundary Shield](/nbs/) (NBS) or "
-"[fingerprint Detector](/fpd/) (FPD) detected a problem. You should have seen"
-" a notification in such cases unless you turned notifications off. We do not"
-" recommend turning notifications off (see [the questions on "
-"notifications](#why-do-i-see-so-many-notifications-from-jshelter)). Whenever"
-" NBS or FPD detect a possible problem on the site, it is up to you to decide"
-" if you believe the owner of the visited page or are tempted to view the "
-"content so much that you turn the protection off."
-msgstr ""
-
-#: ../content/pages/faq.md:block 21 (header)
-msgid "Fingerprint Detector (FPD)"
-msgstr ""
-
-#: ../content/pages/faq.md:block 22 (paragraph)
-msgid "If you see a notification like:"
-msgstr ""
-
-#: ../content/pages/faq.md:block 23 (paragraph)
-msgid ""
-"![Fingerprint Detector "
-"notification]({attach}/images/fpdetection/notifications.png)"
-msgstr ""
-
-#: ../content/pages/faq.md:block 24 (paragraph)
-msgid ""
-"In this case, FPD evaluated that the page tries to fingerprint you. FPD can "
-"be optionally configured to prevent uploading the fingerprint to the server."
-" In that case, FPD blocks all further requests of the visited page and "
-"removes the storages available to the page. Some web pages employ browser "
-"fingerprinting for security purposes. You might want to allow the page to "
-"fingerprint you in such a case. Open the popup by clicking on the JShelter "
-"logo badge icon and turn off the FPD for the visited site."
-msgstr ""
-
-#: ../content/pages/faq.md:block 25 (paragraph)
-msgid "![Turn FPD off](/images/faq/fpd_off.png)"
-msgstr ""
-
-#: ../content/pages/faq.md:block 26 (paragraph)
-msgid ""
-"The depicted setting will turn FPD off for all pages of the visited origin. "
-"If you want to disable FPD for all pages, change the `Global settings`."
-msgstr ""
-
-#: ../content/pages/faq.md:block 27 (header)
-msgid "Network Boundary Shield (NBS)"
-msgstr ""
-
-#: ../content/pages/faq.md:block 29 (paragraph)
-msgid ""
-"![JShelter blocks the scan]({attach}/images/portscan-2_request_blocked.png)"
-msgstr ""
-
-#: ../content/pages/faq.md:block 30 (paragraph)
-msgid ""
-"Then, it was NBS that blocked some requests. Rarely can some pages be broken"
-" because they require interaction between the public Internet and the local "
-"network. For example, the Network Boundary Shield might break some intranet "
-"information systems. JShelter users also reported an increased number of "
-"false positives when using DNS-based filtering programs. If you use one, "
-"make sure that DNS returns 0.0.0.0 for the blocked domains."
-msgstr ""
-
-#: ../content/pages/faq.md:block 31 (paragraph)
-msgid "![Turn NBS off](/images/faq/nbs_off.png)"
-msgstr ""
-
-#: ../content/pages/faq.md:block 32 (paragraph)
-msgid ""
-"The depicted setting will turn NBS off for all pages of the visited origin. "
-"If you want to disable NBS for all pages, change the `Global settings`."
-msgstr ""
-
-#: ../content/pages/faq.md:block 33 (header)
-msgid "JavaScript Shield (JSS)"
-msgstr ""
-
-#: ../content/pages/faq.md:block 34 (paragraph)
-msgid ""
-"If you have not seen any notifications (and didn't disable notifications "
-"manually), it is JavaScript Shield (JSS) that might have broken the page. "
-"See questions on [broken videos](#how-can-i-fix-videos-if-they-fail-to-play-"
-"or-retrieve-data-in-time) and [web workers](#i-want-to-use-a-website-that-"
-"uses-web-workers-but-it-is-broken-how-can-i-fix-the-site) for specific JSS "
-"tweaks that might solve your problem."
-msgstr ""
-
-#: ../content/pages/faq.md:block 35 (paragraph)
-msgid "In other cases, depending on your courage, try:"
-msgstr ""
-
-#: ../content/pages/faq.md:block 36 (header)
-msgid "Disable JSS for this domain"
-msgstr ""
-
-#: ../content/pages/faq.md:block 37 (paragraph)
-msgid ""
-"You can disable JSS for all pages on the visited domain by turning JSS off:"
-msgstr ""
-
-#: ../content/pages/faq.md:block 38 (paragraph)
-msgid "![Turn JSS off](/images/faq/jss_off.png)"
-msgstr ""
-
-#: ../content/pages/faq.md:block 40 (paragraph)
-msgid "Advanced users can change JSS level:"
-msgstr ""
-
-#: ../content/pages/faq.md:block 41 (ordered list)
-msgid ""
-"Spoofing API call results takes some resources. If you see that the page "
-"does not try to fingerprint you, you might want to disable all "
-"fingerprinting protection."
-msgstr ""
-
-#: ../content/pages/faq.md:block 41 (ordered list)
-msgid "Click the `Modify` button next to the JavaScript Shield label."
-msgstr ""
-
-#: ../content/pages/faq.md:block 41 (ordered list)
-msgid ""
-"Select `Turn fingerprinting protection off level`. This will keep security-"
-"related [wrappers](#what-is-a-wrapper), but all fingerprinting protection "
-"will be disabled."
-msgstr ""
-
-#: ../content/pages/faq.md:block 42 (paragraph)
-msgid "![Turn JSS fingerprinting protection off](/images/faq/jss_low.png)"
-msgstr ""
-
-#: ../content/pages/faq.md:block 43 (paragraph)
-msgid ""
-"You can create your own JSS protection levels on the `Global settings` page."
-msgstr ""
-
-#: ../content/pages/faq.md:block 44 (header)
-msgid "Tweak JSS for this domain"
-msgstr ""
-
-#: ../content/pages/faq.md:block 45 (paragraph)
-msgid ""
-"Sometimes you will want to tweak JSS a little bit. For example, you "
-"generally do not need audio. Still, you might want to make a call on some "
-"pages. Or, you generally do not want to reveal your location, but you want "
-"to use a map page to navigate. Occasionally, a JSS can modify an API in a "
-"way that breaks a page. In that case, you might want to tweak your "
-"protection level."
-msgstr ""
-
-#: ../content/pages/faq.md:block 46 (ordered list)
-msgid "Click the `Detail tweaks of JS Shield for this site` button."
-msgstr ""
-
-#: ../content/pages/faq.md:block 47 (paragraph)
-msgid "![Go to tweaking JSS mode](/images/faq/jss_tweak_start.png)"
-msgstr ""
-
-#: ../content/pages/faq.md:block 48 (paragraph)
-msgid ""
-"The JSS section will expand. The applied protection groups are sorted "
-"depending on the number of calls of each API group. Typically, you will want"
-" to tweak the settings of one of the groups with the most calls. See the "
-"highlighted column:"
-msgstr ""
-
-#: ../content/pages/faq.md:block 49 (paragraph)
-msgid "![Tweaking JSS mode](/images/faq/jss_tweak_sorting.png)"
-msgstr ""
-
-#: ../content/pages/faq.md:block 50 (ordered list)
-msgid "Before you tweak any wrapping group, see the description."
-msgstr ""
-
-#: ../content/pages/faq.md:block 50 (ordered list)
-msgid "Tweak the protection according to your needs."
-msgstr ""
-
-#: ../content/pages/faq.md:block 51 (paragraph)
-msgid "![Tweaking JSS mode](/images/faq/jss_tweaking.png)"
-msgstr ""
-
-#: ../content/pages/faq.md:block 52 (header)
-msgid "How can I fix videos if they fail to play or retrieve data in time?"
-msgstr ""
-
-#: ../content/pages/faq.md:block 53 (paragraph)
-msgid ""
-"JShelter reimplements more than 100 JavaScript APIs. However, pages can use "
-"several ways to access the same API. Unfortunately, browsers do not allow "
-"patching every possibility consistently through a simple call. Web Workers "
-"are one of the possibilities to access the APIs (see further "
-"[threats](#what-are-web-workers-and-what-are-the-threats-that-i-face)). Our "
-"ultimate goal is to patch APIs consistently. However, patching Web Worker is"
-" tricky, and we have yet to find a way to patch Workers seamlessly. Our "
-"ultimate goal was to replace Workers with synchronous code. However, so far,"
-" we offer only policies that either disable Workers or make them inoperable."
-msgstr ""
-
-#: ../content/pages/faq.md:block 54 (paragraph)
-msgid ""
-"We are [working](https://pagure.io/JShelter/webextension/issue/43) on "
-"[improvements](https://pagure.io/JShelter/webextension/issue/80). Currently,"
-" we patch Web Workers in the `Recommended` level (`Remove` policy). "
-"Nevertheless, the method breaks Web Workers, and they cannot be used for "
-"benign purposes. The page also cannot detect breakage to limit the "
-"fingerprintability of the browsers."
-msgstr ""
-
-#: ../content/pages/faq.md:block 55 (paragraph)
-msgid ""
-"JShelter users reported that video streaming servers are often affected. We "
-"encountered pages that detect the presence of Web Worker support in browsers"
-" and provide polyfills if they do not detect Web Worker support. The "
-"`Remove` WebWorker policy is ideal for such servers. The page can easily "
-"detect missing Web Worker support. Suppose a page provides its own "
-"alternatives like polyfills. The alternatives do not have the powers of Web "
-"Workers, so you can make the page work at the cost of increased "
-"fingerprintability. Use FPD to evaluate that threat."
-msgstr ""
-
-#: ../content/pages/faq.md:block 56 (paragraph)
-msgid ""
-"If you believe the server operator and their partners not to misuse Web "
-"Workers to access original APIs and [other ways](#what-are-web-workers-and-"
-"what-are-the-threats-that-i-face), or if you do not mind, change the "
-"`WebWorker` policy from `Remove` to `Low` (in Chrome) or deactivate it "
-"completely ([in Firefox](https://pagure.io/JShelter/webextension/issue/80))."
-" Videos and other functionality requiring Web Workers should work. To change"
-" the policy, follow these steps:"
-msgstr ""
-
-#: ../content/pages/faq.md:block 57 (ordered list)
-msgid "Navigate to a page with a video you want to watch."
-msgstr ""
-
-#: ../content/pages/faq.md:block 57 (ordered list)
-msgid ""
-"Click on the JShelter badge icon (typically in the toolbar next to your "
-"navigation bar; if you cannot locate the icon, see [this question](#can-i-"
-"see-a-jshelter-badge-icon-next-to-my-navigation-bar-i-want-to-interact-with-"
-"the-extension-easily-and-avoid-going-through-settings))."
-msgstr ""
-
-#: ../content/pages/faq.md:block 57 (ordered list)
-msgid "Click on the `Modify` button."
-msgstr ""
-
-#: ../content/pages/faq.md:block 57 (ordered list)
-msgid "Click on the `Detail tweaks of JS shield for this site` button."
-msgstr ""
-
-#: ../content/pages/faq.md:block 57 (ordered list)
-msgid ""
-"Click and drag the `WebWorker` slider to the left until `Remove` is replaced"
-" by the `Low` value (Chromium-based browser) or `Unprotected` (Firefox)."
-msgstr ""
-
-#: ../content/pages/faq.md:block 57 (ordered list)
-msgid "Click on the `Refresh page` button at the top."
-msgstr ""
-
-#: ../content/pages/faq.md:block 57 (ordered list)
-msgid "Watch the video."
-msgstr ""
-
-#: ../content/pages/faq.md:block 58 (header)
-msgid ""
-"I want to use a website that uses Web Workers, but it is broken. How can I "
-"fix the site?"
-msgstr ""
-
-#: ../content/pages/faq.md:block 59 (paragraph)
-msgid ""
-"First, see the explanation of [Web Workers](#what-are-web-workers-and-what-"
-"are-the-threats-that-i-face)."
-msgstr ""
-
-#: ../content/pages/faq.md:block 60 (paragraph)
-msgid ""
-"See the [answer to the video question](#how-can-i-fix-videos-if-they-fail-"
-"to-play-or-retrieve-data-in-time)."
-msgstr ""
-
-#: ../content/pages/faq.md:block 61 (paragraph)
-msgid ""
-"If you find a website that needs WebWorker protection set to `Strict` and "
-"does not work with `Remove` or vice-versa, please let us know in the [issue "
-"tracker](https://pagure.io/JShelter/webextension/issues) or send us "
-"[e-mail](mailto:jshelter@gnu.org)."
-msgstr ""
-
-#: ../content/pages/faq.md:block 62 (header)
-msgid "User interface issues"
-msgstr ""
-
-#: ../content/pages/faq.md:block 63 (header)
-msgid ""
-"Can I see a JShelter (badge) icon next to my navigation bar? I want to "
-"interact with the extension easily and avoid going through settings."
-msgstr ""
-
-#: ../content/pages/faq.md:block 64 (paragraph)
-msgid ""
-"JShelter has a badge icon in the toolbar that allows you to open the popup. "
-"However, browsers tend to hide the icon. If you cannot see a JShelter icon "
-"to the right of the bar where you enter URLs. Try to:"
-msgstr ""
-
-#: ../content/pages/faq.md:block 65 (ordered list)
-msgid "Click on the extension icon (typically looks like a puzzle tile)."
-msgstr ""
-
-#: ../content/pages/faq.md:block 65 (ordered list)
-msgid "Pin JShelter to the toolbar."
-msgstr ""
-
-#: ../content/pages/faq.md:block 66 (paragraph)
-msgid ""
-"The figure below shows how to accomplish these two steps in Firefox and a "
-"Chromium-based browser."
-msgstr ""
-
-#: ../content/pages/faq.md:block 67 (paragraph)
-msgid ""
-"![Pin JShelter to Firefox "
-"toolbar]({attach}/images/faq/firefox_pintoolbar.png) ![Pin JShelter to a "
-"Chromium-based browser toolbar]({attach}/images/faq/chromium_pintoolbar.png)"
-msgstr ""
-
-#: ../content/pages/faq.md:block 68 (header)
-msgid ""
-"A site opened a popup window, I want to tweak settings for that window, but "
-"I do not see a badge JShelter icon there. How can I tweak JShelter settings?"
-msgstr ""
-
-#: ../content/pages/faq.md:block 69 (paragraph)
-msgid "If you are using Firefox:"
-msgstr ""
-
-#: ../content/pages/faq.md:block 70 (ordered list)
-msgid "Open `about:config`, click to `Accept the Risk and Continue`,"
-msgstr ""
-
-#: ../content/pages/faq.md:block 70 (ordered list)
-msgid "set `browser.link.open_newwindow` to `3`,"
-msgstr ""
-
-#: ../content/pages/faq.md:block 70 (ordered list)
-msgid "set `browser.link.open_newwindow.restriction` to `0`."
-msgstr ""
-
-#: ../content/pages/faq.md:block 71 (paragraph)
-msgid ""
-"This will force all popup windows to open in a new tab, meaning the JShelter"
-" settings could be adjusted easily everywhere."
-msgstr ""
-
-#: ../content/pages/faq.md:block 72 (header)
-msgid "Why do I see so many notifications from JShelter?"
-msgstr ""
-
-#: ../content/pages/faq.md:block 73 (paragraph)
-msgid ""
-"Generally speaking, you should see only a few notifications by JShelter. The"
-" default settings are tailored to give the user critical information about "
-"JShelter behavior and its possible changes to the page's ability to make "
-"network requests that often break the page's behavior."
-msgstr ""
-
-#: ../content/pages/faq.md:block 74 (paragraph)
-msgid ""
-"We suggest installing a tracker blocker like uBlock Origin. The blocker will"
-" eliminate the most common security and privacy threats."
-msgstr ""
-
-#: ../content/pages/faq.md:block 75 (paragraph)
-msgid ""
-"Also, see [the question on NBS notifications](#i-am-seeing-too-many-nbs-"
-"notifications)."
-msgstr ""
-
-#: ../content/pages/faq.md:block 76 (header)
-msgid "I am seeing too many NBS notifications"
-msgstr ""
-
-#: ../content/pages/faq.md:block 77 (paragraph)
-msgid ""
-"NBS protects from attacks that occur very rarely. JShelter users often "
-"complain about too many notifications when they employ DNS-based blocking. "
-"DNS-blocking resolver resolves predefined domains to a fake IP address, "
-"usually `0.0.0.0` or `127.0.0.1` (IPv4) and `::` or `::1` (IPv6). If your "
-"DNS-blocking resolver returns `127.0.0.1` and `::1`. Please reconfigure the "
-"resolver to return `0.0.0.0` or `::`."
-msgstr ""
-
-#: ../content/pages/faq.md:block 78 (ordered list)
-msgid ""
-"Depending on your OS, you will consume fewer resources. For example, Windows"
-" machines do not create any TCP stream when a website connects to `0.0.0.0` "
-"or `::`, but it creates a TCP stream to `127.0.0.1` and `::1`. Hence, a "
-"remote web page can access a web server if it is running on the local "
-"machine. Note that Linux hosts try to establish a connection to a localhost "
-"port on all these addresses."
-msgstr ""
-
-#: ../content/pages/faq.md:block 78 (ordered list)
-msgid ""
-"If your DNS-based filtering returns `0.0.0.0` or `::`, it will give JShelter"
-" a report on the intentions. If it returns `127.0.0.1` or `::1`, JShelter "
-"has no way to differentiate between such DNS blocker and an attack like the "
-"one in the [blog](/localportscanning/)."
-msgstr ""
-
-#: ../content/pages/faq.md:block 79 (header)
-msgid "Browser fingerprinting"
-msgstr ""
-
-#: ../content/pages/faq.md:block 80 (header)
-msgid "What is the little lies approach to protect from fingerprinters?"
-msgstr ""
-
-#: ../content/pages/faq.md:block 81 (paragraph)
-msgid "Please see [the blog post](/farbling/)."
-msgstr ""
-
-#: ../content/pages/faq.md:block 82 (header)
-msgid ""
-"What is the difference between the little lies and white lies approach to "
-"protect from fingerprinters and farbling?"
-msgstr ""
-
-#: ../content/pages/faq.md:block 83 (paragraph)
-msgid ""
-"None. All refer to the same technique [that is explained in another "
-"question](#what-is-the-little-lies-approach-to-protect-from-fingerprinters)."
-msgstr ""
-
-#: ../content/pages/faq.md:block 84 (header)
-msgid "What JShelter configuration should I pick?"
-msgstr ""
-
-#: ../content/pages/faq.md:block 85 (paragraph)
-msgid ""
-"First, see our [blog post](/fingerprinting/). Consult also other [blog "
-"posts](/blog/) and other questions in this FAQ."
-msgstr ""
-
-#: ../content/pages/faq.md:block 86 (ordered list)
-msgid ""
-"If you want to have the same fingerprint as many users, We suggest going for"
-" Tor Browser (do not install JShelter in Tor Browser)."
-msgstr ""
-
-#: ../content/pages/faq.md:block 86 (ordered list)
-msgid ""
-"If you want to make cross-site fingerprinting linkage hard, go for the "
-"`Recommended` JShelter level. If you want better protection for the real "
-"data at the cost of having the same fingerprint on different sites, go for "
-"the `Strict` JShelter level."
-msgstr ""
-
-#: ../content/pages/faq.md:block 86 (ordered list)
-msgid "Keep NBS active."
-msgstr ""
-
-#: ../content/pages/faq.md:block 86 (ordered list)
-msgid "If you want to detect and prevent fingerprinting attempts, use FPD."
-msgstr ""
-
-#: ../content/pages/faq.md:block 87 (header)
-msgid ""
-"I have a unique fingerprint? Some properties wrapped by JShelter return "
-"random values."
-msgstr ""
-
-#: ../content/pages/faq.md:block 88 (paragraph)
-msgid "First, see our [blog post](/fingerprinting/)."
-msgstr ""
-
-#: ../content/pages/faq.md:block 89 (paragraph)
-msgid ""
-"JShelter indeed modifies some properties like WebGL strings (`renderer`, "
-"`vendor`) to random strings in the `Recommended` level. JShelter also does "
-"not modify random identifiers of microphones and cameras. All these "
-"properties contain random strings that uniquely identify your browser "
-"session."
-msgstr ""
-
-#: ../content/pages/faq.md:block 90 (paragraph)
-msgid ""
-"JShelter provides different lies on different domains, so cross-domain "
-"linking is hard. But remember that a single domain can link all your "
-"activities during a browser session. If you do not want JShelter to generate"
-" the random strings, use `Strict` protection (but see [other FAQ "
-"entries](#browser-fingerprinting))."
-msgstr ""
-
-#: ../content/pages/faq.md:block 91 (paragraph)
-msgid ""
-"We are [considering](https://pagure.io/JShelter/webextension/issue/68) "
-"adding better control for the little lies approach."
-msgstr ""
-
-#: ../content/pages/faq.md:block 92 (paragraph)
-msgid ""
-"We are also [considering](https://pagure.io/JShelter/webextension/issue/69) "
-"replacing the random strings of the Web GL API with real-world strings. "
-"However, we do not have such a database. We are also worried about creating "
-"inconsistencies if we apply invalid combinations of real-world strings. As "
-"creating the real-world database would take a lot of time, and a dedicated "
-"fingerprinter might reveal the inconsistencies anyway, we do not actively "
-"work on the issue."
-msgstr ""
-
-#: ../content/pages/faq.md:block 93 (header)
-msgid "Is browser fingerprinting a real threat?"
-msgstr ""
-
-#: ../content/pages/faq.md:block 94 (paragraph)
-msgid ""
-"More than 100 advertisement companies reveal in the [adtech transparency a "
-"consent framework](https://www.fit.vutbr.cz/~polcak/tcf/tcf2.html) that they"
-" actually actively scan device characteristics for identification: devices "
-"can be identified based on a scan of the device's unique combination of "
-"characteristics. Vendors can create an identifier using data collected via "
-"actively scanning a device for specific characteristics, e.g., installed "
-"fonts or screen resolution, use such an identifier to re-identify a device."
-msgstr ""
-
-#: ../content/pages/faq.md:block 95 (paragraph)
-msgid ""
-"![TCF participants actively scanning devices to create a "
-"fingerprint](https://www.fit.vutbr.cz/~polcak/tcf/graphs/v2sf2.svg)"
-msgstr ""
-
-#: ../content/pages/faq.md:block 96 (paragraph)
-msgid ""
-"See papers like [Browser Fingerprinting: A "
-"survey](https://arxiv.org/pdf/1905.01051.pdf), [Fingerprinting the "
-"Fingerprinters](https://uiowa-irl.github.io/FP-Inspector/) or [The Elephant "
-"in the Background](https://fpmon.github.io/fingerprinting-"
-"monitor/files/FPMON.pdf)."
-msgstr ""
-
-#: ../content/pages/faq.md:block 97 (header)
-msgid "Does FPD collect a list of pages/origins that fingerprinted me?"
-msgstr ""
-
-#: ../content/pages/faq.md:block 98 (paragraph)
-msgid ""
-"No, FPD does not store any information. Each page load starts a new "
-"detection that is not dependent on previous interactions between the browser"
-" and the site."
-msgstr ""
-
-#: ../content/pages/faq.md:block 99 (header)
-msgid ""
-"When FPD detects that an origin tried to fingerprint me, does it mean that "
-"the extension will apply stronger protection like switching to the `Strict` "
-"JSS level or applying the blocking of HTTP requests initiated by the domain?"
-msgstr ""
-
-#: ../content/pages/faq.md:block 100 (paragraph)
-msgid "No."
-msgstr ""
-
-#: ../content/pages/faq.md:block 101 (paragraph)
-msgid ""
-"First of all, the `Strict` JSS level does not mean stronger protection from "
-"fingerprinting. In fact, it makes your fingerprint stable. We do not "
-"recommend using `Strict` level as an anti-fingerprinting mechanism."
-msgstr ""
-
-#: ../content/pages/faq.md:block 102 (paragraph)
-msgid ""
-"Secondly, fingerprinting is quite common on login pages. If one page "
-"fingerprints you, it does not mean that all pages are going to fingerprint "
-"you."
-msgstr ""
-
-#: ../content/pages/faq.md:block 103 (paragraph)
-msgid ""
-"Thirdly, the fingerprinting script may be loaded into the page irregularly. "
-"We want to prevent blocking the site when no fingerprinting is detected."
-msgstr ""
-
-#: ../content/pages/faq.md:block 104 (paragraph)
-msgid ""
-"If you want to switch to a different level for the website, you can do so "
-"manually. We do not recommend such action."
-msgstr ""
-
-#: ../content/pages/faq.md:block 105 (header)
-msgid ""
-"My bank (or another trusted site) fingerprinted me during a login attempt. "
-"Should I worry?"
-msgstr ""
-
-#: ../content/pages/faq.md:block 106 (paragraph)
-msgid ""
-"Browser fingerprinting is a common part of multi-factor authentication. The "
-"provider tries to protect your account. So you should not worry, but you "
-"might be forced to deactivate FPD for that site. However, we suggest that "
-"you do not turn off JavaScript Shield and its anti-fingerprinting "
-"protections."
-msgstr ""
-
-#: ../content/pages/faq.md:block 107 (paragraph)
-msgid ""
-"From the European perspective, [WP29 "
-"clarified](https://ec.europa.eu/justice/article-29/documentation/opinion-"
-"recommendation/files/2014/wp224_en.pdf) (use case 7.5) that user-centric "
-"security can be viewed as strictly necessary to provide a web service. So it"
-" seems likely that browser fingerprinting for security reasons does trigger "
-"the ePrivacy exception, and user consent is not necessary. Depending on the "
-"circumstances, a fingerprint can be personal data. GDPR might also apply. "
-"GDPR lists security as a possible legitimate interest of a data controller, "
-"see recital 49. Nevertheless, whether all fingerprinting is proportionate is"
-" an open question."
-msgstr ""
-
-#: ../content/pages/faq.md:block 108 (paragraph)
-msgid ""
-"We understand that our users do not want to give information about their "
-"devices. Hence, we suggest having JavaScript Shield active on fingerprinting"
-" sites. It is up to you if you want to provide as little information as "
-"possible (`Strict` level), want to have a different fingerprint every visit "
-"(`Recommended` level, keep in mind that you are providing your login, so "
-"your actions are linkable), or you want to create your own level."
-msgstr ""
-
-#: ../content/pages/faq.md:block 109 (header)
-msgid "Do you protect against font enumeration fingerprinting?"
-msgstr ""
-
-#: ../content/pages/faq.md:block 110 (paragraph)
-msgid ""
-"No. We currently do not have a consistent method that spoofs fonts reliably."
-" If you are concerned about font enumeration, you can track the relevant "
-"JShelter [issue](https://pagure.io/JShelter/webextension/issue/60)."
-msgstr ""
-
-#: ../content/pages/faq.md:block 111 (paragraph)
-msgid ""
-"If you are using Firefox and want your fonts hidden consistently, activate "
-"resistFingerprinting. However, cosider [the interaction between JShelter and"
-" resistFingerprinting](#i-am-using-firefox-fingerprinting-protection-"
-"resistfingerprinting-should-i-continue-should-i-turn-firefox-fingerprinting-"
-"protection-on)."
-msgstr ""
-
-#: ../content/pages/faq.md:block 112 (header)
-msgid "Does JShelter completely prevent browser fingerprinting?"
-msgstr ""
-
-#: ../content/pages/faq.md:block 113 (paragraph)
-msgid ""
-"No. See the [threat model](/threatmodel/). As explained there, JShelter "
-"applies reasonable precautions but:"
-msgstr ""
-
-#: ../content/pages/faq.md:block 114 (ordered list)
-msgid "There is no clear boundary between fingerprinting and benign behavior."
-msgstr ""
-
-#: ../content/pages/faq.md:block 114 (ordered list)
-msgid ""
-"A fingerprinter might deploy focused attacks. While we try to deploy "
-"undetectable and reasonable countermeasures, expect that a focused and "
-"motivated attacker will be able to detect JShelter users."
-msgstr ""
-
-#: ../content/pages/faq.md:block 114 (ordered list)
-msgid ""
-"We expect that users will run FPD and JSS in parallel. As both protect from "
-"fingerprinting differently, they complement each other."
-msgstr ""
-
-#: ../content/pages/faq.md:block 115 (paragraph)
-msgid ""
-"Also, read [the other questions in the browser fingerprinting "
-"section](#browser-fingerprinting)."
-msgstr ""
-
-#: ../content/pages/faq.md:block 116 (header)
-msgid "Other protections by JShelter"
-msgstr ""
-
-#: ../content/pages/faq.md:block 117 (header)
-msgid "What are Web Workers, and what are the threats that I face?"
-msgstr ""
-
-#: ../content/pages/faq.md:block 118 (paragraph)
-msgid ""
-"In essence, Web Workers are a threat to JShelter users for two reasons:"
-msgstr ""
-
-#: ../content/pages/faq.md:block 119 (ordered list)
-msgid ""
-"They allow access to some of the modified APIs. There is no simple call that"
-" JShelter can issue to apply the modifications to Web Workers. So, if you do"
-" not apply WebWorker protection, you risk that Web Workers can remove other "
-"protections."
-msgstr ""
-
-#: ../content/pages/faq.md:block 119 (ordered list)
-msgid ""
-"They increase the capabilities of attackers. For example, malicious actors "
-"can install long-lived proxies to the browser."
-msgstr ""
-
-#: ../content/pages/faq.md:block 120 (paragraph)
-msgid ""
-"For more details, see [Web Worker "
-"documentation](https://developer.mozilla.org/en-"
-"US/docs/Web/API/Web_Workers_API/Using_web_workers), the [explanation of "
-"using Web Workers as Man-In-The-Middle "
-"proxy](https://betterprogramming.pub/man-in-the-middle-attacks-via-"
-"javascript-service-workers-52647ac929a2), papers like [Assessing the threat "
-"of web worker distributed "
-"attacks](https://www.researchgate.net/publication/313953354_Assessing_the_threat_of_web_worker_distributed_attacks),"
-" and other [works](http://www.diva-"
-"portal.se/smash/get/diva2:1218197/FULLTEXT01.pdf)."
-msgstr ""
-
-#: ../content/pages/faq.md:block 121 (header)
-msgid "What is Network Boundary Shield (NBS)?"
-msgstr ""
-
-#: ../content/pages/faq.md:block 122 (paragraph)
-msgid ""
-"Your browser can be instructed by the creators of the visited page (or "
-"malicious actors that successfully inserted their code into the visited "
-"page) to act as an intermediary device that creates connections to other "
-"devices in the network. NBS detects and prevents such attacks, see its "
-"[dedicated page](/nbs/) and our [blog post](/localportscanning/) for more "
-"information."
-msgstr ""
-
-#: ../content/pages/faq.md:block 123 (header)
-msgid ""
-"My device has a lot of sensors. Are these accessible by web pages? Does "
-"JShelter help me?"
-msgstr ""
-
-#: ../content/pages/faq.md:block 124 (paragraph)
-msgid ""
-"Depending on your browser and your settings, web pages can read sensors "
-"leading to various attacks that include revealing hidden information, and "
-"fingerprinting. JShelter [deals with sensors](/sensorapi/)."
-msgstr ""
-
-#: ../content/pages/faq.md:block 125 (header)
-msgid "Does JShelter help me against attacks exploiting hardware faults?"
-msgstr ""
-
-#: ../content/pages/faq.md:block 126 (paragraph)
-msgid ""
-"Yes, JShelter modifies all timestamps, which limits the precision of time "
-"measurements. JShelter rounds the timestamps and adds random number of "
-"milliseconds to the rounded value, preserving the monotony of the "
-"timestamps. The modifications also remove the possibility of [detecting "
-"clock "
-"skew](https://www.jucs.org/jucs_21_9/clock_skew_based_computer/jucs_21_09_1210_1233_polcak.pdf)"
-" of your device quickly. See [our paper](#what-is-the-proper-way-to-cite-"
-"jshelter-in-a-paper) for more details."
-msgstr ""
-
-#: ../content/pages/faq.md:block 127 (header)
-msgid "Does JShelter protect my IP address?"
-msgstr ""
-
-#: ../content/pages/faq.md:block 128 (paragraph)
-msgid ""
-"No, and it never will. You need to find a VPN, Tor, or a similar technique "
-"to hide your IP address."
-msgstr ""
-
-#: ../content/pages/faq.md:block 129 (header)
-msgid "Does JShelter replace a tracker blocker?"
-msgstr ""
-
-#: ../content/pages/faq.md:block 130 (paragraph)
-msgid ""
-"No, many extensions specialize in list-based tracking. We consider list-"
-"based tracking out-of-scope of the JShelter mission. You should keep using a"
-" tracker blocker like [uBlock "
-"Origin](https://github.com/gorhill/uBlock#ublock-origin) in parallel with "
-"JShelter."
-msgstr ""
-
-#: ../content/pages/faq.md:block 131 (header)
-msgid ""
-"Does JShelter modify identifiers in cookies, web storage or other tracking "
-"IDs?"
-msgstr ""
-
-#: ../content/pages/faq.md:block 132 (paragraph)
-msgid ""
-"Not directly. Use other tools to block such trackers. Firefox's built-in "
-"protection mechanisms and tracker blockers are excellent tools that "
-"complement JShelter well."
-msgstr ""
-
-#: ../content/pages/faq.md:block 133 (paragraph)
-msgid ""
-"Nevertheless, some IDs might be derived based on fingerprinting scripts. In "
-"that case, JShelter will modify such ID, and depending on the implementation"
-" and your JShelter settings, your identity might change for each visited "
-"origin and each session."
-msgstr ""
-
-#: ../content/pages/faq.md:block 134 (header)
-msgid "Interactions between JShelter and other similar tools"
-msgstr ""
-
-#: ../content/pages/faq.md:block 135 (header)
-msgid "What other extension do you recommend to run along JShelter?"
-msgstr ""
-
-#: ../content/pages/faq.md:block 136 (paragraph)
-msgid ""
-"We consider a tracker blocker like [uBlock "
-"Origin](https://github.com/gorhill/uBlock#ublock-origin) as a must. It will "
-"make your browsing faster, make your pages clean, and improve your privacy. "
-"Nevertheless, it is easy to evade blockers. The malicious web server needs "
-"to change the URL of the script. JShelter developers encountered several "
-"malicious scripts that evaded common lists. Hence, blocklist-based filtering"
-" is beneficial as a first-line defense. However, blockers are not enough as "
-"niche cases evade the blockers."
-msgstr ""
-
-#: ../content/pages/faq.md:block 137 (paragraph)
-msgid ""
-"Web extensions like [NoScript Security Suite](https://noscript.net/) or "
-"[uMatrix](https://github.com/gorhill/uMatrix) allow users to block "
-"JavaScript or other content, either completely or per domain. However, the "
-"user needs to evaluate which domains to allow scripts. [HTTP Archive "
-"reports](https://httparchive.org/reports/page-"
-"weight?start=earliest&end=latest&view=list#reqJs) that an average page "
-"includes (at the time of writing this text) 22 external requests (21 "
-"requests for mobile devices). Many pages depend on JavaScript. Users must "
-"select what content to trust. A typical page contains resources from many "
-"external sources, so such a user requires excellent knowledge. Moreover, "
-"malicious code may be only a part of a resource; the rest of the resource "
-"can be necessary for correct page functionality. We believe that web "
-"extensions like NoScript Security Suite and uMatrix origin are good but do "
-"not protect the user from accidentally allowing malicious code. The NoScript"
-" Suite main developer is a part of the JShelter team, and JShelter shares a "
-"lot of code with NoScript."
-msgstr ""
-
-#: ../content/pages/faq.md:block 138 (paragraph)
-msgid ""
-"We suggest that you use other extensions like [Cookie "
-"AutoDelete](https://github.com/Cookie-AutoDelete/Cookie-AutoDelete), "
-"[Decentraleyes](https://decentraleyes.org), "
-"[ClearURLs](https://docs.clearurls.xyz). All these extensions are important "
-"in making your browser leak as little data as possible, and all these "
-"protections are out-of-scope of JShelter."
-msgstr ""
-
-#: ../content/pages/faq.md:block 139 (paragraph)
-msgid ""
-"Also consider that [web extensions cannot hide your IP address](#does-"
-"jshelter-protect-my-ip-address)."
-msgstr ""
-
-#: ../content/pages/faq.md:block 140 (header)
-msgid "I already have a blocking extension installed. Do I need JShelter?"
-msgstr ""
-
-#: ../content/pages/faq.md:block 141 (paragraph)
-msgid ""
-"Blocking extensions are typically based on a list of commonly known "
-"malicious URLs. Hence, someone needs to discover such a URL first. Some "
-"malicious URLs are never added to blocking lists because they were not "
-"discovered. Others might be added to a small or specialized list only. "
-"JShelter protects you from some threats not yet added to the lists."
-msgstr ""
-
-#: ../content/pages/faq.md:block 142 (paragraph)
-msgid ""
-"Some login pages fingerprint you during the login process. But you might "
-"want to keep your specific device configuration private from such a page. "
-"JShelter can limit (`Strict` level) or fake (`Recommended` level) "
-"information commonly used for browser fingerprinting."
-msgstr ""
-
-#: ../content/pages/faq.md:block 143 (header)
-msgid ""
-"I am using Firefox Fingerprinting Protection (resistFingerprinting). Should "
-"I continue? Should I turn Firefox Fingerprinting Protection on?"
-msgstr ""
-
-#: ../content/pages/faq.md:block 144 (paragraph)
-msgid ""
-"Mozilla is working on integrating fingerprinting resisting techniques [from "
-"Torbrowser](https://bugzilla.mozilla.org/show_bug.cgi?id=1329996) to Firefox"
-" (Firefox Fingerprinting Protection, also known as resist fingerprinting). "
-"However, the work is not done. Firefox Fingerprinting Protection tries to "
-"confuse simple fingerprinters with random data. Sophisticated fingerprinters"
-" will create a [homogeneous fingerprint](/fingerprinting/). It is a research"
-" question if the homogeneous fingerprint strategy makes sense before it is "
-"adopted by all users."
-msgstr ""
-
-#: ../content/pages/faq.md:block 145 (paragraph)
-msgid ""
-"Moreover, inconsistencies arise. For example, Torbrowser does not implement "
-"WebGL. As Firefox adopts fingerprinting protections from Torbrowser, Firefox"
-" modifies readings from 2D canvas and does not modify WebGL canvas. That "
-"creates a false sense of protection. JShelter modifies 2D and WebGL canvas "
-"consistently."
-msgstr ""
-
-#: ../content/pages/faq.md:block 146 (paragraph)
-msgid ""
-"Firefox Fingerprinting Protection may be useful for cases like having an "
-"ordinary laptop with default settings that changes IP addresses a lot. But "
-"if you like to have the same fingerprint as many other users, we suggest "
-"that you use Tor Browser."
-msgstr ""
-
-#: ../content/pages/faq.md:block 147 (paragraph)
-msgid ""
-"You cannot tweak Firefox Fingerprinting Protection. You must activate all or"
-" nothing. JShelter provides options to modify behavior per domain."
-msgstr ""
-
-#: ../content/pages/faq.md:block 148 (header)
-msgid "Should I install JShelter if I am using Brave browser?"
-msgstr ""
-
-#: ../content/pages/faq.md:block 149 (paragraph)
-msgid ""
-"Many JShelter protections come from Brave. While JShelter offers some "
-"additional protections, the key parts are shared with Brave. You should not "
-"use JavaScript Shield, or you should tweak its levels to remove duplicates. "
-"You should use the Network Boundary Shield and Fingerprint Detector. While "
-"we keep a close eye on Brave protection, we do not offer any protection "
-"specifically tailored for Brave. If you have one, please let us know."
-msgstr ""
-
-#: ../content/pages/faq.md:block 150 (header)
-msgid ""
-"I am using some other anti-fingerprinting extension. Should I continue? "
-"Should I combine such extensions?"
-msgstr ""
-
-#: ../content/pages/faq.md:block 151 (paragraph)
-msgid ""
-"You should consider (at least) the following. But first, see our blog post "
-"on [fingerprinting](/fingerprinting/)."
-msgstr ""
-
-#: ../content/pages/faq.md:block 152 (paragraph)
-msgid ""
-"JSS modifies your fingerprint while FPD detects or prevents (if allowed) "
-"fingerprinting. If you combine more approaches to modify the fingerprint, "
-"the results are not predictable. All extensions might modify the same or "
-"similar data, or they might modify different APIs. If you use multiple "
-"approaches that focus on different APIs, you might be less fingerprintable. "
-"However, you might as well use a unique combination and be easily "
-"fingerprintable by a focused or advanced fingerprinter."
-msgstr ""
-
-#: ../content/pages/faq.md:block 153 (paragraph)
-msgid ""
-"Let us see an example. Suppose that you install an extension A that modifies"
-" the content of the canvas element. As JShelter modifies only data during "
-"reading from canvas, it will apply its countermeasures after the "
-"countermeasures of A. In `Strict` level, it will override all modifications "
-"by A. The little lies approach would slightly modify the modifications of A."
-" That would likely be pointless or even counterproductive."
-msgstr ""
-
-#: ../content/pages/faq.md:block 154 (paragraph)
-msgid ""
-"Now, consider another extension B that modifies the read data as well. Both "
-"extensions try to change the same APIs, which likely creates a race "
-"condition on which defense mechanism wins. If it is indeed the race "
-"condition, you may be fingerprintable better as the one who uses both B and "
-"JShelter or less because the fingerprinter sees different fingerprints. "
-"Which one is correct depends on how smart and focused the fingerprinter is."
-msgstr ""
-
-#: ../content/pages/faq.md:block 155 (paragraph)
-msgid ""
-"Jshelter tries to apply consistent modifications. However, if B modifies "
-"only a subset of APIs that JShelter modifies, and an advanced fingerprinter "
-"can misuse that information to improve the fingerprint."
-msgstr ""
-
-#: ../content/pages/faq.md:block 156 (paragraph)
-msgid ""
-"If you use more approaches similar to FPD, they will likely not interact "
-"badly with each other."
-msgstr ""
-
-#: ../content/pages/faq.md:block 157 (paragraph)
-msgid ""
-"You can tweak JShelter to apply only some protections. For example, by "
-"creating your own JSS levels. You can also use the \"Turn fingerprinting "
-"protection off\" built-in level to keep the non-fingerprinting "
-"countermeasures. You can also turn JSS off and benefit from FPD and NBS."
-msgstr ""
-
-#: ../content/pages/faq.md:block 158 (paragraph)
-msgid ""
-"JShelter includes advanced techniques through "
-"[NSCL](https://noscript.net/commons-library) to inject API [wrappers](#what-"
-"is-a-wrapper) in time and reliably. Other extensions might not apply their "
-"protection reliably. See also [the question](#i-saw-several-extensions-that-"
-"claim-that-it-is-not-possible-to-modify-the-javascript-environment-reliably-"
-"are-you-aware-of-the-firefox-bug-1267027) on [Firefox bug "
-"1267027](https://bugzilla.mozilla.org/show_bug.cgi?id=1267027)."
-msgstr ""
-
-#: ../content/pages/faq.md:block 159 (paragraph)
-msgid ""
-"Most other tools focus on [homogeneous fingerprints](/fingerprinting/). By "
-"running the `Recommended` JShelter JSS level, you will modify the "
-"fingerprint and create a very small group, likely consisting only of you. "
-"Nevertheless, some fingerprinters can be confused even in that case, so you "
-"might be less identifiable by such dumb fingerprinters."
-msgstr ""
-
-#: ../content/pages/faq.md:block 160 (paragraph)
-msgid ""
-"Suppose a dumb fingerprinter that creates a single number by combining all "
-"fingerprintable data. As JShelter modifies the APIs differently in each "
-"session and on each domain. There is no point in installing other "
-"fingerprint-modifying extensions."
-msgstr ""
-
-#: ../content/pages/faq.md:block 161 (paragraph)
-msgid ""
-"Suppose a more clever fingerprinter that somehow analyses the "
-"fingerprintable data. It might detect that you use JShelter or a similar "
-"approach. However, it is possible that the analysis fails in case of "
-"unexpected behavior of multiple extensions, so multiple extensions might "
-"help you confuse the fingerprinter."
-msgstr ""
-
-#: ../content/pages/faq.md:block 162 (paragraph)
-msgid ""
-"An even more clever fingerprinter can focus on unique traits of your "
-"extensions (that modify the page, including page decorators or extensions "
-"that include buttons to the page, like downloaders or password managers. As "
-"the JShelter's [threat model](/threatmodel/) does not protect from such "
-"fingerprinters, you will be better off if you do not let JShelter modify the"
-" fingerprint."
-msgstr ""
-
-#: ../content/pages/faq.md:block 163 (header)
-msgid ""
-"I saw several extensions that claim that it is not possible to modify the "
-"JavaScript environment reliably. Are you aware of the [Firefox bug "
-"1267027](https://bugzilla.mozilla.org/show_bug.cgi?id=1267027)"
-msgstr ""
-
-#: ../content/pages/faq.md:block 164 (paragraph)
-msgid ""
-"Yes, we are aware of the issues concerning reliable script injections before"
-" page scripts can permanently access original API calls. In fact, JShelter "
-"(then JavaScript Restrictor) [suffered from the "
-"bug](https://github.com/polcak/jsrestrictor/issues/25) for several versions."
-" JShelter integrates [NSCL](https://noscript.net/commons-library) that "
-"allows JShelter to insert its scripts reliably before page scripts start "
-"running. Hence, the APIs are guaranteed to be protected. NSCL provides a "
-"cross-browser layer that aims at modifying all ways to obtain API functions "
-"like iframes, pages protected by CSP, and others. See our "
-"[paper](https://arxiv.org/pdf/1905.01051.pdf) for more details on the "
-"integration of NSCL to JShelter."
-msgstr ""
-
-#: ../content/pages/faq.md:block 165 (header)
-msgid ""
-"How does NBS interact with proxies? Do my DNS requests leak through NBS?"
-msgstr ""
-
-#: ../content/pages/faq.md:block 166 (paragraph)
-msgid ""
-"If you are using a proxy, the attacks, which the NBS tries to prevent, go "
-"through the proxy to the local network of the proxy (but keep in mind that "
-"this might not be true for more complex configurations)."
-msgstr ""
-
-#: ../content/pages/faq.md:block 167 (paragraph)
-msgid ""
-"NBS in Chromium-based browsers works the same way as it would work without "
-"the proxy. NBS protects the local network of the proxy in that case. "
-"Depending on the deployment and exact configuration, it may also protect "
-"your local network."
-msgstr ""
-
-#: ../content/pages/faq.md:block 168 (paragraph)
-msgid ""
-"NBS in Firefox employs the DNS API that initiates DNS requests. Contextual "
-"identities allow users to go through a proxy in some tabs and not in others."
-" We decided not to perform DNS resolution in NBS for proxied requests. See "
-"<a href=\"https://pagure.io/JShelter/webextension/issue/41\">issue 41</a> "
-"and <a href=\"https://pagure.io/JShelter/webextension/issue/85\">issue "
-"85</a> for more details. We might decide to reimplement NBS in Firefox "
-"similarly to the Chromium version in the future for proxied requests. "
-"Another possible option, we might consider in the future, is adding a "
-"configuration option to allow users to opt-in to perform DNS resolution in "
-"NBS, which would be useful for users running an HTTP proxy in their local "
-"network. If you have good arguments for changing the behavior, please share "
-"them with us."
-msgstr ""
-
-#: ../content/pages/faq.md:block 169 (header)
-msgid "Limitations of supported browsers"
-msgstr ""
-
-#: ../content/pages/faq.md:block 170 (header)
-msgid "Why does JShelter/NSCL initiate web requests to ff00::?"
-msgstr ""
-
-#: ../content/pages/faq.md:block 171 (paragraph)
-msgid ""
-"First, see [question on reliable JavaScript environment "
-"modifications](#i-saw-several-extensions-that-claim-that-it-is-not-possible-"
-"to-modify-the-javascript-environment-reliably-are-you-aware-of-the-firefox-"
-"bug-1267027)."
-msgstr ""
-
-#: ../content/pages/faq.md:block 172 (paragraph)
-msgid ""
-"NSCL needs a synchronous way to transfer data between different scripts of "
-"the extension. Web Extension APIs only allow asynchronous communication. But"
-" do not worry. The request is canceled in the "
-"[code](https://github.com/hackademix/nscl/blob/40e765f0d66a10b25a27a375bc62ea141a73734f/common/SyncMessage.js#L106)."
-msgstr ""
-
-#: ../content/pages/faq.md:block 173 (paragraph)
-msgid "Additionally [ff00::]"
-msgstr ""
-
-#: ../content/pages/faq.md:block 174 (unordered list)
-msgid ""
-"is a [reserved multicast IPV6 "
-"address](https://www.iana.org/assignments/ipv6-multicast-"
-"addresses/ipv6-multicast-addresses.xhtml#ipv6-scope),"
-msgstr ""
-
-#: ../content/pages/faq.md:block 174 (unordered list)
-msgid ""
-"hence, it is not a valid HTTP endpoint (if you try to navigate "
-"http://[ff00::] the browser will always tell you that the resource is "
-"unreachable),"
-msgstr ""
-
-#: ../content/pages/faq.md:block 174 (unordered list)
-msgid ""
-"the [SyncMessage back-end cancels the "
-"webRequest](https://github.com/hackademix/nscl/blob/40e765f0d66a10b25a27a375bc62ea141a73734f/common/SyncMessage.js#L106)."
-msgstr ""
-
-#: ../content/pages/faq.md:block 175 (paragraph)
-msgid ""
-"Some tools can see such a request, but it will never leave your browser."
-msgstr ""
-
-#: ../content/pages/faq.md:block 176 (header)
-msgid "Does NBS work the same way in Firefox and Chromium-based browsers?"
-msgstr ""
-
-#: ../content/pages/faq.md:block 177 (paragraph)
-msgid ""
-"No. Firefox allows webextensions to perform DNS resolution of the domain "
-"name that the browser is about to get information from. The resolution of "
-"the DNS name to an IP address is crucial for FPD. As Firefox allows to "
-"perform the resolution before any request leaves the browser, JShelter can "
-"prevent each attempt to cross the network boundary."
-msgstr ""
-
-#: ../content/pages/faq.md:block 178 (paragraph)
-msgid ""
-"Chromium-based browsers do not offer the DNS resolution APIs. JShelter "
-"collects resolution results in a cache that is filled during the processing "
-"of each request (after the browser makes the request). That means that the "
-"first request for each domain name goes through. JShleter blocks all "
-"subsequent requests only."
-msgstr ""
-
-#: ../content/pages/faq.md:block 179 (paragraph)
-msgid ""
-"Keep in mind that an adversary can change the domain with each request. For "
-"example, the attacker can use a.attacker.com, b.a.attacker.com, "
-"c.b.a.attacker.com in sequence for its requests to go through. So it is easy"
-" for an attacker to bypass NBS. In practice, we know about attackers that do"
-" not change domain names (for example, see [our blog](/localportscanning/))."
-" So we keep the NBS in Chromium-based browsers, even though it is not "
-"perfect."
-msgstr ""
-
-#: ../content/pages/faq.md:block 180 (header)
-msgid "Do you support Firefox for Android?"
-msgstr ""
-
-#: ../content/pages/faq.md:block 181 (paragraph)
-msgid ""
-"We tested JShelter in Firefox for Android in the past and it worked as "
-"expected. We do not test JShelter in Firefox for Android regularly but a "
-"volunteer that tracks the status of JShelter in Firefox for Android is "
-"welcomed."
-msgstr ""
-
-#: ../content/pages/faq.md:block 182 (header)
-msgid ""
-"I cannot see JShelter listed in the addons supported by Firefox for Android."
-msgstr ""
-
-#: ../content/pages/faq.md:block 183 (paragraph)
-msgid ""
-"For whatever reason, Mozilla decided to only present [a small number of "
-"curated extensions](https://support.mozilla.org/en-US/kb/find-and-install-"
-"add-ons-firefox-android) in their mobile application by default. There are "
-"some great extensions there like uBlock Origin, NoScript, and DarkReader, "
-"but JShelter was not one of them."
-msgstr ""
-
-#: ../content/pages/faq.md:block 184 (paragraph)
-msgid ""
-"You should be able to workaround the limitations by creating a [collection "
-"with JShelter](https://www.androidpolice.com/install-add-on-extension-"
-"mozilla-firefox-android/)."
-msgstr ""
-
-#: ../content/pages/faq.md:block 185 (paragraph)
-msgid ""
-"A change in the policy of the default extensions listed by Addons "
-"Mozilla.org is out of our control."
-msgstr ""
-
-#: ../content/pages/faq.md:block 186 (header)
-msgid "Other questions"
-msgstr ""
-
-#: ../content/pages/faq.md:block 187 (header)
-msgid "What is a wrapper?"
-msgstr ""
-
-#: ../content/pages/faq.md:block 188 (paragraph)
-msgid ""
-"Wrapper is typically a small block of code that JShelter attach to some of "
-"the APIs offered by the browser. These code typically reads the original "
-"value to modify that before returning to the caller. Page scripts cannot "
-"side-step the wrappers to get direct access to the original API. "
-"Nevertheless, see the [question on reliable JavaScript environment "
-"modifications](#i-saw-several-extensions-that-claim-that-it-is-not-possible-"
-"to-modify-the-javascript-environment-reliably-are-you-aware-of-the-firefox-"
-"bug-1267027)."
-msgstr ""
-
-#: ../content/pages/faq.md:block 189 (header)
-msgid "What is WebAssembly speed-up?"
-msgstr ""
-
-#: ../content/pages/faq.md:block 190 (paragraph)
-msgid ""
-"In 2023, we improved the speed of some code inside JShelter. Some of the "
-"[wrappers](#what-is-a-wrapper) were reimplemented in WebAssembly with the "
-"focus on providing the same results as the original JavaScript-only "
-"wrappers."
-msgstr ""
-
-#: ../content/pages/faq.md:block 191 (paragraph)
-msgid ""
-"Unless hit by Chrome-bug that prevents injecting WebAssembly wrappers to "
-"some pages, WebAssembly wrappers are enabled by default. We suggest that you"
-" keep WebAssembly wrappers activated. However, you can turn off WebAssembly "
-"speed-up and return to JavaScript-only wrappers."
-msgstr ""
-
-#: ../content/pages/faq.md:block 192 (header)
-msgid "I am a web developer, can JShelter help me?"
-msgstr ""
-
-#: ../content/pages/faq.md:block 193 (paragraph)
-msgid "Possibly yes."
-msgstr ""
-
-#: ../content/pages/faq.md:block 194 (paragraph)
-msgid ""
-"First of all, you can use [FPD and its reports](/fpd/) to learn the APIs "
-"that your page calls. Of course, FPD focuses on APIs that are often misused "
-"during browser fingerprinting, so that you learn only some APIs."
-msgstr ""
-
-#: ../content/pages/faq.md:block 195 (paragraph)
-msgid ""
-"You can create JSS levels that remove some functionality like geolocation, "
-"workers, or access to sensor API to test that your page handles such "
-"browsers."
-msgstr ""
-
-#: ../content/pages/faq.md:block 196 (header)
-msgid ""
-"I am a data protection officer or I work for a data protection agency. Can "
-"JShelter help me?"
-msgstr ""
-
-#: ../content/pages/faq.md:block 197 (paragraph)
-msgid "Yes. Change JShelter configuration to passive mode:"
-msgstr ""
-
-#: ../content/pages/faq.md:block 198 (ordered list)
-msgid "*Turn JavaScript Shield off*,"
-msgstr ""
-
-#: ../content/pages/faq.md:block 198 (ordered list)
-msgid "disable blocking behaviour of [NBS](/nbs/) but keep the notifications,"
-msgstr ""
-
-#: ../content/pages/faq.md:block 198 (ordered list)
-msgid ""
-"set [FPD](/fpd/) to passive, keep the notifications on, and depending on "
-"your use case, set the detection mode to *default* or *strict*."
-msgstr ""
-
-#: ../content/pages/faq.md:block 199 (paragraph)
-msgid ""
-"Compare the information provided by NBS and FPD in notifications and [FPD "
-"report](/fpd/) to the information in the privacy policy of the tested "
-"website."
-msgstr ""
-
-#: ../content/pages/faq.md:block 200 (paragraph)
-msgid ""
-"[Let us know](mailto:jshelter@gnu.org) about any question or experience."
-msgstr ""
-
-#: ../content/pages/faq.md:block 201 (header)
-msgid "What is the proper way to cite JShelter in a paper?"
-msgstr ""
-
-#: ../content/pages/faq.md:block 202 (paragraph)
-msgid ""
-"Please cite *POLČÁK Libor, SALOŇ Marek, MAONE Giorgio, HRANICKÝ Radek and "
-"McMAHON Michael. JShelter: Give Me My Browser Back. In: Proceedings of the "
-"20th International Conference on Security and Cryptography. Rome: SciTePress"
-" - Science and Technology Publications, 2023, pp. 287-294. ISBN "
-"978-989-758-666-8.*"
-msgstr ""
-
-#: ../content/pages/faq.md:block 204 (paragraph)
-msgid ""
-"That paper has an extended version at [ArXiv "
-"paper](https://arxiv.org/abs/2204.01392). Please cite the published version "
-"if possible. We are working on other publications. We will update this "
-"answer in the future."
-msgstr ""
-
-#: ../content/pages/fpd.md:block 1 (paragraph)
-msgid "Title: Fingerprint Detector Slug: fpd"
-msgstr ""
-
-#: ../content/pages/fpd.md:block 2 (paragraph)
-msgid ""
-"Fingerprint Detector (FPD) provides heuristic analysis of fingerprinting "
-"behaviour. FPD monitors APIs that are commonly used by fingerprinters and "
-"applies a heuristic approach to detect fingerprinting behaviour in real-"
-"time. When a fingerprinting attempt is detected, FPD notifies the user. The "
-"user can configure JShelter to reactively block subsequent asynchronous HTTP"
-" requests initiated by the fingerprinting page and clear the storage "
-"facilities where the page could have stored a (partial) fingerprint. "
-"However, this behaviour may break the page. The goal of the aggressive mode "
-"is to prevent the page from uploading the full fingerprint to a server. "
-"However, the fingerprinter can gradually upload detected values and a "
-"partial fingerprint can leak from the browser."
-msgstr ""
-
-#: ../content/pages/fpd.md:block 3 (paragraph)
-msgid ""
-"The heuristic approach was chosen as many prior studies proved it to be a "
-"viable approach with a very low false-positive rate. The most challenging "
-"part of this approach is a careful selection of detection conditions. The "
-"heuristics contain two basic types of entries:"
-msgstr ""
-
-#: ../content/pages/fpd.md:block 4 (ordered list)
-msgid ""
-"JavaScript API endpoints, which are relevant for fingerprinting detection "
-"and"
-msgstr ""
-
-#: ../content/pages/fpd.md:block 4 (ordered list)
-msgid "a hierarchy of groups of related endpoints."
-msgstr ""
-
-#: ../content/pages/fpd.md:block 5 (paragraph)
-msgid ""
-"For example, FPD groups endpoints according to their semantic properties. "
-"Imagine that there are two different endpoints. Both provide hardware "
-"information about the device. FPD can assign both endpoints to a group that "
-"covers access to the same hardware properties. The heuristics allow "
-"clustering groups to other groups and creating a hierarchy of groups. "
-"Ultimately, the heuristics are a tree-like structure that computes the "
-"threat that a webpage tried to obtain enough information to compute a unique"
-" fingerprint."
-msgstr ""
-
-#: ../content/pages/fpd.md:block 6 (paragraph)
-msgid ""
-"The whole evaluation process dynamically observes the API calls performed by"
-" a web page. FPD analyses the calls themselves. Hence, the dynamic analysis "
-"overcomes any obfuscation of fingerprinting scripts."
-msgstr ""
-
-#: ../content/pages/fpd.md:block 7 (paragraph)
-msgid ""
-"FPD provides a report that explains why FPD evaluated a visited page as a "
-"fingerprinter. The report aims to educate users about fingerprinting and "
-"report why FPD notified the user and optionally blocked the page. "
-"Additionally, the report can be generated from passive observation of web "
-"page calls without any JShelter interaction with the page (no API blocking)."
-msgstr ""
-
-#: ../content/pages/fpd.md:block 8 (paragraph)
-msgid ""
-"![FPD report shows the reasoning to claim that a page is fingerprinting the "
-"browser]({attach}/images/cooperation/fpd-report.png)"
-msgstr ""
-
-#: ../content/pages/home.md:block 1 (paragraph)
-msgid "Title: Home Template: home save_as: index.html URL:"
-msgstr ""
-
-#: ../content/pages/install.md:block 1 (paragraph)
-msgid "Title: Installing"
-msgstr ""
-
-#: ../content/pages/install.md:block 2 (paragraph)
-msgid ""
-"JShelter can be installed directly through each browser's extension "
-"repository:"
-msgstr ""
-
-#: ../content/pages/install.md:block 3 (unordered list)
-msgid ""
-"[Firefox](https://addons.mozilla.org/firefox/addon/javascript-restrictor/)"
-msgstr ""
-
-#: ../content/pages/install.md:block 3 (unordered list)
-msgid ""
-"[Chrome](https://chrome.google.com/webstore/detail/javascript-"
-"restrictor/ammoloihpcbognfddfjcljgembpibcmb)"
-msgstr ""
-
-#: ../content/pages/install.md:block 3 (unordered list)
-msgid ""
-"[Opera](https://addons.opera.com/extensions/details/javascript-restrictor/)"
-msgstr ""
-
-#: ../content/pages/install.md:block 4 (paragraph)
-msgid ""
-"To compile the extension from the source code, see the [building from "
-"scratch](/build/) documentation."
-msgstr ""
-
-#: ../content/pages/integration_tests.md:block 1 (paragraph)
-msgid "Title: Instructions on how to run integration tests"
-msgstr ""
-
-#: ../content/pages/integration_tests.md:block 2 (paragraph)
-msgid ""
-"JShelter's integration tests automatically verify that JShelter wraps the "
-"supported JavaScript APIs and does not affect other attributes. You need to "
-"set up your test environment before the first test run!"
-msgstr ""
-
-#: ../content/pages/integration_tests.md:block 3 (header)
-msgid "SET UP TEST ENVIRONMENT"
-msgstr ""
-
-#: ../content/pages/integration_tests.md:block 4 (header)
-msgid "Install required programs and tools"
-msgstr ""
-
-#: ../content/pages/integration_tests.md:block 5 (paragraph)
-msgid "The integration tests depend on the following packages:"
-msgstr ""
-
-#: ../content/pages/integration_tests.md:block 6 (unordered list)
-msgid "[Python 3.5+](https://www.python.org/downloads/)"
-msgstr ""
-
-#: ../content/pages/integration_tests.md:block 6 (unordered list)
-msgid "[Python package `pytest`](https://pypi.org/project/pytest/)"
-msgstr ""
-
-#: ../content/pages/integration_tests.md:block 6 (unordered list)
-msgid "[Python package `selenium`](https://pypi.org/project/selenium/)"
-msgstr ""
-
-#: ../content/pages/integration_tests.md:block 6 (unordered list)
-msgid "[Google Chrome](https://www.google.com/chrome/) - Chromium also work."
-msgstr ""
-
-#: ../content/pages/integration_tests.md:block 6 (unordered list)
-msgid ""
-"Mozilla Firefox - Be careful, [ESR](https://www.mozilla.org/en-"
-"US/firefox/all/#product-desktop-esr), "
-"[Developer](https://www.mozilla.org/en-US/firefox/developer/), or "
-"[Nightly](https://www.mozilla.org/en-US/firefox/channel/desktop/#nightly) "
-"edition are required. The standard edition is not supported."
-msgstr ""
-
-#: ../content/pages/integration_tests.md:block 6 (unordered list)
-msgid "[Web browser drivers](#webdrivers), see below"
-msgstr ""
-
-#: ../content/pages/integration_tests.md:block 7 (paragraph)
-msgid ""
-"A [web browser driver](#webdrivers) selects the installed version of the web"
-" browser. One option is to install only a single version of each browser. "
-"The web browser's profiles must not have JShelter installed. The testing "
-"script installs JShelter by itself. We suggest that you use a separate "
-"profile for testing."
-msgstr ""
-
-#: ../content/pages/integration_tests.md:block 8 (header)
-msgid "How to install Mozilla Firefox on Linux"
-msgstr ""
-
-#: ../content/pages/integration_tests.md:block 9 (paragraph)
-msgid ""
-"We recommend downloading Firefox binaries from the "
-"[ESR](https://www.mozilla.org/en-US/firefox/all/#product-desktop-esr), "
-"[Developer](https://www.mozilla.org/en-US/firefox/developer/), or "
-"[Nightly](https://www.mozilla.org/en-US/firefox/channel/desktop/#nightly) "
-"channels to a local directories. Set `firefox_binary_location` in the test "
-"configuration accordingly."
-msgstr ""
-
-#: ../content/pages/integration_tests.md:block 10 (paragraph)
-msgid "In Ubuntu, you can install ESR following:"
-msgstr ""
-
-#: ../content/pages/integration_tests.md:block 12 (header)
-msgid "Setup web browsers"
-msgstr ""
-
-#: ../content/pages/integration_tests.md:block 13 (paragraph)
-msgid ""
-"Open Mozilla Firefox ESR and change preference "
-"`xpinstall.signatures.required` to `false` in the Firefox Configuration "
-"Editor (`about:config` page). You can follow [official Mozilla "
-"support](https://support.mozilla.org/en-US/kb/add-on-signing-in-"
-"firefox#w_what-are-my-options-if-i-want-to-use-an-unsigned-add-on-advanced-"
-"users)."
-msgstr ""
-
-#: ../content/pages/integration_tests.md:block 14 (paragraph)
-msgid ""
-"Open [testing page](https://polcak.github.io/jsrestrictor/test/test.html) "
-"and click the button *Show GPS data*. Firefox will ask you if you want to "
-"enable the page to access the location. Check the option *Remember this "
-"decision* and then click *Allow*."
-msgstr ""
-
-#: ../content/pages/integration_tests.md:block 15 (paragraph)
-msgid ""
-"The default configuration of Google Chrome is sufficient for integration "
-"tests, so the Chrome settings do not need to be changed."
-msgstr ""
-
-#: ../content/pages/integration_tests.md:block 16 (header)
-msgid "<a name=\"webdrivers\">Download web browser drivers</a>"
-msgstr ""
-
-#: ../content/pages/integration_tests.md:block 17 (paragraph)
-msgid ""
-"Selenium needs web browser drivers to control the browser. If the Selenium "
-"drivers are not in your package repository or you do not want to use drivers"
-" from your repository, download the web browser drivers for your web "
-"browsers - Google Chrome and Mozilla Firefox - and your platform - Windows "
-"and Linux."
-msgstr ""
-
-#: ../content/pages/integration_tests.md:block 18 (paragraph)
-msgid ""
-"Download the ChromeDriver from [download "
-"page](https://chromedriver.chromium.org/downloads) for Google Chrome. Select"
-" the version corresponding to the version of your Google Chrome web browser."
-" Download the correct ChromeDriver to folder "
-"`../common_files/webbrowser_drivers` with the name `chromedriver.exe` (for "
-"Windows) or `chromedriver` (for Linux). If you download an incompatible "
-"version, you will see an error during the initialization of the tests."
-msgstr ""
-
-#: ../content/pages/integration_tests.md:block 19 (paragraph)
-msgid ""
-"Download the GeckoDriver from [download "
-"page](https://github.com/mozilla/geckodriver/releases) for Mozilla Firefox. "
-"Select the version corresponding to the version of your Mozilla Firefox web "
-"browser (typically the newest version). Download the correct GeckoDriver to "
-"folder `../common_files/webbrowser_drivers` with the name `geckodriver.exe` "
-"(for Windows) or `geckodriver` (for Linux). If you download an incompatible "
-"version, you will see an error during starting tests."
-msgstr ""
-
-#: ../content/pages/integration_tests.md:block 20 (header)
-msgid "Integration tests' configuration"
-msgstr ""
-
-#: ../content/pages/integration_tests.md:block 21 (paragraph)
-msgid ""
-"You can change selected browsers, their profiles, and tested JShelter levels"
-" by modifying the file `./testing/configuration.py`."
-msgstr ""
-
-#: ../content/pages/integration_tests.md:block 22 (header)
-msgid "RUN TESTS"
-msgstr ""
-
-#: ../content/pages/integration_tests.md:block 23 (header)
-msgid "on Windows OS"
-msgstr ""
-
-#: ../content/pages/integration_tests.md:block 24 (ordered list)
-msgid ""
-"Install Windows Subsystem for Linux (WSL): https://docs.microsoft.com/en-"
-"us/windows/wsl/install-win10."
-msgstr ""
-
-#: ../content/pages/integration_tests.md:block 24 (ordered list)
-msgid ""
-"Convert EOL in the scripts `fix_manifest.sh` (in the root directory of "
-"JShelter project) and `nscl/include.sh` from Windows (CR LF) to Unix (LF) - "
-"you can use the tool `dos2unix` in WSL to convert CR LF to LF."
-msgstr ""
-
-#: ../content/pages/integration_tests.md:block 24 (ordered list)
-msgid ""
-"Open the root directory of JShelter project in WSL and run the command "
-"`make`."
-msgstr ""
-
-#: ../content/pages/integration_tests.md:block 24 (ordered list)
-msgid ""
-"Open PowerShell in folder *integration_tests* and run command: "
-"`.\\start_integration_tests.ps1`"
-msgstr ""
-
-#: ../content/pages/integration_tests.md:block 25 (paragraph)
-msgid ""
-"The script may ask you for the path into the directory where the file "
-"chrome.exe is stored and where the files of the Firefox ESR default profile "
-"are stored."
-msgstr ""
-
-#: ../content/pages/integration_tests.md:block 26 (paragraph)
-msgid ""
-"The default location of chrome.exe is: `C:\\Program Files "
-"(x86)\\Google\\Chrome\\Application` The default location of Firefox ESR "
-"profile is: "
-"`C:\\Users\\<username>\\AppData\\Roaming\\Mozilla\\Firefox\\Profiles\\<profilename>.default-"
-"esr`"
-msgstr ""
-
-#: ../content/pages/integration_tests.md:block 27 (paragraph)
-msgid ""
-"If the script does not find the needed files in the default locations, it "
-"prompts you to insert the path."
-msgstr ""
-
-#: ../content/pages/integration_tests.md:block 28 (paragraph)
-msgid ""
-"When script execution starts for the first time, OS Windows may ask you to "
-"allow Firewall Exception for this script (for Python). Click *Allow*."
-msgstr ""
-
-#: ../content/pages/integration_tests.md:block 29 (header)
-msgid "on Linux OS"
-msgstr ""
-
-#: ../content/pages/integration_tests.md:block 30 (paragraph)
-msgid ""
-"Open Terminal in folder *integration_tests* and run command: "
-"`./start_integration_tests.sh`"
-msgstr ""
-
-#: ../content/pages/integration_tests.md:block 31 (paragraph)
-msgid ""
-"The script may ask you for the path of the Firefox ESR default profile. The "
-"default location of the default profile is: "
-"`/home/<username>/.mozilla/firefox/<profilename>.default-esr`"
-msgstr ""
-
-#: ../content/pages/integration_tests.md:block 32 (paragraph)
-msgid ""
-"If the script does not find the needed files in the default location, it "
-"prompts you for the path."
-msgstr ""
-
-#: ../content/pages/levels.md:block 1 (header)
-msgid "Title: JavaScript Shield"
-msgstr ""
-
-#: ../content/pages/levels.md:block 2 (paragraph)
-msgid ""
-"JavaScript Shield modifies the behaviour of the JavaScript environment "
-"availble for the visited webpage. JShelter provides fake information to "
-"confuse fingerprinters or make webpage triggered attacks impossible or "
-"harder."
-msgstr ""
-
-#: ../content/pages/levels.md:block 3 (paragraph)
-msgid ""
-"JavaScript Shield internally consists of wrappers, small pieces of code that"
-" modify the original behaviour of a JavaScript API (a function or a "
-"property) defined by standards. The behaviour of the most of the wrappers "
-"can be divided into several categories:"
-msgstr ""
-
-#: ../content/pages/levels.md:block 4 (unordered list)
-msgid ""
-"**Precision reduction**: The original value is too precise and it is not "
-"necessary for most use cases. JavaScript Shield modifies the values so that "
-"typical and benign use cases are not affected."
-msgstr ""
-
-#: ../content/pages/levels.md:block 4 (unordered list)
-msgid ""
-"**Provide fake information**: Some wrappers provide fake information mostly "
-"to confuse fingerprinters. For example, canvas wrappers modifify the image "
-"so that the same instructions produce different result in each session and "
-"for each domain."
-msgstr ""
-
-#: ../content/pages/levels.md:block 4 (unordered list)
-msgid ""
-"**Hide information**: Some APIs provide information that is not generally "
-"needed and can be hidden from most of the pages. Depending on the API, "
-"JavaScript Shield might return an error, an empty value, or block the API "
-"completely."
-msgstr ""
-
-#: ../content/pages/levels.md:block 5 (paragraph)
-msgid ""
-"See our blog posts for more information on [browser fingerprinting counter-"
-"measures](/fingerprinting/) and [farbling](/farbling/)."
-msgstr ""
-
-#: ../content/pages/levels.md:block 6 (header)
-msgid "Protection levels"
-msgstr ""
-
-#: ../content/pages/levels.md:block 7 (paragraph)
-msgid "JShelter supports the following protection levels:"
-msgstr ""
-
-#: ../content/pages/levels.md:block 8 (unordered list)
-msgid ""
-"**Turn JavaScript Shield off**: Use for pages that you trust and you want to"
-" give them access to full APIs supported by the browser."
-msgstr ""
-
-#: ../content/pages/levels.md:block 8 (unordered list)
-msgid ""
-"**Turn fingerprinting protection off**: Apply security counter-measures that"
-" are likely not to break web pages but do not defend against fingerprinting."
-" Disable APIs that are not commonly used. Use this level if Fingerprint "
-"Detector reports low likelihood of fingerprinting, you trust the visited "
-"service, and/or you think that the protection makes the page slow or broken "
-"and your temptation to use the service is so high that you do not want to be"
-" protected."
-msgstr ""
-
-#: ../content/pages/levels.md:block 8 (unordered list)
-msgid ""
-"**Recommended**: Make the browser appear differently to distinct "
-"fingerprinters. Apply security counter-measures that are likely not to break"
-" web pages. Slightly modify the results of API calls in different way on "
-"different domains so that the cross-site fingerprint is not stable. The "
-"generated fingerprint values also differ with each browser restart. If you "
-"need a different fingerprint for the same website without restart, use "
-"incognito mode. Keep in mind that even if you log out from a site, clear "
-"your cookies, change your IP address, the modified APIs will provide a way "
-"to compute the same fingerprint. Restart your browser if you want to change "
-"your fingerprint. If in doubt, use this level."
-msgstr ""
-
-#: ../content/pages/levels.md:block 8 (unordered list)
-msgid ""
-"**Strict**: Enable all non-experimental protection. The wrapped APIs return "
-"fake values. Some APIs are blocked completely, others provide meaningful but"
-" rare values. Some return values are meaningless. This level will make you "
-"fingerprintable because the results of API calls are generally modified in "
-"the same way on all webistes and in each session. Use this level if you want"
-" to limit the information provided by your browser. If you are worried about"
-" fingerprinters, make sure the Fingerprint Detector is activated."
-msgstr ""
-
-#: ../content/pages/license.md:block 1 (paragraph)
-msgid "Title: GNU General Public License"
-msgstr ""
-
-#: ../content/pages/license.md:block 2 (paragraph)
-msgid "Version 3, 29 June 2007"
-msgstr ""
-
-#: ../content/pages/license.md:block 3 (paragraph)
-msgid "Copyright (C) 2007 [Free Software Foundation, Inc.](https://fsf.org/)"
-msgstr ""
-
-#: ../content/pages/license.md:block 4 (paragraph)
-msgid ""
-"Everyone is permitted to copy and distribute verbatim copies of this license"
-" document, but changing it is not allowed."
-msgstr ""
-
-#: ../content/pages/license.md:block 5 (header)
-msgid "Preamble"
-msgstr ""
-
-#: ../content/pages/license.md:block 6 (paragraph)
-msgid ""
-"The GNU General Public License is a free, copyleft license for software and "
-"other kinds of works."
-msgstr ""
-
-#: ../content/pages/license.md:block 7 (paragraph)
-msgid ""
-"The licenses for most software and other practical works are designed to "
-"take away your freedom to share and change the works. By contrast, the GNU "
-"General Public License is intended to guarantee your freedom to share and "
-"change all versions of a program--to make sure it remains free software for "
-"all its users. We, the Free Software Foundation, use the GNU General Public "
-"License for most of our software; it applies also to any other work released"
-" this way by its authors. You can apply it to your programs, too."
-msgstr ""
-
-#: ../content/pages/license.md:block 8 (paragraph)
-msgid ""
-"When we speak of free software, we are referring to freedom, not price. Our "
-"General Public Licenses are designed to make sure that you have the freedom "
-"to distribute copies of free software (and charge for them if you wish), "
-"that you receive source code or can get it if you want it, that you can "
-"change the software or use pieces of it in new free programs, and that you "
-"know you can do these things."
-msgstr ""
-
-#: ../content/pages/license.md:block 9 (paragraph)
-msgid ""
-"To protect your rights, we need to prevent others from denying you these "
-"rights or asking you to surrender the rights. Therefore, you have certain "
-"responsibilities if you distribute copies of the software, or if you modify "
-"it: responsibilities to respect the freedom of others."
-msgstr ""
-
-#: ../content/pages/license.md:block 10 (paragraph)
-msgid ""
-"For example, if you distribute copies of such a program, whether gratis or "
-"for a fee, you must pass on to the recipients the same freedoms that you "
-"received. You must make sure that they, too, receive or can get the source "
-"code. And you must show them these terms so they know their rights."
-msgstr ""
-
-#: ../content/pages/license.md:block 11 (paragraph)
-msgid ""
-"Developers that use the GNU GPL protect your rights with two steps: (1) "
-"assert copyright on the software, and (2) offer you this License giving you "
-"legal permission to copy, distribute and/or modify it."
-msgstr ""
-
-#: ../content/pages/license.md:block 12 (paragraph)
-msgid ""
-"For the developers' and authors' protection, the GPL clearly explains that "
-"there is no warranty for this free software. For both users' and authors' "
-"sake, the GPL requires that modified versions be marked as changed, so that "
-"their problems will not be attributed erroneously to authors of previous "
-"versions."
-msgstr ""
-
-#: ../content/pages/license.md:block 13 (paragraph)
-msgid ""
-"Some devices are designed to deny users access to install or run modified "
-"versions of the software inside them, although the manufacturer can do so. "
-"This is fundamentally incompatible with the aim of protecting users' freedom"
-" to change the software. The systematic pattern of such abuse occurs in the "
-"area of products for individuals to use, which is precisely where it is most"
-" unacceptable. Therefore, we have designed this version of the GPL to "
-"prohibit the practice for those products. If such problems arise "
-"substantially in other domains, we stand ready to extend this provision to "
-"those domains in future versions of the GPL, as needed to protect the "
-"freedom of users."
-msgstr ""
-
-#: ../content/pages/license.md:block 14 (paragraph)
-msgid ""
-"Finally, every program is threatened constantly by software patents. States "
-"should not allow patents to restrict development and use of software on "
-"general-purpose computers, but in those that do, we wish to avoid the "
-"special danger that patents applied to a free program could make it "
-"effectively proprietary. To prevent this, the GPL assures that patents "
-"cannot be used to render the program non-free."
-msgstr ""
-
-#: ../content/pages/license.md:block 15 (paragraph)
-msgid ""
-"The precise terms and conditions for copying, distribution and modification "
-"follow."
-msgstr ""
-
-#: ../content/pages/license.md:block 16 (header)
-msgid "TERMS AND CONDITIONS"
-msgstr ""
-
-#: ../content/pages/license.md:block 17 (header)
-msgid "0. Definitions."
-msgstr ""
-
-#: ../content/pages/license.md:block 18 (paragraph)
-msgid "\"This License\" refers to version 3 of the GNU General Public License."
-msgstr ""
-
-#: ../content/pages/license.md:block 19 (paragraph)
-msgid ""
-"\"Copyright\" also means copyright-like laws that apply to other kinds of "
-"works, such as semiconductor masks."
-msgstr ""
-
-#: ../content/pages/license.md:block 20 (paragraph)
-msgid ""
-"\"The Program\" refers to any copyrightable work licensed under this "
-"License. Each licensee is addressed as \"you\". \"Licensees\" and "
-"\"recipients\" may be individuals or organizations."
-msgstr ""
-
-#: ../content/pages/license.md:block 21 (paragraph)
-msgid ""
-"To \"modify\" a work means to copy from or adapt all or part of the work in "
-"a fashion requiring copyright permission, other than the making of an exact "
-"copy. The resulting work is called a \"modified version\" of the earlier "
-"work or a work \"based on\" the earlier work."
-msgstr ""
-
-#: ../content/pages/license.md:block 22 (paragraph)
-msgid ""
-"A \"covered work\" means either the unmodified Program or a work based on "
-"the Program."
-msgstr ""
-
-#: ../content/pages/license.md:block 23 (paragraph)
-msgid ""
-"To \"propagate\" a work means to do anything with it that, without "
-"permission, would make you directly or secondarily liable for infringement "
-"under applicable copyright law, except executing it on a computer or "
-"modifying a private copy. Propagation includes copying, distribution (with "
-"or without modification), making available to the public, and in some "
-"countries other activities as well."
-msgstr ""
-
-#: ../content/pages/license.md:block 24 (paragraph)
-msgid ""
-"To \"convey\" a work means any kind of propagation that enables other "
-"parties to make or receive copies. Mere interaction with a user through a "
-"computer network, with no transfer of a copy, is not conveying."
-msgstr ""
-
-#: ../content/pages/license.md:block 25 (paragraph)
-msgid ""
-"An interactive user interface displays \"Appropriate Legal Notices\" to the "
-"extent that it includes a convenient and prominently visible feature that "
-"(1) displays an appropriate copyright notice, and (2) tells the user that "
-"there is no warranty for the work (except to the extent that warranties are "
-"provided), that licensees may convey the work under this License, and how to"
-" view a copy of this License. If the interface presents a list of user "
-"commands or options, such as a menu, a prominent item in the list meets this"
-" criterion."
-msgstr ""
-
-#: ../content/pages/license.md:block 26 (header)
-msgid "1. Source Code."
-msgstr ""
-
-#: ../content/pages/license.md:block 27 (paragraph)
-msgid ""
-"The \"source code\" for a work means the preferred form of the work for "
-"making modifications to it. \"Object code\" means any non-source form of a "
-"work."
-msgstr ""
-
-#: ../content/pages/license.md:block 28 (paragraph)
-msgid ""
-"A \"Standard Interface\" means an interface that either is an official "
-"standard defined by a recognized standards body, or, in the case of "
-"interfaces specified for a particular programming language, one that is "
-"widely used among developers working in that language."
-msgstr ""
-
-#: ../content/pages/license.md:block 29 (paragraph)
-msgid ""
-"The \"System Libraries\" of an executable work include anything, other than "
-"the work as a whole, that (a) is included in the normal form of packaging a "
-"Major Component, but which is not part of that Major Component, and (b) "
-"serves only to enable use of the work with that Major Component, or to "
-"implement a Standard Interface for which an implementation is available to "
-"the public in source code form. A \"Major Component\", in this context, "
-"means a major essential component (kernel, window system, and so on) of the "
-"specific operating system (if any) on which the executable work runs, or a "
-"compiler used to produce the work, or an object code interpreter used to run"
-" it."
-msgstr ""
-
-#: ../content/pages/license.md:block 30 (paragraph)
-msgid ""
-"The \"Corresponding Source\" for a work in object code form means all the "
-"source code needed to generate, install, and (for an executable work) run "
-"the object code and to modify the work, including scripts to control those "
-"activities. However, it does not include the work's System Libraries, or "
-"general-purpose tools or generally available free programs which are used "
-"unmodified in performing those activities but which are not part of the "
-"work. For example, Corresponding Source includes interface definition files "
-"associated with source files for the work, and the source code for shared "
-"libraries and dynamically linked subprograms that the work is specifically "
-"designed to require, such as by intimate data communication or control flow "
-"between those subprograms and other parts of the work."
-msgstr ""
-
-#: ../content/pages/license.md:block 31 (paragraph)
-msgid ""
-"The Corresponding Source need not include anything that users can regenerate"
-" automatically from other parts of the Corresponding Source."
-msgstr ""
-
-#: ../content/pages/license.md:block 32 (paragraph)
-msgid ""
-"The Corresponding Source for a work in source code form is that same work."
-msgstr ""
-
-#: ../content/pages/license.md:block 33 (header)
-msgid "2. Basic Permissions."
-msgstr ""
-
-#: ../content/pages/license.md:block 34 (paragraph)
-msgid ""
-"All rights granted under this License are granted for the term of copyright "
-"on the Program, and are irrevocable provided the stated conditions are met. "
-"This License explicitly affirms your unlimited permission to run the "
-"unmodified Program. The output from running a covered work is covered by "
-"this License only if the output, given its content, constitutes a covered "
-"work. This License acknowledges your rights of fair use or other equivalent,"
-" as provided by copyright law."
-msgstr ""
-
-#: ../content/pages/license.md:block 35 (paragraph)
-msgid ""
-"You may make, run and propagate covered works that you do not convey, "
-"without conditions so long as your license otherwise remains in force. You "
-"may convey covered works to others for the sole purpose of having them make "
-"modifications exclusively for you, or provide you with facilities for "
-"running those works, provided that you comply with the terms of this License"
-" in conveying all material for which you do not control copyright. Those "
-"thus making or running the covered works for you must do so exclusively on "
-"your behalf, under your direction and control, on terms that prohibit them "
-"from making any copies of your copyrighted material outside their "
-"relationship with you."
-msgstr ""
-
-#: ../content/pages/license.md:block 36 (paragraph)
-msgid ""
-"Conveying under any other circumstances is permitted solely under the "
-"conditions stated below. Sublicensing is not allowed; section 10 makes it "
-"unnecessary."
-msgstr ""
-
-#: ../content/pages/license.md:block 37 (header)
-msgid "3. Protecting Users' Legal Rights From Anti-Circumvention Law."
-msgstr ""
-
-#: ../content/pages/license.md:block 38 (paragraph)
-msgid ""
-"No covered work shall be deemed part of an effective technological measure "
-"under any applicable law fulfilling obligations under article 11 of the WIPO"
-" copyright treaty adopted on 20 December 1996, or similar laws prohibiting "
-"or restricting circumvention of such measures."
-msgstr ""
-
-#: ../content/pages/license.md:block 39 (paragraph)
-msgid ""
-"When you convey a covered work, you waive any legal power to forbid "
-"circumvention of technological measures to the extent such circumvention is "
-"effected by exercising rights under this License with respect to the covered"
-" work, and you disclaim any intention to limit operation or modification of "
-"the work as a means of enforcing, against the work's users, your or third "
-"parties' legal rights to forbid circumvention of technological measures."
-msgstr ""
-
-#: ../content/pages/license.md:block 40 (header)
-msgid "4. Conveying Verbatim Copies."
-msgstr ""
-
-#: ../content/pages/license.md:block 41 (paragraph)
-msgid ""
-"You may convey verbatim copies of the Program's source code as you receive "
-"it, in any medium, provided that you conspicuously and appropriately publish"
-" on each copy an appropriate copyright notice; keep intact all notices "
-"stating that this License and any non-permissive terms added in accord with "
-"section 7 apply to the code; keep intact all notices of the absence of any "
-"warranty; and give all recipients a copy of this License along with the "
-"Program."
-msgstr ""
-
-#: ../content/pages/license.md:block 42 (paragraph)
-msgid ""
-"You may charge any price or no price for each copy that you convey, and you "
-"may offer support or warranty protection for a fee."
-msgstr ""
-
-#: ../content/pages/license.md:block 43 (header)
-msgid "5. Conveying Modified Source Versions."
-msgstr ""
-
-#: ../content/pages/license.md:block 44 (paragraph)
-msgid ""
-"You may convey a work based on the Program, or the modifications to produce "
-"it from the Program, in the form of source code under the terms of section "
-"4, provided that you also meet all of these conditions:"
-msgstr ""
-
-#: ../content/pages/license.md:block 45 (unordered list)
-msgid ""
-"a) The work must carry prominent notices stating that you modified it, and "
-"giving a relevant date."
-msgstr ""
-
-#: ../content/pages/license.md:block 45 (unordered list)
-msgid ""
-"b) The work must carry prominent notices stating that it is released under "
-"this License and any conditions added under section 7. This requirement "
-"modifies the requirement in section 4 to \"keep intact all notices\"."
-msgstr ""
-
-#: ../content/pages/license.md:block 45 (unordered list)
-msgid ""
-"c) You must license the entire work, as a whole, under this License to "
-"anyone who comes into possession of a copy. This License will therefore "
-"apply, along with any applicable section 7 additional terms, to the whole of"
-" the work, and all its parts, regardless of how they are packaged. This "
-"License gives no permission to license the work in any other way, but it "
-"does not invalidate such permission if you have separately received it."
-msgstr ""
-
-#: ../content/pages/license.md:block 45 (unordered list)
-msgid ""
-"d) If the work has interactive user interfaces, each must display "
-"Appropriate Legal Notices; however, if the Program has interactive "
-"interfaces that do not display Appropriate Legal Notices, your work need not"
-" make them do so."
-msgstr ""
-
-#: ../content/pages/license.md:block 46 (paragraph)
-msgid ""
-"A compilation of a covered work with other separate and independent works, "
-"which are not by their nature extensions of the covered work, and which are "
-"not combined with it such as to form a larger program, in or on a volume of "
-"a storage or distribution medium, is called an \"aggregate\" if the "
-"compilation and its resulting copyright are not used to limit the access or "
-"legal rights of the compilation's users beyond what the individual works "
-"permit. Inclusion of a covered work in an aggregate does not cause this "
-"License to apply to the other parts of the aggregate."
-msgstr ""
-
-#: ../content/pages/license.md:block 47 (header)
-msgid "6. Conveying Non-Source Forms."
-msgstr ""
-
-#: ../content/pages/license.md:block 48 (paragraph)
-msgid ""
-"You may convey a covered work in object code form under the terms of "
-"sections 4 and 5, provided that you also convey the machine-readable "
-"Corresponding Source under the terms of this License, in one of these ways:"
-msgstr ""
-
-#: ../content/pages/license.md:block 49 (unordered list)
-msgid ""
-"a) Convey the object code in, or embodied in, a physical product (including "
-"a physical distribution medium), accompanied by the Corresponding Source "
-"fixed on a durable physical medium customarily used for software "
-"interchange."
-msgstr ""
-
-#: ../content/pages/license.md:block 49 (unordered list)
-msgid ""
-"b) Convey the object code in, or embodied in, a physical product (including "
-"a physical distribution medium), accompanied by a written offer, valid for "
-"at least three years and valid for as long as you offer spare parts or "
-"customer support for that product model, to give anyone who possesses the "
-"object code either (1) a copy of the Corresponding Source for all the "
-"software in the product that is covered by this License, on a durable "
-"physical medium customarily used for software interchange, for a price no "
-"more than your reasonable cost of physically performing this conveying of "
-"source, or (2) access to copy the Corresponding Source from a network server"
-" at no charge."
-msgstr ""
-
-#: ../content/pages/license.md:block 49 (unordered list)
-msgid ""
-"c) Convey individual copies of the object code with a copy of the written "
-"offer to provide the Corresponding Source. This alternative is allowed only "
-"occasionally and noncommercially, and only if you received the object code "
-"with such an offer, in accord with subsection 6b."
-msgstr ""
-
-#: ../content/pages/license.md:block 49 (unordered list)
-msgid ""
-"d) Convey the object code by offering access from a designated place (gratis"
-" or for a charge), and offer equivalent access to the Corresponding Source "
-"in the same way through the same place at no further charge. You need not "
-"require recipients to copy the Corresponding Source along with the object "
-"code. If the place to copy the object code is a network server, the "
-"Corresponding Source may be on a different server (operated by you or a "
-"third party) that supports equivalent copying facilities, provided you "
-"maintain clear directions next to the object code saying where to find the "
-"Corresponding Source. Regardless of what server hosts the Corresponding "
-"Source, you remain obligated to ensure that it is available for as long as "
-"needed to satisfy these requirements."
-msgstr ""
-
-#: ../content/pages/license.md:block 49 (unordered list)
-msgid ""
-"e) Convey the object code using peer-to-peer transmission, provided you "
-"inform other peers where the object code and Corresponding Source of the "
-"work are being offered to the general public at no charge under subsection "
-"6d."
-msgstr ""
-
-#: ../content/pages/license.md:block 50 (paragraph)
-msgid ""
-"A separable portion of the object code, whose source code is excluded from "
-"the Corresponding Source as a System Library, need not be included in "
-"conveying the object code work."
-msgstr ""
-
-#: ../content/pages/license.md:block 51 (paragraph)
-msgid ""
-"A \"User Product\" is either (1) a \"consumer product\", which means any "
-"tangible personal property which is normally used for personal, family, or "
-"household purposes, or (2) anything designed or sold for incorporation into "
-"a dwelling. In determining whether a product is a consumer product, doubtful"
-" cases shall be resolved in favor of coverage. For a particular product "
-"received by a particular user, \"normally used\" refers to a typical or "
-"common use of that class of product, regardless of the status of the "
-"particular user or of the way in which the particular user actually uses, or"
-" expects or is expected to use, the product. A product is a consumer product"
-" regardless of whether the product has substantial commercial, industrial or"
-" non-consumer uses, unless such uses represent the only significant mode of "
-"use of the product."
-msgstr ""
-
-#: ../content/pages/license.md:block 52 (paragraph)
-msgid ""
-"\"Installation Information\" for a User Product means any methods, "
-"procedures, authorization keys, or other information required to install and"
-" execute modified versions of a covered work in that User Product from a "
-"modified version of its Corresponding Source. The information must suffice "
-"to ensure that the continued functioning of the modified object code is in "
-"no case prevented or interfered with solely because modification has been "
-"made."
-msgstr ""
-
-#: ../content/pages/license.md:block 53 (paragraph)
-msgid ""
-"If you convey an object code work under this section in, or with, or "
-"specifically for use in, a User Product, and the conveying occurs as part of"
-" a transaction in which the right of possession and use of the User Product "
-"is transferred to the recipient in perpetuity or for a fixed term "
-"(regardless of how the transaction is characterized), the Corresponding "
-"Source conveyed under this section must be accompanied by the Installation "
-"Information. But this requirement does not apply if neither you nor any "
-"third party retains the ability to install modified object code on the User "
-"Product (for example, the work has been installed in ROM)."
-msgstr ""
-
-#: ../content/pages/license.md:block 54 (paragraph)
-msgid ""
-"The requirement to provide Installation Information does not include a "
-"requirement to continue to provide support service, warranty, or updates for"
-" a work that has been modified or installed by the recipient, or for the "
-"User Product in which it has been modified or installed. Access to a network"
-" may be denied when the modification itself materially and adversely affects"
-" the operation of the network or violates the rules and protocols for "
-"communication across the network."
-msgstr ""
-
-#: ../content/pages/license.md:block 55 (paragraph)
-msgid ""
-"Corresponding Source conveyed, and Installation Information provided, in "
-"accord with this section must be in a format that is publicly documented "
-"(and with an implementation available to the public in source code form), "
-"and must require no special password or key for unpacking, reading or "
-"copying."
-msgstr ""
-
-#: ../content/pages/license.md:block 56 (header)
-msgid "7. Additional Terms."
-msgstr ""
-
-#: ../content/pages/license.md:block 57 (paragraph)
-msgid ""
-"\"Additional permissions\" are terms that supplement the terms of this "
-"License by making exceptions from one or more of its conditions. Additional "
-"permissions that are applicable to the entire Program shall be treated as "
-"though they were included in this License, to the extent that they are valid"
-" under applicable law. If additional permissions apply only to part of the "
-"Program, that part may be used separately under those permissions, but the "
-"entire Program remains governed by this License without regard to the "
-"additional permissions."
-msgstr ""
-
-#: ../content/pages/license.md:block 58 (paragraph)
-msgid ""
-"When you convey a copy of a covered work, you may at your option remove any "
-"additional permissions from that copy, or from any part of it. (Additional "
-"permissions may be written to require their own removal in certain cases "
-"when you modify the work.) You may place additional permissions on material,"
-" added by you to a covered work, for which you have or can give appropriate "
-"copyright permission."
-msgstr ""
-
-#: ../content/pages/license.md:block 59 (paragraph)
-msgid ""
-"Notwithstanding any other provision of this License, for material you add to"
-" a covered work, you may (if authorized by the copyright holders of that "
-"material) supplement the terms of this License with terms:"
-msgstr ""
-
-#: ../content/pages/license.md:block 60 (unordered list)
-msgid ""
-"a) Disclaiming warranty or limiting liability differently from the terms of "
-"sections 15 and 16 of this License; or"
-msgstr ""
-
-#: ../content/pages/license.md:block 60 (unordered list)
-msgid ""
-"b) Requiring preservation of specified reasonable legal notices or author "
-"attributions in that material or in the Appropriate Legal Notices displayed "
-"by works containing it; or"
-msgstr ""
-
-#: ../content/pages/license.md:block 60 (unordered list)
-msgid ""
-"c) Prohibiting misrepresentation of the origin of that material, or "
-"requiring that modified versions of such material be marked in reasonable "
-"ways as different from the original version; or"
-msgstr ""
-
-#: ../content/pages/license.md:block 60 (unordered list)
-msgid ""
-"d) Limiting the use for publicity purposes of names of licensors or authors "
-"of the material; or"
-msgstr ""
-
-#: ../content/pages/license.md:block 60 (unordered list)
-msgid ""
-"e) Declining to grant rights under trademark law for use of some trade "
-"names, trademarks, or service marks; or"
-msgstr ""
-
-#: ../content/pages/license.md:block 60 (unordered list)
-msgid ""
-"f) Requiring indemnification of licensors and authors of that material by "
-"anyone who conveys the material (or modified versions of it) with "
-"contractual assumptions of liability to the recipient, for any liability "
-"that these contractual assumptions directly impose on those licensors and "
-"authors."
-msgstr ""
-
-#: ../content/pages/license.md:block 61 (paragraph)
-msgid ""
-"All other non-permissive additional terms are considered \"further "
-"restrictions\" within the meaning of section 10. If the Program as you "
-"received it, or any part of it, contains a notice stating that it is "
-"governed by this License along with a term that is a further restriction, "
-"you may remove that term. If a license document contains a further "
-"restriction but permits relicensing or conveying under this License, you may"
-" add to a covered work material governed by the terms of that license "
-"document, provided that the further restriction does not survive such "
-"relicensing or conveying."
-msgstr ""
-
-#: ../content/pages/license.md:block 62 (paragraph)
-msgid ""
-"If you add terms to a covered work in accord with this section, you must "
-"place, in the relevant source files, a statement of the additional terms "
-"that apply to those files, or a notice indicating where to find the "
-"applicable terms."
-msgstr ""
-
-#: ../content/pages/license.md:block 63 (paragraph)
-msgid ""
-"Additional terms, permissive or non-permissive, may be stated in the form of"
-" a separately written license, or stated as exceptions; the above "
-"requirements apply either way."
-msgstr ""
-
-#: ../content/pages/license.md:block 64 (header)
-msgid "8. Termination."
-msgstr ""
-
-#: ../content/pages/license.md:block 65 (paragraph)
-msgid ""
-"You may not propagate or modify a covered work except as expressly provided "
-"under this License. Any attempt otherwise to propagate or modify it is void,"
-" and will automatically terminate your rights under this License (including "
-"any patent licenses granted under the third paragraph of section 11)."
-msgstr ""
-
-#: ../content/pages/license.md:block 66 (paragraph)
-msgid ""
-"However, if you cease all violation of this License, then your license from "
-"a particular copyright holder is reinstated (a) provisionally, unless and "
-"until the copyright holder explicitly and finally terminates your license, "
-"and (b) permanently, if the copyright holder fails to notify you of the "
-"violation by some reasonable means prior to 60 days after the cessation."
-msgstr ""
-
-#: ../content/pages/license.md:block 67 (paragraph)
-msgid ""
-"Moreover, your license from a particular copyright holder is reinstated "
-"permanently if the copyright holder notifies you of the violation by some "
-"reasonable means, this is the first time you have received notice of "
-"violation of this License (for any work) from that copyright holder, and you"
-" cure the violation prior to 30 days after your receipt of the notice."
-msgstr ""
-
-#: ../content/pages/license.md:block 68 (paragraph)
-msgid ""
-"Termination of your rights under this section does not terminate the "
-"licenses of parties who have received copies or rights from you under this "
-"License. If your rights have been terminated and not permanently reinstated,"
-" you do not qualify to receive new licenses for the same material under "
-"section 10."
-msgstr ""
-
-#: ../content/pages/license.md:block 69 (header)
-msgid "9. Acceptance Not Required for Having Copies."
-msgstr ""
-
-#: ../content/pages/license.md:block 70 (paragraph)
-msgid ""
-"You are not required to accept this License in order to receive or run a "
-"copy of the Program. Ancillary propagation of a covered work occurring "
-"solely as a consequence of using peer-to-peer transmission to receive a copy"
-" likewise does not require acceptance. However, nothing other than this "
-"License grants you permission to propagate or modify any covered work. These"
-" actions infringe copyright if you do not accept this License. Therefore, by"
-" modifying or propagating a covered work, you indicate your acceptance of "
-"this License to do so."
-msgstr ""
-
-#: ../content/pages/license.md:block 71 (header)
-msgid "10. Automatic Licensing of Downstream Recipients."
-msgstr ""
-
-#: ../content/pages/license.md:block 72 (paragraph)
-msgid ""
-"Each time you convey a covered work, the recipient automatically receives a "
-"license from the original licensors, to run, modify and propagate that work,"
-" subject to this License. You are not responsible for enforcing compliance "
-"by third parties with this License."
-msgstr ""
-
-#: ../content/pages/license.md:block 73 (paragraph)
-msgid ""
-"An \"entity transaction\" is a transaction transferring control of an "
-"organization, or substantially all assets of one, or subdividing an "
-"organization, or merging organizations. If propagation of a covered work "
-"results from an entity transaction, each party to that transaction who "
-"receives a copy of the work also receives whatever licenses to the work the "
-"party's predecessor in interest had or could give under the previous "
-"paragraph, plus a right to possession of the Corresponding Source of the "
-"work from the predecessor in interest, if the predecessor has it or can get "
-"it with reasonable efforts."
-msgstr ""
-
-#: ../content/pages/license.md:block 74 (paragraph)
-msgid ""
-"You may not impose any further restrictions on the exercise of the rights "
-"granted or affirmed under this License. For example, you may not impose a "
-"license fee, royalty, or other charge for exercise of rights granted under "
-"this License, and you may not initiate litigation (including a cross-claim "
-"or counterclaim in a lawsuit) alleging that any patent claim is infringed by"
-" making, using, selling, offering for sale, or importing the Program or any "
-"portion of it."
-msgstr ""
-
-#: ../content/pages/license.md:block 75 (header)
-msgid "11. Patents."
-msgstr ""
-
-#: ../content/pages/license.md:block 76 (paragraph)
-msgid ""
-"A \"contributor\" is a copyright holder who authorizes use under this "
-"License of the Program or a work on which the Program is based. The work "
-"thus licensed is called the contributor's \"contributor version\"."
-msgstr ""
-
-#: ../content/pages/license.md:block 77 (paragraph)
-msgid ""
-"A contributor's \"essential patent claims\" are all patent claims owned or "
-"controlled by the contributor, whether already acquired or hereafter "
-"acquired, that would be infringed by some manner, permitted by this License,"
-" of making, using, or selling its contributor version, but do not include "
-"claims that would be infringed only as a consequence of further modification"
-" of the contributor version. For purposes of this definition, \"control\" "
-"includes the right to grant patent sublicenses in a manner consistent with "
-"the requirements of this License."
-msgstr ""
-
-#: ../content/pages/license.md:block 78 (paragraph)
-msgid ""
-"Each contributor grants you a non-exclusive, worldwide, royalty-free patent "
-"license under the contributor's essential patent claims, to make, use, sell,"
-" offer for sale, import and otherwise run, modify and propagate the contents"
-" of its contributor version."
-msgstr ""
-
-#: ../content/pages/license.md:block 79 (paragraph)
-msgid ""
-"In the following three paragraphs, a \"patent license\" is any express "
-"agreement or commitment, however denominated, not to enforce a patent (such "
-"as an express permission to practice a patent or covenant not to sue for "
-"patent infringement). To \"grant\" such a patent license to a party means to"
-" make such an agreement or commitment not to enforce a patent against the "
-"party."
-msgstr ""
-
-#: ../content/pages/license.md:block 80 (paragraph)
-msgid ""
-"If you convey a covered work, knowingly relying on a patent license, and the"
-" Corresponding Source of the work is not available for anyone to copy, free "
-"of charge and under the terms of this License, through a publicly available "
-"network server or other readily accessible means, then you must either (1) "
-"cause the Corresponding Source to be so available, or (2) arrange to deprive"
-" yourself of the benefit of the patent license for this particular work, or "
-"(3) arrange, in a manner consistent with the requirements of this License, "
-"to extend the patent license to downstream recipients. \"Knowingly relying\""
-" means you have actual knowledge that, but for the patent license, your "
-"conveying the covered work in a country, or your recipient's use of the "
-"covered work in a country, would infringe one or more identifiable patents "
-"in that country that you have reason to believe are valid."
-msgstr ""
-
-#: ../content/pages/license.md:block 81 (paragraph)
-msgid ""
-"If, pursuant to or in connection with a single transaction or arrangement, "
-"you convey, or propagate by procuring conveyance of, a covered work, and "
-"grant a patent license to some of the parties receiving the covered work "
-"authorizing them to use, propagate, modify or convey a specific copy of the "
-"covered work, then the patent license you grant is automatically extended to"
-" all recipients of the covered work and works based on it."
-msgstr ""
-
-#: ../content/pages/license.md:block 82 (paragraph)
-msgid ""
-"A patent license is \"discriminatory\" if it does not include within the "
-"scope of its coverage, prohibits the exercise of, or is conditioned on the "
-"non-exercise of one or more of the rights that are specifically granted "
-"under this License. You may not convey a covered work if you are a party to "
-"an arrangement with a third party that is in the business of distributing "
-"software, under which you make payment to the third party based on the "
-"extent of your activity of conveying the work, and under which the third "
-"party grants, to any of the parties who would receive the covered work from "
-"you, a discriminatory patent license (a) in connection with copies of the "
-"covered work conveyed by you (or copies made from those copies), or (b) "
-"primarily for and in connection with specific products or compilations that "
-"contain the covered work, unless you entered into that arrangement, or that "
-"patent license was granted, prior to 28 March 2007."
-msgstr ""
-
-#: ../content/pages/license.md:block 83 (paragraph)
-msgid ""
-"Nothing in this License shall be construed as excluding or limiting any "
-"implied license or other defenses to infringement that may otherwise be "
-"available to you under applicable patent law."
-msgstr ""
-
-#: ../content/pages/license.md:block 84 (header)
-msgid "12. No Surrender of Others' Freedom."
-msgstr ""
-
-#: ../content/pages/license.md:block 85 (paragraph)
-msgid ""
-"If conditions are imposed on you (whether by court order, agreement or "
-"otherwise) that contradict the conditions of this License, they do not "
-"excuse you from the conditions of this License. If you cannot convey a "
-"covered work so as to satisfy simultaneously your obligations under this "
-"License and any other pertinent obligations, then as a consequence you may "
-"not convey it at all. For example, if you agree to terms that obligate you "
-"to collect a royalty for further conveying from those to whom you convey the"
-" Program, the only way you could satisfy both those terms and this License "
-"would be to refrain entirely from conveying the Program."
-msgstr ""
-
-#: ../content/pages/license.md:block 86 (header)
-msgid "13. Use with the GNU Affero General Public License."
-msgstr ""
-
-#: ../content/pages/license.md:block 87 (paragraph)
-msgid ""
-"Notwithstanding any other provision of this License, you have permission to "
-"link or combine any covered work with a work licensed under version 3 of the"
-" GNU Affero General Public License into a single combined work, and to "
-"convey the resulting work. The terms of this License will continue to apply "
-"to the part which is the covered work, but the special requirements of the "
-"GNU Affero General Public License, section 13, concerning interaction "
-"through a network will apply to the combination as such."
-msgstr ""
-
-#: ../content/pages/license.md:block 88 (header)
-msgid "14. Revised Versions of this License."
-msgstr ""
-
-#: ../content/pages/license.md:block 89 (paragraph)
-msgid ""
-"The Free Software Foundation may publish revised and/or new versions of the "
-"GNU General Public License from time to time. Such new versions will be "
-"similar in spirit to the present version, but may differ in detail to "
-"address new problems or concerns."
-msgstr ""
-
-#: ../content/pages/license.md:block 90 (paragraph)
-msgid ""
-"Each version is given a distinguishing version number. If the Program "
-"specifies that a certain numbered version of the GNU General Public License "
-"\"or any later version\" applies to it, you have the option of following the"
-" terms and conditions either of that numbered version or of any later "
-"version published by the Free Software Foundation. If the Program does not "
-"specify a version number of the GNU General Public License, you may choose "
-"any version ever published by the Free Software Foundation."
-msgstr ""
-
-#: ../content/pages/license.md:block 91 (paragraph)
-msgid ""
-"If the Program specifies that a proxy can decide which future versions of "
-"the GNU General Public License can be used, that proxy's public statement of"
-" acceptance of a version permanently authorizes you to choose that version "
-"for the Program."
-msgstr ""
-
-#: ../content/pages/license.md:block 92 (paragraph)
-msgid ""
-"Later license versions may give you additional or different permissions. "
-"However, no additional obligations are imposed on any author or copyright "
-"holder as a result of your choosing to follow a later version."
-msgstr ""
-
-#: ../content/pages/license.md:block 93 (header)
-msgid "15. Disclaimer of Warranty."
-msgstr ""
-
-#: ../content/pages/license.md:block 94 (paragraph)
-msgid ""
-"THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE "
-"LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR "
-"OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, "
-"EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED "
-"WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE "
-"ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. "
-"SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY "
-"SERVICING, REPAIR OR CORRECTION."
-msgstr ""
-
-#: ../content/pages/license.md:block 95 (header)
-msgid "16. Limitation of Liability."
-msgstr ""
-
-#: ../content/pages/license.md:block 96 (paragraph)
-msgid ""
-"IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL "
-"ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE "
-"PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY "
-"GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE"
-" OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA "
-"OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD "
-"PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), "
-"EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF "
-"SUCH DAMAGES."
-msgstr ""
-
-#: ../content/pages/license.md:block 97 (header)
-msgid "17. Interpretation of Sections 15 and 16."
-msgstr ""
-
-#: ../content/pages/license.md:block 98 (paragraph)
-msgid ""
-"If the disclaimer of warranty and limitation of liability provided above "
-"cannot be given local legal effect according to their terms, reviewing "
-"courts shall apply local law that most closely approximates an absolute "
-"waiver of all civil liability in connection with the Program, unless a "
-"warranty or assumption of liability accompanies a copy of the Program in "
-"return for a fee."
-msgstr ""
-
-#: ../content/pages/license.md:block 99 (paragraph)
-msgid "END OF TERMS AND CONDITIONS"
-msgstr ""
-
-#: ../content/pages/license.md:block 100 (header)
-msgid "How to Apply These Terms to Your New Programs"
-msgstr ""
-
-#: ../content/pages/license.md:block 101 (paragraph)
-msgid ""
-"If you develop a new program, and you want it to be of the greatest possible"
-" use to the public, the best way to achieve this is to make it free software"
-" which everyone can redistribute and change under these terms."
-msgstr ""
-
-#: ../content/pages/license.md:block 102 (paragraph)
-msgid ""
-"To do so, attach the following notices to the program. It is safest to "
-"attach them to the start of each source file to most effectively state the "
-"exclusion of warranty; and each file should have at least the \"copyright\" "
-"line and a pointer to where the full notice is found."
-msgstr ""
-
-#: ../content/pages/license.md:block 104 (paragraph)
-msgid ""
-"Also add information on how to contact you by electronic and paper mail."
-msgstr ""
-
-#: ../content/pages/license.md:block 105 (paragraph)
-msgid ""
-"If the program does terminal interaction, make it output a short notice like"
-" this when it starts in an interactive mode:"
-msgstr ""
-
-#: ../content/pages/license.md:block 107 (paragraph)
-msgid ""
-"The hypothetical commands \\`show w' and \\`show c' should show the "
-"appropriate parts of the General Public License. Of course, your program's "
-"commands might be different; for a GUI interface, you would use an \"about "
-"box\"."
-msgstr ""
-
-#: ../content/pages/license.md:block 108 (paragraph)
-msgid ""
-"You should also get your employer (if you work as a programmer) or school, "
-"if any, to sign a \"copyright disclaimer\" for the program, if necessary. "
-"For more information on this, and how to apply and follow the GNU GPL, see "
-"<https://www.gnu.org/licenses/>."
-msgstr ""
-
-#: ../content/pages/license.md:block 109 (paragraph)
-msgid ""
-"The GNU General Public License does not permit incorporating your program "
-"into proprietary programs. If your program is a subroutine library, you may "
-"consider it more useful to permit linking proprietary applications with the "
-"library. If this is what you want to do, use the GNU Lesser General Public "
-"License instead of this License. But first, please read "
-"<https://www.gnu.org/licenses/why-not-lgpl.html>."
-msgstr ""
-
-#: ../content/pages/nbs.md:block 1 (paragraph)
-msgid "Title: Network Boundary Shield Slug: nbs"
-msgstr ""
-
-#: ../content/pages/nbs.md:block 2 (paragraph)
-msgid ""
-"The Network Boundary Shield (NBS) is a protection against attacks from an "
-"external network (the Internet) to an internal network - especially against "
-"a reconnaissance attacks when a web browser is abused as a proxy. See, for "
-"example, [our blog post](/localportscanning/) or the [ForcePoint "
-"report](https://www.forcepoint.com/blog/x-labs/attacking-internal-network-"
-"public-internet-using-browser-proxy)."
-msgstr ""
-
-#: ../content/pages/nbs.md:block 3 (paragraph)
-msgid ""
-"The NBS functionality is based on filtering HTTP requests. The Network "
-"Boundary Shield uses blocking webRequest API to handle HTTP requests. This "
-"means that processing of each HTTP request is paused before it is analyzed "
-"and allowed (if it seems benign) or blocked (if it is suspicious)."
-msgstr ""
-
-#: ../content/pages/nbs.md:block 4 (paragraph)
-msgid ""
-"The main goal of NBS is to prevent attacks like a public website requests a "
-"resource from the internal network (e.g. the logo of the manufacturer of the"
-" local router); NBS will detect that a web page hosted on the public "
-"Internet tries to connect to a local IP address. NBS blocks only HTTP "
-"requests from a web page hosted on a public IP address to a private network "
-"resource. The user can allow specific web pages to access local resources "
-"(e.g. when using Intranet services)."
-msgstr ""
-
-#: ../content/pages/nbs.md:block 5 (paragraph)
-msgid ""
-"NBS uses [CSV files provided by "
-"IANA](https://www.iana.org/assignments/locally-served-dns-zones/locally-"
-"served-dns-zones.xml) to determine public and local IP address prefixes. "
-"Both IPv4 and IPv6 is supported. The CSV files are downloaded during the "
-"JShelter building process."
-msgstr ""
-
-#: ../content/pages/nbs.md:block 6 (paragraph)
-msgid ""
-"The NBS has only a small impact on the web browser performance. The impact "
-"differs for each implementation."
-msgstr ""
-
-#: ../content/pages/nbs.md:block 7 (paragraph)
-msgid ""
-"More information about the Network Boundary Shield can be obtained from the "
-"[master thesis by Pavel Pohner](https://www.vutbr.cz/studenti/zav-"
-"prace/detail/129272) (in Czech)."
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 1 (paragraph)
-msgid "Title: How to write a new wrapper"
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 2 (paragraph)
-msgid ""
-"The primary focus of jShelter is to provide security and privacy oriented "
-"wrappers of JavaScript APIs. As some of the code is very similar for each "
-"wrapper, we use a unified approach to describe wrappers. The approach is "
-"described below. This approach also helps to automatically modify `toString`"
-" conversions of the wrapped APIs, i.e. a correctly written wrapper creates a"
-" modified function but `wrapper.toString()` returns the original string."
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 4 (header)
-msgid "File structure"
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 5 (unordered list)
-msgid ""
-"`wrapping.js` provides main facilities for interacting with specific "
-"wrappers:"
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 5 (unordered list)
-msgid ""
-"`add_wrappers()` has to be provided with all the wrappers. Hence, a typical "
-"module with wrappers of a web standard APIS. ends with a call of "
-"`add_wrappers(list_of_all_wrappers_defined_by_the_module)`."
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 5 (unordered list)
-msgid ""
-"`build_wrapping_code` contains all the registered wrappers. The keys are "
-"referenced by the levels wrapper list. Do not modify the "
-"`build_wrapping_code` variable directly, use `add_wrappers` instead."
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 5 (unordered list)
-msgid ""
-"The module also provides common functions used by the wrappers, e.g. "
-"`rounding_function` and `noise_function`."
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 5 (unordered list)
-msgid ""
-"`wrappingS-XYZ` are files dealing with APIs introduced by specific web or "
-"ECMA standard. See the **naming conventions** for details on the XYZ part of"
-" the name. See the **wrapper specification** section for the properties of "
-"the wrapper objects."
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 6 (header)
-msgid "Naming conventions"
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 7 (paragraph)
-msgid ""
-"jShelter adopted the naming conventions of the [Web API "
-"Manager](https://github.com/pes10k/web-api-"
-"manager/tree/master/sources/standards). See the paper:"
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 8 (paragraph)
-msgid ""
-"Peter Snyder, Cynthia Taylor, and Chris Kanich, “[Most Websites Don’t Need "
-"to Vibrate: A Cost–Benefit Approach to Improving Browser "
-"Security](https://arxiv.org/abs/1708.08510),” in Proceedings of the [2017 "
-"ACM Conference on Computer and Communications "
-"Security](https://www.sigsac.org/ccs/CCS2017/), 2017."
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 9 (header)
-msgid "Wrapper specification"
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 10 (paragraph)
-msgid ""
-"Once you are set with the file name for your wrappers, you can start coding."
-" The basic structure of the file is:"
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 12 (paragraph)
-msgid ""
-"The content of the module should be in an IIFE so that it does not polute "
-"the global namespace. The property values are strings that are generally "
-"interpreted either as identifiers or JS code."
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 13 (paragraph)
-msgid "Each wrapping object must have the following mandatory properties:"
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 14 (unordered list)
-msgid ""
-"`parent_object` and `parent_object_property` are used to define the name of "
-"the wrapping (`parent_object.parent_object_property`) that is referenced by "
-"level wrappers. Additionally, it is used if `wrapper_prototype` is defined "
-"to provide the object name to have the prototype changed. Finally, "
-"`Object.freeze` can be optionally called on "
-"`parent_object.parent_object_property`."
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 14 (unordered list)
-msgid ""
-"`apply_if` optionally provides a condition that needs to be fullfilled to "
-"apply the wrapper. For example if a wrapper should be applied only when an "
-"API already provides some information. For example, `apply_if: "
-"\"navigator.plugins.length > 0\"`."
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 14 (unordered list)
-msgid ""
-"`wrapped_objects` is a list of objects, each having the following properties"
-" (1 mandatory, 2 optional, typically, wrappers use one of the optional names"
-" in the wrapper code to access the original result of the call):"
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 14 (unordered list)
-msgid ""
-"`original_name` (*mandatory*) - the original name of the object to be "
-"wrapped. Do not mention `window` here!"
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 14 (unordered list)
-msgid ""
-"`wrapped_name` - the variable name that points to the actual original "
-"object. Wrappers might need it for identity comparisons or other instance-"
-"specific use cases. The variable name can be used by "
-"`wrapping_function_body`, `helping_code` and other code fragments to "
-"reference the original object. Note that this name is not available outside "
-"the code generated by this wrappper."
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 14 (unordered list)
-msgid ""
-"`callable_name` - is similar to the `wrapped_name` but the variable refers "
-"to a proxy of the original object. The proxy intercepts calls and "
-"automatically marshals parameters and return values. Wrappers MUST define "
-"`callable_name` if the object is passed to other code like `Promise` objects"
-" or callbacks. The variable is available only in the code generate by this "
-"wrapper. `callable_name` is specifically **meant to be used for native "
-"methods and functions** which the wrapper needs to call. This is especially "
-"important if it **accepts callback arguments or returns `Promise` objects**:"
-" invoking them through their `callable_name` automates complex steps "
-"otherwise required for [sandboxed browser extensions to interact with web "
-"pages](https://developer.mozilla.org/en-US/docs/Mozilla/Add-"
-"ons/WebExtensions/Sharing_objects_with_page_scripts)."
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 15 (paragraph)
-msgid ""
-"Generally speaking, use `wrapped_name` whenever you need to access the "
-"original objects only inside the wrapper and you do not need to pass the "
-"object to other code, such as `Promise` objects or callbacks. Compared to "
-"`callable_name`, `wrapped_name` has less overhead and is the preferred way."
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 16 (paragraph)
-msgid "Each wrapping object can have the following optional properties:"
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 17 (unordered list)
-msgid ""
-"`wrapping_function_args` is a string that is used as an argument list for "
-"the wrapping function. Typically this string reflects the parameters of the "
-"original method, it can be an empty string, a list of parameters, such as "
-"`\"source, target, color\"` or `\"...args\"`."
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 17 (unordered list)
-msgid ""
-"`wrapping_function_body` specified the behaviour of the wrapped function. "
-"You can provide a completely different implementation but often, you want to"
-" refer to the original implementation (available in the variable "
-"`wrapped_name`) and modify the original implementation."
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 17 (unordered list)
-msgid ""
-"`wrapping_code_function_name` can be used to call the wrapping function from"
-" the other code inside the wrapper. For example to create another wrapper "
-"similar to the original wrapper."
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 17 (unordered list)
-msgid ""
-"`wrapper_prototype` - if defined, `parent_object.parent_object_property` "
-"prototype is set to the prototype identifier provided by "
-"`wrapper_prototype`."
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 17 (unordered list)
-msgid ""
-"`original_function` if not provided, it defaults to "
-"`parent_object.parent_object_property`. This name is used for overloading "
-"the `toString` function. Instead of the wrapping code, `toString` returns "
-"the content of the original function."
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 17 (unordered list)
-msgid ""
-"`helping_code` provides you an option to define code available for both "
-"`replacement` function and `post_wrapping_code`"
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 17 (unordered list)
-msgid ""
-"`replace_original_function` is used to control which function should be "
-"replaced"
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 17 (unordered list)
-msgid ""
-"`post_replacement_code` Allows to provide additional code with the access to"
-" the original function and to the wrapped function"
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 17 (unordered list)
-msgid ""
-"`freeze` if set to `true` causes the API to be freezed. It should not be "
-"necessary if the wrapping is performed at the right level of the object's "
-"prototype chain (i.e. where the property to be modified was originally "
-"defined, i.e. usually in the object's prototype). Use this option with "
-"caution, only if strictly needed, because native APIs are configurable "
-"(otherwise our wrapping couldn't work) and therefore freezing them "
-"introduces a \"weirdness\", exploitable for fingerprinting."
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 17 (unordered list)
-msgid ""
-"`post_wrapping_code` is a list of additional wrapping objects with a similar"
-" structure to the wrappers, see the section bellow."
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 18 (header)
-msgid "Post wrapping code"
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 19 (paragraph)
-msgid "Complex wrappers need to provide additional wrapping code."
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 20 (paragraph)
-msgid ""
-"You can make the generation of the post wrapping code generation conditional"
-" by using `apply_if`, e.g.:"
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 22 (paragraph)
-msgid "(`enableGeolocation` is a Booloean variable)"
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 23 (paragraph)
-msgid "Currently jShelter supports additional wrapping of:"
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 24 (unordered list)
-msgid ""
-"Definition of a function (used, for example, to reintroduce `Date.now()` "
-"function to the wrapped `Date` object)"
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 26 (unordered list)
-msgid ""
-"Export a function from the wrapping namespace (currently not used, the "
-"following code exposes the unwrapped, i.e. original, version of Date.now to "
-"page scripts)"
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 28 (unordered list)
-msgid ""
-"Redefine an object property (used to prevent leaking iframe properties to "
-"the unwrapped objects):"
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 30 (unordered list)
-msgid "Deleting a property (used when you want to completely disable an API):"
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 32 (header)
-msgid "The WrapHelper API"
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 33 (paragraph)
-msgid ""
-"A `WrapHelper` object is globally available to wrappers code, exposing some "
-"methods and properties which are mostly used internally by the code builders"
-" to automate tasks such as handling [Firefox's content script "
-"sandbox](https://developer.mozilla.org/en-US/docs/Mozilla/Add-"
-"ons/WebExtensions/Sharing_objects_with_page_scripts) or making replacement "
-"objects look as native as possible. However a few of them may be useful to "
-"complex wrappers or in edge case not covered by `callable_name` and other "
-"declarative object replacement / property definition wrapper constructs:"
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 34 (unordered list)
-msgid ""
-"`WrapHelper.shared: {}` - a \"bare\" JavaScript object which a wrapper can "
-"use to share information with other wrappers (e.g. to coordinate behavior "
-"between related parts of the same API requiring multiple wrappings) by "
-"attaching its own data objects as properties. **Warning**: namespacing is "
-"not enforced and up to the wrapper implementor, but obviously recommended."
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 34 (unordered list)
-msgid ""
-"`WrapHelper.overlay(obj, data)` - Proxies the prototype of the `obj` object "
-"in order to return the properties of the `data` object as if they were "
-"native properties (e.g. as if they were returned by getters on the prototype"
-" chain, rather than defined on the instance). This allows spoofing some "
-"native objects data in a less detectable / fingerprintable way than by using"
-" `Object.defineProperty()`. See `wrappingS-MCS.js` for an example."
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 34 (unordered list)
-msgid ""
-"`WrapHelper.forPage(obj)` - it's mostly used internally and transparently by"
-" `code_builder.js`, but may be useful to very complex proxies in edge cases "
-"needing to explicitly prepare an object/function created in [Firefox's "
-"sandboxed content script environment](https://developer.mozilla.org/en-"
-"US/docs/Mozilla/Add-ons/WebExtensions/Sharing_objects_with_page_scripts) to "
-"be consumed/called from the page context, and to make replacements for "
-"native objects and functions provided by the wrappers look as much native as"
-" possible (on Chromium, too). In most cases, however, this gets automated by"
-" the code builders replacing Object methods with their WrapHelper "
-"counterpart in the wrapper sources and by proxying \"callable_name\" "
-"function references through `WrapHelper.pageAPI()` (see below)."
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 34 (unordered list)
-msgid ""
-"`WrapHelper.pageAPI(f)` - proxies the function/method f so that arguments "
-"and return values, and especially callbacks and `Promise` objects, are "
-"recursively managed in order to transparently marshal objects back and forth"
-" [Firefox's sandbox for extensions (https://developer.mozilla.org/en-"
-"US/docs/Mozilla/Add-ons/WebExtensions/Sharing_objects_with_page_scripts). "
-"**Wrapper implementors should almost never need to use this API directly**, "
-"since any function referenced via its \"callable_name\" goes automatically "
-"through it."
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 35 (header)
-msgid "The generated wrapper structure"
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 36 (paragraph)
-msgid ""
-"To get a better idea how the code is generated see the following pseudo "
-"code. Please do not refer to any name created by the code builders from your"
-" wrapper. Use your custom names. If it is not available, please, open an "
-"issue where you explain what you are trying to achieve. It is probable that "
-"we will introduce a new property that allows to provide your name to the "
-"code builders. The code lives in an anonymous namespaces, so variables "
-"introduced here do not directly leak to page scripts."
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 38 (header)
-msgid "Compiling the wrappers"
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 39 (paragraph)
-msgid ""
-"Of course the wrappers need to be compiled to JavaScript before inserting "
-"the code to page scripts. See `code_builders.js`."
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 40 (header)
-msgid "Registering a new wrapper"
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 41 (paragraph)
-msgid ""
-"`fix_manifest.sh` automatically adds all modules with file name of "
-"`wrapping*.js` to the manifest.json of the extension. There is no need for "
-"any additional action."
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 42 (header)
-msgid ""
-"Register new wrapper to be used by the extension in a level or available in "
-"the GUI."
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 43 (paragraph)
-msgid ""
-"See `levels.js` and its list `wrapping_groups.groups`. Once you add your "
-"wrapper to an existing group or create a new group, the wrapper becomes "
-"available in the built-in levels containing the group and in the GUI for "
-"custom levels."
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 44 (header)
-msgid "Describe the wrapper for Doxygen documentation"
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 45 (paragraph)
-msgid "Describe what the wrapper tries to accomplish and its approach:"
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 46 (unordered list)
-msgid ""
-"Add Doxygen comment at the top of the file with the following structure:"
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 48 (unordered list)
-msgid "Describe helping functions and `wrapping_function_body`"
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 48 (unordered list)
-msgid ""
-"Use Doxygen command `\\fn fake wrapped.object` for each "
-"`wrapping_function_body`"
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 48 (unordered list)
-msgid "Use the following structure for function comments:"
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 50 (header)
-msgid "Write unit tests or integration tests for the wrapper"
-msgstr ""
-
-#: ../content/pages/new-wrapper.md:block 51 (paragraph)
-msgid ""
-"Follow instructions for [unit testing](/unit_tests/) and [integration "
-"testing](/integration_tests/)."
-msgstr ""
-
-#: ../content/pages/permissions.md:block 1 (paragraph)
-msgid "Title: Permissions"
-msgstr ""
-
-#: ../content/pages/permissions.md:block 2 (paragraph)
-msgid "JShelter requires these permissions:"
-msgstr ""
-
-#: ../content/pages/permissions.md:block 3 (unordered list)
-msgid "**storage**: for storing extension configuration and user options"
-msgstr ""
-
-#: ../content/pages/permissions.md:block 3 (unordered list)
-msgid "**tabs**: for updating the extension's icon badge on tab change"
-msgstr ""
-
-#: ../content/pages/permissions.md:block 3 (unordered list)
-msgid ""
-"**webRequest, webRequestBlocking, all_urls**: for modifying JavaScript "
-"objects and APIs on all pages, and for capturing and blocking malicious HTTP"
-" requests"
-msgstr ""
-
-#: ../content/pages/permissions.md:block 3 (unordered list)
-msgid ""
-"**dns**: for resolving DNS queries in Firefox version of HTTP request shield"
-msgstr ""
-
-#: ../content/pages/permissions.md:block 3 (unordered list)
-msgid "**notifications**: for notifying users on blocked HTTP requests/hosts"
-msgstr ""
-
-#: ../content/pages/permissions.md:block 3 (unordered list)
-msgid ""
-"**browsingData**: Fingerprint Detector needs to remove data from any storage"
-" that can save the fingerprint"
-msgstr ""
-
-#: ../content/pages/permissions.md:block 3 (unordered list)
-msgid ""
-"**webNavigation**: for deploying wrappers as early as possible to avoid page"
-" scripts accessing unwrapped objects. NSCL use a different approch for this "
-"purpose in Chromium-based browsers. All brosers need the permission to apply"
-" `window.name` protection"
-msgstr ""
-
-#: ../content/pages/permissions.md:block 4 (paragraph)
-msgid ""
-"jShelter stores all configuration data in the browser or in the user "
-"account. It does not upload any data to our servers."
-msgstr ""
-
-#: ../content/pages/threatmodel.md:block 1 (paragraph)
-msgid "Title: Threat model"
-msgstr ""
-
-#: ../content/pages/threatmodel.md:block 2 (paragraph)
-msgid ""
-"JShelter focuses on threats that affect the mainstream population. Our "
-"adversary creates attacks/derives information in a way that works in "
-"mainstream browsers. The attacker focuses on these browsers and attacks that"
-" are light on performance. For example, the adversary is interested in "
-"identifying the user for targeted advertisement. So they need to identify "
-"the user quickly to display an advertisement. It does not make sense for "
-"such an attacker to deploy scripts that take minutes to compute a "
-"fingerprint."
-msgstr ""
-
-#: ../content/pages/threatmodel.md:block 3 (paragraph)
-msgid ""
-"Our adversary might try to apply low-performance counterattacks. For "
-"example, previous literature identified extensions that modify calls in a "
-"wrong position in the JavaScript prototype chain. It is straightforward for "
-"an adversary to use `Performance.prototype.now()` instead of "
-"`performance.now()` so we apply code that modifies the original method, "
-"`Performance.prototype.now()`, in the example. Another example is an "
-"adversary running canvas fingerprinting several times. If the adversary "
-"receives different results, they can compute an average value (or a minimal "
-"or maximal value) and use this information to derive the correct "
-"fingerprint. As these modifications to fingerprinting are not performance-"
-"heavy, we consider them in the threat model."
-msgstr ""
-
-#: ../content/pages/threatmodel.md:block 4 (paragraph)
-msgid ""
-"We do not have the resources to create a bullet-proof solution that "
-"eliminates all side channels. For example, we expect that an adversary will "
-"be able to detect that something strange is happening in the browser. For "
-"example, an adversary might fill a canvas with content controlled by the "
-"adversary and detect modifications after reading back the content. Or, the "
-"adversary might time the length of each/some operation(s). We modify the "
-"time readings, and the countermeasures take some time. Hence, we expect that"
-" an adversary will be able to detect that the user has modified the "
-"JavaScript environment with a patch or an extension. Our goal is to create a"
-" bigger anonymity set into which the user belongs. Hence, we try to "
-"eliminate the possibility of an attacker identifying the user uniquely. "
-"Still, we accept that the attacker can detect a JShelter user in the worst "
-"case. To do so reliably, the attacker should need to keep track of the code "
-"base changes."
-msgstr ""
-
-#: ../content/pages/threatmodel.md:block 5 (paragraph)
-msgid ""
-"Nevertheless, we want to avoid allowing the attacker to identify JShelter "
-"users easily. We are not aware of any isolated side-effect that reveals "
-"JShelter. For example, some similar webextensions do not modify "
-"`Function.prototype.toString`. A page script could detect such a "
-"webextension as each webextension modifying the same API call by the same "
-"technique will likely use a different code. Our goal is to offer protection "
-"indistinguishable from another privacy-improving tool for each modified API."
-" Nevertheless, a focused observer will very likely be always able to learn "
-"that a user is using JShelter if they aggregate the observable "
-"inconsistencies of all APIs produced by JShelter. We are aware and do not "
-"hide that users of JShelter are vulnerable to focused attacks."
-msgstr ""
-
-#: ../content/pages/threatmodel.md:block 6 (paragraph)
-msgid ""
-"JShelter's goal is to make targeted attacks harder. Still, we do not believe"
-" that we are in a position to prevent them completely. We suggest using Tor "
-"Browser or a similar privacy-enhancing tool for users concerned with "
-"targeted attacks."
-msgstr ""
-
-#: ../content/pages/threatmodel.md:block 7 (paragraph)
-msgid ""
-"It is well-known that some extensions modify the environment of the browser "
-"or the web page. For example, password managers add buttons to fill in "
-"passwords automatically. Page tweakers add additional buttons to web pages "
-"to simplify common tasks or add information likely wanted by a user. "
-"JShelter expects such users and tries to help such users from being "
-"identifiable. For example, a dumb fingerprinter can combine all "
-"fingerprintable data to create a single number. Such a fingerprinter would "
-"unintentionally create a unique fingerprint of the users with a unique set "
-"of extensions. Such a dumb fingerprinter would not link different visits of "
-"the user with Jshelter. JShelter should confuse a more advanced "
-"fingerprinter if they identify single or multiple users."
-msgstr ""
-
-#: ../content/pages/threatmodel.md:block 8 (paragraph)
-msgid ""
-"We also want to provide an option that will limit the information that is "
-"readable from the computer, even if such behaviour generally results in "
-"better fingerprintability. For example, a user might want to disable canvas "
-"operations for pages that should not use canvas (from the user's "
-"standpoint). As the webpage is in a better position to deploy "
-"countermeasures for JShelter anti-fingerprinting techniques, the user might "
-"want the page to always read an empty, white, or random canvas. That would "
-"limit the information available for the web page at the cost of giving the "
-"page an easy way to determine that some countermeasures are in place. Our "
-"aim is to explain the consequences of taking such an option but letting the "
-"user decide for themselves."
-msgstr ""
-
-#: ../content/pages/threatmodel.md:block 9 (paragraph)
-msgid ""
-"Previous literature identified that it is easy for an adversary to detect "
-"inconsistencies in API calls. For example, a fingerprinter can learn the "
-"operating system from HTTP headers, `navigator.oscpu`, installed fonts, "
-"results of mathematical operations, and other techniques. We do not want to "
-"replace such techniques as we do not have the resources to create a "
-"consistent environment."
-msgstr ""
-
-#: ../content/pages/threatmodel.md:block 10 (paragraph)
-msgid ""
-"Besides fingerprinting, JShelter also focuses on other threats appearing on "
-"the web. For example, JShelter prevents web pages from turning the browser "
-"into a proxy to the local [network](/localportscanning/). The user should be"
-" able to decouple anti-fingerprinting countermeasures and other "
-"countermeasures."
-msgstr ""
-
-#: ../content/pages/versions.md:block 1 (header)
-msgid "title: Release history"
-msgstr ""
-
-#: ../content/pages/versions.md:block 2 (header)
-msgid "0.17"
-msgstr ""
-
-#: ../content/pages/versions.md:block 3 (unordered list)
-msgid ""
-"Added support for built-in tweaks for specific domains. The goal is to list "
-"several domains that break unnecessarily. Typically, an addition to the list"
-" should be well explained and must not lower protection. A nice candidate is"
-" WebWorker and the protection of Strict (break) and Remove."
-msgstr ""
-
-#: ../content/pages/versions.md:block 3 (unordered list)
-msgid "Updated translations"
-msgstr ""
-
-#: ../content/pages/versions.md:block 3 (unordered list)
-msgid "Improved FPD report based on user feedback:"
-msgstr ""
-
-#: ../content/pages/versions.md:block 3 (unordered list)
-msgid ""
-"Do not refresh report automatically when tracking callers but introduce an "
-"update button so that users refresh when convenient (prevent glitches in the"
-" interfaces)"
-msgstr ""
-
-#: ../content/pages/versions.md:block 3 (unordered list)
-msgid "Add buttons to hide/show details and fold/unfold groups"
-msgstr ""
-
-#: ../content/pages/versions.md:block 3 (unordered list)
-msgid ""
-"Do not show traces in bold to better differentiate between API names and "
-"traces."
-msgstr ""
-
-#: ../content/pages/versions.md:block 3 (unordered list)
-msgid ""
-"Add possibility to forget current traces. Useful when there is a "
-"fingerprinting script that activates after some action. The button allows "
-"the user to hide the traces triggered in the past and later load only new "
-"traces."
-msgstr ""
-
-#: ../content/pages/versions.md:block 3 (unordered list)
-msgid ""
-"Add support for [signing for Android on "
-"AMO](https://blog.mozilla.org/addons/2023/10/05/changes-to-android-"
-"extension-signing/), so we needed to increase minimal supported version"
-msgstr ""
-
-#: ../content/pages/versions.md:block 4 (header)
-msgid "0.16"
-msgstr ""
-
-#: ../content/pages/versions.md:block 5 (unordered list)
-msgid ""
-"Remove Workers in Recommended JSS level to make JShelter compatible with "
-"some pages. This change might be reverted when [Pagure issue "
-"80](https://pagure.io/JShelter/webextension/issue/80#comment-852202) is "
-"solved."
-msgstr ""
-
-#: ../content/pages/versions.md:block 5 (unordered list)
-msgid ""
-"FPD: Add possibility to learn the calling stack of functions that lead to "
-"the tracked APIs ([Pagure issue "
-"52](https://pagure.io/JShelter/webextension/issue/52)). This information can"
-" be used to create block list or to study the calling code and its effects."
-msgstr ""
-
-#: ../content/pages/versions.md:block 5 (unordered list)
-msgid ""
-"FPD: Fix browser overloading by FPD messages by "
-"HTMLElement.prototype.offsetHeight and offsetWidth wrappers that might have "
-"crashed browsers."
-msgstr ""
-
-#: ../content/pages/versions.md:block 5 (unordered list)
-msgid "FPD: code cleanup"
-msgstr ""
-
-#: ../content/pages/versions.md:block 6 (header)
-msgid "0.15.2"
-msgstr ""
-
-#: ../content/pages/versions.md:block 7 (unordered list)
-msgid ""
-"Fix `window.name` protection, do not clear the property in the first visited"
-" page see https://pagure.io/JShelter/webextension/issue/116#comment-875070 "
-"for more details. The fix affects all Chromium-based browsers and Firefox "
-"installs with the protection active (by default it is off in Firefox as "
-"Firefox contains the protection since Firefox 88). This fixes, for example, "
-"reCaptcha."
-msgstr ""
-
-#: ../content/pages/versions.md:block 7 (unordered list)
-msgid ""
-"options: Improve space distribution, see "
-"https://github.com/polcak/jsrestrictor/pull/204#issuecomment-1727519706"
-msgstr ""
-
-#: ../content/pages/versions.md:block 8 (header)
-msgid "0.15.1"
-msgstr ""
-
-#: ../content/pages/versions.md:block 9 (unordered list)
-msgid ""
-"Fix Chrome manifest that by mistake included a file from a non-existing "
-"path. The error prevented the extension from starting."
-msgstr ""
-
-#: ../content/pages/versions.md:block 10 (header)
-msgid "0.15"
-msgstr ""
-
-#: ../content/pages/versions.md:block 11 (unordered list)
-msgid "Update NSCL to uses built-in and faster function to compute sha256."
-msgstr ""
-
-#: ../content/pages/versions.md:block 11 (unordered list)
-msgid "Russian translation added."
-msgstr ""
-
-#: ../content/pages/versions.md:block 12 (header)
-msgid "0.14"
-msgstr ""
-
-#: ../content/pages/versions.md:block 13 (unordered list)
-msgid ""
-"Added support for internationalization, Czech translation added, see [blog "
-"post](/i18n/) for instrctions for translators"
-msgstr ""
-
-#: ../content/pages/versions.md:block 13 (unordered list)
-msgid "All texts revisited, clarified, and fixed grammar and typos"
-msgstr ""
-
-#: ../content/pages/versions.md:block 13 (unordered list)
-msgid ""
-"Improved performance of Canvas and Audio little-lies wrappers by executing "
-"in WebAssembly, there will be a separate blog post with additional "
-"explanations. See the [bachelor thesis of Martin "
-"Zmitko](https://www.vut.cz/en/students/final-thesis/detail/147218) for more "
-"details."
-msgstr ""
-
-#: ../content/pages/versions.md:block 13 (unordered list)
-msgid ""
-"Improved performance of FPD. See the [bachelor thesis of Martin "
-"Zmitko](https://www.vut.cz/en/students/final-thesis/detail/147218) for more "
-"details."
-msgstr ""
-
-#: ../content/pages/versions.md:block 13 (unordered list)
-msgid ""
-"Expand description of the wrappers applied when the user interacts with the "
-"tweak GUI (suggested by the Plain Text UX review)"
-msgstr ""
-
-#: ../content/pages/versions.md:block 13 (unordered list)
-msgid "Make level names in main options section stable width"
-msgstr ""
-
-#: ../content/pages/versions.md:block 13 (unordered list)
-msgid "NSCL updated:"
-msgstr ""
-
-#: ../content/pages/versions.md:block 13 (unordered list)
-msgid ""
-"Prevent dead object access on using backward/forward cache of the browser"
-msgstr ""
-
-#: ../content/pages/versions.md:block 13 (unordered list)
-msgid "Fixed property/function mismatch"
-msgstr ""
-
-#: ../content/pages/versions.md:block 14 (header)
-msgid "0.13"
-msgstr ""
-
-#: ../content/pages/versions.md:block 15 (paragraph)
-msgid ""
-"Improve performance of the code injection. See the [bachelor thesis of "
-"Martin Zmitko](https://www.vut.cz/en/students/final-thesis/detail/147218) "
-"for more details."
-msgstr ""
-
-#: ../content/pages/versions.md:block 16 (unordered list)
-msgid ""
-"The code is no longer generated in the background due to the latency of "
-"passing huge messages from background to content scripts."
-msgstr ""
-
-#: ../content/pages/versions.md:block 16 (unordered list)
-msgid "Optimize injection code size (remove duplicate code)."
-msgstr ""
-
-#: ../content/pages/versions.md:block 16 (unordered list)
-msgid "Do not generate xray wrapper when in Chromium-based browsers."
-msgstr ""
-
-#: ../content/pages/versions.md:block 17 (header)
-msgid "0.12.2"
-msgstr ""
-
-#: ../content/pages/versions.md:block 18 (unordered list)
-msgid ""
-"Reimplement AudioBuffer.prototype.copyFromChannel to prevent multiple "
-"farbling of the same data"
-msgstr ""
-
-#: ../content/pages/versions.md:block 18 (unordered list)
-msgid "bugfix (Chromium-based): Fix popup to always load current level"
-msgstr ""
-
-#: ../content/pages/versions.md:block 18 (unordered list)
-msgid "Optimize performance of Canvas and Audio wrappers"
-msgstr ""
-
-#: ../content/pages/versions.md:block 18 (unordered list)
-msgid ""
-"NSCL updated: JShelter benefits from the mechanism to prevent "
-"inconsistencies / breakages when the extension gets updated and therefore "
-"the old wrappers are invalidated by Firefox which nukes their sandbox and "
-"new ones are installed on extension's automatic restart"
-msgstr ""
-
-#: ../content/pages/versions.md:block 19 (header)
-msgid "0.12.1"
-msgstr ""
-
-#: ../content/pages/versions.md:block 20 (unordered list)
-msgid ""
-"bugfix: Return the correctly created Worker object from the `Strict` "
-"wrapper."
-msgstr ""
-
-#: ../content/pages/versions.md:block 21 (header)
-msgid "0.12"
-msgstr ""
-
-#: ../content/pages/versions.md:block 22 (unordered list)
-msgid ""
-"Cope with the changes of reported plugins and supported MIME types in the "
-"HTML standard and browsers: The purpose of the wrappers is solely to prevent"
-" fingerprinting. As browsers return the same 5 plugins, browsers modyfing "
-"the array stand out, which makes them more fingerprintable. Hence, JShelter "
-"does not modify the empty list or the list of five standard plugins."
-msgstr ""
-
-#: ../content/pages/versions.md:block 23 (paragraph)
-msgid "Reconsider and rewrite Web Worker wrappers (pagure issue 80)"
-msgstr ""
-
-#: ../content/pages/versions.md:block 24 (unordered list)
-msgid "`Strict` WebWorker policy intentionally breakes Web Workers"
-msgstr ""
-
-#: ../content/pages/versions.md:block 24 (unordered list)
-msgid ""
-"New policy to `Remove` Web Workers used for `Turn fingerprinting protection "
-"off` and `Strict` level."
-msgstr ""
-
-#: ../content/pages/versions.md:block 24 (unordered list)
-msgid ""
-"`Medium` WebWorker policy renamed to `Low` as it only tackles a single issue"
-" with Workers."
-msgstr ""
-
-#: ../content/pages/versions.md:block 25 (paragraph)
-msgid "See FAQ for more information on current Worker wrappers."
-msgstr ""
-
-#: ../content/pages/versions.md:block 26 (paragraph)
-msgid ""
-"Note that the `Low` policy does not work as intended in Firefox and will be "
-"fixed in future. However, it was broken in the same way before 0.12 and the "
-"other changes are worth distributing among our users."
-msgstr ""
-
-#: ../content/pages/versions.md:block 27 (header)
-msgid "0.11.4"
-msgstr ""
-
-#: ../content/pages/versions.md:block 28 (unordered list)
-msgid ""
-"bugfix: allow tweaking all levels except L0 in the popup (pagure issue 89)"
-msgstr ""
-
-#: ../content/pages/versions.md:block 28 (unordered list)
-msgid ""
-"bugfix: clarify and fix the description of changes to NBS in 0.11.3 (pagure "
-"issue 41)"
-msgstr ""
-
-#: ../content/pages/versions.md:block 29 (header)
-msgid "0.11.3"
-msgstr ""
-
-#: ../content/pages/versions.md:block 30 (unordered list)
-msgid ""
-"bugfix: Remove race condition that reset default level to Recommended from "
-"custom levels. Unfortunately, affected users need to manually restore the "
-"default level as JShelter cannot distinguish affected users automatically."
-msgstr ""
-
-#: ../content/pages/versions.md:block 30 (unordered list)
-msgid ""
-"bugfix: Prevent DNS leaks in NBS in the presence of HTTP proxy in Firefox, "
-"see pagure issues #41 and #85 and FAQ for more details on the interaction of"
-" NBS and proxies."
-msgstr ""
-
-#: ../content/pages/versions.md:block 30 (unordered list)
-msgid "enhancement: Fix empty spaces to improve the look of the option page"
-msgstr ""
-
-#: ../content/pages/versions.md:block 31 (header)
-msgid "0.11.2"
-msgstr ""
-
-#: ../content/pages/versions.md:block 32 (unordered list)
-msgid ""
-"bugfix: check domains property in advanced options (introduced in 0.10)"
-msgstr ""
-
-#: ../content/pages/versions.md:block 32 (unordered list)
-msgid "bugfix: remove unused config.whitelistedHosts"
-msgstr ""
-
-#: ../content/pages/versions.md:block 32 (unordered list)
-msgid "bugfix: Fix several typos in the text in options"
-msgstr ""
-
-#: ../content/pages/versions.md:block 32 (unordered list)
-msgid ""
-"bugfix: Do not use hard-coded level in the advanced options validity checks "
-"of configuration"
-msgstr ""
-
-#: ../content/pages/versions.md:block 32 (unordered list)
-msgid "feature: Add option to reset configuration to advanced options"
-msgstr ""
-
-#: ../content/pages/versions.md:block 32 (unordered list)
-msgid ""
-"enhancement: Reimplement JSS configuration in option to improve "
-"understandability"
-msgstr ""
-
-#: ../content/pages/versions.md:block 32 (unordered list)
-msgid ""
-"enhancement: Fix race conditions in displaying stored configuration after "
-"changes through options"
-msgstr ""
-
-#: ../content/pages/versions.md:block 32 (unordered list)
-msgid "enhancement: Add undo to advanced options"
-msgstr ""
-
-#: ../content/pages/versions.md:block 32 (unordered list)
-msgid ""
-"enhancement: Warn users from tweaking their settings due to higher risks of "
-"reidentification via browser fingerprinting"
-msgstr ""
-
-#: ../content/pages/versions.md:block 32 (unordered list)
-msgid ""
-"enhancement: Add button to cancel the addition of a new level, update the "
-"error texts"
-msgstr ""
-
-#: ../content/pages/versions.md:block 32 (unordered list)
-msgid "website: little improvements and clarifications"
-msgstr ""
-
-#: ../content/pages/versions.md:block 33 (paragraph)
-msgid "Most of the changes were influenced by the Plain Text UX review"
-msgstr ""
-
-#: ../content/pages/versions.md:block 34 (header)
-msgid "0.11.1"
-msgstr ""
-
-#: ../content/pages/versions.md:block 35 (unordered list)
-msgid ""
-"NBS: do not show notifications for hostnames resolving to undefined IP "
-"addresses as described in FAQ (broken in 0.11 that does not show "
-"notifications only for undefined IP addresses, but shows notifications for "
-"hostnames resolving to undefined IP addresses)"
-msgstr ""
-
-#: ../content/pages/versions.md:block 36 (header)
-msgid "0.11"
-msgstr ""
-
-#: ../content/pages/versions.md:block 37 (unordered list)
-msgid "Reset `window.name` only on eTLD+1 changes"
-msgstr ""
-
-#: ../content/pages/versions.md:block 37 (unordered list)
-msgid "Farbling: Use eTLD+1 instead of origin to generate hash"
-msgstr ""
-
-#: ../content/pages/versions.md:block 37 (unordered list)
-msgid ""
-"FPD: Clear storage during navigation (prevent the page from storing the hash"
-" to a local storage and loading the hash after page reload)"
-msgstr ""
-
-#: ../content/pages/versions.md:block 37 (unordered list)
-msgid ""
-"FPD configuration: Decouple notification and behaviour settings. Let a user "
-"to optionally disable notifications without strict effect on behaviour"
-msgstr ""
-
-#: ../content/pages/versions.md:block 37 (unordered list)
-msgid "Improve CSP of the extension pages, fix broken favicons in FPD report"
-msgstr ""
-
-#: ../content/pages/versions.md:block 37 (unordered list)
-msgid ""
-"NBS: Block requests to undefined IP address (0.0.0.0 or [::]) but do not "
-"show notifications"
-msgstr ""
-
-#: ../content/pages/versions.md:block 37 (unordered list)
-msgid "Fix extension initialization in permanent private mode"
-msgstr ""
-
-#: ../content/pages/versions.md:block 37 (unordered list)
-msgid "options: Add external links to JShelter.org FAQ and threat model"
-msgstr ""
-
-#: ../content/pages/versions.md:block 37 (unordered list)
-msgid "Add favicons to options pages"
-msgstr ""
-
-#: ../content/pages/versions.md:block 37 (unordered list)
-msgid "Remove unused icons"
-msgstr ""
-
-#: ../content/pages/versions.md:block 38 (header)
-msgid "0.10"
-msgstr ""
-
-#: ../content/pages/versions.md:block 39 (unordered list)
-msgid ""
-"Add wrappers modifying calls detecting supported media types and installed "
-"codecs (Multimedia playback), github issue 66"
-msgstr ""
-
-#: ../content/pages/versions.md:block 39 (unordered list)
-msgid ""
-"Add wrappers modifying `HTMLMediaElement.prototype.canPlayType` (Multimedia "
-"playback)"
-msgstr ""
-
-#: ../content/pages/versions.md:block 39 (unordered list)
-msgid ""
-"Add wrappers disabling Network Information API inspired by Brave, github "
-"issue 66"
-msgstr ""
-
-#: ../content/pages/versions.md:block 39 (unordered list)
-msgid "Add wrappers disabling Web NFC API, github issue 66"
-msgstr ""
-
-#: ../content/pages/versions.md:block 39 (unordered list)
-msgid ""
-"Add wrappers for Cooperative Scheduling of Background Tasks API, github "
-"issue 66"
-msgstr ""
-
-#: ../content/pages/versions.md:block 39 (unordered list)
-msgid "Add wrappers for User idle detection, github issue 66"
-msgstr ""
-
-#: ../content/pages/versions.md:block 39 (unordered list)
-msgid ""
-"Add possibility to set NBS as passive (notify user but do not block), github"
-" issue 66"
-msgstr ""
-
-#: ../content/pages/versions.md:block 39 (unordered list)
-msgid "Fix Web Audio wrappers (Pagure issue #16)"
-msgstr ""
-
-#: ../content/pages/versions.md:block 39 (unordered list)
-msgid "FPD Report allows exporting data as JSON"
-msgstr ""
-
-#: ../content/pages/versions.md:block 39 (unordered list)
-msgid "Modified FPD wrappers independent on JSS"
-msgstr ""
-
-#: ../content/pages/versions.md:block 39 (unordered list)
-msgid ""
-"FPD can be configured as strict (more aggressive fingerprinting detection)"
-msgstr ""
-
-#: ../content/pages/versions.md:block 39 (unordered list)
-msgid ""
-"Better storages removal through content script in the absence of browserData"
-" permissions by FPD"
-msgstr ""
-
-#: ../content/pages/versions.md:block 39 (unordered list)
-msgid ""
-"Fix early loading of module configuration (FPD used to be disabled after "
-"first installation)"
-msgstr ""
-
-#: ../content/pages/versions.md:block 39 (unordered list)
-msgid "FPD initialization reworked"
-msgstr ""
-
-#: ../content/pages/versions.md:block 39 (unordered list)
-msgid ""
-"Add support for customizing settings for file:// scheme (Github issue #180)"
-msgstr ""
-
-#: ../content/pages/versions.md:block 39 (unordered list)
-msgid "Improve config checker in advanced options"
-msgstr ""
-
-#: ../content/pages/versions.md:block 39 (unordered list)
-msgid "Improved English, naming consistency, and some descriptions"
-msgstr ""
-
-#: ../content/pages/versions.md:block 39 (unordered list)
-msgid "Apply Content-Security-Policy to webextension pages"
-msgstr ""
-
-#: ../content/pages/versions.md:block 39 (unordered list)
-msgid ""
-"Fix some issues with invalid domains in advanced JavaScript Shield "
-"configuration (Pagure issue 45)"
-msgstr ""
-
-#: ../content/pages/versions.md:block 40 (header)
-msgid "0.9"
-msgstr ""
-
-#: ../content/pages/versions.md:block 41 (unordered list)
-msgid ""
-"Firefox: deactivate window.name wrapper for Firefox; Firefox provides "
-"protection since 88 and JShelter wrapper brakes pages"
-msgstr ""
-
-#: ../content/pages/versions.md:block 41 (unordered list)
-msgid ""
-"Enable webworker wrappers by default, see the paper "
-"https://arxiv.org/abs/2204.01392, §4.3"
-msgstr ""
-
-#: ../content/pages/versions.md:block 41 (unordered list)
-msgid "Tidy up popup UI and FPD report UI"
-msgstr ""
-
-#: ../content/pages/versions.md:block 41 (unordered list)
-msgid "Show wrapper groups descriptions in options.html"
-msgstr ""
-
-#: ../content/pages/versions.md:block 42 (header)
-msgid "0.8.1"
-msgstr ""
-
-#: ../content/pages/versions.md:block 43 (unordered list)
-msgid ""
-"Add \"Turn fingerprinting protection off\" level. As the AFPD shows the "
-"likelihood of fingerprinting, some users might be tempted to trade some "
-"performance gain for no protection against fingerprinting. See for example "
-"Github #179."
-msgstr ""
-
-#: ../content/pages/versions.md:block 43 (unordered list)
-msgid "Fix displaying empty FPD report"
-msgstr ""
-
-#: ../content/pages/versions.md:block 44 (header)
-msgid "0.8"
-msgstr ""
-
-#: ../content/pages/versions.md:block 45 (unordered list)
-msgid "Add FPD report page"
-msgstr ""
-
-#: ../content/pages/versions.md:block 45 (unordered list)
-msgid "Show fingerprinting likelihood in the popup and badge icon colour"
-msgstr ""
-
-#: ../content/pages/versions.md:block 45 (unordered list)
-msgid ""
-"GPS wrapper reimplemented to use farbling (simulate a stationary device for "
-"per domain and sessions), previously each page load generated a new position"
-msgstr ""
-
-#: ../content/pages/versions.md:block 45 (unordered list)
-msgid "Reorganize canvas reading wrappers, all are in the same group"
-msgstr ""
-
-#: ../content/pages/versions.md:block 45 (unordered list)
-msgid "Security review and hardening of the wrappers"
-msgstr ""
-
-#: ../content/pages/versions.md:block 45 (unordered list)
-msgid "Do not change values depending on activated tweaks"
-msgstr ""
-
-#: ../content/pages/versions.md:block 45 (unordered list)
-msgid "Remove obvious reversibility of the canvas farbling"
-msgstr ""
-
-#: ../content/pages/versions.md:block 45 (unordered list)
-msgid "Unify wrapping between H-C and WEBGL"
-msgstr ""
-
-#: ../content/pages/versions.md:block 45 (unordered list)
-msgid ""
-"Unify the wrappers in Strict and Farbling wrapping of WebGL parameters (some"
-" were farbled but not disabled on Strict)"
-msgstr ""
-
-#: ../content/pages/versions.md:block 45 (unordered list)
-msgid ""
-"Farbling of WebGL parameters spread more wildly to hide the correct number "
-"(that might have been revealed after several visits)"
-msgstr ""
-
-#: ../content/pages/versions.md:block 45 (unordered list)
-msgid "WebGL: Farble renderer and vendor the same way as unmasked versions"
-msgstr ""
-
-#: ../content/pages/versions.md:block 45 (unordered list)
-msgid ""
-"Remove possible dependencies between multiple wrapping groups using "
-"randomString()"
-msgstr ""
-
-#: ../content/pages/versions.md:block 45 (unordered list)
-msgid ""
-"Strict: Return empty UNMASKED VENDOR and RENDERER - Previosuly, these values"
-" depended on the domainHash, that meant that the unique value could be used "
-"to uniquely fingerprint the device."
-msgstr ""
-
-#: ../content/pages/versions.md:block 45 (unordered list)
-msgid "Harden WEBA farbling"
-msgstr ""
-
-#: ../content/pages/versions.md:block 45 (unordered list)
-msgid ""
-"Scramble the output of PRNG with domainHash to prevent guessing the future "
-"PRNs"
-msgstr ""
-
-#: ../content/pages/versions.md:block 45 (unordered list)
-msgid ""
-"Try to improve speed as possible but the wrapping is likely slower than "
-"0.7.x"
-msgstr ""
-
-#: ../content/pages/versions.md:block 45 (unordered list)
-msgid ""
-"Github #125: Add option to disable NBS notifications, limit the number of "
-"notifications"
-msgstr ""
-
-#: ../content/pages/versions.md:block 45 (unordered list)
-msgid ""
-"Fix Pagure #18 Optional permissions for AFPD - it is not necessary to give "
-"browsingData"
-msgstr ""
-
-#: ../content/pages/versions.md:block 45 (unordered list)
-msgid ""
-"Allowlist options in NBS and FPD changed breaking backwards compatibility"
-msgstr ""
-
-#: ../content/pages/versions.md:block 45 (unordered list)
-msgid ""
-"When optionally activated, wrap BigInt typed arrays the same way as other "
-"typed arrays"
-msgstr ""
-
-#: ../content/pages/versions.md:block 46 (header)
-msgid "0.7.1"
-msgstr ""
-
-#: ../content/pages/versions.md:block 47 (unordered list)
-msgid "Apply proper shielding for `navigator.plugins` in Firefox."
-msgstr ""
-
-#: ../content/pages/versions.md:block 47 (unordered list)
-msgid ""
-"Hide FPD notification after a while to prevent windows notification spam in "
-"chromium-based browsers"
-msgstr ""
-
-#: ../content/pages/versions.md:block 48 (header)
-msgid "0.7"
-msgstr ""
-
-#: ../content/pages/versions.md:block 49 (unordered list)
-msgid "JavaScript Restrictor rebranded to JShelter."
-msgstr ""
-
-#: ../content/pages/versions.md:block 49 (unordered list)
-msgid ""
-"The extension officially consists of JavaScript Shield (originally called "
-"wrappers), NBS, and FPD. Unified way to disable each component in the pop "
-"up. This should prevent users from disabling NBS thinking they disabled JSS."
-msgstr ""
-
-#: ../content/pages/versions.md:block 49 (unordered list)
-msgid "New UI to create and tweak JavaScript Shield levels."
-msgstr ""
-
-#: ../content/pages/versions.md:block 49 (unordered list)
-msgid ""
-"Pop up redesigned. Try not to confuse the user about global/per-page "
-"settings."
-msgstr ""
-
-#: ../content/pages/versions.md:block 49 (unordered list)
-msgid ""
-"It is possible to create per-domain JavaScript Shield tweaks, i.e. enable or"
-" disable specific group of wrappers for certain domain only without the "
-"necessity to create a new level."
-msgstr ""
-
-#: ../content/pages/versions.md:block 49 (unordered list)
-msgid "The wrapping strength is defined by the user with a range input."
-msgstr ""
-
-#: ../content/pages/versions.md:block 49 (unordered list)
-msgid ""
-"The badge icon does not show level ID anymore. JShelter shows the number of "
-"wrapping groups accessed by the current page. Report the number of calls for"
-" wrapped APIs in the pop up."
-msgstr ""
-
-#: ../content/pages/versions.md:block 49 (unordered list)
-msgid "Level 1 removed as it was not properly maintained."
-msgstr ""
-
-#: ../content/pages/versions.md:block 49 (unordered list)
-msgid "Timestamp protection in level 2 increased to match level 3."
-msgstr ""
-
-#: ../content/pages/versions.md:block 49 (unordered list)
-msgid ""
-"XHR wrappings and (sharred) array buffers not wrapped anymore as XHR is "
-"superseded by FPD and array buffers break other APIs."
-msgstr ""
-
-#: ../content/pages/versions.md:block 49 (unordered list)
-msgid "New experimental level added that is based on original level 3."
-msgstr ""
-
-#: ../content/pages/versions.md:block 49 (unordered list)
-msgid "Better and much longer description of built-in levels."
-msgstr ""
-
-#: ../content/pages/versions.md:block 49 (unordered list)
-msgid ""
-"Added support for device rotation. Accelerometer, LinearAccelerationSensor, "
-"GravitySensor, and Magnetometer now adjust the gravity vector by the "
-"rotation matrix."
-msgstr ""
-
-#: ../content/pages/versions.md:block 49 (unordered list)
-msgid ""
-"AmbientLightSensor, Gyroscope, AbsoluteOrientationSensor, and "
-"RelativeOrientationSensor wrappers added."
-msgstr ""
-
-#: ../content/pages/versions.md:block 49 (unordered list)
-msgid "Accessibility improvements in pop up."
-msgstr ""
-
-#: ../content/pages/versions.md:block 49 (unordered list)
-msgid ""
-"New colour scheme based on the logo and JShelter.org web site for both light"
-" and dark theme."
-msgstr ""
-
-#: ../content/pages/versions.md:block 49 (unordered list)
-msgid "Load FPD settings from advanced options correctly."
-msgstr ""
-
-#: ../content/pages/versions.md:block 49 (unordered list)
-msgid ""
-"Some inconsistences in update mechanism of hardware and enumerateDevices "
-"found and fixed."
-msgstr ""
-
-#: ../content/pages/versions.md:block 49 (unordered list)
-msgid ""
-"Level settings are not backward-comptible, backup 0.6.x configuration if you"
-" plan to downgrade."
-msgstr ""
-
-#: ../content/pages/versions.md:block 50 (header)
-msgid "0.6.5"
-msgstr ""
-
-#: ../content/pages/versions.md:block 51 (unordered list)
-msgid "Update NSCL to work around a change in Chrome permissions:"
-msgstr ""
-
-#: ../content/pages/versions.md:block 51 (unordered list)
-msgid ""
-"Use HTTPS endpoint for Chromium (works around lack of file access by default"
-" on packed extensions), see also "
-"https://forums.informaction.com/viewtopic.php?p=104921#p104921"
-msgstr ""
-
-#: ../content/pages/versions.md:block 51 (unordered list)
-msgid ""
-"Also includes a work-around for object element initialization "
-"inconsistencies on Firefox"
-msgstr ""
-
-#: ../content/pages/versions.md:block 52 (header)
-msgid "0.6.4"
-msgstr ""
-
-#: ../content/pages/versions.md:block 53 (unordered list)
-msgid ""
-"Fix wrapping of `navigator.plugins` in Firefox. This regression appeared in "
-"0.6 in the generated code restricted by `apply_if` condition."
-msgstr ""
-
-#: ../content/pages/versions.md:block 54 (header)
-msgid "0.6.3"
-msgstr ""
-
-#: ../content/pages/versions.md:block 55 (unordered list)
-msgid ""
-"Make sure that dynamically created iframes are not vulnerable to leaking "
-"unwrapped APIs (Update NSCL)"
-msgstr ""
-
-#: ../content/pages/versions.md:block 55 (unordered list)
-msgid "Fix FPD when run in a limited environment"
-msgstr ""
-
-#: ../content/pages/versions.md:block 55 (unordered list)
-msgid "Do not interfere with time explicitly given to Date object"
-msgstr ""
-
-#: ../content/pages/versions.md:block 55 (unordered list)
-msgid "Fix Network Boundary Shield name in the popup"
-msgstr ""
-
-#: ../content/pages/versions.md:block 56 (header)
-msgid "0.6.2"
-msgstr ""
-
-#: ../content/pages/versions.md:block 57 (unordered list)
-msgid ""
-"Fix required permissions for Chromium-based browsers - webNavigation is not "
-"needed"
-msgstr ""
-
-#: ../content/pages/versions.md:block 58 (header)
-msgid "0.6.1"
-msgstr ""
-
-#: ../content/pages/versions.md:block 59 (unordered list)
-msgid "Disable FPD by default, you are welcome to opt-in"
-msgstr ""
-
-#: ../content/pages/versions.md:block 59 (unordered list)
-msgid "Provide access to advanced options from the main options page"
-msgstr ""
-
-#: ../content/pages/versions.md:block 59 (unordered list)
-msgid "Fix update script to migrate to new configuration"
-msgstr ""
-
-#: ../content/pages/versions.md:block 60 (header)
-msgid "0.6"
-msgstr ""
-
-#: ../content/pages/versions.md:block 61 (unordered list)
-msgid ""
-"New protection: Fingerprint detector, see the blogpost for explanation."
-msgstr ""
-
-#: ../content/pages/versions.md:block 61 (unordered list)
-msgid ""
-"Physical environment wrapper group added. It contains `Sensor`, "
-"`Magnetometer`, `Accelerometer`, `LinearAccelerationSensor`, `GravitySensor`"
-" wrappers. Some readings might be inconsistent. `Gyroscope` and "
-"`Orientation` sensors will be a part of a future release."
-msgstr ""
-
-#: ../content/pages/versions.md:block 61 (unordered list)
-msgid "It is possible to import/export configuration (Github issue #159)."
-msgstr ""
-
-#: ../content/pages/versions.md:block 61 (unordered list)
-msgid "Improved accessibility of the pop up and option pages."
-msgstr ""
-
-#: ../content/pages/versions.md:block 61 (unordered list)
-msgid ""
-"Bugfix: Fix double injection of some wrappers. For example, this solves "
-"regression in Geolocation wrapper introduced in 0.5."
-msgstr ""
-
-#: ../content/pages/versions.md:block 62 (header)
-msgid "0.5.5"
-msgstr ""
-
-#: ../content/pages/versions.md:block 63 (unordered list)
-msgid "Tighter content script initialization"
-msgstr ""
-
-#: ../content/pages/versions.md:block 63 (unordered list)
-msgid ""
-"Bugfix: wrap `Navigator.prototype` and `Geolocation.prototype` instead of "
-"`navigator` and `navigator.geolocation`"
-msgstr ""
-
-#: ../content/pages/versions.md:block 63 (unordered list)
-msgid ""
-"Remove additional Geolocation API objects when Geolocation is disabled "
-"completely"
-msgstr ""
-
-#: ../content/pages/versions.md:block 63 (unordered list)
-msgid "Icons updated and synced with the JShelter website"
-msgstr ""
-
-#: ../content/pages/versions.md:block 64 (header)
-msgid "0.5.4"
-msgstr ""
-
-#: ../content/pages/versions.md:block 65 (unordered list)
-msgid "Dark style support added (Github issue #134)"
-msgstr ""
-
-#: ../content/pages/versions.md:block 65 (unordered list)
-msgid "Bugfix: Removal of debugging noise (Github issue #139)"
-msgstr ""
-
-#: ../content/pages/versions.md:block 65 (unordered list)
-msgid ""
-"Bugfix: Allow removal of user-defined levels with names of a built-in level"
-msgstr ""
-
-#: ../content/pages/versions.md:block 65 (unordered list)
-msgid ""
-"Bugfix: Make sure that all user-defined levels are displayed in \"Specific "
-"domain level configuration\" settings page"
-msgstr ""
-
-#: ../content/pages/versions.md:block 65 (unordered list)
-msgid "Bugfix: Ignore non-existing levels for a specific domain"
-msgstr ""
-
-#: ../content/pages/versions.md:block 66 (header)
-msgid "0.5.3"
-msgstr ""
-
-#: ../content/pages/versions.md:block 67 (unordered list)
-msgid ""
-"Bugfix: Cascade top document's level to subframes with no explicitly "
-"assigned level. (workaround for Github issue #133)."
-msgstr ""
-
-#: ../content/pages/versions.md:block 67 (unordered list)
-msgid "Bugfix: Improve IPv6 handling in NBS"
-msgstr ""
-
-#: ../content/pages/versions.md:block 67 (unordered list)
-msgid ""
-"Bugfix (Chromium-based browsers): Fix per-domain level options/settings page"
-" (Github issue #147)"
-msgstr ""
-
-#: ../content/pages/versions.md:block 67 (unordered list)
-msgid ""
-"Do not display NBS notifications when accessing 0.0.0.0 and :: (workaround "
-"for Github issue #125)"
-msgstr ""
-
-#: ../content/pages/versions.md:block 67 (unordered list)
-msgid "Improve NBS description in the option/settings page."
-msgstr ""
-
-#: ../content/pages/versions.md:block 67 (unordered list)
-msgid "Display level names in the pop up to improve usability."
-msgstr ""
-
-#: ../content/pages/versions.md:block 68 (header)
-msgid "0.5.2"
-msgstr ""
-
-#: ../content/pages/versions.md:block 69 (unordered list)
-msgid ""
-"Bugfix: Do not modify JS environment on level 0. Regression appeared in 0.5."
-msgstr ""
-
-#: ../content/pages/versions.md:block 70 (header)
-msgid "0.5.1"
-msgstr ""
-
-#: ../content/pages/versions.md:block 71 (unordered list)
-msgid ""
-"Bugfix: Display correctly NBS status at the current page (Github issue #114)"
-msgstr ""
-
-#: ../content/pages/versions.md:block 71 (unordered list)
-msgid "Rebranding step 1: change UI-facing icons"
-msgstr ""
-
-#: ../content/pages/versions.md:block 71 (unordered list)
-msgid ""
-"Set minimal pop up width so that the pop up is usable in Chrome (Github "
-"issue #112, Pagure issue #7)"
-msgstr ""
-
-#: ../content/pages/versions.md:block 71 (unordered list)
-msgid ""
-"Chromium-based browsers: revise Battery API protection that should match the"
-" expectations of page scripts (mimic Firefox behaviour)."
-msgstr ""
-
-#: ../content/pages/versions.md:block 71 (unordered list)
-msgid "Fixed typos in settings."
-msgstr ""
-
-#: ../content/pages/versions.md:block 72 (header)
-msgid "0.5"
-msgstr ""
-
-#: ../content/pages/versions.md:block 73 (unordered list)
-msgid ""
-"Add fingerprinting defenses based on Farbling developed by the Brave browser"
-" (improved or added wrappers for Canvas, Audio, WebGL, device memory, "
-"hardware concurrency, enumerateDevices). Most wrappers support provisioning "
-"of little lies that differ between origins and sessions (the fingeprint is "
-"different across origins and across sessions)."
-msgstr ""
-
-#: ../content/pages/versions.md:block 73 (unordered list)
-msgid ""
-"We claimed to generate white image fake Canvas value but instead generated "
-"fully transparent black image. We now generate the white image as it is more"
-" common in other anti-canvas fingerprinting tools (level 3)."
-msgstr ""
-
-#: ../content/pages/versions.md:block 73 (unordered list)
-msgid "toDataUrl() no longer destructs the original canvas."
-msgstr ""
-
-#: ../content/pages/versions.md:block 73 (unordered list)
-msgid ""
-"We use NoScript Commons Library to simplify some tasks like cross-browser "
-"support."
-msgstr ""
-
-#: ../content/pages/versions.md:block 73 (unordered list)
-msgid "More reliable early content script configuration."
-msgstr ""
-
-#: ../content/pages/versions.md:block 73 (unordered list)
-msgid ""
-"CSP headers no longer prevents the extension from wrapping JS APIs in "
-"Firefox (Github issue #25)"
-msgstr ""
-
-#: ../content/pages/versions.md:block 73 (unordered list)
-msgid ""
-"Wrappers should be injected reliably before page scripts start to operate "
-"(Github issue #40)"
-msgstr ""
-
-#: ../content/pages/versions.md:block 73 (unordered list)
-msgid "We use NSCL to wrap APIs in iframes and workers"
-msgstr ""
-
-#: ../content/pages/versions.md:block 73 (unordered list)
-msgid ""
-"It is no longer possible to access unwrapped functions from iframes and "
-"workers (Pagure issue #2, Github issue #56)"
-msgstr ""
-
-#: ../content/pages/versions.md:block 73 (unordered list)
-msgid ""
-"Ignore trailing '.' in domain names when selecting appropriate custom level."
-msgstr ""
-
-#: ../content/pages/versions.md:block 73 (unordered list)
-msgid ""
-"Do not freeze wrappers to prevent fingerprintability of the users of "
-"JShelter. We wrap the correct function in the prototype chain instead."
-msgstr ""
-
-#: ../content/pages/versions.md:block 73 (unordered list)
-msgid "navigator.getGamepads() wrapper added"
-msgstr ""
-
-#: ../content/pages/versions.md:block 73 (unordered list)
-msgid "navigator.activeVRDisplays() and navigator.xr wrappers added"
-msgstr ""
-
-#: ../content/pages/versions.md:block 73 (unordered list)
-msgid ""
-"Limit precision of high resolution timestamps in the Event, VRFrameData, and"
-" Gamepad interface to be consistent with Date and Performance precision"
-msgstr ""
-
-#: ../content/pages/versions.md:block 74 (header)
-msgid "0.4.7"
-msgstr ""
-
-#: ../content/pages/versions.md:block 75 (unordered list)
-msgid "Wrap Beacon API"
-msgstr ""
-
-#: ../content/pages/versions.md:block 75 (unordered list)
-msgid "Bugfix: inject content scripts to all iframes"
-msgstr ""
-
-#: ../content/pages/versions.md:block 75 (unordered list)
-msgid ""
-"Fix exception throwing in the code generator dealing with Firefox bug "
-"1267027"
-msgstr ""
-
-#: ../content/pages/versions.md:block 76 (header)
-msgid "0.4.6"
-msgstr ""
-
-#: ../content/pages/versions.md:block 77 (unordered list)
-msgid ""
-"NBS improvements for Chromium-based browsers: block a host after detecting "
-"the first suspicious HTTP request from the public to the private network."
-msgstr ""
-
-#: ../content/pages/versions.md:block 78 (header)
-msgid "0.4.5"
-msgstr ""
-
-#: ../content/pages/versions.md:block 79 (unordered list)
-msgid "Add wrapper of MediaDevices.prototype.enumerateDevices"
-msgstr ""
-
-#: ../content/pages/versions.md:block 79 (unordered list)
-msgid "Fix missing Date properties"
-msgstr ""
-
-#: ../content/pages/versions.md:block 79 (unordered list)
-msgid "Fix Geolocation overflows appearing near poles"
-msgstr ""
-
-#: ../content/pages/versions.md:block 79 (unordered list)
-msgid "Improve handling of domain names (URLs):"
-msgstr ""
-
-#: ../content/pages/versions.md:block 79 (unordered list)
-msgid "Handle IPv4 addresses used as hostnames correctly"
-msgstr ""
-
-#: ../content/pages/versions.md:block 79 (unordered list)
-msgid ""
-"Do not treat TLD specially and allow specifying wrapping levels for TLDs"
-msgstr ""
-
-#: ../content/pages/versions.md:block 79 (unordered list)
-msgid "Fix handling of two-letters 2-nd level domains"
-msgstr ""
-
-#: ../content/pages/versions.md:block 80 (header)
-msgid "0.4.4"
-msgstr ""
-
-#: ../content/pages/versions.md:block 81 (unordered list)
-msgid ""
-"Bugfix: Do not try to redefine undefined objects. The exceptions thrown in "
-"injected code used to prevent application of all the wrapping code."
-msgstr ""
-
-#: ../content/pages/versions.md:block 82 (header)
-msgid "0.4.3"
-msgstr ""
-
-#: ../content/pages/versions.md:block 83 (unordered list)
-msgid "Add an option to clear `window.name` with each page reload."
-msgstr ""
-
-#: ../content/pages/versions.md:block 84 (header)
-msgid "0.4.2"
-msgstr ""
-
-#: ../content/pages/versions.md:block 85 (unordered list)
-msgid ""
-"Rewrite the NBS for Chromium-based browsers with custom DNS cache build with"
-" resolved data available in onResponseStartedListener()"
-msgstr ""
-
-#: ../content/pages/versions.md:block 86 (header)
-msgid "0.4.1"
-msgstr ""
-
-#: ../content/pages/versions.md:block 87 (unordered list)
-msgid ""
-"Fix the amount of saved data through pop-up (for a specific domain), it is "
-"much harder to reach the quoa"
-msgstr ""
-
-#: ../content/pages/versions.md:block 88 (header)
-msgid "0.4"
-msgstr ""
-
-#: ../content/pages/versions.md:block 89 (unordered list)
-msgid "Re-introduced Geolocation API wrapping (several settings available)."
-msgstr ""
-
-#: ../content/pages/versions.md:block 90 (header)
-msgid "0.3.2"
-msgstr ""
-
-#: ../content/pages/versions.md:block 91 (unordered list)
-msgid "Bugfix: Set up domain-specific levels from storage correctly"
-msgstr ""
-
-#: ../content/pages/versions.md:block 91 (unordered list)
-msgid ""
-"Wrap PerformanceEntry instead of performance.getEntries\\*() - prevents a "
-"known leak of precise time stamps in Chromium-based browsers."
-msgstr ""
-
-#: ../content/pages/versions.md:block 91 (unordered list)
-msgid "Add note on the effectivity of time randomization"
-msgstr ""
-
-#: ../content/pages/versions.md:block 91 (unordered list)
-msgid ""
-"Firefox fix background and content scripts synchronization, use correct "
-"naming (improves speed)"
-msgstr ""
-
-#: ../content/pages/versions.md:block 91 (unordered list)
-msgid ""
-"Time wrappers in Firefox affected by the <a "
-"href=\"https://bugzilla.mozilla.org/show_bug.cgi?id=1267027\">Fiefox CSP "
-"bug</a> should work better. However, the precise timers are not wrapped, see"
-" also <a href=\"https://github.com/polcak/jsrestrictor/issues/25\">#25</a>."
-msgstr ""
-
-#: ../content/pages/versions.md:block 91 (unordered list)
-msgid "NBS message for Chromium-based browsers reworded."
-msgstr ""
-
-#: ../content/pages/versions.md:block 92 (header)
-msgid "0.3.1"
-msgstr ""
-
-#: ../content/pages/versions.md:block 93 (unordered list)
-msgid "Improve compatibility with Chromium based browsers"
-msgstr ""
-
-#: ../content/pages/versions.md:block 94 (header)
-msgid "0.3"
-msgstr ""
-
-#: ../content/pages/versions.md:block 95 (unordered list)
-msgid "Major code rewrite - make the code more modular, remove duplications"
-msgstr ""
-
-#: ../content/pages/versions.md:block 95 (unordered list)
-msgid ""
-"Add wrappings inspired by [JavaScript Zero: Real JavaScript and Zero S ide-"
-"Channel Attacks](https://misc0110.net/web/files/jszero.pdf)"
-msgstr ""
-
-#: ../content/pages/versions.md:block 95 (unordered list)
-msgid ""
-"Network Boundary Shield prevents web pages to use the browser as a proxy "
-"between local network and the public Internet. See the [Force Point "
-"report](https://www.forcepoint.com/sites/default/files/resources/files/report-"
-"attacking-internal-network-en_0.pdf) for an example of the attack. The "
-"protection encapsulates the WebRequest API, so it captures all outgoing "
-"requests."
-msgstr ""
-
-#: ../content/pages/versions.md:block 95 (unordered list)
-msgid "Allow multiple custom levels"
-msgstr ""
-
-#: ../content/pages/versions.md:block 95 (unordered list)
-msgid ""
-"Do not modify DOM of displayed pages (the modifications were detectable by "
-"the page scripts and may reveal that the user is running JShelter)"
-msgstr ""
-
-#: ../content/pages/versions.md:block 95 (unordered list)
-msgid ""
-"Canvas fingerprinting: originally, only `toDataURL` was blocked. The "
-"extension now blocks `CanvasRenderingContext2D.prototype.getImageData` and "
-"`HTMLCanvasElement.prototype.toBlob`."
-msgstr ""
-
-#: ../content/pages/versions.md:block 95 (unordered list)
-msgid "Block additionaly methods to get performance data."
-msgstr ""
-
-#: ../content/pages/versions.md:block 95 (unordered list)
-msgid ""
-"Unfortunately, we do not migrate old settings as the levels were redesigned "
-"and several features were removed. We expect to migrate previous settings in"
-" the future."
-msgstr ""
-
-#: ../content/pages/versions.md:block 95 (unordered list)
-msgid ""
-"Initial attempt to deal with a bug "
-"<https://bugzilla.mozilla.org/show_bug.cgi?id=1267027> but it does not work "
-"completely as expected, yet."
-msgstr ""
-
-#: ../content/pages/versions.md:block 95 (unordered list)
-msgid ""
-"Make sure that calling toString on the wrapped function does not leak the "
-"wrapping code."
-msgstr ""
-
-#: ../content/pages/versions.md:block 95 (unordered list)
-msgid "Fix original canvas method leaks through iframes"
-msgstr ""
-
-#: ../content/pages/versions.md:block 95 (unordered list)
-msgid "Do not allow page scripts to delete wrappers"
-msgstr ""
-
-#: ../content/pages/versions.md:block 95 (unordered list)
-msgid "GUI rewritten."
-msgstr ""
-
-#: ../content/pages/versions.md:block 95 (unordered list)
-msgid ""
-"Do not open the main page after browser or extension update as it is "
-"irritating and may send a signal that the user is tracked."
-msgstr ""
-
-#: ../content/pages/versions.md:block 95 (unordered list)
-msgid ""
-"*Removed feature* Do not change request HTTP headers. See the paper FP-"
-"Scanner: The privacy implications of browser fingerprint inconsistencies and"
-" pages like "
-"<https://ghacksuserjs.github.io/TorZillaPrint/TorZillaPrint.html>."
-msgstr ""
-
-#: ../content/pages/versions.md:block 95 (unordered list)
-msgid ""
-"*Removed feature* GPS/location is not blocked anymore, we expect to "
-"reintroduce this feature in the future."
-msgstr ""
-
-#: ../content/pages/versions.md:block 96 (header)
-msgid "0.2.1"
-msgstr ""
-
-#: ../content/pages/versions.md:block 97 (unordered list)
-msgid ""
-"Fix `Date` wrapping that used to break some pages; `Date` wrapping code "
-"improved"
-msgstr ""
-
-#: ../content/pages/versions.md:block 97 (unordered list)
-msgid "Improve `XMLHttpRequest` wrapping"
-msgstr ""
-
-#: ../content/pages/versions.md:block 98 (header)
-msgid "0.2"
-msgstr ""
-
-#: ../content/pages/versions.md:block 99 (unordered list)
-msgid "Additional APIs that can be wrapped:"
-msgstr ""
-
-#: ../content/pages/versions.md:block 99 (unordered list)
-msgid ""
-"`navigator` properties: `userAgent`, `vendor`, `platform`, `appVersion`, "
-"`oscpu`, `language`, `languages`"
-msgstr ""
-
-#: ../content/pages/versions.md:block 99 (unordered list)
-msgid "`document` properties: `referrer`"
-msgstr ""
-
-#: ../content/pages/versions.md:block 100 (header)
-msgid "0.1"
-msgstr ""
-
-#: ../content/pages/versions.md:block 101 (unordered list)
-msgid "Initial public version"
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 1 (paragraph)
-msgid "Title: Instructions on how to run unit tests"
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 2 (header)
-msgid "on Linux"
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 3 (ordered list)
-msgid "Install [NodeJS](https://nodejs.org)."
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 3 (ordered list)
-msgid "Install `jq` and another necessary tools (e.g. `sed`)."
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 3 (ordered list)
-msgid "Open Terminal."
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 3 (ordered list)
-msgid "Run `npm install`."
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 3 (ordered list)
-msgid "Run `npm test`."
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 4 (header)
-msgid "on Windows"
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 5 (ordered list)
-msgid ""
-"Convert EOL in the script *./start_unit_tests.sh* from Windows (CR LF) to "
-"Unix (LF) - you can use the tool `dos2unix` in WSL to convert CR LF to LF."
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 5 (ordered list)
-msgid ""
-"Follow the instructions for Linux. Install NodeJS and run the following "
-"commands in WSL."
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 6 (header)
-msgid "Developer documentation"
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 7 (header)
-msgid "The framework"
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 8 (paragraph)
-msgid ""
-"The test cases are based on top of Jasmine framework. `start_unit_tests.sh` "
-"preprocesses the files using shell commands. Use `bash` if in doubt. Patches"
-" for other shells might be accepted but will probably not be supported by "
-"the core team."
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 9 (header)
-msgid "Structure"
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 10 (paragraph)
-msgid ""
-"The test cases are stored in the `tests` directory. The file names typically"
-" mirror the tested files in the `common` webextension directory with the "
-"suffix `_tests.js`. Each file and its requirements needs to be registered in"
-" `config/global.json` file."
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 11 (paragraph)
-msgid "The configuration file stores for each test:"
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 13 (unordered list)
-msgid "`name` represents the tested file name (no `_tests.js` suffix)"
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 13 (unordered list)
-msgid ""
-"`remove_custom_namespace` modifies the source file to remove the IIFE to "
-"make its internals global. This is typically necessary to test wrappers that"
-" commonly create IIFE."
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 13 (unordered list)
-msgid ""
-"`let_to_var` allows transforming all let variables to var variables. This "
-"might be necessary to transform inner variables but might modify the "
-"behaviour. Set to `false` unless you have good reason for the modification."
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 13 (unordered list)
-msgid ""
-"`src_script_requirements` allows specifying dependencies of the file under "
-"test (the file used by the webextension)."
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 13 (unordered list)
-msgid ""
-"`test_script_requirements` allows specifying dependencies of the file with "
-"test cases (the file with the `_tests.js` suffix)."
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 13 (unordered list)
-msgid ""
-"`extra_exports` appends export line to the file under test and imports these"
-" objects to the file with the test cases."
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 13 (unordered list)
-msgid ""
-"`replace_in_src` allows replacing lines in the file under test with a "
-"different code, use with caution as this modifies the behaviour."
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 13 (unordered list)
-msgid ""
-"`inject_code_to_src` allows injecting additional code to the file under "
-"test. Currently only inserting to `begin` (first line) and `end` (last line)"
-" are supported."
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 14 (paragraph)
-msgid ""
-"Note that the preprocessor (`start_unit_tests.sh`) modifies the files under "
-"test and the file with test cases according to the instuctions in "
-"`global.json`. The files are temporarily stored in the `tmp` directory."
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 15 (header)
-msgid "Add new unit tests if a test set already exists"
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 16 (paragraph)
-msgid ""
-"If a test set already exists for the target modul (e.g. a test set "
-"*background_tests.js* for the *background.js* file), you can add your own "
-"tests to the test script (e.g. to the *background_tests.js* file)."
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 17 (paragraph)
-msgid ""
-"You may need to update the requirements in the global configuration "
-"(*./config/global.json* file). Open the global configuration file for "
-"editing and find the configuration of the target script (according to the "
-"`name` property). Add the necessary requirements to the "
-"`src_script_requirements` and `test_script_requirements` sections."
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 18 (header)
-msgid "Add new unit tests if a test set does not already exists"
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 19 (paragraph)
-msgid ""
-"If a test set does not already exists for the target modul (e.g. a test set "
-"*background_tests.js* for the *background.js* file), create new file (e.g. "
-"*background_tests.js* file) in the *./tests* directory. It is recommended to"
-" create a new test script by copying any existing test script, deleting its "
-"tests, and creating new ones."
-msgstr ""
-
-#: ../content/pages/unit_tests.md:block 20 (paragraph)
-msgid ""
-"When a new test script is created, add a new entry to the global "
-"configuration (*./config/global.json* file). The new entry must be created "
-"according to the example (*./config/global-example.json* file) and schema "
-"(*./config/global-schema.json* file)."
-msgstr ""
diff --git a/website/i18n/en/posts.po b/website/i18n/en/posts.po
deleted file mode 100644
index 87799d9..0000000
--- a/website/i18n/en/posts.po
+++ /dev/null
@@ -1,6196 +0,0 @@
-#
-msgid ""
-msgstr "Content-Type: text/plain; charset=utf-8\n"
-
-#: ../content/posts/cooperation.md:block 1 (header)
-msgid ""
-"title: Cooperation with the JShelter project, rebranding, and latest features\n"
-"date: 2022-03-17 15:00\n"
-"Series: JShelter background"
-msgstr ""
-
-#: ../content/posts/cooperation.md:block 2 (paragraph)
-msgid ""
-"This project started as JavaScript Restrictor at [Brno University of "
-"Technology](https://www.fit.vut.cz). As announced in [a previous "
-"post](/support), we got funding from NLNet [NGI0 PET "
-"Fund](https://nlnet.nl/project/JSRestrictor/). Furthermore, NLNet allowed us"
-" to cooperate with another NGI0 PET Fund project - [JShelter project "
-"(formerly known as JavaScript Shield project) run by Free Software "
-"Foundation](https://nlnet.nl/project/JavascriptShield/)."
-msgstr ""
-
-#: ../content/posts/cooperation.md:block 3 (paragraph)
-msgid ""
-"What did the cooperation bring to the users? More experience, more "
-"developers, new ideas. Let us go through the list."
-msgstr ""
-
-#: ../content/posts/cooperation.md:block 4 (header)
-msgid "1. Open development"
-msgstr ""
-
-#: ../content/posts/cooperation.md:block 5 (paragraph)
-msgid ""
-"We created [mailing list](https://lists.nongnu.org/archive/html/js-shield/) "
-"where we discussed the core issues of the development of the extension. We "
-"held weekly meetings with the minutes available in the mailing list "
-"archives."
-msgstr ""
-
-#: ../content/posts/cooperation.md:block 6 (header)
-msgid "2. Integration of NoScript Common Library"
-msgstr ""
-
-#: ../content/posts/cooperation.md:block 7 (paragraph)
-msgid ""
-"Giorgio Maone, the developer of NoScript Suite, is a part of the JShelter "
-"project. His recent efforts were in developing NoScript Common Library "
-"(NSCL). The library aims at simplifying the development of privacy and "
-"security-oriented web extensions with cross-browser support."
-msgstr ""
-
-#: ../content/posts/cooperation.md:block 8 (paragraph)
-msgid ""
-"Giorgio refactored the defence mechanism code injection and cross-browser "
-"support. Both now depend on NSCL."
-msgstr ""
-
-#: ../content/posts/cooperation.md:block 9 (paragraph)
-msgid ""
-"The improved code injection solved several long-term issues of the previous "
-"mechanism like (1) the uncertainty that the defences are inserted in time "
-"before page scripts have access to the environment and (2) the vulnerability"
-" to [Firefox bug](https://bugzilla.mozilla.org/show_bug.cgi?id=1267027) that"
-" did not allow to insert (full) defenses for pages relying on [CSP "
-"headers](https://content-security-policy.com/)."
-msgstr ""
-
-#: ../content/posts/cooperation.md:block 10 (paragraph)
-msgid ""
-"Improved cross-browser support should make the future lives of developers "
-"easier. Should there be a change like the switch to Manifest3, we will "
-"benefit from the effort put into NSCL."
-msgstr ""
-
-#: ../content/posts/cooperation.md:block 11 (header)
-msgid "3. Development of a new site"
-msgstr ""
-
-#: ../content/posts/cooperation.md:block 12 (paragraph)
-msgid ""
-"[Manufactura Independente](https://manufacturaindependente.org/), another "
-"participant of JShelter, created a new website for the extension, see "
-"<https://jshelter.org/>. Besides the polished structure and look, the new "
-"website allows generating documentation for the Javascript Shield wrappers "
-"directly from the comments in the source code. We do not have automatic "
-"updates, yet. But we are working on that."
-msgstr ""
-
-#: ../content/posts/cooperation.md:block 13 (header)
-msgid "4. Improved user interface"
-msgstr ""
-
-#: ../content/posts/cooperation.md:block 14 (paragraph)
-msgid ""
-"The original method of assigning JavaScript Shield levels of protection to "
-"each domain is nice to explain and should be easy to understand for users. "
-"However, as the number of protected APIs grew, it became clear that we "
-"needed to fine-tune the protection for each page for power users. For "
-"example, allow Geolocation API for maps or allow Media Devices on a video "
-"call application."
-msgstr ""
-
-#: ../content/posts/cooperation.md:block 15 (paragraph)
-msgid ""
-"The user often had to create a new level for each misbehaving domain. With "
-"time, the amount of levels becomes overwhelming, and the user needs to keep "
-"them in sync with the addition of the new APIs. Each version of the "
-"extension that adds new wrappers tries to guess how to modify user-defined "
-"levels to ease this task. But these modifications are not perfect."
-msgstr ""
-
-#: ../content/posts/cooperation.md:block 16 (paragraph)
-msgid ""
-"0.7 brought a redesigned UI and backend that allows fine-tuning JavaScript "
-"Shield protection for each domain. The new UI is a result of the effort of "
-"most of the developers of the extension."
-msgstr ""
-
-#: ../content/posts/cooperation.md:block 17 (paragraph)
-msgid "![visited page]({attach}/images/cooperation/fine-tuning.png)"
-msgstr ""
-
-#: ../content/posts/cooperation.md:block 18 (paragraph)
-msgid ""
-"0.6 introduced Fingerprint Detector that was improved in 0.8. The pop up "
-"shows the number of potentially suspicious calls and the likelihood of "
-"fingerprinting behaviour. The fingerprint report provides an explanation "
-"about the fingerprinting activities. Marek Saloň is the main author of the "
-"Fingerprint Detector."
-msgstr ""
-
-#: ../content/posts/cooperation.md:block 19 (paragraph)
-msgid ""
-"![FPD report shows the reasoning to claim that a page is fingerprinting the "
-"browser]({attach}/images/cooperation/fpd-report.png)"
-msgstr ""
-
-#: ../content/posts/cooperation.md:block 20 (paragraph)
-msgid ""
-"Marek also improved notifications so that the user cannot be overwhelmed by "
-"many similar notifications during a very short period. Starting from 0.8, it"
-" is also possible to use the extension for passive monitoring of page "
-"activities without active modifications to the JavaScript environment. "
-"Network Boundary Shield cannot be turned into notify mode, but it is very "
-"rare to find a page accessing a local network. This configuration should not"
-" break any page, the user is not protected from fingerprinting, but the "
-"extension notifies about suspicious activities."
-msgstr ""
-
-#: ../content/posts/cooperation.md:block 21 (paragraph)
-msgid ""
-"![Almost passive configuration of the "
-"extension]({attach}/images/cooperation/almost-passive.png)"
-msgstr ""
-
-#: ../content/posts/cooperation.md:block 22 (header)
-msgid "5. Publicity"
-msgstr ""
-
-#: ../content/posts/cooperation.md:block 23 (paragraph)
-msgid ""
-"At the beginning of 2021, we only had a handful of users. When FSF "
-"[announced the project](https://www.fsf.org/news/fsf-announces-jshelter-"
-"browser-add-on-to-combat-threats-from-nonfree-javascript) the number of "
-"users raised. We managed to retain about 75% of the peek of Firefox and "
-"Chrome users. See graphs below."
-msgstr ""
-
-#: ../content/posts/cooperation.md:block 24 (paragraph)
-msgid "The number of daily users with Firefox browser:"
-msgstr ""
-
-#: ../content/posts/cooperation.md:block 25 (paragraph)
-msgid ""
-"![30th, some users left afterwards]({attach}/images/cooperation/firefox-"
-"daily-2022-03-17.png)"
-msgstr ""
-
-#: ../content/posts/cooperation.md:block 26 (paragraph)
-msgid "The number of weekly users with Chrome browser:"
-msgstr ""
-
-#: ../content/posts/cooperation.md:block 27 (paragraph)
-msgid ""
-"![We managed to keep most of the Chrome "
-"users]({attach}/images/cooperation/chrome-weekly-2022-03-17.png)"
-msgstr ""
-
-#: ../content/posts/cooperation.md:block 28 (paragraph)
-msgid ""
-"The more users we have, the more bugs are found and the more likely we "
-"receive contributions from other parties. Also, keep in mind that some "
-"defences against fingerprinting work best when many users employ the "
-"defences. So it is beneficial for everyone to have as many users as "
-"possible."
-msgstr ""
-
-#: ../content/posts/cooperation.md:block 29 (header)
-msgid "6. New name, rebranding"
-msgstr ""
-
-#: ../content/posts/cooperation.md:block 30 (paragraph)
-msgid ""
-"The cooperation initially started between JavaScript Restrictor and "
-"JavaScript Shield project. We thought about several rebranding options for "
-"the project to give users a warm feeling of safety. Starting from 0.7 the "
-"extension is called JShelter, uses a more privacy-friendly repository, and "
-"we already had a new crab icon in the late 0.5 releases."
-msgstr ""
-
-#: ../content/posts/cooperation.md:block 31 (paragraph)
-msgid ""
-"We intend to keep the current infrastructure like the Github repository "
-"intact. All Github pages links should work and are redirected to the new "
-"website."
-msgstr ""
-
-#: ../content/posts/crawling.md:block 1 (header)
-msgid ""
-"title: Measurement of JavaScript API usage on the web\n"
-"date: 2021-03-30 14:00\n"
-"Series: JavaScript API usage"
-msgstr ""
-
-#: ../content/posts/crawling.md:block 2 (paragraph)
-msgid ""
-"The world wide web is a complex environment. Web pages can access many APIs "
-"ranging from text formatting to access to nearby Bluetooth devices. While "
-"many APIs are used for legitimate purposes, some are misused to track and "
-"identify their users without their knowledge. In this paper, we propose a "
-"methodology to measure the usage of JavaScript APIs on the public web. The "
-"methodology consists of an automated visit of several thousand websites and "
-"intercepting JavaScript calls performed by the pages. We also provide a "
-"design and architecture of a measurement platform that can be used for an "
-"automated visit of a list of websites. The proposed platform is based on "
-"OpenWPM. The browser is instrumented by OpenWPM and a customized Web API "
-"Manager extension is responsible for capturing JavaScript API calls."
-msgstr ""
-
-#: ../content/posts/crawling.md:block 3 (header)
-msgid "Introduction"
-msgstr ""
-
-#: ../content/posts/crawling.md:block 4 (paragraph)
-msgid ""
-"Web browsers offer a wide range of possibilities. on the surface they *just*"
-" display web pages, but under the hood, web browsers provide a bridge "
-"between a viewed page and the host operating system. A web browser allows a "
-"web page to access information like values from sensors, information about "
-"battery status, installed fonts, and much more. The advertisement industry "
-"often takes advantage of the wide range of information provided by web "
-"browsers to create a web browser [fingerprint](https://amiunique.org/links)."
-" Most commonly, the fingeprinters misuse Web APIs (also called JavaScript "
-"APIs)."
-msgstr ""
-
-#: ../content/posts/crawling.md:block 5 (paragraph)
-msgid ""
-"This blog post is mainly concerned with user tracking and fingerprinting. "
-"For example Battery Status API implementation on Mozilla Firefox revealed "
-"very precise value allowing the trackers to identify the user for a [period "
-"of time](https://petsymposium.org/2017/papers/hotpets/batterystatus-not-"
-"included.pdf). As the Battery Status API was used heavily for "
-"fingerprinting, it has been removed from Mozilla Firefox in 2017. Other "
-"examples of JavaScript APIs that are used often for fingerprinting are "
-"[Canvas API](http://cseweb.ucsd.edu/~hovav/papers/ms12.html), [Audio "
-"API](https://senglehardt.com/papers/princeton_phd_dissertation_englehardt.pdf),"
-" [Permissions API](https://arxiv.org/abs/2008.04480) or [APIs for device "
-"sensors](https://dl.acm.org/doi/10.1145/3243734.3243860)."
-msgstr ""
-
-#: ../content/posts/crawling.md:block 6 (paragraph)
-msgid ""
-"In our work, we aim to measure the JavaScript APIs usage by popular "
-"websites. In this article, we present core technologies to accomplish these "
-"measurements. The stack of technologies is based on "
-"[OpenWPM](https://github.com/mozilla/OpenWPM) enriched by a browser "
-"extension, that allows us to intercept JavaScript calls of different APIs. "
-"This browser extension is based on Proxy objects."
-msgstr ""
-
-#: ../content/posts/crawling.md:block 7 (paragraph)
-msgid ""
-"Our work is based on work of [Peter Snyders et "
-"al.](https://www3.cs.uic.edu/pub/Bits/PeterSnyder/Browser_Feature_Usage_on_the_Modern_Web.pdf)"
-" carried in 2016. Since then many new APIs were specified and implemented in"
-" web browsers, see the figure below (based on data from [Can I Use? "
-"website](https://caniuse.com/))."
-msgstr ""
-
-#: ../content/posts/crawling.md:block 8 (paragraph)
-msgid ""
-"![Progress of Web APIs amount implemented in distinct browsers in "
-"time.]({attach}/images/crawling-apis.png)"
-msgstr ""
-
-#: ../content/posts/crawling.md:block 9 (header)
-msgid "Methodology proposal"
-msgstr ""
-
-#: ../content/posts/crawling.md:block 10 (paragraph)
-msgid ""
-"This section describes the methodology that we plan to use. This methodology"
-" is based on As it is based on the work of Peter Snyders, it is already "
-"validated. Moreover, using a methodology that is very close to the original "
-"one should show us a difference in the usage of the JavaScript APIs in 2016 "
-"and 2021."
-msgstr ""
-
-#: ../content/posts/crawling.md:block 11 (paragraph)
-msgid ""
-"The main idea of the measurement is to visit several thousands of the most "
-"[popular pages](https://tranco-list.eu/#aboutus) on the internet and "
-"intercept as many JavaScript calls as possible."
-msgstr ""
-
-#: ../content/posts/crawling.md:block 12 (paragraph)
-msgid ""
-"Visiting websites will be performed through Mozilla Firefox with an "
-"extension that intercepts and logs the JavaScript calls. We will visit not "
-"only the landing page but also the subset of subpages of each website. From "
-"the landing page, we will extract three links that point to a subpage of a "
-"given page. From each of these three subpages, we will get another three "
-"subpage links resulting in up to 13 pages of a given website being visited. "
-"This amount of pages should be high enough to catch the most of JavaScript "
-"calls. We will wait and intercept JavaScript calls for 30 seconds on each "
-"page to wait of API calls performed during the page load."
-msgstr ""
-
-#: ../content/posts/crawling.md:block 13 (paragraph)
-msgid ""
-"Results of our measurements should also provide information about the "
-"JavaScript APIs, that were probably used in a manner, that is not necessary "
-"for a page to be working and is very likely used in a way, that the user "
-"would not find useful. To achieve this,"
-msgstr ""
-
-#: ../content/posts/crawling.md:block 14 (paragraph)
-msgid ""
-"We will run our measurements on every page in two different modes. Firstly, "
-"we will visit the page using the a browser withou adblocker. Later, we will "
-"also employ an adblocker. Hence, the study will show the difference API "
-"usage of regular pages and trackers."
-msgstr ""
-
-#: ../content/posts/crawling.md:block 15 (header)
-msgid "The original study"
-msgstr ""
-
-#: ../content/posts/crawling.md:block 16 (paragraph)
-msgid ""
-"The Snyders' study suggests that some of the JavaScript APIs are extremely "
-"popular and they are used on more than 90% of measured pages (e.g. a well "
-"known `Document.createElement` method from DOM API). On the other hand, "
-"there are many APIs that are used by a minority of measured pages. That "
-"being said, almost 50% of JavaScript APIs implemented in the browser at the "
-"time were not used by any of the measured pages."
-msgstr ""
-
-#: ../content/posts/crawling.md:block 17 (paragraph)
-msgid ""
-"The study also suggests that there is no direct connection between the "
-"implementation date of a given JavaScript API in the browser (or by its "
-"specification date by some of the specifications vendors) and its popularity"
-" in using by websites. Concretely, there are some old JavaScript APIs, such "
-"as `XMLHttpRequest` that are still very popular. However, there are also "
-"quite new JavaScript APIs, that are used very frequently (i.e., `Selectors "
-"API Level 1`)."
-msgstr ""
-
-#: ../content/posts/crawling.md:block 18 (paragraph)
-msgid ""
-"The conducted study also measured the pages in two ways - with the ad "
-"blocker and without any ad blocking extension. Results of measurements "
-"showed that the blocking of different JavaScript APIs is not uniform and "
-"some APIs are blocked more often than others. Specifically, 10% of "
-"JavaScript APIs were blocked in 90% of cases resulting in a fact that 83% of"
-" APIs were used on less than 1% of websites when the page was visited with "
-"active blocking extension."
-msgstr ""
-
-#: ../content/posts/crawling.md:block 19 (header)
-msgid "Web API Manager"
-msgstr ""
-
-#: ../content/posts/crawling.md:block 20 (paragraph)
-msgid ""
-"Web API Manager is a browser extension, that aims to block explicitly "
-"defined JavaScript APIs. It has been developed by Snyders in 2016 and used "
-"in several studies conducted by [Snyders et "
-"al.](https://www.peteresnyder.com/https://www.peteresnyder.com/)."
-msgstr ""
-
-#: ../content/posts/crawling.md:block 21 (paragraph)
-msgid ""
-"The original purpose of the Web API Manager is to block explicitly defined "
-"JavaScript APIs. However, in our measurements, we just need to intercept the"
-" API calls, log these calls and delegate the calls to original receivers."
-msgstr ""
-
-#: ../content/posts/crawling.md:block 22 (paragraph)
-msgid ""
-"The main principle of Web API Manager is based on Proxy objects. This "
-"metaprogramming technique allows intercepting calls performed on objects. "
-"While the main goal of the Web API Manager extension is to block the calls "
-"performed on objects that belong to particular JavaScript APIs, our goal is "
-"only to intercept these operations and delegate them to their original "
-"receivers. We will use the Log Aggregator interface to log the API calls."
-msgstr ""
-
-#: ../content/posts/crawling.md:block 23 (paragraph)
-msgid ""
-"To provide a Web API Manager the list of JavaScript APIs members we need a "
-"list of supported APIs. The APIs implemented in Mozilla Firefox are "
-"available as [IDL files](https://searchfox.org/mozilla-"
-"central/source/dom/webidl)."
-msgstr ""
-
-#: ../content/posts/crawling.md:block 24 (header)
-msgid "Measurement tools"
-msgstr ""
-
-#: ../content/posts/crawling.md:block 25 (paragraph)
-msgid ""
-"The figure below shows a simplified illustration of the measurement "
-"platform. There is OpenWPM in the middle of the architecture. OpenWPM "
-"orchestrates Selenium and Mozilla Firefox with the proxy-based intercepting "
-"Web API Manager."
-msgstr ""
-
-#: ../content/posts/crawling.md:block 26 (paragraph)
-msgid "![image]({attach}/images/crawling-architecture.png)"
-msgstr ""
-
-#: ../content/posts/crawling.md:block 27 (header)
-msgid "The impact on JShelter"
-msgstr ""
-
-#: ../content/posts/crawling.md:block 28 (paragraph)
-msgid ""
-"Once we have data from our crawling study, we will compare the data with "
-"[another recent study](https://github.com/uiowa-irl/FP-"
-"Inspector/blob/master/Data/potential_fingerprinting_APIs.md). As already "
-"mentioned, we want to develop a fingerprinting detection based on counting "
-"the number of different APIs employed by a page, especially APIs that are "
-"not frequently used for benign purposes. When a fingerprinting attempt is "
-"identified, we want to (1) inform the user, (2) prevent uploading of the "
-"fingerprint to the server, (3) prevent storing the fingerprint for later "
-"usage."
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 1 (header)
-msgid ""
-"title: \"RESULTS: Measurement of JavaScript API usage on the web\"\n"
-"date: 2022-01-14 12:00\n"
-"Series: JavaScript API usage"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 2 (paragraph)
-msgid ""
-"A [previous blogpost](/crawling/) introduced a methodology to measure the "
-"usage of JavaScript APIs on the web by crawling the web. The starting point "
-"of our web crawling research is the [work of Peter "
-"Snyder](https://www.peteresnyder.com/static/papers/improving-web-privacy-"
-"and-security-thesis.pdf). Most importantly, we wanted to compare the "
-"differences in JS API usage between browsers with and without privacy "
-"extension (e.g., uBlock Origin). We have finished the development of the "
-"[crawling tool](https://github.com/martinbednar/web_crawler). We crawled "
-"thousands of websites and collected JavaScript calls on the visited web "
-"pages."
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 3 (paragraph)
-msgid "This blog post introduces the methodology and results of the crawling."
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 5 (paragraph)
-msgid ""
-"When a user opens a webpage in a JavaScript-enabled web browser, that "
-"webpage can access various APIs supported by the web browser. The webpage "
-"can read, for example, the value of performance.now(), battery status or "
-"data from sensors (when available). All these values can be misused to "
-"create a [device fingerprint](https://arxiv.org/pdf/1905.01051.pdf) that can"
-" be used to identify the user."
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 6 (paragraph)
-msgid ""
-"We aim to research how JS APIs are used on websites. The main research "
-"questions are:"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 7 (unordered list)
-msgid "What APIs do websites use?"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 7 (unordered list)
-msgid "How many APIs does a website use?"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 7 (unordered list)
-msgid "What endpoints do websites access most often?"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 7 (unordered list)
-msgid "How many JS calls are made?"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 7 (unordered list)
-msgid ""
-"What are the differences in results in all the previous questions with an "
-"active privacy web-browser extension (e.g., uBlock Origin)? For example, "
-"What JS calls are blocked by uBlock Origin?"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 8 (paragraph)
-msgid ""
-"The answers to these questions should help us better understand websites' "
-"behaviour. Based on the obtained data, we want to define the suspicious "
-"behaviour indicating that the website is trying to fingerprint the user's "
-"device."
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 9 (paragraph)
-msgid ""
-"We plan to keep the [anti-fingerprint mechanism](/fpdetection/) updated "
-"based on derived heuristics. The heuristics are derived from the following "
-"statistics:"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 10 (unordered list)
-msgid "How many APIs and endpoints does the website access?"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 10 (unordered list)
-msgid "How many JS calls did the website make?"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 10 (unordered list)
-msgid "Is the number and combination of JS APIs calls suspicious?"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 11 (paragraph)
-msgid ""
-"When our anti-fingerprint mechanism detects suspicious combinations or a "
-"high number of used APIs, it can block communication with the webpage."
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 12 (header)
-msgid "Crawler"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 13 (paragraph)
-msgid ""
-"We have developed [Web "
-"crawler](https://github.com/martinbednar/web_crawler/) - a tool for "
-"automatically visiting websites from a given list and collecting JavaScript "
-"calls made by the website. Our Web crawler is based on the "
-"[OpenWPM](https://github.com/openwpm/OpenWPM) platform. A modified web "
-"browser extension [Web API Manager](https://github.com/pes10k/web-api-"
-"manager) collects statistics on called JS APIs."
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 14 (paragraph)
-msgid "The crawling process can be described in the following steps:"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 15 (ordered list)
-msgid ""
-"The python script `start_docker_runs.py` launches the Docker image "
-"[martan305/web_crawler](https://hub.docker.com/repository/docker/martan305/web_crawler)."
-" The parameters set in the Python startup script are given to the Docker "
-"container as environmental variables."
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 15 (ordered list)
-msgid ""
-"If a privacy extension is required (in the script parameter), uBlock Origin "
-"will be installed as soon as the web browser is started."
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 15 (ordered list)
-msgid ""
-"Python script running in the container visits web pages from a given list "
-"one by one."
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 15 (ordered list)
-msgid ""
-"The browser waits for 30 seconds on each page. The customised web browser "
-"extension Web API Manager intercepts JS calls and stores the stats into the "
-"SQLite database."
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 15 (ordered list)
-msgid ""
-"When the script finishes the crawl of assigned pages, it checks if there is "
-"a batch of pages not yet visited. If there is an unprocessed batch, the "
-"crawling continues with step 3 and the new list of web pages to visit. If "
-"the crawler visited all sites, the crawling ends."
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 16 (paragraph)
-msgid ""
-"For now, we only visited the homepages because we wanted to visit as many "
-"different websites as possible. In the future, we plan to launch long-term "
-"crawling, which will include subpages. In particular, we want to focus on "
-"visiting login pages, where we expect fingerprint scripts to be included. "
-"Then, we can compare API calls on login pages and other pages."
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 17 (paragraph)
-msgid ""
-"Afterwards, we analyse the collected data with a standalone [analysis "
-"tool](https://github.com/martinbednar/web_crawler_data_analysis). The "
-"analysis process consists of the following steps:"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 18 (ordered list)
-msgid ""
-"Databases created by browsing with and without the web-browser extension "
-"uBlock Origin are loaded separately."
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 18 (ordered list)
-msgid ""
-"Aggregation SQL queries are executed in databases. The results are loaded "
-"into Python dictionaries."
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 18 (ordered list)
-msgid ""
-"Data sets are analysed, compared and the results are exported to CSV files."
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 19 (header)
-msgid "Measurement results"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 20 (paragraph)
-msgid "This section presents the results of the analysis."
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 21 (paragraph)
-msgid ""
-"We tried to visit the first 250 000 websites from the [Tranco list "
-"X79N](https://tranco-list.eu/list/X79N/1000000). 211 843 homepages of "
-"websites from the Tranco list were successfully visited in both modes - with"
-" and without uBlock Origin. More than 4 000 000 000 JS calls were "
-"intercepted and stored into 5 000 [SQLite "
-"databases](https://nextcloud.fit.vutbr.cz/s/XKm3PCZnr2xkPH9) that have a "
-"total size of over 880 GB."
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 22 (paragraph)
-msgid ""
-"Let us focus on the answers to the research questions on JavaScript API "
-"calls made by the websites. This blog post usually lists only 10 result "
-"lines for each experiment. Complete tables with all rows can be found in the"
-" [results stored on the "
-"server](https://nextcloud.fit.vutbr.cz/s/xDfSAe3Nx7iFSm4)."
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 23 (paragraph)
-msgid "The meaning of the table columns:"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 24 (unordered list)
-msgid "Endpoint = a function or a property provided by a web browser."
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 24 (unordered list)
-msgid ""
-"API = a group of functions and properties that are thematically related."
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 24 (unordered list)
-msgid "Website = URL of the visited website."
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 24 (unordered list)
-msgid ""
-"Calls without uBlock Origin = the number of JavaScript calls intercepted "
-"without the uBlock Origin extension."
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 24 (unordered list)
-msgid ""
-"Calls with uBlock Origin = the number of JavaScript calls intercepted with "
-"the uBlock Origin extension."
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 24 (unordered list)
-msgid ""
-"Difference = the difference between the number of JavaScript calls "
-"intercepted with and without the uBlock Origin extension."
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 24 (unordered list)
-msgid ""
-"Difference [%] = the difference expressed as a percentage. Difference [%] = "
-"100 \\* Difference/Calls without uBlock Origin"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 24 (unordered list)
-msgid ""
-"Websites without uBlock [%] - what percentage of websites use the given API "
-"(measured without the uBlock Origin extension installed)."
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 24 (unordered list)
-msgid ""
-"Websites with uBlock [%] - what percentage of websites use the given API "
-"(measured with the uBlock Origin extension installed)."
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 25 (paragraph)
-msgid ""
-"All result tables are sorted by the `Difference [%]` column decreasing."
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 26 (header)
-msgid "The most blocked API"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "API"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "Calls without uBlock"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "Calls with uBlock"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "Difference"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "Difference [%]"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "Non-Standard"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "340 777"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "18 180"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "322 597"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "94,67%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "Web Audio API"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "14 390 507"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "1 431 286"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "12 959 221"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "90,05%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "Web Speech API"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "93 889"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "10 712"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "83 177"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "88,59%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "Background Tasks API"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "5 950 947"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "954 740"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "4 996 207"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "83,96%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "High Resolution Time (Level 2)"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "367 400 369"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "63 507 434"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "303 892 935"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "82,71%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "Navigation Timing"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "8 160"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "1 749"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "6 411"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "78,57%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "CSS Animations Level 1"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "1 301"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "317"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "984"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "75,63%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "Beacon"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "223 209"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "62 651"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "160 558"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "71,93%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "DOM Level 2: Traversal and Range"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "25 814 025"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "7 996 500"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "17 817 525"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "69,02%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "Indexed Database API"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "1 308 464"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "408 983"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "899 481"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 27 (table)
-msgid "68,74%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 28 (header)
-msgid "The most blocked API endpoints"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "Endpoint"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "Range.prototype.cloneContents"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "2 603"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "16"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "2 587"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "99,39%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "Range.prototype.setStartAfter"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "1 234"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "9"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "1 225"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "99,27%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "MessagePort.prototype.close"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "HTML: Channel Messaging"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "51 802"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "416"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "51 386"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "99,20%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "SubtleCrypto.prototype.deriveBits"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "Web Cryptography API"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "208"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "2"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "206"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "99,04%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "Range.prototype.selectNode"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "337 795"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "7 384"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "330 411"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "97,81%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "Range.prototype.getBoundingClientRect"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "337 650"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "7 565"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "330 085"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "97,76%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "Document.prototype.close"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "HTML: Dynamic Markup Insertion"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "21 666"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "666"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "21 000"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "96,93%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "Navigator.prototype.javaEnabled"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "334 580"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "11 781"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "322 799"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "96,48%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "ServiceWorkerContainer.prototype.getRegistration"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "Service Workers"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "34 176"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "1 375"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "32 801"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "95,98%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "FormData.prototype.append"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "XMLHttpRequest"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "670 137"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "27 767"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "642 370"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 29 (table)
-msgid "95,86%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 30 (header)
-msgid "Use of APIs on websites"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 31 (table)
-msgid "Websites without uBlock [%]"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 31 (table)
-msgid "Websites with uBlock [%]"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 31 (table)
-msgid "62,06%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 31 (table)
-msgid "4,80%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 31 (table)
-msgid "57,29%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 31 (table)
-msgid "61,40%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 31 (table)
-msgid "21,98%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 31 (table)
-msgid "39,56%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 31 (table)
-msgid "32,91%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 31 (table)
-msgid "7,60%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 31 (table)
-msgid "25,36%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 31 (table)
-msgid "71,53%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 31 (table)
-msgid "47,76%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 31 (table)
-msgid "24,08%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 31 (table)
-msgid "45,58%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 31 (table)
-msgid "24,71%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 31 (table)
-msgid "21,03%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 31 (table)
-msgid "Performance Timeline"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 31 (table)
-msgid "41,15%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 31 (table)
-msgid "21,22%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 31 (table)
-msgid "20,06%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 31 (table)
-msgid "57,37%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 31 (table)
-msgid "39,24%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 31 (table)
-msgid "18,39%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 31 (table)
-msgid "HTML 5"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 31 (table)
-msgid "50,14%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 31 (table)
-msgid "33,45%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 31 (table)
-msgid "16,91%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 31 (table)
-msgid "HTML: Web Storage"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 31 (table)
-msgid "65,69%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 31 (table)
-msgid "49,48%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 31 (table)
-msgid "16,53%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 31 (table)
-msgid "URL"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 31 (table)
-msgid "29,73%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 31 (table)
-msgid "15,79%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 31 (table)
-msgid "14,05%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 31 (table)
-msgid "14,41%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 31 (table)
-msgid "0,81%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 31 (table)
-msgid "13,61%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 31 (table)
-msgid "22,23%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 31 (table)
-msgid "9,40%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 31 (table)
-msgid "12,89%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 31 (table)
-msgid "HTML: Canvas Element"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 31 (table)
-msgid "42,54%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 31 (table)
-msgid "29,89%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 31 (table)
-msgid "12,85%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 32 (header)
-msgid "The number of APIs used by the website"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 33 (paragraph)
-msgid ""
-"**Average value** - Number of APIs used without uBlock Origin: **18.78**"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 34 (paragraph)
-msgid "![image]({attach}/images/crawling_results/APIs_without_uBlock.png)"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 35 (paragraph)
-msgid "**Average value** - Number of APIs used with uBlock Origin: **14.27**"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 36 (paragraph)
-msgid "![image]({attach}/images/crawling_results/APIs_with_uBlock.png)"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 37 (header)
-msgid "The number of JavaScript calls on websites"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 38 (paragraph)
-msgid ""
-"**Average value** - Number of JavaScript calls made without uBlock Origin: "
-"**10 629.92**"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 39 (paragraph)
-msgid "![image]({attach}/images/crawling_results/JScalls_without_uBlock.png)"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 40 (paragraph)
-msgid ""
-"**Average value** - Number of JavaScript calls made with uBlock Origin: **7 "
-"176.2**"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 41 (paragraph)
-msgid "![image]({attach}/images/crawling_results/JScalls_with_uBlock.png)"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 42 (header)
-msgid "The number of endpoint calls on websites"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 43 (table)
-msgid "Website"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 43 (table)
-msgid "https://www.woolworths.co.za/"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 43 (table)
-msgid "window.getComputedStyle"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 43 (table)
-msgid "202 013"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 43 (table)
-msgid "1"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 43 (table)
-msgid "202 012"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 43 (table)
-msgid "100,00%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 43 (table)
-msgid "https://www.superkopilka.com/"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 43 (table)
-msgid "Performance.prototype.now"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 43 (table)
-msgid "158 034"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 43 (table)
-msgid "158 033"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 43 (table)
-msgid "https://www.jarir.com/"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 43 (table)
-msgid "DOMTokenList.prototype.contains"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 43 (table)
-msgid "156 917"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 43 (table)
-msgid "156 916"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 43 (table)
-msgid "https://shm.ru/#"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 43 (table)
-msgid "153 653"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 43 (table)
-msgid "153 652"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 43 (table)
-msgid "https://znanium.com/"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 43 (table)
-msgid "138 465"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 43 (table)
-msgid "138 464"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 43 (table)
-msgid "https://www.soliton.az/"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 43 (table)
-msgid "137 467"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 43 (table)
-msgid "137 466"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 43 (table)
-msgid "https://www.lasenza.com/"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 43 (table)
-msgid "118 945"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 43 (table)
-msgid "118 944"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 43 (table)
-msgid "https://nethouse.ru/"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 43 (table)
-msgid "113 580"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 43 (table)
-msgid "113 579"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 43 (table)
-msgid "https://boodmo.com/"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 43 (table)
-msgid "108 376"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 43 (table)
-msgid "108 375"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 43 (table)
-msgid "https://fipi.ru/"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 43 (table)
-msgid "108 255"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 43 (table)
-msgid "108 254"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 43 (table)
-msgid "https://belregion.ru/"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 43 (table)
-msgid "105 227"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 43 (table)
-msgid "105 226"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 43 (table)
-msgid "https://tsargrad.tv/"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 43 (table)
-msgid "99 445"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 43 (table)
-msgid "99 444"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 44 (header)
-msgid "Measurement results for opensource websites only"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 45 (paragraph)
-msgid ""
-"As this project focuses on free and open source software, we compared the "
-"general results with a list of pages connected to free software or open "
-"source."
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 46 (paragraph)
-msgid ""
-"We collected the list of the home pages from [Gentoo "
-"repository](https://gitweb.gentoo.org/repo/gentoo.git/tree/)."
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 47 (paragraph)
-msgid ""
-"We tried to visit all 5 271 collected websites. 4 528 homepages were "
-"successfully visited in both modes, with and without uBlock Origin. More "
-"than 11 000 000 JS calls were intercepted and stored into 2 [SQLite "
-"databases](https://nextcloud.fit.vutbr.cz/s/yoLa5rcGzkgbSka) that have a "
-"total size of over 3 GB."
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 48 (paragraph)
-msgid ""
-"Only the first 10 lines of the analysis results are usually listed below. "
-"Complete tables with all rows can be found in the [results stored on the "
-"server](https://nextcloud.fit.vutbr.cz/s/LWANmRxoXc5YYzy)."
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "Resource Timing Level 2"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "348"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "8"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "340"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "97,70%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "1 711"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "66"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "1 645"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "96,14%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "18 763"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "1 037"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "17 726"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "94,47%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "306"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "18"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "288"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "94,12%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "HTML: Plugins"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "13"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "11"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "84,62%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "Permissions API"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "705"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "186"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "519"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "73,62%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "3 981"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "1 088"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "2 893"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "72,67%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "849 390"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "232 806"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "616 584"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "72,59%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "21"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "6"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "15"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "71,43%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "Performance Timeline (Level 2)"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "2 548"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "745"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "1 803"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "70,76%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "Storage API"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "3"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "66,67%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "727"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "250"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "477"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "65,61%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "7 632"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "2 928"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "4 704"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 50 (table)
-msgid "61,64%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 52 (table)
-msgid "IdleDeadline.prototype.timeRemaining"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 52 (table)
-msgid "2 258"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 52 (table)
-msgid "2 256"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 52 (table)
-msgid "99,91%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 52 (table)
-msgid "Element.prototype.getAttributeNames"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 52 (table)
-msgid "DOM"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 52 (table)
-msgid "1 648"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 52 (table)
-msgid "12"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 52 (table)
-msgid "1 636"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 52 (table)
-msgid "268"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 52 (table)
-msgid "266"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 52 (table)
-msgid "99,25%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 52 (table)
-msgid "Document.prototype.elementFromPoint"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 52 (table)
-msgid "CSS Object Model (CSSOM)"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 52 (table)
-msgid "2 554"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 52 (table)
-msgid "22"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 52 (table)
-msgid "2 532"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 52 (table)
-msgid "99,14%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 52 (table)
-msgid "106"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 52 (table)
-msgid "105"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 52 (table)
-msgid "99,06%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 52 (table)
-msgid "CanvasRenderingContext2D.prototype.createLinearGradient"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 52 (table)
-msgid "4 634"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 52 (table)
-msgid "56"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 52 (table)
-msgid "4 578"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 52 (table)
-msgid "98,79%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 52 (table)
-msgid "CanvasRenderingContext2D.prototype.transform"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 52 (table)
-msgid "37 792"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 52 (table)
-msgid "845"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 52 (table)
-msgid "36 947"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 52 (table)
-msgid "PerformanceResourceTiming.prototype.toJSON"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 52 (table)
-msgid "1 691"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 52 (table)
-msgid "47"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 52 (table)
-msgid "1 644"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 52 (table)
-msgid "97,22%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 52 (table)
-msgid "PerformanceObserverEntryList.prototype.getEntriesByName"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 52 (table)
-msgid "52"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 52 (table)
-msgid "50"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 52 (table)
-msgid "96,15%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 52 (table)
-msgid "CanvasGradient.prototype.addColorStop"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 52 (table)
-msgid "9 623"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 52 (table)
-msgid "453"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 52 (table)
-msgid "9 170"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 52 (table)
-msgid "95,29%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 54 (table)
-msgid "26,47%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 54 (table)
-msgid "1,13%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 54 (table)
-msgid "25,26%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 54 (table)
-msgid "21,94%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 54 (table)
-msgid "7,24%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 54 (table)
-msgid "14,64%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 54 (table)
-msgid "26,42%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 54 (table)
-msgid "14,94%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 54 (table)
-msgid "11,41%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 54 (table)
-msgid "13,70%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 54 (table)
-msgid "9,08%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 54 (table)
-msgid "4,58%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 54 (table)
-msgid "6,35%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 54 (table)
-msgid "1,76%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 54 (table)
-msgid "10,07%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 54 (table)
-msgid "5,68%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 54 (table)
-msgid "4,36%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 54 (table)
-msgid "15,46%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 54 (table)
-msgid "11,12%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 54 (table)
-msgid "4,29%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 54 (table)
-msgid "10,79%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 54 (table)
-msgid "6,46%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 54 (table)
-msgid "20,60%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 54 (table)
-msgid "16,26%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 54 (table)
-msgid "4,27%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 56 (paragraph)
-msgid "**Average value** - Number of APIs used without uBlock Origin: **7.4**"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 57 (paragraph)
-msgid "![image](crawling_results/APIs_without_uBlock_opensource.png)"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 58 (paragraph)
-msgid "**Average value** - Number of APIs used with uBlock Origin: **6.2**"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 59 (paragraph)
-msgid "![image](crawling_results/APIs_with_uBlock_opensource.png)"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 61 (paragraph)
-msgid ""
-"**Average value** - Number of JavaScript calls made without uBlock Origin: "
-"**1598.18**"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 62 (paragraph)
-msgid "![image](crawling_results/JScalls_without_uBlock_opensource.png)"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 63 (paragraph)
-msgid ""
-"**Average value** - Number of JavaScript calls made with uBlock Origin: "
-"**1304.06**"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 64 (paragraph)
-msgid "![image](crawling_results/JScalls_with_uBlock_opensource.png)"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 66 (table)
-msgid "https://wci.llnl.gov/"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 66 (table)
-msgid "Element.prototype.hasAttribute"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 66 (table)
-msgid "34 860"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 66 (table)
-msgid "34 859"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 66 (table)
-msgid "https://wiibrew.org/wiki/Main_Page"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 66 (table)
-msgid "6 512"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 66 (table)
-msgid "6 511"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 66 (table)
-msgid "99,98%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 66 (table)
-msgid "http://www.vsound.org/"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 66 (table)
-msgid "Document.prototype.getElementById"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 66 (table)
-msgid "5 797"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 66 (table)
-msgid "5 796"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 66 (table)
-msgid "http://wormsofprey.org/"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 66 (table)
-msgid "5 793"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 66 (table)
-msgid "5 792"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 66 (table)
-msgid "http://konst.org.ua/"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 66 (table)
-msgid "Element.prototype.setAttribute"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 66 (table)
-msgid "4 248"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 66 (table)
-msgid "4 247"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 66 (table)
-msgid "https://www.union.edu/mathematics"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 66 (table)
-msgid "5 317"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 66 (table)
-msgid "5 315"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 66 (table)
-msgid "99,96%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 66 (table)
-msgid "https://www.mongodb.com/"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 66 (table)
-msgid "30 516"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 66 (table)
-msgid "14"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 66 (table)
-msgid "30 502"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 66 (table)
-msgid "99,95%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 66 (table)
-msgid "https://www.monotype.com/"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 66 (table)
-msgid "4 091"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 66 (table)
-msgid "4 089"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 66 (table)
-msgid "https://sylabs.io/"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 66 (table)
-msgid "1 839"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 66 (table)
-msgid "1 838"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 66 (table)
-msgid "http://vlgothic.dicey.org/"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 66 (table)
-msgid "3 427"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 66 (table)
-msgid "3 425"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 66 (table)
-msgid "99,94%"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 66 (table)
-msgid "https://www.ppsspp.org/"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 66 (table)
-msgid "3 397"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 66 (table)
-msgid "3 395"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 67 (header)
-msgid "Measurement results for FingerPrint Detector"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 68 (paragraph)
-msgid ""
-"We designed the web crawling primarily to retrieve data to create or "
-"evaluate heuristics for the [FingerPrint Detector (FPD)](/fpdetection/). The"
-" above results are helpful in understanding the JavaScript APIs usage on the"
-" web. For FPD, only the name of the endpoint and the weight of this endpoint"
-" are important. The weight expresses how often a given endpoint is used to "
-"create a fingerprint."
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 69 (paragraph)
-msgid ""
-"The resulting table below was created from crawled data from websites of the"
-" Tranco list . Two data sets were combined to obtain more accurate results. "
-"The first dataset obtained while crawling with uBlock Origin, the second one"
-" obtained while crawling with uMatrix. The resulting endpoint weight (marked"
-" as `average_weight`) was calculated in Python as follows:"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 71 (paragraph)
-msgid ""
-"Again, only the first 10 lines of the FPD analysis result are listed below. "
-"Complete table with all rows can be found in the [results stored on the "
-"server](https://nextcloud.fit.vutbr.cz/s/GjkTJzweccgxw6n)."
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "Average weight"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "uMatrix weight"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "uBlock weight"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "Calls without extension"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "Calls with uMatrix"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "Difference uMatrix"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "Difference uBlock"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "Difference uMatrix [%]"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "Difference uBlock [%]"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "13,427"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "13,060"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "455"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "454"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "449"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "0,998"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "0,987"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "Range.prototype.insertNode"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "13,138"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "12,920"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "460"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "5"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "452"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "0,989"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "0,983"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "HTMLFormControlsCollection.prototype.namedItem"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "12,714"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "12,623"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "2 211"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "19"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "25"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "2 192"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "2 186"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "0,991"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "Document.prototype.open"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "12,475"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "11,274"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "8 190"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "129"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "424"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "8 061"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "7 766"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "0,984"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "0,948"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "12,438"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "12,424"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "16 208"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "30"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "37"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "16 178"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "16 171"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "Document.prototype.getElementsByTagNameNS"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "12,374"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "10,811"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "533"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "43"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "515"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "490"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "0,966"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "0,919"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "12,086"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "11,944"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "7 731"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "212"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "245"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "7 519"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "7 486"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "0,973"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "0,968"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "SubtleCrypto.prototype.generateKey"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "11,876"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "11,503"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "985"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "48"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "59"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "937"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "926"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "0,951"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "0,940"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "Document.prototype.elementsFromPoint"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "12,469"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "11,365"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "46 938"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "44"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "1 598"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "46 894"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "45 340"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "0,999"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "10,892"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "110 665"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "3 677"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "3 679"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "106 988"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "106 986"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 72 (table)
-msgid "0,967"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 73 (paragraph)
-msgid ""
-"More about FingerPrint Detector is written in the [following "
-"blogpost](/fpdetection/)."
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 74 (header)
-msgid "Conclusion"
-msgstr ""
-
-#: ../content/posts/crawling_results.md:block 75 (paragraph)
-msgid ""
-"The crawl identified JavaScript endpoints, often used to create a browser "
-"fingerprint. The observed data allow assigning weights for each endpoint. "
-"[FingerPrint Detector](/fpdetection/) configuration file uses the crawl "
-"results."
-msgstr ""
-
-#: ../content/posts/farbling.md:block 1 (header)
-msgid ""
-"title: Farbling-based wrappers to hinder browser fingerprinting\n"
-"date: 2021-08-23 09:00\n"
-"Series: Browser fingerprinting"
-msgstr ""
-
-#: ../content/posts/farbling.md:block 2 (paragraph)
-msgid ""
-"[Browser fingerprinting](https://arxiv.org/pdf/1905.01051.pdf) is a more and"
-" more popular technique used to identify browsers. The fingerprint is "
-"computed based on the results of JavaScript calls, the content of HTTP "
-"headers, hardware characteristics, underlying operating system and other "
-"software information. Consequently, browser fingerprints are used for cross-"
-"domain tracking. However, users cannot clear their browser fingerprint as it"
-" is not stored on the client-side. It is also challenging to determine "
-"whether a browser is being fingerprinted."
-msgstr ""
-
-#: ../content/posts/farbling.md:block 3 (paragraph)
-msgid ""
-"Another issue that hinders fingerprinting protection is the ever-changing "
-"variety of supported APIs. Browsers implement new APIs over time, and "
-"existing APIs change. Consequently, it is necessary to continuously monitor "
-"the APIs being used for fingerprinting purposes to block fingerprinting "
-"attempts."
-msgstr ""
-
-#: ../content/posts/farbling.md:block 4 (paragraph)
-msgid ""
-"Due to fingerprinting scripts being [more "
-"prevalent](https://www.cs.princeton.edu/~arvindn/publications/OpenWPM_1_million_site_tracking_measurement.pdf),"
-" various web browsers - for example, Tor, Brave, and Firefox - started "
-"implementing fingerprinting protection to protect users and their privacy."
-msgstr ""
-
-#: ../content/posts/farbling.md:block 5 (paragraph)
-msgid "This post contains:"
-msgstr ""
-
-#: ../content/posts/farbling.md:block 6 (paragraph)
-msgid "[TOC]"
-msgstr ""
-
-#: ../content/posts/farbling.md:block 7 (header)
-msgid "Brave fingerprinting protection"
-msgstr ""
-
-#: ../content/posts/farbling.md:block 8 (paragraph)
-msgid ""
-"Why is Brave's Farbling special? Until recently, [Tor "
-"browser](https://2019.www.torproject.org/projects/torbrowser/design/#fingerprinting-"
-"linkability) had the most robust defence against fingerprinting. It (1) "
-"implemented modifications in various APIs, (2) blocks some other APIs, (3) "
-"runs in a window of predefined size, etc. to ensure all users have the same "
-"fingerprint. This approach is very effective at producing uniform "
-"fingerprint for all users, which makes it difficult for fingerprinters to "
-"differentiate between browsers. Still, such fingerprint is also brittle -- "
-"minor changes like resizing the window could cause the browser to have a "
-"unique fingerprint. Hence, users need to follow inconvenient steps to keep "
-"their fingerprint uniform."
-msgstr ""
-
-#: ../content/posts/farbling.md:block 9 (paragraph)
-msgid ""
-"With all this in [mind](https://brave.com/brave-fingerprinting-and-privacy-"
-"budgets/), Brave software decided to improve their fingerprinting "
-"protection. They [proposed](https://brave.com/privacy-updates-3/) new "
-"fingerprinting protection, Farbling, arguing that it is (almost) impossible "
-"to produce uniform fingerprint without compromising user experience. Their "
-"countermeasures involve randomising values based on previous research papers"
-" [PriVaricator](https://www.doc.ic.ac.uk/~livshits/papers/pdf/www15.pdf) and"
-" [FPRandom](https://hal.inria.fr/hal-01527580/document) Both papers have "
-"shown promising results, and Brave has perfected this approach, creating "
-"effective defence while retaining almost full user experience. Farbling is a"
-" comprehensive collection of modifications that aim at producing a unique "
-"fingerprint on every domain and in every session."
-msgstr ""
-
-#: ../content/posts/farbling.md:block 10 (header)
-msgid "How does farbling work?"
-msgstr ""
-
-#: ../content/posts/farbling.md:block 11 (paragraph)
-msgid ""
-"Farbling uses generated session and [eTLD+1](https://web.dev/same-site-same-"
-"origin/) keys to deterministically change outputs of certain APIs commonly "
-"used for browser fingerprinting. These little lies result in different "
-"websites calculating different fingerprints. Moreover, a previously visited "
-"website calculates a different fingerprint in a new browsing session."
-msgstr ""
-
-#: ../content/posts/farbling.md:block 12 (paragraph)
-msgid ""
-"Farbling implementation is publicly available on Github "
-"[issue](https://github.com/brave/brave-browser/issues/8787) with discussions"
-" on design decisions, future plans and possible changes in a separate "
-"[issue](https://github.com/brave/brave-browser/issues/11770)."
-msgstr ""
-
-#: ../content/posts/farbling.md:block 13 (paragraph)
-msgid "Farbling operates on three levels:"
-msgstr ""
-
-#: ../content/posts/farbling.md:block 14 (ordered list)
-msgid "**Off** - countermeasures are not active"
-msgstr ""
-
-#: ../content/posts/farbling.md:block 14 (ordered list)
-msgid ""
-"**Balanced** - various APIs have modified values based on domain/session "
-"keys"
-msgstr ""
-
-#: ../content/posts/farbling.md:block 14 (ordered list)
-msgid ""
-"**Maximum** - various APIs values replaced by randomised values based on "
-"domain/session keys"
-msgstr ""
-
-#: ../content/posts/farbling.md:block 15 (paragraph)
-msgid "Now, what changes did actually Brave implement to specific APIs?"
-msgstr ""
-
-#: ../content/posts/farbling.md:block 16 (header)
-msgid "Canvas"
-msgstr ""
-
-#: ../content/posts/farbling.md:block 17 (paragraph)
-msgid ""
-"Canvas modifications are tracked in a separate "
-"[issue](https://github.com/brave/brave-browser/issues/9186). Both *balanced*"
-" and *maximum* approach modify API calls "
-"`CanvasRendering2dContext.getImageData`, `HTMLCanvasElement.toDataURL`, "
-"`HTMLCanvasElement.toBlob`, and `OffscreenCanvas.convertToBlob`. A [Filter "
-"function](https://github.com/brave/brave-"
-"core/blob/master/chromium_src/third_party/blink/renderer/core/execution_context/execution_context.cc)"
-" changes values of certain pixels chosen based on session/domain keys, "
-"resulting in a unique canvas fingerprint. On *maximum* level, methods "
-"`CanvasRenderingContext2D.isPointInPath` and "
-"`CanvasRenderingContext2D.isPointInStroke` always return *false*."
-msgstr ""
-
-#: ../content/posts/farbling.md:block 18 (header)
-msgid "WebGL"
-msgstr ""
-
-#: ../content/posts/farbling.md:block 19 (paragraph)
-msgid ""
-"Modifications for both WebGL and WebGL2 are described in issues "
-"[webgl](https://github.com/brave/brave-browser/issues/9188) , "
-"[webgl2](https://github.com/brave/brave-browser/issues/9189). On *balanced* "
-"level `WebGLRenderingContext.getParameter` and other methods return slightly"
-" modified values. `WebGLRenderingContext.readPixels` is modified similarly "
-"to canvas methods. On *maximum* level, `WebGLRenderingContext.getParameter` "
-"returns random strings for unmasked vendor and renderer, bottom values for "
-"other arguments. Other modified calls return bottom values. All "
-"modifications can be found in the issues mentioned above or directly in the "
-"[code](https://github.com/brave/brave-"
-"core/tree/master/chromium_src/third_party/blink/renderer/modules/webgl)."
-msgstr ""
-
-#: ../content/posts/farbling.md:block 20 (header)
-msgid "Web Audio"
-msgstr ""
-
-#: ../content/posts/farbling.md:block 21 (paragraph)
-msgid ""
-"The [issue](https://github.com/brave/brave-browser/issues/9187) modifies "
-"several endpoints of `AnalyserNode` and `AudioBuffer` APIs used for audio "
-"data handling are modified. On the *balanced* level, the amplitude of "
-"returned audio data is slightly changed based on the domain key. However, "
-"data are replaced by white noise generated from domain hash on the maximum "
-"level, so there is no relation with original data."
-msgstr ""
-
-#: ../content/posts/farbling.md:block 22 (header)
-msgid "Plugins"
-msgstr ""
-
-#: ../content/posts/farbling.md:block 23 (paragraph)
-msgid ""
-"Currently, `navigator.plugins` and `navigator.mimeTypes` are modified on "
-"*balanced* level to return an array with altered plugins and two fake "
-"plugins. On *maximum* level, the returned array contains only two fake "
-"plugins. See [issue1](https://github.com/brave/brave-browser/issues/9435) "
-"and [issue2](https://github.com/brave/brave-browser/issues/10597) for more "
-"details."
-msgstr ""
-
-#: ../content/posts/farbling.md:block 24 (header)
-msgid "User agent"
-msgstr ""
-
-#: ../content/posts/farbling.md:block 25 (paragraph)
-msgid ""
-"Brave employs the default Chrome UA and the newest OS version as the user "
-"agent string. Also, a random number of blank spaces (up to 5) appended to "
-"the end of the user agent string. For more details, see the [GitHub "
-"issue](https://github.com/brave/brave-browser/issues/9190)."
-msgstr ""
-
-#: ../content/posts/farbling.md:block 26 (header)
-msgid "EnumerateDevices"
-msgstr ""
-
-#: ../content/posts/farbling.md:block 27 (paragraph)
-msgid ""
-"This API is used to list I/O media devices like microphone or speakers. When"
-" fingerprinting protection is active, Brave returns a shuffled list of "
-"devices. For more details, see [issue1](https://github.com/brave/brave-"
-"browser/issues/11271) and [issue2](https://github.com/brave/brave-"
-"browser/issues/8666)."
-msgstr ""
-
-#: ../content/posts/farbling.md:block 28 (header)
-msgid "HardwareConcurrency"
-msgstr ""
-
-#: ../content/posts/farbling.md:block 29 (paragraph)
-msgid ""
-"The number of logical processors returned by this interface is modified as "
-"follows -- on *balanced* level, a valid value between 2 and the true value, "
-"on *maximum* level, a valid value between 2 and 8. See the [GitHub "
-"issue](https://github.com/brave/brave-browser/issues/10808) for more "
-"details."
-msgstr ""
-
-#: ../content/posts/farbling.md:block 30 (header)
-msgid "Porting Farbling to JShelter"
-msgstr ""
-
-#: ../content/posts/farbling.md:block 31 (paragraph)
-msgid ""
-"Our goal was to extend JShelter anti-fingerprinting protections with similar"
-" measures to those available in Brave's Farbling. We decided to implement "
-"Brave Farbling with minor tweaks. As Brave is an open-source project based "
-"on [Chromium](https://www.chromium.org/Home), core changes are available in "
-"the public [repository](https://github.com/brave/brave-core). Furthermore, "
-"as Brave is licensed under [MPL 2.0](https://www.mozilla.org/en-US/MPL/2.0/)"
-" license, its countermeasures can be ported to JShelter. Similarly to Brave,"
-" JShelter utilises session and domain hashes (currently, we use a different "
-"domain hash based on origin, however, we consider switching to the eTLD+1 "
-"approach used by Brave). Nevertheless, we ported only those changes that an "
-"extension can reasonably apply. So we do not plan to change system fonts as "
-"the true set of fonts can leak in several ways (e.g., CSS, canvas). We will "
-"keep a close eye on anti-fingerprining techniquest applied by Brave in the "
-"future."
-msgstr ""
-
-#: ../content/posts/farbling.md:block 32 (paragraph)
-msgid ""
-"Former JShelter defences were left as an option so user can choose which "
-"protection they want. For example, for **Canvas API**, JShelter retains the "
-"old defence that returns a white image, but it is also possible to use "
-"Farbling and slightly modify the image."
-msgstr ""
-
-#: ../content/posts/farbling.md:block 33 (paragraph)
-msgid ""
-"`CanvasRenderingContext2D.isPointInPath` and "
-"`CanvasRenderingContext2D.isPointInStroke` are modified to return *false* "
-"with 5% probability, returning *false* to every call seems to be easily "
-"identifiable and it limits the usablity of the calls."
-msgstr ""
-
-#: ../content/posts/farbling.md:block 34 (paragraph)
-msgid ""
-"**WebGL**, **Web audio**, **plugins**, **hardwareConcurrency** and "
-"**deviceMemory** have been changed accordingly to Brave. API "
-"**enumerateDevices** has the same functionality as in Brave. In addition, we"
-" add fake devices to the list. **User agent** wasn't modified because it can"
-" cause compatibility issues as we support multiple browsers. Adding empty "
-"spaces at the end of UAS seems to be quite a weak countermeasure. We will "
-"continue to watch changes in the user agent and may implement some defence "
-"in future, although it looks like a [better "
-"solution](https://datatracker.ietf.org/doc/html/rfc8942) is on the way."
-msgstr ""
-
-#: ../content/posts/farbling.md:block 35 (paragraph)
-msgid ""
-"JShelter 0.5 changes the default level -- **level 2** to apply the farbling-"
-"based defence for all covered APIs, and it will be very similar to the "
-"*balanced* level of *Brave*. **Level 3** is redesigned to partly apply new "
-"and partly old countermeasures to provide as little information as possible."
-" Please report websites that does not work correctly with Farbling."
-msgstr ""
-
-#: ../content/posts/farbling.md:block 36 (paragraph)
-msgid ""
-"During the examination of the ported code, we [identified and "
-"reported](https://github.com/brave/brave-browser/issues/15882) an issue in "
-"the original Brave implementation. The issue was acknowledged and fixed by "
-"Brave. This is the beauty of the free software: several projects can benefit"
-" from the same code-base and mutualy improve the quality."
-msgstr ""
-
-#: ../content/posts/farbling.md:block 38 (paragraph)
-msgid ""
-"Farbling-based wrappers produce very similar outputs to Brave. So with "
-"JShelter, Farbling-like capabilities are available in multiple browsers. "
-"Nevertheless, keep in mind that the best anti-fingerprinting techniques are "
-"still a research question, fingerprinting techniques are deployed for "
-"security reasons (and farbling-like anti-fingerprinting masking may "
-"complicate some log in processes), so it is not completely clear what "
-"defences are the best and the choice of the defences also depends on "
-"specific use cases. We will investigate fingerprinting scripts further "
-"during the future work on this project."
-msgstr ""
-
-#: ../content/posts/fingerprinting.md:block 1 (header)
-msgid ""
-"title: Browser fingerprinting and JShelter\n"
-"date: 2022-01-14 13:00\n"
-"modified: 2023-04-14 14:00\n"
-"Series: Browser fingerprinting\n"
-"series_index: 1"
-msgstr ""
-
-#: ../content/posts/fingerprinting.md:block 2 (paragraph)
-msgid ""
-"This post introduces [browser "
-"fingerprinting](https://arxiv.org/pdf/1905.01051.pdf) and anti-"
-"fingerprinting mechanisms. We explain what JShelter implements and the "
-"strengths and downsides of the anti-fingerprinting mechanisms."
-msgstr ""
-
-#: ../content/posts/fingerprinting.md:block 3 (paragraph)
-msgid ""
-"In short, browser fingerprinting is a stateless tracking method vastly "
-"prevalent on the web in recent years. Similarly to a human *fingerprint*, "
-"browser fingerprinting tries to find a set of features that make (almost) "
-"every fingerprint unique and the browser uniquely identifiable."
-msgstr ""
-
-#: ../content/posts/fingerprinting.md:block 4 (paragraph)
-msgid ""
-"The fingerprinting features contain various sources, mostly accessible "
-"through browser application interfaces, APIs. The APIs provide essential "
-"functionality for modern websites; however, they leak sensitive information "
-"about the browser, operating system, or device itself. Many different "
-"devices are connected to the internet — most of them with a very specific "
-"configuration. Leaking hardware and software properties may result in a "
-"sufficiently identifiable browser fingerprint. Furthermore, do not forget "
-"about the possibility of leaking information that may uncover "
-"vulnerabilities of your system for the sake of potential attackers."
-msgstr ""
-
-#: ../content/posts/fingerprinting.md:block 5 (paragraph)
-msgid ""
-"At first glance, browser fingerprinting seems to be a great evil in the "
-"world full of privacy concerns. However, we should be aware of two distinct "
-"purposes for using browser fingerprinting."
-msgstr ""
-
-#: ../content/posts/fingerprinting.md:block 6 (paragraph)
-msgid ""
-"Firstly, there is *a negative or destructive use case* during which websites"
-" profile cross-domain user activities without user consent. Trackers use the"
-" fingerprint as a cross-domain identifier."
-msgstr ""
-
-#: ../content/posts/fingerprinting.md:block 7 (paragraph)
-msgid ""
-"Secondly, there is *a positive or constructive use case*, where websites "
-"tend to collect information about your system to improve the usability or "
-"security of their application. For example, applications can recommend "
-"installing critical security updates based on your system properties. Some "
-"websites collect browser fingerprints to verify known devices of their users"
-" to prevent fraud. The JShelter.org website offers the download link in the "
-"extension store based on the user agent."
-msgstr ""
-
-#: ../content/posts/fingerprinting.md:block 8 (paragraph)
-msgid ""
-"Many browser vendors have already introduced changes to the cookie policy. "
-"Browsers such as Firefox, Safari, and Brave block third-party cookies, often"
-" abused for stateful tracking. Chrome developers [recently "
-"announced](https://blog.google/products/chrome/updated-timeline-privacy-"
-"sandbox-milestones/) that they will jump on the bandwagon too. The counter-"
-"measures against stateful tracking techniques result in a substantial "
-"increase in the usage of browser fingerprinting."
-msgstr ""
-
-#: ../content/posts/fingerprinting.md:block 9 (header)
-msgid "Counter-measures to browser fingerprinting"
-msgstr ""
-
-#: ../content/posts/fingerprinting.md:block 10 (paragraph)
-msgid ""
-"Unlike cookies, browser fingerprinting does not require storing an "
-"identifier on the device. Instead, the identifier is recomputed with each "
-"visited page. Once the fingerprint is obtained, it can be sent to a tracking"
-" server in a subsequent request. Moreover, the whole process of fingerprint "
-"extraction is invisible to a user. There are many sources of potentially "
-"identifiable information from which a fingerprint can be constructed. A "
-"fingerprint is considered *passive* when it contains natively accessible "
-"information from HTTP headers or network traffic. On the other hand, "
-"*active* fingerprint runs JavaScript code to retrieve data from browser "
-"APIs. JShelter focuses on detecting and preventing active fingerprinting."
-msgstr ""
-
-#: ../content/posts/fingerprinting.md:block 11 (paragraph)
-msgid ""
-"Nowadays, there are many solutions to mitigate the effects of browser "
-"fingerprinting to improve internet privacy."
-msgstr ""
-
-#: ../content/posts/fingerprinting.md:block 12 (paragraph)
-msgid ""
-"[Modifying the content of fingerprints](/farbling/) is a valid choice to "
-"resist a fingerprinting attempt. However, each modification may create an "
-"inconsistency that may improve the fingerprintability of the browser. Many "
-"protection tools use predefined or real fingerprints instead of the user's "
-"one to counter this issue."
-msgstr ""
-
-#: ../content/posts/fingerprinting.md:block 13 (paragraph)
-msgid ""
-"Another approach is to create homogeneous fingerprints. If every fingerprint"
-" is the same, there is no way to tell the users behind the browsers apart. "
-"The leading representative of this approach is the [Tor "
-"browser](https://www.torproject.org/). Level 3 of JShelter aims to create a "
-"homogenous fingerprint. Unfortunately, homogeneous fingerprints have an "
-"inherent downside of following specific rules to be effective. Most "
-"importantly, the effectiveness of the approach depends on the broad coverage"
-" of the blocked APIs and the size of the population employing the counter-"
-"measures. All browsers with the same fingerprint form an anonymity set. An "
-"observer cannot distinguish between browsers in the anonymity set. With "
-"every missed fingerprintable attribute, the anonymity set breaks into "
-"smaller sets. For example, the Tor browser strongly recommends using a "
-"specific window size. Suppose you use a window size different from all other"
-" Tor browser users. In that case, a fingerprinter can identify you solely by"
-" this attribute. Also, keep in mind that Tor browser hides your IP address, "
-"which JShelter does not do. Hence we see Level 3 protections more as leak "
-"prevention than an anti-fingerprinting measure. If you like the idea of "
-"homogeneous fingerprints, install Tor browser."
-msgstr ""
-
-#: ../content/posts/fingerprinting.md:block 14 (paragraph)
-msgid ""
-"[Brave browser](https://brave.com/) modifies the readings from APIs misused "
-"to create fingerprints. Nevertheless, the goal is to [create a unique "
-"fingerprint for each domain and session](/farbling/). As the fingerprint "
-"changes for every visited domain, its use for linking cross-domain "
-"activities is smaller. JShelter already [implements the farbling protection "
-"of Brave](/farbling/) and uses them as the default anti-fingerprinting "
-"approach."
-msgstr ""
-
-#: ../content/posts/fingerprinting.md:block 15 (paragraph)
-msgid ""
-"Recently, we added [Fingerprint detector (FPD)](/fpdetection/) to JShelter. "
-"FPD does not modify the fingerprint. Instead, FPD monitors APIs that are "
-"often misused by fingerprinters. When FPD detects a fingerprinting attempt, "
-"it warns the user. You can also allow FPD to block all subsequent "
-"transmissions of the page and remove stored data to prevent storing the "
-"fingerprint and loading it after a page reload. Hence, FPD allows the page "
-"to compute the fingerprint but (if allowed) blocks the page from uploading "
-"the fingerprint away from your computer."
-msgstr ""
-
-#: ../content/posts/fingerprinting.md:block 16 (paragraph)
-msgid ""
-"Other approaches include blocking JavaScript code from suspicious sources or"
-" decreasing the surface of browser APIs with explicit permission control. "
-"Extensions like [NoScript Suite](https://noscript.net/) are perfect "
-"complementary measures to JShelter."
-msgstr ""
-
-#: ../content/posts/fingerprinting.md:block 17 (paragraph)
-msgid ""
-"Despite all the efforts, there is no ultimate approach that can prevent "
-"fingerprinting while keeping a high level of usability in mind. Every "
-"approach has its strengths and weaknesses, so the challenge is to find a "
-"balance between privacy and usability."
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 1 (header)
-msgid ""
-"title: Catch websites red-handed fingerprinting your browser\n"
-"date: 2022-01-14 14:00\n"
-"Series: Browser fingerprinting"
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 2 (paragraph)
-msgid ""
-"We want to identify [fingerprinting](/fingerprinting/) attempts by counting "
-"the number of different APIs employed by a page, especially those not "
-"frequently used for benign purposes. This blog post introduces a new "
-"fingerprinting protection mechanism - FingerPrint Detector (FPD) available "
-"in JShelter 0.6. This tool allows users to gain more control over browser "
-"fingerprinting, which has become an invisible threat to our privacy."
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 3 (header)
-msgid "Heuristics as a template for the fingerprinting detection"
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 4 (paragraph)
-msgid ""
-"[Mitigation of browser fingerprinting is not "
-"straightforward](/fingerprinting/). FPD does not attempt to prevent a script"
-" from taking a fingerprint. Neither does FPD falsify a fingerprint. Instead,"
-" FPD monitors the APIs that a web page accesses and detects suspicious "
-"activities. FPD quickly reacts in case of fingerprint extraction and blocks "
-"further web page communication, including storing information."
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 5 (paragraph)
-msgid ""
-"Several studies over the last decade detected fingerprinting attempts. Many "
-"of them used a simple heuristic approach to create a set of conditions. If "
-"these conditions are met, suspicious activity is detected. Studies like [The"
-" Web Never "
-"Forgets](https://securehomes.esat.kuleuven.be/~gacar/persistent/the_web_never_forgets.pdf)"
-" and [A 1-million-site Measurement and "
-"Analysis](https://www.cs.princeton.edu/~arvindn/publications/OpenWPM_1_million_site_tracking_measurement.pdf)"
-" used this approach to measure the real-world occurrence of web tracking. At"
-" the same time, they verified the usability of heuristic-based detection. "
-"They found the detection effective with a very low false-positive rate. The "
-"most challenging part of this approach is a careful selection of detection "
-"conditions. Later, studies began to experiment with more sophisticated "
-"methods. For example, [Fingerprinting the "
-"Fingerprinters](https://web.cs.ucdavis.edu/~zubair/files/fpinspector-"
-"sp2021.pdf) used machine learning for fingerprinting detection. They managed"
-" to achieve even better precision, but at the cost of demanding model "
-"training."
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 6 (paragraph)
-msgid ""
-"For JShelter, we settled down on using a simple heuristic approach, but with"
-" a little twist to it. Internet technology is constantly changing, so we "
-"want to make our heuristics as flexible as possible. Instead of hard-coding "
-"them, we propose a declarative way to describe the heuristics. This concept "
-"allows us to make changes with a new release and progressively [adapt to the"
-" latest changes in the field](/crawling_results/). For this purpose, we "
-"defined JSON configuration files, which contain all the information required"
-" for fingerprinting detection. As these files make an input for our "
-"evaluation/detection logic, their content directly reflects how JShelter "
-"should evaluate websites in terms of fingerprinting."
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 7 (paragraph)
-msgid ""
-"On closer inspection, the configuration files contain two basic types of "
-"entries. Firstly, they define JavaScript endpoints, which are relevant for "
-"fingerprinting detection. Secondly, they group related endpoints. For "
-"example, we group endpoints according to their semantic properties. Imagine "
-"that there are two different endpoints. Both provide hardware information "
-"about the device. We can assign both endpoints to a group that covers access"
-" to hardware properties in this scenario. The configuration allows "
-"clustering groups to other groups and creating a hierarchy of groups. "
-"Ultimately, the configuration is a tree-like structure whose evaluation can "
-"detect browser fingerprinting."
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 8 (paragraph)
-msgid ""
-"The whole evaluation process dynamically observes the API calls performed by"
-" a web page. Note that we analyse the calls themselves. Hence, the dynamic "
-"analysis overcomes any obfuscation of fingerprinting scripts."
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 9 (paragraph)
-msgid ""
-"The current heuristics are based on many prior studies, [our own "
-"crawl](/crawling_results/), and available tools focused on browser "
-"fingerprinting."
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 10 (unordered list)
-msgid "We extracted and modified detection rules from studies like:"
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 10 (unordered list)
-msgid ""
-"[Fingerprinting the "
-"Fingerprinters](https://web.cs.ucdavis.edu/~zubair/files/fpinspector-"
-"sp2021.pdf)"
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 10 (unordered list)
-msgid ""
-"[A 1-million-site Measurement and "
-"Analysis](https://www.cs.princeton.edu/~arvindn/publications/OpenWPM_1_million_site_tracking_measurement.pdf)"
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 10 (unordered list)
-msgid ""
-"[The Web Never "
-"Forgets](https://securehomes.esat.kuleuven.be/~gacar/persistent/the_web_never_forgets.pdf)"
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 10 (unordered list)
-msgid "We reflected traits of known fingerprinting tools like:"
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 10 (unordered list)
-msgid "[FingerprintJS](https://github.com/fingerprintjs)"
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 10 (unordered list)
-msgid "[Am I Unique](https://amiunique.org/)"
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 10 (unordered list)
-msgid "[Cover Your Tracks](https://coveryourtracks.eff.org/)"
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 10 (unordered list)
-msgid "We utilized knowledge of existing detection tools like:"
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 10 (unordered list)
-msgid ""
-"[A Fingerprinting Monitor For Chrome "
-"(FPMON)](https://fpmon.github.io/fingerprinting-monitor/)"
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 10 (unordered list)
-msgid "[Don't FingerPrint Me (DFPM)](https://github.com/freethenation/DFPM)"
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 11 (header)
-msgid "Keep your fingerprint for yourself"
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 12 (paragraph)
-msgid ""
-"FPD works in three basic phases, *monitoring*, *evaluation* and *reactive*."
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 13 (header)
-msgid "Monitoring phase"
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 14 (paragraph)
-msgid ""
-"If the FPD module is active, it locally logs all accesses to crucial "
-"JavaScript API endpoints during the monitoring phase. FPD injects custom "
-"wrapping code of all suspicious APIs (properties or methods) into the "
-"browser when a user visits a page. Hence, the extension observes API calls "
-"initiated by the website."
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 15 (paragraph)
-msgid ""
-"FPD stores the number of accessed calls in the context of a displayed page. "
-"It contains all the metadata needed for evaluation. This metadata includes "
-"the number of calls for each logged endpoint with a corresponding argument "
-"value. Consequently, FPD can tell how often the visited web page called a "
-"particular endpoint and the arguments for these calls."
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 16 (header)
-msgid "Evaluation phase"
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 17 (paragraph)
-msgid ""
-"The evaluation phase starts whenever a new HTTP request occurs. FPD counts "
-"the fingerprinting score from the observed calls in the past. If the "
-"fingerprinting score is above a specified threshold, FPD considers a web "
-"page to perform fingerprinting. In this case, FPD warns the user with a "
-"notification."
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 18 (paragraph)
-msgid ""
-"![Notification example for Chrome (left) and Firefox "
-"(right).]({attach}/images/fpdetection/notifications.png)"
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 19 (header)
-msgid "Reactive phase"
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 20 (paragraph)
-msgid ""
-"FPD blocks all subsequent asynchronous HTTP requests initiated by the "
-"fingerprinting page in the reaction phase. After that, FPD cleans all "
-"supported browser storage mechanisms such as `cookies` and `localStorage`. "
-"This measure prevents web pages from caching already extracted fingerprints "
-"for later transmission. To be clear, blocking of subsequent requests **may "
-"result in breakage** of the visited page. The user can create an exception "
-"for the page and add it to a whitelist in this situation. FPD is not active "
-"on whitelisted domains for browser fingerprinting. Users can opt in to be "
-"fingerprinted on the pages they trust."
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 21 (paragraph)
-msgid ""
-"For now, we only support whitelisting of the visited domains. However, as "
-"fingerprinting is often performed for security reasons and it is more "
-"prevalent on login pages, we plan to evaluate if adding a specific behaviour"
-" for a URL is a better choice."
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 22 (header)
-msgid "Testing fingerprinting detection in the wild"
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 23 (paragraph)
-msgid ""
-"The line between fingerprinting and non-fingerprinting behaviour is very "
-"thin. Defining the fixed threshold can easily result in very doubtful "
-"results. Hence, the heuristics approach needs careful fine-tuning."
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 24 (paragraph)
-msgid ""
-"We have made significant efforts to tailor the heuristics in such a way as "
-"to target mainly excessive fingerprints that identify users. We also focused"
-" on achieving a very low number of false positives for a better user "
-"experience. Because of the radical step of blocking subsequent requests, we "
-"must ensure that this blocking occurs only in the necessary cases when there"
-" is a high probability of fingerprinting."
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 25 (paragraph)
-msgid ""
-"Additionally, it is very hard to differentiate between benign and "
-"fingerprinting usage of a JavaScript endpoint. From the heuristic point of "
-"view, setting a higher threshold for fingerprinting behaviour helps FPD "
-"reduce false positives. We decided to verify all these assumptions in "
-"practice. We tested FPD on real-world web pages and refined heuristics "
-"accordingly."
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 26 (paragraph)
-msgid ""
-"In terms of methodology, we manually visited homepages and login pages of "
-"the top 100 websites from [the Tranco list](https://tranco-"
-"list.eu/list/23W9/1000000). For inaccessible websites at the time of "
-"testing, we replaced them with random websites from the top 200 list."
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 27 (paragraph)
-msgid ""
-"With each access to the tested page, we wiped browser settings to ensure "
-"determinism of initial access. As the erasure removed any previously-stored "
-"identifier, the visited pages may have deployed fingerprinting scripts more "
-"aggressively to identify the user and reinstall the identifier."
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 28 (paragraph)
-msgid ""
-"To boost the probability of fingerprinting even more, we switched off all "
-"protection mechanisms offered by the browser. However, we blocked third-"
-"party cookies because our previous experience suggests that the missing "
-"possibility to store a permanent identifier tempts trackers to start "
-"fingerprinting. To see an impact of a browser on the detection process, we "
-"used both [Google Chrome](https://www.google.com/chrome/) and [Mozzila "
-"Firefox](https://www.mozilla.org/en-US/firefox/)."
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 29 (paragraph)
-msgid ""
-"We needed the ground truth for web pages employing fingerprinting. We used "
-"[FPMON](https://fpmon.github.io/fingerprinting-monitor/) and "
-"[DFPM](https://github.com/freethenation/DFPM) to create the ground truth. We"
-" selected these two extensions because they are the only ones capable of "
-"real-time fingerprinting detection. FPMON reports fingerprinting pages with "
-"colour. We assigned Yellow colour 1 point and red colour 3 points. DFPM "
-"reports danger warnings. If DFPM reports one danger warning, we assign 1 "
-"point to the page. For a higher number of danger warnings, we assign 3 "
-"points to the page. Therefore, each page gets a fingerprinting score from 0 "
-"to 6."
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 30 (paragraph)
-msgid ""
-"The score of 6 means that both extensions detected excessive fingerprinting "
-"behaviour. Web pages with the score of 6 certainly deploy fingerprinting, "
-"and FPD must detect such pages. FPD does not detect fingerprinting on "
-"*Google login* pages since FPD heuristics evaluate *Google login* pages just"
-" below its threshold. FPMON and DFPM detect fingerprinting on *Google login*"
-" pages but just above their thresholds. *Google login* pages occurred six "
-"times in total during testing. According to the methodology, these are false"
-" negatives. Nevertheless, the final fingerprint is not aggressive enough to "
-"provide enough entropy to identify most users uniquely."
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 31 (paragraph)
-msgid ""
-"The score of 4 means that one extension detected fingerprinting and the "
-"other suspects. We classify these web pages as deploying fingerprinting. FPD"
-" managed to detect all web pages with two exceptions, *Facebook login* page "
-"and `yandex.ru`. Both are border-line cases that do not obtain enough "
-"entropy, similarly to *Google login* pages."
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 32 (paragraph)
-msgid ""
-"The score of 3 means that one extension detected fingerprinting and the "
-"other did not detect fingerprinting at all. FPMON and DFPM treat browser "
-"fingerprinting differently, so we observed a few web pages with this score. "
-"It is questionable how to classify these pages when the reference extensions"
-" conflict. FPD does not detect most of these pages. FPD detected "
-"fingerprinting only on one of these pages, *Paypal login* page. We consider "
-"this detection justified as we manually checked FPD logs and found clear "
-"tracks of [canvas fingerprinting](https://fingerprintjs.com/blog/canvas-"
-"fingerprinting/). In contrast, FPMON reported negligible fingerprinting "
-"signs and did not recognise the fingerprinting attempt."
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 33 (paragraph)
-msgid ""
-"The score of 2 means that both extensions suspect fingerprinting. We assume "
-"that web pages with this score may or may not fingerprint. Nevertheless, the"
-" fingerprint is likely not extensive enough to serve as a unique identifier "
-"if they do. Moreover, these web pages are prone to misclassification because"
-" they may be close to the heuristic threshold. FPD detected two web pages "
-"with this score, namely *Cloudflare login* page and *Washingtonpost login* "
-"page. A closer analysis revealed that both pages use canvas fingerprinting "
-"in conjunction with other fingerprinting methods. Interestingly, the "
-"reference extensions could not detect such fingerprinting with enough "
-"certainty."
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 34 (paragraph)
-msgid ""
-"The score of 1 means that only one extension suspects fingerprinting, and "
-"the other extension does not detect anything. Similarly, for the score of 0 "
-"where neither reference extension does detect fingerprinting. According to "
-"our testing methodology, FPD should not detect such web pages as "
-"fingerprinting. However, FPD detected fingerprinting on `ebay.com`. Manual "
-"inspection showed that `ebay.com` did fingerprint indeed using canvas "
-"fingerprinting, [audio fingerprinting](https://fingerprintjs.com/blog/audio-"
-"fingerprinting/) and other techniques. Amusingly, the string used by canvas "
-"fingerprint says `\"@Browsers~%fingGPRint$&,<canvas>\"`."
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 35 (paragraph)
-msgid ""
-"We decided to classify web pages as follows. We considered a page to be "
-"fingerprinting when its score is above or equal to 4. We did not count pages"
-" with the score of 3 or 2 as fingerprinting because they may not be engaged "
-"in fingerprinting in reality. It means that FPD may or may not detect such "
-"pages; we do not count such classification as an error in both cases. As "
-"discussed above, we manually inspected FPD in these situations. Finally, we "
-"consider anything below the score of 2 as not fingerprinting."
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 36 (unordered list)
-msgid "Number of fingerprinting web pages identified by *our ground truth*."
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 36 (unordered list)
-msgid "Homepages: **20**"
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 36 (unordered list)
-msgid "Login pages: **34**"
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 36 (unordered list)
-msgid "Number of fingerprinting web pages identified by *JShelter*."
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 36 (unordered list)
-msgid "Login pages: **30**"
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 36 (unordered list)
-msgid "Number of wrong identifications by *JShelter*."
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 36 (unordered list)
-msgid "Homepages: **2**"
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 36 (unordered list)
-msgid "False positives: **1**"
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 36 (unordered list)
-msgid "False negatives: **1**"
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 36 (unordered list)
-msgid "Login pages: **7**"
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 36 (unordered list)
-msgid "False positives: **0**"
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 36 (unordered list)
-msgid "False negatives: **7**"
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 37 (paragraph)
-msgid ""
-"At first glance, the numbers are close but not the same. Different heuristic"
-" thresholds of the extensions caused the main difference. However, as we "
-"found out, the ground truth is far from being flawless. We encountered many "
-"exceptions during testing and examined them in detail. In many cases, FPD "
-"detects fingerprinting, but the reference extensions do not. For `ebay.com`,"
-" neither FPMON nor DPFM identified the ongoing fingerprinting. We got a very"
-" low false positive rate and an acceptable false negative rate in terms of "
-"methodology."
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 38 (paragraph)
-msgid ""
-"We also observed other notable behaviour during the testing. The asymmetry "
-"between detection on different browsers was minor but did occur sometimes. "
-"However, the difference between browsers should be minimal. We had "
-"implemented a mechanism that automatically recalculates heuristics to "
-"compensate unsupported APIs. Finally, note that blocking tools like "
-"*adblockers* can significantly reduce the number of positive detections. "
-"These tools use filter lists to block tracking scripts before their "
-"execution. Using FPD with a filter-based blocking tool can significantly "
-"improve user experience and privacy."
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 39 (header)
-msgid "TL;DR"
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 40 (paragraph)
-msgid ""
-"We have developed a JShelter module dedicated to browser fingerprinting "
-"detection called *FingerPrint Detector (FPD)*. FPD applies a heuristic "
-"approach to detect fingerprinting behaviour in real-time. FPD counts calls "
-"to JavaScript APIs often employed by fingerprinting scripts. When FPD "
-"detects fingerprinting attempt, it will (1) inform the user, (2) prevent "
-"uploading of the fingerprint to the server, (3) prevent storing the "
-"fingerprint for later usage. We tested FPD on the top 100 homepages and "
-"login pages. The results show that FPD identifies excessive fingerprinting "
-"behaviour and takes the necessary measures against fingerprint leakage."
-msgstr ""
-
-#: ../content/posts/fpdetection.md:block 41 (paragraph)
-msgid ""
-"Nevertheless, there is always more work to do. The detection heuristics "
-"still have room for improvement. The real-world testing yields stimulating "
-"research questions. How to define an excessive fingerprint? What "
-"fingerprints should be blocked by the extension, and what fingerprints "
-"should not? What is the best behaviour (threshold) so that the users find "
-"the extension helpful?"
-msgstr ""
-
-#: ../content/posts/i18n_developers.md:block 1 (header)
-msgid ""
-"title: What should a JShelter developer know about internationalization?\n"
-"date: 2023-08-31 15:00\n"
-"Series: i18n"
-msgstr ""
-
-#: ../content/posts/i18n_developers.md:block 2 (paragraph)
-msgid ""
-"We are working to improve the internationalization of JShelter. While the "
-"webextension API already contains [APIs](https://developer.mozilla.org/en-"
-"US/docs/Mozilla/Add-ons/WebExtensions/API/i18n) for internationalization, "
-"not everything works great. This post is written for webextension developers"
-" as well as JShelter developers working with strings presented to our users."
-" Please see our [other post](/i18n/) if you are looking for ways to "
-"translate JShelter."
-msgstr ""
-
-#: ../content/posts/i18n_developers.md:block 4 (header)
-msgid "Translating manifest, CSS files, and JS files"
-msgstr ""
-
-#: ../content/posts/i18n_developers.md:block 5 (paragraph)
-msgid ""
-"Let us start with the simple and easy items. Adding your translated strings "
-"to the [manifest](https://developer.mozilla.org/en-US/docs/Mozilla/Add-"
-"ons/WebExtensions/Internationalization#internationalizing_manifest.json) and"
-" [CSS](https://developer.mozilla.org/en-US/docs/Mozilla/Add-"
-"ons/WebExtensions/Internationalization#locale-dependent_css) files is really"
-" simple and straightforward. For example, if you want to provide a "
-"translatable description of your extension, you would change your "
-"`manifest.json` to contain a line like:"
-msgstr ""
-
-#: ../content/posts/i18n_developers.md:block 7 (paragraph)
-msgid ""
-"You add the description as `extensionDescription` to your `messages.json`:"
-msgstr ""
-
-#: ../content/posts/i18n_developers.md:block 9 (paragraph)
-msgid "Similarly, you can localize CSS files like:"
-msgstr ""
-
-#: ../content/posts/i18n_developers.md:block 11 (paragraph)
-msgid "Afterward, you define `ShieldOnSlider`, and you are done."
-msgstr ""
-
-#: ../content/posts/i18n_developers.md:block 12 (paragraph)
-msgid ""
-"Translations in JavaScript files work a little bit differently, but it is "
-"easy to adapt your JavaScript files. You just use the "
-"`browser.i18n.getMessage` [API](https://developer.mozilla.org/en-"
-"US/docs/Mozilla/Add-ons/WebExtensions/API/i18n/getMessage). You provide the "
-"key in the `messages.json`. This time, you can add parameters that can be "
-"utilized inside the `messages.json` file. For example, you can pass a string"
-" that should appear inside the translated string:"
-msgstr ""
-
-#: ../content/posts/i18n_developers.md:block 14 (paragraph)
-msgid "and the `message.json` can contain something like:"
-msgstr ""
-
-#: ../content/posts/i18n_developers.md:block 16 (paragraph)
-msgid ""
-"If you like the placeholders, for example, because you read in the best "
-"practices that placeholder substitutions help specify parts that you [do not"
-" want translated](https://developer.mozilla.org/en-US/docs/Mozilla/Add-"
-"ons/WebExtensions/Internationalization#hardcoded_substitution). You are out "
-"of luck if you want to add parameters to your manifest or CSS files. "
-"Luckily, JShelter does not need parameters in manifest and CSS files, and "
-"such a need is rare."
-msgstr ""
-
-#: ../content/posts/i18n_developers.md:block 17 (header)
-msgid "Translating HTML files"
-msgstr ""
-
-#: ../content/posts/i18n_developers.md:block 18 (paragraph)
-msgid ""
-"Webextensions contain HTML pages. For example, you can configure "
-"`options_ui` or `default_popup` in `manifest.json`. Even so, the "
-"[internationalization page on MDN](https://developer.mozilla.org/en-"
-"US/docs/Mozilla/Add-ons/WebExtensions/Internationalization) is quiet about "
-"the internationalization of HTML files. Let us have a [look at what others "
-"do](https://stackoverflow.com/questions/25467009/internationalization-of-"
-"html-pages-for-my-google-chrome-extension)."
-msgstr ""
-
-#: ../content/posts/i18n_developers.md:block 19 (paragraph)
-msgid ""
-"In essence, others add some markup to the HTML file and later process that "
-"markup in JS files. For example, in JShelter, we add `data-localize` "
-"attribute to each element we want to translate. The attribute holds the key "
-"in the `message.json`. For example, JShelter defines:"
-msgstr ""
-
-#: ../content/posts/i18n_developers.md:block 21 (paragraph)
-msgid ""
-"We added a [translation "
-"file](https://pagure.io/JShelter/webextension/blob/bff8ce9c69ca28c1952898125983429c1f7f8a32/f/common/i18n_translate_dom.js)"
-" `i18n_translate_dom.js` to all HTML pages with translatable elements. The "
-"script is simple. It finds elements with the correct attributes and forwards"
-" the strings to the `browser.i18n.getMessage` "
-"[API](https://developer.mozilla.org/en-US/docs/Mozilla/Add-"
-"ons/WebExtensions/API/i18n/getMessage)."
-msgstr ""
-
-#: ../content/posts/i18n_developers.md:block 22 (paragraph)
-msgid ""
-"Still, one needs to take care of special sections in the pages, like "
-"[templates](https://pagure.io/JShelter/webextension/blob/bff8ce9c69ca28c1952898125983429c1f7f8a32/f/common/i18n_translate_dom.js#_43)."
-msgstr ""
-
-#: ../content/posts/i18n_developers.md:block 23 (paragraph)
-msgid ""
-"The lack of a standard way to cope with HTML translations means that if you "
-"go to different webextension, they will likely have a similar script, but "
-"the details would be different. That is not optimal."
-msgstr ""
-
-#: ../content/posts/i18n_developers.md:block 24 (header)
-msgid "Language priorities"
-msgstr ""
-
-#: ../content/posts/i18n_developers.md:block 25 (paragraph)
-msgid ""
-"Webextension manifest file specifies `default_locale` as the default "
-"language. This language is used as the last resort to pick untranslated "
-"strings. Each language can have variants like `en_US` and `en_UK`. "
-"Translators can create `message.json` for variants and the base language "
-"(like `en`). Browsers select translations based on [the algorithm documented"
-" on MDN](https://developer.mozilla.org/en-US/docs/Mozilla/Add-"
-"ons/WebExtensions/Internationalization#localized_string_selection). First, "
-"they look for the variant, then for the base language, and if they are not "
-"successful, they go to the `default_locale`. The API returns an empty string"
-" if the default language does not contain the key."
-msgstr ""
-
-#: ../content/posts/i18n_developers.md:block 26 (paragraph)
-msgid ""
-"Unfortunately, there is no way to tweak the algorithm. For example, some "
-"languages are similar. Czech speakers mostly understand Slovaks and vice-"
-"versa. However, JShelter cannot tweak the algorithm to look at the Czech "
-"translation if a Slovak translation is missing."
-msgstr ""
-
-#: ../content/posts/i18n_developers.md:block 27 (header)
-msgid "Handling plurals"
-msgstr ""
-
-#: ../content/posts/i18n_developers.md:block 28 (paragraph)
-msgid ""
-"Plurals in English are simple for cardinal numbers. There is just the "
-"singular and plural version. However, English has several forms for ordinal "
-"numbers, like 1st, 2nd, 3rd, 4th, or 21st. Other languages behave "
-"[differently](https://www.unicode.org/cldr/charts/43/supplemental/language_plural_rules.html)."
-" In essence, almost every language has a specific handling of plurals."
-msgstr ""
-
-#: ../content/posts/i18n_developers.md:block 29 (paragraph)
-msgid ""
-"Although there is the `Intl.PluralRules()` "
-"[API](https://developer.mozilla.org/en-"
-"US/docs/Web/JavaScript/Reference/Global_Objects/Intl/PluralRules) in "
-"JavaScript that is available to webextensions, there is no direct support "
-"for plural messages in the `browser.i18n` API."
-msgstr ""
-
-#: ../content/posts/i18n_developers.md:block 30 (paragraph)
-msgid ""
-"We considered creating several keys for the plural forms. For example, "
-"suppose that JShelter needs to translate a string with `message.json` key "
-"`pluralExample`. We would create a code like:"
-msgstr ""
-
-#: ../content/posts/i18n_developers.md:block 32 (paragraph)
-msgid ""
-"At first sight, this is a straightforward solution. However, English defines"
-" only categories \"one\" and \"other.\" Imagine that the user uses a "
-"different locale with the category \"few.\" If JShelter supports that "
-"language and that language defines `pluralExamplefew`, great, everything "
-"works. But imagine the key `pluralExamplefew` is missing for that language. "
-"The [string selection algorithm](https://developer.mozilla.org/en-"
-"US/docs/Mozilla/Add-"
-"ons/WebExtensions/Internationalization#localized_string_selection) would "
-"search for `pluralExamplefew` in English `message.json`. However, that key "
-"would not be defined in English. So, the string selection algorithm would "
-"yield an empty string."
-msgstr ""
-
-#: ../content/posts/i18n_developers.md:block 33 (paragraph)
-msgid "There are several solutions to the problem:"
-msgstr ""
-
-#: ../content/posts/i18n_developers.md:block 34 (unordered list)
-msgid ""
-"Define all variants for the default locale language. We do not like that "
-"idea because it would be confusing for the translators — why is there "
-"`pluralExamplefew` and other categories if only `one` and `other` are used "
-"in English? They might attempt to remove the unused variants. Moreover, we "
-"would unnecessarily overload the translators as they would need to provide "
-"the default translation even if that is the same as \"other.\" Finally, "
-"translators of other languages would likely be confused and add their "
-"translations that would overwhelm them as well."
-msgstr ""
-
-#: ../content/posts/i18n_developers.md:block 34 (unordered list)
-msgid ""
-"We could create code that handles the missing translations. For example, the"
-" program should check that `message` is not empty. If empty, it would get "
-"the plural category for the English locale and the English translation. We "
-"might opt for this path in the future."
-msgstr ""
-
-#: ../content/posts/i18n_developers.md:block 34 (unordered list)
-msgid ""
-"There are libraries like [webextension-"
-"plural](https://github.com/joelspadin/webextension-plural) that specialize "
-"in this task. However, `webextension-plural` has not been developed for "
-"several years."
-msgstr ""
-
-#: ../content/posts/i18n_developers.md:block 35 (paragraph)
-msgid ""
-"As JShelter would benefit from plurals only in notifications of Network "
-"Boundary Shield that we might be forced to remove in Manifest v3, we decided"
-" not to write complex code to handle all exceptions and not to add "
-"additional dependencies. We decided to generate messages like \"Blocked "
-"messages: 5\"."
-msgstr ""
-
-#: ../content/posts/i18n_developers.md:block 36 (header)
-msgid "Placeholders used in complex messages"
-msgstr ""
-
-#: ../content/posts/i18n_developers.md:block 37 (paragraph)
-msgid ""
-"[Developers should not make assumptions about the composition of the "
-"sentences](https://mozilla-l10n.github.io/documentation/localization/dev_best_practices.html#splitting-"
-"and-composing-sentences). However, some texts need special rules."
-msgstr ""
-
-#: ../content/posts/i18n_developers.md:block 38 (paragraph)
-msgid ""
-"Consider the buttons for adding and removing exceptions for Network Boundary"
-" Shield and Fingerprint Detector. For example, the \"Enable for the selected"
-" domains\" button caption. We want to give the user a full and clear "
-"explanation; hence, the text is long. But we also want to emphasize the word"
-" \"Enable.\" So the button caption uses HTML markup: "
-"`<strong>Enable</strong> for the selected domains`."
-msgstr ""
-
-#: ../content/posts/i18n_developers.md:block 39 (paragraph)
-msgid ""
-"We decided to use placeholders to describe to translators how to handle the "
-"translation:"
-msgstr ""
-
-#: ../content/posts/i18n_developers.md:block 41 (paragraph)
-msgid ""
-"This way, translators are free to change the structure of the message. For "
-"example, consider that the translator decides that an appropriate "
-"translation to Czech is \"Vybrané domény "
-"&lt;strong&gt;povol&lt;/strong&gt;\". The word \"enable\" is translated as "
-"\"povol\". The translator can generate text like:"
-msgstr ""
-
-#: ../content/posts/i18n_developers.md:block 43 (paragraph)
-msgid ""
-"All perfect until we decided to use "
-"[Weblate](https://hosted.weblate.org/projects/jshelter/webextension/) to "
-"help with the translation, for example, to notify translators about new and "
-"changed strings that need translations. According to the "
-"[docs](https://docs.weblate.org/en/latest/formats/webextension.html), "
-"Weblate does support Webextension JSON. [Weblate "
-"manual](https://readthedocs.org/projects/weblate/downloads/pdf/weblate-3.9.1/)"
-" lists `placeholders as supported. The Weblate UI does not properly display "
-"placeholders. Translators [do not see the "
-"description](https://github.com/WeblateOrg/weblate/issues/3398) and example "
-"content of the placeholders. They cannot translate the content of the "
-"placeholder."
-msgstr ""
-
-#: ../content/posts/i18n_developers.md:block 44 (paragraph)
-msgid "In this case, we could change the definition to something like:"
-msgstr ""
-
-#: ../content/posts/i18n_developers.md:block 46 (paragraph)
-msgid ""
-"However, we have other complex cases where dividing the message into "
-"placeholders makes sense. For example, we suggest different rules for "
-"translating a part of the message, like API names. Hence, we created "
-"[scripts](https://pagure.io/JShelter/webextension/blob/main/f/tools/i18n) to"
-" help synchronize the strings between the repository and Weblate so that all"
-" strings can be translated in Weblate. A developer needs to run the "
-"synchronization scripts manually. The expected order is to first propagate "
-"changes from Grammarly to main (or other branch), and after that, propagate "
-"the changes from that branch in the repository to Weblate."
-msgstr ""
-
-#: ../content/posts/i18n_developers.md:block 47 (header)
-msgid "Additional reading"
-msgstr ""
-
-#: ../content/posts/i18n_developers.md:block 48 (paragraph)
-msgid ""
-"If you are a JShelter developer or are interested in helping JShelter's "
-"internationalization development, please read [localization best practices "
-"for "
-"developers](https://mozilla-l10n.github.io/documentation/localization/dev_best_practices.html),"
-" [MDN guide on webextension "
-"internationalization](https://developer.mozilla.org/en-US/docs/Mozilla/Add-"
-"ons/WebExtensions/Internationalization), and the [i18n API "
-"documentation](https://developer.mozilla.org/en-US/docs/Mozilla/Add-"
-"ons/WebExtensions/API/i18n)."
-msgstr ""
-
-#: ../content/posts/i18n.md:block 1 (header)
-msgid ""
-"title: JShelter can be translated into different languages\n"
-"date: 2023-09-08 14:00\n"
-"Series: i18n\n"
-"series_index: 1"
-msgstr ""
-
-#: ../content/posts/i18n.md:block 2 (paragraph)
-msgid ""
-"JShelter's audience is international. As not all people speak English, "
-"JShelter is now adding support for internationalization. Hence, it can be "
-"translated into languages other than English."
-msgstr ""
-
-#: ../content/posts/i18n.md:block 3 (paragraph)
-msgid ""
-"The webextension API already contains "
-"[APIs](https://developer.mozilla.org/en-US/docs/Mozilla/Add-"
-"ons/WebExtensions/API/i18n) that help to [translate "
-"extensions](https://developer.mozilla.org/en-US/docs/Mozilla/Add-"
-"ons/WebExtensions/Internationalization). This way we can localize not only "
-"the interface of the extension but also its description and even the name."
-msgstr ""
-
-#: ../content/posts/i18n.md:block 5 (header)
-msgid "Status"
-msgstr ""
-
-#: ../content/posts/i18n.md:block 6 (paragraph)
-msgid ""
-"JShelter can be translated to other languages as of version 0.14. Besides "
-"English, Czech and Russian translations are also available."
-msgstr ""
-
-#: ../content/posts/i18n.md:block 7 (paragraph)
-msgid ""
-"Nevertheless, we are looking for translators in other languages. If you are "
-"willing to translate JShelter to a language that you know, please read on. "
-"We suggest that you contact us early so that we have information about "
-"ongoing translations and that we can tell you if someone else is already "
-"interested in the same language as you."
-msgstr ""
-
-#: ../content/posts/i18n.md:block 8 (header)
-msgid "How can I translate JShelter? Option 1: Weblate"
-msgstr ""
-
-#: ../content/posts/i18n.md:block 9 (paragraph)
-msgid ""
-"We use [Weblate](https://github.com/WeblateOrg/weblate) to manage the "
-"translations. This software helps us monitor the status of the translations,"
-" providing suggestions and improving the lives of the translators. If you "
-"want to help, visit [JShelter on "
-"Weblate](https://hosted.weblate.org/projects/jshelter/webextension/). You "
-"can send us suggestions without registration. However, some features, like "
-"notifications, are only available to registered users."
-msgstr ""
-
-#: ../content/posts/i18n.md:block 10 (paragraph)
-msgid "When you start translating, you should see a form like:"
-msgstr ""
-
-#: ../content/posts/i18n.md:block 11 (paragraph)
-msgid "![A screenshot from Weblate]({attach}/images/i18n/webly.png)"
-msgstr ""
-
-#: ../content/posts/i18n.md:block 12 (paragraph)
-msgid "The interface shows:"
-msgstr ""
-
-#: ../content/posts/i18n.md:block 13 (ordered list)
-msgid "The name of the key of the currently translated string,"
-msgstr ""
-
-#: ../content/posts/i18n.md:block 13 (ordered list)
-msgid "the original English translation,"
-msgstr ""
-
-#: ../content/posts/i18n.md:block 13 (ordered list)
-msgid "the description of the usage of the string,"
-msgstr ""
-
-#: ../content/posts/i18n.md:block 13 (ordered list)
-msgid "the translation to the current target language,"
-msgstr ""
-
-#: ../content/posts/i18n.md:block 13 (ordered list)
-msgid ""
-"the information on similar and nearby strings that might be handy to grasp "
-"the context of the string,"
-msgstr ""
-
-#: ../content/posts/i18n.md:block 13 (ordered list)
-msgid "glossary containing key terms used in the project."
-msgstr ""
-
-#: ../content/posts/i18n.md:block 14 (paragraph)
-msgid ""
-"Most of the strings that translators face are simple, as shown above. "
-"However, some strings are composed with `placeholders` (see the translation "
-"option 2 for more details on placeholders). For example, consider [string "
-"`defaultLevelSelection`](https://hosted.weblate.org/translate/jshelter/webextension/en/?checksum=a11db49ff616c6f0&sort_by=-priority,position)."
-" Its English translation is `Default level ($levelName$)`. Strings enclosed "
-"by `$` signs (`levelName` in this case) are `placeholders`. Each placeholder"
-" is in the database with the key composed as `the base key "
-"###placeholders### placeholder name`. So, in this case, the key of the "
-"placeholder is `defaultLevelSelection###placeholders###levelName`."
-msgstr ""
-
-#: ../content/posts/i18n.md:block 15 (paragraph)
-msgid ""
-"Most placeholders should not be changed. The typical content of such "
-"placeholders is like `$1`. It means that the extension generates the "
-"content, and typically, translators are supposed to keep the string intact. "
-"Always read carefully the description of the usage of the string that "
-"indicates how the string should be translated."
-msgstr ""
-
-#: ../content/posts/i18n.md:block 16 (paragraph)
-msgid ""
-"Some placeholder strings contain the names of APIs or other technical terms."
-" For example, `jssgroupTimePrecisionDescription2###placeholders###apis` in "
-"English contains `(Date, Performance, events, Gamepad API, and Web VR API)`."
-" Please read the instructions for each string carefully. In this case, "
-"translators should keep the names of the APIs but translate the punctuation "
-"and conjunctions."
-msgstr ""
-
-#: ../content/posts/i18n.md:block 17 (paragraph)
-msgid ""
-"Please consider the translations of each placeholder in the context of the "
-"base string so that the whole string makes sense. It should be easy to find "
-"the base key. Look at the start of the placeholder key or to the "
-"instructions. Weblate should show the base string and its placeholders in "
-"the *Nearby strings* section."
-msgstr ""
-
-#: ../content/posts/i18n.md:block 18 (paragraph)
-msgid ""
-"Strings containing URLs should not be translated. However, occasionally, "
-"there is a localized version of the content at the original URL. In such "
-"cases, it makes sense to provide URL to the localized version."
-msgstr ""
-
-#: ../content/posts/i18n.md:block 19 (paragraph)
-msgid ""
-"As we explain below, we do not support plural forms due to technical "
-"limitations and our decisions. So, use phrasing that does not need plurals. "
-"See the example for option 2 for more details."
-msgstr ""
-
-#: ../content/posts/i18n.md:block 20 (header)
-msgid "How can I translate JShelter? Option 2: JSON files in the repository"
-msgstr ""
-
-#: ../content/posts/i18n.md:block 21 (paragraph)
-msgid ""
-"Technically, translations are strings located in JSON files, one JSON file "
-"per language. The languages are stored in the "
-"[`common/_locales`](https://pagure.io/JShelter/webextension/blob/i18n/f/common/_locales)"
-" directory. If you do not see your language there, you can add a new "
-"language by creating a new directory with the [language "
-"code](https://www.unicode.org/cldr/charts/43/supplemental/language_plural_rules.html)"
-" as the name, see the [docs](https://developer.mozilla.org/en-"
-"US/docs/Mozilla/Add-"
-"ons/WebExtensions/Internationalization#localized_string_selection)."
-msgstr ""
-
-#: ../content/posts/i18n.md:block 22 (paragraph)
-msgid ""
-"Then, copy the `en/messages.json` to the just created directory, and you "
-"have the basis for the translation."
-msgstr ""
-
-#: ../content/posts/i18n.md:block 23 (paragraph)
-msgid "Next, go through all the strings and translate them to your language."
-msgstr ""
-
-#: ../content/posts/i18n.md:block 24 (paragraph)
-msgid "Typically, a translation entry looks like this:"
-msgstr ""
-
-#: ../content/posts/i18n.md:block 26 (paragraph)
-msgid ""
-"The first line (`javascriptShield`) displays the name of the string. "
-"JShelter pairs the name of the string with the locations in the source code "
-"where this translation should appear. So, do not change that line."
-msgstr ""
-
-#: ../content/posts/i18n.md:block 27 (paragraph)
-msgid ""
-"The second line (key `message`) shows the actual translation. Usually, "
-"translators are supposed to change that line."
-msgstr ""
-
-#: ../content/posts/i18n.md:block 28 (paragraph)
-msgid ""
-"The third line is the description of the context of the string. So, for "
-"example, the translator would learn where and how the extension uses the "
-"message. Please do not translate the description."
-msgstr ""
-
-#: ../content/posts/i18n.md:block 29 (paragraph)
-msgid "So, for example, in the Czech translation, the entry becomes:"
-msgstr ""
-
-#: ../content/posts/i18n.md:block 31 (paragraph)
-msgid "However, some entries are more tricky, let us look at:"
-msgstr ""
-
-#: ../content/posts/i18n.md:block 33 (paragraph)
-msgid ""
-"The `message` contains a variable enclosed by the dollar sign (in this case,"
-" `levelName`). Note that the `placeholders` section contains the "
-"specification of the variable. We add substrings with special properties to "
-"the `placeholders` section. Such substrings are either filled automatically "
-"or hold data that should be translated according to the different rules than"
-" the `message`. Follow the `description` to learn the rules."
-msgstr ""
-
-#: ../content/posts/i18n.md:block 34 (paragraph)
-msgid ""
-"In this case, the single `placeholders` entry contains three keys: "
-"`content`, `description`, and `example`. The meaning of the description is "
-"the same as in the original case. It explains the context of the variable. "
-"Additionally, `example` gives example strings or their description to "
-"provide the translator with more information about the possible content. The"
-" `content` controls how the content is created. If the file does not give "
-"translators any further instructions (like in this case), please do not "
-"translate the `placeholder` section. So the translated entry becomes:"
-msgstr ""
-
-#: ../content/posts/i18n.md:block 36 (paragraph)
-msgid "See that only the `message` string changed."
-msgstr ""
-
-#: ../content/posts/i18n.md:block 37 (paragraph)
-msgid "A more complicated example is:"
-msgstr ""
-
-#: ../content/posts/i18n.md:block 39 (paragraph)
-msgid ""
-"This string holds two placeholders: `apis` and "
-"`jssgroupPhysicalLocationGeolocation`. Let us start from the end. "
-"`jssgroupPhysicalLocationGeolocation` should not be touched by the "
-"translator. The text explains that `jssgroupPhysicalLocationGeolocation` "
-"will hold the translation of the string with the same name during the "
-"execution of the extension (\"Physical location (geolocation)\" in this "
-"case). Do not change anything in entries like "
-"`jssgroupPhysicalLocationGeolocation` during the translation."
-msgstr ""
-
-#: ../content/posts/i18n.md:block 40 (paragraph)
-msgid ""
-"Then, there is the entry called `apis`. If you look at the content, it does "
-"not refer to any automatically filled string like the previous examples. "
-"Instead, the string holds the names of several APIs. The `desription` "
-"provides instructions on how to handle the translation. In this case, we "
-"suggest keeping the APIs' names in English. That way, the user can search "
-"for the APIs for more information. If you translate the API names, the user "
-"would likely be unable to find any information about the API. However, "
-"different languages have different rules for punctuation, and the "
-"conjunction *and* must be translated. So the translation can look like:"
-msgstr ""
-
-#: ../content/posts/i18n.md:block 42 (paragraph)
-msgid ""
-"Note that the original translation used a different kind of quotation marks."
-" The English original uses the same character as the JSON delimiter. Hence, "
-"the character '' precedes the quotation mark. The Czech translation does not"
-" use quotation marks conflicting with the JSON quotation marks, so it does "
-"not need the '' sign."
-msgstr ""
-
-#: ../content/posts/i18n.md:block 43 (paragraph)
-msgid ""
-"Occasionally, we extract URLs to the `placeholders` section to highlight "
-"that they should not be translated like:"
-msgstr ""
-
-#: ../content/posts/i18n.md:block 45 (paragraph)
-msgid ""
-"Note that strings for translation can hold HTML markup in some cases. In "
-"that case, we suggest keeping the same markup. However, if other languages "
-"handle such texts differently, translators are free to apply such rules. The"
-" translation can look like:"
-msgstr ""
-
-#: ../content/posts/i18n.md:block 47 (paragraph)
-msgid ""
-"On rare occasions, we do not expect the translators to touch the `message` "
-"itself but rather work with the placeholders. For example, see:"
-msgstr ""
-
-#: ../content/posts/i18n.md:block 49 (paragraph)
-msgid ""
-"You can see that the message holds a template with an HTML markup. In this "
-"case, we opted for this approach for several reasons:"
-msgstr ""
-
-#: ../content/posts/i18n.md:block 50 (unordered list)
-msgid ""
-"We expect translators to preserve the same template (`message`) in most, if "
-"not all, languages."
-msgstr ""
-
-#: ../content/posts/i18n.md:block 50 (unordered list)
-msgid "Each paragraph (`placeholders` entry) can have specific instructions."
-msgstr ""
-
-#: ../content/posts/i18n.md:block 50 (unordered list)
-msgid ""
-"The text blocks are not as long as a single block containing all text would "
-"be."
-msgstr ""
-
-#: ../content/posts/i18n.md:block 51 (paragraph)
-msgid ""
-"English has a single plural form for cardinal numbers (usually a suffix `s` "
-"or `es` appended to the singular form) and several forms of ordinal numbers "
-"(1st, 2nd, 3rd, 4th). [Other languages behave "
-"differently.](https://www.unicode.org/cldr/charts/43/supplemental/language_plural_rules.html)"
-" Unfortunately, the [Webextension APIs do not handle plurals "
-"well](/i18n_developers/) and JShelter could use plurals only in "
-"notifications of Network Boundary Shield, so we decided to rephrase the "
-"messages so plurals are not needed:"
-msgstr ""
-
-#: ../content/posts/i18n.md:block 53 (header)
-msgid "Final remarks"
-msgstr ""
-
-#: ../content/posts/i18n.md:block 54 (paragraph)
-msgid ""
-"If you want to start translating a new language, let us know. For example, "
-"you can open an issue in the [issue "
-"tracker](https://pagure.io/JShelter/webextension/issues) or send us "
-"[e-mail](mailto:jshelter@gnu.org). If you are in doubt about how to "
-"translate a string or do not understand its meaning, let us know in an "
-"[issue](https://pagure.io/JShelter/webextension/issues) or send us "
-"[e-mail](mailto:jshelter@gnu.org)."
-msgstr ""
-
-#: ../content/posts/jsrfinal.md:block 1 (header)
-msgid ""
-"title: Final remarks on the JSR project\n"
-"date: 2022-05-10 18:00\n"
-"Series: JShelter background"
-msgstr ""
-
-#: ../content/posts/jsrfinal.md:block 2 (paragraph)
-msgid ""
-"The [JavaScript Restrictor](https://nlnet.nl/project/JSRestrictor/) "
-"([JSR](/support/)) project (supported by [NGI0 PET "
-"Fund](https://nlnet.nl/PET), a fund established by "
-"[NLnet](https://nlnet.nl/) with financial support from the European "
-"Commission's [Next Generation Internet](https://ngi.eu/) programme, under "
-"the aegis of DG Communications Networks, Content and Technology under grant "
-"agreement No 825310) is heading towards its end, and we summarize what the "
-"project gave JShelter and reiterate the chosen approaches."
-msgstr ""
-
-#: ../content/posts/jsrfinal.md:block 3 (header)
-msgid "What are the steps that JShelter takes to protect users?"
-msgstr ""
-
-#: ../content/posts/jsrfinal.md:block 4 (paragraph)
-msgid ""
-"During the NGI0 PET Fund JSR project, we investigated fingerprinting scripts"
-" and prepared wrappers, developed Fingerprint Detector, ported anti-"
-"fingerprinting mechanisms from Brave, and improved the reliability of the "
-"code-injection mechanisms (the credit for the relaible injection goes to "
-"[the parallel NGI0 PET project](https://nlnet.nl/project/JShelter/)). Let us"
-" go through the list in more detail:"
-msgstr ""
-
-#: ../content/posts/jsrfinal.md:block 5 (paragraph)
-msgid ""
-"We reviewed literature focusing on the fingerprinting scripts and studied "
-"APIs [declined by Apple](https://github.com/polcak/jsrestrictor/issues/66). "
-"During the project, we added or improved wrappers to JavaScript Shield for:"
-msgstr ""
-
-#: ../content/posts/jsrfinal.md:block 6 (unordered list)
-msgid "All API calls providing timestamps,"
-msgstr ""
-
-#: ../content/posts/jsrfinal.md:block 6 (unordered list)
-msgid "`window.name`,"
-msgstr ""
-
-#: ../content/posts/jsrfinal.md:block 6 (unordered list)
-msgid "`MediaDevices.prototype.enumerateDevices`"
-msgstr ""
-
-#: ../content/posts/jsrfinal.md:block 6 (unordered list)
-msgid "Beacon API,"
-msgstr ""
-
-#: ../content/posts/jsrfinal.md:block 6 (unordered list)
-msgid "Canvas API and Web GL API,"
-msgstr ""
-
-#: ../content/posts/jsrfinal.md:block 6 (unordered list)
-msgid "Audio API,"
-msgstr ""
-
-#: ../content/posts/jsrfinal.md:block 6 (unordered list)
-msgid "`Navigator.prototype.hardwareConcurrency`"
-msgstr ""
-
-#: ../content/posts/jsrfinal.md:block 6 (unordered list)
-msgid "`Navigator.prototype.deviceMemory`"
-msgstr ""
-
-#: ../content/posts/jsrfinal.md:block 6 (unordered list)
-msgid "`Navigator.prototype.getGamepads`"
-msgstr ""
-
-#: ../content/posts/jsrfinal.md:block 6 (unordered list)
-msgid "`Navigator.prototype.activeVRDisplays`"
-msgstr ""
-
-#: ../content/posts/jsrfinal.md:block 6 (unordered list)
-msgid "`Navigator.prototype.plugins`"
-msgstr ""
-
-#: ../content/posts/jsrfinal.md:block 6 (unordered list)
-msgid ""
-"Sensor API: Magnetometer, Accelerometer, LinearAccelerationSensor, "
-"GravitySensor, Gyroscope,"
-msgstr ""
-
-#: ../content/posts/jsrfinal.md:block 6 (unordered list)
-msgid ""
-"AbsoluteOrientationSensor, RelativeOrientationSensor, and AmbientLightSensor"
-msgstr ""
-
-#: ../content/posts/jsrfinal.md:block 6 (unordered list)
-msgid "BigInt typed arrays"
-msgstr ""
-
-#: ../content/posts/jsrfinal.md:block 6 (unordered list)
-msgid "`Navigator.prototype.requestMediaKeySystemAccess`"
-msgstr ""
-
-#: ../content/posts/jsrfinal.md:block 6 (unordered list)
-msgid "`MediaCapabilities.prototype.encodingInfo`"
-msgstr ""
-
-#: ../content/posts/jsrfinal.md:block 6 (unordered list)
-msgid "`MediaCapabilities.prototype.decodingInfo`"
-msgstr ""
-
-#: ../content/posts/jsrfinal.md:block 6 (unordered list)
-msgid "`HTMLMediaElement.prototype.canPlayType`"
-msgstr ""
-
-#: ../content/posts/jsrfinal.md:block 6 (unordered list)
-msgid "Network Information API"
-msgstr ""
-
-#: ../content/posts/jsrfinal.md:block 6 (unordered list)
-msgid "Web NFC API"
-msgstr ""
-
-#: ../content/posts/jsrfinal.md:block 6 (unordered list)
-msgid "Cooperative Scheduling of Background Tasks API"
-msgstr ""
-
-#: ../content/posts/jsrfinal.md:block 6 (unordered list)
-msgid "User idle detection"
-msgstr ""
-
-#: ../content/posts/jsrfinal.md:block 7 (paragraph)
-msgid ""
-"Note that JShelter modifies APIs depending on the selected JavaScript Shield"
-" level and the tweaks for the visited domain."
-msgstr ""
-
-#: ../content/posts/jsrfinal.md:block 8 (paragraph)
-msgid ""
-"Previous literature modifies outputs of some APIs differently during "
-"repeated calls. JShelter [adopted the model of Brave](/farbling/). Hence, "
-"different origins read different values from the same APIs. One origin reads"
-" the same values for each repeated reading in the same browser session. "
-"Therefore, a fingerprint computed from these values is different for each "
-"origin and session, making cross-site correlation harder. Note that some "
-"identifiers like an IP address are outside of JShelter reach. JShelter "
-"provides different readings to the same origin in a new browser session."
-msgstr ""
-
-#: ../content/posts/jsrfinal.md:block 9 (paragraph)
-msgid ""
-"[FP-Random](https://github.com/plaperdr/fprandom) modifies data inserted "
-"into the canvas. For example, if the page wants to draw with orange colour, "
-"FP-Random draws with a different shade of orange. We do not think that this "
-"is a good strategy for JShelter:"
-msgstr ""
-
-#: ../content/posts/jsrfinal.md:block 10 (unordered list)
-msgid ""
-"JShelter currently does not modify what users see in canvases (i.e. the "
-"browser does not modify the visual representation). JShelter only modifies "
-"read data - so each script sees different values than users. In other words,"
-" while FP-Random breaks both visual representation and export functions, "
-"JShelter breaks only export functions."
-msgstr ""
-
-#: ../content/posts/jsrfinal.md:block 10 (unordered list)
-msgid ""
-"Web GL offers visual effects produced by lighting, textures and other "
-"techniques. Identifying all mechanisms that need to be wrapped and modified "
-"seem to be too complex and out of the reach of this project."
-msgstr ""
-
-#: ../content/posts/jsrfinal.md:block 11 (paragraph)
-msgid ""
-"JShelter provides [Fingerprint Detector](/fpdetection/) (FPD), a module that"
-" heuristically detects fingerprinting and notifies users with an option to "
-"block future communications. This anti-fingerprinting mechanism is "
-"orthogonal to the little lies anti-fingerprinting mechanisms in JavaScript "
-"Shield, and we advise using both mechanisms. Little lies help if the "
-"fingerprinting scripts upload some readings before FPD detects the attempt "
-"or the user deactivates FPD for a website. FPD provides an additional safety"
-" net for fingerprinters trying to nullify the little lies. FPD also provides"
-" a report page that can educate users about the APIs misused for "
-"fingerprinting. We developed code for crawling websites and detecting APIs "
-"often blocked by uBlock Origin with the goal of gradually improving "
-"heuristics. We do not have an automatic generation of heuristics, and manual"
-" oversight is needed."
-msgstr ""
-
-#: ../content/posts/jsrfinal.md:block 12 (paragraph)
-msgid ""
-"The badge icon does not show level ID anymore. It shows the number of "
-"wrapping groups accessed by the current page as a number; the colour informs"
-" the user about the likelihood that the current page tries to fingerprint "
-"the user. The user can see more details about the activated wrappers and FPD"
-" findings in the popup window."
-msgstr ""
-
-#: ../content/posts/jsrfinal.md:block 13 (paragraph)
-msgid ""
-"JShelter depends on [NSCL](https://github.com/hackademix/nscl/) (developed "
-"outside JSR project) that provides reliable cross-browser support to inject "
-"scripts before page scripts can access original APIs. That solved several "
-"long-standing bugs and allowed the extension to be used with confidence. "
-"However, NSCL does not implement reliable code injections into WebWorkers, "
-"so we apply Strict WebWorker protection by default. The protection disables "
-"WebWorkers and replaces them with a polyfill."
-msgstr ""
-
-#: ../content/posts/jsrfinal.md:block 14 (header)
-msgid "Issues"
-msgstr ""
-
-#: ../content/posts/jsrfinal.md:block 15 (paragraph)
-msgid ""
-"During the final stages of the NGI0 PET Fund project JSR project, we "
-"investigated the consistency of the mechanisms and their real-world "
-"deployment. We closed [6 issues on "
-"Pagure](https://pagure.io/JShelter/webextension/issues?status=Closed&milestone=NLNet+evaluation)"
-" and [13 issues on "
-"Github](https://github.com/polcak/jsrestrictor/issues?q=is%3Aissue+label%3A%22NLNet+project+evaluation+phase%22+is%3Aclosed)."
-msgstr ""
-
-#: ../content/posts/jsrfinal.md:block 16 (paragraph)
-msgid ""
-"5 investigated issues remain open on "
-"[Github](https://github.com/polcak/jsrestrictor/issues?q=is%3Aissue+label%3A%22NLNet+project+evaluation+phase%22+is%3Aopen)."
-" For three we need more details or cannot reproduce the issue, two refer to "
-"bugs that we are trying to fix (the issues were delegated to other JShelter "
-"developer outside the JSR project)."
-msgstr ""
-
-#: ../content/posts/jsrfinal.md:block 17 (paragraph)
-msgid ""
-"We opened [8 "
-"issues](https://pagure.io/JShelter/webextension/issues?status=Open&tags=enhancement&milestone=NLNet+evaluation&close_status=)"
-" that cover possible enhancement of the JShelter, future directions, and "
-"possible ideas for future projects. We have additional [5 opened issues on "
-"Pagure](https://pagure.io/JShelter/webextension/issues?status=Open&milestone=NLNet+evaluation&close_status=)"
-" that we investigated during the evaluation phase. "
-"[One](https://pagure.io/JShelter/webextension/issue/55) is a duplicate of "
-"the issue opened at Github, "
-"[another](https://pagure.io/JShelter/webextension/issue/37) is almost "
-"closed. We are working on all 5 issues outside the JSR project."
-msgstr ""
-
-#: ../content/posts/jsrfinal.md:block 19 (paragraph)
-msgid ""
-"JShelter is not perfect, but we believe that we are heading in the right "
-"direction. We want to continue to work on this project. However, be patient "
-"with some issues that need time and a lot of work to be solved. The JSR "
-"project and the [parallel NGI0 PET Fund "
-"project](https://nlnet.nl/project/JShelter/) transformed the original "
-"JavaScript Restrictor extension to JShelter, suitable for everyday "
-"protection."
-msgstr ""
-
-#: ../content/posts/jsrfinal.md:block 20 (paragraph)
-msgid ""
-"If you have not noticed yet, we created a [FAQ section](/faq/) and the page "
-"describing [JShelter threat model](/threatmodel/) during the final stages of"
-" the JSR project."
-msgstr ""
-
-#: ../content/posts/localportscanning.md:block 1 (header)
-msgid ""
-"title: How JShelter prevents other parties from sniffing on your local applications?\n"
-"date: 2021-06-15 09:00"
-msgstr ""
-
-#: ../content/posts/localportscanning.md:block 2 (paragraph)
-msgid ""
-"We recently found a [blog post](https://blog.nem.ec/2020/05/24/ebay-port-"
-"scanning/) about ThreatMetrix Inc. (a part of LexisNexis) scanning locally "
-"open ports for about 30,000 web sites, including eBay. The figure below "
-"shows that a browser tries to connect to ports commonly used for remote "
-"access to the computer (e.g., RDesktop, VNC, TeamViewer) and other "
-"applications."
-msgstr ""
-
-#: ../content/posts/localportscanning.md:block 3 (paragraph)
-msgid ""
-"![A screenshot of the browser being used as a proxy to scan locally open "
-"ports]({attach}/images/portscan-1_captured_traffic.png)"
-msgstr ""
-
-#: ../content/posts/localportscanning.md:block 4 (paragraph)
-msgid ""
-"The obvious question is, what is the reason for such behaviour? The simple "
-"answer is security. See additional links to [Security "
-"Boulevard](https://securityboulevard.com/2020/05/is-ebay-port-scanning-your-"
-"pc-probably/), [Avast](https://blog.avast.com/why-is-ebay-port-scanning-my-"
-"computer-avast), and [The "
-"register](https://www.theregister.com/2020/05/26/ebay_port_scans_your_pc/)."
-msgstr ""
-
-#: ../content/posts/localportscanning.md:block 5 (paragraph)
-msgid ""
-"One possibility is that ThreatMetrix creates a "
-"[fingerprint](https://arxiv.org/pdf/1905.01051.pdf), and locally running "
-"applications are a part of the fingerprint. Consequently, the authentication"
-" algorithm stores attributes about your device(s) and compare them during "
-"each log in with the previous values. Seeing that you are logging in using a"
-" previously seen device, the algorithm can let you in with just a password "
-"without additional proves. However, should you use a new device, the "
-"algorithm might decide that additional authentication steps are required and"
-" send you an SMS."
-msgstr ""
-
-#: ../content/posts/localportscanning.md:block 6 (paragraph)
-msgid ""
-"Another option is that ThreatMetrix knows that many fraudulent activities "
-"occur on devices with specific ports open. Recall that the ports being "
-"checked concern remote desktop access. Having a remote desktop port open "
-"means that the computer may be used by an adversary that does not sit near "
-"the computer but is connected remotely. Consequently, the authentication "
-"algorithm might decide that additional proves about the user identity should"
-" be checked."
-msgstr ""
-
-#: ../content/posts/localportscanning.md:block 7 (paragraph)
-msgid ""
-"We do not know what the real reason behind the scanning is. It might be one "
-"of the above, both, or a similar reason."
-msgstr ""
-
-#: ../content/posts/localportscanning.md:block 8 (header)
-msgid "Ethical and legal issues"
-msgstr ""
-
-#: ../content/posts/localportscanning.md:block 9 (paragraph)
-msgid ""
-"Although it could be that the underlying intentions are benign and users "
-"actually do benefit from the scanning, the scanning raises some ethical "
-"issues."
-msgstr ""
-
-#: ../content/posts/localportscanning.md:block 10 (paragraph)
-msgid ""
-"Very often, security and privacy are interconnected. But sometimes, one "
-"might increase security by revealing something private. In this case, "
-"ThreatMetrix learns information about the running device that is not obvious"
-" to the device owner (a user or a company). Typically, the owner of the "
-"device does not even know that such information can leak. If the information"
-" stays with ThreatMetrix, then the benefits could appear to be greater than "
-"the disadvantages. However, adversaries could stole information from "
-"ThreatMetrix (see for example the [Ecquifax "
-"breach](https://en.wikipedia.org/wiki/2017_Equifax_data_breach)) or the "
-"company can start to [sell](https://www.vice.com/en/article/qjdkq7/avast-"
-"antivirus-sells-user-browsing-data-investigation) the "
-"[information](https://www.pcmag.com/news/the-cost-of-avasts-free-antivirus-"
-"companies-can-spy-on-your-clicks) or even [share with "
-"others](https://brave.com/rtb-evidence/)."
-msgstr ""
-
-#: ../content/posts/localportscanning.md:block 11 (paragraph)
-msgid ""
-"So is the scanning and data collecting legal? As some of our developers and "
-"users are based in the EU, we will dig into the EU perspective. You might "
-"want to consult your local laws if you are outside the EU. Moreover, as we "
-"are not lawyers, you might want to consult one even in the EU."
-msgstr ""
-
-#: ../content/posts/localportscanning.md:block 12 (paragraph)
-msgid ""
-"[EU ePrivacy Directive](https://eur-lex.europa.eu/legal-"
-"content/EN/ALL/?uri=CELEX:32002L0058) applies. However, as [WP29 "
-"clarified](https://ec.europa.eu/justice/article-29/documentation/opinion-"
-"recommendation/files/2014/wp224_en.pdf) (use case 7.5), user-centric "
-"security can be viewed as strictly necessary to provide the service. So it "
-"seems likely that port scanning for security reasons would trigger the "
-"ePrivacy exception and user consent is not necessary."
-msgstr ""
-
-#: ../content/posts/localportscanning.md:block 13 (paragraph)
-msgid ""
-"As the port scanning is a part of the login mechanism, open ports are "
-"personal data without doubts. So GDPR also applies. GDPR also list security "
-"as a possible legitimate interest of a data controller (e.g. eBay), see "
-"recital 49. Nevertheless, if such a scan is proportionate is an open "
-"question; it is possible that the legitimate interests of data controllers "
-"(such as eBay) are overriden by the interests or fundamental rights and "
-"freedoms of the data subject (you), see Article(6)(1)(f). The Court of "
-"Justice of EU (CJEU) decided several issues that concerned legitimate "
-"interests and the necessity of processing, e.g. [C-13/16, point 30 that also"
-" points to other related "
-"cases](https://curia.europa.eu/juris/liste.jsf?num=C-13/16) or [C-708/18 "
-"points 40–45](https://curia.europa.eu/juris/liste.jsf?num=C-708/18). It "
-"might be possible that it is strictly necessary for eBay to perform local "
-"port scanning."
-msgstr ""
-
-#: ../content/posts/localportscanning.md:block 14 (paragraph)
-msgid ""
-"Nevertheless, Article 12-14 of GDPR lists requirements on the information "
-"that a data controller should reveal to each data subject before the data "
-"processing starts or in a reasonable time afterwards. Hence, each controller"
-" employing ThreatMetrix should reveal, for example, in the privacy policy, "
-"what categories of data it is using and for which purposes. From the "
-"[linked](https://blog.avast.com/why-is-ebay-port-scanning-my-computer-avast)"
-" "
-"[articles](https://www.theregister.com/2020/05/26/ebay_port_scans_your_pc/),"
-" it seems that ThreatMetrix and eBay are secretive about data being "
-"collected."
-msgstr ""
-
-#: ../content/posts/localportscanning.md:block 15 (paragraph)
-msgid ""
-"Another GDPR issue might be data transfers to third countries. Data "
-"transfers of open ports may not be compatible with GDPR in the light of the "
-"[CJEU C-311/18](https://curia.europa.eu/juris/liste.jsf?num=C-311/18) "
-"decision if the information leaves EEA."
-msgstr ""
-
-#: ../content/posts/localportscanning.md:block 16 (header)
-msgid ""
-"Why is not my browser protecting me from remote servers accessing local "
-"information?"
-msgstr ""
-
-#: ../content/posts/localportscanning.md:block 17 (paragraph)
-msgid ""
-"OK, so even though the scanning could be legal, one can disagree that others"
-" should be allowed to sniff on local applications. So why does a browser "
-"leak the information?"
-msgstr ""
-
-#: ../content/posts/localportscanning.md:block 18 (paragraph)
-msgid ""
-"Well, the browser employs so called [same origin "
-"policy](https://developer.mozilla.org/en-US/docs/Web/Security/Same-"
-"origin_policy) (SOP) that in abstract theory should prevent websites from "
-"the scans in question. As your local computer is of a different origin from "
-"the remote website, your computer should be protected by SOP. Nevertheless, "
-"SOP has its limitations. First of all, some [cross-origin resource "
-"sharing](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) is "
-"beneficial, so the browser cannot block outgoing requests to other origins. "
-"Such behaviour opens possibilities for [side-"
-"channels](https://www.forcepoint.com/sites/default/files/resources/files/report-"
-"attacking-internal-network-en_0.pdf) to be identified. So even though the "
-"web page cannot communicate with applications on your computer (or in your "
-"network) without the cooperation of these applications, it can observe the "
-"behaviour and make some conclusions based on the observed errors, timing, "
-"etc."
-msgstr ""
-
-#: ../content/posts/localportscanning.md:block 19 (paragraph)
-msgid ""
-"An (ad) blocker can prevent you from the activity. As the blockers typically"
-" leverage blocklists, such a port scanning script URL needs to match a rule "
-"in a block list. Once information about a misbehaving script becomes public,"
-" a rule can be added to a block list. However, this could take some time. "
-"Additional techniques like [DNS de-"
-"cloaking](https://blog.lukaszolejnik.com/large-scale-analysis-of-dns-based-"
-"tracking-evasion-broad-data-leaks-included/) need to be applied in this "
-"case."
-msgstr ""
-
-#: ../content/posts/localportscanning.md:block 20 (header)
-msgid "Network Boundary Shield to the rescue"
-msgstr ""
-
-#: ../content/posts/localportscanning.md:block 21 (paragraph)
-msgid ""
-"JShelter contains a Network Boundary Shield (NBS) that blocks outgoing "
-"browser requests based on the observed behaviour, i.e. a page hosted on "
-"public internet tries to access local URLs. NBS just works and cannot be "
-"fooled by changes in the URL path, DNS cloaking or other techniques."
-msgstr ""
-
-#: ../content/posts/localportscanning.md:block 22 (paragraph)
-msgid ""
-"![JShelter blocks the scan]({attach}/images/portscan-2_request_blocked.png)"
-msgstr ""
-
-#: ../content/posts/localportscanning.md:block 23 (paragraph)
-msgid ""
-"Firefox contains DNS API, so NBS works flawlessly. In Chromium-based "
-"browsers, the exact blocking behaviour depends on how quickly a scanning "
-"script can fire the requests and the precise destination (IP address or a "
-"domain name). Depending on the interaction with DNS, NBS can be side-stepped"
-" on Chrome. In this case, ThreatMetrix does not try any evasion technique, "
-"so NBS just works in the case of eBay and ThreatMetrix."
-msgstr ""
-
-#: ../content/posts/mv3.md:block 1 (header)
-msgid ""
-"title: What is Manifest v3 and how it affects JShelter\n"
-"date: 2023-11-01 12:00\n"
-"Series: Manifest v3"
-msgstr ""
-
-#: ../content/posts/mv3.md:block 2 (paragraph)
-msgid ""
-"Over the years, privacy and security-oriented browser extensions in the same"
-" category of JShelter (e.g. uBlock or NoScript, whose code is partially "
-"inherited by JShelter through the NoScript Commons Library), have been "
-"forced into multiple complex refactorings and modernizations, including "
-"complete rewrites such as those [required by the transition from Mozilla's "
-"original flexible XUL/XPCOM technology](https://yoric.github.io/post/why-"
-"did-mozilla-remove-xul-addons/) to the more limiting [WebExtensions "
-"API](https://developer.mozilla.org/en-US/docs/Mozilla/Add-"
-"ons/WebExtensions), largely copied from [Google Chrome's Extensions "
-"API](https://developer.chrome.com/docs/extensions/reference/)."
-msgstr ""
-
-#: ../content/posts/mv3.md:block 3 (paragraph)
-msgid ""
-"During the past 2 years, the [Manifest V3 "
-"API](https://developer.chrome.com/docs/extensions/mv3/intro/) (\"MV3\" from "
-"now on) has been aggressively pushed by Google as the successor of the "
-"current semi-unified browser extensions APIs (known as Manifest V2 or "
-"\"MV2\")."
-msgstr ""
-
-#: ../content/posts/mv3.md:block 4 (paragraph)
-msgid ""
-"MV3 comes with renewed migration challenges, made worse by its "
-"*incompleteness* and apparent [hostility against privacy and security use "
-"cases](https://www.eff.org/deeplinks/2021/12/chrome-users-beware-"
-"manifest-v3-deceitful-and-threatening>)."
-msgstr ""
-
-#: ../content/posts/mv3.md:block 5 (paragraph)
-msgid ""
-"Let's have a look at some threats that the MV3 specification poses to "
-"JShelter and other security and privacy-oriented extensions:"
-msgstr ""
-
-#: ../content/posts/mv3.md:block 6 (unordered list)
-msgid ""
-"The new content script injection APIs are promising on paper, thanks also to"
-" [specific](https://bugs.chromium.org/p/chromium/issues/detail?id=1128112) "
-"[requests](https://bugs.chromium.org/p/chromium/issues/detail?id=1180659) "
-"for "
-"[enhancements](https://bugs.chromium.org/p/chromium/issues/detail?id=1180659#c5)"
-" [coming](https://bugs.chromium.org/p/chromium/issues/detail?id=1054624#c19)"
-" from [us](https://github.com/w3c/webextensions/issues/402), but their "
-"implementation is still incomplete and buggy."
-msgstr ""
-
-#: ../content/posts/mv3.md:block 6 (unordered list)
-msgid ""
-"The removal of the blocking capabilities of the `webRequest` API excludes "
-"any runtime [algorithmic "
-"flexibility](https://lists.nongnu.org/archive/html/js-"
-"shield/2021-02/msg00009.html) to [analyze and "
-"manipulate](https://bugs.chromium.org/p/chromium/issues/detail?id=896897#c23)"
-" the network traffic."
-msgstr ""
-
-#: ../content/posts/mv3.md:block 6 (unordered list)
-msgid ""
-"The new `declarativeNetRequest` API should replace the `webRequest` API. But"
-" it is triggered by a [limited number of basic URL-matching "
-"rules](https://github.com/w3c/webextensions/issues/394), which are easy to "
-"bypass for malicious actors"
-msgstr ""
-
-#: ../content/posts/mv3.md:block 6 (unordered list)
-msgid ""
-"The forced switch of extensions' main logic from a persistent and stateful "
-"background process (MV2) to an ephemeral and stateless service worker "
-"(which, by MV3's design, can be killed at any time) hampers the ability of "
-"security extensions to promptly counter-react synchronous events such as the"
-" start of a page script execution and dramatically impacts any extension of "
-"medium complexity, now forced to reconstruct its state from slow "
-"asynchronous storage every time its service worker gets woken up by user "
-"interaction or network events."
-msgstr ""
-
-#: ../content/posts/mv3.md:block 7 (paragraph)
-msgid ""
-"These and other technical problems are making the transition extremely "
-"painful to privacy and security-oriented browser extensions, and more in "
-"general those aimed to change the browser's default behavior in restrictive "
-"/ protective directions or just give back some agency to the users rather "
-"than prioritize the will of web authors, advertisers, and trackers."
-msgstr ""
-
-#: ../content/posts/mv3.md:block 8 (paragraph)
-msgid "Further factors make any migration route even harder:"
-msgstr ""
-
-#: ../content/posts/mv3.md:block 9 (ordered list)
-msgid ""
-"*MV2 and MV3 API access is mutually exclusive*, meaning that we cannot pick "
-"\"the best tool for the task\" during the transition. Therefore, web "
-"developers are forced to maintain multiple versions, i.e. MV2-based for the "
-"general public and MV3-based for early adopters/testers willing to bear with"
-" bugs and missing features until MV3 is good enough."
-msgstr ""
-
-#: ../content/posts/mv3.md:block 9 (ordered list)
-msgid ""
-"*MV3 is far from having any finalized shape or roadmap*, despite the "
-"relentless efforts to make it more viable from extensions developers, "
-"including myself, convening with browser vendors in [W3C's Web Extensions "
-"Community Group](https://www.w3.org/groups/cg/webextensions) (WECG)."
-msgstr ""
-
-#: ../content/posts/mv3.md:block 9 (ordered list)
-msgid ""
-"There's still *no stable, feature-complete and reliable MV3 API "
-"implementation* for moderately complex extensions to experiment with."
-msgstr ""
-
-#: ../content/posts/mv3.md:block 9 (ordered list)
-msgid ""
-"Its actual implementations suffer from *fragmentation and countless "
-"incompatibilities*, for the better or the worse, across browser vendors "
-"adopting it, including Mozilla, Microsoft and Apple."
-msgstr ""
-
-#: ../content/posts/mv3.md:block 10 (paragraph)
-msgid ""
-"Notwithstanding the aforementioned critical issues, one year ago, Google "
-"announced a bellicose [timeline to extinguish \"legacy\" MV2 "
-"extensions](https://developer.chrome.com/docs/extensions/mv3/mv2-sunset/), "
-"starting with a \"soft\" deprecation on the 1st of January 2023 but quickly "
-"ramping up to enterprise-only support in June and complete extermination by "
-"the end of the year, except for [backpedalling at the last "
-"moment](https://arstechnica.com/gadgets/2022/12/chrome-delays-plan-to-limit-"
-"ad-blockers-new-timeline-coming-in-march/), putting those dates \"under "
-"review until March\" with the admission that an API still in such a bad "
-"shape prevents too many extensions (even outside the controversial realm of "
-"content blockers) from migrating."
-msgstr ""
-
-#: ../content/posts/mv3.md:block 11 (paragraph)
-msgid ""
-"In our project, we're seeking to navigate the uncertainty of Manifest V3 "
-"transition towards a successful outcome, trying to stay compatible with as "
-"many browsers as possible, preserving as many features as possible, through "
-"different interventions, some sequential, some parallel:"
-msgstr ""
-
-#: ../content/posts/mv3.md:block 12 (ordered list)
-msgid ""
-"actively participating in the ongoing *browser extensions API design work* "
-"of the [Web Extensions Community "
-"Group](https://www.w3.org/groups/cg/webextensions), in order to steer the "
-"MV3 specification in the most favorable direction for security and privacy "
-"use cases;"
-msgstr ""
-
-#: ../content/posts/mv3.md:block 12 (ordered list)
-msgid ""
-"publishing a *MV3-compatible JShelter prototype* as much feature complete "
-"and cross-browser compatible as possible, and developed/distributed/tested "
-"separately from the MV2 version aimed at the general public;"
-msgstr ""
-
-#: ../content/posts/mv3.md:block 12 (ordered list)
-msgid ""
-"simultaneously advocating for, keeping track of and taking advantage of "
-"*useful API changes* (even if browser-specific) to improve the MV3-based "
-"prototype;"
-msgstr ""
-
-#: ../content/posts/mv3.md:block 12 (ordered list)
-msgid ""
-"*sharing the results with other extension developers* through the [NoScript "
-"Commons Library](https://noscript.net/commons-library); the compatibility "
-"layer eases the migration work for other developers."
-msgstr ""
-
-#: ../content/posts/optimizations.md:block 1 (header)
-msgid ""
-"title: Recent improvements in JShelter performance\n"
-"date: 2023-09-21 15:00"
-msgstr ""
-
-#: ../content/posts/optimizations.md:block 2 (paragraph)
-msgid ""
-"You might have noticed that [recent versions](/versions/#015/) improved "
-"JShelter performance. This blog post explains the improvements in more "
-"detail and contains graphs. The improvements are based on the [bachelor "
-"thesis of Martin Zmitko](https://www.vut.cz/en/students/final-"
-"thesis/detail/147218). If you are interested in this topic, you will find "
-"more information in the thesis. We thank Martin for his work and his "
-"proposals."
-msgstr ""
-
-#: ../content/posts/optimizations.md:block 4 (header)
-msgid "1. The code inserted into each page"
-msgstr ""
-
-#: ../content/posts/optimizations.md:block 5 (paragraph)
-msgid ""
-"Archaic versions of JShelter (at that time JavaScript Restrictor) generated "
-"the wrapping code during each page load (in so-called content scripts). "
-"However, we still needed to solve the reliable code injection at that time. "
-"We wanted the lowest amount of work in content script. So, JShelter started "
-"to generate the code in the background and send the generated code to the "
-"content script."
-msgstr ""
-
-#: ../content/posts/optimizations.md:block 6 (paragraph)
-msgid ""
-"Starting from [0.5](/versions/#015/), NSCL solved the reliable code "
-"injection. The preferred and fast solution is to inject the configuration in"
-" the `BeforeNavigate` event handler. However, there is a race condition "
-"between the `BeforeNavigate` event and `document_start` phase of the page "
-"load. If the script detects that the configuration is not available during "
-"the `document_start`, it initiates a synchronous request to retrieve the "
-"configuration before page scripts start running."
-msgstr ""
-
-#: ../content/posts/optimizations.md:block 7 (paragraph)
-msgid ""
-"However, Martin realized that a synchronous request takes a long time. "
-"Moreover, he confirmed [our old "
-"observations](https://pagure.io/JShelter/webextension/issue/46#comment-793783)"
-" that the synchronous request is needed very often. The time needed to "
-"process the configuration increases linearly with the size of the "
-"configuration. JShelter used to inject 572kB of code in the default "
-"configuration. By shifting the code generation process back to content "
-"scripts, we decreased the configuration size to 21.2kB."
-msgstr ""
-
-#: ../content/posts/optimizations.md:block 8 (paragraph)
-msgid ""
-"During the work, we also optimized the code-generating process and "
-"eliminated duplicates in the code as well as Firefox-specific code in "
-"Chromium-based browsers."
-msgstr ""
-
-#: ../content/posts/optimizations.md:block 9 (header)
-msgid "2. Improvements to little-lies"
-msgstr ""
-
-#: ../content/posts/optimizations.md:block 10 (paragraph)
-msgid ""
-"As you probably know, the [anti-fingerprinting code](/farbling/) modifies "
-"the results of some APIs with little lies. However, that approach is "
-"performance-heavy for some APIs. The most critical are APIs that read from "
-"canvas (`readPixels` and `toDataURL`) and `AudioBuffer.getChannelData`. For "
-"example, the original `getChannelData` passes a reference to the underlying "
-"buffer, so the browser does not need to do any computation. But JShelter "
-"needs to copy each item, determine how to apply the lies (ensuring "
-"consistent lies to the same data) and modify selected items."
-msgstr ""
-
-#: ../content/posts/optimizations.md:block 11 (paragraph)
-msgid ""
-"Martin discovered that the JShelter modifications to `readPixels`, "
-"`toDataURL`, and `getChannelData` can benefit from a different iterator. "
-"More importantly, Martin proposed to translate the code to WebAssembly, "
-"which runs much faster."
-msgstr ""
-
-#: ../content/posts/optimizations.md:block 12 (header)
-msgid "3. Improvements to FPD"
-msgstr ""
-
-#: ../content/posts/optimizations.md:block 13 (paragraph)
-msgid ""
-"[Fingerprint detector](/fpd/) collects information on each call of the APIs "
-"that are often misused for fingerprinting. Martin discovered that some "
-"serializations performed during its operations are not really needed."
-msgstr ""
-
-#: ../content/posts/optimizations.md:block 14 (header)
-msgid "4. Other optimizations"
-msgstr ""
-
-#: ../content/posts/optimizations.md:block 15 (paragraph)
-msgid ""
-"Martin also implemented several other performance improvements, some aiming "
-"at NSCL and not only JShelter. For example, NSCL included a JavaScript "
-"library to compute SHA-256, while native `SubtleCrypto` implementation is "
-"faster."
-msgstr ""
-
-#: ../content/posts/optimizations.md:block 16 (header)
-msgid "5. Results"
-msgstr ""
-
-#: ../content/posts/optimizations.md:block 17 (paragraph)
-msgid ""
-"First, let us have a look at Firefox and the improvements in 2D Canvas in "
-"`getImageData()` (note that the y-axis is logarithmic):"
-msgstr ""
-
-#: ../content/posts/optimizations.md:block 18 (paragraph)
-msgid ""
-"![Performance of getImageData in "
-"Firefox]({attach}/images/optimizations/firefox_canvas_recommended.png)"
-msgstr ""
-
-#: ../content/posts/optimizations.md:block 19 (paragraph)
-msgid ""
-"As expected, the optimized implementation is slower than the original "
-"because it needs much more work. Even so, the performance hit is several "
-"magnitudes lower than the hit in 0.12.2."
-msgstr ""
-
-#: ../content/posts/optimizations.md:block 20 (paragraph)
-msgid ""
-"Now, let us have a look the improvements in 3D Canvas in `readPixels()` "
-"(this time, we show the graph with the linear y-axis, the shape of the "
-"points depicting the performance is similar for 2D and 3D canvas):"
-msgstr ""
-
-#: ../content/posts/optimizations.md:block 21 (paragraph)
-msgid ""
-"![Performance of readPixels in "
-"Firefox]({attach}/images/optimizations/firefox_canvas3d_recommended.png)"
-msgstr ""
-
-#: ../content/posts/optimizations.md:block 22 (paragraph)
-msgid ""
-"See that the original implementation quickly leaves the plotted range. Its "
-"performance hit was more significant than the 2D version while starting from"
-" 0.14, the performance hit of 2D and 3D canvases are comparable."
-msgstr ""
-
-#: ../content/posts/optimizations.md:block 23 (paragraph)
-msgid ""
-"Firefox implementation of `getChannelData` has a negligible running time "
-"(almost 0). The following figure shows that the little lies are computed "
-"much quicker (about two orders of magnitude), but the impact is still "
-"significant. Note that the y-axis is again logarithmic."
-msgstr ""
-
-#: ../content/posts/optimizations.md:block 24 (paragraph)
-msgid ""
-"![Performance of getChannelData in "
-"Firefox]({attach}/images/optimizations/firefox_audio_recommended.png)"
-msgstr ""
-
-#: ../content/posts/optimizations.md:block 25 (paragraph)
-msgid ""
-"Martin also developed [performance "
-"tests](https://pagure.io/JShelter/webextension/blob/1c86c45f565a36a6234c210392a89e3e20f32027/f/tests/performance_tests)"
-" based on [Google Lighthouse](https://developer.chrome.com/docs/lighthouse/)"
-" that run in Chrome. We tested on 46 pages from the 100 of "
-"[Tranco](https://tranco-list.eu/) and give the [performance "
-"score](https://developer.chrome.com/docs/lighthouse/performance/performance-"
-"scoring/) below. The performance score approximates how users perceive the "
-"loading speed of the visited page. The 25th percentile of all pages should "
-"receive a score of 50."
-msgstr ""
-
-#: ../content/posts/optimizations.md:block 26 (paragraph)
-msgid ""
-"The average performance score of all tested pages was 66 without JShelter. "
-"When tested with JShelter 0.12.2, the score dropped to 62.5. The average of "
-"all tested pages raised to 64 with JShelter 0.15.1. The performance score "
-"was the same or better in JShelter 0.15.1 compared to 0.12.2 on 33 pages. It"
-" increased on 18 pages."
-msgstr ""
-
-#: ../content/posts/paper2022.md:block 1 (header)
-msgid ""
-"title: Paper about JShelter\n"
-"date: 2022-04-05 00:00\n"
-"Series: JShelter background"
-msgstr ""
-
-#: ../content/posts/paper2022.md:block 2 (paragraph)
-msgid ""
-"We recently submitted a position paper about JShelter for [CNIL Privacy "
-"Research Day 2022](https://www.cnil.fr/en/privacy-research-day-2022) and "
-"posted the paper on [arXive](https://arxiv.org/abs/2204.01392). If you are "
-"interested in the project or if you are already using JShelter, we recommend"
-" reading the paper as it explains the project, its historical decisions, the"
-" thread model, design decision, experiments, and provides more information "
-"that you should know if you want to use JShelter correctly, or, you might "
-"decide that JShelter is not the correct tool for you and you might pick one "
-"of the alternative tools referenced in the paper."
-msgstr ""
-
-#: ../content/posts/paper2022.md:block 3 (paragraph)
-msgid ""
-"The Web is used daily by billions. Even so, users are not protected from "
-"many threats by default. Jshelter builds on previous web privacy and "
-"security research and fights to return the browser to users. The paper "
-"introduces [NSCL](https://noscript.net/commons-library), a library helping "
-"with common webextension development tasks and fixing loopholes misused by "
-"previous research. JShelter focuses on fingerprinting prevention, "
-"limitations of rich web APIs, prevention of attacks connected to timing, and"
-" learning information about the computer, the browser, the user, and "
-"surrounding physical environment and location. We discovered a loophole in "
-"the sensor timestamps that lets any page observe the device boot time if "
-"sensor APIs are enabled in Chromium-based browsers. JShelter provides a "
-"fingerprinting report and other feedback that can be used by future security"
-" research and data protection authorities. Thousands of users around the "
-"world use the webextension every day."
-msgstr ""
-
-#: ../content/posts/paper2022.md:block 4 (paragraph)
-msgid ""
-"Previous research established that browser security, privacy, and "
-"customizability are important topics. The imminent danger of third-party "
-"cookies' removal forces trackers to employ even more privacy-invading "
-"techniques. Real-time bidding leaves users easy targets for various attacks,"
-" including gaining information about other applications running on the local"
-" computer. Moreover, continuous additions of new JavaScript APIs open new "
-"ways for fingerprinting the browsers and gaining additional knowledge about "
-"the browser or user preferences and physical environment. One of the major "
-"concerns is a lack of effective tools that everyday user wants to use. "
-"Current methods to tackle web threats are list-based blockers that might be "
-"evaded with a change of URL, specialised browsers, or research-only projects"
-" that are quickly abandoned."
-msgstr ""
-
-#: ../content/posts/paper2022.md:block 5 (paragraph)
-msgid ""
-"In contrast, JShelter is a webextension that can be installed on major "
-"browsers and consequently does not require the user to change the browser "
-"and routines. We integrate several previous research projects like [Chrome "
-"Zero](https://github.com/IAIK/ChromeZero), [little-lies-based fingerprinting"
-" prevention](https://brave.com/privacy-updates/3-fingerprint-"
-"randomization/), and ideas of limiting APIs brought by [Web API "
-"Manager](https://github.com/pes10k/web-api-manager). JShelter comes with [a "
-"heuristic-based fingerprint detector](/fpdetection/) and prevents webpages "
-"from [misusing the browser as a proxy to access the local network and "
-"computer](/localportscanning/). We needed to solve issues with reliable "
-"environment modifications that stem from webextension API that opens many "
-"loopholes that previous research exploited. In addition to JShelter, we "
-"introduce [NSCL](https://noscript.net/commons-library). Both NoScript "
-"Security Suite and JShelter include NSCL. Moreover, NSCL is available for "
-"other privacy- and security-related webextensions."
-msgstr ""
-
-#: ../content/posts/paper2022.md:block 6 (paragraph)
-msgid ""
-"In cooperation with the Free Software Foundation, we aim for long-term "
-"JShelter development; thus, users' privacy and security should be improved "
-"in the future. We explain fingerprinting vectors introduced by Sensor API in"
-" mobile browsers. Data protection specialists should detect browser "
-"fingerprinting and other information leaks with JShelter. We integrated "
-"[fingerprint report](/cooperation/) and notifications to facilitate the "
-"task. We discussed considerations and issues connected with deployment. The "
-"webextension is under development. Future work will include fixing problems "
-"breaking pages, improved heuristics of FPD, and research fingerprinting on "
-"login pages. We want to revisit and evaluate the little-lies-based anti-"
-"fingerprinting technique; are the little changes enough to stop a determined"
-" fingerprinter that can, for example, approximate colour values of several "
-"pixels or repeat an effect multiple times? JShelter should not be considered"
-" a single bullet-proof solution. We anticipate that everyday users will "
-"install JShelter together with other webextensions like list-based blockers "
-"or JavaScript blockers."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 1 (header)
-msgid ""
-"title: Protection against fingerprinting with Generic Sensor API\n"
-"date: 2022-05-06 15:34\n"
-"Series: Browser fingerprinting"
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 2 (paragraph)
-msgid ""
-"Today devices contain [various "
-"sensors](https://www.researchgate.net/publication/224170986_A_survey_of_mobile_phone_sensing_IEEE_Commun_Mag)"
-" for reading information about the device's position, state, and "
-"environment. Such equipment is typical for mobile devices like cellphones, "
-"tablets, or laptops that often include sensors for obtaining geolocation or "
-"device orientation data. Another example is a smartwatch that could monitor "
-"the heartbeat rate of the wearer, or a car with a tire pressure sensor, etc."
-" While the benefits of having sensors are undisputed, allowing websites to "
-"access their readings represents a considerable danger."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 5 (header)
-msgid "Generic Sensor API"
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 6 (paragraph)
-msgid ""
-"JavaScript's [Generic sensor API](https://www.w3.org/TR/generic-sensor/) "
-"provides a unified way for accessing these sensors and reading data. The "
-"physical (hardware) sensor instances are called **device sensors**, while "
-"**platform sensors** represent interfaces over which the user agent can "
-"interact with the device sensors and read data. JavaScript represents "
-"sensors by a class hierarchy. The base class `Sensor` cannot be used "
-"directly but provides essential properties, event handlers, and methods for "
-"its subclasses. These represent concrete sensors like Accelerometer, "
-"Magnetometer, or Gyroscope."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 7 (header)
-msgid "Browser Support"
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 8 (paragraph)
-msgid ""
-"The API is currently implemented, or partially implemented, in Chrome, Edge,"
-" and Opera browsers. For Android devices, the support exists in Chrome for "
-"Android, Opera for Android, and various Chromium-based browsers like Samsung"
-" Mobile or Kiwi Browser. The concrete support for individual classes depends"
-" on the browser type and version. Some features are considered experimental "
-"and, for now, only work when browser flags like `#enable-experimental-web-"
-"platform-features` or `#enable-generic-sensor-extra-classes` are enabled."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 9 (header)
-msgid "Sensor Types"
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 10 (paragraph)
-msgid ""
-"Some sensors are characterized by their implementation, e.g. a `Gyroscope` "
-"or `Magnetometer`. Those are called **low-level** sensors. Sensors that are "
-"named after their readings, not their implementation, are called **high-"
-"level** sensors. For instance, the `GeolocationSensor` may read data from "
-"the GPS chip, Wifi networks, cellular network triangulation, or their "
-"combination. Using a combination of low-level sensor readings is called "
-"**sensor fusion**. An example is the `AbsoluteOrientaionSensor` that uses "
-"data from the Accelerometer, Gyroscope, and Magnetometer low-level sensors."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 11 (header)
-msgid "Threats"
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 12 (paragraph)
-msgid ""
-"The risk of using Generic Sensor API calls for device fingerprinting is "
-"mentioned within the [W3C Candidate Recommendation Draft, 29 July "
-"2021]((https://www.w3.org/TR/2021/CRD-generic-sensor-20210729/#device-"
-"fingerprinting)). Documented threats include manufacturing imperfections and"
-" differences that are unique to the concrete model of the device and can be "
-"used for fingerprinting. Concrete examples are discussed in the following "
-"sections dedicated to individual sensor classes."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 13 (header)
-msgid "Timestamps"
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 14 (paragraph)
-msgid ""
-"We discovered a loophole in the `Sensor.timestamp` attribute. The value "
-"contains the time when the last `Sensor.onreading` event occurred, in "
-"millisecond precision. We observed that the time is not relative to the time"
-" of page context creation (like `performance.now`) but the last boot time of"
-" the device. Exposing such information is dangerous as it allows to "
-"fingerprint the user easily. Not many devices boot at the same time. The "
-"longer a device is running, the less likely that another device booted at "
-"the same time, and both are still running."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 15 (paragraph)
-msgid ""
-"The behaviour was with the Magnetometer sensor on the following devices:"
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 16 (unordered list)
-msgid ""
-"Samsung Galaxy S21 Ultra; Android 11, kernel 5.4.6-215566388-abG99BXXU3AUE1,"
-" Build/RP1A.200720.012.G998BXXU3AUE1, Chrome 94.0.4606.71 and Kiwi "
-"(Chromium) 94.0.4606.56"
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 16 (unordered list)
-msgid ""
-"Xiaomi Redmi Note 5; Android 9, kernel 4.4.156-perf+, Build/9 "
-"PKQ1.180901.001, Chrome 94.0.4606.71"
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 17 (paragraph)
-msgid ""
-"Our wrapper thus protects the device by changing the time origin to the page"
-" context creation time, the timestamp should still uniquely identify the "
-"reading, i.e. two readings by the same page have a different timestamp."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 18 (header)
-msgid "Global Orientation Settings"
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 19 (paragraph)
-msgid ""
-"Many sensor classes need access to the device's orientation to calculate its"
-" values accordingly. Readings from different sensors are thus not "
-"independent of each other, and relations between the sensor classes exist. "
-"We wanted even the faked readings to look real and believable, and therefore"
-" JShelter uses a model of the orientation that is shared between the "
-"individual wrappers."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 20 (paragraph)
-msgid ""
-"Let us consider a cell phone as a use case device. For all devices we "
-"examined:"
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 21 (unordered list)
-msgid "The `x` axis is oriented from the user's left to the right."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 21 (unordered list)
-msgid "The `y` axis from the bottom side of the display towards the top side."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 21 (unordered list)
-msgid ""
-"The `z` axis is perpendicular to the display; it leads from the phone's "
-"display towards the user's face."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 22 (paragraph)
-msgid ""
-"Similar to [Aircaft principal "
-"axes](https://www.grc.nasa.gov/www/k-12/airplane/rotations.html), the "
-"rotation of the device is defined by three values: `yaw`, `pitch`, and "
-"`roll`:"
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 23 (unordered list)
-msgid ""
-"`Yaw` defines rotation around the `z` axis. Assume a phone lying display up "
-"on a flat surface - a table, for instance. If you rotate the phone without "
-"taking any part up from the surface, only the yaw changes."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 23 (unordered list)
-msgid ""
-"`Pitch` defines rotation around the `x` axis. Assume you want to have better"
-" visibility of the display. You may put something under the top (camera) "
-"part of the phone to lift it up a bit. This is where the pitch changes. For "
-"the phone, the surface is not horizontal anymore."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 23 (unordered list)
-msgid ""
-"`Roll` defines rotation around the `y` axis. This is done by rotating the "
-"phone to the left and right. Assume you are holding the phone in your hand, "
-"looking at the display. If you decide to look at the buttons on the side "
-"instead, you rotate the phone, which applies the roll."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 24 (paragraph)
-msgid ""
-"As we observed, the yaw, pitch, and roll define the rotation of the phone on"
-" the Earth reference coordinate system:"
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 25 (unordered list)
-msgid "The `x` axis is oriented towards the **East**"
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 25 (unordered list)
-msgid "The `y` axis is oriented towards the (Earth's magnetic) **North**"
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 25 (unordered list)
-msgid "The `-z` axis is oriented toward the **centre of the Earth**"
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 26 (paragraph)
-msgid ""
-"In our solution, the three values (`yaw`, `pitch`, and `roll`) are "
-"pseudorandomly drawn using the "
-"[Mulberry32](https://gist.github.com/tommyettinger/46a874533244883189143505d203312c)"
-" PRNG that is seeded with a value generated from the `domainHash` which "
-"ensures deterministic behaviour for the given website, e.g. producing same "
-"values on different tabs."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 27 (paragraph)
-msgid ""
-"Future improvements could also introduce movements where JShelter would "
-"change the orientation over time."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 28 (paragraph)
-msgid ""
-"A rotation matrix is calculated and stored within the global `orient` "
-"variable from the values obtained. All our wrappers that need access to the "
-"device's orientation load it from this variable."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 29 (header)
-msgid "AmbientLightSensor"
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 30 (paragraph)
-msgid ""
-"An ambient light sensor is a photodetector that senses the amount of ambient"
-" light present. The motivation for integrating electronic devices is mostly "
-"to dim the screen accordingly and protect users' eyes. In the Generic Sensor"
-" API, the sensor is implemented using the `AmbientLightSensor` class "
-"provides readings of the illuminance of the device's environment. The unit "
-"of the illuminance values is `lux`."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 31 (header)
-msgid "Fingerprinting with AmbientLightSensor"
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 32 (paragraph)
-msgid ""
-"While the light sensors in devices may protect users' eyes, they do not "
-"protect their privacy. As the illuminance value describes the light "
-"conditions of the nearby physical surrounding of the device, an observer can"
-" use the illuminance together with other sensors' readings to create a "
-"unique fingerprint. Using readings from the `AmbientLightSensor`, it is "
-"possible to [scan the nearby "
-"environment](https://blog.lukaszolejnik.com/additional-security-and-privacy-"
-"risks-of-light-sensors/). For instance, [behavioral "
-"analysis](https://blog.lukaszolejnik.com/privacy-of-ambient-light-sensors/) "
-"can reveal information about the time of day that the user usually works, "
-"preferred lighting conditions, frequency of movement around different "
-"places, etc. By applying the [inverse square law](http://hyperphysics.phy-"
-"astr.gsu.edu/hbase/Forces/isq.html), one can also compute the distance "
-"between the device and another light-emitting object: `d = sqrt(L / 4 * π * "
-"B)` where `L` is luminosity that is roughly constant for a light source, and"
-" `B` is brightness obtained from the sensor readings."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 33 (paragraph)
-msgid ""
-"It is also possible to detect the position of the user's fingers by "
-"analyzing the shadows the cast. An example that presents a serious danger is"
-" [PIN "
-"Skimming](https://www.researchgate.net/publication/262380810_PIN_Skimming_Exploiting_the_Ambient-"
-"Light_Sensor_in_Mobile_Devices). In this case, a malicious website or "
-"application exploits the sensor readings to detect PINs for applications "
-"that make bank transactions, etc. Spreitzer et al. Using a linear "
-"discriminant analysis with a training set of 15 PINs, each repeated eight "
-"times, it was possible to classify more than 90 % of device PINs correctly. "
-"The chance of correctly guessing the right PIN from the set of 15 is only "
-"6.7 %. If the user watches TV and a light sensor-equipped smartphone or "
-"smartwatch is nearby, it can [identify concrete TV channels and on-demand "
-"videos](https://www.sciencedirect.com/science/article/pii/S1574119216302085)."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 34 (paragraph)
-msgid ""
-"Multiple devices allow conducting [cross-device "
-"tracking](https://blog.lukaszolejnik.com/privacy-of-ambient-light-sensors/)."
-" For instance, when someone uses a phone and a tablet in the same room, a "
-"website with access to their light sensors can compare the values to "
-"distinguish whether the same person uses two separate devices. The sensor "
-"can also be used for [cross-device "
-"communication](https://blog.lukaszolejnik.com/privacy-of-ambient-light-"
-"sensors/) where one device emits light by displaying content on its screen "
-"and the other reads the message through the sensor-measured illuminance "
-"values."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 35 (header)
-msgid "Wrapping the AmbientLightSensor readings"
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 36 (paragraph)
-msgid ""
-"To eliminate possible exploitation of sensor readings, we decided to "
-"generate fake readings instead of modifying existing ones. On examined "
-"stationary devices inside an office, the illuminance measured was between "
-"500 and 900, depending on the concrete position's light conditions. All "
-"measured values were rounded to the nearest 50 illuminance value. The "
-"wrapper simulates the same behaviour under non-changing light conditions. In"
-" the beginning, a pseudorandom illuminance value is drawn using PRNG seeded "
-"with the domain hash - which should guarantee to produce the same values on "
-"multiple browser tabs on the same domain. As we simulate a stationary device"
-" under constant light conditions, this value remains the same for all "
-"readings. The faked value is returned using a wrapped `illuminance` getter "
-"of the `AmbientLightSensor.prototype`."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 37 (header)
-msgid "Accelerometer"
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 38 (paragraph)
-msgid "Accelerometers provide information about the device's acceleration"
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 39 (unordered list)
-msgid ""
-"i.e., the rate of change of its velocity. The Generic Sensor API provides "
-"access to the readings using three classes: the `Accelerometer` sensor, the "
-"`LinearAccelerationSensor`, and the `GravitySensor`. All use data from the "
-"underlying `accelerometer` device sensor. The difference between them is "
-"whether and how the gravity acceleration is applied. The `Accelerometer` "
-"sensor provides information about the total acceleration that is applied to "
-"the device. The remaining two isolate the sources. The "
-"`LinearAccelerationSensor` ignores the influence of gravity. The "
-"`GravitySensor` returns just the gravity acceleration."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 40 (header)
-msgid "Fingerprinting with Accelerometer"
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 41 (paragraph)
-msgid ""
-"Readings from the accelerometer sensor classes represent a potential risk "
-"and need to be protected. A unique fingerprint [can be obtained by "
-"describing the device's "
-"vibrations](https://link.springer.com/chapter/10.1007/978-3-319-30806-7_7). "
-"Using [trajectory "
-"inference](https://www.researchgate.net/publication/220990763_ACComplice_Location_inference_using_accelerometers_on_smartphones)"
-" and matching the model to map data, one may use the readings from the "
-"Accelerometer to determine the device's position"
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 42 (paragraph)
-msgid ""
-"From the accelerometer readings, [it is possible to "
-"infer](https://www.mysk.blog/2021/10/24/accelerometer-ios/) whether the "
-"device user is lying, sitting, walking, or cycling. For walking and running,"
-" the data allow calculating steps. Accelerometer readings can also be used "
-"to determine [human walking "
-"patterns](https://www.researchgate.net/publication/322835708_Classifying_Human_Walking_Patterns_using_Accelerometer_Data_from_Smartphone)."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 43 (paragraph)
-msgid ""
-"Similar to `Gyroscope`, the `Accelerometer` sensor is also influenced by "
-"vibrations from speech. Using the [Spearphone "
-"attack](https://arxiv.org/abs/1907.05972), it is possible to perform gender "
-"classification (with accuracy over 90%) and speaker identification (with "
-"accuracy over 80%). Speech recognition and classification can also be done "
-"from the reading of this sensor."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 44 (header)
-msgid "Wrapping the Accelerometer readings"
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 45 (paragraph)
-msgid ""
-"Our wrapper replaces the acceleration getters of these sensors. The goal is "
-"to simulate a stationary device, possibly rotated. A rotation matrix "
-"represents the orientation of the device. Its values are drawn "
-"pseudorandomly from the domain hash, and are shared between all sensor "
-"wrappers to simulate the same behaviour."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 46 (paragraph)
-msgid ""
-"The `GravitySensor` provides readings of gravity acceleration applied to the"
-" device. This is represented by a vector made of `x`, `y`, `z` portions. To "
-"get this faked gravity vector for the device, the reference vector `[0, 0, "
-"9.8]` is multiplied with the rotation matrix. Wrappers for the "
-"GravitySensor's getters return the individual portions of the fake gravity "
-"vector."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 47 (paragraph)
-msgid ""
-"Next, the `LinearAccelerationSensor` should return acceleration values "
-"without the contribution of gravity. For a stationary device, it should be "
-"all zeroes. Yet, vibrations may change values a little bit, e.g., spin "
-"around `-0.1` to `+0.1`, as seen on the examined devices. Such vibrations "
-"usually do not happen with every reading but only in intervals of seconds. "
-"And thus, JShelter pseudorandomly changes these values after a few seconds."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 48 (paragraph)
-msgid ""
-"Finally, the `Accelerometer` sensor combines the previous two. Our wrappers "
-"thus return the values from the LinearAccelerationSensor with the fake "
-"gravity vector portions added."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 49 (paragraph)
-msgid ""
-"For all three classes, we return the faked orientation values using the "
-"wrapped `x`, `y`, `z` component getters of the `Accelerometer.prototype`. "
-"Based on the constructor name the wrapper detects which concrete class is "
-"used and thus what behaviour to simulate."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 50 (header)
-msgid "Gyroscope"
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 51 (paragraph)
-msgid ""
-"The Gyroscope sensor provides readings of the angular velocity of the device"
-" along the `x`, `y`, `z` axes. The class uses the underlying `gyroscope` "
-"device sensor. Physically, classic gyroscopes used a spinning wheel or a "
-"disc with free axes of rotation. In modern electronic devices, gyroscopes "
-"use piezoelectric or silicon transducers and [various mechanical "
-"structures](https://www5.epsondevice.com/en/information/technical_info/gyro/)."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 52 (header)
-msgid "Fingerprinting with Gyroscope"
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 53 (paragraph)
-msgid ""
-"Gyroscope readings can be used for [speech "
-"recognition](https://crypto.stanford.edu/gyrophone/) and various "
-"fingerprinting operations. For stationary devices, the resonance of the "
-"unique internal or external sounds affect angular velocities affect the "
-"Gyroscope, and [allow to create a "
-"fingerprint](https://www.researchgate.net/publication/356678825_Mobile_Device_Fingerprint_Identification_Using_Gyroscope_Resonance)."
-" For moving devices, one of the options is using the Gyroscope to analyze "
-"[human walking "
-"patterns](https://www.ncbi.nlm.nih.gov/pmc/articles/PMC7071017/)."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 54 (header)
-msgid "Wrapping the Gyroscope Readings"
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 55 (paragraph)
-msgid ""
-"All velocities should be zero in an ideal state for a stationary device. As "
-"we observed on the examined devices, various device sensor imperfections and"
-" tiny vibrations cause the values oscillate between `-0.002` and `0.002` on "
-"the examined devices. Our wrapper thus simulates the same behaviour."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 56 (paragraph)
-msgid ""
-"The changes are applied in pseudorandom intervals between `500 ms` to `2 s`."
-" These boundaries were chosen with respect to our observations from the "
-"examined devices' real sensors. The actual values of change are also "
-"calculated pseudorandomly from the domain hash to ensure deterministic and "
-"consistent behaviour within a given domain. The faked values are then "
-"returned using wrapped `x`, `y`, `z` getters of the `Gyroscope.prototype`."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 57 (header)
-msgid "Magnetometer"
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 58 (paragraph)
-msgid ""
-"A magnetometer measures the strength and direction of the magnetic field "
-"around the device. The interface offers sensor readings using three "
-"properties: `x`, `y`, and `z`. Each returns a number that describes the "
-"magnetic field around the particular axis. The numbers have a double "
-"precision and can be positive or negative, depending on the orientation of "
-"the field. The total strength of the magnetic field (`M`) can be calculated "
-"as `M = sqrt(x^2 + z^2 + y^2)`. The unit is in microtesla (&micro;T)."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 59 (header)
-msgid "Fingerprinting with Magnetometer"
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 60 (paragraph)
-msgid ""
-"The Earth's magnetic field "
-"[ranges](https://doi.org/10.1111%2Fj.1365-246X.2010.04804.x) between "
-"approximately 25 and 65 &micro;T. Concrete values depend on location, "
-"altitude, weather, and other factors. Yet, there are characteristics of the "
-"field for different places on Earth. The common model used for their "
-"description is the [International Geomagnetic Reference Field "
-"(IGRF)](https://www.ngdc.noaa.gov/IAGA/vmod/igrf.html). While the magnetic "
-"field changes over time, the changes are slow: There is a decrease of 5% "
-"every 100 years. Therefore, for the given latitude, longitude, and altitude,"
-" the average strength of the field should be stable. Can one determine the "
-"device's location based on the data from the Magnetometer sensor? Not "
-"exactly. The measured values are influenced by the interference with other "
-"electrical devices, isolation (buildings, vehicles), the weather, and other "
-"factors. Moreover, the field is not unique - similar fields can be measured "
-"in different places on Earth."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 61 (paragraph)
-msgid ""
-"What, however, can be determined is the orientation of the device. In the "
-"case of a stationary (non-moving) device, the measured values can serve as a"
-" fingerprint. As we experimentally examined, it is also possible to "
-"distinguish whether the device is moving or when its environment changes. "
-"When a person with a cellphone enters a car or an elevator, the metal "
-"barrier serves as isolation, and the strength of the field gets lower "
-"rapidly (e.g., from 60&micro;T outside to 27&micro;T inside). A cellphone "
-"lying on a case of a running computer can produce values over 100&micro;T, "
-"especially if it is near the power supply unit. Either way, for a single "
-"device at the same location in the same environment, the average strength of"
-" the magnetic field should be stable."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 62 (paragraph)
-msgid ""
-"Magnetometer values can be used for fingerprinting. First, Magnetometer "
-"readings can tell the attacker whether the device is moving or not. In the "
-"case of a stationary device, we can make a fingerprint from the device "
-"orientation. Another fingerprintable value is the average total strength of "
-"the field, which should remain stable if the device is at the same position "
-"and in the same environment."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 63 (paragraph)
-msgid ""
-"Yet, even moving devices can be exploited. One can misuse the sensor "
-"readings to make a [calibration fingerprint attack](https://www.ieee-"
-"security.org/TC/SP2019/papers/405.pdf) that infers per device factory "
-"calibration data. The researchers showed the attack to be usable and "
-"efficient on both Android and iOS devices. A device can be identified using "
-"Magnetometer reading [through the analysis of the "
-"bias](https://seclab.bu.edu/papers/magnetometer-wisec2019.pdf). Moreover, "
-"the device itself also produces electromagnetic emissions and can thus be "
-"identified using the [physical proximity "
-"attack](https://seclab.bu.edu/papers/magnetometer-wisec2019.pdf) is also "
-"possible to use an external device. As the underlying device sensor is also "
-"disturbed by the device's CPU activity, Magnetometer measurements can also "
-"be [used to identify running applications or web "
-"pages](https://arxiv.org/pdf/1906.11117.pdf)."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 64 (header)
-msgid "Wrapping of Magnetometer readings"
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 65 (paragraph)
-msgid ""
-"JShelter wraps the `x`, `y`, `z` getters of the `Magnetometer.prototype` "
-"object to protect the device. Instead of using the original data, JShelter "
-"returns artificially generated values that look like actual sensor readings."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 66 (paragraph)
-msgid ""
-"At every moment, our wrapper stores information about the previous reading. "
-"Each rewrapped getter first checks the `timestamp` value of the sensor "
-"object. If there is no difference of the prior reading's timestamp, the "
-"wrapper returns the last measured value. Otherwise, it provides a new fake "
-"reading."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 67 (paragraph)
-msgid ""
-"We designed our fake field generator to fulfil the following properties:"
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 68 (unordered list)
-msgid ""
-"The randomness of the generator should be high enough to prevent attackers "
-"from deducing the sensor values."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 68 (unordered list)
-msgid ""
-"Multiple scripts from the same website that access readings with the same "
-"timestamp must get the same results. And thus:"
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 68 (unordered list)
-msgid ""
-"The readings are deterministic - e.g., for a given website and time, we must"
-" be able to say what values to return."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 69 (paragraph)
-msgid ""
-"For every \"random\" toss-up, we use the "
-"[Mulberry32](https://gist.github.com/tommyettinger/46a874533244883189143505d203312c)"
-" PRNG that is seeded with a value generated from the `domainHash`, which "
-"ensures deterministic behaviour for the given website. First, we choose the "
-"desired total strength `M` of the magnetic field at our simulated location. "
-"This is a pseudorandom number from `25` to `60` &micro;T, like on the Earth."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 70 (paragraph)
-msgid ""
-"First, we need to set the initial orientation of the axes. Our wrappers "
-"support two methods:"
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 71 (unordered list)
-msgid ""
-"The original implementation where the orientation of axes is drawn "
-"pseudorandomly."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 71 (unordered list)
-msgid ""
-"An improved version where we use the faked device rotation shared by other "
-"wrappers. In this case, we start with the reference magnetic field vector "
-"that is oriented towards the Earth's magnetic North and towards the centre "
-"of the Earth. The vector is then multiplied with the shared faked rotation "
-"matrix. The elements of the resulting vector then represents the axes "
-"orientation."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 72 (paragraph)
-msgid ""
-"For both methods, the orientation is defined by a number from -1 to 1 for "
-"each axis: JShelter simulates a stationary device with a pseudorandomly "
-"drawn orientation in the current implementation. Therefore, we choose the "
-"orientation of the device by generating a number from `-1` to `1` for each "
-"axis. Those values we call `baseX`, `baseY`, and `baseZ`. By modifying the "
-"above-shown formula, we calculate the `multiplier` that needs to be applied "
-"to the base values to get the desired field. The calculation is done as "
-"follows: `mult = (M * sqrt(baseX^2 + baseY^2 + baseZ^2) / (baseX^2 + baseY^2"
-" + baseZ^2))` For axis `x`, the value should fluctuate around `baseX * "
-"mult`, etc."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 73 (paragraph)
-msgid ""
-"How much the field changes over time is specified by the **fluctuation "
-"factor** from `(0;1]` that can also be configured. For instance, `0.2` means"
-" that the magnetic field on the axis may change from the base value by `20%`"
-" in both positive and negative ways."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 74 (paragraph)
-msgid ""
-"The fluctuation is simulated by using a series of **sine** functions for "
-"each axis. Each sine has a unique amplitude, phase shift, and period. The "
-"number of sines per axis is chosen pseudorandomly based on the wrapper "
-"settings. For initial experiments, we used around `20` to `30` sines for "
-"each axis. The optimal configuration is in question. More sines give less "
-"predictable results but also increase the computing complexity that could "
-"have a negative impact on the browser's performance."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 75 (paragraph)
-msgid ""
-"For the given timestamp `t`, we make the sum of all sine values at the point"
-" `x=t`. The result is then shifted over the y-axis by adding `base[X|Y|Z] * "
-"multiplier` to the sum. The initial configuration of the fake field "
-"generator was chosen intuitively to resemble the results of the real "
-"measurements. Currently, the generator uses **at least one** sine with the "
-"period around `100` &micro;s (with `10%` tolerance), which seems to be the "
-"minimum sampling rate obtainable using the API on mobile devices. Then, at "
-"least one sine around `1 s`, around `10 s`, `1 minute` and `1 hour`. When "
-"more than `5` sines are used, the cycle repeats using `modulo 5` and creates"
-" a new sine with the period around `100` &micro;s, but this time the "
-"tolerance is `20%`. The same follows for seconds, tens of seconds, minutes, "
-"and hours. The tolerance grows every five sines. For 11+ sines, the "
-"tolerance is `30%` up to the maximum (currently `50%`). The amplitude of "
-"each sine is chosen pseudorandomly based on the **fluctuation factor** "
-"described above. The phase shift of each sine is also a pseudorandom number "
-"from [0;2&#960;)."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 76 (paragraph)
-msgid ""
-"Based on the results, this heuristic returns believable values that look "
-"like actual sensor readings. Nevertheless, the generator uses a series of "
-"constants whose optimal values should be a subject of future research and "
-"improvements. Perhaps, a correlation analysis with real measurements could "
-"help in the future. Figures below show the values of `x`, `y`, `z`, and the "
-"total strength `M` measured within 10 minutes on a: 1) Stationary device, 2)"
-" Moving device, and 3) Device with the fake wrapped magnetometer."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 77 (paragraph)
-msgid ""
-"![Stationary device]({attach}/images/device_stationary.svg) ![Moving "
-"device]({attach}/images/device_moving.svg) ![Device with fake "
-"magnetometer]({attach}/images/device_artificial.svg)"
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 78 (header)
-msgid "Device Orientation Sensors"
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 79 (paragraph)
-msgid ""
-"This group includes two sensor classes: `AbsoluteOrientationSensor` and "
-"`RelativeOrientationSensor`. Both describe the physical orientation of the "
-"device, and both require access to the `accelerometer` and `gyroscope` "
-"device sensors. The difference between the two classes is what they consider"
-" as a reference coordinate system"
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 80 (unordered list)
-msgid ""
-"i.e., what is the real orientation of a non-rotated device. For this "
-"purpose, the `AbsoluteOrientationSensor` uses the Earth's reference "
-"coordinate system. And thus, it also requires access to the `magnetometer` "
-"device sensor, simply to know where the North is. The "
-"`RelativeOrientationSensor` does not require this information as the "
-"cardinal directions are not used. Yet, the sensor still needs to some "
-"coordinate system to calculate with - i.e., physical orientation of the "
-"device that is considered as reference. For this purpose, it may use the "
-"orientation from the moment the sensor instance is created. When the sensor "
-"is initialized, it creates a new coordinate system, and the device can be "
-"considered non-rotated. Any rotations from this point are done in relation "
-"to this newly created coordinate system. Readings are represented by the "
-"`OrientationSensor.quaternion` made of `x`, `y`, `z`, and `w` components "
-"that describe the orientation of the device."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 81 (header)
-msgid "Fingerprinting with Device Orientation Sensors"
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 82 (paragraph)
-msgid ""
-"Device orientation sensors can be easily used for fingerprinting. As it "
-"highly unlikely that two devices visiting the same site will be oriented "
-"exactly the same, the orientation itself can serve as a fingerprint."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 83 (paragraph)
-msgid ""
-"As the device orientation sensor use data from both the `accelerometer` and "
-"the `gyroscope` device sensors, determining the location using [trajectory "
-"inference](https://www.researchgate.net/publication/220990763_ACComplice_Location_inference_using_accelerometers_on_smartphones)"
-" or determining [human walking "
-"patterns](https://www.researchgate.net/publication/322835708_Classifying_Human_Walking_Patterns_using_Accelerometer_Data_from_Smartphone)."
-" could be even easier than with bare `Accelerometer` class."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 84 (header)
-msgid "Wrapping of Device Orientation Readings"
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 85 (paragraph)
-msgid ""
-"The `AbsoluteOrientationSensor` returns a quaternion describing the physical"
-" orientation of the device in relation to the Earth's reference coordinate "
-"system. As discussed above, the faked orientation of the device is drawn "
-"pseudorandomly using domain hash as a seed and sored inside a global "
-"variable called `orient` that is accessible to all wrappers. With each "
-"reading, it loads the \"orient\" 's contents, converts the rotation matrix "
-"to a quaternion that is returned by the wrapped getter. This design makes "
-"the outputs realistic and in accordance with other sensors' reading. The "
-"implemenation also supports possible changes of orientation."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 86 (paragraph)
-msgid ""
-"The `RelativeOrientationSensor` also describes the orientation, but without "
-"regard to the Earth's reference coordinate system. We suppose the coordinate"
-" system is chosen at the beginning of the sensor instance creation. As we "
-"observed, no matter how the device is oriented, there is always a slight "
-"difference from the AbsoluteOrientationSensor's in at least one axis. When "
-"the device moves, both sensors' readings change. But their difference should"
-" always be constant. And thus, we pseudorandomly generate rotation "
-"deviations from the Earth's reference coordinate system. The deviations are "
-"between `0` and `π/2`. For each reading, we take the values from the fake "
-"AbsoluteOrientationSensor and modify them by the constant deviation."
-msgstr ""
-
-#: ../content/posts/sensorapi.md:block 87 (paragraph)
-msgid ""
-"For both sensor classes, we return the faked orientation values using the "
-"wrapped `x`, `y`, `z`, and `w` quaternion component getters of the "
-"`OrientationSensor.prototype`. Based on the constructor name the wrapper "
-"detects whether it should simulate the absolute or relative orientation "
-"sensor's behaviour."
-msgstr ""
-
-#: ../content/posts/support.md:block 1 (header)
-msgid ""
-"title: We received support from NGI0 PET Fund\n"
-"date: 2021-03-30 09:00\n"
-"Series: JShelter background"
-msgstr ""
-
-#: ../content/posts/support.md:block 2 (paragraph)
-msgid ""
-"We are very happy to announce that the <a "
-"href=\"https://nlnet.nl/project/JSRestrictor/\">JavaScript Restrictor "
-"received support from NGI0 PET Fund</a>, a fund established by NLnet with "
-"financial support from the European Commission's Next Generation Internet "
-"programme, under the aegis of DG Communications Networks, Content and "
-"Technology under grant agreement No 825310."
-msgstr ""
-
-#: ../content/posts/support.md:block 3 (paragraph)
-msgid ""
-"We are very excited to improve the extension further. We will focus on the "
-"following main goals:"
-msgstr ""
-
-#: ../content/posts/support.md:block 4 (header)
-msgid "1. Investigate fingerprinting scripts and prepare wrappers"
-msgstr ""
-
-#: ../content/posts/support.md:block 5 (paragraph)
-msgid ""
-"Review the previously identified APIs suitable for fingerprinting. Select "
-"APIs suitable for JShelter and add wrappers for these APIs. This work has "
-"already started, see issue #66. Additionally, we want to focus on "
-"identification of methods used for fingeprinting such as those identified by"
-" Iqbal et al., see https://uiowa-irl.github.io/FP-Inspector/"
-msgstr ""
-
-#: ../content/posts/support.md:block 6 (header)
-msgid "2. Prevent unique identification of a device"
-msgstr ""
-
-#: ../content/posts/support.md:block 7 (paragraph)
-msgid ""
-"It is hard, if not impossible, to both prevent fingerprinting and still "
-"provide customized environment for the user. Hence, we want to identify "
-"fingerprinting attempts by counting the number of different APIs employed by"
-" a page, especially APIs that are not frequently used for benign purposes. "
-"When a fingerprinting attempt is identified, we want to (1) inform the user,"
-" (2) prevent uploading of the fingerprint to the server, (3) prevent storing"
-" the fingerprint for later usage."
-msgstr ""
-
-#: ../content/posts/support.md:block 8 (header)
-msgid "3. Code ported from Chrome Zero"
-msgstr ""
-
-#: ../content/posts/support.md:block 9 (paragraph)
-msgid ""
-"In version 0.3, we integrated features of Chrome Zero 7 as it is no longer "
-"maintained. By integrating the functionality to JShelter, we want to keep "
-"the counter-meassures available in a maintained extension. However, we do "
-"not have sufficient tests for the functionality."
-msgstr ""
-
-#: ../content/posts/support.md:block 10 (header)
-msgid "4. Evaluation and porting of code from Brave"
-msgstr ""
-
-#: ../content/posts/support.md:block 11 (paragraph)
-msgid ""
-"Brave browser currently implements anti-fingerprinting techniques that aim "
-"at providing little lies about the browser environment. We want to evaluate "
-"the messures and select techniques that are suitable for JShelter."
-msgstr ""
-
-#: ../content/posts/support.md:block 12 (header)
-msgid "5. Fixing known bugs"
-msgstr ""
-
-#: ../content/posts/support.md:block 13 (paragraph)
-msgid ""
-"We want to focus on the proposed changes and found bugs that are reported in"
-" the GitHub bug tracker."
-msgstr ""
-
-#: ../content/posts/support.md:block 14 (unordered list)
-msgid ""
-"We already closed issues #53, #62, and #72 as a part of this project. The "
-"fixes are already available as a part of the 0.4 subversions."
-msgstr ""
-
-#: ../content/posts/support.md:block 14 (unordered list)
-msgid ""
-"We want to also deal with issues #56 and #71 that are crucial for the "
-"success of the extension."
-msgstr ""
-
-#: ../content/posts/support.md:block 14 (unordered list)
-msgid ""
-"We will focus on other identified bugs in the wrappers or developped "
-"techniques."
-msgstr ""
-
-#: ../content/posts/support.md:block 15 (header)
-msgid "6. Cooperation with the Privacy Shield project"
-msgstr ""
-
-#: ../content/posts/support.md:block 16 (paragraph)
-msgid ""
-"We are also excited to announce that we found other partners that are "
-"willing to work on our code base through the NGI0 PET Fund, <a "
-"href=\"https://nlnet.nl/project/JavascriptShield/\">Privacy Shield project "
-"run by Free Software Foundation</a>. Expect inclusion of code that will help"
-" to defend your freedoms and provide anti-malware protections. This "
-"cooperation should also improve the GUI of the extension and create "
-"explenatory web pages explaining the functionality and its risks. It is "
-"possible that the project will be rebranded as a result of the cooperation."
-msgstr ""
diff --git a/website/i18n/en/wrappers.po b/website/i18n/en/wrappers.po
deleted file mode 100644
index 2bebd58..0000000
--- a/website/i18n/en/wrappers.po
+++ /dev/null
@@ -1,1486 +0,0 @@
-#
-msgid ""
-msgstr "Content-Type: text/plain; charset=utf-8\n"
-
-#: ../content/wrappers/ajax.md:block 1 (paragraph)
-msgid "Title: Ajax Filename: ../common/wrappingS-AJAX.js"
-msgstr ""
-
-#: ../content/wrappers/ajax.md:block 2 (paragraph)
-msgid ""
-"XHR may be misused to exfiltrate data from the browser to the server. We "
-"provide a wrapper that either blocks all XHR requests or lets the user "
-"decide."
-msgstr ""
-
-#: ../content/wrappers/ajax.md:block 3 (paragraph)
-msgid "**Known bug**: There are two flaws in the current implementation:"
-msgstr ""
-
-#: ../content/wrappers/ajax.md:block 4 (unordered list)
-msgid ""
-"There are many ways (see e.g. https://github.com/cure53/HTTPLeaks) to "
-"replace XHR and consequently evade the wrapper. This can be mitigating by "
-"monitoring the requests using Web Request API."
-msgstr ""
-
-#: ../content/wrappers/ajax.md:block 4 (unordered list)
-msgid ""
-"The confirm method puts a lot of responsibility on the user who needs to "
-"have a good knowledge about the requests on each visited page."
-msgstr ""
-
-#: ../content/wrappers/ajax.md:block 5 (paragraph)
-msgid ""
-"**Note**: We expect to remove the wrapper once we release JShelter with "
-"Fingerprint Detector (FPD). FPD should solve both issues above."
-msgstr ""
-
-#: ../content/wrappers/battery-cr.md:block 1 (paragraph)
-msgid "Title: Battery level Filename: ../common/wrappingS-BATTERY-CR.js"
-msgstr ""
-
-#: ../content/wrappers/battery-cr.md:block 2 (paragraph)
-msgid ""
-"The `navigator.getBattery()` reports the state of the battery and can be "
-"misused to fingerprint users for a short term. The API was removed from "
-"Firefox, but is still supported in browsers derived from Chromium. The "
-"wrapper mimics Firefox behaviour."
-msgstr ""
-
-#: ../content/wrappers/battery-cr.md:block 3 (paragraph)
-msgid "\\see <https://lukaszolejnik.com/battery>"
-msgstr ""
-
-#: ../content/wrappers/battery-cr.md:block 4 (paragraph)
-msgid ""
-"**Known bug**: Because we mimic Firefox behaviour, a Chromium derived "
-"browser becomes more easily fingerprintable. This can be fixed by properly "
-"wrapping `BatteryManager.prototype` getters and setters."
-msgstr ""
-
-#: ../content/wrappers/be.md:block 1 (paragraph)
-msgid "Title: Beacon API Filename: ../common/wrappingS-BE.js"
-msgstr ""
-
-#: ../content/wrappers/be.md:block 2 (paragraph)
-msgid ""
-"The `navigator.sendBeacon()` method asynchronously sends a small amount of "
-"data over HTTP to a web server. It is intended to be used for sending "
-"analytics data to a web server. For more details see the MDN docs on the "
-"[Beacon API](https://developer.mozilla.org/en-US/docs/Web/API/Beacon_API) "
-"and [sendBeacon](https://developer.mozilla.org/en-"
-"US/docs/Web/API/Navigator/sendBeacon)."
-msgstr ""
-
-#: ../content/wrappers/be.md:block 3 (paragraph)
-msgid ""
-"`navigator.sendBeacon` is the only method currently defined for the Beacon "
-"API."
-msgstr ""
-
-#: ../content/wrappers/coop-scheduling.md:block 1 (paragraph)
-msgid ""
-"Title: Cooperative Scheduling Filename: ../common/wrappingS-COOP-"
-"SCHEDULING.js"
-msgstr ""
-
-#: ../content/wrappers/coop-scheduling.md:block 2 (paragraph)
-msgid ""
-"The `window.requestIdleCallback()` API can schedule background tasks such "
-"that they do not introduce delays to other high priority tasks that share "
-"the same event loop, such as input processing, animations and frame "
-"compositing."
-msgstr ""
-
-#: ../content/wrappers/coop-scheduling.md:block 3 (paragraph)
-msgid ""
-"But the API leaks information about the other tasks running in the browser "
-"as it leaks information on currently scheduled tasks, vsync deadlines, user-"
-"interaction and so on."
-msgstr ""
-
-#: ../content/wrappers/coop-scheduling.md:block 4 (paragraph)
-msgid "JShelter modifies the return call to:"
-msgstr ""
-
-#: ../content/wrappers/coop-scheduling.md:block 5 (ordered list)
-msgid ""
-"Never leak the information that the call was triggered by an expired "
-"timeout."
-msgstr ""
-
-#: ../content/wrappers/coop-scheduling.md:block 5 (ordered list)
-msgid ""
-"Fake the information on remaining time in synchronization with the "
-"`Date.now()` wrapper. Returns up to 50% more time compared to the original "
-"value."
-msgstr ""
-
-#: ../content/wrappers/dm.md:block 1 (paragraph)
-msgid "Title: Device memory Filename: ../common/wrappingS-DM.js"
-msgstr ""
-
-#: ../content/wrappers/dm.md:block 2 (paragraph)
-msgid ""
-"This file contains a wrapper for "
-"[navigator.deviceMemory](https://developer.mozilla.org/en-"
-"US/docs/Web/API/Navigator/deviceMemory)."
-msgstr ""
-
-#: ../content/wrappers/dm.md:block 3 (paragraph)
-msgid ""
-"The goal is to prevent fingerprinting by modifying the return value of the "
-"`navigator.deviceMemory` parameter."
-msgstr ""
-
-#: ../content/wrappers/dm.md:block 4 (paragraph)
-msgid "This wrapper operates with three levels of protection:"
-msgstr ""
-
-#: ../content/wrappers/dm.md:block 5 (unordered list)
-msgid "(0) - return random valid value from range [0.25 - real value]"
-msgstr ""
-
-#: ../content/wrappers/dm.md:block 5 (unordered list)
-msgid "(1) - return random valid value from range [0.25 - 8]"
-msgstr ""
-
-#: ../content/wrappers/dm.md:block 5 (unordered list)
-msgid "(2) - return 4"
-msgstr ""
-
-#: ../content/wrappers/dm.md:block 6 (paragraph)
-msgid ""
-"These approaches are inspired by the algorithms created by [Brave "
-"Software](https://brave.com) available "
-"[here](https://github.com/brave/brave-"
-"core/blob/master/chromium_src/third_party/blink/renderer/core/frame/navigator_device_memory.cc)."
-msgstr ""
-
-#: ../content/wrappers/dom.md:block 1 (paragraph)
-msgid "Title: DOM API Filename: ../common/wrappingS-DOM.js"
-msgstr ""
-
-#: ../content/wrappers/dom.md:block 2 (paragraph)
-msgid ""
-"The events carry timestamp of their creation. As we allow wrapping of "
-"several ways to obtain timestamps, we need to provide the same precision for"
-" the Event API."
-msgstr ""
-
-#: ../content/wrappers/ecma-array.md:block 1 (paragraph)
-msgid "Title: ECMAscript arrays Filename: ../common/wrappingS-ECMA-ARRAY.js"
-msgstr ""
-
-#: ../content/wrappers/ecma-array.md:block 2 (paragraph)
-msgid ""
-"This wrapper aims on prevention of microarchitectural attacks like Meltdown "
-"and Spectre. This code was originally a part of "
-"[ChromeZero](https://github.com/IAIK/ChromeZero)."
-msgstr ""
-
-#: ../content/wrappers/ecma-array.md:block 3 (paragraph)
-msgid "**Known bug**: The `subarray()` method always ruturns the full array."
-msgstr ""
-
-#: ../content/wrappers/ecma-array.md:block 4 (paragraph)
-msgid "The wrappers support the following behaviour:"
-msgstr ""
-
-#: ../content/wrappers/ecma-array.md:block 5 (unordered list)
-msgid ""
-"Offset: The content of the buffer is shifted by a fix offset. This is a "
-"faster method but can be removed."
-msgstr ""
-
-#: ../content/wrappers/ecma-array.md:block 5 (unordered list)
-msgid ""
-"Random mapping: All items are mapped randomly. This is a slower method but "
-"more reliable."
-msgstr ""
-
-#: ../content/wrappers/ecma-array.md:block 6 (paragraph)
-msgid ""
-"\\see "
-"<https://www.fit.vut.cz/study/thesis/22374/?year=0&sup=Pol%C4%8D%C3%A1k>, "
-"especially Sect. 5.1"
-msgstr ""
-
-#: ../content/wrappers/ecma-date.md:block 1 (paragraph)
-msgid "Title: ECMAscript date Filename: ../common/wrappingS-ECMA-DATE.js"
-msgstr ""
-
-#: ../content/wrappers/ecma-date.md:block 2 (paragraph)
-msgid ""
-"This wrapper aims on prevention of microarchitectural attacks, clock-skew "
-"attacks, and other time related attacks. The goal is to limit the precision "
-"of the time returned by the Date object."
-msgstr ""
-
-#: ../content/wrappers/ecma-date.md:block 3 (paragraph)
-msgid ""
-"\\see "
-"<https://www.fit.vut.cz/study/thesis/22308/?year=0&sup=Pol%C4%8D%C3%A1k>, "
-"especially Sect. 7.2."
-msgstr ""
-
-#: ../content/wrappers/ecma-date.md:block 4 (paragraph)
-msgid ""
-"\\see Tom Van Goethem, Wouter Joosen, Nick Nikiforakis. The Clock is Still "
-"Ticking: Timing Attacks in the Modern Web. CCS'15. "
-"[Link](https://lirias.kuleuven.be/retrieve/389086), "
-"[DOI](http://dx.doi.org/10.1145/2810103.2813632)"
-msgstr ""
-
-#: ../content/wrappers/ecma-date.md:block 5 (paragraph)
-msgid ""
-"\\see Schwarz, M., Lipp, M. a Gruss, D. JavaScript Zero: Real JavaScript and"
-" Zero Side-Channel Attacks. NDSS'18."
-msgstr ""
-
-#: ../content/wrappers/ecma-date.md:block 6 (paragraph)
-msgid ""
-"\\see Schwarz M., Maurice C., Gruss D., Mangard S. (2017) Fantastic Timers "
-"and Where to Find Them: High-Resolution Microarchitectural Attacks in "
-"JavaScript. In: Kiayias A. (eds) Financial Cryptography and Data Security. "
-"FC 2017. Lecture Notes in Computer Science, vol 10322. Springer, Cham. "
-"https://doi.org/10.1007/978-3-319-70972-7_13"
-msgstr ""
-
-#: ../content/wrappers/ecma-date.md:block 8 (unordered list)
-msgid ""
-"Round timestamp: Limit the precision by removing (a part of) the decimal "
-"part of the timestamp."
-msgstr ""
-
-#: ../content/wrappers/ecma-date.md:block 8 (unordered list)
-msgid ""
-"Randomize after rounding: Create a fake decimal part to confuse attackers "
-"and to create timestamps that look similar to expected timestamps."
-msgstr ""
-
-#: ../content/wrappers/ecma-shared.md:block 1 (paragraph)
-msgid ""
-"Title: ECMA shared buffers Filename: ../common/wrappingS-ECMA-SHARED.js"
-msgstr ""
-
-#: ../content/wrappers/ecma-shared.md:block 2 (paragraph)
-msgid ""
-"This wrapper aims on prevention of misusing `SharedArrayBuffer` to create "
-"perfect timers and to perfrom microarchitectural attacks. This code was "
-"originally a part of [ChromeZero](https://github.com/IAIK/ChromeZero)."
-msgstr ""
-
-#: ../content/wrappers/ecma-shared.md:block 3 (paragraph)
-msgid ""
-"\\see "
-"https://www.fit.vut.cz/study/thesis/22374/?year=0&sup=Pol%C4%8D%C3%A1k, "
-"especially Sect. 5.1"
-msgstr ""
-
-#: ../content/wrappers/eme.md:block 1 (paragraph)
-msgid "Title: Encrypted Media Extensions Filename: ../common/wrappingS-EME.js"
-msgstr ""
-
-#: ../content/wrappers/eme.md:block 2 (paragraph)
-msgid ""
-"`Navigator.requestMediaKeySystemAccess()` provides access to "
-"`MediaKeySystemAccess` object that allows to query supported encryption "
-"mechanisms and other information about the system."
-msgstr ""
-
-#: ../content/wrappers/eme.md:block 3 (paragraph)
-msgid ""
-"For example, visit https://www.fit.vutbr.cz/~polcak/jsr/hdcp/ and try a "
-"different browser or computer."
-msgstr ""
-
-#: ../content/wrappers/eme.md:block 4 (paragraph)
-msgid ""
-"\\see https://w3c.github.io/encrypted-media/ \\see "
-"https://developer.mozilla.org/en-"
-"US/docs/Web/API/Navigator/requestMediaKeySystemAccess \\see "
-"https://developer.mozilla.org/en-US/docs/Web/API/MediaKeySystemAccess \\see "
-"https://developer.mozilla.org/en-"
-"US/docs/Web/API/MediaKeySystemAccess/getConfiguration"
-msgstr ""
-
-#: ../content/wrappers/eme.md:block 5 (paragraph)
-msgid "We provide two modes of protection:"
-msgstr ""
-
-#: ../content/wrappers/eme.md:block 6 (ordered list)
-msgid "Strict approach prevents accessing the API."
-msgstr ""
-
-#: ../content/wrappers/eme.md:block 6 (ordered list)
-msgid ""
-"Farbling approach changes the output to a non-existing key system with 12.5%"
-" probability."
-msgstr ""
-
-#: ../content/wrappers/geo.md:block 1 (paragraph)
-msgid "Title: Geolocation Filename: ../common/wrappingS-GEO.js"
-msgstr ""
-
-#: ../content/wrappers/geo.md:block 2 (paragraph)
-msgid ""
-"The goal is to prevent leaks of user current position. The Geolocation API "
-"also provides access to high precision timestamps which can be used to "
-"various web attacks (see for example, "
-"http://www.jucs.org/jucs_21_9/clock_skew_based_computer, "
-"https://lirias.kuleuven.be/retrieve/389086)."
-msgstr ""
-
-#: ../content/wrappers/geo.md:block 3 (paragraph)
-msgid ""
-"Although it is true that the user needs to specificaly approve access to "
-"location facilities, these wrappers aim on improving the control of the "
-"precision of the geolocation."
-msgstr ""
-
-#: ../content/wrappers/geo.md:block 4 (paragraph)
-msgid "The wrappers support the following controls:"
-msgstr ""
-
-#: ../content/wrappers/geo.md:block 5 (unordered list)
-msgid ""
-"Accurate data: the extension provides precise geolocation position but "
-"modifies the time precision in conformance with the Date and Performance "
-"wrappers."
-msgstr ""
-
-#: ../content/wrappers/geo.md:block 5 (unordered list)
-msgid ""
-"Modified position: the extension modifies the time precision of the time "
-"stamps in conformance with the Date and Performance wrappers, and "
-"additionally, allows to limit the precision of the current position to "
-"hundered of meters, kilometers, tens, or hundereds of kilometers."
-msgstr ""
-
-#: ../content/wrappers/geo.md:block 6 (paragraph)
-msgid "When modifying position:"
-msgstr ""
-
-#: ../content/wrappers/geo.md:block 7 (unordered list)
-msgid ""
-"Repeated calls of `navigator.geolocation.getCurrentPosition()` return the "
-"same position without page load and typically return another position after "
-"page reload."
-msgstr ""
-
-#: ../content/wrappers/geo.md:block 7 (unordered list)
-msgid "`navigator.geolocation.watchPosition()` does not change position."
-msgstr ""
-
-#: ../content/wrappers/gp.md:block 1 (paragraph)
-msgid "Title: Gamepad Filename: ../common/wrappingS-GP.js"
-msgstr ""
-
-#: ../content/wrappers/gp.md:block 2 (paragraph)
-msgid ""
-"navigator.getGamepads() allows any page script to learn the gamepads "
-"connected to the computer if the feature is not blocked by the Feature-"
-"Policy."
-msgstr ""
-
-#: ../content/wrappers/gp.md:block 3 (paragraph)
-msgid ""
-"The \"Fingerprinting the Fingerprinters\" paper (see reference below) "
-"observed that the interface is used in the wild to fingerprint users. As it "
-"is likely that only a minority of users have a gamepad connected and the API"
-" provides additional information on the HW, it is likely that users with a "
-"gamepad connected are easily fingerprintable."
-msgstr ""
-
-#: ../content/wrappers/gp.md:block 4 (paragraph)
-msgid ""
-"As we expect that the majority of the users does not have a gamepad "
-"connected, we provide only a single mitigation - the wrapped APIs return an "
-"empty list."
-msgstr ""
-
-#: ../content/wrappers/gp.md:block 5 (paragraph)
-msgid ""
-"**Known bug**: The standard provides an event `gamepadconnected` and "
-"`gamepaddisconnected` that fires at least on the window object. We do not "
-"mitigate the event to fire and consequently, it is possible that an "
-"adversary can learn that a gamepad was (dis)connected but there was no "
-"change in the result of the `navigator.getGamepads()` API."
-msgstr ""
-
-#: ../content/wrappers/gp.md:block 6 (paragraph)
-msgid ""
-"The gamepad representing object carries a timestamp of the last change of "
-"the gamepad. As we allow wrapping of several ways to obtain timestamps, we "
-"need to provide the same precision for the Gamepad object."
-msgstr ""
-
-#: ../content/wrappers/gp.md:block 7 (paragraph)
-msgid ""
-"\\see U. Iqbal, S. Englehardt and Z. Shafiq, [Fingerprinting the "
-"Fingerprinters: Learning to Detect Browser Fingerprinting "
-"Behaviors](https://github.com/uiowa-irl/FP-"
-"Inspector/blob/master/Data/potential_fingerprinting_APIs.md) in 2021 2021 "
-"IEEE Symposium on Security and Privacy (SP), San Francisco, CA, US, 2021 pp."
-" 283-301"
-msgstr ""
-
-#: ../content/wrappers/h-c.md:block 1 (paragraph)
-msgid "Title: HTML Canvas Filename: ../common/wrappingS-H-C.js"
-msgstr ""
-
-#: ../content/wrappers/h-c.md:block 2 (paragraph)
-msgid ""
-"This file contains wrappers for calls related to the Canvas API, about which"
-" you can read more at MDN:"
-msgstr ""
-
-#: ../content/wrappers/h-c.md:block 3 (unordered list)
-msgid ""
-"[Canvas API](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API)"
-msgstr ""
-
-#: ../content/wrappers/h-c.md:block 3 (unordered list)
-msgid ""
-"[CanvasRenderingContext2D](https://developer.mozilla.org/en-"
-"US/docs/Web/API/CanvasRenderingContext2D)"
-msgstr ""
-
-#: ../content/wrappers/h-c.md:block 3 (unordered list)
-msgid ""
-"[OffscreenCanvas](https://developer.mozilla.org/en-"
-"US/docs/Web/API/OffscreenCanvas)"
-msgstr ""
-
-#: ../content/wrappers/h-c.md:block 4 (paragraph)
-msgid ""
-"The goal is to prevent fingerprinting by modifying the values that can be "
-"read from the canvas. So the visual content of wrapped canvases as displayed"
-" on the screen is the same as intended."
-msgstr ""
-
-#: ../content/wrappers/h-c.md:block 5 (paragraph)
-msgid ""
-"The modified content can be either an empty image or a fake image that is "
-"modified according to session and domain keys to be different than the "
-"original albeit very similar (i.e. the approach inspired by the algorithms "
-"created by [Brave Software](https://brave.com) available "
-"[here](https://github.com/brave/brave-"
-"core/blob/master/chromium_src/third_party/blink/renderer/core/execution_context/execution_context.cc)."
-msgstr ""
-
-#: ../content/wrappers/h-c.md:block 6 (paragraph)
-msgid ""
-"Note that both approaches are detectable by a fingerprinter that checks if a"
-" predetermined image inserted to the canvas is the same as the read one, see"
-" [here](https://arkenfox.github.io/TZP/tests/canvasnoise.html) for an "
-"example, Nevertheless, the aim of the wrappers is to limit the "
-"finerprintability."
-msgstr ""
-
-#: ../content/wrappers/h-c.md:block 7 (paragraph)
-msgid ""
-"Also note that a determined fingerprinter can reveal the modifications and "
-"consequently uncover the original image. This can be avoided with the "
-"approach that completely clears the data stored in the canvas. Use the "
-"modifications based on session and domain keys if you want to provide an "
-"image that is similar to the original or if you want to produce a fake image"
-" that is not obviously spoofed to a naked eye. Otherwise, use the clearing "
-"approach."
-msgstr ""
-
-#: ../content/wrappers/hrt.md:block 1 (paragraph)
-msgid "Title: HTML Performance Filename: ../common/wrappingS-HRT.js"
-msgstr ""
-
-#: ../content/wrappers/hrt.md:block 2 (paragraph)
-msgid ""
-"This wrapper aims on prevention of microarchitectural attacks, clock-skew "
-"attacks, and other time related attacks. The goal is to limit the precision "
-"of the time returned by the Performance API."
-msgstr ""
-
-#: ../content/wrappers/hrt.md:block 3 (paragraph)
-msgid ""
-"\\see "
-"https://www.fit.vut.cz/study/thesis/22308/?year=0&sup=Pol%C4%8D%C3%A1k, "
-"especially Sect. 7.2."
-msgstr ""
-
-#: ../content/wrappers/hrt.md:block 4 (paragraph)
-msgid ""
-"\\see Tom Van Goethem, Wouter Joosen, Nick Nikiforakis. The Clock is Still "
-"Ticking: Timing Attacks in the Modern Web. CCS'15. DOI: "
-"http://dx.doi.org/10.1145/2810103.2813632. "
-"https://lirias.kuleuven.be/retrieve/389086"
-msgstr ""
-
-#: ../content/wrappers/html5.md:block 1 (paragraph)
-msgid "Title: HTML multimedia Filename: ../common/wrappingS-HTML5.js"
-msgstr ""
-
-#: ../content/wrappers/html5.md:block 2 (paragraph)
-msgid ""
-"Supported codecs (multimedia media types) can be misued for fingerprinting, "
-"see for example the [FPMon paper](https://fpmon.github.io/fingerprinting-"
-"monitor/files/FPMON.pdf)."
-msgstr ""
-
-#: ../content/wrappers/html5.md:block 3 (paragraph)
-msgid "JShelter provides two modes of protection:"
-msgstr ""
-
-#: ../content/wrappers/html5.md:block 4 (ordered list)
-msgid "Strict approach returns all media types as not supported."
-msgstr ""
-
-#: ../content/wrappers/html5.md:block 4 (ordered list)
-msgid "Modifies the output of probably/maybe supported codecs."
-msgstr ""
-
-#: ../content/wrappers/html-ls.md:block 1 (paragraph)
-msgid "Title: HTML Workers Filename: ../common/wrappingS-HTML-LS.js"
-msgstr ""
-
-#: ../content/wrappers/html-ls.md:block 2 (paragraph)
-msgid ""
-"This wrapper aims on prevention of microarchitectural attacks. This code was"
-" originally a part of [ChromeZero](https://github.com/IAIK/ChromeZero)."
-msgstr ""
-
-#: ../content/wrappers/html-ls.md:block 4 (unordered list)
-msgid "Polyfill: Completely eliminates the paralelism."
-msgstr ""
-
-#: ../content/wrappers/html-ls.md:block 4 (unordered list)
-msgid ""
-"Randomly slow messages: Add noise to the `postMessage` method execution."
-msgstr ""
-
-#: ../content/wrappers/html-ls.md:block 5 (paragraph)
-msgid ""
-"\\see Lipp, M., Gruss, D., Schwarz, M., Bidner, D., Maurice, C. et al. "
-"Practical Keystroke Timing Attacks in Sandboxed JavaScript. In:. August "
-"2017, s. 191–209. ISBN 978-3-319-66398-2."
-msgstr ""
-
-#: ../content/wrappers/html-ls.md:block 7 (paragraph)
-msgid ""
-"\\see "
-"<https://www.fit.vut.cz/study/thesis/22374/?year=0&sup=Pol%C4%8D%C3%A1k>"
-msgstr ""
-
-#: ../content/wrappers/html.md:block 1 (paragraph)
-msgid "Title: HTML window name Filename: ../common/wrappingS-HTML.js"
-msgstr ""
-
-#: ../content/wrappers/html.md:block 2 (paragraph)
-msgid ""
-"`window.name` provides a simple cross-origin tracking method of the same "
-"tab:"
-msgstr ""
-
-#: ../content/wrappers/html.md:block 4 (paragraph)
-msgid "Go to completely different web site and window.name stays the same."
-msgstr ""
-
-#: ../content/wrappers/html.md:block 5 (paragraph)
-msgid ""
-"\\see https://2019.www.torproject.org/projects/torbrowser/design/ provides a"
-" library build on top of `window.name`: "
-"https://www.thomasfrank.se/sessionvars.html."
-msgstr ""
-
-#: ../content/wrappers/html.md:block 6 (paragraph)
-msgid ""
-"\\see https://html.spec.whatwg.org/#history-traversal; this feature should "
-"not be ncessary for Firefox 86 or newer "
-"https://bugzilla.mozilla.org/show_bug.cgi?id=444222."
-msgstr ""
-
-#: ../content/wrappers/idle.md:block 1 (paragraph)
-msgid "Title: Idle detection Filename: ../common/wrappingS-IDLE.js"
-msgstr ""
-
-#: ../content/wrappers/idle.md:block 2 (paragraph)
-msgid ""
-"\\see https://web.dev/idle-detection/ \\see "
-"https://developer.mozilla.org/en-US/docs/Web/API/IdleDetector"
-msgstr ""
-
-#: ../content/wrappers/idle.md:block 3 (paragraph)
-msgid ""
-"The Idle Detection API can detect inactive users and locked screens. "
-"JShelter either removes the API (IdleDetector), or disables permission "
-"requests and returns user activity and unlocked screen (for previously "
-"granted permissions), or just always report user activity and unlocked "
-"screen."
-msgstr ""
-
-#: ../content/wrappers/idle.md:block 4 (paragraph)
-msgid ""
-"**Known bug**: JShelter does not block events, so the page is notified that "
-"something changed but it cannot read what changed."
-msgstr ""
-
-#: ../content/wrappers/mcs.md:block 1 (paragraph)
-msgid "Title: Media devices Filename: ../common/wrappingS-MCS.js"
-msgstr ""
-
-#: ../content/wrappers/mcs.md:block 2 (paragraph)
-msgid ""
-"This file contains wrapper for MediaDevices.enumerateDevices "
-"https://developer.mozilla.org/en-"
-"US/docs/Web/API/MediaDevices/enumerateDevices"
-msgstr ""
-
-#: ../content/wrappers/mcs.md:block 3 (paragraph)
-msgid ""
-"The goal is to prevent fingerprinting by modifying return value of "
-"enumerateDevices."
-msgstr ""
-
-#: ../content/wrappers/mcs.md:block 5 (unordered list)
-msgid "(0) - return promise with shuffled array"
-msgstr ""
-
-#: ../content/wrappers/mcs.md:block 5 (unordered list)
-msgid ""
-"(1) - return promise with shuffled array with additional 0-4 fake devices"
-msgstr ""
-
-#: ../content/wrappers/mcs.md:block 5 (unordered list)
-msgid "(2) - return empty promise"
-msgstr ""
-
-#: ../content/wrappers/mcs.md:block 6 (paragraph)
-msgid ""
-"The shuffling approach is inspired by the algorithms created by [Brave "
-"Software](https://brave.com) available "
-"[here](https://github.com/brave/brave-"
-"core/blob/master/chromium_src/third_party/blink/renderer/modules/mediastream/media_devices.cc)."
-msgstr ""
-
-#: ../content/wrappers/media-capabilities.md:block 1 (paragraph)
-msgid ""
-"Title: Media capabilities Filename: ../common/wrappingS-MEDIA-"
-"CAPABILITIES.js"
-msgstr ""
-
-#: ../content/wrappers/media-capabilities.md:block 2 (paragraph)
-msgid ""
-"`` provides access to `MediaKeySystemAccess` object that allows to query "
-"supported codecs and other informations about the system."
-msgstr ""
-
-#: ../content/wrappers/media-capabilities.md:block 4 (paragraph)
-msgid "\\see https://w3c.github.io/media-capabilities/"
-msgstr ""
-
-#: ../content/wrappers/media-capabilities.md:block 6 (ordered list)
-msgid ""
-"Farbling approach changes the output to a non-existing codec with 12.5% "
-"probability."
-msgstr ""
-
-#: ../content/wrappers/net.md:block 1 (paragraph)
-msgid "Title: Network information Filename: ../common/wrappingS-NET.js"
-msgstr ""
-
-#: ../content/wrappers/net.md:block 2 (paragraph)
-msgid ""
-"This file contains a wrapper for "
-"[NetworkInformation](https://developer.mozilla.org/en-"
-"US/docs/Web/API/NetworkInformation#specifications)."
-msgstr ""
-
-#: ../content/wrappers/net.md:block 3 (paragraph)
-msgid ""
-"NetworkInformation allows sites to learn about local network conditions by "
-"querying `navigator.connection`. Fingerprinters can misuse the feature. "
-"Long-term observers may learn about traveling patterns through observation "
-"of repeated values (for example a network at work, home, travel, etc.)."
-msgstr ""
-
-#: ../content/wrappers/net.md:block 4 (paragraph)
-msgid ""
-"We implement the same protection as Brave: https://github.com/brave/brave-"
-"browser/issues/20122."
-msgstr ""
-
-#: ../content/wrappers/nfc.md:block 1 (paragraph)
-msgid "Title: Web NFC Filename: ../common/wrappingS-NFC.js"
-msgstr ""
-
-#: ../content/wrappers/nfc.md:block 2 (paragraph)
-msgid ""
-"This file contains a wrapper for [Web NFC "
-"API](https://developer.mozilla.org/en-US/docs/Web/API/Web_NFC_API)."
-msgstr ""
-
-#: ../content/wrappers/nfc.md:block 3 (paragraph)
-msgid "This API is not broadly supported and we just disable all objects."
-msgstr ""
-
-#: ../content/wrappers/np.md:block 1 (paragraph)
-msgid "Title: Navigator Plugins Filename: ../common/wrappingS-NP.js"
-msgstr ""
-
-#: ../content/wrappers/np.md:block 2 (paragraph)
-msgid ""
-"This file contains wrappers for NavigatorPlugins. See the MDN docs on the "
-"[plugins](https://developer.mozilla.org/en-"
-"US/docs/Web/API/NavigatorPlugins/plugins) and [MIME "
-"types](https://developer.mozilla.org/en-"
-"US/docs/Web/API/NavigatorPlugins/mimeTypes)."
-msgstr ""
-
-#: ../content/wrappers/np.md:block 3 (paragraph)
-msgid ""
-"The goal is to prevent fingerprinting by modifying value returned by getters"
-" navigator.plugins and navigator.mimeTypes"
-msgstr ""
-
-#: ../content/wrappers/np.md:block 5 (unordered list)
-msgid ""
-"(0) - replace by shuffled edited PluginArray with two added fake plugins, "
-"edited MimeTypeArray"
-msgstr ""
-
-#: ../content/wrappers/np.md:block 5 (unordered list)
-msgid ""
-"(1) - replace by shuffled PluginArray with two fake plugins, empty "
-"MimeTypeArray"
-msgstr ""
-
-#: ../content/wrappers/np.md:block 5 (unordered list)
-msgid "(2) - replace by empty PluginArray and MimeTypeArray"
-msgstr ""
-
-#: ../content/wrappers/np.md:block 6 (paragraph)
-msgid ""
-"These approaches are inspired by the algorithms created by [Brave "
-"Software](https://brave.com) available "
-"[here](https://github.com/brave/brave-"
-"core/blob/master/chromium_src/third_party/blink/renderer/modules/plugins/dom_plugin_array.cc)."
-msgstr ""
-
-#: ../content/wrappers/np.md:block 7 (paragraph)
-msgid ""
-"The purpose of the wrappers is solely to prevent fingerprinting. However, "
-"browsers modyfing the array stand out of the crowd, which makes them more "
-"fingerprintable. Consequently, JShelter does not modify an empty list. So no"
-" matter the configuration, an empty list is not populated by the wrappers."
-msgstr ""
-
-#: ../content/wrappers/np.md:block 8 (paragraph)
-msgid "If PDF inline viewing is supported, Firefox returns 5 plugins:"
-msgstr ""
-
-#: ../content/wrappers/np.md:block 9 (unordered list)
-msgid "\"PDF Viewer\""
-msgstr ""
-
-#: ../content/wrappers/np.md:block 9 (unordered list)
-msgid "\"Chrome PDF Viewer\""
-msgstr ""
-
-#: ../content/wrappers/np.md:block 9 (unordered list)
-msgid "\"Chromium PDF Viewer\""
-msgstr ""
-
-#: ../content/wrappers/np.md:block 9 (unordered list)
-msgid "\"Microsoft Edge PDF Viewer\""
-msgstr ""
-
-#: ../content/wrappers/np.md:block 9 (unordered list)
-msgid "\"WebKit built-in PDF\""
-msgstr ""
-
-#: ../content/wrappers/np.md:block 10 (paragraph)
-msgid ""
-"A list containing exactly these plugins is treated as the empty list and it "
-"is not modified."
-msgstr ""
-
-#: ../content/wrappers/pt2.md:block 1 (paragraph)
-msgid "Title: Performance Timeline (L2) Filename: ../common/wrappingS-PT2.js"
-msgstr ""
-
-#: ../content/wrappers/pt2.md:block 2 (paragraph)
-msgid ""
-"This wrapper aims on prevention of microarchitectural attacks, clock-skew "
-"attacks, and other time related attacks. The goal is to limit the precision "
-"of the time returned by the Performance Timeline API."
-msgstr ""
-
-#: ../content/wrappers/sensor-accelerometer.md:block 1 (paragraph)
-msgid ""
-"Title: Accelerometer Filename: ../common/wrappingS-SENSOR-ACCELEROMETER.js"
-msgstr ""
-
-#: ../content/wrappers/sensor-accelerometer.md:block 2 (paragraph)
-msgid ""
-"MOTIVATION Readings from the Accelerometer, LinearAccelerationSensor, and "
-"GravitySensor of the Generic Sensor API should be secured as they provide a "
-"potentially valuable data for creating fingerprints. There are multiple "
-"options. A unique fingerprint can be obtained by describing the device's "
-"vibrations (See "
-"https://link.springer.com/chapter/10.1007/978-3-319-30806-7_7). Using "
-"trajectory inference and matching of the model to map data, one may use the "
-"readings from the Accelerometer to determing the device's position (See "
-"https://www.researchgate.net/publication/220990763_ACComplice_Location_ "
-"inference_using_accelerometers_on_smartphones)."
-msgstr ""
-
-#: ../content/wrappers/sensor-accelerometer.md:block 3 (paragraph)
-msgid ""
-"WRAPPING The wrapper replaces the \"XYZ\" getters of the Accelerometer "
-"sensor, LinearAccelerationSensor, and GravitySensor. The wrapping's goal is "
-"to simulate a stationary device that is lying bottom down on a flat surface,"
-" e.g., a cell phone on the table. In such a case, only the `z` axis is "
-"affected by gravity. The `x` and `y` axes values should be set to zero. Yet,"
-" there could be vibrations that may change values a little bit, e.g., to "
-"spin around -0.1 to +0.1. This usually does not happed with every reading "
-"but only in intervals of seconds. And thus, after a few seconds we pseudo-"
-"randomly change these values. For the LinearAccelerationSensor, the returned"
-" values should represent the acceleration without the conribution of "
-"gravity. For stationary devices, the `x` and `y` are zeroes, while the 'z' "
-"portion fluctuates between 0 and 0.1 on the examined devices. The wrapper "
-"simulates the same behavior. Lastly, the GravitySensor's readings are "
-"calculated as the difference between the previous two."
-msgstr ""
-
-#: ../content/wrappers/sensor-accelerometer.md:block 4 (paragraph)
-msgid ""
-"POSSIBLE IMPROVEMENTS Currently, we assume te device is lying on a flat "
-"surface bottom down, and thus only the `z` is affected by gravity. As "
-"improvement, we can also assume the device is in an oblique position. In "
-"this case, the gravitational acceleration would affect two or three axes. "
-"Those will have to be updated properly to create a realistic behavior."
-msgstr ""
-
-#: ../content/wrappers/sensor-accel.md:block 1 (paragraph)
-msgid "Title: Accelerometer Filename: ../common/wrappingS-SENSOR-ACCEL.js"
-msgstr ""
-
-#: ../content/wrappers/sensor-accel.md:block 2 (paragraph)
-msgid ""
-"MOTIVATION Readings from the Accelerometer, LinearAccelerationSensor, and "
-"GravitySensor of the Generic Sensor API should be secured as they provide a "
-"potentially valuable data for creating fingerprints. There are multiple "
-"options. A unique fingerprint can be obtained by describing the device's "
-"vibrations (See "
-"https://link.springer.com/chapter/10.1007/978-3-319-30806-7_7). Using "
-"trajectory inference and matching of the model to map data, one may use the "
-"readings from the Accelerometer to determing the device's position (See "
-"https://www.researchgate.net/publication/220990763_ACComplice_Location_ "
-"inference_using_accelerometers_on_smartphones). Accelerometer readings can "
-"also be used for determining human walking patterns (See "
-"https://www.researchgate.net/publication/322835708_Classifying_Human_ "
-"Walking_Patterns_using_Accelerometer_Data_from_Smartphone)."
-msgstr ""
-
-#: ../content/wrappers/sensor-accel.md:block 3 (paragraph)
-msgid ""
-"WRAPPING The wrapper replaces the \"XYZ\" getters of the Accelerometer "
-"sensor, LinearAccelerationSensor, and GravitySensor. The wrapping's goal is "
-"to simulate a stationary device that can be possibly rotated. The rotation "
-"of the device is represented by the fake rotation matrix \"orient.rotMat\"."
-msgstr ""
-
-#: ../content/wrappers/sensor-accel.md:block 4 (paragraph)
-msgid ""
-"The GravitySensor should provide readings of gravity acceleration applied to"
-" the device. This is represented by a vector made of x, y, z portions. To "
-"get this faked gravity vector for the device, the reference vector [0, 0, "
-"9.8] is multipled with the rotation matrix. Wrappers for the GravitySensor's"
-" getters return x, y, z portions of the fake gravity vector."
-msgstr ""
-
-#: ../content/wrappers/sensor-accel.md:block 5 (paragraph)
-msgid ""
-"Next, the LinearAccelerationSensor should return acceleration values without"
-" the contribution of gravity. For a stationary device, it should be all "
-"zeroes. Yet, there could be vibrations that may change values a little bit, "
-"e.g., spin around -0.1 to +0.1, as seen on the examined devices. This "
-"usually does not happed with every reading but only in intervals of seconds."
-" And thus, after a few seconds we pseudo-randomly change these values."
-msgstr ""
-
-#: ../content/wrappers/sensor-accel.md:block 6 (paragraph)
-msgid ""
-"Finally, the Accelerometer sensor combines the previous two. Our wrappers "
-"thus return tha values from the LinearAccelerationSensor with the fake "
-"gravity vector portions added."
-msgstr ""
-
-#: ../content/wrappers/sensor-accel.md:block 7 (paragraph)
-msgid ""
-"POSSIBLE IMPROVEMENTS Support for simulation of a non-stationary device "
-"where the rotation can change. Currently, the calculation of the gravity "
-"vector is done only once by the initDataGenerator() where the reference "
-"vector is multiplied with the rotation matrix. If orient.rotMat could "
-"change, the dataGen would have to be updated periodically. Moreover, such a "
-"change should also be taken into account in wrappers for other movement-"
-"related sensors (Gyroscope, etc.)."
-msgstr ""
-
-#: ../content/wrappers/sensor-gyro.md:block 1 (paragraph)
-msgid "Title: Gyroscope Filename: ../common/wrappingS-SENSOR-GYRO.js"
-msgstr ""
-
-#: ../content/wrappers/sensor-gyro.md:block 2 (paragraph)
-msgid ""
-"MOTIVATION Gyroscope readings can be used for speech recognition: "
-"https://crypto.stanford.edu/gyrophone/ and various fingerprinting "
-"operations. For stationary devices, the resonance of the unique internal or "
-"external sounds affects angular velocities affect the Gyroscope and allow to"
-" create a fingerprint: "
-"https://www.researchgate.net/publication/356678825_Mobile_Device_Fingerprint_Identification_Using_Gyroscope_Resonance"
-" For moving devices, one of the options is using the Gyroscope analyze human"
-" walking patterns: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC7071017/"
-msgstr ""
-
-#: ../content/wrappers/sensor-gyro.md:block 3 (paragraph)
-msgid ""
-"WRAPPING The Gyroscope sensor provides readings of the angular velocity of "
-"the device alongthe x/y/z axes. For a stationary device, all velocities "
-"should be zero in an ideal state. As we observed on the examined devices, "
-"device sensor imperfections andlittle vibrations cause the `x`, `y` and `z` "
-"to oscillate between -0.002 and 0.002 on the examined devices. The wrapper "
-"simulates the same behavior."
-msgstr ""
-
-#: ../content/wrappers/sensor-gyro.md:block 4 (paragraph)
-msgid ""
-"POSSIBLE IMPROVEMENTS Support for simulation of a non-stationary device. "
-"This would require modifications to other movement-related sensors "
-"(Accelerometer, etc.)"
-msgstr ""
-
-#: ../content/wrappers/sensor-light.md:block 1 (paragraph)
-msgid ""
-"Title: Ambient light sensor Filename: ../common/wrappingS-SENSOR-LIGHT.js"
-msgstr ""
-
-#: ../content/wrappers/sensor-light.md:block 2 (paragraph)
-msgid ""
-"MOTIVATION The AmbientLightSensor returns illuminance of the device's "
-"environment. This is another value that describes the nearby physical "
-"surrounding of the device, and can thus be used together with other readings"
-" for creating a unique fingerprint."
-msgstr ""
-
-#: ../content/wrappers/sensor-light.md:block 3 (paragraph)
-msgid ""
-"WRAPPING On examined stationary devices inside an office, the illuminance "
-"measured was between 500 and 900, depending on the concrete position's light"
-" conditions. All measured values were rounded to nearest 50 illuminance "
-"value. The wrapper silumlates the same behavior. At start, a pseudorandom "
-"illuminance value is drawn. As we simulate a stationary device, this value "
-"remains constant for all AmbientLightSensor.prototype.illuminance calls."
-msgstr ""
-
-#: ../content/wrappers/sensor-light.md:block 4 (paragraph)
-msgid "POSSIBLE IMPROVEMENTS Simulation of changes in the illuminance."
-msgstr ""
-
-#: ../content/wrappers/sensor-magnet.md:block 1 (paragraph)
-msgid "Title: Magnet Filename: ../common/wrappingS-SENSOR-MAGNET.js"
-msgstr ""
-
-#: ../content/wrappers/sensor-magnet.md:block 2 (paragraph)
-msgid "MOTIVATION"
-msgstr ""
-
-#: ../content/wrappers/sensor-magnet.md:block 3 (paragraph)
-msgid ""
-"Magnetometer is a platform sensor available under the Generic Sensor API. "
-"Magnetometer measures strength and direction of the magnetic field at "
-"device's location. The interface offers sensor readings using three "
-"properties: x, y, and z. Each returns a number that describes the magnetic "
-"field aroud the particular axis. The numbers have a double precision and can"
-" be positive or negative, depending on the orientation of the field. The "
-"total strength of the magnetic field (M) can be calculated as M = sqrt(x^2 +"
-" z^2 + y^2). The unit is in microtesla (µT)."
-msgstr ""
-
-#: ../content/wrappers/sensor-magnet.md:block 4 (paragraph)
-msgid ""
-"The Earth's magnetic field ranges between approximately 25 and 65 µT. "
-"Concrete values depend on location, altitude, weather, interference made by "
-"other electric. devices, etc. While we consider it is unlikely that someone "
-"determines the precise location of the device from the Mangetometer values, "
-"its data can be used for fingerprinting. For instance, it can be determined "
-"wheter the device is moving or not. In case of a stationary device, we can "
-"make a fingerprint from the device's orientation. Another fingerprintable "
-"value is the average total strength of the field, which should remain stable"
-" if the device is at the same position and in the same environment."
-msgstr ""
-
-#: ../content/wrappers/sensor-magnet.md:block 5 (paragraph)
-msgid "WRAPPING"
-msgstr ""
-
-#: ../content/wrappers/sensor-magnet.md:block 6 (paragraph)
-msgid ""
-"To protect the device, we are wrapping the x, y, z getters of the "
-"`Magnetometer.prototype` object. Instead of using the original data, we use "
-"artificially generated values that look like actual sensor readings."
-msgstr ""
-
-#: ../content/wrappers/sensor-magnet.md:block 7 (paragraph)
-msgid ""
-"At every moment, our wrapper stores information about the previous reading. "
-"Each rewrapped getter first checks the `timestamp` value of the sensor "
-"object. If there is no difference from the previous reading's timestamp, the"
-" wrapper returns the last measured value. Otherwise, it provides a new fake "
-"reading."
-msgstr ""
-
-#: ../content/wrappers/sensor-magnet.md:block 8 (paragraph)
-msgid ""
-"We designed our fake field generator to fulfill the following properties:"
-msgstr ""
-
-#: ../content/wrappers/sensor-magnet.md:block 9 (unordered list)
-msgid ""
-"The randomness of the generator should be high enough to prevent attackers "
-"from deducing the sensor values."
-msgstr ""
-
-#: ../content/wrappers/sensor-magnet.md:block 9 (unordered list)
-msgid ""
-"Multiple scripts from the same website that access readings with the same "
-"timestamp must get the same results. And thus:"
-msgstr ""
-
-#: ../content/wrappers/sensor-magnet.md:block 9 (unordered list)
-msgid ""
-"The readings are deterministic - e.g., for a given website and time, we must"
-" be able to say what values to return."
-msgstr ""
-
-#: ../content/wrappers/sensor-magnet.md:block 10 (paragraph)
-msgid ""
-"For every \"random\" draw, we use the Mulberry32 sen_prng that is seeded "
-"with a value generated from the `domainHash` which ensures deterministic "
-"behavior for the given website. First, we choose the desired total strength "
-"`M` of the magnetic field at our simulated location. This is a pseudo-random"
-" number from 25 to 60 uT, like on the Earth."
-msgstr ""
-
-#: ../content/wrappers/sensor-magnet.md:block 11 (paragraph)
-msgid "We support two variants of settings the initial axes orientaton:"
-msgstr ""
-
-#: ../content/wrappers/sensor-magnet.md:block 12 (unordered list)
-msgid ""
-"A pseudorandom draw (RANDOM_AXES_ORIENTATION = true) - the original "
-"implementation"
-msgstr ""
-
-#: ../content/wrappers/sensor-magnet.md:block 12 (unordered list)
-msgid ""
-"Calculation from the faked device rotation (shared by other wrappers) - "
-"improved version"
-msgstr ""
-
-#: ../content/wrappers/sensor-magnet.md:block 13 (paragraph)
-msgid ""
-"For both methods, the orientation is defined by a number from -1 to 1 for "
-"each axis: `baseX`, `baseY`, and `baseZ`. By modifying the above-shown "
-"formula, we calculate the `multiplier` that needs to be applied to the base "
-"values to get the desired field. The calculation is done as follows:"
-msgstr ""
-
-#: ../content/wrappers/sensor-magnet.md:block 14 (unordered list)
-msgid ""
-"mult = (M * sqrt(baseX^2 + baseY^2 + baseZ^2) / (baseX^2 + baseY^2 + "
-"baseZ^2)) Now, we know that for axis `x`, the value should fluctuate around "
-"`baseX * mult`, etc."
-msgstr ""
-
-#: ../content/wrappers/sensor-magnet.md:block 15 (paragraph)
-msgid ""
-"How much the field changes over time is specified by the fluctuation factor "
-"(0;1] that can also be configured. For instance, 0.2 means that the magnetic"
-" field on the axis may change from the base value by 20% in both positive "
-"and negative way."
-msgstr ""
-
-#: ../content/wrappers/sensor-magnet.md:block 16 (paragraph)
-msgid ""
-"The fluctuation is simulated by using a series of **sine** functions for "
-"each axis. Each sine has a unique amplitude, phase shift, and period. The "
-"number of sines per axis is chosen pseudorandomly based on the wrapper "
-"settings. For initial experiments, we used around 20 to 30 sines for each "
-"axis. The optimal configuration is in question. More sines give less "
-"predictable results, but also increase the computing complexity that could "
-"have a negative impact on the browser's performance."
-msgstr ""
-
-#: ../content/wrappers/sensor-magnet.md:block 17 (paragraph)
-msgid ""
-"For the given timestamp `t`, we make the sum of all sine values at the point"
-" `x=t`. The result is then shifted over the y-axis by adding `base[X|Y|Z] * "
-"multiplier` to the sum. The initial configuration of the fake field "
-"generator was chosen intuitively to resemble the results of the real "
-"measurements. Currently, the generator uses at least one sine with the "
-"period around 100 us (with 10% tolerance), which seems to be the minimum "
-"sampling rate obtainable using the API on mobile devices. Then, at least one"
-" sine around 1 s, around 10 s, 1 minute, and 1 hour. When more than 5 sines "
-"are used, the cycle repeats using `modulo 5` and creates a new sine with the"
-" period around 100 us, but this time the tolerance is 20%. The same follows "
-"for seconds, tens of seconds, minutes, hours. The tolerance grows every 5 "
-"sines. For 11+ sines, the tolerance is 30% up to the maximum (currently "
-"50%). The amplitude of each sine is chosen pseudo- randomly based on the "
-"**fluctuation factor** described above. The phase shift of each sine is also"
-" pseudo-random number from [0;2PI)."
-msgstr ""
-
-#: ../content/wrappers/sensor-magnet.md:block 18 (paragraph)
-msgid ""
-"Based on the results, this heuristic returns belivable values that look like"
-" actual sensor readings. Nevertheless, the generator uses a series of "
-"constants, whose optimal values should be a subject of future research and "
-"improvements. Perphaps, a correlation analysis with real mesurements could "
-"help in the future."
-msgstr ""
-
-#: ../content/wrappers/sensor-magnet.md:block 19 (paragraph)
-msgid ""
-"POSSIBLE IMPROVEMENTS Non-stationary devices can be supported if the "
-"baseX,Y,Z is updated with each movement. Do more experiments in real "
-"environments and possibly update the reference magnetic field vector, or the"
-" sine generator, e.g. by simulating temporary pseudorandom electromagnetic "
-"interferences, etc."
-msgstr ""
-
-#: ../content/wrappers/sensor.md:block 1 (paragraph)
-msgid "Title: Generic sensor Filename: ../common/wrappingS-SENSOR.js"
-msgstr ""
-
-#: ../content/wrappers/sensor.md:block 2 (paragraph)
-msgid ""
-"MOTIVATION The risk of using Generic Sensor API calls for device "
-"fingerprinting is mentioned within the W3C Candidate Recommendation Draft, "
-"29 July 2021 (https://www.w3.org/TR/2021/CRD-generic-"
-"sensor-20210729/#device-fingerprinting) Documented threats include "
-"manufacturing imperfections and differences that are unique to the concrete "
-"model of the device and can be used for fingerprinting."
-msgstr ""
-
-#: ../content/wrappers/sensor.md:block 3 (paragraph)
-msgid ""
-"We discovered another loophole in the `Sensor.timestamp` attribute. The "
-"value describes when the last `Sensor.onreading` event occurred, in "
-"millisecond precision. We observed the time origin is not the time of "
-"browsing context creation but the last boot time of the device. Exposing "
-"such information is dangerous as it allows to fingerprint the user easily. "
-"It is unlikely that two different devices will boot at exactly the same "
-"time."
-msgstr ""
-
-#: ../content/wrappers/sensor.md:block 4 (paragraph)
-msgid "Tested with the Magnetometer sensor on the following devices:"
-msgstr ""
-
-#: ../content/wrappers/sensor.md:block 5 (unordered list)
-msgid ""
-"Samsung Galaxy S21 Ultra; Android 11, kernel 5.4.6-215566388-abG99BXXU3AUE1,"
-" Build/RP1A.200720.012.G998BXXU3AUE1 Chrome 94.0.4606.71 and Kiwi (Chromium)"
-" 94.0.4606.56"
-msgstr ""
-
-#: ../content/wrappers/sensor.md:block 5 (unordered list)
-msgid ""
-"Xiaomi Redmi Note 5; Android 9, kernel 4.4.156-perf+, Build/9 "
-"PKQ1.180901.001 Chrome 94.0.4606.71"
-msgstr ""
-
-#: ../content/wrappers/sensor.md:block 7 (paragraph)
-msgid ""
-"The wrapper thus protects device by changing the time origin to the browsing"
-" context creation time, whereas the timestamp should still uniquely identify"
-" the reading. This is achieved in the following way:"
-msgstr ""
-
-#: ../content/wrappers/sensor.md:block 8 (unordered list)
-msgid ""
-"At the first reading, we calculate the difference between the original value"
-" and performance.now(). This gives us the offset between 1) the device boot "
-"and 2) the page context initialization."
-msgstr ""
-
-#: ../content/wrappers/sensor.md:block 8 (unordered list)
-msgid ""
-"On every reading, the offset is subtracted from the original value. The "
-"resulting value then uniquely identifies the reading sample without exposing"
-" the boot time."
-msgstr ""
-
-#: ../content/wrappers/sensor.md:block 8 (unordered list)
-msgid ""
-"Like in the other time precision wrappers, the resulting timestamp is "
-"processed by the mitigation function before return. The mitigation may round"
-" and (optionally) add noise to the resulting timestamp."
-msgstr ""
-
-#: ../content/wrappers/sensor.md:block 9 (paragraph)
-msgid ""
-"POSSIBLE IMPROVEMENTS in protection level 2, the timestamp origin may be set"
-" to a random value based on the session hash. This can serve as a \"fake "
-"boot time.\""
-msgstr ""
-
-#: ../content/wrappers/sensor-orient.md:block 1 (paragraph)
-msgid ""
-"Title: Orientation sensor Filename: ../common/wrappingS-SENSOR-ORIENT.js"
-msgstr ""
-
-#: ../content/wrappers/sensor-orient.md:block 2 (paragraph)
-msgid ""
-"MOTIVATION Device orientation sensors can be easily used for fingerprinting."
-" As it highly unlikely that two devices visiting the same site will be "
-"oriented exactly the same, the orientation itself can serve as a "
-"fingerprint."
-msgstr ""
-
-#: ../content/wrappers/sensor-orient.md:block 3 (paragraph)
-msgid ""
-"WRAPPING AbsoluteOrientationSensor returns a quaterion decribing the "
-"physical orientation of the device in relation to the Earth's reference "
-"coordinate system. The faked orientation of the device is saved inside the "
-"\"orient\" global variable that is accessible to all wrappers. The value is "
-"chosen pseudorandomly from the domain hash. The wrappper supports possible "
-"change of orientation. With each reading, it loads the \"orient\"'s "
-"contents, converts the rotation matrix to a quaternion that is returned by "
-"the wrapped getter."
-msgstr ""
-
-#: ../content/wrappers/sensor-orient.md:block 4 (paragraph)
-msgid ""
-"RelativeOrientationSensor also describes the orientation, but without regard"
-" to the Earth's reference coordinate system. We suppose the coordinate "
-"system is chosen at the beginning of the sensor instance creation. As we "
-"observed, no matter how the device is oriented, there is always a slight "
-"difference from the AbsoluteOrientationSensor's in at least one axis. When "
-"the device moves, both sensors' readings change. But their difference should"
-" be always constant. And thus, we pseudorandomly generate a deviation from "
-"the Earth's reference coordinate system. And for each reading, we take the "
-"values from the fake AbsoluteOrientationSensor and modify them by the "
-"constant deviation."
-msgstr ""
-
-#: ../content/wrappers/sensor-orient.md:block 5 (paragraph)
-msgid ""
-"POSSIBLE IMPROVEMENTS Study the supported coordinate systems of the "
-"RelativeOrientationSensor and modify the wrapper behavior if needed."
-msgstr ""
-
-#: ../content/wrappers/vr.md:block 1 (paragraph)
-msgid "Title: Virtual Reality 1.1 Filename: ../common/wrappingS-VR.js"
-msgstr ""
-
-#: ../content/wrappers/vr.md:block 2 (paragraph)
-msgid ""
-"navigator.activeVRDisplays() allows any page script to learn the VR displays"
-" attached to the computer."
-msgstr ""
-
-#: ../content/wrappers/vr.md:block 3 (paragraph)
-msgid ""
-"U. Iqbal, S. Englehardt and Z. Shafiq, \"Fingerprinting the Fingerprinters: "
-"Learning to Detect Browser Fingerprinting Behaviors,\" in 2021 2021 IEEE "
-"Symposium on Security and Privacy (SP), San Francisco, CA, US, 2021 pp. "
-"283-301 observed (https://github.com/uiowa-irl/FP-"
-"Inspector/blob/master/Data/potential_fingerprinting_APIs.md) that the "
-"interface is used in the wild to fingerprint users. As it is likely that "
-"only a minority of users have a VR display connected and the API provides "
-"additional information on the HW, it is likely that users with a VR display "
-"connected are easily fingerprintable."
-msgstr ""
-
-#: ../content/wrappers/vr.md:block 4 (paragraph)
-msgid ""
-"As we expect that the majority of the users does not have a VR display "
-"connected, we provide only a single mitigation - the wrapped APIs returns an"
-" empty list."
-msgstr ""
-
-#: ../content/wrappers/vr.md:block 5 (paragraph)
-msgid ""
-"**Known bug**: The standard provides events *vrdisplayconnect*, "
-"*vrdisplaydisconnect* *vrdisplayactivate* and *vrdisplaydeactivate* that "
-"fires at least on the window object. We do not mitigate the event to fire "
-"and consequently, it is possible that an adversary can learn that a VR "
-"display was (dis)connected but there was no change in the result of the "
-"navigator.activeVRDisplays() API."
-msgstr ""
-
-#: ../content/wrappers/vr.md:block 6 (paragraph)
-msgid ""
-"The VRFrameData object carries a timestamp. As we allow wrapping of several "
-"ways to obtain timestamps, we need to provide the same precision for the "
-"VRFrameData object."
-msgstr ""
-
-#: ../content/wrappers/weba.md:block 1 (paragraph)
-msgid "Title: WebAudio Filename: ../common/wrappingS-WEBA.js"
-msgstr ""
-
-#: ../content/wrappers/weba.md:block 2 (paragraph)
-msgid ""
-"This file contains wrappers for AudioBuffer and AnalyserNode related calls"
-msgstr ""
-
-#: ../content/wrappers/weba.md:block 3 (unordered list)
-msgid "https://developer.mozilla.org/en-US/docs/Web/API/AudioBuffer"
-msgstr ""
-
-#: ../content/wrappers/weba.md:block 3 (unordered list)
-msgid "https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode"
-msgstr ""
-
-#: ../content/wrappers/weba.md:block 4 (paragraph)
-msgid ""
-"The goal is to prevent fingerprinting by modifying the values from functions"
-" which are reading/copying from AudioBuffer and AnalyserNode. So the audio "
-"content of wrapped objects is the same as intended."
-msgstr ""
-
-#: ../content/wrappers/weba.md:block 5 (paragraph)
-msgid ""
-"The modified content can be either a white noise based on domain key or a "
-"fake audio data that is modified according to domain key to be different "
-"than the original albeit very similar (i.e. the approach inspired by the "
-"algorithms created by Brave Software <https://brave.com> available at "
-"https://github.com/brave/brave-"
-"core/blob/master/chromium_src/third_party/blink/renderer/core/execution_context/execution_context.cc.)"
-msgstr ""
-
-#: ../content/wrappers/weba.md:block 6 (paragraph)
-msgid ""
-"**Note**: Both approaches are detectable by a fingerprinter that checks if a"
-" predetermined audio is the same as the read one. Nevertheless, the aim of "
-"the wrappers is to limit the finerprintability."
-msgstr ""
-
-#: ../content/wrappers/weba.md:block 7 (paragraph)
-msgid ""
-"**Known bug**: Possibly inconsistant data between AudioBuffer and "
-"AnalyserNode wrappers."
-msgstr ""
-
-#: ../content/wrappers/weba.md:block 8 (paragraph)
-msgid ""
-"**Known bug**: Inconsistency between AudioBuffer.prototype.copyFromChannel "
-"and AudioBuffer.prototype.getChannelData. "
-"AudioBuffer.prototype.copyFromChannel should call "
-"AudioBuffer.prototype.getChannelData wrapper and then return result of the "
-"original call."
-msgstr ""
-
-#: ../content/wrappers/webgl.md:block 1 (paragraph)
-msgid "Title: WebGL Filename: ../common/wrappingS-WEBGL.js"
-msgstr ""
-
-#: ../content/wrappers/webgl.md:block 2 (paragraph)
-msgid "This file contains wrappers for WebGL related calls"
-msgstr ""
-
-#: ../content/wrappers/webgl.md:block 3 (unordered list)
-msgid "https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext"
-msgstr ""
-
-#: ../content/wrappers/webgl.md:block 3 (unordered list)
-msgid ""
-"https://developer.mozilla.org/en-US/docs/Web/API/WebGL2RenderingContext"
-msgstr ""
-
-#: ../content/wrappers/webgl.md:block 4 (paragraph)
-msgid ""
-"The goal is to prevent fingerprinting by modifying the values from certain "
-"WebGLRenderingContext API functions. This includes return values of various "
-"functions which can be hardware/software specific and image data reading."
-msgstr ""
-
-#: ../content/wrappers/webgl.md:block 5 (paragraph)
-msgid ""
-"Content is either modified according to domain and session keys to be "
-"different than the original albeit very similar or replaced by bottom value "
-"which is consistent every time. Both approaches are inspired by the "
-"algorithms created by [Brave Software](https://brave.com) available "
-"[here](https://github.com/brave/brave-"
-"core/$blob/master/chromium_src/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc)"
-" and [here](https://github.com/brave/brave-"
-"core/blob/master/chromium_src/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc)."
-msgstr ""
-
-#: ../content/wrappers/webgl.md:block 6 (paragraph)
-msgid "This wrapper operates with two levels of protection:"
-msgstr ""
-
-#: ../content/wrappers/webgl.md:block 7 (unordered list)
-msgid ""
-"(0) - return modified results, such as slightly changed image, slightly "
-"changed number or random string"
-msgstr ""
-
-#: ../content/wrappers/webgl.md:block 7 (unordered list)
-msgid ""
-"(1) - return bottom values - such as zero, empty string, empty image, null, "
-"etc."
-msgstr ""
-
-#: ../content/wrappers/webgl.md:block 8 (paragraph)
-msgid ""
-"Level 0 is trying to force WebGL fingeprint to be unique on every domain and"
-" every session. This can be effective when used with other wrappers with "
-"same options. This level causes breakage of websites using WebGL only "
-"rarely. Level 1 is trying to return as little information as possible while "
-"being consistent across domains and sessions. This level can cause breakage "
-"on majority of websites using WebGL."
-msgstr ""
-
-#: ../content/wrappers/webgl.md:block 9 (paragraph)
-msgid ""
-"**Note**: Both approaches are detectable by a fingerprinter that checks if a"
-" predetermined image is the same as the read one or if specific function "
-"returns expected value. Nevertheless, the aim of the wrappers is to limit "
-"the finerprintability."
-msgstr ""
-
-#: ../content/wrappers/xr.md:block 1 (paragraph)
-msgid "Title: Web XR Filename: ../common/wrappingS-XR.js"
-msgstr ""
-
-#: ../content/wrappers/xr.md:block 2 (paragraph)
-msgid ""
-"navigator.xr allows any page script to learn the VR displays attached to the"
-" computer and more."
-msgstr ""
-
-#: ../content/wrappers/xr.md:block 3 (paragraph)
-msgid ""
-"U. Iqbal, S. Englehardt and Z. Shafiq, \"Fingerprinting the Fingerprinters: "
-"Learning to Detect Browser Fingerprinting Behaviors,\" in 2021 2021 IEEE "
-"Symposium on Security and Privacy (SP), San Francisco, CA, US, 2021 pp. "
-"283-301 observed (https://github.com/uiowa-irl/FP-"
-"Inspector/blob/master/Data/potential_fingerprinting_APIs.md) that the "
-"orginal WebVR API is used in the wild to fingerprint users. As it is likely "
-"that only a minority of users have a VR display connected and the API "
-"provides additional information on the HW, it is likely that users with a VR"
-" display connected are easily fingerprintable."
-msgstr ""
-
-#: ../content/wrappers/xr.md:block 4 (paragraph)
-msgid ""
-"As all the API calls are accessible through the navigator.xr API, we provide"
-" a single mitigation. We disable the API completely. This might need to be "
-"revised once this API is commonly enabled in browsers."
-msgstr ""

From 8de8f96baca5d5ba14e48848ea221f97688880bd Mon Sep 17 00:00:00 2001
From: Ricardo Lafuente <r@manufacturaindependente.org>
Date: Jan 23 2024 11:23:22 +0000
Subject: [PATCH 8/17] Document the translation pipeline


---

diff --git a/website/README.md b/website/README.md
index 2a29b9f..d985f73 100644
--- a/website/README.md
+++ b/website/README.md
@@ -11,16 +11,6 @@ Before starting, it's important to keep in mind that:
   directly -- edit the original source comments instead (inside the `common/`
   project directory)
 
-## Adding new pages
-
-## Translating content
-
-Translated content goes inside the subfolders of the `content/` directory using
-the language code. For instance, pages translated to Spanish should be placed
-inside `content/pages/es/`, taking care to keep the file names and the metadata
-names (e.g. `Title:`) intact. The site generator will gather the files and put
-them in their place inside the site structure.
-
 ## Generating the site
 
 To make a local copy of the web site, follow these steps:
@@ -29,3 +19,42 @@ To make a local copy of the web site, follow these steps:
 2. Generate the site with `make html`
 3. Run the local webserver with `make serve` and go to `http://localhost:8000`
    in your browser
+
+## Adding new pages
+
+TODO
+
+## Translating
+
+The JShelter website uses [Weblate](https://hosted.weblate.org) to manage translations. The `website/i18n/` directory contains a set of scripts to automate translation management, and the website build process (`make html`) runs these to synchronise the most recent updates to the translations on Weblate. Translators shouldn't need to worry about the internals as the build process should take care of everything; for more involved operations such as adding languages, updating the source files and others, here is a rundown of the translation pipeline.
+
+### 1. Generate the translation source files
+
+The `build_po_files.sh` script scans the Markdown content files and groups all the strings into `.po` files. The files are placed inside the `website/i18n/en/` directory. This process uses the `md2po` command from the [mdpo](https://mondeja.github.io/mdpo/latest/) Markdown parsing package.
+
+This step is necessary when there are changes to the source content (e.g. updating a post or page) to make sure the new strings will show up on the Weblate interface.
+
+NOTE/TODO: Uploading the `.po` files to Weblate needs to be done manually through the Weblate web UI. We intend to automate this part but there are a couple of bugs to deal with to make this feasible.
+
+### 2. Download the latest translations
+
+The `download.sh` script takes care of pulling the latest version of each available translation. The resulting `.po` files are placed inside the `website/i18n/<lang>/` directory, where `<lang>` is the language 2-letter code.
+
+### 3. Generate translated files
+
+The `translate_content.sh` script uses the `po2md` command from the [mdpo](https://mondeja.github.io/mdpo/latest/) package to generate translated Markdown files from the `.po` translation sources obtained in the previous step. The resulting files can be found inside the content directory: it creates a directory with the language code inside each section dir (`website/content/pages`, `website/content/posts` and `website/content/wrappers`).
+
+### 4. Post-process translated files
+
+The conversion process mangles the YAML frontmatter (there is an [open issue](https://github.com/mondeja/mdpo/issues/228) about this), so we perform some simple post-process to restore the proper formatting using the `postprocess.py` script.
+
+Currently the script runs on a single file outputting the result to stdout. The full set of files can be processed as in the website build `Makefile`:
+
+```bash
+for f in `ls ../content/pages/*.md`
+  do ./postprocess.py $f
+done
+```
+
+Note that this example only processes the `pages` section; just repeat it on the `posts` and `wrappers` dir to post-process the full set of translated files.
+

From 2abc4ddbd5f2286173330f7a76e8561f5bce924a Mon Sep 17 00:00:00 2001
From: Ricardo Lafuente <r@manufacturaindependente.org>
Date: Jan 23 2024 11:23:49 +0000
Subject: [PATCH 9/17] Add pages and wrappers to the postprocess build step


---

diff --git a/website/Makefile b/website/Makefile
index 976dc35..523d749 100644
--- a/website/Makefile
+++ b/website/Makefile
@@ -53,7 +53,7 @@ extract:
 	$(ACTIVATE); python extract_comments.py
 
 translate:
-	$(ACTIVATE); cd i18n; ./download.sh; ./translate_content.sh; for f in `ls ../content/posts/pt/*.md`; do ./postprocess.py $$f; done
+	$(ACTIVATE); cd i18n; ./download.sh; ./translate_content.sh; for f in `ls ../content/posts/pt/*.md`; do ./postprocess.py $$f; done; for f in `ls ../content/pages/pt/*.md`; do ./postprocess.py $$f; done; for f in `ls ../content/wrappers/*.md`; do ./postprocess.py $$f; done
 
 html: extract translate
 	cp ../tests/integration_tests/README.md content/pages/integration_tests.md

From cd6500330e652672a1995fdfe072dff99c410e4c Mon Sep 17 00:00:00 2001
From: Ricardo Lafuente <r@manufacturaindependente.org>
Date: Feb 05 2024 10:48:16 +0000
Subject: [PATCH 10/17] Separate html and build directives


---

diff --git a/website/Makefile b/website/Makefile
index 523d749..5d534df 100644
--- a/website/Makefile
+++ b/website/Makefile
@@ -55,7 +55,7 @@ extract:
 translate:
 	$(ACTIVATE); cd i18n; ./download.sh; ./translate_content.sh; for f in `ls ../content/posts/pt/*.md`; do ./postprocess.py $$f; done; for f in `ls ../content/pages/pt/*.md`; do ./postprocess.py $$f; done; for f in `ls ../content/wrappers/*.md`; do ./postprocess.py $$f; done
 
-html: extract translate
+html: extract 
 	cp ../tests/integration_tests/README.md content/pages/integration_tests.md
 	cp ../tests/unit_tests/README.md content/pages/unit_tests.md
 	mkdir -p output/ output/.well-known/
@@ -66,6 +66,8 @@ html: extract translate
 	# fix translated indexes to address a Pelican bug
 	# cd content/pages; for lang in */; do mv ../../output/$$lang/$$lang/index.html ../../output/$$lang; rm -f ../../output/$$lang/$$lang/index.html; done
 
+build: translate html
+
 clean:
 	[ ! -d "$(OUTPUTDIR)" ] || rm -rf "$(OUTPUTDIR)"
 	rm -fr content/pages/pt

From b65eeeca8b74f8cb773ccbc3f98a7e928557c4b9 Mon Sep 17 00:00:00 2001
From: Ricardo Lafuente <r@manufacturaindependente.org>
Date: Feb 05 2024 15:49:54 +0000
Subject: [PATCH 11/17] review home page


---

diff --git a/website/content/pages/home.md b/website/content/pages/home.md
index 47c8554..88787e2 100644
--- a/website/content/pages/home.md
+++ b/website/content/pages/home.md
@@ -40,12 +40,12 @@ URL:
         <h4>What is JShelter?</h4>
       </header>
       <div>
-        <p>JShelter is a browser extension to give back control over what your
+        <p>JShelter is a browser extension to give you control over what your
         browser is doing. A JavaScript-enabled web page can access much of the
         browser's functionality, with little control over this process available
         to the user: malicious websites can uniquely identify you through
         fingerprinting and use other tactics for tracking your activity.
-        JShelter aims to improve the privacy and security of your web
+        JShelter improves the privacy and security of your web
         browsing. For more details, see JShelter <a href="/threatmodel/">threat model</a>.</p>
       </div>
     </article>
@@ -70,7 +70,8 @@ URL:
       </header>
       <div>
         <p>First, install the extension using the button above or checking the various <a href="/install/">installation options</a>.</p>
-        <p>Afterwards, read our <a href="/blog/">blog</a>, <a href="https://arxiv.org/abs/2204.01392">paper</a>, <a href="/faq/">FAQ</a>, the <a href="/permissions/">required permissions</a> and the different protection <a href="/levels/">levels</a>.</p>
+        <p>Afterwards, read our <a href="/faq/">FAQ</a>, the <a href="/permissions/">required permissions</a> and the different protection <a href="/levels/">levels</a>.</p>
+        <p>For more details about what's going on under the hood, check out the <a href="/blog/">JShelter blog</a> and <a href="https://arxiv.org/abs/2204.01392">paper</a>.</p>
       </div>
     </article>
     <article>

From 0180356ea7f98cb668bc70f9297d0c57e1da34fc Mon Sep 17 00:00:00 2001
From: Ricardo Lafuente <r@manufacturaindependente.org>
Date: Feb 06 2024 15:00:28 +0000
Subject: [PATCH 12/17] Review threat model page


---

diff --git a/website/content/pages/threatmodel.md b/website/content/pages/threatmodel.md
index 1e651dd..b5c5681 100644
--- a/website/content/pages/threatmodel.md
+++ b/website/content/pages/threatmodel.md
@@ -1,11 +1,14 @@
 Title: Threat model
 
-JShelter focuses on threats that affect the mainstream population. Our adversary creates
-attacks/derives information in a way that works in mainstream browsers. The attacker focuses on these
-browsers and attacks that are light on performance. For example, the adversary is interested in
-identifying the user for targeted advertisement. So they need to identify the user quickly to
-display an advertisement. It does not make sense for such an attacker to deploy scripts that
-take minutes to compute a fingerprint.
+JShelter focuses on threats that target mainstream internet users. Attackers
+derive information and create attacks aimed at mainstream browsers, using
+approaches that minimize the performance requirements for such attacks.  For
+example, we can consider an adversary interested in identifying the user for
+targeted advertisement purposes. So, they will need to identify the user
+quickly to display an advertisement; it does not make sense for such an
+attacker to deploy scripts that take minutes to compute a fingerprint.
+
+## Fingerprinting countermeasures
 
 Our adversary might try to apply low-performance counterattacks. For example, previous literature
 identified extensions that modify calls in a wrong position in the JavaScript prototype chain. It is
@@ -14,7 +17,41 @@ so we apply code that modifies the original method, `Performance.prototype.now()
 Another example is an adversary running canvas fingerprinting several times. If the adversary
 receives different results, they can compute an average value (or a minimal or maximal value) and
 use this information to derive the correct fingerprint. As these modifications to fingerprinting are
-not performance-heavy, we consider them in the threat model.
+not performance-heavy, we consider them in the JShelter threat model.
+
+It is well-known that some extensions modify the environment of the browser or
+the web page. For example, password managers add buttons to fill in passwords
+automatically. Page tweakers add additional buttons to web pages to simplify
+common tasks or add information likely wanted by a user.  JShelter expects such
+users and tries to help such users from being identifiable. For example, a dumb
+fingerprinter can combine all fingerprintable data to create a single number.
+Such a fingerprinter would unintentionally create a unique fingerprint of the
+users with a unique set of extensions. Such a dumb fingerprinter would not link
+different visits of the user with Jshelter. JShelter should confuse a more
+advanced fingerprinter if they identify single or multiple users.
+
+We also want to provide an option that will limit the information that is
+readable from the computer, even if such behaviour generally results in better
+fingerprintability. For example, a user might want to disable canvas operations
+for pages that should not use canvas (from the user's standpoint). As the
+webpage is in a better position to deploy countermeasures for JShelter
+anti-fingerprinting techniques, the user might want the page to always read an
+empty, white, or random canvas. That would limit the information available for
+the web page at the cost of giving the page an easy way to determine that some
+countermeasures are in place. Our aim is to explain the consequences of taking
+such an option but letting the user decide for themselves.
+
+Previous literature identified that it is easy for an adversary to detect inconsistencies in API
+calls. For example, a fingerprinter can learn the operating system from HTTP headers,
+`navigator.oscpu`, installed fonts, results of mathematical operations, and other techniques. We do
+not want to replace such techniques as we do not have the resources to create a consistent environment.
+
+Besides fingerprinting, JShelter also focuses on other threats appearing on the web. For example,
+JShelter prevents web pages from turning the browser into a proxy to the local
+[network](/localportscanning/). The user should be able to decouple anti-fingerprinting
+countermeasures and other countermeasures.
+
+## Limitations and mitigation methods
 
 We do not have the resources to create a bullet-proof solution that eliminates all side channels. For
 example, we expect that an adversary will be able to detect that something strange is happening in
@@ -27,42 +64,20 @@ belongs. Hence, we try to eliminate the possibility of an attacker identifying t
 accept that the attacker can detect a JShelter user in the worst case. To do
 so reliably, the attacker should need to keep track of the code base changes.
 
-Nevertheless, we want to avoid allowing the attacker to identify JShelter users easily. We
-are not aware of any isolated side-effect that reveals JShelter. For example, some similar
-webextensions do not modify `Function.prototype.toString`. A page script could detect such a webextension as each
-webextension modifying the same API call by the same technique will likely use a different code.
-Our goal is to offer protection indistinguishable from another privacy-improving tool for
-each modified API. Nevertheless, a focused observer will very likely be always able to learn that a
-user is using JShelter if they aggregate the observable inconsistencies of all APIs produced by
-JShelter. We are aware and do not hide that users of JShelter are vulnerable to focused
-attacks.
-
-JShelter's goal is to make targeted attacks harder. Still, we do not believe that we are
-in a position to prevent them completely. We suggest
-using Tor Browser or a similar privacy-enhancing tool for users concerned with targeted attacks.
-
-It is well-known that some extensions modify the environment of the browser or the web page. For
-example, password managers add buttons to fill in passwords automatically. Page tweakers add
-additional buttons to web pages to simplify common tasks or add information likely wanted by a user.
-JShelter expects such users and tries to help such users from being identifiable. For example, a
-dumb fingerprinter can combine all fingerprintable data to create a single number. Such a fingerprinter
-would unintentionally create a unique fingerprint of the users with a unique set of extensions. Such a dumb fingerprinter would not link different visits of the user with Jshelter. JShelter should
-confuse a more advanced fingerprinter if they identify single or multiple users.
+Nevertheless, we want to avoid allowing the attacker to identify JShelter users
+easily. We are not aware of any isolated side-effect that reveals JShelter. For
+example, some similar webextensions do not modify
+`Function.prototype.toString`. A page script could detect such a webextension
+as each webextension modifying the same API call by the same technique will
+likely use a different code.  Our goal is to offer protection indistinguishable
+from another privacy-improving tool for each modified API. Nevertheless, a
+focused observer will very likely be always able to learn that a user is using
+JShelter if they aggregate the observable inconsistencies of all APIs produced
+by JShelter. We are aware and do not hide that users of JShelter are vulnerable
+to focused attacks.
 
-We also want to provide an option that will limit the information that is readable from the computer,
-even if such behaviour generally results in better fingerprintability. For example, a user
-might want to disable canvas operations for pages that should not use canvas (from the user's standpoint). As the webpage is in a better position to deploy countermeasures for JShelter
-anti-fingerprinting techniques, the user might want the page to always read an empty, white, or random
-canvas. That would limit the information available for the web page at the cost of giving the page
-an easy way to determine that some countermeasures are in place. Our aim is to explain
-the consequences of taking such an option but letting the user decide for themselves.
-
-Previous literature identified that it is easy for an adversary to detect inconsistencies in API
-calls. For example, a fingerprinter can learn the operating system from HTTP headers,
-`navigator.oscpu`, installed fonts, results of mathematical operations, and other techniques. We do
-not want to replace such techniques as we do not have the resources to create a consistent environment.
+JShelter's goal is to make targeted attacks harder. Still, we do not believe
+that we are in a position to prevent them completely. We suggest using [Tor
+Browser](https://www.torproject.org/download/) or a similar privacy-enhancing
+tool for users concerned with targeted attacks.
 
-Besides fingerprinting, JShelter also focuses on other threats appearing on the web. For example,
-JShelter prevents web pages from turning the browser into a proxy to the local
-[network](/localportscanning/). The user should be able to decouple anti-fingerprinting
-countermeasures and other countermeasures.

From be6bd6f175f72fd252429ee7a394e1f2312868a5 Mon Sep 17 00:00:00 2001
From: Ricardo Lafuente <r@manufacturaindependente.org>
Date: Feb 06 2024 15:16:17 +0000
Subject: [PATCH 13/17] More copy reviews


---

diff --git a/website/content/pages/credits.md b/website/content/pages/credits.md
index 8aeb1ca..fe3571c 100644
--- a/website/content/pages/credits.md
+++ b/website/content/pages/credits.md
@@ -4,40 +4,74 @@ Title: Credits
 
 ### Developers
 
-**[Libor Polčák](https://www.fit.vutbr.cz/~polcak)** was behind an idea to implement a webextension that works as a firewall for JavaScript APIs. He is the current main maintainer. He received support for this project through the <a href="https://nlnet.nl/project/JSRestrictor/">JavaScript Restrictor</a> project of NGI0 PET Fund, a fund established by NLnet with financial support from the European Commission's Next Generation Internet programme, under the aegis of DG Communications Networks, Content and Technology under grant agreement No 825310. He supervised/supervises diploma theses that improve the web extension.
-
-**Giorgio Maone** is working on the extension as a part of the [JS Shield project](https://nlnet.nl/project/JavascriptShield/), for example, he is working on cross-browser support, improvements on code injection and the compatibility between the global JS environment, Workers, and iframes.
-
-**Zbyněk Červinka** developed a [proof-of-concept version](https://github.com/cervinka-zbynek/masters-thesis) of this extension as a part of his [master's thesis](https://www.fit.vut.cz/study/thesis/21274/) (in Czech).
-
-**Martin Timko** developed first public versions upto [0.2.1](https://pagure.io/JShelter/webextension/archive/0.2.1/webextension-0.2.1.zip) as a part of his [master's thesis](https://www.fit.vut.cz/study/thesis/21824/). He also ported the extension to Chrome and Opera.
-
-**Martin Bednář** developed test suites of the extension as a part of his
-[master's thesis](https://www.fit.vut.cz/study/thesis/22376/) and continued to work on the extension for some
-time afterwards. He also fixed some bugs found during the testing.
-
-**Pavel Pohner** developed the Network Boundary Scanner as a part of his [master's thesis](https://www.fit.vut.cz/study/thesis/22377/).
-
-**Pater Horňák** ported functionality from [Chrome Zero](https://github.com/IAIK/ChromeZero) as a part of his [bachelor thesis](https://www.fit.vut.cz/study/thesis/22374/). He also provided several small fixes to the code base.
-
-**Matúš Švancár** ported Farbling anti-fingerprinting measures from the Brave browser as a part of his [master's thesis](https://www.fit.vut.cz/study/thesis/23310/).
-
-**Marek Saloň** created Fingerprint Detector as a part of his [master's thesis](https://www.fit.vut.cz/study/thesis/23645/) and later improved the detector.
+**[Libor Polčák](https://www.fit.vutbr.cz/~polcak)** is behind the idea to
+implement a web extension that works as a firewall for JavaScript APIs. He is
+the current lead maintainer of JShelter. He received support for this project
+through the <a href="https://nlnet.nl/project/JSRestrictor/">JavaScript
+Restrictor</a> project of NGI0 PET Fund, a fund established by NLnet with
+financial support from the European Commission's Next Generation Internet
+programme, under the aegis of DG Communications Networks, Content and
+Technology under grant agreement No 825310. He supervised/supervises diploma
+theses that improve the web extension.
+
+**Giorgio Maone** is working on the extension as a part of the [JS Shield
+project](https://nlnet.nl/project/JavascriptShield/). Among other efforts, he is
+working on cross-browser support, improvements on code injection and the
+compatibility between the global JS environment, Workers, and iframes.
+
+**Zbyněk Červinka** developed a [proof-of-concept
+version](https://github.com/cervinka-zbynek/masters-thesis) of the extension
+as a part of his [master's thesis](https://www.fit.vut.cz/study/thesis/21274/)
+(in Czech).
+
+**Martin Timko** developed the first public versions up to
+[0.2.1](https://pagure.io/JShelter/webextension/archive/0.2.1/webextension-0.2.1.zip)
+as a part of his [master's thesis](https://www.fit.vut.cz/study/thesis/21824/).
+He also ported the extension to Chrome and Opera.
+
+**Martin Bednář** developed test suites as a part of his [master's
+thesis](https://www.fit.vut.cz/study/thesis/22376/) and continued to work on
+the project for some time afterwards. He also fixed some bugs found during the
+testing.
+
+**Pavel Pohner** developed the Network Boundary Scanner as a part of his
+[master's thesis](https://www.fit.vut.cz/study/thesis/22377/).
+
+**Pater Horňák** ported functionality from [Chrome
+Zero](https://github.com/IAIK/ChromeZero) as a part of his [bachelor
+thesis](https://www.fit.vut.cz/study/thesis/22374/). He also provided several
+small fixes to the code base.
+
+**Matúš Švancár** ported Farbling anti-fingerprinting measures from the Brave
+browser as a part of his [master's
+thesis](https://www.fit.vut.cz/study/thesis/23310/).
+
+**Marek Saloň** created Fingerprint Detector as a part of his [master's
+thesis](https://www.fit.vut.cz/study/thesis/23645/) and later improved the
+detector.
 
 **Radek Hranický** created sensor API wrappers.
 
-**Martin Zmitko** improved performance of the extension as a part of his bachelor thesis. He fixed
-some bugs during the process.
+**Martin Zmitko** improved performance of the extension as a part of his
+bachelor thesis. He fixed some bugs during the process.
 
-We thank all other minor contributors of the project that are not listed in this section.
+We thank all other minor contributors of the project that are not listed in
+this section.
 
 ### Key ideas
 
-The development of this extension is influenced by the paper [JavaScript Zero: Real JavaScript and Zero Side-Channel Attacks](https://graz.pure.elsevier.com/de/publications/javascript-zero-real-javascript-and-zero-side-channel-attacks). It appeared during the work of Zbyněk Červinka and provided basically the same approach to restrict APIs as was at the time developed by Zbyněk Červinka.
+The development of this extension is influenced by the paper [JavaScript Zero:
+Real JavaScript and Zero Side-Channel
+Attacks](https://graz.pure.elsevier.com/de/publications/javascript-zero-real-javascript-and-zero-side-channel-attacks).
+It appeared during the work of Zbyněk Červinka and provided basically the same
+approach to restrict APIs as was at the time developed by Zbyněk Červinka.
 
-The [Force Point report](https://www.forcepoint.com/sites/default/files/resources/files/report-attacking-internal-network-en_0.pdf) was a key inspiration for the development of the Network Boundary Shield.
+The [Force Point
+report](https://www.forcepoint.com/sites/default/files/resources/files/report-attacking-internal-network-en_0.pdf)
+was a key inspiration for the development of the Network Boundary Shield.
 
-Some of the fingerprinting counter-measures are inspired by [Farbling of the Brave browser](blogarticles/farbling.md).
+Some of the fingerprinting counter-measures are inspired by [Farbling of the
+Brave browser](blogarticles/farbling.md).
 
 ### Borrowed code
 
diff --git a/website/content/pages/nbs.md b/website/content/pages/nbs.md
index 55b1141..b0da495 100644
--- a/website/content/pages/nbs.md
+++ b/website/content/pages/nbs.md
@@ -3,30 +3,30 @@ Slug: nbs
 
 The Network Boundary Shield (NBS) is a protection against attacks from an
 external network (the Internet) to an internal network - especially against a
-reconnaissance attacks when a web browser is abused as a proxy. See, for
-example, [our blog post](/localportscanning/) or the [ForcePoint
+reconnaissance attack where a web browser is abused as a proxy. See, for
+example, [our blog post on port scanning](/localportscanning/) or the [ForcePoint
 report](https://www.forcepoint.com/blog/x-labs/attacking-internal-network-public-internet-using-browser-proxy).
 
-The NBS functionality is based on filtering HTTP requests. The Network Boundary
-Shield uses blocking webRequest API to handle HTTP requests. This means that
-processing of each HTTP request is paused before it is analyzed and allowed (if
-it seems benign) or blocked (if it is suspicious).
+It works by filtering HTTP requests by means of the blocking webRequest API to
+handle HTTP requests. This means that the processing of each HTTP request is
+paused before it is analyzed and allowed (if it seems benign) or blocked (if it
+is suspicious).
 
-The main goal of NBS is to prevent attacks like a public website requests a
+The main goal of NBS is to prevent attacks where a public website requests a
 resource from the internal network (e.g. the logo of the manufacturer of the
-local router); NBS will detect that a web page hosted on the public Internet
-tries to connect to a local IP address. NBS blocks only HTTP requests from a web
-page hosted on a public IP address to a private network resource. The user can
-allow specific web pages to access local resources (e.g. when using Intranet
-services).
+local router); NBS will detect that a web page hosted on the public Internet is
+trying to connect to a local IP address. NBS only blocks HTTP requests from a
+web page hosted on a public IP address to a private network resource; the user
+can allow specific web pages to access local resources (e.g.  when using
+Intranet services).
 
 NBS uses [CSV files provided by
 IANA](https://www.iana.org/assignments/locally-served-dns-zones/locally-served-dns-zones.xml)
 to determine public and local IP address prefixes. Both IPv4 and IPv6 is
 supported. The CSV files are downloaded during the JShelter building process.
 
-The NBS has only a small impact on the web browser performance. The impact
-differs for each implementation.
+The NBS has a small performance footprint, which differs for each browser
+implementation.
 
 More information about the Network Boundary Shield can be obtained from the
 [master thesis by Pavel

From 31ecd89936c68cfc7c6b18899c2b1ff4edebcd5c Mon Sep 17 00:00:00 2001
From: Ricardo Lafuente <r@manufacturaindependente.org>
Date: Feb 06 2024 16:14:26 +0000
Subject: [PATCH 14/17] Remove generated translation files


---

diff --git a/website/content/pages/pt/build.md b/website/content/pages/pt/build.md
deleted file mode 100644
index 07a5d3d..0000000
--- a/website/content/pages/pt/build.md
+++ /dev/null
@@ -1,32 +0,0 @@
-Title: Compilar
-
-Esta é a versão em português!
-
-### GNU/Linux and Mac OS
-
-1. Go to the project repository: [https://pagure.io/JShelter/webextension](https://pagure.io/JShelter/webextension).
-1. Download the desired branch, e.g. as zip archive.
-1. Unpack the zip archive.
-1. Run `git submodule update`
-1. Run `make`.
-	* You will need common software, such as `zip`, `wget`, `bash`, `awk`, `sed`.
-1. Import the extension to the browser.
-	* Firefox: [https://extensionworkshop.com/documentation/develop/temporary-installation-in-firefox/](https://extensionworkshop.com/documentation/develop/temporary-installation-in-firefox/)
-		* Use the file `jshelter_firefox.zip` created by `make`.
-	* Chromium-based browsers:
-		1. Open `chrome://extensions`.
-		1. Enable developper mode.
-		1. Click `Load unpacked`.
-		1. Import the `jshelter_chrome/` directory created by `make`.
-
-### Windows
-
-1. Install Windows Subsystem for Linux (WSL): [https://docs.microsoft.com/en-us/windows/wsl/install-win10](https://docs.microsoft.com/en-us/windows/wsl/install-win10).
-2. Go to the project repository: [https://pagure.io/JShelter/webextension](https://pagure.io/JShelter/webextension).
-3. Download the desired branch, e.g. as zip archive.
-4. Unpack the zip archive.
-5. Run `git submodule update`
-6. Open the JShelter project folder in WSL, run `make`.
-	* Make sure that `zip` and all other necessary tools are installed.
-	* Note that EOL in `fix_manifest.sh` must be set to `LF` (you can use the tool `dos2unix` in WSL to convert `CR LF` to `LF`).
-7. On Windows, import the extension to the browser according to the instructions for Linux (above).
diff --git a/website/content/pages/pt/home.md b/website/content/pages/pt/home.md
deleted file mode 100644
index 1050e5c..0000000
--- a/website/content/pages/pt/home.md
+++ /dev/null
@@ -1,122 +0,0 @@
-Title: Início
-Template: home
-URL:
-save_as: pt/index.html
-
-<section class="hero block">
-  <div class="hero-body">
-    <h3 class="has-text-centered">
-      jShelter
-    </h3>
-
-    <p class="has-text-centered">Uma extensão anti-malware para o seu browser, dedicada a mitigar potenciais ameaças via Javascript, como fingerprinting, tracking e armazenamento de dados pessoais!</p>
-
-    <div class="block has-text-centered">
-      <p>Instalar já</p>
-      <p class="buttons are-medium is-centered">
-        <a class="button" href="https://addons.mozilla.org/firefox/addon/javascript-restrictor/">
-          <i class="fa fa-firefox" aria-hidden="true"></i> Firefox
-        </a>
-        <a class="button" href="https://chrome.google.com/webstore/detail/javascript-restrictor/ammoloihpcbognfddfjcljgembpibcmb">
-          <i class="fa fa-chrome" aria-hidden="true"></i> Chrome
-        </a>
-        <a class="button" href="https://addons.opera.com/extensions/details/javascript-restrictor/">
-          <i class="fa fa-opera" aria-hidden="true"></i> Opera
-        </a>
-      </p>
-    </div>
-
-  </div><!-- /.hero-body -->
-</section><!-- /.hero -->
-
-
-<section id="about" class="block">
-  <div class="grid">
-    <article>
-      <header>
-        <h4>O que é o jShelter?</h4>
-      </header>
-      <div>
-        <p>Accessing cookies, performing fingerprinting to track users across
-        multiple sites, revealing the local network address, or capturing the
-        user's input before they submit a form are some examples of JavaScript's
-        capabilities that can be used in harmful ways.</p>
-      </div>
-    </article>
-    <article>
-      <header>
-        <h4>Como funciona?</h4>
-      </header>
-      <div>
-        <p>JavaScript Shield adds a
-        safety layer that allows the user to choose if a certain action should
-        be forbidden on a site, or if it should be allowed with restrictions,
-        such as reducing the precision of geolocation to the city area. This
-        layer can also aid as a countermeasure against attacks targeting the
-        browser, operating system or hardware levels.</p>
-      </div>
-    </article>
-    <article>
-      <header>
-        <h4>Qual é a diferença entre o jShelter e X, Y ou Z?</h4>
-      </header>
-      <div>
-        <p>Accessing cookies, performing fingerprinting to track users across
-        multiple sites, revealing the local network address, or capturing the
-        user's input before they submit a form are some examples of JavaScript's
-        capabilities that can be used in harmful ways.</p>
-      </div>
-    </article>
-    <article>
-      <header>
-        <h4>Quem está por trás deste projeto?</h4>
-      </header>
-      <div>
-        <p>Accessing cookies, performing fingerprinting to track users across
-        multiple sites, revealing the local network address, or capturing the
-        user's input before they submit a form are some examples of JavaScript's
-        capabilities that can be used in harmful ways.</p>
-      </div>
-    </article>
-  </div>
-</section>
-
-<section id="contribute" class="block">
-  <div class="grid">
-    <article>
-      <header>
-        <h4>Como posso ajudar?</h4>
-      </header>
-      <div>
-        <p>Accessing cookies, performing fingerprinting to track users across
-        multiple sites, revealing the local network address, or capturing the
-        user's input before they submit a form are some examples of JavaScript's
-        capabilities that can be used in harmful ways.</p>
-      </div>
-    </article>
-
-    <article>
-      <header>
-        <h4>Encontrei um bug!</h4>
-      </header>
-      <div>
-        <p>Accessing cookies, performing fingerprinting to track users across
-        multiple sites, revealing the local network address, or capturing the
-        user's input before they submit a form are some examples of JavaScript's
-        capabilities that can be used in harmful ways.</p>
-      </div>
-    </article>
-
-    <article>
-      <header>
-        <h4>Quais são os termos da licença?</h4>
-      </header>
-      <div>
-        <p>Accessing cookies, performing fingerprinting to track users across
-        multiple sites, revealing the local network address, or capturing the
-        user's input before they submit a form are some examples of JavaScript's
-        capabilities that can be used in harmful ways.</p>
-      </div>
-    </article>
-  </div>
-</section>
diff --git a/website/content/posts/pt/crawling.md b/website/content/posts/pt/crawling.md
deleted file mode 100644
index dd89524..0000000
--- a/website/content/posts/pt/crawling.md
+++ /dev/null
@@ -1,140 +0,0 @@
----
-title: Medição do uso de APIs JavaScript na web
----
-
-The world wide web is a complex environment. Web pages can access many APIs ranging from text formatting to access to nearby Bluetooth devices. While many APIs are used for legitimate purposes, some are misused to track and identify their users without their knowledge. In this paper, we propose a methodology to measure the usage of JavaScript APIs on the public web. The methodology consists of an automated visit of several thousand websites and intercepting JavaScript calls performed by the pages. We also provide a design and architecture of a measurement platform that can be used for an automated visit of a list of websites. The proposed platform is based on OpenWPM. The browser is instrumented by OpenWPM and a customized Web API Manager extension is responsible for capturing JavaScript API calls.
-
-## Introduction
-
-Web browsers offer a wide range of possibilities. on the surface
-they _just_ display web pages, but under the hood, web
-browsers provide a bridge between a viewed page and the host
-operating system. A web browser allows a web page to access information
-like values from sensors, information about battery status, installed
-fonts, and much more. The advertisement industry often takes advantage of
-the wide range of information provided by web browsers to create a web browser
-[fingerprint](https://amiunique.org/links). Most commonly, the fingeprinters misuse Web APIs (also
-called JavaScript APIs).
-
-This blog post is mainly concerned
-with user tracking and fingerprinting.
-For example Battery Status API implementation on Mozilla Firefox
-revealed very precise value allowing the trackers to identify the user
-for a [period of time](https://petsymposium.org/2017/papers/hotpets/batterystatus-not-included.pdf).
-As the Battery Status API was used heavily for fingerprinting, it
-has been removed from Mozilla Firefox in 2017. Other examples of
-JavaScript APIs that are used often for fingerprinting are [Canvas API](http://cseweb.ucsd.edu/~hovav/papers/ms12.html), [Audio API](https://senglehardt.com/papers/princeton_phd_dissertation_englehardt.pdf),
-[Permissions API](https://arxiv.org/abs/2008.04480) or [APIs for device sensors](https://dl.acm.org/doi/10.1145/3243734.3243860).
-
-In our work, we aim to measure the JavaScript APIs usage by popular
-websites. In this article, we present core technologies to accomplish
-these measurements. The stack of technologies is based on [OpenWPM](https://github.com/mozilla/OpenWPM)
-enriched by a browser extension, that allows us to intercept JavaScript
-calls of different APIs. This browser extension is based on Proxy
-objects.
-
-Our work is based on work of [Peter Snyders et al.](https://www3.cs.uic.edu/pub/Bits/PeterSnyder/Browser_Feature_Usage_on_the_Modern_Web.pdf)
-carried in 2016. Since then many new
-APIs were specified and implemented in web browsers, see the figure below
-(based on data from [Can I Use? website](https://caniuse.com/)).
-
-![Progress of Web APIs amount implemented in distinct browsers in time.]({attach}/images/crawling-apis.png)
-
-## Methodology proposal
-
-This section describes the methodology that we plan to use.
-This methodology is based on
-As it is based on the work of Peter Snyders, it is already validated.
-Moreover, using a methodology that is very close to the
-original one should show us a difference in the usage of the JavaScript
-APIs in 2016 and 2021.
-
-The main idea of the measurement is to visit several thousands of the
-most [popular pages](https://tranco-list.eu/#aboutus) on the internet and intercept as many JavaScript calls
-as possible.
-
-Visiting websites will be performed through Mozilla Firefox with
-an extension that intercepts and logs the JavaScript calls.
-We will visit not
-only the landing page but also the subset of subpages of each website.
-From the landing page, we will extract three links that point to
-a subpage of a given page. From each of these three subpages, we will
-get another three subpage links resulting in up to 13 pages of a given
-website being visited. This amount of pages should be high enough to
-catch the most of JavaScript calls.
-We will wait and intercept JavaScript
-calls for 30 seconds on each page to wait of API calls performed during the page load.
-
-Results of our measurements should also provide information about the
-JavaScript APIs, that were probably used in a manner, that is not
-necessary for a page to be working and is very likely used in a way,
-that the user would not find useful. To achieve this,
-
-We will run our
-measurements on every page in two different modes. Firstly, we will
-visit the page using the a browser withou adblocker. Later, we will also employ an adblocker.
-Hence, the study will show the difference API usage of regular pages and trackers.
-
-### The original study
-
-The Snyders' study suggests that some of the JavaScript APIs are
-extremely popular and they are used on more than 90% of measured pages
-(e.g. a well known `Document.createElement` method from DOM API). On the
-other hand, there are many APIs that are used by a minority of measured
-pages. That being said, almost 50% of JavaScript APIs implemented in the
-browser at the time were not used by any of the measured pages.
-
-The study also suggests that there is no direct connection between the
-implementation date of a given JavaScript API in the browser (or by its
-specification date by some of the specifications vendors) and its
-popularity in using by websites. Concretely, there are some old
-JavaScript APIs, such as `XMLHttpRequest` that are still very popular.
-However, there are also quite new
-JavaScript APIs, that are used very frequently (i.e., `Selectors API
-Level 1`).
-
-The conducted study also measured the pages in two ways - with the ad
-blocker and without any ad blocking extension. Results of measurements
-showed that the blocking of different JavaScript APIs is not uniform and
-some APIs are blocked more often than others. Specifically, 10% of
-JavaScript APIs were blocked in 90% of cases resulting in a fact that
-83% of APIs were used on less than 1% of websites when the page was
-visited with active blocking extension.
-
-### Web API Manager
-
-Web API Manager is a browser extension, that aims to block explicitly
-defined JavaScript APIs. It has been developed by Snyders in 2016 and
-used in several studies conducted by [Snyders et al.](https://www.peteresnyder.com/https://www.peteresnyder.com/).
-
-The original purpose of the Web API Manager is to block explicitly
-defined JavaScript APIs. However, in our measurements, we just need to
-intercept the API calls, log these calls and delegate the calls to
-original receivers.
-
-The main principle of Web API Manager is based on Proxy objects. This
-metaprogramming technique allows intercepting calls performed on
-objects. While the main goal of the Web API Manager extension is to
-block the calls performed on objects that belong to particular
-JavaScript APIs, our goal is only to intercept these operations and
-delegate them to their original receivers. We will use the Log Aggregator interface to log the API
-calls.
-
-To provide a Web API Manager the list of JavaScript APIs members we need
-a list of supported APIs. The APIs implemented in Mozilla Firefox are available as [IDL files](https://searchfox.org/mozilla-central/source/dom/webidl).
-
-### Measurement tools
-
-The figure below shows a simplified
-illustration of the measurement platform. There is OpenWPM in the middle of the
-architecture. OpenWPM orchestrates
-Selenium and Mozilla Firefox with the proxy-based intercepting Web API Manager.
-
-![image]({attach}/images/crawling-architecture.png)
-
-## The impact on JShelter
-
-Once we have data from our crawling study, we will compare the data with [another recent study](https://github.com/uiowa-irl/FP-Inspector/blob/master/Data/potential_fingerprinting_APIs.md). As already mentioned, we want to develop a fingerprinting detection based on  counting the number of different
-APIs employed by a page, especially APIs that are not frequently used for benign purposes. When
-a fingerprinting attempt is identified, we want to (1) inform the user, (2) prevent uploading of the
-fingerprint to the server, (3) prevent storing the fingerprint for later usage.
diff --git a/website/content/posts/pt/localportscanning.md b/website/content/posts/pt/localportscanning.md
deleted file mode 100644
index 7e07c7f..0000000
--- a/website/content/posts/pt/localportscanning.md
+++ /dev/null
@@ -1,84 +0,0 @@
----
-title: Como é que o jShelter impede terceiros de espiar as nossas aplicações locais?
----
-
-We recently found a [blog post](https://blog.nem.ec/2020/05/24/ebay-port-scanning/) about
-ThreatMetrix Inc. (a part of LexisNexis) scanning locally open ports for about 30,000 web
-sites, including eBay. The figure below shows that a browser tries to connect to ports commonly used for remote access to the computer (e.g., RDesktop, VNC, TeamViewer) and other applications.
-
-![A screenshot of the browser being used as a proxy to scan locally open ports](localportscanning/1_captured_traffic.png)
-
-The obvious question is, what is the reason for such behaviour? The simple answer is security. See
-additional links to [Security Boulevard](https://securityboulevard.com/2020/05/is-ebay-port-scanning-your-pc-probably/), [Avast](https://blog.avast.com/why-is-ebay-port-scanning-my-computer-avast), and [The register](https://www.theregister.com/2020/05/26/ebay_port_scans_your_pc/).
-
-One possibility is that ThreatMetrix creates a [fingerprint](https://arxiv.org/pdf/1905.01051.pdf), and locally running
-applications are a part of the fingerprint. Consequently, the authentication algorithm stores
-attributes about your device(s) and compare them during each log in with the previous values. Seeing
-that you are logging in using a previously seen device, the algorithm can let you in with just a
-password without additional proves. However, should you use a new device, the algorithm might decide that
-additional authentication steps are required and send you an SMS.
-
-Another option is that ThreatMetrix knows that many fraudulent activities occur on
-devices with specific ports open. Recall that the ports being checked concern remote desktop
-access. Having a remote desktop port open means that the computer may be used by an adversary that does not sit near the computer but is connected remotely. Consequently, the authentication algorithm might decide that additional proves about the user identity should be checked.
-
-We do not know what the real reason behind the scanning is. It might be one of the above, both, or a
-similar reason.
-
-## Ethical and legal issues
-
-Although it could be that the underlying intentions are benign and users actually do benefit from
-the scanning, the scanning raises some ethical issues.
-
-Very often, security and privacy are interconnected. But sometimes, one might increase security by
-revealing something private. In this case, ThreatMetrix learns information about the running device
-that is not obvious to the device owner (a user or a company). Typically, the owner of the device
-does not even know that such information can leak. If the information
-stays with ThreatMetrix, then the benefits could appear to be greater than the disadvantages.
-However, adversaries could stole information from ThreatMetrix (see for example the [Ecquifax breach](https://en.wikipedia.org/wiki/2017_Equifax_data_breach)) or the company can start to [sell](https://www.vice.com/en/article/qjdkq7/avast-antivirus-sells-user-browsing-data-investigation) the [information](https://www.pcmag.com/news/the-cost-of-avasts-free-antivirus-companies-can-spy-on-your-clicks) or even [share with others](https://brave.com/rtb-evidence/).
-
-So is the scanning and data collecting legal? As we are based in the EU, we will dig into the EU perspective. You might want to
-consult your local laws if you are outside the EU. Moreover, as we are not lawyers, you might want to
-consult one even in the EU.
-
-[EU ePrivacy Directive](https://eur-lex.europa.eu/legal-content/EN/ALL/?uri=CELEX:32002L0058) applies. However, as [WP29 clarified](https://ec.europa.eu/justice/article-29/documentation/opinion-recommendation/files/2014/wp224_en.pdf) (use case 7.5), user-centric security can be viewed as strictly necessary to provide
-the service. So it seems likely that port scanning for security reasons would
-trigger the ePrivacy exception and user consent is not necessary.
-
-As the port scanning is a part of the login mechanism, open ports are personal data
-without doubts. So GDPR also applies.
-GDPR also list security as a possible legitimate interest of a data controller (e.g. eBay), see
-recital 49. Nevertheless, if such a scan is proportionate is an open question; it is possible that the legitimate interests of data controllers (such as eBay) are overriden by the interests or fundamental rights and freedoms of the data subject (you), see Article(6)(1)(f).
-The Court of Justice of EU (CJEU) decided several issues that concerned legitimate interests and the necessity of processing, e.g. [C-13/16, point 30 that also points to other related cases](https://curia.europa.eu/juris/liste.jsf?num=C-13/16) or [C-708/18 points 40–45](https://curia.europa.eu/juris/liste.jsf?num=C-708/18). It might be possible that it is strictly necessary for eBay to perform local port scanning.
-
-Nevertheless, Article 12-14 of GDPR lists requirements on the information that a data controller should reveal
-to each data subject before the data processing starts or in a reasonable time afterwards. Hence, each controller employing ThreatMetrix should reveal, for example, in the privacy policy, what categories of data it is using and
-for which purposes. From the [linked](https://blog.avast.com/why-is-ebay-port-scanning-my-computer-avast) [articles](https://www.theregister.com/2020/05/26/ebay_port_scans_your_pc/), it seems that ThreatMetrix and eBay are secretive about data being collected.
-
-Another GDPR issue might be data transfers to third countries. Data transfers of open ports may not be
-compatible with GDPR in the light of the [CJEU C-311/18](https://curia.europa.eu/juris/liste.jsf?num=C-311/18) decision if the information leaves EEA.
-
-## Why is not my browser protecting me from remote servers accessing local information?
-
-OK, so even though the scanning could be legal, one can disagree that others should be allowed to sniff on
-local applications. So why does a browser leak the information?
-
-Well, the browser employs so called [same origin policy](https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy) (SOP) that in abstract theory should prevent websites from the scans in question. As your local computer is of a different origin from the remote website, your computer should be protected by SOP. Nevertheless, SOP has its limitations. First of all, some [cross-origin resource sharing](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) is beneficial, so the browser cannot block outgoing requests to other origins. Such behaviour opens possibilities for [side-channels](https://www.forcepoint.com/sites/default/files/resources/files/report-attacking-internal-network-en_0.pdf) to be identified. So even though the web page cannot communicate with applications on your computer (or in your network) without the cooperation of these applications, it can observe the behaviour and make some conclusions based on the observed errors, timing, etc.
-
-An (ad) blocker can prevent you from the activity. As the blockers typically leverage blocklists,
-such a port scanning script URL needs to match a rule in a block list. Once information about a
-misbehaving script becomes public, a rule can be added to a block list. However, this could take some time. Additional techniques like [DNS de-cloaking](https://blog.lukaszolejnik.com/large-scale-analysis-of-dns-based-tracking-evasion-broad-data-leaks-included/)
-need to be applied in this case.
-
-## Network Boundary Shield to the rescue
-
-JShelter contains a Network Boundary Shield (NBS) that blocks outgoing browser requests based on the observed behaviour, i.e. a
-page hosted on public internet tries to access local URLs.
-NBS just works and cannot be fooled by changes in the URL path, DNS cloaking or other techniques.
-
-![JShelter blocks the scan](localportscanning/2_request_blocked.png)
-
-Firefox contains DNS API, so NBS works flawlessly. In Chromium-based browsers, the exact blocking
-behaviour depends on how quickly a scanning script can fire the requests and the precise
-destination (IP address or a domain name). Depending on the interaction with DNS, NBS can be side-stepped on Chrome. In this case, ThreatMetrix does not try any evasion technique, so
-NBS just works in the case of eBay and ThreatMetrix.
diff --git a/website/content/posts/pt/support.md b/website/content/posts/pt/support.md
deleted file mode 100644
index 39b6458..0000000
--- a/website/content/posts/pt/support.md
+++ /dev/null
@@ -1,55 +0,0 @@
----
-title: Conseguimos o apoio do NGI0 PET Fund
----
-
-We are very happy to announce that the <a href="https://nlnet.nl/project/JSRestrictor/">JavaScript
-Restrictor received support from NGI0 PET Fund</a>, a fund established by NLnet with financial
-support from the European Commission's Next Generation Internet programme, under the aegis of DG
-Communications Networks, Content and Technology under grant agreement No 825310.
-
-We are very excited to improve the extension further. We will focus on the following main goals:
-
-### 1. Investigate fingerprinting scripts and prepare wrappers
-
-Review the previously identified APIs suitable for fingerprinting. Select APIs suitable for JShelter and
-add wrappers for these APIs. This work has already started, see issue #66. Additionally, we want to focus
-on identification of methods used for fingeprinting such as those identified by Iqbal et al., see
-https://uiowa-irl.github.io/FP-Inspector/
-
-### 2. Prevent unique identification of a device
-
-It is hard, if not impossible, to both prevent fingerprinting and still provide customized environment
-for the user. Hence, we want to identify fingerprinting attempts by counting the number of different
-APIs employed by a page, especially APIs that are not frequently used for benign purposes. When
-a fingerprinting attempt is identified, we want to (1) inform the user, (2) prevent uploading of the
-fingerprint to the server, (3) prevent storing the fingerprint for later usage.
-
-### 3. Code ported from Chrome Zero
-
-In version 0.3, we integrated features of Chrome Zero 7 as it is no longer maintained. By
-integrating the functionality to JShelter, we want to keep the counter-meassures available in a
-maintained extension. However, we do not have sufficient tests for the functionality.
-
-### 4. Evaluation and porting of code from Brave
-
-Brave browser currently implements anti-fingerprinting techniques that aim at providing little lies
-about the browser environment. We want to evaluate the messures and select techniques that are
-suitable for JShelter.
-
-### 5. Fixing known bugs
-
-We want to focus on the proposed changes and found bugs that are reported in the GitHub bug tracker.
-
-* We already closed issues #53, #62, and #72 as a part of this project. The fixes are already available as
-	a part of the 0.4 subversions.
-* We want to also deal with issues #56 and #71 that are crucial for the success of the extension.
-* We will focus on other identified bugs in the wrappers or developped techniques.
-
-### 6. Cooperation with the Privacy Shield project
-
-We are also excited to announce that we found other partners that are willing to work on our code
-base through the NGI0 PET Fund, <a href="https://nlnet.nl/project/JavascriptShield/">Privacy Shield
-project run by Free Software Foundation</a>. Expect inclusion of code that will help to defend your
-freedoms and provide anti-malware protections. This cooperation should also improve the GUI of the
-extension and create explenatory web pages explaining the functionality and its risks. It is
-possible that the project will be rebranded as a result of the cooperation.

From ed8ea9bd9e3ee75dfaff4b9affac95afa579d1fe Mon Sep 17 00:00:00 2001
From: Ricardo Lafuente <r@manufacturaindependente.org>
Date: Feb 06 2024 16:14:41 +0000
Subject: [PATCH 15/17] Merge branch 'website-i18n' into website


---

diff --git a/chrome/manifest.json b/chrome/manifest.json
index c8bef2c..fa2c343 100644
--- a/chrome/manifest.json
+++ b/chrome/manifest.json
@@ -1,5 +1,5 @@
 {
-  "author": "Libor Polčák, Martin Bednář, Martin Timko, Pavel Pohner, Peter Horňák, Matúš Švancár, Giorgio Maone, Marek Saloň, Radek Hranický, Martin Zmitko",
+  "author": "Libor Polčák, Giorgio Maone, Martin Timko, Pavel Pohner, Peter Horňák, Matúš Švancár, Marek Saloň, Martin Bednář, Radek Hranický, Martin Zmitko",
   "background": {
       "scripts": [
         "nscl/lib/browser-polyfill.js",
@@ -92,5 +92,5 @@
   ],
   "optional_permissions": ["browsingData"],
   "short_name": "JShelter",
-  "version": "0.16"
+  "version": "0.17"
 }
diff --git a/common/_locales/cs/messages.json b/common/_locales/cs/messages.json
index 55d48f4..c22bd59 100644
--- a/common/_locales/cs/messages.json
+++ b/common/_locales/cs/messages.json
@@ -1116,16 +1116,25 @@
 		"message": "Vestavěné úpravy pro JavaScriptový štít",
 		"description": "Displayed in expert settings, heading for the table of built-in tweaks"
 	},
-	"JSSBuiltinExceptionsAppliedTo": {
-		"message": "Týká se jen úrovně $LEVEL_NAME$, pro více informací navštivte:",
-		"description": "Displayed in expert settings, text explaining what level is changed",
-		"placeholders": {
-			"level_name": {
-				"content": "$1",
-				"description": "The name of the level to which the exception applies, do not translate",
-				"example": "See JSSL*Name, e.g. Recommended"
-			}
-		}
+	"JSSBuiltinExceptionsDomain": {
+		"message": "Doména",
+		"description": "Displayed in expert settings, heading in the table of built-in tweaks"
+	},
+	"JSSBuiltinExceptionsLevels": {
+		"message": "Úrovně",
+		"description": "Displayed in expert settings, heading in the table of built-in tweaks"
+	},
+	"JSSBuiltinExceptionsLevelsSeparator": {
+		"message": ", ",
+		"description": "Displayed in expert settings, separator for levels displayed"
+	},
+	"JSSBuiltinExceptionsChanges": {
+		"message": "Změny",
+		"description": "Displayed in expert settings, heading in the table of built-in tweaks"
+	},
+	"JSSBuiltinExceptionsReason": {
+		"message": "Vysvětlení",
+		"description": "Displayed in expert settings, heading in the table of built-in tweaks"
 	},
 
 	"protectionConfigurationOptionActivatedOn": {
@@ -1540,6 +1549,14 @@
 		"message": "Zjisti volající skripty",
 		"description": "Button caption. The purpose of the button is to reload the page while injecting additional scripts that track the location of the callers. This functionality needs to be on demand as it is performance heavy."
 	},
+	"FPDReportTrackCallersRestart": {
+		"message": "Znovu spusť zjišťování volajících skriptů",
+		"description": "Button caption. The purpose of the button is to reload the page while injecting additional scripts that track the location of the callers. This functionality needs to be on demand as it is performance heavy."
+	},
+	"FPDReportTrackCallersWaiting": {
+		"message": "Zjišťuji volající skripty. Prosím, počkejte chvíli.",
+		"description": "Text displayed inside FPD report to explain what is happening."
+	},
 	"FPDReportTrackCallersFailed": {
 		"message": "Není možné zjistit volající skripty kvůli chybě. $errorFromBrowser$",
 		"description": "Prefix strings that intoroduces an error strings generated by the browser. Shown when action started by clicking on button with text of FPDReportTrackCallers failed.",
@@ -1551,6 +1568,14 @@
 			}
 		}
 	},
+	"FPDReportForgetTraces": {
+		"message": "Nezobrazuj současné volající",
+		"description": "Button caption"
+	},
+	"FPDReportRefresh": {
+		"message": "Aktualizuj zprávu",
+		"description": "Button caption"
+	},
 	"FPDReportExportJSON": {
 		"message": "Exportuj úplnou zprávu jako JSON",
 		"description": "Button caption"
diff --git a/common/_locales/en/messages.json b/common/_locales/en/messages.json
index 001d803..a76af1a 100644
--- a/common/_locales/en/messages.json
+++ b/common/_locales/en/messages.json
@@ -1119,16 +1119,25 @@
 		"message": "Built-in tweaks for JavaScript Shield",
 		"description": "Displayed in expert settings, heading for the table of built-in tweaks"
 	},
-	"JSSBuiltinExceptionsAppliedTo": {
-		"message": "Applied only to level $LEVEL_NAME$, for more details, see:",
-		"description": "Displayed in expert settings, text explaining what level is changed",
-		"placeholders": {
-			"level_name": {
-				"content": "$1",
-				"description": "The name of the level to which the exception applies, do not translate",
-				"example": "See JSSL*Name, e.g. Recommended"
-			}
-		}
+	"JSSBuiltinExceptionsDomain": {
+		"message": "Domain",
+		"description": "Displayed in expert settings, heading in the table of built-in tweaks"
+	},
+	"JSSBuiltinExceptionsLevels": {
+		"message": "Levels",
+		"description": "Displayed in expert settings, heading in the table of built-in tweaks"
+	},
+	"JSSBuiltinExceptionsLevelsSeparator": {
+		"message": ", ",
+		"description": "Displayed in expert settings, separator for levels displayed"
+	},
+	"JSSBuiltinExceptionsChanges": {
+		"message": "Changes",
+		"description": "Displayed in expert settings, heading in the table of built-in tweaks"
+	},
+	"JSSBuiltinExceptionsReason": {
+		"message": "Reason",
+		"description": "Displayed in expert settings, heading in the table of built-in tweaks"
 	},
 
 	"protectionConfigurationOptionActivatedOn": {
@@ -1543,6 +1552,14 @@
 		"message": "Track calling scripts",
 		"description": "Button caption. The purpose of the button is to reload the page while injecting additional scripts that track the location of the callers. This functionality needs to be on demand as it is performance heavy."
 	},
+	"FPDReportTrackCallersRestart": {
+		"message": "Restart tracking calling scripts",
+		"description": "Button caption. The purpose of the button is to reload the page while injecting additional scripts that track the location of the callers. This functionality needs to be on demand as it is performance heavy."
+	},
+	"FPDReportTrackCallersWaiting": {
+		"message": "Detection of calling scripts in progress. Wait a moment, please.",
+		"description": "Text displayed inside FPD report to explain what is happening."
+	},
 	"FPDReportTrackCallersFailed": {
 		"message": "Cannot track calling scripts due to an error. $errorFromBrowser$",
 		"description": "Prefix strings that intoroduces an error strings generated by the browser. Shown when action started by clicking on button with text of FPDReportTrackCallers failed.",
@@ -1554,6 +1571,14 @@
 			}
 		}
 	},
+	"FPDReportForgetTraces": {
+		"message": "Hide current callers",
+		"description": "Button caption"
+	},
+	"FPDReportRefresh": {
+		"message": "Refresh report",
+		"description": "Button caption"
+	},
 	"FPDReportExportJSON": {
 		"message": "Export full FPD Report as JSON",
 		"description": "Button caption"
diff --git a/common/common.css b/common/common.css
index 32cfb74..2e764d0 100644
--- a/common/common.css
+++ b/common/common.css
@@ -13,7 +13,7 @@
 	--light-logo-contrast: #333333; /* Very dark grey */
 	--dark-logo: #e76f51; /* Logo dark red */
 	--dark-logo-contrast: white;
-	--help-icon-color: white;  
+	--help-icon-color: white;
 	--help-icon-background: blue;
 	--title-color: var(--dark-logo);
 	--good-news: darkgreen; /* Combine with background color */
@@ -22,6 +22,7 @@
 	--button-text-color: black;
 	--button-background-active-color: var(--light-logo);
 	--button-text-active-color: black;
+	--button-text-disabled-color: #888;
 	--button-background-hover-color: #c9c9c9; /* low dark grey */
 	--button-text-hover-color: black;
 	--menu-color: blue;
@@ -29,6 +30,7 @@
 	--attention-color: var(--dark-logo-contrast);
 	--attention-background: var(--dark-logo);
 	--slider-bg-color: white;
+	--slider-text-color: black;
 	--slider-off-color: gray;
 	--slider-on-color: var(--light-logo);
 	--slider-text-color: black;
@@ -39,7 +41,7 @@
 		--text-color: #e8e6e3; /* Almost white */
 		--background-color: #181a1b; /* Very very dark grey */
 		--background-color-input: var(--background-color);
-		--help-icon-color: blue;  
+		--help-icon-color: blue;
 		--help-icon-background: white;
 		--title-color: var(--light-logo);
 		--good-news: lightgreen;
@@ -72,7 +74,11 @@ button {
 	color: var(--button-text-color);
 }
 
-button:hover {
+button:disabled {
+	color: var(--button-text-disabled-color);
+}
+
+button:hover:not(:disabled) {
 	cursor: pointer;
 	background-color: var(--button-background-hover-color);
 	color: var(--button-text-hover-color);
@@ -181,7 +187,7 @@ a:hover, a:active {
 	background-color: var(--slider-bg-color);
 	-webkit-transition: .4s;
 	transition: .4s;
-	color: var(--off-color);
+	color: var(--slider-text-color);
 	content:"__MSG_ShieldOffSlider__";
 }
 
diff --git a/common/fp_report.css b/common/fp_report.css
index aa6c829..945ab7b 100644
--- a/common/fp_report.css
+++ b/common/fp_report.css
@@ -45,7 +45,7 @@ h4 {
 	color: var(--title-color);
 }
 
-.fpd-group > .fpd-group  {
+.fpd-group   .fpd-group  {
 	padding-left: 2em;
 	border-left: 2px solid #aaa;
 }
diff --git a/common/fp_report.html b/common/fp_report.html
index 8795bc5..a593e9e 100644
--- a/common/fp_report.html
+++ b/common/fp_report.html
@@ -50,6 +50,8 @@ SPDX-License-Identifier: GPL-3.0-or-later
 			Export full FPD Report as JSON
 		</button>
 		<button id="trackCallersBtn" class="sticky-button" data-localize="FPDReportTrackCallers">Track callers</button>
+		<button id="forgetCurrentBtn" class="sticky-button hidden" data-localize="FPDReportForgetTraces">Forget</button>
+		<button id="updateReportBtn" class="sticky-button hidden" data-localize="FPDReportRefresh">Update</button>
 		<span class="alert" id="fpdError"></span>
 		<div id="fpd-report">
 		</div>
diff --git a/common/fp_report.js b/common/fp_report.js
index 4798d25..f9f44e3 100644
--- a/common/fp_report.js
+++ b/common/fp_report.js
@@ -21,6 +21,8 @@
 //  along with this program.  If not, see <https://www.gnu.org/licenses/>.
 //
 
+let hiddenTraces = {};
+
 /**
  * Event listener that listens for a load of FPD report page. If the page is loaded, fetch FPD data from background.
  *
@@ -79,6 +81,8 @@ function createReport(data) {
 			if (groups.all[group].description) {
 				html += "<div id=\"" + group + "\" class=\"fpd-group access\">";
 				html += "<h2>" + group + "</h2>";
+				html += `<button class="help" id="expand${group}" >⤵</button>`;
+				html += "<section>";
 				html += "<p>" + groups.all[group].description + "</p>";
 			}
 			for (let [item, type] of Object.entries(groups.all[group].items)) {
@@ -90,7 +94,7 @@ function createReport(data) {
 				}
 			}
 			if (groups.all[group].description) {
-				html += "</div>";
+				html += "</section></div>";
 			}
 		}
 	}
@@ -103,17 +107,16 @@ function createReport(data) {
 				for (let t of Object.values(fpDb[resource])) {
 					let traces = Object.keys(t.callers);
 					for (trace of traces) {
-						if (trace !== "") {
-							callers += "<br><br>" + trace;
+						if (trace !== "" && !(trace in hiddenTraces)) {
+							callers += "<p>" + trace.replace(/\n/g, '<br>') + "</p>";
 						}
 					}
 				}
 			}
-			callers = callers.replace(/\n/g, '<br>');
 			let accessRaw = processedEvals[resource].total;
 			let accessCount = accessRaw >= 1000 ? "1000+" : accessRaw;
-			html += `<h4 class="hidden ${accessRaw > 0 ? "access" : "no-access"}"><span class="dot">-</span> ` +
-			`${resource} (${exceptionWrappers.includes(resource) ? "n/a" : accessCount})\n${callers}</h4>`;
+			html += `<div class="details ${accessRaw > 0 ? "access" : "no-access"}"><h4><span class="dot">-</span> ` +
+			`${resource} (${exceptionWrappers.includes(resource) ? "n/a" : accessCount})</h4>\n${callers}</div>`;
 		}
 	}
 
@@ -127,7 +130,7 @@ function createReport(data) {
 	for (let i = groupElements.length; i > 0; i--) {
 		// remove duplicit entries from groups
 		let duplicitArray = [];
-		let elements = groupElements[i-1].querySelectorAll(":scope > h4");
+		let elements = groupElements[i-1].querySelectorAll(":scope > section > div.details > h4");
 		elements.forEach((d) => {
 			if (duplicitArray.indexOf(d.innerHTML) > -1) {
 				d.remove();
@@ -138,49 +141,45 @@ function createReport(data) {
 		});
 
 		// hide groups with no relevant entries
-		if (!document.querySelectorAll(`#${groupElements[i-1].id} > .access`).length) {
+		if (!document.querySelectorAll(`#${groupElements[i-1].id} > section > .access`).length) {
 			groupElements[i-1].classList.replace("access", "no-access");
 		}
 	}
 
 	// function that enables to show accessed resources of the group
-	let toggleResources = (event) => {
+	function toggleResources(event) {
 		let parent =  event.target.parentElement;
 		for (let i = 0; i < parent.children.length; i++) {
 			let child = parent.children[i];
-			if (child.tagName == "H4") {
+			if (child.tagName == "SECTION") {
 				child.classList.toggle("hidden");
 			}
 		}
 	}
 
 	// make group name clickable only if it makes sense - groups with resources
-	let makeClickableTitles = () => {
+	function makeGroupExpansionsClickable() {
 		for (let element of document.querySelectorAll(".fpd-group")) {
 			let button;
-			let haveChild = false;
 
 			for (let i = 0; i < element.children.length; i++) {
 				let child = element.children[i];
-				if (child.tagName == "H2") {
+				if (child.tagName == "BUTTON") {
 					button = child;
 				}
-				if (child.tagName == "H4" && !child.classList.contains("no-access")) {
-					haveChild = true;
-				}
 			}
 
-			if (button && haveChild) {
+			if (button) {
 				button.classList.add("clickable");
 				button.addEventListener("click", toggleResources);
 			}
 		}
 	}
-	makeClickableTitles();
+	makeGroupExpansionsClickable();
 
 	// show resources for every group in FPD report
 	let showAll = (event) => {
-		for (let element of document.querySelectorAll(".fpd-group > h4")) {
+		for (let element of document.querySelectorAll(".fpd-group div.details")) {
 			element.classList.remove("hidden");
 		}
 		showBtn.classList.add("hidden");
@@ -189,28 +188,40 @@ function createReport(data) {
 
 	// hide resources for every group in FPD report
 	let hideDetails = (event) => {
-		for (let element of document.querySelectorAll(".fpd-group > h4")) {
+		for (let element of document.querySelectorAll(".fpd-group div.details")) {
 			element.classList.add("hidden");
 		}
 		showBtn.classList.remove("hidden");
 		hideBtn.classList.add("hidden");
 	}
+	hideDetails();
+
+	// refresh data in the report
+	function refreshReport() {
+		browser.runtime.sendMessage({
+			purpose: "fpd-get-report-data",
+			tabId: tabId
+		}).then((result) => {
+			createReport(result);
+			showAll();
+		});
+		browser.runtime.sendMessage({purpose: "fpd-track-callers-stop"});
+		document.getElementById("updateReportBtn").classList.remove("hidden");
+		document.getElementById("forgetCurrentBtn").classList.remove("hidden");
+		let trackCallersBtn = document.getElementById("trackCallersBtn");
+		trackCallersBtn.innerText = browser.i18n.getMessage("FPDReportTrackCallersRestart");
+		trackCallersBtn.classList.remove("hidden");
+	}
 
 	// Reload the report with data on the identity of the calling scripts
 	function trackCallers() {
 		tabId = new URLSearchParams(window.location.search).get("id");
 		function onReloaded() {
-			function refresh() {
-				browser.runtime.sendMessage({
-					purpose: "fpd-get-report-data",
-					tabId: tabId
-				}).then((result) => {
-					createReport(result);
-					showAll();
-				});
-				browser.runtime.sendMessage({purpose: "fpd-track-callers-stop"});
-			}
-			setInterval(refresh, 5000);
+			setTimeout(refreshReport, 5000);
+			report.innerHTML = browser.i18n.getMessage("FPDReportTrackCallersWaiting");
+			document.getElementById("trackCallersBtn").classList.add("hidden");
+			document.getElementById("updateReportBtn").classList.add("hidden");
+			document.getElementById("forgetCurrentBtn").classList.add("hidden");
 		}
 		function onError(error) {
 			document.getElementById("fpdError").innerHTML = browser.i18n.getMessage("FPDReportTrackCallersFailed", error);
@@ -222,12 +233,26 @@ function createReport(data) {
 		}).then(onReloaded, onError);
 	}
 
+	function updateReport() {
+	}
+
 	// show all groups/resources even if not accessed
 	let showNotAccessed = () => {
 		for (let element of document.querySelectorAll(".no-access")) {
 			element.classList.remove("no-access");
 		}
-		makeClickableTitles();
+		makeGroupExpansionsClickable();
+	}
+
+	function forgetTraces() {
+		for (resource of Object.values(fpDb)) {
+			for (type of Object.values(resource)) {
+				for (trace of Object.keys(type.callers)) {
+					hiddenTraces[trace] = true;
+				}
+			}
+		}
+		createReport(data);
 	}
 
 	// create on-site JSON representation of FPD evaluation data and download it
@@ -249,6 +274,8 @@ function createReport(data) {
 	document.getElementById("hideBtn").onclick = hideDetails;
 	document.getElementById("exportBtn").onclick = exportReport.bind(null, `fpd_report_${url}.json`);
 	document.getElementById("trackCallersBtn").onclick = trackCallers;
+	document.getElementById("forgetCurrentBtn").onclick = forgetTraces;
+	document.getElementById("updateReportBtn").onclick = refreshReport;
 	document.getElementById("unhideAll").onclick = showNotAccessed;
 }
 
diff --git a/common/levels.js b/common/levels.js
index 014feb3..1786695 100644
--- a/common/levels.js
+++ b/common/levels.js
@@ -932,8 +932,8 @@ function updateLevels(res) {
 	default_level.is_default = true;
 	var redefined_domains = res["domains"] || {};
 	for (let [d, settings] of Object.entries(tweak_domains)) {
-		if ((settings.level_id === default_level.level_id) && !(d in redefined_domains)) {
-			redefined_domains[d] = settings;
+		if ((default_level.level_id in settings.level_id) && !(d in redefined_domains)) {
+			redefined_domains[d] = {level_id: default_level.level_id, tweaks: settings.tweaks};
 		}
 	}
 	for (let [d, {level_id, tweaks, restore, restore_tweaks}] of Object.entries(redefined_domains)) {
@@ -983,27 +983,9 @@ function saveDomainLevels() {
 		if (k[k.length - 1] === ".") {
 			k = k.substring(0, k.length-1);
 		}
-		// Do not save built-in tweaks as they are automatically added in updateLevels
-		if (k in tweak_domains) {
-			// Skip further check if the user has a different default_level
-			if (tweak_domains[k].level_id === default_level.level_id) {
-				tdb_tweaks = Object.entries(tweak_domains[k].tweaks);
-				current_tweaks = Object.entries(domains[k].tweaks);
-				if (tdb_tweaks.length === current_tweaks.length) {
-					var equal = true;
-					for ([name, val] of tdb_tweaks) {
-						if (domains[k].tweaks[name] !== val) {
-							equal = false;
-							break;
-						}
-					}
-					if (equal) {
-						// This entry should not be saved
-						continue;
-					}
-				}
-			}
-		}
+		// Tweaks not contain the new value defined by the user. However, that might
+		// be the value of the level. Remove such tweaks as they to not change the
+		// level of protection
 		if (tweaks) {
 			for (let [group, param] of Object.entries(tweaks)) {
 				if (param === (levels[level_id][group] || 0)) {
@@ -1013,6 +995,27 @@ function saveDomainLevels() {
 			if (Object.keys(tweaks).length === 0) {
 				tweaks = undefined;
 			}
+			// Do not save built-in tweaks as they are automatically added in updateLevels
+			if (k in tweak_domains) {
+				// Skip further check if the user has a different default_level
+				if (default_level.level_id in tweak_domains[k].level_id) {
+					tdb_tweaks = Object.entries(tweak_domains[k].tweaks);
+					current_tweaks = Object.entries(tweaks || {});
+					if (tdb_tweaks.length === current_tweaks.length) {
+						var equal = true;
+						for ([name, val] of tdb_tweaks) {
+							if (tweaks[name] !== val) {
+								equal = false;
+								break;
+							}
+						}
+						if (equal) {
+							// This entry should not be saved
+							continue;
+						}
+					}
+				}
+			}
 		}
 		tobesaved[k] = tweaks ? {level_id, tweaks} : {level_id};
 		if (restore) {
diff --git a/common/options.css b/common/options.css
index ce75664..130900f 100644
--- a/common/options.css
+++ b/common/options.css
@@ -259,3 +259,18 @@ fieldset {
 form {
 	margin: 2em;
 }
+
+#builtin-jss-tweaks {
+	display: grid;
+	grid-template-columns: auto auto auto auto;
+	column-gap: 3em;
+	row-gap: 3ex;
+}
+
+#builtin-jss-tweaks span {
+	text-align: left;
+}
+
+#builtin-jss-tweaks .tweak_domain {
+	color: var(--title-color);
+}
diff --git a/common/options_advanced.js b/common/options_advanced.js
index d8f0488..ce2641b 100644
--- a/common/options_advanced.js
+++ b/common/options_advanced.js
@@ -73,24 +73,31 @@ document.getElementById("levels-storage-undo").addEventListener("click", async f
 });
 
 window.addEventListener("DOMContentLoaded", function() {
-	function appendElement(type, innerHtml) {
+	function appendElement(innerText, type="span") {
 		let el = document.createElement(type);
-		el.innerHTML = innerHtml;
+		el.innerText = innerText;
 		parent.appendChild(el);
 		return el;
 	}
 	let parent = document.getElementById("builtin-jss-tweaks");
+	if (Object.keys(tweak_domains_builtin).length > 0) {
+		appendElement(browser.i18n.getMessage("JSSBuiltinExceptionsDomain"), "h4");
+		appendElement(browser.i18n.getMessage("JSSBuiltinExceptionsLevels"), "h4");
+		appendElement(browser.i18n.getMessage("JSSBuiltinExceptionsChanges"), "h4");
+		appendElement(browser.i18n.getMessage("JSSBuiltinExceptionsReason"), "h4");
+	}
 	for ([d, settings] of Object.entries(tweak_domains_builtin)) {
-		appendElement("h4", d);
-		appendElement("p", browser.i18n.getMessage("JSSBuiltinExceptionsAppliedTo",
-			levels[settings.level_id].level_text) + ` <a href="${settings.explanation}">${settings.explanation}</a>`);
-		var currentTweaksEl = appendElement("div", "");
+		appendElement(d).classList.add("tweak_domain");
+		appendElement((settings.level_id.map((id) => levels[id].level_text)).join(browser.i18n.getMessage("JSSBuiltinExceptionsLevelsSeparator")));
+		let currentTweaksEl = appendElement("", "div");
 		currentTweaksEl.classList.add("tweakgrid");
 		let tweaksBusiness = Object.create(tweaks_gui);
 		tweaksBusiness.get_current_tweaks = function() {
 			return settings.tweaks;
 		};
 		tweaksBusiness.create_tweaks_html(currentTweaksEl);
+		let reasonEl = appendElement(settings.explanation, "a");
+		reasonEl.href = settings.explanation;
 	}
 });
 
diff --git a/common/popup.js b/common/popup.js
index 272afc4..a7d7adb 100644
--- a/common/popup.js
+++ b/common/popup.js
@@ -119,7 +119,7 @@ function enableRefreshIfNeeded() {
 /**
  * Save level settings for current page, show correct button
  */
-function modify_level(level, levelButton) {
+function modify_level(level, levelButton, forceUpdateLevels = false) {
 	if (level) {
 		current_level = level;
 		saveDomainLevels();
@@ -127,7 +127,16 @@ function modify_level(level, levelButton) {
 			changeActiveLevel(levelButton);
 		}
 		update_level_info();
-		update_tweaks();
+		if (forceUpdateLevels) {
+			function refresh() {
+				current_level = getCurrentLevelJSON("https://" + site);
+				update_tweaks();
+			}
+			browser.storage.sync.get(null).then(updateLevels).then(refresh);
+		}
+		else {
+			update_tweaks();
+		}
 	}
 }
 
@@ -207,7 +216,7 @@ function add_level_buttons() {
 	default_lev_button = addButton({level_id: "DEFAULT", level_description: browser.i18n.getMessage("popupDefaultLevelHelpText"), level_text: browser.i18n.getMessage("defaultLevelSelection", default_level.level_text)});
 	default_lev_button.addEventListener("click", ev => {
 		delete domains[site];
-		modify_level(default_level, ev.target);
+		modify_level(default_level, ev.target, true); // We need to force update config to display built-in tweaks
 	});
 	// Load built-in and custom levels
 	for (let level_id in levels) {
diff --git a/common/settings_tweaks.js b/common/settings_tweaks.js
index c7e0d71..314e042 100644
--- a/common/settings_tweaks.js
+++ b/common/settings_tweaks.js
@@ -23,14 +23,14 @@
 var tweak_domains_builtin = {
 	"docs.google.com": {
 		"explanation": "https://pagure.io/JShelter/webextension/issue/122",
-		"level_id": "2",
+		"level_id": ["1", "2"],
 		"tweaks": {
 			"webworker": 2
 		}
 	},
 	"app.mediafire.com": {
 		"explanation": "https://github.com/polcak/jsrestrictor/issues/207",
-		"level_id": "2",
+		"level_id": ["1", "2"],
 		"tweaks": {
 			"webworker": 2
 		}
diff --git a/firefox/manifest.json b/firefox/manifest.json
index fac16f1..485c933 100644
--- a/firefox/manifest.json
+++ b/firefox/manifest.json
@@ -1,5 +1,5 @@
 {
-  "author": "Libor Polčák, Martin Bednář, Martin Timko, Pavel Pohner, Peter Horňák, Matúš Švancár, Giorgio Maone, Marek Saloň, Radek Hranický, Martin Zmitko",
+  "author": "Libor Polčák, Giorgio Maone, Martin Timko, Pavel Pohner, Peter Horňák, Matúš Švancár, Marek Saloň, Martin Bednář, Radek Hranický, Martin Zmitko",
   "background": {
       "scripts": [
         "nscl/lib/browser-polyfill.js",
@@ -92,7 +92,7 @@
   ],
   "optional_permissions": ["browsingData"],
   "short_name": "JShelter",
-  "version": "0.16",
+  "version": "0.17",
   "browser_specific_settings": {
     "gecko": {
         "id": "jsr@javascriptrestrictor",
diff --git a/tests/integration_tests/testing/web_browser.py b/tests/integration_tests/testing/web_browser.py
index 7831b3b..0989f6c 100644
--- a/tests/integration_tests/testing/web_browser.py
+++ b/tests/integration_tests/testing/web_browser.py
@@ -96,15 +96,23 @@ class Browser:
                     self._jsr_options_page = elem.text.split(',')[2].split('=')[1][:-1] + "options.html"
         if self.type == BrowserType.CHROME:
             self.driver.get('chrome://system/')
-            WebDriverWait(self.driver, 10).until(
-                ec.presence_of_element_located((By.ID, 'expandAll'))
-            )
-            self.driver.find_element(By.ID, 'expandAll').click()
+            try:
+                WebDriverWait(self.driver, 2).until(
+                    ec.presence_of_element_located((By.ID, 'expandAll'))
+                )
+                self.driver.find_element(By.ID, 'expandAll').click()
+            except:
+                self.driver.find_elements(By.TAG_NAME, 'system-app')[0].shadow_root.find_elements(By.CSS_SELECTOR, 'button')[0].click()
             sleep(1)
             try:
                 extensions = self.driver.find_element(By.ID, 'div-extensions-value')
             except NoSuchElementException:
-                extensions = self.driver.find_element(By.ID, 'extensions-value')
+                try:
+                    extensions = self.driver.find_element(By.ID, 'extensions-value')
+                except NoSuchElementException:
+                    system_app = self.driver.find_elements(By.TAG_NAME, 'system-app')[0].shadow_root
+                    log_entry = system_app.find_elements(By.CSS_SELECTOR, 'log-entry')[5].shadow_root
+                    extensions = log_entry.find_elements(By.CLASS_NAME, 'stat-value')[0]
             for elem in extensions.text.splitlines():
                 if 'JShelter' in elem:
                     self._jsr_options_page = "chrome-extension://" + elem.split(':')[0][:-1] + "/options.html"
diff --git a/tests/unit_tests/README.md b/tests/unit_tests/README.md
index 2fe916e..95d3f5b 100644
--- a/tests/unit_tests/README.md
+++ b/tests/unit_tests/README.md
@@ -2,7 +2,7 @@ Title: Instructions on how to run unit tests
 
 #### on Linux
 
-1. Install NodeJS ([https://nodejs.org]()).
+1. Install [NodeJS](https://nodejs.org).
 2. Install `jq` and another necessary tools (e.g. `sed`).
 3. Open Terminal.
 4. Run `npm install`.
diff --git a/website/.gitignore b/website/.gitignore
new file mode 100644
index 0000000..5ff575d
--- /dev/null
+++ b/website/.gitignore
@@ -0,0 +1,5 @@
+# ignore auto-generated translations
+content/pages/*/*
+content/posts/*/*
+content/wrappers/*/*
+i18n/*/
diff --git a/website/Makefile b/website/Makefile
index 48cd818..5d534df 100644
--- a/website/Makefile
+++ b/website/Makefile
@@ -52,37 +52,45 @@ install:
 extract:
 	$(ACTIVATE); python extract_comments.py
 
-html: extract
+translate:
+	$(ACTIVATE); cd i18n; ./download.sh; ./translate_content.sh; for f in `ls ../content/posts/pt/*.md`; do ./postprocess.py $$f; done; for f in `ls ../content/pages/pt/*.md`; do ./postprocess.py $$f; done; for f in `ls ../content/wrappers/*.md`; do ./postprocess.py $$f; done
+
+html: extract 
 	cp ../tests/integration_tests/README.md content/pages/integration_tests.md
 	cp ../tests/unit_tests/README.md content/pages/unit_tests.md
 	mkdir -p output/ output/.well-known/
 	cp -r theme/favicon.ico output/
 	cp -r theme/security.txt output/.well-known/
 	$(ACTIVATE); python extract_comments.py
-	$(ACTIVATE); $(PELICAN) "$(INPUTDIR)" -o "$(OUTPUTDIR)" -s "$(CONFFILE)" $(PELICANOPTS)
+	$(PELICAN) "$(INPUTDIR)" -o "$(OUTPUTDIR)" -s "$(CONFFILE)" $(PELICANOPTS)
 	# fix translated indexes to address a Pelican bug
-	cd content/pages; for lang in */; do mv ../../output/$$lang/$$lang/index.html ../../output/$$lang; rm -f ../../output/$$lang/$$lang/index.html; done
+	# cd content/pages; for lang in */; do mv ../../output/$$lang/$$lang/index.html ../../output/$$lang; rm -f ../../output/$$lang/$$lang/index.html; done
+
+build: translate html
 
 clean:
 	[ ! -d "$(OUTPUTDIR)" ] || rm -rf "$(OUTPUTDIR)"
+	rm -fr content/pages/pt
+	rm -fr content/posts/pt
+	rm -fr content/wrappers/pt
 
 regenerate:
-	$(ACTIVATE); $(PELICAN) -r "$(INPUTDIR)" -o "$(OUTPUTDIR)" -s "$(CONFFILE)" $(PELICANOPTS)
+	$(PELICAN) -r "$(INPUTDIR)" -o "$(OUTPUTDIR)" -s "$(CONFFILE)" $(PELICANOPTS)
 
 serve:
-	$(ACTIVATE); $(PELICAN) -l "$(INPUTDIR)" -o "$(OUTPUTDIR)" -s "$(CONFFILE)" $(PELICANOPTS)
+	$(PELICAN) -l "$(INPUTDIR)" -o "$(OUTPUTDIR)" -s "$(CONFFILE)" $(PELICANOPTS)
 
 serve-global:
-	$(ACTIVATE); $(PELICAN) -l "$(INPUTDIR)" -o "$(OUTPUTDIR)" -s "$(CONFFILE)" $(PELICANOPTS) -b $(SERVER)
+	$(PELICAN) -l "$(INPUTDIR)" -o "$(OUTPUTDIR)" -s "$(CONFFILE)" $(PELICANOPTS) -b $(SERVER)
 
 devserver:
-	$(ACTIVATE); $(PELICAN) -lr "$(INPUTDIR)" -o "$(OUTPUTDIR)" -s "$(CONFFILE)" $(PELICANOPTS)
+	$(PELICAN) -lr "$(INPUTDIR)" -o "$(OUTPUTDIR)" -s "$(CONFFILE)" $(PELICANOPTS)
 
 devserver-global:
-	$(ACTIVATE); $(PELICAN) -lr $(INPUTDIR) -o $(OUTPUTDIR) -s $(CONFFILE) $(PELICANOPTS) -b 0.0.0.0
+	$(PELICAN) -lr $(INPUTDIR) -o $(OUTPUTDIR) -s $(CONFFILE) $(PELICANOPTS) -b 0.0.0.0
 
 publish:
-	$(ACTIVATE); $(PELICAN) "$(INPUTDIR)" -o "$(OUTPUTDIR)" -s "$(PUBLISHCONF)" $(PELICANOPTS)
+	$(PELICAN) "$(INPUTDIR)" -o "$(OUTPUTDIR)" -s "$(PUBLISHCONF)" $(PELICANOPTS)
 
 deploy: html
 	rsync -e "ssh -p 22" -P -rvzc output/ root@jshelter.org:/var/www/html/ --cvs-exclude
diff --git a/website/README.md b/website/README.md
index 2a29b9f..d985f73 100644
--- a/website/README.md
+++ b/website/README.md
@@ -11,16 +11,6 @@ Before starting, it's important to keep in mind that:
   directly -- edit the original source comments instead (inside the `common/`
   project directory)
 
-## Adding new pages
-
-## Translating content
-
-Translated content goes inside the subfolders of the `content/` directory using
-the language code. For instance, pages translated to Spanish should be placed
-inside `content/pages/es/`, taking care to keep the file names and the metadata
-names (e.g. `Title:`) intact. The site generator will gather the files and put
-them in their place inside the site structure.
-
 ## Generating the site
 
 To make a local copy of the web site, follow these steps:
@@ -29,3 +19,42 @@ To make a local copy of the web site, follow these steps:
 2. Generate the site with `make html`
 3. Run the local webserver with `make serve` and go to `http://localhost:8000`
    in your browser
+
+## Adding new pages
+
+TODO
+
+## Translating
+
+The JShelter website uses [Weblate](https://hosted.weblate.org) to manage translations. The `website/i18n/` directory contains a set of scripts to automate translation management, and the website build process (`make html`) runs these to synchronise the most recent updates to the translations on Weblate. Translators shouldn't need to worry about the internals as the build process should take care of everything; for more involved operations such as adding languages, updating the source files and others, here is a rundown of the translation pipeline.
+
+### 1. Generate the translation source files
+
+The `build_po_files.sh` script scans the Markdown content files and groups all the strings into `.po` files. The files are placed inside the `website/i18n/en/` directory. This process uses the `md2po` command from the [mdpo](https://mondeja.github.io/mdpo/latest/) Markdown parsing package.
+
+This step is necessary when there are changes to the source content (e.g. updating a post or page) to make sure the new strings will show up on the Weblate interface.
+
+NOTE/TODO: Uploading the `.po` files to Weblate needs to be done manually through the Weblate web UI. We intend to automate this part but there are a couple of bugs to deal with to make this feasible.
+
+### 2. Download the latest translations
+
+The `download.sh` script takes care of pulling the latest version of each available translation. The resulting `.po` files are placed inside the `website/i18n/<lang>/` directory, where `<lang>` is the language 2-letter code.
+
+### 3. Generate translated files
+
+The `translate_content.sh` script uses the `po2md` command from the [mdpo](https://mondeja.github.io/mdpo/latest/) package to generate translated Markdown files from the `.po` translation sources obtained in the previous step. The resulting files can be found inside the content directory: it creates a directory with the language code inside each section dir (`website/content/pages`, `website/content/posts` and `website/content/wrappers`).
+
+### 4. Post-process translated files
+
+The conversion process mangles the YAML frontmatter (there is an [open issue](https://github.com/mondeja/mdpo/issues/228) about this), so we perform some simple post-process to restore the proper formatting using the `postprocess.py` script.
+
+Currently the script runs on a single file outputting the result to stdout. The full set of files can be processed as in the website build `Makefile`:
+
+```bash
+for f in `ls ../content/pages/*.md`
+  do ./postprocess.py $f
+done
+```
+
+Note that this example only processes the `pages` section; just repeat it on the `posts` and `wrappers` dir to post-process the full set of translated files.
+
diff --git a/website/content/pages/coding-style.md b/website/content/pages/coding-style.md
index 39013f1..18219ac 100644
--- a/website/content/pages/coding-style.md
+++ b/website/content/pages/coding-style.md
@@ -60,7 +60,7 @@ function example(abc)
   find it before merge, it is better to fix the bug in the original commit.
   Available Git operations for this are `rebase (-i)`, `fixup`, `squash` and
   `push --force`.
-- This [pull request]() contains an example of big commits that needed to be refactored.
+- This pull request (FIXME: need to find link) contains an example of big commits that needed to be refactored.
 - Provide merge request more often rather than commiting big changes. If you fix
   Makefile or other scripts, provide the change and do not wait. Create code
   that is understandable and does not repeat itself. If possible, use variables
diff --git a/website/content/pages/faq.md b/website/content/pages/faq.md
index 430c376..0e2ab87 100644
--- a/website/content/pages/faq.md
+++ b/website/content/pages/faq.md
@@ -1,5 +1,5 @@
 Title: Frequently Asked Questions
-Slug: faq
+
 [TOC]
 
 ### Project information
diff --git a/website/content/pages/fpd.md b/website/content/pages/fpd.md
index 35de520..0927bbb 100644
--- a/website/content/pages/fpd.md
+++ b/website/content/pages/fpd.md
@@ -1,5 +1,4 @@
 Title: Fingerprint Detector
-Slug: fpd
 
 Fingerprint Detector (FPD) provides heuristic analysis of fingerprinting
 behaviour. FPD monitors APIs that are commonly used by fingerprinters and
diff --git a/website/content/pages/levels.md b/website/content/pages/levels.md
index f5377b0..ad3791d 100644
--- a/website/content/pages/levels.md
+++ b/website/content/pages/levels.md
@@ -1,6 +1,4 @@
----
 Title: JavaScript Shield
----
 
 JavaScript Shield modifies the behaviour of the JavaScript environment availble for the visited webpage. JShelter provides fake information to confuse fingerprinters or make webpage triggered attacks impossible or harder.
 
diff --git a/website/content/pages/nbs.md b/website/content/pages/nbs.md
index 55b1141..bb80cba 100644
--- a/website/content/pages/nbs.md
+++ b/website/content/pages/nbs.md
@@ -1,5 +1,4 @@
 Title: Network Boundary Shield
-Slug: nbs
 
 The Network Boundary Shield (NBS) is a protection against attacks from an
 external network (the Internet) to an internal network - especially against a
diff --git a/website/content/pages/versions.md b/website/content/pages/versions.md
index 26e8061..df4f128 100644
--- a/website/content/pages/versions.md
+++ b/website/content/pages/versions.md
@@ -1,6 +1,18 @@
----
-title: Release history
----
+Title: Release history
+
+## 0.17
+
+* Added support for built-in tweaks for specific domains. The goal is to list several domains that
+  break unnecessarily. Typically, an addition to the list should be well explained and must not
+  lower protection. A nice candidate is WebWorker and the protection of Strict (break) and Remove.
+* Updated translations
+* Improved FPD report based on user feedback:
+ * Do not refresh report automatically when tracking callers but introduce an update button so that
+   users refresh when convenient (prevent glitches in the interfaces)
+ * Add buttons to hide/show details and fold/unfold groups
+ * Do not show traces in bold to better differentiate between API names and traces.
+ * Add possibility to forget current traces. Useful when there is a fingerprinting script that activates after some action. The button allows the user to hide the traces triggered in the past and later load only new traces.
+* Add support for [signing for Android on AMO](https://blog.mozilla.org/addons/2023/10/05/changes-to-android-extension-signing/), so we needed to increase minimal supported version
 
 ## 0.16
 
diff --git a/website/content/posts/cooperation.md b/website/content/posts/cooperation.md
index d94619c..733706d 100644
--- a/website/content/posts/cooperation.md
+++ b/website/content/posts/cooperation.md
@@ -1,8 +1,6 @@
----
-title: Cooperation with the JShelter project, rebranding, and latest features
-date: 2022-03-17 15:00
+Title: Cooperation with the JShelter project, rebranding, and latest features
+Date: 2022-03-17 15:00
 Series: JShelter background
----
 
 This project started as JavaScript Restrictor at [Brno University of
 Technology](https://www.fit.vut.cz). As announced in [a previous post](/support), we got funding
diff --git a/website/content/posts/crawling.md b/website/content/posts/crawling.md
index a9d117f..df047fa 100644
--- a/website/content/posts/crawling.md
+++ b/website/content/posts/crawling.md
@@ -1,8 +1,6 @@
----
-title: Measurement of JavaScript API usage on the web
-date: 2021-03-30 14:00
+Title: Measurement of JavaScript API usage on the web
+Date: 2021-03-30 14:00
 Series: JavaScript API usage
----
 
 The world wide web is a complex environment. Web pages can access many APIs ranging from text formatting to access to nearby Bluetooth devices. While many APIs are used for legitimate purposes, some are misused to track and identify their users without their knowledge. In this paper, we propose a methodology to measure the usage of JavaScript APIs on the public web. The methodology consists of an automated visit of several thousand websites and intercepting JavaScript calls performed by the pages. We also provide a design and architecture of a measurement platform that can be used for an automated visit of a list of websites. The proposed platform is based on OpenWPM. The browser is instrumented by OpenWPM and a customized Web API Manager extension is responsible for capturing JavaScript API calls.
 
diff --git a/website/content/posts/crawling_results.md b/website/content/posts/crawling_results.md
index 1aa367b..f061cac 100644
--- a/website/content/posts/crawling_results.md
+++ b/website/content/posts/crawling_results.md
@@ -1,8 +1,6 @@
----
-title: "RESULTS: Measurement of JavaScript API usage on the web"
-date: 2022-01-14 12:00
+Title: "RESULTS: Measurement of JavaScript API usage on the web"
+Date: 2022-01-14 12:00
 Series: JavaScript API usage
----
 
 A [previous blogpost](/crawling/) introduced a methodology to measure the usage of JavaScript APIs on the web by crawling the web. 
 The starting point of our web crawling research is the [work of Peter Snyder](https://www.peteresnyder.com/static/papers/improving-web-privacy-and-security-thesis.pdf). Most importantly,  we wanted to compare the differences in JS API usage between browsers with and without privacy extension (e.g., uBlock Origin). We have finished the development of the [crawling tool](https://github.com/martinbednar/web_crawler). We crawled thousands of websites and collected JavaScript calls on the visited web pages.
diff --git a/website/content/posts/farbling.md b/website/content/posts/farbling.md
index ca95b31..7fd6f32 100644
--- a/website/content/posts/farbling.md
+++ b/website/content/posts/farbling.md
@@ -1,6 +1,5 @@
----
-title: Farbling-based wrappers to hinder browser fingerprinting
-date: 2021-08-23 09:00
+Title: Farbling-based wrappers to hinder browser fingerprinting
+Date: 2021-08-23 09:00
 Series: Browser fingerprinting
 ---
 
diff --git a/website/content/posts/fingerprinting.md b/website/content/posts/fingerprinting.md
index bd9cfc3..7c50396 100644
--- a/website/content/posts/fingerprinting.md
+++ b/website/content/posts/fingerprinting.md
@@ -1,10 +1,8 @@
----
-title: Browser fingerprinting and JShelter
-date: 2022-01-14 13:00
-modified: 2023-04-14 14:00
+Title: Browser fingerprinting and JShelter
+Date: 2022-01-14 13:00
+Modified: 2023-04-14 14:00
 Series: Browser fingerprinting
 series_index: 1
----
 
 This post introduces [browser fingerprinting](https://arxiv.org/pdf/1905.01051.pdf) and anti-fingerprinting mechanisms. We explain what JShelter implements and the strengths and downsides of the anti-fingerprinting mechanisms.
 
diff --git a/website/content/posts/fpdetection.md b/website/content/posts/fpdetection.md
index 07a02ec..ab73bb8 100644
--- a/website/content/posts/fpdetection.md
+++ b/website/content/posts/fpdetection.md
@@ -1,8 +1,6 @@
----
-title: Catch websites red-handed fingerprinting your browser
-date: 2022-01-14 14:00
+Title: Catch websites red-handed fingerprinting your browser
+Date: 2022-01-14 14:00
 Series: Browser fingerprinting
----
 
 We want to identify [fingerprinting](/fingerprinting/) attempts by counting the number of different APIs employed by a page, especially those not frequently used for benign purposes. This blog post introduces a new fingerprinting protection mechanism - FingerPrint Detector (FPD) available in JShelter 0.6. This tool allows users to gain more control over browser fingerprinting, which has become an invisible threat to our privacy.
 
diff --git a/website/content/posts/i18n.md b/website/content/posts/i18n.md
index ad72b69..3f75dd4 100644
--- a/website/content/posts/i18n.md
+++ b/website/content/posts/i18n.md
@@ -1,9 +1,7 @@
----
-title: JShelter can be translated into different languages
-date: 2023-09-08 14:00
+Title: JShelter can be translated into different languages
+Date: 2023-09-08 14:00
 Series: i18n
 series_index: 1
----
 
 JShelter's audience is international. As not all people speak English, JShelter
 is now adding support for internationalization. Hence, it can be translated
diff --git a/website/content/posts/i18n_developers.md b/website/content/posts/i18n_developers.md
index c215370..ecfd1d9 100644
--- a/website/content/posts/i18n_developers.md
+++ b/website/content/posts/i18n_developers.md
@@ -1,8 +1,6 @@
----
-title: What should a JShelter developer know about internationalization?
-date: 2023-08-31 15:00
+Title: What should a JShelter developer know about internationalization?
+Date: 2023-08-31 15:00
 Series: i18n
----
 
 We are working to improve the internationalization of JShelter. While the webextension API already contains [APIs](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/i18n) for internationalization, not everything works great. This post is written for webextension developers as well as JShelter developers working with strings presented to our users. Please see our [other post](/i18n/) if you are looking for ways to translate JShelter.
 
diff --git a/website/content/posts/jsrfinal.md b/website/content/posts/jsrfinal.md
index d47a631..4810500 100644
--- a/website/content/posts/jsrfinal.md
+++ b/website/content/posts/jsrfinal.md
@@ -1,8 +1,6 @@
----
-title: Final remarks on the JSR project
-date: 2022-05-10 18:00
+Title: Final remarks on the JSR project
+Date: 2022-05-10 18:00
 Series: JShelter background
----
 
 The [JavaScript Restrictor](https://nlnet.nl/project/JSRestrictor/) ([JSR](/support/)) project (supported by [NGI0 PET
 Fund](https://nlnet.nl/PET), a fund established by [NLnet](https://nlnet.nl/) with financial support
diff --git a/website/content/posts/localportscanning.md b/website/content/posts/localportscanning.md
index 060e8b6..dbd3f58 100644
--- a/website/content/posts/localportscanning.md
+++ b/website/content/posts/localportscanning.md
@@ -1,7 +1,5 @@
----
-title: How JShelter prevents other parties from sniffing on your local applications?
-date: 2021-06-15 09:00
----
+Title: How JShelter prevents other parties from sniffing on your local applications?
+Date: 2021-06-15 09:00
 
 We recently found a [blog post](https://blog.nem.ec/2020/05/24/ebay-port-scanning/) about
 ThreatMetrix Inc. (a part of LexisNexis) scanning locally open ports for about 30,000 web
diff --git a/website/content/posts/mv3.md b/website/content/posts/mv3.md
index dc087b3..4768629 100644
--- a/website/content/posts/mv3.md
+++ b/website/content/posts/mv3.md
@@ -1,8 +1,6 @@
----
-title: What is Manifest v3 and how it affects JShelter
-date: 2023-11-01 12:00
+Title: What is Manifest v3 and how it affects JShelter
+Date: 2023-11-01 12:00
 Series: Manifest v3
----
 
 Over the years, privacy and security-oriented browser extensions in the same category of JShelter (e.g. uBlock or NoScript, whose code is
 partially inherited by JShelter through the NoScript Commons Library),
diff --git a/website/content/posts/optimizations.md b/website/content/posts/optimizations.md
index 42862e9..a497e14 100644
--- a/website/content/posts/optimizations.md
+++ b/website/content/posts/optimizations.md
@@ -1,7 +1,5 @@
----
-title: Recent improvements in JShelter performance
-date: 2023-09-21 15:00
----
+Title: Recent improvements in JShelter performance
+Date: 2023-09-21 15:00
 
 You might have noticed that [recent versions](/versions/#015/) improved JShelter performance. This
 blog post explains the improvements in more detail and contains graphs. The improvements are based on the [bachelor thesis of Martin Zmitko](https://www.vut.cz/en/students/final-thesis/detail/147218). If you are interested in this topic, you will find more information in the thesis. We thank Martin for his work and his proposals.
diff --git a/website/content/posts/paper2022.md b/website/content/posts/paper2022.md
index 7dcfeed..4da4317 100644
--- a/website/content/posts/paper2022.md
+++ b/website/content/posts/paper2022.md
@@ -1,8 +1,6 @@
----
-title: Paper about JShelter
-date: 2022-04-05 00:00
+Title: Paper about JShelter
+Date: 2022-04-05 00:00
 Series: JShelter background
----
 
 We recently submitted a position paper about JShelter for [CNIL Privacy Research Day 2022](https://www.cnil.fr/en/privacy-research-day-2022) and posted the paper on [arXive](https://arxiv.org/abs/2204.01392). If you are interested in the project or if you are already using JShelter, we recommend reading the paper as it explains the project, its historical decisions, the thread model, design decision, experiments, and provides more information that you should know if you want to use JShelter correctly, or, you might decide that JShelter is not the correct tool for you and you might pick one of the alternative tools referenced in the paper.
 
diff --git a/website/content/posts/sensorapi.md b/website/content/posts/sensorapi.md
index 37c639e..56b7366 100644
--- a/website/content/posts/sensorapi.md
+++ b/website/content/posts/sensorapi.md
@@ -1,8 +1,6 @@
----
-title: Protection against fingerprinting with Generic Sensor API
-date: 2022-05-06 15:34
+Title: Protection against fingerprinting with Generic Sensor API
+Date: 2022-05-06 15:34
 Series: Browser fingerprinting
----
 
 Today devices contain [various sensors](https://www.researchgate.net/publication/224170986_A_survey_of_mobile_phone_sensing_IEEE_Commun_Mag) for reading information about the device's position, state, and environment. Such equipment is typical for mobile devices like cellphones, tablets, or laptops that often include sensors for obtaining geolocation or device orientation data. Another example is a smartwatch that could monitor the heartbeat rate of the wearer, or a car with a tire pressure sensor, etc. While the benefits of having sensors are undisputed, allowing websites to access their readings represents a considerable danger.
 
diff --git a/website/content/posts/support.md b/website/content/posts/support.md
index 652d312..9bcba6c 100644
--- a/website/content/posts/support.md
+++ b/website/content/posts/support.md
@@ -1,8 +1,6 @@
----
-title: We received support from NGI0 PET Fund
-date: 2021-03-30 09:00
+Title: We received support from NGI0 PET Fund
+Date: 2021-03-30 09:00
 Series: JShelter background
----
 
 We are very happy to announce that the <a href="https://nlnet.nl/project/JSRestrictor/">JavaScript
 Restrictor received support from NGI0 PET Fund</a>, a fund established by NLnet with financial
diff --git a/website/i18n/build_po_files.sh b/website/i18n/build_po_files.sh
new file mode 100755
index 0000000..918a49a
--- /dev/null
+++ b/website/i18n/build_po_files.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+#
+# Generates .po files from the original Markdown source files.
+#
+
+mkdir -p en
+
+for f in ../content/pages/*.md; do
+  md2po --quiet \
+    --po-encoding=UTF-8 $f --save --merge-po-files --po-filepath en/pages.po \
+    -d "Content-Type: text/plain; charset=utf-8" 
+  # -d ”Language: es”
+done
+
+for f in ../content/posts/*.md; do
+  md2po --quiet \
+    --po-encoding=UTF-8 $f --save --merge-po-files --po-filepath en/posts.po \
+    -d "Content-Type: text/plain; charset=utf-8" 
+  # -d ”Language: es”
+done
+
+for f in ../content/wrappers/*.md; do
+  md2po --quiet \
+    --po-encoding=UTF-8 $f --save --merge-po-files --po-filepath en/wrappers.po \
+    -d "Content-Type: text/plain; charset=utf-8" 
+  # -d ”Language: es”
+done
diff --git a/website/i18n/download.sh b/website/i18n/download.sh
new file mode 100755
index 0000000..543bd70
--- /dev/null
+++ b/website/i18n/download.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+#
+# Updates the local translation files with the most recent Weblate versions.
+#
+
+for lang in `ls -d */ | sed 's/\///' | grep -v '^en$'`; do
+  echo $lang
+  wlc download jshelter/website/$lang >| $lang/pages.po
+  wlc download jshelter/website-posts/$lang >| $lang/posts.po
+  wlc download jshelter/website-wrappers/$lang >| $lang/wrappers.po
+done
diff --git a/website/i18n/postprocess.py b/website/i18n/postprocess.py
new file mode 100755
index 0000000..6d232b4
--- /dev/null
+++ b/website/i18n/postprocess.py
@@ -0,0 +1,49 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Apply some post-processing to deal with broken 
+# lines in the Markdown frontmatter in the Weblate
+# translated files. Accepts a file as argument and
+# overwrites it with the processed version.
+
+import sys
+
+FIELDNAMES = ["Series", "series_index", "Date", "Modified"]
+
+with open(sys.argv[1], 'r') as f:
+    lines = f.readlines()
+
+# first pass: join all lines
+raw_frontmatter = ""
+for line in lines:
+    if not line.strip():
+        break
+    raw_frontmatter += line.strip() + ' '
+
+# remove header markup if present
+if raw_frontmatter.startswith('# '):
+    raw_frontmatter = raw_frontmatter.replace('# ', '', 1)
+if raw_frontmatter.startswith('## '):
+    raw_frontmatter = raw_frontmatter.replace('## ', '', 1)
+if raw_frontmatter.startswith('### '):
+    raw_frontmatter = raw_frontmatter.replace('### ', '', 1)
+
+# second pass: break lines on field names
+output = raw_frontmatter
+for name in FIELDNAMES:
+    tag = name + ": "
+    if tag in raw_frontmatter:
+        output = output.replace(tag, '\n' + tag)
+
+# now combine frontmatter and content
+output += '\n'
+frontmatter_ended = False
+for line in lines:
+    if not line.strip():
+        frontmatter_ended = True
+    if not frontmatter_ended:
+        continue
+    output += line
+
+with open(sys.argv[1], 'w') as f:
+    f.write(output)
diff --git a/website/i18n/translate_content.sh b/website/i18n/translate_content.sh
new file mode 100755
index 0000000..4033099
--- /dev/null
+++ b/website/i18n/translate_content.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+#
+# Generates translated content files from the .po sources
+
+for lang in `ls -d */ | sed 's/\///' | grep -v '^en$'`; do
+  for section in 'pages' 'posts' 'wrappers'; do
+    mkdir -p ../content/$section/$lang # /content/pages/pt
+    echo "Translating $section for language $lang..."
+    for f in `ls ../content/$section/*.md`; do
+       # echo $f
+       po2md $f -p $lang/$section.po >| ${f/$section/$section\/$lang}
+    done
+  done
+done
diff --git a/website/requirements.txt b/website/requirements.txt
index d7f793b..1f49218 100644
--- a/website/requirements.txt
+++ b/website/requirements.txt
@@ -3,3 +3,5 @@ Markdown>=3.3.4
 comment-parser>=1.2.3
 jinja2>=3.0
 pelican-series>=2.1.0
+mdpo==1.1.4
+wlc==1.13

From 5b31ea2d0cfcedd2f61cbd0eb94f5c0c761abb70 Mon Sep 17 00:00:00 2001
From: Ricardo Lafuente <r@manufacturaindependente.org>
Date: Feb 06 2024 16:15:42 +0000
Subject: [PATCH 16/17] Don't download new translations on site build


---

diff --git a/website/Makefile b/website/Makefile
index 5d534df..cd54ae4 100644
--- a/website/Makefile
+++ b/website/Makefile
@@ -66,7 +66,7 @@ html: extract
 	# fix translated indexes to address a Pelican bug
 	# cd content/pages; for lang in */; do mv ../../output/$$lang/$$lang/index.html ../../output/$$lang; rm -f ../../output/$$lang/$$lang/index.html; done
 
-build: translate html
+build: html
 
 clean:
 	[ ! -d "$(OUTPUTDIR)" ] || rm -rf "$(OUTPUTDIR)"

From 573727854aaa3b3c06ef9cf1150d2d074c2e912f Mon Sep 17 00:00:00 2001
From: Ricardo Lafuente <r@manufacturaindependente.org>
Date: Feb 06 2024 16:16:19 +0000
Subject: [PATCH 17/17] Merge branch 'web-copy-review' into website


---

diff --git a/website/content/pages/credits.md b/website/content/pages/credits.md
index 8aeb1ca..fe3571c 100644
--- a/website/content/pages/credits.md
+++ b/website/content/pages/credits.md
@@ -4,40 +4,74 @@ Title: Credits
 
 ### Developers
 
-**[Libor Polčák](https://www.fit.vutbr.cz/~polcak)** was behind an idea to implement a webextension that works as a firewall for JavaScript APIs. He is the current main maintainer. He received support for this project through the <a href="https://nlnet.nl/project/JSRestrictor/">JavaScript Restrictor</a> project of NGI0 PET Fund, a fund established by NLnet with financial support from the European Commission's Next Generation Internet programme, under the aegis of DG Communications Networks, Content and Technology under grant agreement No 825310. He supervised/supervises diploma theses that improve the web extension.
-
-**Giorgio Maone** is working on the extension as a part of the [JS Shield project](https://nlnet.nl/project/JavascriptShield/), for example, he is working on cross-browser support, improvements on code injection and the compatibility between the global JS environment, Workers, and iframes.
-
-**Zbyněk Červinka** developed a [proof-of-concept version](https://github.com/cervinka-zbynek/masters-thesis) of this extension as a part of his [master's thesis](https://www.fit.vut.cz/study/thesis/21274/) (in Czech).
-
-**Martin Timko** developed first public versions upto [0.2.1](https://pagure.io/JShelter/webextension/archive/0.2.1/webextension-0.2.1.zip) as a part of his [master's thesis](https://www.fit.vut.cz/study/thesis/21824/). He also ported the extension to Chrome and Opera.
-
-**Martin Bednář** developed test suites of the extension as a part of his
-[master's thesis](https://www.fit.vut.cz/study/thesis/22376/) and continued to work on the extension for some
-time afterwards. He also fixed some bugs found during the testing.
-
-**Pavel Pohner** developed the Network Boundary Scanner as a part of his [master's thesis](https://www.fit.vut.cz/study/thesis/22377/).
-
-**Pater Horňák** ported functionality from [Chrome Zero](https://github.com/IAIK/ChromeZero) as a part of his [bachelor thesis](https://www.fit.vut.cz/study/thesis/22374/). He also provided several small fixes to the code base.
-
-**Matúš Švancár** ported Farbling anti-fingerprinting measures from the Brave browser as a part of his [master's thesis](https://www.fit.vut.cz/study/thesis/23310/).
-
-**Marek Saloň** created Fingerprint Detector as a part of his [master's thesis](https://www.fit.vut.cz/study/thesis/23645/) and later improved the detector.
+**[Libor Polčák](https://www.fit.vutbr.cz/~polcak)** is behind the idea to
+implement a web extension that works as a firewall for JavaScript APIs. He is
+the current lead maintainer of JShelter. He received support for this project
+through the <a href="https://nlnet.nl/project/JSRestrictor/">JavaScript
+Restrictor</a> project of NGI0 PET Fund, a fund established by NLnet with
+financial support from the European Commission's Next Generation Internet
+programme, under the aegis of DG Communications Networks, Content and
+Technology under grant agreement No 825310. He supervised/supervises diploma
+theses that improve the web extension.
+
+**Giorgio Maone** is working on the extension as a part of the [JS Shield
+project](https://nlnet.nl/project/JavascriptShield/). Among other efforts, he is
+working on cross-browser support, improvements on code injection and the
+compatibility between the global JS environment, Workers, and iframes.
+
+**Zbyněk Červinka** developed a [proof-of-concept
+version](https://github.com/cervinka-zbynek/masters-thesis) of the extension
+as a part of his [master's thesis](https://www.fit.vut.cz/study/thesis/21274/)
+(in Czech).
+
+**Martin Timko** developed the first public versions up to
+[0.2.1](https://pagure.io/JShelter/webextension/archive/0.2.1/webextension-0.2.1.zip)
+as a part of his [master's thesis](https://www.fit.vut.cz/study/thesis/21824/).
+He also ported the extension to Chrome and Opera.
+
+**Martin Bednář** developed test suites as a part of his [master's
+thesis](https://www.fit.vut.cz/study/thesis/22376/) and continued to work on
+the project for some time afterwards. He also fixed some bugs found during the
+testing.
+
+**Pavel Pohner** developed the Network Boundary Scanner as a part of his
+[master's thesis](https://www.fit.vut.cz/study/thesis/22377/).
+
+**Pater Horňák** ported functionality from [Chrome
+Zero](https://github.com/IAIK/ChromeZero) as a part of his [bachelor
+thesis](https://www.fit.vut.cz/study/thesis/22374/). He also provided several
+small fixes to the code base.
+
+**Matúš Švancár** ported Farbling anti-fingerprinting measures from the Brave
+browser as a part of his [master's
+thesis](https://www.fit.vut.cz/study/thesis/23310/).
+
+**Marek Saloň** created Fingerprint Detector as a part of his [master's
+thesis](https://www.fit.vut.cz/study/thesis/23645/) and later improved the
+detector.
 
 **Radek Hranický** created sensor API wrappers.
 
-**Martin Zmitko** improved performance of the extension as a part of his bachelor thesis. He fixed
-some bugs during the process.
+**Martin Zmitko** improved performance of the extension as a part of his
+bachelor thesis. He fixed some bugs during the process.
 
-We thank all other minor contributors of the project that are not listed in this section.
+We thank all other minor contributors of the project that are not listed in
+this section.
 
 ### Key ideas
 
-The development of this extension is influenced by the paper [JavaScript Zero: Real JavaScript and Zero Side-Channel Attacks](https://graz.pure.elsevier.com/de/publications/javascript-zero-real-javascript-and-zero-side-channel-attacks). It appeared during the work of Zbyněk Červinka and provided basically the same approach to restrict APIs as was at the time developed by Zbyněk Červinka.
+The development of this extension is influenced by the paper [JavaScript Zero:
+Real JavaScript and Zero Side-Channel
+Attacks](https://graz.pure.elsevier.com/de/publications/javascript-zero-real-javascript-and-zero-side-channel-attacks).
+It appeared during the work of Zbyněk Červinka and provided basically the same
+approach to restrict APIs as was at the time developed by Zbyněk Červinka.
 
-The [Force Point report](https://www.forcepoint.com/sites/default/files/resources/files/report-attacking-internal-network-en_0.pdf) was a key inspiration for the development of the Network Boundary Shield.
+The [Force Point
+report](https://www.forcepoint.com/sites/default/files/resources/files/report-attacking-internal-network-en_0.pdf)
+was a key inspiration for the development of the Network Boundary Shield.
 
-Some of the fingerprinting counter-measures are inspired by [Farbling of the Brave browser](blogarticles/farbling.md).
+Some of the fingerprinting counter-measures are inspired by [Farbling of the
+Brave browser](blogarticles/farbling.md).
 
 ### Borrowed code
 
diff --git a/website/content/pages/home.md b/website/content/pages/home.md
index 47c8554..88787e2 100644
--- a/website/content/pages/home.md
+++ b/website/content/pages/home.md
@@ -40,12 +40,12 @@ URL:
         <h4>What is JShelter?</h4>
       </header>
       <div>
-        <p>JShelter is a browser extension to give back control over what your
+        <p>JShelter is a browser extension to give you control over what your
         browser is doing. A JavaScript-enabled web page can access much of the
         browser's functionality, with little control over this process available
         to the user: malicious websites can uniquely identify you through
         fingerprinting and use other tactics for tracking your activity.
-        JShelter aims to improve the privacy and security of your web
+        JShelter improves the privacy and security of your web
         browsing. For more details, see JShelter <a href="/threatmodel/">threat model</a>.</p>
       </div>
     </article>
@@ -70,7 +70,8 @@ URL:
       </header>
       <div>
         <p>First, install the extension using the button above or checking the various <a href="/install/">installation options</a>.</p>
-        <p>Afterwards, read our <a href="/blog/">blog</a>, <a href="https://arxiv.org/abs/2204.01392">paper</a>, <a href="/faq/">FAQ</a>, the <a href="/permissions/">required permissions</a> and the different protection <a href="/levels/">levels</a>.</p>
+        <p>Afterwards, read our <a href="/faq/">FAQ</a>, the <a href="/permissions/">required permissions</a> and the different protection <a href="/levels/">levels</a>.</p>
+        <p>For more details about what's going on under the hood, check out the <a href="/blog/">JShelter blog</a> and <a href="https://arxiv.org/abs/2204.01392">paper</a>.</p>
       </div>
     </article>
     <article>
diff --git a/website/content/pages/nbs.md b/website/content/pages/nbs.md
index bb80cba..be04aad 100644
--- a/website/content/pages/nbs.md
+++ b/website/content/pages/nbs.md
@@ -2,30 +2,30 @@ Title: Network Boundary Shield
 
 The Network Boundary Shield (NBS) is a protection against attacks from an
 external network (the Internet) to an internal network - especially against a
-reconnaissance attacks when a web browser is abused as a proxy. See, for
-example, [our blog post](/localportscanning/) or the [ForcePoint
+reconnaissance attack where a web browser is abused as a proxy. See, for
+example, [our blog post on port scanning](/localportscanning/) or the [ForcePoint
 report](https://www.forcepoint.com/blog/x-labs/attacking-internal-network-public-internet-using-browser-proxy).
 
-The NBS functionality is based on filtering HTTP requests. The Network Boundary
-Shield uses blocking webRequest API to handle HTTP requests. This means that
-processing of each HTTP request is paused before it is analyzed and allowed (if
-it seems benign) or blocked (if it is suspicious).
+It works by filtering HTTP requests by means of the blocking webRequest API to
+handle HTTP requests. This means that the processing of each HTTP request is
+paused before it is analyzed and allowed (if it seems benign) or blocked (if it
+is suspicious).
 
-The main goal of NBS is to prevent attacks like a public website requests a
+The main goal of NBS is to prevent attacks where a public website requests a
 resource from the internal network (e.g. the logo of the manufacturer of the
-local router); NBS will detect that a web page hosted on the public Internet
-tries to connect to a local IP address. NBS blocks only HTTP requests from a web
-page hosted on a public IP address to a private network resource. The user can
-allow specific web pages to access local resources (e.g. when using Intranet
-services).
+local router); NBS will detect that a web page hosted on the public Internet is
+trying to connect to a local IP address. NBS only blocks HTTP requests from a
+web page hosted on a public IP address to a private network resource; the user
+can allow specific web pages to access local resources (e.g.  when using
+Intranet services).
 
 NBS uses [CSV files provided by
 IANA](https://www.iana.org/assignments/locally-served-dns-zones/locally-served-dns-zones.xml)
 to determine public and local IP address prefixes. Both IPv4 and IPv6 is
 supported. The CSV files are downloaded during the JShelter building process.
 
-The NBS has only a small impact on the web browser performance. The impact
-differs for each implementation.
+The NBS has a small performance footprint, which differs for each browser
+implementation.
 
 More information about the Network Boundary Shield can be obtained from the
 [master thesis by Pavel
diff --git a/website/content/pages/threatmodel.md b/website/content/pages/threatmodel.md
index 1e651dd..b5c5681 100644
--- a/website/content/pages/threatmodel.md
+++ b/website/content/pages/threatmodel.md
@@ -1,11 +1,14 @@
 Title: Threat model
 
-JShelter focuses on threats that affect the mainstream population. Our adversary creates
-attacks/derives information in a way that works in mainstream browsers. The attacker focuses on these
-browsers and attacks that are light on performance. For example, the adversary is interested in
-identifying the user for targeted advertisement. So they need to identify the user quickly to
-display an advertisement. It does not make sense for such an attacker to deploy scripts that
-take minutes to compute a fingerprint.
+JShelter focuses on threats that target mainstream internet users. Attackers
+derive information and create attacks aimed at mainstream browsers, using
+approaches that minimize the performance requirements for such attacks.  For
+example, we can consider an adversary interested in identifying the user for
+targeted advertisement purposes. So, they will need to identify the user
+quickly to display an advertisement; it does not make sense for such an
+attacker to deploy scripts that take minutes to compute a fingerprint.
+
+## Fingerprinting countermeasures
 
 Our adversary might try to apply low-performance counterattacks. For example, previous literature
 identified extensions that modify calls in a wrong position in the JavaScript prototype chain. It is
@@ -14,7 +17,41 @@ so we apply code that modifies the original method, `Performance.prototype.now()
 Another example is an adversary running canvas fingerprinting several times. If the adversary
 receives different results, they can compute an average value (or a minimal or maximal value) and
 use this information to derive the correct fingerprint. As these modifications to fingerprinting are
-not performance-heavy, we consider them in the threat model.
+not performance-heavy, we consider them in the JShelter threat model.
+
+It is well-known that some extensions modify the environment of the browser or
+the web page. For example, password managers add buttons to fill in passwords
+automatically. Page tweakers add additional buttons to web pages to simplify
+common tasks or add information likely wanted by a user.  JShelter expects such
+users and tries to help such users from being identifiable. For example, a dumb
+fingerprinter can combine all fingerprintable data to create a single number.
+Such a fingerprinter would unintentionally create a unique fingerprint of the
+users with a unique set of extensions. Such a dumb fingerprinter would not link
+different visits of the user with Jshelter. JShelter should confuse a more
+advanced fingerprinter if they identify single or multiple users.
+
+We also want to provide an option that will limit the information that is
+readable from the computer, even if such behaviour generally results in better
+fingerprintability. For example, a user might want to disable canvas operations
+for pages that should not use canvas (from the user's standpoint). As the
+webpage is in a better position to deploy countermeasures for JShelter
+anti-fingerprinting techniques, the user might want the page to always read an
+empty, white, or random canvas. That would limit the information available for
+the web page at the cost of giving the page an easy way to determine that some
+countermeasures are in place. Our aim is to explain the consequences of taking
+such an option but letting the user decide for themselves.
+
+Previous literature identified that it is easy for an adversary to detect inconsistencies in API
+calls. For example, a fingerprinter can learn the operating system from HTTP headers,
+`navigator.oscpu`, installed fonts, results of mathematical operations, and other techniques. We do
+not want to replace such techniques as we do not have the resources to create a consistent environment.
+
+Besides fingerprinting, JShelter also focuses on other threats appearing on the web. For example,
+JShelter prevents web pages from turning the browser into a proxy to the local
+[network](/localportscanning/). The user should be able to decouple anti-fingerprinting
+countermeasures and other countermeasures.
+
+## Limitations and mitigation methods
 
 We do not have the resources to create a bullet-proof solution that eliminates all side channels. For
 example, we expect that an adversary will be able to detect that something strange is happening in
@@ -27,42 +64,20 @@ belongs. Hence, we try to eliminate the possibility of an attacker identifying t
 accept that the attacker can detect a JShelter user in the worst case. To do
 so reliably, the attacker should need to keep track of the code base changes.
 
-Nevertheless, we want to avoid allowing the attacker to identify JShelter users easily. We
-are not aware of any isolated side-effect that reveals JShelter. For example, some similar
-webextensions do not modify `Function.prototype.toString`. A page script could detect such a webextension as each
-webextension modifying the same API call by the same technique will likely use a different code.
-Our goal is to offer protection indistinguishable from another privacy-improving tool for
-each modified API. Nevertheless, a focused observer will very likely be always able to learn that a
-user is using JShelter if they aggregate the observable inconsistencies of all APIs produced by
-JShelter. We are aware and do not hide that users of JShelter are vulnerable to focused
-attacks.
-
-JShelter's goal is to make targeted attacks harder. Still, we do not believe that we are
-in a position to prevent them completely. We suggest
-using Tor Browser or a similar privacy-enhancing tool for users concerned with targeted attacks.
-
-It is well-known that some extensions modify the environment of the browser or the web page. For
-example, password managers add buttons to fill in passwords automatically. Page tweakers add
-additional buttons to web pages to simplify common tasks or add information likely wanted by a user.
-JShelter expects such users and tries to help such users from being identifiable. For example, a
-dumb fingerprinter can combine all fingerprintable data to create a single number. Such a fingerprinter
-would unintentionally create a unique fingerprint of the users with a unique set of extensions. Such a dumb fingerprinter would not link different visits of the user with Jshelter. JShelter should
-confuse a more advanced fingerprinter if they identify single or multiple users.
+Nevertheless, we want to avoid allowing the attacker to identify JShelter users
+easily. We are not aware of any isolated side-effect that reveals JShelter. For
+example, some similar webextensions do not modify
+`Function.prototype.toString`. A page script could detect such a webextension
+as each webextension modifying the same API call by the same technique will
+likely use a different code.  Our goal is to offer protection indistinguishable
+from another privacy-improving tool for each modified API. Nevertheless, a
+focused observer will very likely be always able to learn that a user is using
+JShelter if they aggregate the observable inconsistencies of all APIs produced
+by JShelter. We are aware and do not hide that users of JShelter are vulnerable
+to focused attacks.
 
-We also want to provide an option that will limit the information that is readable from the computer,
-even if such behaviour generally results in better fingerprintability. For example, a user
-might want to disable canvas operations for pages that should not use canvas (from the user's standpoint). As the webpage is in a better position to deploy countermeasures for JShelter
-anti-fingerprinting techniques, the user might want the page to always read an empty, white, or random
-canvas. That would limit the information available for the web page at the cost of giving the page
-an easy way to determine that some countermeasures are in place. Our aim is to explain
-the consequences of taking such an option but letting the user decide for themselves.
-
-Previous literature identified that it is easy for an adversary to detect inconsistencies in API
-calls. For example, a fingerprinter can learn the operating system from HTTP headers,
-`navigator.oscpu`, installed fonts, results of mathematical operations, and other techniques. We do
-not want to replace such techniques as we do not have the resources to create a consistent environment.
+JShelter's goal is to make targeted attacks harder. Still, we do not believe
+that we are in a position to prevent them completely. We suggest using [Tor
+Browser](https://www.torproject.org/download/) or a similar privacy-enhancing
+tool for users concerned with targeted attacks.
 
-Besides fingerprinting, JShelter also focuses on other threats appearing on the web. For example,
-JShelter prevents web pages from turning the browser into a proxy to the local
-[network](/localportscanning/). The user should be able to decouple anti-fingerprinting
-countermeasures and other countermeasures.

