Credits
Bachelor Thesis 2026

Concept and design:

Taylor Noelle Kovacevic

Tutors:

Thomas Bircher Viola Diehl

Programs used:

Asperite Photoshop Figma Godot Engine VS Code Claude AI (AI was strictly used for help with complex code, no images were generated) Thanks to Privacy Badger Further thanks to Invar-Torre Hollaus for being an excellent mentor during the theoretical thesis FHNW, Basel Academy of Art and Design Institute Digital Communication Environments Bachelor Visual Communication and Digital Spaces Specialization: Digital Spaces

© 2026 Taylor Noelle Kovacevic / FHNW HGK Basel

All rights reserved.
Theoretical thesis
My thesis will touch upon the technologies involved in the harvesting of data, the economic and political motivations and the ways in which the user can counter said harvesting. The technological portion will explain what cookies are and how they function in both beneficial and malicious ways. The history of cookies may also be touched upon if characters allow. While researching for the practice thesis I found myself recognizing patterns related to the motivations behind cookie/data usage. So, for this part, I find it important for the user to understand exactly why their data is being harvested and used to influence them, to reinforce the importance of data privacy. The economic motivations will mainly revolve around data brokers and how social media makes money off personal data. Politically I will mention various examples like Cambridge analytica, in which data was harvested and utilized to change electoral results. Adding to that I will also reflect critically on sources, as many can be rather contradictory and/or sponsored by biased companies. I will achieve this by presenting reliable sources and explaining my criteria. The last and arguably most important part will revolve around possible methods for users to counteract said data harvesting and how to implement them in a user-friendly way. This part will contribute to my project and vice versa, as my goal is to make said methods easily accessible through a tool. The main method of research will be through papers, though if possible, contacting organizations involved in fighting for data privacy would be beneficial. The main questions I would like to answer with my thesis and project are: - How do you spread awareness about data privacy? - How do you make privacy/tools more accessible? / How do you introduce users to privacy tools? My criteria for the thesis are for it to be easily accessible for non-technically knowledgeable consumers.
Concept Development
January
February
March
Base concept already clear, with a focus on digital privacy and the education of the average user on the subject. Though exactly how that would be achieved is undefined.
At this point the exact medium is discussed and narrowed
Plug-ins pondered about for the first time, alongside further possible ideas
Praxis/Creative Idea mindmap
Maybe just reduce to only a tool to help privacy
Makes it easier instead of a whole website
Maybe a tool of tools basically
Do you focus on stopping a consumer profile from being created or from being influenced by the targeted advertisement?
Essentially at what point in the chain do you stop it, the start or the end?
Everything is in the realm of tools
Maybe also making tools like that more accessible to people who don't know much about computer stuff
Final title brought up for the first time, alongside discussion about what can realistically be done
Possible title
Countering cookies: Democratizing Privacy

Notes
What can you possibly/realistically code?
Adblock
client side sure, server side?
Cookie tracker
Social Media Blocker?
Dekstop pet idea has been brought up for the first time during a presentation
Presentation Notes
Make sure you try to whittle down the scope
Really try to find people to test things
What differenciates your adblock from others
Try to visualize the data harvesting/consequences
digital assistant that tells you what cookies are on and what is getting blocked
maybe have it tell you things when you go on social media, and like, what the social media had for scandals
First concrete concept definition
First sketches delving into the Desktop Pet idea with a cat as the character, alongside improved thesis concept
June
Final concept, tool will be a web-plugin with an app if implementation works
Improved second concept, nearing the final practical thesis topic
Visual Development
AD-blocker
First concept that was later discarded. The ad-blocker wasnt fully designed, though mock-ups were attempted with a simple and clean look inspired by other ad-blockers like uBlock Origin.
Desktop Pet, Character
The Pixel art style makes its first appearance. Inspired by games like Deltarune, Balatro and Mina the Hollower I decided to apply the retro aesthetic to make the game more palatable towards the young adult audience. The decision was made to make the main cat sprites with the pixel art style.
A mix was used of Asperite for pixel art, photoshop for paintings and blender for the 3D animation for the character art.
While pixel art works great to quickly create character sprites and animations, the simplicity doesn't lend well to expression. In reference to the usage of the cat as a meme, it was decided to use different styles for each emotion, to make the expression clearer and more playful.
While theorising a potential pet customisation option, Raisin the guinea pig was conceptualised as a secondary pet that could be chosen instead of Chip. This idea was later discarded due to time constraints, with the idea of later implementation once the Bachelors project is finished.
First ever drawing of Chip. The cat aspect is the same, alongside the idea of giving him a fur color related to cookies, though the aesthetic is clean and futuristic. Chip here is more of a cyber-cat entering your browser to inform you about cookies.
Desktop Pet, GUI
The GUI began rather simple, sticking with the pixel aesthetic and attempting to incorporate colors coherent with the cat design. Initial designs were the icon, the radial menu and a basic settings menu. The only remaining design from this step is the icon, as the settings menu was redesigned and the radial menu was later removed.
At this step a basic text box was introduced, utilising the native windows app pop-up. This was merely due to me not knowing that could be disabled, so at this stage the text box is just a basic app window with the same color used previously for the radial menu and settings attempt.
Later attempts were made to refine the app window concept, to actually design its contents and add to the overall aesthetic of the app. Two main ideas were tried, the first being an AI inspired idea with sleek and modern design choices with the added white icon that acts according to the situation. While this idea was liked by mentors, my opinion was that it clashed too strongly with the design of the cat itself.
The second idea was trying to stick to the pixel/video game aesthetic, with adjustments to make it seem much more like an actual game window chip is using to communicate, alongside settings options.
While researching the game engine I am utilising for this project, Godot, I was made aware that animating text is rather easy. This step was merely cataloguing the different possibilities of animation that could be used later to further enhance the visuals of the GUI.
In a later occurence while coding, I stumbled upon the ability to make the app window transparent, thus only showing the contents. This lead to the first animated text box, growing in size with the size of the text.
By side, the plug-in utilised to feed tracker data to the app was modified from the original look of privacy badger. The additions serving to add the pixel aesthetic to remain consistent with the app. Due to the fact this is intended to be removed in later versions and time constraints this was the only extent of the designing.
After middling success with the last few designs, I went back to brainstorming, reaching two possible ideas for the GUI as described below. The windows history idea in my mind seemed the most promising, so further care was taken to create a plug-in design and later on implement it within the app.
Demos created to give an idea of what the different styles would look like in context during a tracker warning.
Third and last redesign after feedback from the last mentoring. The windows UI idea was widely rejected, while the cyber terminal aesthetic was seen as more cohesive, yet lacking. With this last attempt at redesigning the UI I started from scratch choosing a color palette based off Chip. One being the colorful palette and the other being a complementary contrast palette. These colors were analysed for various issues like contrast, if they work together, and color blindness conflicts.
Disbelief/Confusion
First attempts at emotions
Final emotions, not all were used
Confusion
Anger/Shock
Mad
Fear
Happy/Pleased
Nerd face
Congratulations
Radial menu triggered on cat click. Buttons shown in idle and clicked state
Default PB window
First changes on the UI
Final UI design
Info box on the left is windows vista, the grey dialogue box is windows 98, the black button box below is windows 10
Plug-in design with the windows UI
Cyber terminal idea inspired by games I played, heavy use of code like elements like the chip.exe name and the binary code in the back
Windows UI history demo, added pop-up sounds to further enhance the windows OS theme
Cyber terminal demo, pop-up noises used here too, though ones much more in line with the video game theme
Alternative icons mixing many different designs from previous eras
Colorful palette
Contrast palette
Tests for various color blindness, only noticeably conflict is with tritanopia
Tests for contrast, what works with which colors and in what context
First experiments on figma
Pixel art renditions of the GUI in the same colors
Settings Menu
Tracker Menu
Dialogue box
Button Box
Information box
The final step with the UI was to make it accessible for tritanopia, as it was the only color blindness with potential issues. The fix here was to separate the orange from the red much more clearly, for people to be able to differentiate these colors. With the red being turned into a dark purple, it should be seen as a dark and muddy pink for someone with tritanopia.
Based off the colors chosen I began experimenting with various combinations, quickly figuring out which ones work together the best. After the base experiments on figma I created the GUI on Asperite as pixel art in these various colors.
After many attempts to find the right combinations I came to use the blue hues, the red and the orange, with the idea being of utilising these colors in consistent ways to after some use should feel intuitive. The blues are used as background to highlight its contents, the red is used for the informational layer of the app showcasing settings or warnings, and the orange is the interactive layer that a user can press, slide or scroll with. Each box was further detailed with outlines, shadows and highlights to add dimension to them, with the dialogue box being given slight texture to set it apart from the rest of the GUI.
App Development
App Development
AD-Blocker Idea
The initial idea was a simple ad-blocker. The code for it was relatively simple, utilising a normal browser extension structure alongside a list of “rules” being known domains ads are shown with, thus blocking most ads, as testing proved. A quick mock-up was done for a presentation before the idea was fully scrapped.
Desktop pet, version 0.1.0
The first attempt at the desktop pet after abandoning the ad-blocker idea. After having created base walking and sitting sprites, they were coded into the app. In this version all that Chip does is walk from left to right. The big step here being able to code the cat to recognise the size of the screen and move accordingly at the bottom left to right.
Desktop pet, version 0.2.0
Development on version 0.2 began with defining what functions the app could have, mainly considering feedback and assessing what could be realistically done within the given time. The next step was to define what actions the pet should have, to better prepare for the coding process.
The app itself had a few features added, mainly giving the cat idling logic, meaning instead of just walking the pet was now tied to a random timer that decided between sleep, walk or stand, a radial menu for options and a basic textbox for Chip to communicate with.
Walk animation is enabled
Alongside the walk animation, Chip can now recognise where the screen ends and walk accordingly
Few functions and emotions weren’t added to due either time constraint or difficulty coding
Idling logic added
Radial menu added
Basic text box examples
Command prompt showing websocket connection through a relay, later on the relay would be removed and the connection would be direct
Chip now shows emotions based off the amount of trackers found on a website
Animated text box
Emotion rules based off how many trackers and fingerprinters were found
Desktop pet, version 0.3.0
Version 0.3 is where the bulk of the browser implementation occurred, and where most time was spent. Early on, it was clear that the app itself could not talk to the browser without a lot of effort and security issues within the computer, so the choice was made to pair the app with a browser plug-in. This browser plug-in would connect to the app via a websocket, and send the tracker and url data to the desktop pet. Here is where the bulk of the coding occurred, alongside AI usage, as websocket connections and data transfer is beyond my capabilities. For disclosure, the only parts that utilised AI are the websocket data transfer and processing and debugging code where needed.
Other than the websocket, a transparent text box was implemented.
To summarise, version 0.3 now connects to the browser and has the cat react to the data, though not very well. Chip also has a new, animated text box,
Desktop pet, version 0.4.0
Version 0.4 was mainly about refining a lot of the established functions in 0.3. The tracker reactions were catalogued as “moods”, depending on the tracker amount. These moods detailed exactly how the cat should act and what windows should open for how long. Alongside that the screentime feature was added, starting a 5 minute timer when a social media site is loaded, after which the user is prompted by Chip. The windows UI was implemented as well, here seen as an animated text box. Alongside the box, Chip was given a sound for the first time, based off games like deltarune I sampled a meowing sound that within the program repeats per letter shown.
Desktop pet, version 0.5.0
Having finished most of the code, the remaining parts to be done are implementing the new UI and refining its behaviour, as at times it would overlap wrong or text would leave the box. In this step the radial menu was removed after feedback and a settings and info menu were added as a replacement. The info menu functions to show the user how many trackers and fingerprinters were currently present and to give them resources for further information. Here a feeding functino was also added, making chip eat the total cookies collected. The settings menu has the ability to change the font size for the dialogue and information, alongside a tritanopia mode added for accessibility. A small part was adding an ad recognition function, that reacts based off which websites you’re visiting. As I was unable to make an actual ad recognition script, I cheated by collecting websites that are known or seem to have a a lot of ads, when a user visits those sites, they are prompted by chip.
All in all this last version was about implementing the last parts and refining the app before it had to be handed in. Further work will be done after this project.
Example of a mood
New text box added
Voice added, sampled from a cat’s meowing
Showcase of a GUI error, text exiting box
Various new GUI implementations, here information box and dialogue box
Ad recongition code, showing urls that trigger the mood
Various Chip reactions, trackers and screentime
Showcase of settings menu with tritanopia mode enabled
Ads reaction Chip
Social media reaction from Chip
Settings demo
Daily Overview

26/01/26

Mindmap

Visuals for first hand-in

https://cambridge-intelligence.com/visualizing-cyber-security-graphs-data-breaches/

Sentence for first hand-in

How do you counteract the loss of privacy instigated by cookies and spyware? This project aims to visualise and aid the regular consumer in understanding the problem and taking steps to solve it for themselves.

How do you make privacy accessible to the average consumer?

27/01/26

Praxis/Creative Idea mindmap

Maybe just reduce to only a tool to help privacy

  • Makes it easier instead of a whole website
    • Maybe a tool of tools basically
  • Do you focus on stopping a consumer profile from being created or from being influenced by the targeted advertisement?
    • Essentially at what point in the chain do you stop it, the start or the end?

Notes

Look at what the law says

Try to narrow the scope of data privacy

  • You'd think to do swiss law but all the apps and Internet are essentially US centred

Critically question everything, especially sources.

28/01/26

Other possible ideas

Everything is in the realm of tools

  • Maybe also making tools like that more accessible to people who don't know much about computer stuff

29/01/26

Meeting 1 with Invar

Before meeting notes:

possible title is countering cookies, the focus of the written part now goes from the consequences to how to counter the data theft and preventing influence from the targeted advertisement. Cookies will still be explained and examples will still be given, specifically ones mentioned in the grading email (Musk, Thiel, Palantir). The part about how to counter the cookies will directly relate to the praxis part of the bachelor.

Meeting notes:

Explain things simpler

Touch more on the political side

Critique sources and mention why you didnt use some

  • Write about how to recognise sponsored papers and fake papers,
  • forensic architecture, belincat, are those good alternatives
  • Find one really good example for sources and how to go about it, explain why they are good

explain your position clearly, where are your critiques situated

How does the public understand the topic

  • Public is still relatively lead astray
  • what possibilities does the public have to find good sources

Memorial in russia, activists

What possibilities does one have to critique fairly, is anonymity trustworthy. Authority is important?

Even a government has their ideals, look at the website for UNO, the un right? Also peace institutes, institutes against hate towards minorities, look at statements from them or deals they made for the digital discrimination

Grok wikipedia and image generation, saving personal rights, minors etc. In this case the EU has good laws.

02/02/26

Possible title

Countering cookies: Democratizing Privacy

Notes

Possibly find an expert to email

03/02/26

Notes

What can you possibly/realistically code?

  • Adblock
    • client side sure, server side?
  • Cookie tracker
  • Social Media Blocker?

Current mockup for presentations, mainly and a concept showcase, it’s still unclear how many of these features i can fully accomplish.

  • again, ad blocker def doable. Cookie tracking too, the rest idk.

05/02/26

Notes

Cambridge analytical Robert mercer was heavily involved with Jeffrey Epstein in colluding for the 2016 election.


Presentation Notes

Make sure you try to whittle down the scope

Really try to find people to test things

What differenciates your adblock from others

Try to visualize the data harvesting/consequences

  • digital assistant that tells you what cookies are on and what is getting blocked
    • maybe have it tell you things when you go on social media, and like, what the social media had for scandals

All watched over by machines of loving grace by Richard Brautigan

I like to think
(it has to be!)
of a cybernetic ecology
where we are free of our labors
and joined back to nature,
returned to our mammal
brothers and sisters,
and all watched over
by machines of loving grace.

14/02/26

presentation ideas

what if you prepared your laptop to be the ideal for privacy, so that you have a hands on example you can show?

  • for ex. linux distro like omarchy, librewolf, mullvad or own adblock, other possible private/opensource apps
    • omarchy is rather easy (rather, it’s still arch)
    • librewolf or any other fork of firefox should be good
    • technically for emails and cloud storage there’s proton but yknow there’s still servers with your data

16/02/26

Meeting 2 with Invar

Pre-meeting notes:

Thesis will be split into explaining the chain of events:

How data gets taken, how it’s processed, how it’s organised and then how it’s used

The part after explains the motivations, building up on the last part “how its used”. Talking about the political and monetary motivations and why said companies cant be trusted.

Then bring in one specific source and explain why they themselves are trustworthy. As well as explaining what makes certain apps or tech trustworthy i.e transparency and being opensource.

Last step is to explain to the reader how to protect themselves with examples that fit the above mentioned criteria for different use cases. This also ties in with my own tool.

Meeting notes:

Dont stick with like, good/bad. Maybe in the introduction use an example to show what its about and what the consequences are

Its interesting to explain where the responsibility of the algorhythm is and where that of the person, who makes the algorhythms

Looks at alternative providers/platforms, look at how they do with data and what their data management is. Are they as good?

Compare the market leaders with the alternative or opensource providers

Dont just list off examples for data harvesting, just keep to comparing what the market leaders say and do to that of the alternatives

Dont play the highground, dont be the morale police, stay with the facts. Which possibilities do you have? You dont have to use em but if you do what does it provide and how transparent is it with it’s data?

What do you wanna show or give as an alternative?

How do you get into these mechanisms/ ecosystems?

Why do people use certain apps? What gets them into it?

There’s a ton of aspects, so just narrow it down about what you wanna do maybe linked to your practical project

Work on which apsects you like most

Precise critique and analysis about what providers do and how easy it would be to be actually transparent and how they purposefully make it to be hard

  • the things are so hidden and written so complicated

Explain a good platform with transparent and clear data collection

  • explain what the consequences are if you just accept and not read

So explain how the big platforms make it to understand the cookies and the consequences and explain how to do it better with examples?

  • With this you go away from a good/bad morale thing, stay factual talking about what all apps take from data
  • Each company has certain values or motives, so explain maybe if the values fit the reality of the company, maybe do the slogans fit with their identity, is what they preach actually implemented.

How did the platforms change their algorhythsm or data cookies accept things change since facebook, meta whatever existed. Did it get better with criticism? Everyone is mad but does nothing, so what can people do to change and do better? Are alternatives better?

06/03/26

meeting 3

Pre-meeting notes:

I guess just, do the things i wrote make sense for the structure

So he mentioned using current examples to amplify how important it is to be transparent. Is it smart to use CA as the initial example bc it’s concise, easy to understand what went wrong, to introduce the topic, then in the conclusion to strengthen my point mention current world examples.

Meeting notes

Which initiatives are started to better the situation?

Compare different positions, do people actually do things against data theft? What are the different positions?

Talk about how not much got better, so mention people like Karp and Thiel who dont care about transparency

Mention CA and then later current examples, alongside good

Noone knows about these huge corpos or people, if they dont put themselves in the light and then put themselves in places where they can change a lot from the background

  • it’s interesting how little poeple know and how little the news actually talk about them

Try to find pictures, show them multiple times maybe?

Maybe put the bigger corpos in the background and instead mostly focus on the alternatives, are they actual good alternatives, what do they offer?

Small companies often got bought, would mean they would have no influence on their app anymore, so the big corpos would

12/03/26

Project mentoring 1

Calendar might have, to plan what you’re exactly doing when.

What is your target group?

What else can you do, can you make it a campaign?

Inject things where the ads arent anymore

Maybe work with explaining what data is taken in an easy manner

How can you make people more easily aware, how can you present the topic etc.

18/03/26

THESIS MEETING 3

Good intro, dimension is explained well

Pictures

Look at what sources were deleted, mention what sources i had to find backed up on the wayback machine. Maybe discuss what sort of sources are better. Maybe in the body or in the conclusion as a way to criticise how information is deleted to be even less transparent towards the user

  • have i been able to answer my questions, are there new questions?
    • is the internet really a good source of information?
    • What happens when companies control access to information?

Give an outlook about what could be done further to stop this deletion of data, what can laws do etc.

Who makes the laws, is it the EU, Country, or the companies

Where is the problem exactly, would it help to have digital experts in brussels instead of just lobbyists, since companies like meta are just so advanced

Do not put the criticism in the body, put it in the conclusion. Offer solutions, do not repeat, go into each aspects and put em toghether

Mention how companies want to train AI on dead people data

Print pics, look at them in chronological order

Laws are very varied in the EU despite the unified front, haven countries exist that destroys the goals of the GDPR

  • Structure of EU itself is more of an issue
  • Experts are needed, lobbyists removed

07/04/26

So supposedly to inject images into ads instead of blocking them you have to change the

action: block to action:redirect and have it redirect to an image URL

Issue is, what if i have multiple. Do i put them in an array and try to get it to choose a random?

20/04/26

Questions were asked to copilot github AI to understand the Catblock picture redirection code, these are the answers.

How CatBlock redirects ads to images

  • filtering/* files parse AdBlock rules and decide which requests are ads.
  • background.js checks each resource request and flags blocked image/object/frame requests.
  • When a blocked ad resource is detected, it sends a purge-elements message to the page.
  • adblock_start_chrome.js finds the element whose src/data matched that ad URL and hides it.
  • contentscript.js contains picinjection, which then inserts a replacement <img> into the hidden ad slot.
  • That replacement image uses CSS background:url(...), sized and positioned to fill the original ad area.
  • In Safari, adblock_start_safari.js uses beforeload and destroyElement() to hide blocked elements, then also calls picinjection to show pictures.
  • So the extension does not truly redirect HTTP traffic; it blocks the ad and replaces the blocked element in the DOM with an image.

To make the ad redirection template actually usable as a working browser extension, you'll need to implement several key components that are currently placeholders or simplified. Here's what you need to add, organized by category:

1. Filter System Implementation

The template has placeholder isAdUrl() and loadFilters() functions. You need:

// Real filter parsing (replace the placeholder)
function loadFilters() {
    // Parse AdBlock-style rules from text
    // Example rule formats: ||ads.example.com^, /ads/*.jpg
    const rules = parseFilterRules(filterText);

    return {
        blocking: {
            matches: function(url, elType, domain) {
                return rules.some(rule => rule.matches(url, elType, domain));
            }
        }
    };
}

// Filter rule parser
function parseFilterRules(text) {
    return text.split('\\n')
        .filter(line => line.trim() && !line.startsWith('!'))
        .map(line => new FilterRule(line));
}

// Filter rule class
class FilterRule {
    constructor(ruleText) {
        this.text = ruleText;
        this.regex = this.parseToRegex(ruleText);
    }

    parseToRegex(rule) {
        // Convert AdBlock syntax to regex
        // ||domain.com^ -> ^https?://[^/]*domain\\.com[^a-zA-Z0-9.-]
        // Handle wildcards, anchors, etc.
    }

    matches(url, elType, domain) {
        return this.regex.test(url);
    }
}

2. Picture Source System

Replace the placeholder getRandomPictureUrl() with actual image fetching:

// Picture database/manager
const PictureManager = {
    pictures: [], // Array of {url, width, height, attribution}

    async loadPictures() {
        // Fetch from API or local storage
        // For CatBlock, this would load cat pictures
        this.pictures = await fetch('/api/pictures').then(r => r.json());
    },

    getRandomPicture(width, height) {
        // Find pictures that fit the dimensions
        const candidates = this.pictures.filter(p =>
            p.width >= width && p.height >= height
        );
        return candidates[Math.floor(Math.random() * candidates.length)];
    }
};

// In the template, replace:
function getRandomPictureUrl(width, height) {
    const pic = PictureManager.getRandomPicture(width, height);
    return pic ? pic.url : 'fallback-image.jpg';
}

3. Browser Extension Manifest

Create manifest.json:

{
    "manifest_version": 3,
    "name": "Ad Redirector",
    "version": "1.0",
    "permissions": [
        "webRequest",
        "webRequestBlocking",
        "storage",
        "tabs",
        "activeTab"
    ],
    "host_permissions": ["<all_urls>"],
    "background": {
        "service_worker": "background.js"
    },
    "content_scripts": [{
        "matches": ["<all_urls>"],
        "js": ["content.js"],
        "run_at": "document_start"
    }]
}

4. Element Matching Improvements

The current findElementsByUrl() is basic. Add more robust matching:

function findElementsByUrl(url, elType) {
    const elements = [];

    // Handle different URL variations (absolute, relative, protocol-relative)
    const urlVariations = generateUrlVariations(url);

    urlVariations.forEach(variation => {
        const selector = createSelectorForUrl(variation, elType);
        const found = document.querySelectorAll(selector);
        elements.push(...Array.from(found));
    });

    return elements;
}

function generateUrlVariations(url) {
    const parsed = new URL(url);
    return [
        url, // full URL
        parsed.pathname + parsed.search, // path + query
        '//' + parsed.host + parsed.pathname, // protocol-relative
        parsed.pathname // just path
    ];
}

5. Storage and Settings

Add persistent storage for filters and user preferences:

// In background.js
async function loadUserFilters() {
    const { filters } = await chrome.storage.local.get('filters');
    return filters || getDefaultFilters();
}

async function saveUserFilters(filters) {
    await chrome.storage.local.set({ filters });
}

// Settings for enabling/disabling picture injection
const settings = {
    enabled: true,
    pictureSource: 'cats', // or 'random', 'custom'
    // ... other settings
};

6. Error Handling and Edge Cases

Add comprehensive error handling:

// Wrap async operations
async function safeInjectPicture(selector, elType) {
    try {
        await injectPicture(selector, elType);
    } catch (error) {
        console.error('Picture injection failed:', error);
        // Fallback: just hide the element
        const element = document.querySelector(selector);
        if (element) element.style.display = 'none';
    }
}

// Handle network failures
function getRandomPictureUrl(width, height) {
    return PictureManager.getRandomPicture(width, height)
        .catch(() => 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'); // 1x1 transparent
}

7. Performance Optimizations

Add caching and debouncing:

// Cache element selectors
const elementCache = new Map();

function getCachedElements(url, elType) {
    const key = `${url}-${elType}`;
    if (elementCache.has(key)) {
        return elementCache.get(key);
    }

    const elements = findElementsByUrl(url, elType);
    elementCache.set(key, elements);
    return elements;
}

// Debounce rapid requests
const purgeQueue = [];
let purgeTimeout;

function queuePurge(request) {
    purgeQueue.push(request);
    clearTimeout(purgeTimeout);
    purgeTimeout = setTimeout(() => {
        processPurgeQueue();
    }, 100);
}

8. Security and Privacy

Add content security policy and input validation:

// Validate URLs before processing
function isValidUrl(url) {
    try {
        new URL(url);
        return true;
    } catch {
        return false;
    }
}

// Sanitize user input for custom filters
function sanitizeFilterInput(input) {
    // Remove dangerous characters, validate regex patterns
    return input.replace(/[<>]/g, '');
}

9. User Interface

Add popup/options pages for managing filters and settings:

<!-- popup.html -->
<div>
    <button id="toggle">Enable/Disable</button>
    <button id="openOptions">Options</button>
</div>

10. Testing and Debugging

Add logging and test utilities:

const DEBUG = true;

function log(...args) {
    if (DEBUG) console.log('[Ad Redirector]', ...args);
}

// Unit tests for filter matching
function testFilters() {
    assert(loadFilters().blocking.matches('<http://ads.example.com/banner.jpg>', 'image', 'example.com'));
    assert(!loadFilters().blocking.matches('<http://example.com/logo.png>', 'image', 'example.com'));
}

Implementation Priority

Start with:

  1. Basic filter parsing and matching
  1. Element finding and hiding
  1. Simple picture replacement
  1. Manifest and extension setup

Then add:

  • Advanced filter features
  • Picture management system
  • Settings and storage
  • Error handling and performance optimizations

The template provides the architectural skeleton - these additions will make it a fully functional ad redirection extension.

This is my first attempt at chip

Catblock replacing images

21/04/26

Mentoring 2

App usage implementation, so show how much certain apps are used

Aesthetic changes maybe with time? Maybe sudden 3D, abstract

Think about 5 scenarios and then make specific visuals just for that, to show

Why am i making something? How do i do that?

  • All in all just decide on 5 scenarios to work on, work lots on visuals, maybe even prototypes. Just experiment lots. Lots of cat pictures, animations, maybe try to mix media?

22/04/26

Initial sprites for Chip

29/04/26

Picked up with cursor

Intermediate Presentation Feedback

EFF extension that helps tracking things, it’s for firefox. It’s opensourcehttps://www.eff.org/deeplinks/2019/07/eff-extensions-recommended-firefox

Maybe keep to the extension idea bc making a program would be too complicated unless backdoor

Maybe feed the cat with cookies

Concentrate on the metaphor if you cant finish the app

Explain things things with the cat, maybe as the cookies grow then the cat grows. Translate everything in cat language.

Add functions with like, making the animal taken care of, customize, feed it etc.etc.

04/05/26

Mentorat 4

My opinion is make it plugin, makes it easier to get direct browser data, to not have to circumvent privacy and security features from OS.

A lot of approach is playful, you feed the cat with cookies, to make him smaller again you have to turn on the adblocker etc.

What should the functions be, what could it do?

…………….

AI recognition, can it see

Perhaps a prototype for the future

Plug-in arent smth people wanna download, make it interesting and trustworthy to download, make it appealing

cat eats cookies, could be bad cookies and cat reacts badly, maybe cpvers screen

cat social media thing

05/05/26

EFF privacy badger:

Observes Fingerprinting, supercookies, pixel cookies

Observes cross-site tracking

Can send Do not track requests, if rejected Badger will block that site

11/05/26

Added idling logic. The cat now, when not prompted with anything, will move, sleep or look around on it’s own.

15/05/26

Added window and dialogue. Window opens when triggered by specific events, same with the dialogue.

16/05/26

added pick up logic only for a time, removed until i can simplify script

Code from AI to be analyzed for understanding and potential use/simplification

extends Node2D
var move_speed = 5
var direction = Vector2(1, 0) 
var is_chilling = false
var current_states 
enum cat_states{WALK, SLEEP, IDLE}
var selected = false
var mouse_offset = Vector2(0, 0)
# Flag set when the left button is held on the sprite/window.
var dragging_pressed = false
# Time the button has been held down during a drag.
var press_hold_time = 0.0
# How long the left button must be held before showing the pick animation.
var pick_animation_delay = 1.0
# Tracks whether the pick animation is waiting to play after the hold delay.
var pending_pick_animation = false
# Remember the original window position so it can return after release.
var home_window_position = Vector2i()
var return_to_origin = false
# How fast the window returns to its home position.
var return_speed = 0.2

var dir
var state_timer = 0.0
var walk_duration = 4.0
var sleep_duration = 8.0
var idle_duration = 3.0

var mywin = preload("res://mywindow.tscn")
var dialogue_window
var dialogue_manager

func _input(event):
	# Handle left mouse button press and global release
	if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT:
		if event.pressed:
			$AnimatedSprite2D/RadialMenuButton.toggle_menu()
			
			if not is_chilling:
				start_chilling()
			
			# Show the dialogue window when clicked
			show_click_dialogue()
		elif selected:
			# Stop dragging if the button is released anywhere.
			selected = false
			dragging_pressed = false
			pending_pick_animation = false
			press_hold_time = 0.0
			return_to_origin = true
			update_state()


# Function to show the dialogue window with specific lines - can be called from click or other events
func show_dialogue_window(lines: Array[String]):
	dialogue_window.visible = true
	dialogue_manager.start_dialogue(lines)

# Specific dialogue for clicking
func show_click_dialogue():
	show_dialogue_window(["Hey!!!!!!", "Dont touch me!!!!!"])

# Function to hide the dialogue window
func hide_dialogue_window():
	dialogue_window.visible = false

func random_generation():
	# Weighted random: 75% sleep, 15% walk, 10% idle
	var rand_value = randf()
	if rand_value < 0.75:
		dir = 0  # SLEEP
		state_timer = sleep_duration
		print("State: SLEEP Duration: ", state_timer)
	elif rand_value < 0.9:
		dir = 1  # WALK
		state_timer = walk_duration
		print("State: WALK Duration: ", state_timer)
	else:
		dir = 2  # IDLE
		state_timer = idle_duration
		print("State: IDLE Duration: ", state_timer)
	random_direction()
	
func random_direction():
	match dir:
		0:
			current_states = cat_states.SLEEP
		1:
			current_states = cat_states.WALK
		2: current_states = cat_states.IDLE
	update_state()

func update_state():
	match current_states:
		cat_states.WALK:
			move_speed = 5
			$AnimatedSprite2D.play("walk")
		cat_states.SLEEP:
			move_speed = 0
			$AnimatedSprite2D.play("sleep")
		cat_states.IDLE:
			move_speed = 0
			$AnimatedSprite2D.play("look_around")


func _ready() -> void:
	
	get_viewport().set_embedding_subwindows(false)
	# Instantiate the dialogue window and add it as a child
	dialogue_window = mywin.instantiate()
	add_child(dialogue_window)
	
	# Get reference to the dialogue manager
	dialogue_manager = dialogue_window.get_node("HBoxContainer/DialogueManager")
	
	# Set window properties
	dialogue_window.position = Vector2(800, 800)
	dialogue_window.title = "Chip wants to talk"
	dialogue_window.size = Vector2(300, 300)
	# Hide the window initially
	dialogue_window.visible = false
	# Connect the close button to hide the window
	dialogue_window.close_requested.connect(hide_dialogue_window)
		
	random_generation()
	update_state()
	$Timer.wait_time = state_timer
	$Timer.start()
	if is_chilling:return
	
	
	var window = get_window()
	
	get_viewport().transparent_bg = true
	window.transparent = true
	
	window.borderless = true
	
	window.always_on_top = true
	
	window.unresizable = false
	
	var usable_rect = DisplayServer.screen_get_usable_rect()
	
	var target_y = usable_rect.end.y - window.size.y
	
	var target_x = usable_rect.end.x - window.size.x
	
	window.position = Vector2i(target_x, target_y)
	home_window_position = window.position
	
	_update_mouse_mask()
	$AnimatedSprite2D.frame_changed.connect(_update_mouse_mask)
	
	
	
	
	Engine.max_fps = 30
	
	
func _process(_delta):
	if selected:
		# While dragging is active, move the window with the mouse.
		if not Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT):
			selected = false
			dragging_pressed = false
			pending_pick_animation = false
			press_hold_time = 0.0
			return_to_origin = true
			update_state()
			return

		followMouse()
		return

	if dragging_pressed and not selected:
		# Only begin dragging after the hold delay has passed.
		press_hold_time += _delta
		if press_hold_time >= pick_animation_delay:
			var window = get_window()
			var screen_mouse = DisplayServer.mouse_get_position()
			mouse_offset = Vector2(window.position.x, window.position.y) - Vector2(screen_mouse.x, screen_mouse.y)
			selected = true
			$AnimatedSprite2D.play("pick")
			pending_pick_animation = false
		return

	if return_to_origin:
		return_to_origin = returnWindowToOrigin()
		return

	var window = get_window()

	#this moves the pet
	var move_vector = Vector2i(direction*move_speed)
	window.position += move_vector
	#this returns where it can move, the safe area
	var usable_rect = DisplayServer.screen_get_usable_rect()
	
	if window.position.x + window.size.x > usable_rect.end.x:
		direction.x = -1
		$AnimatedSprite2D.flip_h = true
		
	elif window.position.x < usable_rect.position.x:
		direction.x = 1
		$AnimatedSprite2D.flip_h = false

func _update_mouse_mask():
	var anim = $AnimatedSprite2D
	
	var texture = anim.sprite_frames.get_frame_texture(anim.animation, anim.frame)
	var image = texture.get_image()
	
	if anim.flip_h:
		image.flip_x()
	
	var bitmap = BitMap.new()
	bitmap.create_from_image_alpha(image)
	
	var polygons = bitmap.opaque_to_polygons(Rect2(Vector2.ZERO, texture.get_size()), 0.1)
	
	DisplayServer.window_set_mouse_passthrough(polygons)
	
func start_chilling():
	is_chilling = true
	$AnimatedSprite2D.play("idle")
	move_speed = 0
	await get_tree().create_timer(3.0).timeout
	
	is_chilling = false 
	update_state()

	
func _on_timer_timeout():
	random_generation()
	update_state()
	$Timer.wait_time = state_timer
	$Timer.start()
	
	# Example: Trigger specific dialogue based on the new state
	# Here, when Chip enters the SLEEP state, show a sleep-related dialogue
	if current_states == cat_states.SLEEP:
		show_dialogue_window(["Chip is sleeping...", "Zzz..."])
	


func followMouse():
	var window = get_window()
	var screen_mouse = DisplayServer.mouse_get_position()
	# Follow the cursor by moving the whole OS window, preserving the offset from the initial press.
	window.position = Vector2i(Vector2(screen_mouse.x, screen_mouse.y) + mouse_offset)
	


func returnWindowToOrigin() -> bool:
	var window = get_window()
	# Smoothly move the window toward the home position each frame.
	var current = Vector2(window.position.x, window.position.y)
	var target = Vector2(home_window_position.x, home_window_position.y)
	var next_pos = current.move_toward(target, 16)
	window.position = Vector2i(next_pos.round())
	if window.position == home_window_position:
		return false
	return true

func _on_area_2d_input_event(_viewport, event, _shape_idx):
	if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT:
		if event.pressed:
			# Start the hold timer, but don't begin drag immediately.
			dragging_pressed = true
			press_hold_time = 0.0
			pending_pick_animation = true
			return_to_origin = false
		else:
			# Only snap back if the drag was actually active.
			if selected:
				selected = false
				return_to_origin = true
				update_state()
			dragging_pressed = false
			pending_pick_animation = false
			press_hold_time = 0.0

Return to origin function works by setting a few var at the start:

  • return_to_origin, home_window_position = Vector2i()

and set return to false. When it it supposed to be true, you put it in an if statement and make it equal the function

if return_to_origin is true:

return_to_origin = returnWindowOrigin

return

Now the actual logic begins in the function. The func is set as a bool by doing:

func returnWIndowOrigin() → bool:

Bool just means a variable that can only detect true or false, can be used in if statements. That’s why the previous code worked.

then you get the window, simply:

var window = get_window() / get window is an inbuilt func

Now you need to define where the window currently is, what the target position for the return is, and what the next position will be (to move it toward the target)

var current = Vector2(window.position.x, window.position.y) / just get where window is now

var target = Vector2(home_window_position.x, home_window_position.y) / set target to be the original position of window

var next_pos = current.move_toward(target, 16) / take the current pos and move it towards the target with a speed of 16 (16 measured in delta, a time measurement within gdscript)

Then you set the window position as next pos, meaning it will return to the original position

window.position = Vector2i(next_pos.round()))

Then you set an if statement, setting if window pos and home pos are the same, nothing happens

if window.position == home_window_position:

return false

return true / this is for the previous window is next pos to be true

19/05/26

MENTORAT 5

Work on GUI, animations, charts, etc. Design as well. Work on the presentaton of the info

  • Reference to average, more than last time, more than average
  • Take one situation, design it 5 times GUI

Make the interaction with the cat interesting.

Style not too different: Not necessarily different style but moreso chip should stay the same color

  • Dither pic is off

How to present app

  • live demo
  • Video

21/05/26

Varied attemps at UI design

Petting animation

Improved anger sprite, made it closer to actual design

Improved the nerd face

27/05/26

Various emotions

28/05/26

Sprites for possible alternate pet

29/05/26

Interim presentation 2

Consider how to have the pet act between tabs, is it multiple cats for each tab, is it just one?

how does the cat talk to you, since in the browser itself it cant open a native window. Maybe it injects speech into the html of a website?

Explore more with dynamics of the cat, the size and expressions, mainly size and how it interacts with the whole screen.

Guinea pig might be not good to express emotion

when presenting make sure that you effectively explain how the app works, preferably by showing it in the browser and showing what data is getting taken from where, maybe like, do a whole browser presentation? Maybe by injecting code about your project into tabs, switching tab to tab for what you wanna say

31/05/26

Issues with app to extension

The main issue currently is trying to figure out if the app can become an extension that could be implemented within browsers

https://www.youtube.com/watch?v=TgLxdEA6f04

Very technically i could do this, essentially implementing the desktop pet within one window that is launched, that then fetches data from the whole broswer

One could also assume, since you can code HTML5 games, you could conceivably export the godot part, add the privacy badger part and have it work on browsers

After forum questions and ai asking, it appears that using pure godot on the browser leads to heavy cpu usage, meaning the browser usability and performance tanks. It seems the best option is to forgo the web-extension only idea to go with a bridge.

  • Websocket or Native messaging

// background.js (service worker style)
let ws;
function connect() {
ws = new WebSocket("ws://localhost:12345");
ws.onopen = () => console.log("Connected to Godot");
ws.onmessage = e => {
const msg = JSON.parse(e.data);
// forward to content scripts if needed
chrome.tabs.query({}, tabs => {
for (const t of tabs) {
chrome.tabs.sendMessage(t.id, msg);
}
});
};
ws.onclose = () => setTimeout(connect, 1000);
}
connect();

// receive from content scripts and forward to Godot:
chrome.runtime.onMessage.addListener((msg, sender) => {
if (ws && ws.readyState === WebSocket.OPEN) ws.send(JSON.stringify(msg));
});

// content_script.js
// receive messages from background
chrome.runtime.onMessage.addListener((msg) => {
if (msg.type === "show_notification") {
// example: create overlay or highlight something
console.log("From Godot:", msg);
}
});

// send page event to background (forwarded to Godot)
window.addEventListener("click", e => {
chrome.runtime.sendMessage({ type: "page_click", x: e.clientX, y: e.clientY });
});

01/06/26

Websocket

A websocket is an api that allows two-way messaging between the browser and a server/client. (API by itself already means two applications talking between eachother)

Script wise all you need is a main file that sets up the server that the browser will utilize to send messages and a file within the target application that connects to said server.

source: developer.mozilla.com

so in short client sends a “handshake” http request with details in the header specifying the kind of connection wanted. The server responds to the http get “handshake” request with accepting and upgrading to a websocket if details are correct and server can verify an actual not malicious client. Server sends a key, that is then encoded into a hash that verifies the handshake. Both the client and the server have a key each. If header is missing or key is not correct data will not be exchanged.

Websockets fragment data to prevent buffer overload.

02/06/26

Websocket

Implemented first part with PB data

let ws;

function connectWS() {
  ws = new WebSocket("ws://localhost:8765");

  ws.onclose = () => {
    // Retry connection every 5 seconds
    setTimeout(connectWS, 5000);
  };

  ws.onerror = () => {
    ws.close(); // triggers onclose, which retries
  };
}

connectWS();

async function pushTrackerData(tabId) {
  if (ws.readyState !== WebSocket.OPEN) return;

  const { action_map, snitch_map, tracking_map } =
    await chrome.storage.local.get(["action_map", "snitch_map", "tracking_map"]);

  const tab = await chrome.tabs.get(tabId);
  if (!tab.url) return;

  const hostname = new URL(tab.url).hostname;

  const pageTrackers = Object.entries(action_map || {}).filter(([domain]) => {
    return snitch_map?.[domain]?.includes(hostname);
  });

  ws.send(JSON.stringify({
    type: "tracker_update",
    url: hostname,
    trackers: pageTrackers,
    fingerprinters: Object.keys(tracking_map || {}).filter(d =>
      tracking_map[d]?.includes("canvas")
    )
  }));
}

function startBackgroundListeners() {
  chrome.tabs.onUpdated.addListener(function(tab_id, changeInfo, tab) {
    if (badger.INITIALIZED && changeInfo.status == "complete" && tab.url) {
      badger.updateIcon(tab.id, tab.url);
      badger.updateBadge(tab_id);
      pushTrackerData(tab_id); // ← just call the function here
    }
  });

  chrome.tabs.onReplaced.addListener(function(addedTabId) {
    if (badger.INITIALIZED) {
      chrome.tabs.get(addedTabId, function(tab) {
        badger.updateIcon(tab.id, tab.url);
      });
    }
  });

  chrome.tabs.onActivated.addListener(function(activeInfo) {
    if (badger.INITIALIZED) {
      badger.updateBadge(activeInfo.tabId);
    }
  });
}

Modified Extension look for Chipblock

03/06/26

New attempts to correct issue with Dialogue boxes

Feedback was that it wasnt clear Chip was talking, plus that you got the feeling you could reply

04/06/26

Added custom icon plus changed the name for all languages. For now it’s english in all languages, but if time remains in the end i will make it custom in each language.

05/06/26

Improvements on base popup

07/06/26

Adding richtextlabel animations

"[wave amp=30 freq=5 speed=3 ease=2.0]Hey!!!!!![/wave]”

"[pulse freq=1.0 ease=2.0]Hey!!!!!![/pulse]”

"[tornado radius=10.0 freq=3.0 connected=1]Hey!!!!!![/tornado]”

"[shake rate=20.0 level=5 connected=1]Hey!!!!!![/shake]”

[rainbow freq=1.0 sat=0.8 val=0.8 speed=1.0]

Added text box and animated it according to text size

var is_dialogue_active: bool = false




func _ready() -> void:
	dialogue_box.visible = false
	start_dialogue(["Hey!!!!!!you're meannnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
	and horrible and a lot of stuff that is annoying and i will kill you",
					"Dont touch me!!!!!"])

func start_dialogue(lines: Array[String]):
	dialogue_lines = lines
	current_line_index = 0
	is_dialogue_active = true
	dialogue_box.visible = true
	dialogue_text.bbcode_text = dialogue_lines[current_line_index]
	dialogue_text.reveal_text()
	




func advance_dialogue():
	if current_line_index < dialogue_lines.size() -1:
		current_line_index += 1
		dialogue_text.bbcode_text = dialogue_lines[current_line_index]
		dialogue_text.reveal_text()
		
	else:
		#get_tree().paused = false
		is_dialogue_active = false
		dialogue_box.visible = false
		

08/06/26

Experimenting with transparent windows

Looks nice, issue is you cant close it easily and you cant use whatever is behind the text

Managed to fix the issues with the box, mainly that it wouldnt grow for big text, it would just crop. Took a long time filled with stress and AI.

Extension and godot are now connected

rudimentary tracking logic now applies

10/06/26

Attempts to redesign UI

Moodboard

Ideas

Windows UI history design idea

11/06/26

Terminal idea

Demo video

12/06/26

Second demo video

Alternate idea for more varied icons

13/06/26

Potential Browser recognition features?

Could be used to give advice on what browser to use

Added social media function, timer counts to 5 minutes then prompts user with question if they did something productive

15/06/26

Functions

Cookies:

Warn

Recommend browsers or extensions

When detected they were removed chip is fed

Ads:

Recommend browsers or extensions

Social media:

Try to get out of it

Recommen alternatives

  • Ex. WhatsApp to signal etc

Others:

When pet chip will give random advice

Question tab on chip gives detailed view of cookies detected plus explains what they are

Window logic added

16/06/26

Mentoring

feed cat stored amount of cookies stored over last week

lots of testing

Presentation

  • Set the stage, what is cb
    • Set a clear problem at the start, why should we worry about people not knowing you could be private?
      • Elections, ID scans, social media bans, teens not being tech literate
    • Set solution, CB teaches you how to optimize your browser in a fun and engaging way without disrupting your usual browsing. Explain in VERY short what it is, you will explain more later.
    • give short review
    • Give links to follow
  • Why did it make it?
    • Here go in depth also about the conclusions from the thesis
    • Main point is, people hate friction. Research and testing is friction, So why not give people an app that functions passively, is fun to have, and informs them about alternatives and issues without them feeling forced to go out and look through dozens of articles and reviews. This is still a demo, the full end goal if for it to just be one full app, to reduce friction even more.
    • Maybe explain who this is for? Younger adult/ older teen who grew up with ipads and macbooks that doesnt know well about tech
    • explain design choices, popularity of retro aesthetic, tamagotchi, pixel art in many video games
  • How would you use it? Explain use case
    • Give 3 concrete functions:
      • Cookies
      • ADS
      • Social media
  • How was it designed?
    • Young people dislike sleek clean minimalist approach, thus pixel and colorful.
  • How does it work?
    • Very short technical explanation
  • What would the perfect outcome be after using CB?

What is the narrative?

chip ver 0.1: Animations, basic walking screen to screen recognizing boundaries

chip ver 0.2: idling logic added with different cat states cycling, radial menu added for options, basic text box

chip ver 0.3: added browser plugin, cat now reacts to websites and their cookies, text box improved with animated text, animated box. Box is overall smaller. Browser plugin modified to send data to chip through websocket, also window for plugin redesigned.

chip ver 0.4: text box redesign with windows history UI, now cat fully reacts cookies, trackers etc, the reactions actually last and user actually gets prompted based on amount of cookies and given advice.

18/06/26

Third and last design overhaul

Color palette based off of chip, to make the design unified

Complementary palette for contrast, mainly the blue

Various tests checking for colorblindness and visibility

Testing color combinations

Various assets created in pixel artstyle in different colors

Two of many attempts at combinations

Final assets

21/06/26

Implemented new UI, slight improvements needed

Implemented info box on cat click with settings, removed radial menu

22/06/26

Fully implemented screentime warning

screentime pop-up errors to show progress

23/06/26

Ad recognition implementation

since privacy badger cant detect ad servers it cant tell you if there’s ads directly, potential alternatives could be:

  • assume user isnt using adblockers, when urls known for ads detected then start the script telling the user about ublock etc.

websites added to react to ad pop-up


Added total trackers seen plus way to feed chip the cookies

24/06/26

Improved settings

Added exit buttons and close program, personalised slider. Fixed the font sizing bugs

Dialogue

Cookies:

1. No cookies or fingerprints

No trackers or fingerprinters found! :3

2. few cookies

A few trackers were found… :0

Nothing too worrying, though keep in mind that third-party tracking data can still pile and be used to target you in various ways. Cookie-blocker extensions or another browser would be helpful, as cookies can be easily blocked. Check your browser settings, you might find some options to block them!

3. few cookies and fingerprint

A few trackers AND fingerprinters were found!! :c

While trackers are worrying, the actual concerns lies with the fingerprinters found, as they are hard to detect, block, delete and function without consent. To avoid being profiled consider privacy focused browsers, extensions or look at your browser settings. Do you want any recommendations?

https://www.reform.app/blog/device-fingerprinting-vs-cookies

https://coveryourtracks.eff.org/learn

yes:

Recommendations vary on browsers, specifically on what privacy means for the user and how easy it is to use. Brave is a great start, as it blocks everything by default. Firefox is another good option, though extensions like uBlock origin will be needed. Open-source options also exist like the Mullvad Browser, LibreWolf, Zen Browser and Waterfox.

You’ll only need extensions if your browser doesnt already block cookies, fingerprinting or ads. But for good overall extensions Privacy Badger and uBlock Origin will do a good job.

Keep in mind that privacy comes at the cost of accessibility, some websites may break, some browsers might be difficult to understand. That is the price for privacy nowadays.

no:

Alright, keep the warnings in mind though!

4. A lot of cookies and fingerprints

There’s so many trackers!!!!!!!! AAAAAAAAAAAAA >:0

This website contains more than 10 individual trackers and multiple fingerprinters. While some cookies can be used for accessibility and ease of use, this many alongside the amount of fingerprinters is concerning. I would not recommend browsing without privacy protection. Have you thought about browsers or extentions? Do you need recommendations?

https://www.reform.app/blog/device-fingerprinting-vs-cookies

https://coveryourtracks.eff.org/learn

yes:

Recommendations vary on browsers, specifically on what privacy means for the user and how easy it is to use. Brave is a great start, as it blocks everything by default. Firefox is another good option, though extensions like uBlock origin will be needed. Open-source options also exist like the Mullvad Browser, LibreWolf, Zen Browser and Waterfox.

You’ll only need extensions if your browser doesnt already block cookies, fingerprinting or ads. But for good overall extensions Privacy Badger and uBlock Origin will do a good job.

Keep in mind that privacy comes at the cost of accessibility, some websites may break, some browsers might be difficult to understand. That is the price for privacy nowadays.

no:

Understandable, just keep in mind that you are browsing tracker-heavy sites. Privacy focused browsers like brave or firefox are quite easy to use and set up, it’s worth researching it.

Social media:

Booooo social media is baaaaaad!!!!!!! >:c

You’ve spent 5 minutes on social media!! Did you do anything productive today?

yes:

That’s good, relaxing after some work is understandable then. Just keep in mind that the largest collectors of data nowadays are socials like tiktok, instagram, Facebook etc. These services can still be used, but keep in mind the data they have about you. If you are truly concerned, alternatives like Bluesky exist, functioning as an open-source model that can be self-hosted.

https://epic.org/issues/consumer-privacy/social-media-privacy/

no:

You should probably get off then and get to work! Or do something fun! Social media is designed to keep you glued to your screen, which is achieved by collecting data about you. The algorhythms you may have heard about utilise data to microtarget posts or advertisements. These can be used for nefarious purposes too, like in the Cambridge Analytica case in 2018. And with AI being a huge industry, and firms like Oracle and Palantir weaponizing data as a service, your data is worth more than ever. Consider using open-source alternatives like Bluesky.

https://epic.org/issues/consumer-privacy/social-media-privacy/

ADS:

Do you really wanna see ads… : p

Are you currently seeing ads?

yes:

Well, i assume you dont want to see them, as it would be letting all kinds of cookies and fingerprinters do their job and help microtarget products to you based on your data. Using browsers like Brave, Firefox, Mullvad, or extensions like uBlock Origin will block ads quite effectively and save you a good amount of time.

no:

oh, that’s good! Good on you for using a good browser or an extension.

25/06/26

Added dialogue and improved presentation with animations

Tritanopia mode added because color palette showed issues with that specific color blindness

Attempt at shaders to amplify retro aesthetic

27/06/26

Testing feedback

Info box too big, make it smaller

  • Maybe shorten the text? Unsure if this should be implemented as this may be in conflict with my initial idea of a somewhat annoying but informational interaction

Put everything in focus

  • Sometimes buttons take two presses, as box is not in focus. Attempt to put the info window permanently in focus

Plug-in loading into browser too complicated