From 3999bb29f9f6711df32aabd2428922c3d72045bf Mon Sep 17 00:00:00 2001 From: yoNico21 <119441054+yoNico21@users.noreply.github.com> Date: Thu, 17 Oct 2024 14:25:16 +0200 Subject: [PATCH] working extension for chrome (Manifest V3) and Firefox (Manifest V2) + created a package_me.sh for packaging the extensions for both platforms --- 1000_bots_webextension/background.js | 128 ++++--- 1000_bots_webextension/background_chrome.js | 312 ++++++++++++++++++ 1000_bots_webextension/background_ff.js | 207 ++++++++++++ 1000_bots_webextension/content.js | 196 ++++++----- 1000_bots_webextension/content_chrome.js | 132 ++++++++ 1000_bots_webextension/content_ff.js | 144 ++++++++ 1000_bots_webextension/manifest.json | 102 +++--- 1000_bots_webextension/manifest_chrome.json | 56 ++++ 1000_bots_webextension/manifest_ff.json | 32 ++ 1000_bots_webextension/old.background.js | 79 ----- 1000_bots_webextension/old.manifest.json | 22 -- 1000_bots_webextension/package_me.sh | 70 ++++ .../refused_to_be_human-0.0.2.xpi | Bin 0 -> 10850 bytes .../refused_to_be_human-0.0.2.zip | Bin 0 -> 12142 bytes .../refused_to_be_human-0.0.3.xpi | Bin 0 -> 12032 bytes .../refused_to_be_human-0.0.3.zip | Bin 0 -> 12718 bytes 16 files changed, 1205 insertions(+), 275 deletions(-) create mode 100644 1000_bots_webextension/background_chrome.js create mode 100644 1000_bots_webextension/background_ff.js create mode 100644 1000_bots_webextension/content_chrome.js create mode 100644 1000_bots_webextension/content_ff.js create mode 100644 1000_bots_webextension/manifest_chrome.json create mode 100644 1000_bots_webextension/manifest_ff.json delete mode 100644 1000_bots_webextension/old.background.js delete mode 100644 1000_bots_webextension/old.manifest.json create mode 100755 1000_bots_webextension/package_me.sh create mode 100644 1000_bots_webextension/packaged/refused_to_be_human-0.0.2/refused_to_be_human-0.0.2.xpi create mode 100644 1000_bots_webextension/packaged/refused_to_be_human-0.0.2/refused_to_be_human-0.0.2.zip create mode 100644 1000_bots_webextension/packaged/refused_to_be_human-0.0.3/refused_to_be_human-0.0.3.xpi create mode 100644 1000_bots_webextension/packaged/refused_to_be_human-0.0.3/refused_to_be_human-0.0.3.zip diff --git a/1000_bots_webextension/background.js b/1000_bots_webextension/background.js index b0ecc22..286273c 100644 --- a/1000_bots_webextension/background.js +++ b/1000_bots_webextension/background.js @@ -20,22 +20,24 @@ "use strict"; +const DEBUG = false; + // Use chrome or browser depending on the environment -var browser = chrome || browser; +const browser = chrome || browser; // Custom user-agent to spoof Googlebot -var user_agent = +const user_agent = "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"; -var target_urls = "*://*/*"; +const target_urls = "*://*/*"; // Duration to display the injected HTML (in milliseconds) const DISPLAY_DURATION = 8000; // Set to 8 seconds // Initialize storage for duration -browser.storage.local +browser.storage.sync .set({ duration: DISPLAY_DURATION }) .then(() => { - console.log("Duration set to:", DISPLAY_DURATION); + if (DEBUG) console.log("Duration set to:", DISPLAY_DURATION); }) .catch((error) => { console.error("Error setting duration:", error); @@ -43,14 +45,16 @@ browser.storage.local // Set extension status to ON function set_extension_status_ON() { - browser.storage.local - .set({ status: 1 }) + browser.storage.sync + .set({ status: 1, bannerInjected: false, debug: DEBUG }) .then(() => { - console.log("Extension status set to ON"); + if (DEBUG) console.log("Extension status set to ON"); return browser.action.setIcon({ path: "icon_ON_48.png" }); }) .then(() => { - return browser.action.setTitle({ title: "1000 Bots" }); + return browser.action.setTitle({ + title: "You are now surfing the web as a bot 🤖", + }); }) .then(() => { // Start user-agent spoofing @@ -71,14 +75,16 @@ function set_extension_status_ON() { // Set extension status to OFF function set_extension_status_OFF() { - browser.storage.local + browser.storage.sync .set({ status: 0 }) .then(() => { - console.log("Extension status set to OFF"); + if (DEBUG) console.log("Extension status set to OFF"); return browser.action.setIcon({ path: "icon_OFF_48.png" }); }) .then(() => { - return browser.action.setTitle({ title: "1000 Bots activate" }); + return browser.action.setTitle({ + title: "Click here to refuse to be human 🤖", + }); }) .then(() => { // Remove the content from all active tabs @@ -99,7 +105,7 @@ function set_extension_status_OFF() { // Toggle the icon between ON and OFF function update_icon() { - browser.storage.local + browser.storage.sync .get("status") .then((result) => { if (result.status === 0) { @@ -143,7 +149,10 @@ function startUserAgentSpoofing() { removeRuleIds: [], }) .then(() => { - return console.log("User-Agent spoofing rules added successfully."); + if (DEBUG) + return console.log( + "User-Agent spoofing rules added successfully." + ); }) .then(() => {}) .catch((error) => { @@ -158,11 +167,12 @@ function stopUserAgentSpoofing() { removeRuleIds: [1], }) .then(() => { - console.log("User-Agent spoofing rules removed successfully."); + if (DEBUG) + console.log("User-Agent spoofing rules removed successfully."); }) .then(() => { // Clear the bannerInjected flag when stopping the extension - return browser.storage.local.set({ bannerInjected: false }); + return browser.storage.sync.set({ bannerInjected: false }); }) .catch((error) => { console.error("Error removing rules:", error); @@ -176,7 +186,7 @@ function refreshAllTabs() { browser.tabs .reload(tab.id) .then(() => { - console.log(`Refreshed tab: ${tab.id}`); + if (DEBUG) console.log(`Refreshed tab: ${tab.id}`); }) .catch((error) => { console.error(`Error refreshing tab ${tab.id}:`, error); @@ -190,33 +200,57 @@ function injectContentScript() { return browser.tabs .query({}) .then((tabs) => { - return Promise.all( - tabs.map((tab) => { - // Check if the tab is not a chrome URL - if (!tab.url.startsWith("chrome://")) { - return browser.scripting - .executeScript({ - target: { tabId: tab.id }, - files: ["content.js"], - }) - .then(() => { + // Create an array of promises for each tab + const promises = tabs.map((tab) => { + // Check if the URL is not something like chrome:// or about:// etc. + if (tab.url.startsWith("https://")) { + return browser.scripting + .executeScript({ + target: { tabId: tab.id }, + files: ["content.js"], + }) + .then(() => { + if (DEBUG) console.log( `Content script injected into tab ${tab.id}` ); - }) - .catch((error) => { - console.error( - `Error injecting content script into tab ${tab.id}:`, - error - ); - }); - } else { + + // Use a hardcoded duration for removal + const duration = 80000; // 8 seconds or whatever you need + + // Set a timeout to remove the content after the hardcoded duration + setTimeout(() => { + browser.storage.sync.set({ + bannerInjected: true, + }); + if (DEBUG) + console.log( + "Duration expired. Removing content." + ); + removeInjectedContent(); // Ensure this is defined + }, duration); + }) + .catch((error) => { + console.error( + `Error injecting content script into tab ${tab.id}:`, + error + ); + }); + } else { + if (DEBUG) console.log( - `Skipped injecting content script into tab ${tab.id} (chrome:// URL)` + `Skipped injecting content script into tab ${tab.id} (chrome://, about:// URL or similar)` ); - } - }) - ); + return Promise.resolve(); // Return resolved promise for skipped tabs + } + }); + + // Return a promise that resolves when all injections are complete + return Promise.all(promises); + }) + .then(() => { + if (DEBUG) + console.log("All scripts injected and removal timers set."); }) .catch((error) => { console.error("Error querying tabs:", error); @@ -229,7 +263,7 @@ function removeInjectedContent() { .query({}) .then((tabs) => { tabs.forEach((tab) => { - if (!tab.url.startsWith("chrome://")) { + if (tab.url.startsWith("https://")) { browser.scripting .executeScript({ target: { tabId: tab.id }, @@ -242,9 +276,10 @@ function removeInjectedContent() { }, }) .then(() => { - console.log( - `Removed injected content from tab ${tab.id}` - ); + if (DEBUG) + console.log( + `Removed injected content from tab ${tab.id}` + ); }) .catch((error) => { console.error( @@ -253,9 +288,10 @@ function removeInjectedContent() { ); }); } else { - console.log( - `Skipped removing injected content from tab ${tab.id} (chrome:// URL)` - ); + if (DEBUG) + console.log( + `Skipped removing injected content from tab ${tab.id} (chrome://, about:// URL or similar)` + ); } }); }) diff --git a/1000_bots_webextension/background_chrome.js b/1000_bots_webextension/background_chrome.js new file mode 100644 index 0000000..286273c --- /dev/null +++ b/1000_bots_webextension/background_chrome.js @@ -0,0 +1,312 @@ +/* + 1000 Bots - Surf the Web as Googlebot + + Copyleft (C) 2020 !Mediengruppe Bitnik, connect@bitnik.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +*/ + +"use strict"; + +const DEBUG = false; + +// Use chrome or browser depending on the environment +const browser = chrome || browser; + +// Custom user-agent to spoof Googlebot +const user_agent = + "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"; +const target_urls = "*://*/*"; + +// Duration to display the injected HTML (in milliseconds) +const DISPLAY_DURATION = 8000; // Set to 8 seconds + +// Initialize storage for duration +browser.storage.sync + .set({ duration: DISPLAY_DURATION }) + .then(() => { + if (DEBUG) console.log("Duration set to:", DISPLAY_DURATION); + }) + .catch((error) => { + console.error("Error setting duration:", error); + }); + +// Set extension status to ON +function set_extension_status_ON() { + browser.storage.sync + .set({ status: 1, bannerInjected: false, debug: DEBUG }) + .then(() => { + if (DEBUG) console.log("Extension status set to ON"); + return browser.action.setIcon({ path: "icon_ON_48.png" }); + }) + .then(() => { + return browser.action.setTitle({ + title: "You are now surfing the web as a bot 🤖", + }); + }) + .then(() => { + // Start user-agent spoofing + return startUserAgentSpoofing(); + }) + .then(() => { + // Refresh all tabs after starting user-agent spoofing + return refreshAllTabs(); + }) + .then(() => { + // Inject the content script into all active tabs after refreshing + return injectContentScript(); + }) + .catch((error) => { + console.error("Error setting extension status ON:", error); + }); +} + +// Set extension status to OFF +function set_extension_status_OFF() { + browser.storage.sync + .set({ status: 0 }) + .then(() => { + if (DEBUG) console.log("Extension status set to OFF"); + return browser.action.setIcon({ path: "icon_OFF_48.png" }); + }) + .then(() => { + return browser.action.setTitle({ + title: "Click here to refuse to be human 🤖", + }); + }) + .then(() => { + // Remove the content from all active tabs + return removeInjectedContent(); + }) + .then(() => { + // Stop user-agent spoofing + return stopUserAgentSpoofing(); + }) + .then(() => { + // Refresh all tabs before stopping the extension + return refreshAllTabs(); + }) + .catch((error) => { + console.error("Error setting extension status OFF:", error); + }); +} + +// Toggle the icon between ON and OFF +function update_icon() { + browser.storage.sync + .get("status") + .then((result) => { + if (result.status === 0) { + set_extension_status_ON(); + } else { + set_extension_status_OFF(); + } + }) + .catch((error) => { + console.error("Error fetching extension status:", error); + }); +} + +// Start user-agent spoofing +function startUserAgentSpoofing() { + const rules = [ + { + id: 1, + priority: 1, + action: { + type: "modifyHeaders", + requestHeaders: [ + { + operation: "set", + header: "User-Agent", + value: user_agent, + }, + ], + }, + condition: { + urlFilter: target_urls, + resourceTypes: ["main_frame"], + }, + }, + ]; + + // Add the rules + return browser.declarativeNetRequest + .updateDynamicRules({ + addRules: rules, + removeRuleIds: [], + }) + .then(() => { + if (DEBUG) + return console.log( + "User-Agent spoofing rules added successfully." + ); + }) + .then(() => {}) + .catch((error) => { + console.error("Error adding rules:", error); + }); +} + +// Stop user-agent spoofing +function stopUserAgentSpoofing() { + return browser.declarativeNetRequest + .updateDynamicRules({ + removeRuleIds: [1], + }) + .then(() => { + if (DEBUG) + console.log("User-Agent spoofing rules removed successfully."); + }) + .then(() => { + // Clear the bannerInjected flag when stopping the extension + return browser.storage.sync.set({ bannerInjected: false }); + }) + .catch((error) => { + console.error("Error removing rules:", error); + }); +} + +// Function to refresh all active tabs +function refreshAllTabs() { + return browser.tabs.query({}).then((tabs) => { + tabs.forEach((tab) => { + browser.tabs + .reload(tab.id) + .then(() => { + if (DEBUG) console.log(`Refreshed tab: ${tab.id}`); + }) + .catch((error) => { + console.error(`Error refreshing tab ${tab.id}:`, error); + }); + }); + }); +} + +// Inject the content.js script into all active tabs +function injectContentScript() { + return browser.tabs + .query({}) + .then((tabs) => { + // Create an array of promises for each tab + const promises = tabs.map((tab) => { + // Check if the URL is not something like chrome:// or about:// etc. + if (tab.url.startsWith("https://")) { + return browser.scripting + .executeScript({ + target: { tabId: tab.id }, + files: ["content.js"], + }) + .then(() => { + if (DEBUG) + console.log( + `Content script injected into tab ${tab.id}` + ); + + // Use a hardcoded duration for removal + const duration = 80000; // 8 seconds or whatever you need + + // Set a timeout to remove the content after the hardcoded duration + setTimeout(() => { + browser.storage.sync.set({ + bannerInjected: true, + }); + if (DEBUG) + console.log( + "Duration expired. Removing content." + ); + removeInjectedContent(); // Ensure this is defined + }, duration); + }) + .catch((error) => { + console.error( + `Error injecting content script into tab ${tab.id}:`, + error + ); + }); + } else { + if (DEBUG) + console.log( + `Skipped injecting content script into tab ${tab.id} (chrome://, about:// URL or similar)` + ); + return Promise.resolve(); // Return resolved promise for skipped tabs + } + }); + + // Return a promise that resolves when all injections are complete + return Promise.all(promises); + }) + .then(() => { + if (DEBUG) + console.log("All scripts injected and removal timers set."); + }) + .catch((error) => { + console.error("Error querying tabs:", error); + }); +} + +// Remove the content from all active tabs +function removeInjectedContent() { + return browser.tabs + .query({}) + .then((tabs) => { + tabs.forEach((tab) => { + if (tab.url.startsWith("https://")) { + browser.scripting + .executeScript({ + target: { tabId: tab.id }, + function: () => { + const banner = + document.querySelector(".extension-banner"); + if (banner && banner.parentNode) { + banner.parentNode.removeChild(banner); + } + }, + }) + .then(() => { + if (DEBUG) + console.log( + `Removed injected content from tab ${tab.id}` + ); + }) + .catch((error) => { + console.error( + `Error removing injected content from tab ${tab.id}:`, + error + ); + }); + } else { + if (DEBUG) + console.log( + `Skipped removing injected content from tab ${tab.id} (chrome://, about:// URL or similar)` + ); + } + }); + }) + .catch((error) => { + console.error( + "Error querying tabs for injected content removal:", + error + ); + }); +} + +// Event listeners for Manifest v3 Service Worker +browser.runtime.onInstalled.addListener(() => { + set_extension_status_OFF(); // Set status to OFF on installation/startup +}); + +// Handle browser action clicks to toggle status +browser.action.onClicked.addListener(update_icon); diff --git a/1000_bots_webextension/background_ff.js b/1000_bots_webextension/background_ff.js new file mode 100644 index 0000000..3680bca --- /dev/null +++ b/1000_bots_webextension/background_ff.js @@ -0,0 +1,207 @@ +/* + 1000 Bots - Surf the Web as Googlebot + + Copyleft (C) 2020 !Mediengruppe Bitnik, connect@bitnik.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +*/ + +"use strict"; + +var browser = browser || chrome; +var user_agent = + "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"; +var target_urls = "*://*/*"; +var status = 0; + +const DEBUG = false; // Set to true to enable debug mode + +// Duration to display the injected HTML (in milliseconds) +const DISPLAY_DURATION = 8000; // Set to 8 seconds + +// Initialize storage for duration +browser.storage.sync.set( + { duration: DISPLAY_DURATION, debug: DEBUG }, + function () { + if (browser.runtime.lastError) { + console.error("Error setting duration:", browser.runtime.lastError); + } else { + if (DEBUG) console.log("Duration set to:", DISPLAY_DURATION); + } + } +); + +// Inject the content.js script into all active tabs +function injectContentScript() { + browser.tabs.query({}, (tabs) => { + tabs.forEach((tab) => { + // Check if the URL is not something like chrome:// or about:// etc. + if (tab.url.startsWith("https://")) { + browser.tabs.executeScript( + tab.id, + { file: "content.js" }, + () => { + if (browser.runtime.lastError) { + console.error( + `Error injecting content script into tab ${tab.id}:`, + browser.runtime.lastError + ); + } else { + if (DEBUG) + console.log( + `Content script injected into tab ${tab.id}` + ); + + // If the duration has passed, removeInjectedContent + const interval = setInterval(() => { + browser.storage.sync.get( + "duration", + (result) => { + if (browser.runtime.lastError) { + console.error( + "Error fetching duration:", + browser.runtime.lastError + ); + } else if (result.duration <= 0) { + clearInterval(interval); + removeInjectedContent(); + } + } + ); + }); + } + } + ); + } else { + if (DEBUG) + console.log( + `Skipped injecting content script into tab ${tab.id} (chrome://, about:// URL or similar)` + ); + } + }); + }); +} + +// Remove the content from all active tabs +function removeInjectedContent() { + browser.tabs.query({}, (tabs) => { + tabs.forEach((tab) => { + if (tab.url.startsWith("https://")) { + browser.tabs.executeScript( + tab.id, + { + code: ` + const banner = document.querySelector('.extension-banner'); + if (banner && banner.parentNode) { + banner.parentNode.removeChild(banner); + } + `, + }, + () => { + if (browser.runtime.lastError) { + console.error( + `Error removing injected content from tab ${tab.id}:`, + browser.runtime.lastError + ); + } else { + if (DEBUG) + console.log( + `Removed injected content from tab ${tab.id}` + ); + } + } + ); + } else { + if (DEBUG) + console.log( + `Skipped removing injected content from tab ${tab.id} (chrome://, about:// URL or similar)` + ); + } + }); + }); +} + +// Function to refresh all active tabs +function refreshAllTabs() { + browser.tabs.query({}, (tabs) => { + tabs.forEach((tab) => { + browser.tabs.reload(tab.id, () => { + if (browser.runtime.lastError) { + console.error( + `Error refreshing tab ${tab.id}:`, + browser.runtime.lastError + ); + } else { + if (DEBUG) console.log(`Refreshed tab: ${tab.id}`); + } + }); + }); + }); +} + +function set_extension_status_ON() { + status = 1; + if (DEBUG) console.log("Setting status to ON"); + browser.browserAction.setIcon({ path: "icon_ON_48.png" }); + browser.browserAction.setTitle({ + title: "You are now surfing the web as a bot 🤖", + }); + injectContentScript(); +} + +function set_extension_status_OFF() { + status = 0; + if (DEBUG) console.log("Setting status to OFF"); + browser.browserAction.setIcon({ path: "icon_OFF_48.png" }); + browser.browserAction.setTitle({ + title: "Click here to refuse to be human 🤖", + }); + removeInjectedContent(); + refreshAllTabs(); +} + +function update_icon() { + if (status == 0) { + set_extension_status_ON(); + } else { + set_extension_status_OFF(); + } +} + +function rewrite_user_agent_header(e) { + if (DEBUG) console.log("Browser http request!"); + + if (status == 0) { + if (DEBUG) console.log("Nothing to do"); + return { requestHeaders: e.requestHeaders }; + } + + for (var header of e.requestHeaders) { + if (header.name.toLowerCase() === "user-agent") { + header.value = user_agent; + } + } + if (DEBUG) console.log("Set user-agent header to: " + user_agent); + return { requestHeaders: e.requestHeaders }; +} + +browser.runtime.onStartup.addListener(set_extension_status_OFF); +browser.browserAction.onClicked.addListener(update_icon); + +browser.webRequest.onBeforeSendHeaders.addListener( + rewrite_user_agent_header, + { urls: [target_urls] }, + ["blocking", "requestHeaders"] +); diff --git a/1000_bots_webextension/content.js b/1000_bots_webextension/content.js index 0e72239..f9c47f9 100644 --- a/1000_bots_webextension/content.js +++ b/1000_bots_webextension/content.js @@ -1,94 +1,130 @@ +// Use chrome or browser depending on the environment +const browser = chrome || browser; + +let DEBUG; // Declare the DEBUG variable in the outer scope + +browser.storage.sync.get("debug").then((result) => { + DEBUG = result.debug; + console.log("DEBUG mode:", DEBUG); +}); + +// Duration to show the banner (in milliseconds) +let DISPLAY_DURATION = 5000; // Initialize the duration to 5 seconds +let CSS_ANIMATION_DURATION, + CSS_DURATION, + CSS_DELAY = 0; // Initialize the CSS variables +let BANNER; // Declare the banner variable in the outer scope + +function initializeCSSProperties(result) { + DISPLAY_DURATION = result.duration || DISPLAY_DURATION; + if (DEBUG) console.log("Duration set to:", DISPLAY_DURATION, "(in ms)"); + + // Set variables to css for delay for animation + CSS_ANIMATION_DURATION = 300 / 1000; + CSS_DURATION = DISPLAY_DURATION / 1000; + CSS_DELAY = CSS_DURATION - CSS_ANIMATION_DURATION - CSS_ANIMATION_DURATION; + + if (DEBUG) console.log("--duration:", `${CSS_ANIMATION_DURATION}s`); + if (DEBUG) console.log("--delay:", `${CSS_DURATION}s`); + + CSS_ANIMATION_DURATION = CSS_ANIMATION_DURATION + "s"; + document.body.style.setProperty("--duration", CSS_ANIMATION_DURATION); + + CSS_DELAY = CSS_DELAY + "s"; + document.body.style.setProperty("--delay", CSS_DELAY); +} + +function injectCSS() { + // Inject the CSS file + const link = document.createElement("link"); + link.href = browser.runtime.getURL("style.css"); + link.rel = "stylesheet"; + document.head.appendChild(link); + + // Return the link element + return link; +} + +function createBanner() { + // Create the banner container + const banner = document.createElement("div"); + banner.classList.add("extension-banner-container"); + + const marqeeText = "YOU ARE NOW SURFING THE WEB AS A BOT 🤖 "; + + const bannerContent = ` + + `; + + // Set the banner content + banner.innerHTML = bannerContent; + + // Append the banner to the body + document.body.appendChild(banner); + + // Return the banner + return banner; +} + +function removeBanner() { + setTimeout(() => { + if (BANNER && BANNER.parentNode) { + // Remove the banner + BANNER.parentNode.removeChild(BANNER); + if (DEBUG) console.log("Banner removed after duration."); + + // Remove the injected CSS file + const link = document.querySelector('link[href$="style.css"]'); // Match any href ending with "style.css" + link.parentNode.removeChild(link); + } + }, DISPLAY_DURATION); +} + (function () { - // Use chrome or browser depending on the environment - var browser = chrome || browser; - - // Duration to show the banner (in milliseconds) - let DISPLAY_DURATION = 5000; // Initialize the duration to 5 seconds - let banner; // Declare the banner variable in the outer scope - // Get the duration from local storage and update the DISPLAY_DURATION variable - browser.storage.local - .get(["duration", "status"]) // Fetch both duration and status + browser.storage.sync + .get(["duration", "status", "bannerInjected"]) // Fetch both duration and status .then((result) => { - DISPLAY_DURATION = result.duration || DISPLAY_DURATION; - console.log("Duration set to:", DISPLAY_DURATION, "(in ms)"); + if (DEBUG) + console.log( + "content.js reads from storage: bannerInjected =", + result.bannerInjected + ); + if (!result.bannerInjected) { + // Initialize the CSS properties + initializeCSSProperties(result); - // Set variables to css for delay for animation - let CSS_ANIMATION_DURATION = 300 / 1000; - let CSS_DURATION = DISPLAY_DURATION / 1000; - let CSS_DELAY = - CSS_DURATION - CSS_ANIMATION_DURATION - CSS_ANIMATION_DURATION; + if (result.status === 0) { + // Extension is OFF, do nothing + if (DEBUG) console.log("Extension is OFF, exiting."); + return; + } - console.log("--duration:", `${CSS_ANIMATION_DURATION}s`); - console.log("--delay:", `${CSS_DURATION}s`); + if (DEBUG) console.log("Injecting CSS..."); - CSS_ANIMATION_DURATION = CSS_ANIMATION_DURATION + "s"; - document.body.style.setProperty( - "--duration", - CSS_ANIMATION_DURATION - ); + // Inject the CSS file + injectCSS(); + if (DEBUG) console.log("CSS file injected."); - CSS_DELAY = CSS_DELAY + "s"; - document.body.style.setProperty("--delay", CSS_DELAY); - - if (result.status === 0) { - // Extension is OFF, do nothing - console.log("Extension is OFF, exiting."); - return; + // Create the banner + BANNER = createBanner(); + if (DEBUG) console.log("Banner injected:", BANNER); + } else { + // Banner has already been injected, remove the banner + if (DEBUG) + console.log("Banner already injected... removing banner."); + removeBanner(); } - - if (result.bannerInjected) { - // Banner has already been injected, do nothing - console.log("Banner already injected, exiting."); - return; - } - - console.log("Injecting the banner..."); - - // Inject the CSS file - const link = document.createElement("link"); - link.href = browser.runtime.getURL("style.css"); - link.rel = "stylesheet"; - document.head.appendChild(link); - console.log("CSS file injected."); - - // Create and style the banner container - banner = document.createElement("div"); - banner.classList.add("extension-banner-container"); - - const marqeeText = "YOU ARE NOW SURFING THE WEB AS A BOT 🤖 "; - - const bannerContent = ` - - `; - - // Set the banner content - banner.innerHTML = bannerContent; - - // Append the banner to the body - document.body.appendChild(banner); - console.log("Banner injected:", banner); - - // Set the flag in local storage to indicate that the banner was injected - return browser.storage.local.set({ bannerInjected: true }); }) .then(() => { // Remove the banner after the specified duration - setTimeout(() => { - if (banner && banner.parentNode) { - banner.parentNode.removeChild(banner); - console.log("Banner removed after duration."); - - // Reset the flag when the banner is removed - browser.storage.local.set({ bannerInjected: false }); - } - }, DISPLAY_DURATION); + removeBanner(); }) .catch((error) => { console.error("Error in content script:", error); diff --git a/1000_bots_webextension/content_chrome.js b/1000_bots_webextension/content_chrome.js new file mode 100644 index 0000000..b662b75 --- /dev/null +++ b/1000_bots_webextension/content_chrome.js @@ -0,0 +1,132 @@ +// Use chrome or browser depending on the environment +const browser = chrome || browser; + +let DEBUG; // Declare the DEBUG variable in the outer scope + +browser.storage.sync.get("debug").then((result) => { + DEBUG = result.debug; + if (DEBUG) console.log("DEBUG mode:", DEBUG); +}); + +// Duration to show the banner (in milliseconds) +let DISPLAY_DURATION = 5000; // Initialize the duration to 5 seconds +let CSS_ANIMATION_DURATION, + CSS_DURATION, + CSS_DELAY = 0; // Initialize the CSS variables +let BANNER; // Declare the banner variable in the outer scope + +function initializeCSSProperties(result) { + DISPLAY_DURATION = result.duration || DISPLAY_DURATION; + if (DEBUG) console.log("Duration set to:", DISPLAY_DURATION, "(in ms)"); + + // Set variables to css for delay for animation + CSS_ANIMATION_DURATION = 300 / 1000; + CSS_DURATION = DISPLAY_DURATION / 1000; + CSS_DELAY = CSS_DURATION - CSS_ANIMATION_DURATION - CSS_ANIMATION_DURATION; + + if (DEBUG) console.log("--duration:", `${CSS_ANIMATION_DURATION}s`); + if (DEBUG) console.log("--delay:", `${CSS_DURATION}s`); + + CSS_ANIMATION_DURATION = CSS_ANIMATION_DURATION + "s"; + document.body.style.setProperty("--duration", CSS_ANIMATION_DURATION); + + CSS_DELAY = CSS_DELAY + "s"; + document.body.style.setProperty("--delay", CSS_DELAY); +} + +function injectCSS() { + // Inject the CSS file + const link = document.createElement("link"); + link.href = browser.runtime.getURL("style.css"); + link.rel = "stylesheet"; + document.head.appendChild(link); + + // Return the link element + return link; +} + +function createBanner() { + // Create the banner container + const banner = document.createElement("div"); + banner.classList.add("extension-banner-container"); + + const marqeeText = "YOU ARE NOW SURFING THE WEB AS A BOT 🤖 "; + + const bannerContent = ` + + `; + + // Set the banner content + banner.innerHTML = bannerContent; + + // Append the banner to the body + document.body.appendChild(banner); + + // Return the banner + return banner; +} + +function removeBanner() { + setTimeout(() => { + if (BANNER && BANNER.parentNode) { + // Remove the banner + BANNER.parentNode.removeChild(BANNER); + if (DEBUG) console.log("Banner removed after duration."); + + // Remove the injected CSS file + const link = document.querySelector('link[href$="style.css"]'); // Match any href ending with "style.css" + link.parentNode.removeChild(link); + } + }, DISPLAY_DURATION); +} + +(function () { + // Get the duration from local storage and update the DISPLAY_DURATION variable + browser.storage.sync + .get(["duration", "status", "bannerInjected"]) // Fetch both duration and status + .then((result) => { + if (DEBUG) + console.log( + "content.js reads from storage: bannerInjected =", + result.bannerInjected + ); + if (!result.bannerInjected) { + // Initialize the CSS properties + initializeCSSProperties(result); + + if (result.status === 0) { + // Extension is OFF, do nothing + if (DEBUG) console.log("Extension is OFF, exiting."); + return; + } + + if (DEBUG) console.log("Injecting CSS..."); + + // Inject the CSS file + injectCSS(); + if (DEBUG) console.log("CSS file injected."); + + // Create the banner + BANNER = createBanner(); + if (DEBUG) console.log("Banner injected:", BANNER); + } else { + // Banner has already been injected, remove the banner + if (DEBUG) + console.log("Banner already injected... removing banner."); + removeBanner(); + } + }) + .then(() => { + // Remove the banner after the specified duration + removeBanner(); + }) + .catch((error) => { + console.error("Error in content script:", error); + }); +})(); diff --git a/1000_bots_webextension/content_ff.js b/1000_bots_webextension/content_ff.js new file mode 100644 index 0000000..98a13e7 --- /dev/null +++ b/1000_bots_webextension/content_ff.js @@ -0,0 +1,144 @@ +// Use chrome or browser depending on the environment +const browser = chrome || browser; + +let DEBUG; // Declare the DEBUG variable in the outer scope + +browser.storage.sync.get("debug").then((result) => { + DEBUG = result.debug; + if (DEBUG) console.log("DEBUG mode:", DEBUG); +}); + +// Duration to show the banner (in milliseconds) +let DISPLAY_DURATION = 5000; // Initialize the duration to 5 seconds +let CSS_ANIMATION_DURATION, + CSS_DURATION, + CSS_DELAY = 0; // Initialize the CSS variables +let BANNER; // Declare the banner variable in the outer scope + +function initializeCSSProperties(result) { + DISPLAY_DURATION = result.duration || DISPLAY_DURATION; + if (DEBUG) console.log("Duration set to:", DISPLAY_DURATION, "(in ms)"); + + // Set variables to css for delay for animation + CSS_ANIMATION_DURATION = 300 / 1000; + CSS_DURATION = DISPLAY_DURATION / 1000; + CSS_DELAY = CSS_DURATION - CSS_ANIMATION_DURATION - CSS_ANIMATION_DURATION; + + if (DEBUG) console.log("--duration:", `${CSS_ANIMATION_DURATION}s`); + if (DEBUG) console.log("--delay:", `${CSS_DURATION}s`); + + CSS_ANIMATION_DURATION = CSS_ANIMATION_DURATION + "s"; + document.body.style.setProperty("--duration", CSS_ANIMATION_DURATION); + + CSS_DELAY = CSS_DELAY + "s"; + document.body.style.setProperty("--delay", CSS_DELAY); +} + +function injectCSS() { + // Inject the CSS file + const link = document.createElement("link"); + link.href = browser.runtime.getURL("style.css"); + link.rel = "stylesheet"; + document.head.appendChild(link); + + // Return the link element + return link; +} + +function createBanner() { + // Create the banner container + const banner = document.createElement("div"); + banner.classList.add("extension-banner-container"); + + const marqeeText = "YOU ARE NOW SURFING THE WEB AS A BOT 🤖 "; + + const bannerContent = ` + + `; + + // Set the banner content + banner.innerHTML = bannerContent; + + // Append the banner to the body + document.body.appendChild(banner); + + // Return the banner + return banner; +} + +(function () { + // Get the duration from local storage and update the DISPLAY_DURATION variable + browser.storage.sync.get(["duration", "status"], function (result) { + // Initialize the CSS properties + initializeCSSProperties(result); + + if (result.status === 0) { + // Extension is OFF, do nothing + if (DEBUG) console.log("Extension is OFF, exiting."); + return; + } + + if (result.bannerInjected === true) { + // Banner has already been injected, do nothing + if (DEBUG) console.log("Banner already injected, exiting."); + return; + } + + if (DEBUG) console.log("Injecting CSS..."); + + // Inject the CSS file + injectCSS(); + if (DEBUG) console.log("CSS file injected."); + + // Create the banner + BANNER = createBanner(); + if (DEBUG) console.log("Banner injected:", BANNER); + + // Set the flag in local storage to indicate that the banner was injected + browser.storage.sync.set({ bannerInjected: true }, function () { + if (browser.runtime.lastError) { + console.error( + "Error setting bannerInjected flag:", + browser.runtime.lastError + ); + } else { + // Remove the banner after the specified duration + setTimeout(() => { + if (BANNER && BANNER.parentNode) { + // Remove the banner + BANNER.parentNode.removeChild(BANNER); + if (DEBUG) + console.log("Banner removed after duration."); + + // Remove the injected CSS file + const link = document.querySelector( + 'link[href="style.css"]' + ); + if (link) { + link.parentNode.removeChild(link); // Corrected to remove the link + } + + // Reset the flag when the banner is removed + browser.storage.sync.set( + { bannerInjected: false }, + function () { + if (browser.runtime.lastError) { + console.error( + "Error resetting bannerInjected flag:", + browser.runtime.lastError + ); + } + } + ); + } + }, DISPLAY_DURATION); + } + }); + }); +})(); diff --git a/1000_bots_webextension/manifest.json b/1000_bots_webextension/manifest.json index 6831b9a..46aeacc 100644 --- a/1000_bots_webextension/manifest.json +++ b/1000_bots_webextension/manifest.json @@ -1,50 +1,56 @@ { - "name": "1000 Bots", - "version": "0.0.1", - "description": "Surf the Web as Googlebot. Ever wondered what the Googlebot get’s to see online that you do not?", - "homepage_url": "http://1000scores.com/portfolio-items/mediengruppe-bitnik-1000-bots/", - "manifest_version": 3, - - "background": { - "service_worker": "background.js" - }, - - "permissions": [ - "storage", - "tabs", - "scripting", - "activeTab", - "declarativeNetRequest", - "declarativeNetRequestFeedback" - ], - - "host_permissions": ["*://*/*"], - - "action": { - "default_title": "Click to change your browser's perspective", - "default_icon": "icon_OFF_48.png" - }, - - "content_scripts": [ - { - "matches": [""], - "js": ["content.js"], - "css": ["style.css"], - "run_at": "document_idle" - } - ], - - "web_accessible_resources": [ - { - "resources": ["style.css"], - "matches": [""] - } - ], - - "browser_specific_settings": { - "gecko": { - "id": "trash@bitnik.org", - "strict_min_version": "55.0" - } - } + "name": "Refuse to be Human — Surf the Web as Googlebot", + "short_name": "Refuse to be Human", + "version": "0.0.3", + "description": "Surf the Web as Googlebot. Ever wondered what the Googlebot get’s to see online that you do not?", + "homepage_url": "http://1000scores.com/portfolio-items/mediengruppe-bitnik-1000-bots/", + "manifest_version": 3, + "background": { + "service_worker": "background.js" + }, + "permissions": [ + "storage", + "tabs", + "scripting", + "activeTab", + "declarativeNetRequest", + "declarativeNetRequestFeedback" + ], + "host_permissions": [ + "*://*/*" + ], + "action": { + "default_title": "Click to change your browser's perspective", + "default_icon": "icon_OFF_48.png" + }, + "content_scripts": [ + { + "matches": [ + "" + ], + "js": [ + "content.js" + ], + "css": [ + "style.css" + ], + "run_at": "document_idle" + } + ], + "web_accessible_resources": [ + { + "resources": [ + "style.css" + ], + "matches": [ + "" + ] + } + ], + "browser_specific_settings": { + "gecko": { + "id": "trash@bitnik.org", + "strict_min_version": "55.0" + } + } } diff --git a/1000_bots_webextension/manifest_chrome.json b/1000_bots_webextension/manifest_chrome.json new file mode 100644 index 0000000..46aeacc --- /dev/null +++ b/1000_bots_webextension/manifest_chrome.json @@ -0,0 +1,56 @@ +{ + "name": "Refuse to be Human — Surf the Web as Googlebot", + "short_name": "Refuse to be Human", + "version": "0.0.3", + "description": "Surf the Web as Googlebot. Ever wondered what the Googlebot get’s to see online that you do not?", + "homepage_url": "http://1000scores.com/portfolio-items/mediengruppe-bitnik-1000-bots/", + "manifest_version": 3, + "background": { + "service_worker": "background.js" + }, + "permissions": [ + "storage", + "tabs", + "scripting", + "activeTab", + "declarativeNetRequest", + "declarativeNetRequestFeedback" + ], + "host_permissions": [ + "*://*/*" + ], + "action": { + "default_title": "Click to change your browser's perspective", + "default_icon": "icon_OFF_48.png" + }, + "content_scripts": [ + { + "matches": [ + "" + ], + "js": [ + "content.js" + ], + "css": [ + "style.css" + ], + "run_at": "document_idle" + } + ], + "web_accessible_resources": [ + { + "resources": [ + "style.css" + ], + "matches": [ + "" + ] + } + ], + "browser_specific_settings": { + "gecko": { + "id": "trash@bitnik.org", + "strict_min_version": "55.0" + } + } +} diff --git a/1000_bots_webextension/manifest_ff.json b/1000_bots_webextension/manifest_ff.json new file mode 100644 index 0000000..fa79983 --- /dev/null +++ b/1000_bots_webextension/manifest_ff.json @@ -0,0 +1,32 @@ +{ + "homepage_url": "http://1000scores.com/portfolio-items/mediengruppe-bitnik-1000-bots/", + "name": "Refuse to be Human — Surf the Web as Googlebot", + "short_name": "Refuse to be Human", + "browser_specific_settings": { + "gecko": { + "id": "trash@bitnik.org", + "strict_min_version": "55.0" + } + }, + "description": "Surf the Web as Googlebot. Ever wondered what the Googlebot get’s to see online that you do not?", + "version": "0.0.3", + "background": { + "scripts": [ + "background.js" + ], + "persistent": true + }, + "permissions": [ + "tabs", + "activeTab", + "webRequest", + "webRequestBlocking", + "storage", + "*://*/*" + ], + "browser_action": { + "name": "Click to change your browsers perspective", + "default_icon": "icon_OFF_48.png" + }, + "manifest_version": 2 +} diff --git a/1000_bots_webextension/old.background.js b/1000_bots_webextension/old.background.js deleted file mode 100644 index 34f592f..0000000 --- a/1000_bots_webextension/old.background.js +++ /dev/null @@ -1,79 +0,0 @@ -/* - 1000 Bots - Surf the Web as Googlebot - - Copyleft (C) 2020 !Mediengruppe Bitnik, connect@bitnik.org - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -*/ - -'use strict'; - -var browser = browser || chrome -var user_agent = "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"; -var target_urls = "*://*/*"; -var status = 0; - - -function set_extension_status_ON() { - status = 1; - //console.log('Setting status to ON'); - browser.browserAction.setIcon({path: 'icon_ON_48.png'}); - browser.browserAction.setTitle({title: "1000 Bots"}); -} - -function set_extension_status_OFF() { - status = 0; - //console.log('Setting status to OFF'); - browser.browserAction.setIcon({path: 'icon_OFF_48.png'}); - browser.browserAction.setTitle({title: "1000 Bots activate"}); -} - -function update_icon(){ - if(status == 0) { - set_extension_status_ON(); - }else{ - set_extension_status_OFF(); - } -} - - -function rewrite_user_agent_header(e){ - - //console.log('Browser http request!'); - - if(status == 0) { - // console.log('Nothing to do'); - return {requestHeaders: e.requestHeaders}; - } - - for (var header of e.requestHeaders) { - if (header.name.toLowerCase() === "user-agent") { - header.value = user_agent; - } - } - //console.log('Set user-agent header to: ' + user_agent); - return {requestHeaders: e.requestHeaders}; - -} - - -browser.runtime.onStartup.addListener(set_extension_status_OFF); -browser.browserAction.onClicked.addListener(update_icon); - -browser.webRequest.onBeforeSendHeaders.addListener( - rewrite_user_agent_header, - {urls: [target_urls]}, - ["blocking", "requestHeaders"] -); diff --git a/1000_bots_webextension/old.manifest.json b/1000_bots_webextension/old.manifest.json deleted file mode 100644 index e5ff046..0000000 --- a/1000_bots_webextension/old.manifest.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "homepage_url": "http://1000scores.com/portfolio-items/mediengruppe-bitnik-1000-bots/", - "name": "1000 Bots", - "browser_specific_settings": { - "gecko": { - "id": "trash@bitnik.org", - "strict_min_version": "55.0" - } - }, - "description": "Surf the Web as Googlebot. Ever wondered what the Googlebot get’s to see online that you do not?", - "version": "0.0.1", - "background": { - "scripts": ["background.js"], - "persistent": true - }, - "permissions": ["webRequest", "webRequestBlocking", "*://*/*"], - "browser_action": { - "name": "Click to change your browsers perspective", - "default_icon": "icon_OFF_48.png" - }, - "manifest_version": 2 -} diff --git a/1000_bots_webextension/package_me.sh b/1000_bots_webextension/package_me.sh new file mode 100755 index 0000000..cab6b78 --- /dev/null +++ b/1000_bots_webextension/package_me.sh @@ -0,0 +1,70 @@ +#!/bin/bash + +# Export folder +export_folder="packaged" + +# Name of the extension +extension_name="refused_to_be_human" + +# Files to include in the package +include_files="background.js content.js icon_OFF_48.png icon_ON_48.png manifest.json style.css" + +# Get the current version using jq to parse JSON (if jq is available) +current_version=$(jq -r '.version' manifest.json) + +# If jq is not available, fallback to a simpler grep (removing the -P flag) +# current_version=$(grep -o '"version": "[0-9.]*"' manifest_ff.json | grep -o '[0-9.]*') + +# Split version into major, minor, and patch +IFS='.' read -r major minor patch <<< "$current_version" + +# Increment the patch version by 1 +new_patch=$((patch + 1)) + +# Format the new version +new_version="$major.$minor.$new_patch" + +# Output the new version +echo "New version: $new_version" + +# Update version in manifest.json, manifest_ff.json, and manifest_chrome.json +for file in manifest.json manifest_ff.json manifest_chrome.json; do + if [ -f "$file" ]; then + # Use jq to update the version in each JSON file + jq --arg new_version "$new_version" '.version = $new_version' "$file" > tmp.json && mv tmp.json "$file" + echo "Updated $file to version $new_version" + else + echo "$file not found, skipping..." + fi +done + +# Replace version number in manifest_ff.json and chrome +sed -i "s/\"version\": \"$current_version\"/\"version\": \"$new_version\"/" manifest_ff.json +sed -i "s/\"version\": \"$current_version\"/\"version\": \"$new_version\"/" manifest_chrome.json + +folder_name="$extension_name-$new_version" + +# Create a new folder with the extension name and version inside the export folder if it doesn't exist +if [ ! -d "$export_folder/$folder_name" ]; then + mkdir -p "$export_folder/$folder_name" + echo "Created folder: $export_folder/$folder_name" +else + echo "Folder $export_folder/$folder_name already exists, skipping..." +fi + +# prepping firefox xpi +cp background_ff.js background.js +cp content_ff.js content.js +cp manifest_ff.json manifest.json +zip "$export_folder/$folder_name/$extension_name-$new_version.xpi" $include_files + +# prepping chrome file +cp background_chrome.js background.js +cp content_chrome.js content.js +cp manifest_chrome.json manifest.json +zip "$export_folder/$folder_name/$extension_name-$new_version.zip" $include_files + +# setting back to chrome manifest +cp background_chrome.js background.js +cp content_chrome.js content.js +cp manifest_chrome.json manifest.json \ No newline at end of file diff --git a/1000_bots_webextension/packaged/refused_to_be_human-0.0.2/refused_to_be_human-0.0.2.xpi b/1000_bots_webextension/packaged/refused_to_be_human-0.0.2/refused_to_be_human-0.0.2.xpi new file mode 100644 index 0000000000000000000000000000000000000000..87c64b748b6454e79e6dd476c948a174bfccf4b2 GIT binary patch literal 10850 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 literal 0 HcmV?d00001 diff --git a/1000_bots_webextension/packaged/refused_to_be_human-0.0.2/refused_to_be_human-0.0.2.zip b/1000_bots_webextension/packaged/refused_to_be_human-0.0.2/refused_to_be_human-0.0.2.zip new file mode 100644 index 0000000000000000000000000000000000000000..0b15515ffb2bfe22bae4b459f3f85bf699dccbf3 GIT binary patch literal 12142 zcmeHt1y>%?vgL=nyA#}lyGwBA!`~*I6wmcXSe_W0stRiXkcVz=4j_)Ys_Hj z1XO_mfNf7BoBcHxcQ^nD_&o>!@E@-?soU7$aiG4_y+!`oQ;^^{J1lY&B+iXe#;3*9 zp9m!zV2tc9cBPI$XxeaWb6i~bcrzXKneX_1_opw>HEgDnk42>3MFr}QmzSd>C{dE+ z4g$O~9|+67{me)&>Qm8z%I`X67h2Eiy&nf?U@^B8oje|HpaR;r3fJc4^PET5LTM7- z{GozkC`gljBM&V#cMDZSQ=*`Cs>)MG{(6)dP7(`)yew1ewJOx$bf7V55p#xFxQP9L zsQ#3njB5F5bo9vlGKKM0Ru#LRIsT5Jey7`gl!OjbWE;gs)S#`XAaSU2?}K+_={Ly3 zh~X*DW03}?5Y8ARETk&V@Y*|G2yoSCe-H!?rI-he6xIq@)4uGpm8M~`&+U;*n2tBS zKLC<^Ly1YE_>{3FSVTmfe``p<7$I8pQYXPCY}hf&_ToH6kWhs-FM(;LY5%sda~U>q%b8OPos&=@0$ zRCf)}swYkw2En4JadLZ=y0_Jfxe|b-mli+J7{Mu{gG2S- z^Nzr??2iZZcggpo%QZEAsg~<50T!oK(MRY_M!v%%rbT8Utu9h+hXw9&?~gRg2~TDO z3moZYXZ%Rt0i|JHo!IJ{ya2lFLRpes^#g;SmHXm`J4SZyUW*>?f804vqCGi$2L0lE z4$+Z4Myq8jNWSRBG?Km#MhTIMZN~2u=oy*5K8fFiY!{8b+@2T{+P$2>pKhTf^U}$+ zBiPxXv-j8HhDEuEX!Fiu$5~e|vT~HgI#Rq&u8C)Oh6k<1$273JgZkwM#C>>Pjm#|s zVRd+Rfbe_~@0W;83*|>?#Fl!!p(-A=RHmobQcH`B><%`rZFLDF3r!a^61eu?cb76< zaU@fn<^*BS54EkMntugawzQKTLN604EH<#2P9OwX&>826MY9n1N5?~;)0}5uh%h5m zSn4$8@Wkg2m7Z>mAHM}}?VQQ_g{-G+e0}}3c|o}6*76Dj7kFj}bnDpezqWn+5Oqk^ z+Mvfjc=4ZE46L~}4g@pHCZ=UA!sx0DGwbB+9nM$0=?hf4aa*2GlQ+*4RA*wEie2J0 ztD*VP6EeMd$-p1CfG%E^83-K-nQ0cQMVrOkO0M(61$VzVK_GDhgkm4s)?KbmEdrxG zO-kAG3q?HNEsONb^z=^AudOB5SQzPZtR2)x=2y|Oy{z+=V5fdXXDwd0htO=B_H%fi zcGmP=R~+u-tY(HD;zl^7@PW&;?jcPo`bp-Gi__}tkX||?8ZNiM)&uxB#0ay)c;lWD zUZ&N7=Amkn>!+}e8}Eu;1L6j;rnSlOeG%rTn5I_u7JX(hmqSwqubVx7zb2wfD4TH6 zMWu}_mk?HPoz?2YVhZnq!l%R-^O_K>2;oFtD=q+WI>|~=`6FHNmGvp-7csOt?a_Kd z5p*-9@GaSrxZu2!*H5IW-7SSf-fVs-9SV(^^*k^7A$3~o#J}FQBx=O(FLG+TnR5_- zC!Zz`7MQ*>O!}uHAFWFZ`$U5dVLwZO!@weED z^UM-jL&onC>v}^~dm!HX%@Dn>hatZ+Yk<1pBMru)CAU z*+9&`n?~+WY3tILv(7dw_6|%~}f@T^p9^(sdRwVO^Ige**_?e|xG;m38D35w8To z%%ADhggRC@dx?0quJ}+e6ENLaxP*v!Tbd-4nPTA(u=Ul(Z>4(%7r(sUI1`h5rgmY! z=0pN0GK0xy#2t;uRe zX0YD&qFd6kJ=^$9EAi7#X4_mgnT1GItb3|F<@{Wqf9kHbcg2{j_T|aFUoZjmHs$P|68hB<10%kk>8}?Tbjk-uZnmMT2CuHJD=3V z+w^#YP^AE0YUpepVAA>$>bB;te2}%Wg31G|Mzfl`foPe%o5xk@Wl2-Q8|>TSsV?

0A+*f!^l^8kev{r8LWB1Le6s=Ke4WOQPN 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 Gum1)5Y~0`g literal 0 HcmV?d00001 diff --git a/1000_bots_webextension/packaged/refused_to_be_human-0.0.3/refused_to_be_human-0.0.3.zip b/1000_bots_webextension/packaged/refused_to_be_human-0.0.3/refused_to_be_human-0.0.3.zip new file mode 100644 index 0000000000000000000000000000000000000000..4512005ff67e69522fbfdf6f0f420aaec84e02ee GIT binary patch literal 12718 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