Repository: tmr232/function-graph-overview
Pull request #151: Include settings & color-scheme when sharing in the demo #84
Author: login: Nivb1569
Created: 2025-04-03T14:34:31Z | Merged: 2025-04-17T19:37:22Z

## Type of changes

- [x] Bug fix
- [x] New feature
- [x] Documentation / docstrings
- [ ] Tests
- [ ] Other

## Checklist

- [x] I've run the `bun lint` on the code.
- [x] I've updated CHANGELOG.md and CONTRIBUTORS.md where appropriate.
- [ ] I've added tests for new code.
- [ ] For visual changes, I've added screenshots to the PR.
- [x] I accept that @tmr232 may be pedantic in the code review.

## Description

**Pull Request Summary**

Added `onMount` import (line 10): This ensures the color scheme is updated only once when the page loads.

Initialized color scheme (line 83): Now retrieves the color scheme when the demo first loads.
I chose not to place this in the `run` function, as doing so would prevent users from updating the color scheme later via state changes.

Added support for new query parameters in the URL:

`fontSize`

`simplify`

`flatSwitch`

`highlight`

`version`

`colorList` (compressed)

**URL version:**
Introduced to support future changes to the URL structure without breaking backward compatibility for shared links.
When a new format is introduced, the currentVersion variable should be incremented accordingly.

**Moved fontSize parsing (from line 112 to line 74):**
This was done to ensure it’s parsed early with the other URL parameters.

**URL structure:**
fontSize, simplify, flatSwitch, and version are added as-is to the URL to save space, while colorList is compressed.

**Fixed language comparison bug (previously line 129 → now line 169):**
The condition now compares language values rather than objects.
This solves a bug where clicking “Share” again after loading a shared link would incorrectly reset the language to the default (Go).

Changed the “Share (experimental)” label to simply “Share”.

Updated CHANGELOG.md with all relevant changes.

Closes #84 

Linked issue #84: Include settings & color-scheme when sharing in the demo
Currently only the code is maintained, so when you share - someone might see something visually different than what you shared!
Linked issue comments: user: login: Nivb1569
created_at: 2025-03-27T15:35:12Z
body: Hi Tamir,
We are starting to work on this issue too.
author_association: CONTRIBUTOR
user: login: tmr232
created_at: 2025-03-27T18:18:34Z
body: Ah, great :)

I am now realizing that I need to provide a lot more info on those issues... I'll try to do that in the future.

As for this one - I think we should try to share the following:

- The _currently displayed_ code (we don't wanna share the other languages as people might not expect it to be shared)
- The color scheme
- The settings (highlight, flat switch, simplify checkboxes)
(I think that's all the relevant state - I hope I'm not missing anything).

Additionally, we should include a "schema version number" of sorts (basically, `{"version":1}`).
This will allow us to change the format in the future and add/remove fields without breaking older shared links.
author_association: OWNER
user: login: Nivb1569
created_at: 2025-03-27T18:44:20Z
body: Great! Thank you for the information.
Let me know if there are any updates or anything you’d like me to look into.
author_association: CONTRIBUTOR

Diff:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 72bcf0b6..46e70c83 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -14,17 +14,22 @@ Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how
 - Added support for "special" function detection and process-terminating nodes in the graph.
   This is currently only enabled in the `/render` page to slowly build up a collection of
   functions to match and confidence in the representation before adding to the main tool.
+- When changing the code language, the URL is updated to reflect that.
 
 ### Fixed
 
 - Multiple `catch` clauses in C++ are now handled properly, even in case of comments between them.
 - Segmentation of `catch` clauses in C++ is now a lot better.
+- Fixed an issue where after sharing and reopening the page, clicking the "Share" button again would default the language back to Go instead of preserving the selected one.
 
 ### Changed
 
 - The `bun typedoc` command was renamed to `bun docs`, as some contributors had issues
   with unexpected recursion in the command. It is also a nicer name.
 - Language definitions are now more unified, making it easier to add new languages.
+- `language` URL query parameter now takes language name instead of index.
+- Sharing now shares full config in addition to code.
+- Sharing now uses the `compressed=` query parameter for all information.
 
 ## [0.0.15] - 2025-03-26
 
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index 7515c076..c7de511c 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -5,4 +5,5 @@ The following people have contributed to the development of Function-Graph-Overv
 <!-- Add your name below, sort alphabetically by surname. Link to GitHub profile / your home page. -->
 
 - [Tamir Bahar](https://github.com/tmr232)
+- [Niv Baumel](https://github.com/Nivb1569)
 - [buherator](https://github.com/v-p-b)
\ No newline at end of file
diff --git a/README.md b/README.md
index 85fc2cef..4d2fbdb4 100644
--- a/README.md
+++ b/README.md
@@ -43,7 +43,7 @@ You can change to a different preset via the settings:
 
 ### Custom Color Schemes
 
-Custom color schems are created via the [interactive demo](https://tmr232.github.io/function-graph-overview/).
+Custom color schemes are created via the [interactive demo](https://tmr232.github.io/function-graph-overview/).
 
 1. Enable the `Color Picker` above the graph
 2. Select the colors you want for your color scheme<br/>
@@ -54,9 +54,9 @@ Custom color schems are created via the [interactive demo](https://tmr232.github
 
 ## Supported Languages
 
-- [Go](https://tmr232.github.io/function-graph-overview/?language=0)
-- [C](https://tmr232.github.io/function-graph-overview/?language=1)
-- [C++](https://tmr232.github.io/function-graph-overview/?language=3)
-- [Python](https://tmr232.github.io/function-graph-overview/?language=2)
-- TypesScript & TSX
-- JavaScript & JSX
+- [Go](https://tmr232.github.io/function-graph-overview/?language=go)
+- [C](https://tmr232.github.io/function-graph-overview/?language=c)
+- [C++](https://tmr232.github.io/function-graph-overview/?language=cpp)
+- [Python](https://tmr232.github.io/function-graph-overview/?language=python)
+- [TypesScript](https://tmr232.github.io/function-graph-overview/?language=typescript) & [TSX]((https://tmr232.github.io/function-graph-overview/?language=tsx))
+- [JavaScript](https://tmr232.github.io/function-graph-overview/?language=typescript) & [JSX]((https://tmr232.github.io/function-graph-overview/?language=tsx))
diff --git a/src/components/Demo.svelte b/src/components/Demo.svelte
index d0ffcd3e..bc9756bd 100644
--- a/src/components/Demo.svelte
+++ b/src/components/Demo.svelte
@@ -7,6 +7,7 @@ import { javascript } from "@codemirror/lang-javascript";
 import { python } from "@codemirror/lang-python";
 import type { LanguageSupport } from "@codemirror/language";
 import * as LZString from "lz-string";
+import { onMount } from "svelte";
 import type { Language } from "../control-flow/cfg";
 import { evolve } from "../control-flow/evolve.ts";
 import CodeSegmentation from "./CodeSegmentation.svelte";
@@ -69,47 +70,125 @@ let languages: {
   },
 ] as const;
 
-const urlParams = new URLSearchParams(window.location.search);
-if (urlParams.has("go")) {
-  languageCode.Go = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("go"),
-  );
-}
-if (urlParams.has("c")) {
-  languageCode.C = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c"),
-  );
-}
-if (urlParams.has("c++")) {
-  languageCode["C++"] = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c++"),
-  );
-}
-if (urlParams.has("python")) {
-  languageCode.Python = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("python"),
-  );
-}
-if (urlParams.has("typescript")) {
-  languageCode.TypeScript = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("typescript"),
-  );
-}
-if (urlParams.has("tsx")) {
-  languageCode.TSX = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("tsx"),
-  );
+type ShareParameters = {
+  version: number;
+  language: string;
+  code: string;
+  fontSize: string;
+  simplify: boolean;
+  flatSwitch: boolean;
+  highlight: boolean;
+  colors: ColorList;
+};
+
+// ADD-LANGUAGES-HERE
+const languageAliases: Record<string, Language> = {
+  go: "Go",
+  c: "C",
+  cpp: "C++",
+  python: "Python",
+  typescript: "TypeScript",
+  tsx: "TSX",
+};
+
+function languageToAlias(language: Language): string {
+  for (const [alias, lang] of Object.entries(languageAliases)) {
+    if (lang === language) {
+      return alias;
+    }
+  }
+  throw new Error(`No alias found for language "${language}"`);
 }
 
+const currentVersion: number = 1; // Needs to be updated when a new version is released.
+let fontSize = $state("1em");
 let simplify = $state(true);
 let flatSwitch = $state(true);
 let highlight = $state(true);
+let parsedColorList = undefined;
+const urlParams = new URLSearchParams(window.location.search);
+let isLanguageInURL: boolean = false;
+let selection = $state(languages[0]);
+
+if (urlParams.has("language")) {
+  isLanguageInURL = true;
+  const urlLanguage = urlParams.get("language");
+  const language = languageAliases[urlLanguage];
+  const requestedLanguage = languages.find(
+    (lang) => lang.language === language,
+  );
+  if (requestedLanguage) {
+    selection = requestedLanguage;
+  } else {
+    console.error(`Unsupported language alias: '${urlLanguage}'`);
+  }
+}
+
+/*
+ * Parses URL parameters according to version 1 format.
+ *
+ * This version expects a single `compressed` parameter containing a compressed JSON
+ * with all necessary configuration, including:
+ *
+ * - version
+ * - language
+ * - code
+ * - fontSize
+ * - simplify
+ * - flatSwitch
+ * - highlight
+ * - colors
+ *
+ * This format makes the URL more compact and easier to extend in the future.
+ *
+ * Notes:
+ * - If both `language` and `compressed` are present,
+ *   `compressed` will be ignored and an error will be logged to the console.
+ * - If language is provided, the default code sample for that
+ *   language is used.
+ */
+
+if (urlParams.has("compressed")) {
+  if (isLanguageInURL) {
+    console.error(
+      "Cannot provide both `language` and `compressed` in the URL.",
+    );
+  } else {
+    try {
+      const parsedData = JSON.parse(
+        LZString.decompressFromEncodedURIComponent(urlParams.get("compressed")),
+      );
+      if (parsedData.version === 1) {
+        fontSize = parsedData.fontSize;
+        simplify = parsedData.simplify;
+        flatSwitch = parsedData.flatSwitch;
+        highlight = parsedData.highlight;
+        parsedColorList = parsedData.colors;
+        const language = languageAliases[parsedData.language];
+        if (language) {
+          selection = languages.find((lang) => lang.language === language);
+          languageCode[language] = parsedData.code;
+        }
+      }
+    } catch (exception) {
+      console.error(
+        "Failed to parse configuration compressed data from URL:",
+        exception,
+      );
+    }
+  }
+}
+onMount(() => {
+  if (parsedColorList) {
+    colorList = parsedColorList;
+  }
+});
+
 let colorPicker = $state(false);
 let verbose = $state(urlParams.has("verbose"));
 let showSegmentation = $state(urlParams.has("segmentation"));
 let showRegions = $state(urlParams.has("showRegions"));
 let debugMode = urlParams.has("debug");
-let fontSize = $state("1em");
 const range = (start: number, end: number) =>
   Array.from({ length: end - start }, (_v, k) => k + start);
 const fontSizes: { label: string; value: string }[] = [
@@ -117,17 +196,24 @@ const fontSizes: { label: string; value: string }[] = [
   ...range(8, 31).map((n) => ({ label: `${n}`, value: `${n}px` })),
 ];
 
-let selection = $state(
-  languages[Number.parseInt(urlParams.get("language"))] ?? languages[0],
-);
-
 function share() {
-  const compressedCode = LZString.compressToEncodedURIComponent(
-    languageCode[selection.language],
+  const code = languageCode[selection.language];
+  const codeAlias = languageToAlias(selection.language);
+  const colorConfig = colorList;
+  const parameters: ShareParameters = {
+    version: currentVersion,
+    language: codeAlias,
+    code,
+    fontSize,
+    simplify,
+    flatSwitch,
+    highlight,
+    colors: colorConfig,
+  };
+  const compressed = LZString.compressToEncodedURIComponent(
+    JSON.stringify(parameters),
   );
-  const codeName = selection.language.toLowerCase();
-  const language = languages.findIndex((lang) => lang === selection);
-  const query = `?language=${language}&${codeName}=${compressedCode}`;
+  const query = `?compressed=${compressed}`;
   const newUrl = `${window.location.protocol}//${window.location.host}${window.location.pathname}${query}`;
   navigator.clipboard.writeText(newUrl);
   window.open(newUrl, "_blank").focus();
@@ -196,6 +282,21 @@ function onToggleClick(e) {
   toggleTheme();
 }
 
+function onSelectionChanged(e) {
+  try {
+    console.log(selection);
+    const languageAlias = languageToAlias(selection.language);
+    const url = new URL(window.location.href);
+    const parameters = url.searchParams;
+    parameters.set("language", languageAlias);
+    parameters.delete("compressed");
+    url.search = parameters.toString();
+    window.history.replaceState(null, "", url);
+  } catch (exception) {
+    console.error("Could not update URL with selected language:", exception);
+  }
+}
+
 isDark.subscribe(() => {
   colorList = getSystemColorList();
 });
@@ -232,7 +333,7 @@ isDark.subscribe(() => {
       <div class="controls">
         <select
           bind:value={selection}
-          onchange={(e) => console.log(selection)}
+          onchange={(e) => onSelectionChanged(e)}
         >
           {#each languages as language}
             <option value={language}>
@@ -247,7 +348,7 @@ isDark.subscribe(() => {
             </option>
           {/each}
         </select>
-        <button onclick={share}>Share (experimental)</button>
+        <button onclick={share}>Share</button>
       </div>
       <div class="codemirror">
         <Editor


Reviews:
user: login: tmr232
body: Thanks for the PR!

It seems to work well, but there are a few changes I want to make.

I think the entire shared data should go in a single query parameter.
That single parameter should be a JSON serialized object with all the rest of the data inside it, including the version number.
That way, when there is an update, we can modify things without the users seeing that or being affected.

Additionally, I want users to still be able to link to a specific language (not code, just a language setting) as it makes it easier to tell people "here, use this with C code" if they don't need to change the selected language.

Please tell me if you have any further questions - it seems I was not clear enough the first time, and I don't want to make you do duplicate work.
state: CHANGES_REQUESTED
author_association: OWNER
submitted_at: 2025-04-04T12:57:30Z
user: login: tmr232
body: This is looking much better!

There are still some changes I'd like to see though.
Mostly around error handling and code structure.

Thank you for contributing!
state: CHANGES_REQUESTED
author_association: OWNER
submitted_at: 2025-04-11T07:59:36Z
user: login: Nivb1569
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-13T07:43:54Z
user: login: Nivb1569
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-13T07:52:51Z
user: login: Nivb1569
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-13T07:53:26Z
user: login: Nivb1569
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-13T08:03:22Z
user: login: Nivb1569
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-13T08:03:39Z
user: login: Nivb1569
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-13T08:13:36Z
user: login: Nivb1569
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-13T08:14:00Z
user: login: Nivb1569
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-13T08:21:08Z
user: login: tmr232
state: COMMENTED
author_association: OWNER
submitted_at: 2025-04-13T09:59:54Z
user: login: tmr232
state: COMMENTED
author_association: OWNER
submitted_at: 2025-04-13T10:01:14Z
user: login: tmr232
state: COMMENTED
author_association: OWNER
submitted_at: 2025-04-13T10:01:49Z
user: login: tmr232
body: This is looking much better, great work!

Still a few things to fix though, and you need to update the branch.

Also - feel free to add yourself to the `CONTRIBUTORS.md` file.
state: CHANGES_REQUESTED
author_association: OWNER
submitted_at: 2025-04-14T17:44:00Z
user: login: Nivb1569
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-16T06:31:57Z
user: login: Nivb1569
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-16T06:33:16Z
user: login: Nivb1569
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-16T06:37:28Z
user: login: Nivb1569
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-16T06:37:51Z
user: login: Nivb1569
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-16T06:43:37Z
user: login: Nivb1569
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-16T06:48:22Z
user: login: tmr232
body: So the code looks a lot nicer, and I don't really have comments on that.
But it seems that this PR breaks the color-picker feature.

With this patch, if you use the color-picker to change the colors - they don't change at all.
Please solve this bug.
state: CHANGES_REQUESTED
author_association: OWNER
submitted_at: 2025-04-16T19:20:52Z
user: login: tmr232
body: I have no idea what changed - but it works on my machine now.
state: APPROVED
author_association: OWNER
submitted_at: 2025-04-17T19:35:44Z

Review comments:
diff_hunk: @@ -69,65 +70,106 @@ let languages: {
   },
 ] as const;
 
+let currentVersion: number = 1; // Needs to be updated when a new version is released.
+let fontSize = $state("1em");
+let simplify = $state(true);
+let flatSwitch = $state(true);
+let highlight = $state(true);
+let parsedColorList = undefined;
 const urlParams = new URLSearchParams(window.location.search);
-if (urlParams.has("go")) {
-  languageCode.Go = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("go"),
-  );
-}
-if (urlParams.has("c")) {
-  languageCode.C = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c"),
-  );
-}
-if (urlParams.has("c++")) {
-  languageCode["C++"] = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c++"),
-  );
-}
-if (urlParams.has("python")) {
-  languageCode.Python = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("python"),
-  );
-}
-if (urlParams.has("typescript")) {
-  languageCode.TypeScript = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("typescript"),
-  );
-}
-if (urlParams.has("tsx")) {
-  languageCode.TSX = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("tsx"),
+let selection = $state(
+  languages.find(
+    (lang) =>
+      lang.language.toLowerCase() === urlParams.get("language")?.toLowerCase(),
+  ) ?? languages[0],
+);
+/**
+ * Parses URL parameters according to version 1 format.
+ *
+ * This version expects a single `data` parameter containing a compressed JSON
+ * with all necessary configuration, including:
+ *
+ * - version
+ * - language
+ * - code
+ * - fontSize
+ * - simplify
+ * - flatSwitch
+ * - highlight
+ * - colors
+ *
+ * This format makes the URL more compact and easier to extend in the future.
+ *
+ * Notes:
+ * - If `data` is present, it overrides all other URL parameters.
+ * - If `language` is provided without `data`, the default code sample for that
+ *   language is used.
+ */
+
+if (urlParams.has("data")) {
+  const parsedData = JSON.parse(
+    LZString.decompressFromEncodedURIComponent(urlParams.get("data")),
   );
+  if (parsedData.version === 1) {
+    fontSize = parsedData.fontSize;
+    simplify = parsedData.simplify;
+    flatSwitch = parsedData.flatSwitch;
+    highlight = parsedData.highlight;
+    parsedColorList = parsedData.colors;
+    selection = languages.find(
+      (lang) => lang.language.toLowerCase() === parsedData.language,
+    );
+    if (parsedData.language === "go") {
+      languageCode.Go = parsedData.code;
+    } else if (parsedData.language === "c") {
+      languageCode.C = parsedData.code;
+    } else if (parsedData.language === "c++") {
path: src/components/Demo.svelte
user: login: tmr232
body: `c++` is tricky to write in a URL, as you need to encode it, so it's better if we go for something like `cpp`.
created_at: 2025-04-11T07:27:53Z
author_association: OWNER
diff_hunk: @@ -69,65 +70,106 @@ let languages: {
   },
 ] as const;
 
+let currentVersion: number = 1; // Needs to be updated when a new version is released.
+let fontSize = $state("1em");
+let simplify = $state(true);
+let flatSwitch = $state(true);
+let highlight = $state(true);
+let parsedColorList = undefined;
 const urlParams = new URLSearchParams(window.location.search);
-if (urlParams.has("go")) {
-  languageCode.Go = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("go"),
-  );
-}
-if (urlParams.has("c")) {
-  languageCode.C = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c"),
-  );
-}
-if (urlParams.has("c++")) {
-  languageCode["C++"] = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c++"),
-  );
-}
-if (urlParams.has("python")) {
-  languageCode.Python = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("python"),
-  );
-}
-if (urlParams.has("typescript")) {
-  languageCode.TypeScript = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("typescript"),
-  );
-}
-if (urlParams.has("tsx")) {
-  languageCode.TSX = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("tsx"),
+let selection = $state(
+  languages.find(
+    (lang) =>
+      lang.language.toLowerCase() === urlParams.get("language")?.toLowerCase(),
+  ) ?? languages[0],
+);
+/**
+ * Parses URL parameters according to version 1 format.
+ *
+ * This version expects a single `data` parameter containing a compressed JSON
+ * with all necessary configuration, including:
+ *
+ * - version
+ * - language
+ * - code
+ * - fontSize
+ * - simplify
+ * - flatSwitch
+ * - highlight
+ * - colors
+ *
+ * This format makes the URL more compact and easier to extend in the future.
+ *
+ * Notes:
+ * - If `data` is present, it overrides all other URL parameters.
+ * - If `language` is provided without `data`, the default code sample for that
+ *   language is used.
+ */
+
+if (urlParams.has("data")) {
+  const parsedData = JSON.parse(
+    LZString.decompressFromEncodedURIComponent(urlParams.get("data")),
   );
+  if (parsedData.version === 1) {
+    fontSize = parsedData.fontSize;
+    simplify = parsedData.simplify;
+    flatSwitch = parsedData.flatSwitch;
+    highlight = parsedData.highlight;
+    parsedColorList = parsedData.colors;
+    selection = languages.find(
+      (lang) => lang.language.toLowerCase() === parsedData.language,
+    );
+    if (parsedData.language === "go") {
+      languageCode.Go = parsedData.code;
+    } else if (parsedData.language === "c") {
+      languageCode.C = parsedData.code;
+    } else if (parsedData.language === "c++") {
+      languageCode["C++"] = parsedData.code;
+    } else if (parsedData.language === "python") {
+      languageCode.Python = parsedData.code;
+    } else if (parsedData.language === "typescript") {
+      languageCode.TypeScript = parsedData.code;
+    } else if (parsedData.language === "tsx") {
+      languageCode.TSX = parsedData.code;
path: src/components/Demo.svelte
user: login: tmr232
body: This piece of control-flow can better be expressed via data. 
It will make it easier to modify in the future (as we add languages), and allow TypeScript to work for us.

Consider the following:

```typescript
const languageAliases:Record<string, Language> = {
  "go":"Go",
  "cpp":"C++",
  // ...
}

const language = languageAliases[parsedData.language];
if (language) {
  languageCode[language] = parsedData.code;
}
```

This gives us a few benefits:
1. using a record to hold the alias->language mappings guarantees that we have no duplicate aliases, even by mistake;
2. it allows us defining multiple aliases per language, if we decide that's something we want;
3. it keeps the mapping in a small place, with no logic, so it is easier to read;
4. the lookup itself is straight-forward and has hardly any logic to it (it's also likely to be faster, but that's irrelevant here);
5. it allows us to put the mapping outside the function, in a visible and easily modifiable place with an `// ADD-LANGUAGES-HERE` comment on it.


created_at: 2025-04-11T07:43:14Z
author_association: OWNER
diff_hunk: @@ -69,65 +70,106 @@ let languages: {
   },
 ] as const;
 
+let currentVersion: number = 1; // Needs to be updated when a new version is released.
+let fontSize = $state("1em");
+let simplify = $state(true);
+let flatSwitch = $state(true);
+let highlight = $state(true);
+let parsedColorList = undefined;
 const urlParams = new URLSearchParams(window.location.search);
-if (urlParams.has("go")) {
-  languageCode.Go = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("go"),
-  );
-}
-if (urlParams.has("c")) {
-  languageCode.C = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c"),
-  );
-}
-if (urlParams.has("c++")) {
-  languageCode["C++"] = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c++"),
-  );
-}
-if (urlParams.has("python")) {
-  languageCode.Python = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("python"),
-  );
-}
-if (urlParams.has("typescript")) {
-  languageCode.TypeScript = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("typescript"),
-  );
-}
-if (urlParams.has("tsx")) {
-  languageCode.TSX = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("tsx"),
+let selection = $state(
+  languages.find(
+    (lang) =>
+      lang.language.toLowerCase() === urlParams.get("language")?.toLowerCase(),
+  ) ?? languages[0],
+);
+/**
+ * Parses URL parameters according to version 1 format.
+ *
+ * This version expects a single `data` parameter containing a compressed JSON
+ * with all necessary configuration, including:
+ *
+ * - version
+ * - language
+ * - code
+ * - fontSize
+ * - simplify
+ * - flatSwitch
+ * - highlight
+ * - colors
+ *
+ * This format makes the URL more compact and easier to extend in the future.
+ *
+ * Notes:
+ * - If `data` is present, it overrides all other URL parameters.
+ * - If `language` is provided without `data`, the default code sample for that
+ *   language is used.
+ */
+
+if (urlParams.has("data")) {
+  const parsedData = JSON.parse(
+    LZString.decompressFromEncodedURIComponent(urlParams.get("data")),
path: src/components/Demo.svelte
user: login: tmr232
body: Please add error handling.
Currently, if the data is invalid the page would completely fail to load.

I think the best way to handle errors at the moment is to catch the exceptions and report them to the console with a full trace. 
created_at: 2025-04-11T07:48:46Z
author_association: OWNER
diff_hunk: @@ -69,65 +70,106 @@ let languages: {
   },
 ] as const;
 
+let currentVersion: number = 1; // Needs to be updated when a new version is released.
+let fontSize = $state("1em");
+let simplify = $state(true);
+let flatSwitch = $state(true);
+let highlight = $state(true);
+let parsedColorList = undefined;
 const urlParams = new URLSearchParams(window.location.search);
-if (urlParams.has("go")) {
-  languageCode.Go = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("go"),
-  );
-}
-if (urlParams.has("c")) {
-  languageCode.C = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c"),
-  );
-}
-if (urlParams.has("c++")) {
-  languageCode["C++"] = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c++"),
-  );
-}
-if (urlParams.has("python")) {
-  languageCode.Python = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("python"),
-  );
-}
-if (urlParams.has("typescript")) {
-  languageCode.TypeScript = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("typescript"),
-  );
-}
-if (urlParams.has("tsx")) {
-  languageCode.TSX = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("tsx"),
+let selection = $state(
+  languages.find(
+    (lang) =>
+      lang.language.toLowerCase() === urlParams.get("language")?.toLowerCase(),
+  ) ?? languages[0],
+);
+/**
+ * Parses URL parameters according to version 1 format.
+ *
+ * This version expects a single `data` parameter containing a compressed JSON
+ * with all necessary configuration, including:
+ *
+ * - version
+ * - language
+ * - code
+ * - fontSize
+ * - simplify
+ * - flatSwitch
+ * - highlight
+ * - colors
+ *
+ * This format makes the URL more compact and easier to extend in the future.
+ *
+ * Notes:
+ * - If `data` is present, it overrides all other URL parameters.
+ * - If `language` is provided without `data`, the default code sample for that
+ *   language is used.
+ */
+
+if (urlParams.has("data")) {
+  const parsedData = JSON.parse(
+    LZString.decompressFromEncodedURIComponent(urlParams.get("data")),
   );
+  if (parsedData.version === 1) {
path: src/components/Demo.svelte
user: login: tmr232
body: If the version is invalid, we should report that to the console as an error.
In the future we might want to add user-facing errors, but not yet.
For now, we just want to make sure a developer or tech-savvy user can see the error reported.
created_at: 2025-04-11T07:49:36Z
author_association: OWNER
diff_hunk: @@ -69,65 +70,106 @@ let languages: {
   },
 ] as const;
 
+let currentVersion: number = 1; // Needs to be updated when a new version is released.
+let fontSize = $state("1em");
+let simplify = $state(true);
+let flatSwitch = $state(true);
+let highlight = $state(true);
+let parsedColorList = undefined;
 const urlParams = new URLSearchParams(window.location.search);
-if (urlParams.has("go")) {
-  languageCode.Go = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("go"),
-  );
-}
-if (urlParams.has("c")) {
-  languageCode.C = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c"),
-  );
-}
-if (urlParams.has("c++")) {
-  languageCode["C++"] = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c++"),
-  );
-}
-if (urlParams.has("python")) {
-  languageCode.Python = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("python"),
-  );
-}
-if (urlParams.has("typescript")) {
-  languageCode.TypeScript = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("typescript"),
-  );
-}
-if (urlParams.has("tsx")) {
-  languageCode.TSX = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("tsx"),
+let selection = $state(
+  languages.find(
+    (lang) =>
+      lang.language.toLowerCase() === urlParams.get("language")?.toLowerCase(),
+  ) ?? languages[0],
+);
+/**
+ * Parses URL parameters according to version 1 format.
+ *
+ * This version expects a single `data` parameter containing a compressed JSON
+ * with all necessary configuration, including:
+ *
+ * - version
+ * - language
+ * - code
+ * - fontSize
+ * - simplify
+ * - flatSwitch
+ * - highlight
+ * - colors
+ *
+ * This format makes the URL more compact and easier to extend in the future.
+ *
+ * Notes:
+ * - If `data` is present, it overrides all other URL parameters.
+ * - If `language` is provided without `data`, the default code sample for that
+ *   language is used.
+ */
+
+if (urlParams.has("data")) {
path: src/components/Demo.svelte
user: login: tmr232
body: Let's call it `compressed`, as it is _compressed_ data, after all.
created_at: 2025-04-11T07:49:54Z
author_association: OWNER
diff_hunk: @@ -69,65 +70,106 @@ let languages: {
   },
 ] as const;
 
+let currentVersion: number = 1; // Needs to be updated when a new version is released.
+let fontSize = $state("1em");
+let simplify = $state(true);
+let flatSwitch = $state(true);
+let highlight = $state(true);
+let parsedColorList = undefined;
 const urlParams = new URLSearchParams(window.location.search);
-if (urlParams.has("go")) {
-  languageCode.Go = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("go"),
-  );
-}
-if (urlParams.has("c")) {
-  languageCode.C = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c"),
-  );
-}
-if (urlParams.has("c++")) {
-  languageCode["C++"] = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c++"),
-  );
-}
-if (urlParams.has("python")) {
-  languageCode.Python = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("python"),
-  );
-}
-if (urlParams.has("typescript")) {
-  languageCode.TypeScript = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("typescript"),
-  );
-}
-if (urlParams.has("tsx")) {
-  languageCode.TSX = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("tsx"),
+let selection = $state(
+  languages.find(
+    (lang) =>
+      lang.language.toLowerCase() === urlParams.get("language")?.toLowerCase(),
+  ) ?? languages[0],
+);
+/**
path: src/components/Demo.svelte
user: login: tmr232
body: That's a bit of a nitpick, but important - regular comments should start with `/*` not `/**`.

`/**` is for JSDoc/typedoc comments describing variables of functions.
Since this is just a block comment, it should use `/*`.
created_at: 2025-04-11T07:51:14Z
author_association: OWNER
diff_hunk: @@ -69,65 +70,106 @@ let languages: {
   },
 ] as const;
 
+let currentVersion: number = 1; // Needs to be updated when a new version is released.
+let fontSize = $state("1em");
+let simplify = $state(true);
+let flatSwitch = $state(true);
+let highlight = $state(true);
+let parsedColorList = undefined;
 const urlParams = new URLSearchParams(window.location.search);
-if (urlParams.has("go")) {
-  languageCode.Go = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("go"),
-  );
-}
-if (urlParams.has("c")) {
-  languageCode.C = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c"),
-  );
-}
-if (urlParams.has("c++")) {
-  languageCode["C++"] = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c++"),
-  );
-}
-if (urlParams.has("python")) {
-  languageCode.Python = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("python"),
-  );
-}
-if (urlParams.has("typescript")) {
-  languageCode.TypeScript = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("typescript"),
-  );
-}
-if (urlParams.has("tsx")) {
-  languageCode.TSX = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("tsx"),
+let selection = $state(
+  languages.find(
+    (lang) =>
+      lang.language.toLowerCase() === urlParams.get("language")?.toLowerCase(),
+  ) ?? languages[0],
+);
+/**
+ * Parses URL parameters according to version 1 format.
+ *
+ * This version expects a single `data` parameter containing a compressed JSON
+ * with all necessary configuration, including:
+ *
+ * - version
+ * - language
+ * - code
+ * - fontSize
+ * - simplify
+ * - flatSwitch
+ * - highlight
+ * - colors
+ *
+ * This format makes the URL more compact and easier to extend in the future.
+ *
+ * Notes:
+ * - If `data` is present, it overrides all other URL parameters.
+ * - If `language` is provided without `data`, the default code sample for that
+ *   language is used.
path: src/components/Demo.svelte
user: login: tmr232
body: I find this comment confusing - can they be used together?
And more importantly - does it make sense to use them together? I tend to think not, as `data` will only have the code for a single language.
created_at: 2025-04-11T07:52:23Z
author_association: OWNER
diff_hunk: @@ -69,65 +70,106 @@ let languages: {
   },
 ] as const;
 
+let currentVersion: number = 1; // Needs to be updated when a new version is released.
+let fontSize = $state("1em");
+let simplify = $state(true);
+let flatSwitch = $state(true);
+let highlight = $state(true);
+let parsedColorList = undefined;
 const urlParams = new URLSearchParams(window.location.search);
-if (urlParams.has("go")) {
-  languageCode.Go = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("go"),
-  );
-}
-if (urlParams.has("c")) {
-  languageCode.C = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c"),
-  );
-}
-if (urlParams.has("c++")) {
-  languageCode["C++"] = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c++"),
-  );
-}
-if (urlParams.has("python")) {
-  languageCode.Python = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("python"),
-  );
-}
-if (urlParams.has("typescript")) {
-  languageCode.TypeScript = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("typescript"),
-  );
-}
-if (urlParams.has("tsx")) {
-  languageCode.TSX = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("tsx"),
+let selection = $state(
+  languages.find(
+    (lang) =>
+      lang.language.toLowerCase() === urlParams.get("language")?.toLowerCase(),
+  ) ?? languages[0],
+);
+/**
+ * Parses URL parameters according to version 1 format.
+ *
+ * This version expects a single `data` parameter containing a compressed JSON
+ * with all necessary configuration, including:
+ *
+ * - version
+ * - language
+ * - code
+ * - fontSize
+ * - simplify
+ * - flatSwitch
+ * - highlight
+ * - colors
+ *
+ * This format makes the URL more compact and easier to extend in the future.
+ *
+ * Notes:
+ * - If `data` is present, it overrides all other URL parameters.
+ * - If `language` is provided without `data`, the default code sample for that
+ *   language is used.
+ */
+
+if (urlParams.has("data")) {
+  const parsedData = JSON.parse(
+    LZString.decompressFromEncodedURIComponent(urlParams.get("data")),
   );
+  if (parsedData.version === 1) {
+    fontSize = parsedData.fontSize;
+    simplify = parsedData.simplify;
+    flatSwitch = parsedData.flatSwitch;
+    highlight = parsedData.highlight;
+    parsedColorList = parsedData.colors;
+    selection = languages.find(
+      (lang) => lang.language.toLowerCase() === parsedData.language,
+    );
+    if (parsedData.language === "go") {
+      languageCode.Go = parsedData.code;
+    } else if (parsedData.language === "c") {
+      languageCode.C = parsedData.code;
+    } else if (parsedData.language === "c++") {
+      languageCode["C++"] = parsedData.code;
+    } else if (parsedData.language === "python") {
+      languageCode.Python = parsedData.code;
+    } else if (parsedData.language === "typescript") {
+      languageCode.TypeScript = parsedData.code;
+    } else if (parsedData.language === "tsx") {
+      languageCode.TSX = parsedData.code;
+    }
+  }
 }
+onMount(() => {
+  if (parsedColorList) {
+    colorList = parsedColorList;
+  }
+});
 
-let simplify = $state(true);
-let flatSwitch = $state(true);
-let highlight = $state(true);
 let colorPicker = $state(false);
 let verbose = $state(urlParams.has("verbose"));
 let showSegmentation = $state(urlParams.has("segmentation"));
 let showRegions = $state(urlParams.has("showRegions"));
 let debugMode = urlParams.has("debug");
-let fontSize = $state("1em");
 const range = (start: number, end: number) =>
   Array.from({ length: end - start }, (_v, k) => k + start);
 const fontSizes: { label: string; value: string }[] = [
   { label: "Default", value: "1em" },
   ...range(8, 31).map((n) => ({ label: `${n}`, value: `${n}px` })),
 ];
 
-let selection = $state(
-  languages[Number.parseInt(urlParams.get("language"))] ?? languages[0],
-);
-
 function share() {
-  const compressedCode = LZString.compressToEncodedURIComponent(
-    languageCode[selection.language],
-  );
+  const code = languageCode[selection.language];
   const codeName = selection.language.toLowerCase();
-  const language = languages.findIndex((lang) => lang === selection);
-  const query = `?language=${language}&${codeName}=${compressedCode}`;
+  const colorConfig = colorList;
+  const parameters = {
+    version: currentVersion,
+    language: codeName,
+    code,
+    fontSize,
+    simplify,
+    flatSwitch,
+    highlight,
+    colors: colorConfig,
+  };
path: src/components/Demo.svelte
user: login: tmr232
body: We should probably have a type definition for this.

```typescript
type ShareParameters = {
    version: number,
    language: Language,
    // ...
}
```

Both for good-measure, and for when we change the version and want to be explicit about what each version expects.
created_at: 2025-04-11T07:54:39Z
author_association: OWNER
diff_hunk: @@ -69,65 +70,106 @@ let languages: {
   },
 ] as const;
 
+let currentVersion: number = 1; // Needs to be updated when a new version is released.
+let fontSize = $state("1em");
+let simplify = $state(true);
+let flatSwitch = $state(true);
+let highlight = $state(true);
+let parsedColorList = undefined;
 const urlParams = new URLSearchParams(window.location.search);
-if (urlParams.has("go")) {
-  languageCode.Go = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("go"),
-  );
-}
-if (urlParams.has("c")) {
-  languageCode.C = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c"),
-  );
-}
-if (urlParams.has("c++")) {
-  languageCode["C++"] = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c++"),
-  );
-}
-if (urlParams.has("python")) {
-  languageCode.Python = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("python"),
-  );
-}
-if (urlParams.has("typescript")) {
-  languageCode.TypeScript = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("typescript"),
-  );
-}
-if (urlParams.has("tsx")) {
-  languageCode.TSX = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("tsx"),
+let selection = $state(
path: src/components/Demo.svelte
user: login: tmr232
body: Do you think we can make it so that as the language selection changes in the UI it is reflected in the URL as well?
created_at: 2025-04-11T07:57:12Z
author_association: OWNER
diff_hunk: @@ -69,65 +70,106 @@ let languages: {
   },
 ] as const;
 
+let currentVersion: number = 1; // Needs to be updated when a new version is released.
path: src/components/Demo.svelte
user: login: tmr232
body: Should be `const`.
created_at: 2025-04-11T07:57:32Z
author_association: OWNER
diff_hunk: @@ -69,65 +70,106 @@ let languages: {
   },
 ] as const;
 
+let currentVersion: number = 1; // Needs to be updated when a new version is released.
+let fontSize = $state("1em");
+let simplify = $state(true);
+let flatSwitch = $state(true);
+let highlight = $state(true);
+let parsedColorList = undefined;
 const urlParams = new URLSearchParams(window.location.search);
-if (urlParams.has("go")) {
-  languageCode.Go = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("go"),
-  );
-}
-if (urlParams.has("c")) {
-  languageCode.C = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c"),
-  );
-}
-if (urlParams.has("c++")) {
-  languageCode["C++"] = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c++"),
-  );
-}
-if (urlParams.has("python")) {
-  languageCode.Python = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("python"),
-  );
-}
-if (urlParams.has("typescript")) {
-  languageCode.TypeScript = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("typescript"),
-  );
-}
-if (urlParams.has("tsx")) {
-  languageCode.TSX = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("tsx"),
+let selection = $state(
+  languages.find(
+    (lang) =>
+      lang.language.toLowerCase() === urlParams.get("language")?.toLowerCase(),
+  ) ?? languages[0],
+);
+/**
+ * Parses URL parameters according to version 1 format.
+ *
+ * This version expects a single `data` parameter containing a compressed JSON
+ * with all necessary configuration, including:
+ *
+ * - version
+ * - language
+ * - code
+ * - fontSize
+ * - simplify
+ * - flatSwitch
+ * - highlight
+ * - colors
+ *
+ * This format makes the URL more compact and easier to extend in the future.
+ *
+ * Notes:
+ * - If `data` is present, it overrides all other URL parameters.
+ * - If `language` is provided without `data`, the default code sample for that
+ *   language is used.
+ */
+
+if (urlParams.has("data")) {
+  const parsedData = JSON.parse(
+    LZString.decompressFromEncodedURIComponent(urlParams.get("data")),
   );
+  if (parsedData.version === 1) {
+    fontSize = parsedData.fontSize;
+    simplify = parsedData.simplify;
+    flatSwitch = parsedData.flatSwitch;
+    highlight = parsedData.highlight;
+    parsedColorList = parsedData.colors;
+    selection = languages.find(
+      (lang) => lang.language.toLowerCase() === parsedData.language,
+    );
+    if (parsedData.language === "go") {
+      languageCode.Go = parsedData.code;
+    } else if (parsedData.language === "c") {
+      languageCode.C = parsedData.code;
+    } else if (parsedData.language === "c++") {
path: src/components/Demo.svelte
user: login: Nivb1569
body: Great, no problem.
created_at: 2025-04-13T07:43:54Z
author_association: CONTRIBUTOR
diff_hunk: @@ -69,65 +70,106 @@ let languages: {
   },
 ] as const;
 
+let currentVersion: number = 1; // Needs to be updated when a new version is released.
+let fontSize = $state("1em");
+let simplify = $state(true);
+let flatSwitch = $state(true);
+let highlight = $state(true);
+let parsedColorList = undefined;
 const urlParams = new URLSearchParams(window.location.search);
-if (urlParams.has("go")) {
-  languageCode.Go = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("go"),
-  );
-}
-if (urlParams.has("c")) {
-  languageCode.C = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c"),
-  );
-}
-if (urlParams.has("c++")) {
-  languageCode["C++"] = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c++"),
-  );
-}
-if (urlParams.has("python")) {
-  languageCode.Python = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("python"),
-  );
-}
-if (urlParams.has("typescript")) {
-  languageCode.TypeScript = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("typescript"),
-  );
-}
-if (urlParams.has("tsx")) {
-  languageCode.TSX = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("tsx"),
+let selection = $state(
+  languages.find(
+    (lang) =>
+      lang.language.toLowerCase() === urlParams.get("language")?.toLowerCase(),
+  ) ?? languages[0],
+);
+/**
+ * Parses URL parameters according to version 1 format.
+ *
+ * This version expects a single `data` parameter containing a compressed JSON
+ * with all necessary configuration, including:
+ *
+ * - version
+ * - language
+ * - code
+ * - fontSize
+ * - simplify
+ * - flatSwitch
+ * - highlight
+ * - colors
+ *
+ * This format makes the URL more compact and easier to extend in the future.
+ *
+ * Notes:
+ * - If `data` is present, it overrides all other URL parameters.
+ * - If `language` is provided without `data`, the default code sample for that
+ *   language is used.
+ */
+
+if (urlParams.has("data")) {
+  const parsedData = JSON.parse(
+    LZString.decompressFromEncodedURIComponent(urlParams.get("data")),
   );
+  if (parsedData.version === 1) {
+    fontSize = parsedData.fontSize;
+    simplify = parsedData.simplify;
+    flatSwitch = parsedData.flatSwitch;
+    highlight = parsedData.highlight;
+    parsedColorList = parsedData.colors;
+    selection = languages.find(
+      (lang) => lang.language.toLowerCase() === parsedData.language,
+    );
+    if (parsedData.language === "go") {
+      languageCode.Go = parsedData.code;
+    } else if (parsedData.language === "c") {
+      languageCode.C = parsedData.code;
+    } else if (parsedData.language === "c++") {
+      languageCode["C++"] = parsedData.code;
+    } else if (parsedData.language === "python") {
+      languageCode.Python = parsedData.code;
+    } else if (parsedData.language === "typescript") {
+      languageCode.TypeScript = parsedData.code;
+    } else if (parsedData.language === "tsx") {
+      languageCode.TSX = parsedData.code;
path: src/components/Demo.svelte
user: login: Nivb1569
body: Yes you're right, using this mapping object is more cleaner and eaiser to maintain as we might want to add more languages in the future.
Thank you.
created_at: 2025-04-13T07:52:51Z
author_association: CONTRIBUTOR
diff_hunk: @@ -69,65 +70,106 @@ let languages: {
   },
 ] as const;
 
+let currentVersion: number = 1; // Needs to be updated when a new version is released.
+let fontSize = $state("1em");
+let simplify = $state(true);
+let flatSwitch = $state(true);
+let highlight = $state(true);
+let parsedColorList = undefined;
 const urlParams = new URLSearchParams(window.location.search);
-if (urlParams.has("go")) {
-  languageCode.Go = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("go"),
-  );
-}
-if (urlParams.has("c")) {
-  languageCode.C = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c"),
-  );
-}
-if (urlParams.has("c++")) {
-  languageCode["C++"] = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c++"),
-  );
-}
-if (urlParams.has("python")) {
-  languageCode.Python = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("python"),
-  );
-}
-if (urlParams.has("typescript")) {
-  languageCode.TypeScript = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("typescript"),
-  );
-}
-if (urlParams.has("tsx")) {
-  languageCode.TSX = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("tsx"),
+let selection = $state(
+  languages.find(
+    (lang) =>
+      lang.language.toLowerCase() === urlParams.get("language")?.toLowerCase(),
+  ) ?? languages[0],
+);
+/**
+ * Parses URL parameters according to version 1 format.
+ *
+ * This version expects a single `data` parameter containing a compressed JSON
+ * with all necessary configuration, including:
+ *
+ * - version
+ * - language
+ * - code
+ * - fontSize
+ * - simplify
+ * - flatSwitch
+ * - highlight
+ * - colors
+ *
+ * This format makes the URL more compact and easier to extend in the future.
+ *
+ * Notes:
+ * - If `data` is present, it overrides all other URL parameters.
+ * - If `language` is provided without `data`, the default code sample for that
+ *   language is used.
+ */
+
+if (urlParams.has("data")) {
+  const parsedData = JSON.parse(
+    LZString.decompressFromEncodedURIComponent(urlParams.get("data")),
path: src/components/Demo.svelte
user: login: Nivb1569
body: Ok, sure.
created_at: 2025-04-13T07:53:26Z
author_association: CONTRIBUTOR
diff_hunk: @@ -69,65 +70,106 @@ let languages: {
   },
 ] as const;
 
+let currentVersion: number = 1; // Needs to be updated when a new version is released.
+let fontSize = $state("1em");
+let simplify = $state(true);
+let flatSwitch = $state(true);
+let highlight = $state(true);
+let parsedColorList = undefined;
 const urlParams = new URLSearchParams(window.location.search);
-if (urlParams.has("go")) {
-  languageCode.Go = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("go"),
-  );
-}
-if (urlParams.has("c")) {
-  languageCode.C = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c"),
-  );
-}
-if (urlParams.has("c++")) {
-  languageCode["C++"] = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c++"),
-  );
-}
-if (urlParams.has("python")) {
-  languageCode.Python = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("python"),
-  );
-}
-if (urlParams.has("typescript")) {
-  languageCode.TypeScript = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("typescript"),
-  );
-}
-if (urlParams.has("tsx")) {
-  languageCode.TSX = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("tsx"),
+let selection = $state(
+  languages.find(
+    (lang) =>
+      lang.language.toLowerCase() === urlParams.get("language")?.toLowerCase(),
+  ) ?? languages[0],
+);
+/**
+ * Parses URL parameters according to version 1 format.
+ *
+ * This version expects a single `data` parameter containing a compressed JSON
+ * with all necessary configuration, including:
+ *
+ * - version
+ * - language
+ * - code
+ * - fontSize
+ * - simplify
+ * - flatSwitch
+ * - highlight
+ * - colors
+ *
+ * This format makes the URL more compact and easier to extend in the future.
+ *
+ * Notes:
+ * - If `data` is present, it overrides all other URL parameters.
+ * - If `language` is provided without `data`, the default code sample for that
+ *   language is used.
+ */
+
+if (urlParams.has("data")) {
+  const parsedData = JSON.parse(
+    LZString.decompressFromEncodedURIComponent(urlParams.get("data")),
   );
+  if (parsedData.version === 1) {
path: src/components/Demo.svelte
user: login: Nivb1569
body: But the `version` field is part of the `data` parameter, so if the data is invalid, the version would be invalid too.
Also, in the future when we release new versions, we'd want to keep supporting older ones, so by the time this part of the code runs, the version should already be valid, right?

But I can still add an error message to the console if you think it's helpful.
created_at: 2025-04-13T08:03:22Z
author_association: CONTRIBUTOR
diff_hunk: @@ -69,65 +70,106 @@ let languages: {
   },
 ] as const;
 
+let currentVersion: number = 1; // Needs to be updated when a new version is released.
+let fontSize = $state("1em");
+let simplify = $state(true);
+let flatSwitch = $state(true);
+let highlight = $state(true);
+let parsedColorList = undefined;
 const urlParams = new URLSearchParams(window.location.search);
-if (urlParams.has("go")) {
-  languageCode.Go = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("go"),
-  );
-}
-if (urlParams.has("c")) {
-  languageCode.C = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c"),
-  );
-}
-if (urlParams.has("c++")) {
-  languageCode["C++"] = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c++"),
-  );
-}
-if (urlParams.has("python")) {
-  languageCode.Python = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("python"),
-  );
-}
-if (urlParams.has("typescript")) {
-  languageCode.TypeScript = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("typescript"),
-  );
-}
-if (urlParams.has("tsx")) {
-  languageCode.TSX = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("tsx"),
+let selection = $state(
+  languages.find(
+    (lang) =>
+      lang.language.toLowerCase() === urlParams.get("language")?.toLowerCase(),
+  ) ?? languages[0],
+);
+/**
+ * Parses URL parameters according to version 1 format.
+ *
+ * This version expects a single `data` parameter containing a compressed JSON
+ * with all necessary configuration, including:
+ *
+ * - version
+ * - language
+ * - code
+ * - fontSize
+ * - simplify
+ * - flatSwitch
+ * - highlight
+ * - colors
+ *
+ * This format makes the URL more compact and easier to extend in the future.
+ *
+ * Notes:
+ * - If `data` is present, it overrides all other URL parameters.
+ * - If `language` is provided without `data`, the default code sample for that
+ *   language is used.
+ */
+
+if (urlParams.has("data")) {
path: src/components/Demo.svelte
user: login: Nivb1569
body: Yes, sure!
created_at: 2025-04-13T08:03:39Z
author_association: CONTRIBUTOR
diff_hunk: @@ -69,65 +70,106 @@ let languages: {
   },
 ] as const;
 
+let currentVersion: number = 1; // Needs to be updated when a new version is released.
+let fontSize = $state("1em");
+let simplify = $state(true);
+let flatSwitch = $state(true);
+let highlight = $state(true);
+let parsedColorList = undefined;
 const urlParams = new URLSearchParams(window.location.search);
-if (urlParams.has("go")) {
-  languageCode.Go = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("go"),
-  );
-}
-if (urlParams.has("c")) {
-  languageCode.C = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c"),
-  );
-}
-if (urlParams.has("c++")) {
-  languageCode["C++"] = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c++"),
-  );
-}
-if (urlParams.has("python")) {
-  languageCode.Python = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("python"),
-  );
-}
-if (urlParams.has("typescript")) {
-  languageCode.TypeScript = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("typescript"),
-  );
-}
-if (urlParams.has("tsx")) {
-  languageCode.TSX = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("tsx"),
+let selection = $state(
+  languages.find(
+    (lang) =>
+      lang.language.toLowerCase() === urlParams.get("language")?.toLowerCase(),
+  ) ?? languages[0],
+);
+/**
+ * Parses URL parameters according to version 1 format.
+ *
+ * This version expects a single `data` parameter containing a compressed JSON
+ * with all necessary configuration, including:
+ *
+ * - version
+ * - language
+ * - code
+ * - fontSize
+ * - simplify
+ * - flatSwitch
+ * - highlight
+ * - colors
+ *
+ * This format makes the URL more compact and easier to extend in the future.
+ *
+ * Notes:
+ * - If `data` is present, it overrides all other URL parameters.
+ * - If `language` is provided without `data`, the default code sample for that
+ *   language is used.
path: src/components/Demo.svelte
user: login: Nivb1569
body: Yes, I agree with you.
Maybe we should check that only one of the query parameters is present, either `data` or `language`, but not both and then handle it?

created_at: 2025-04-13T08:13:36Z
author_association: CONTRIBUTOR
diff_hunk: @@ -69,65 +70,106 @@ let languages: {
   },
 ] as const;
 
+let currentVersion: number = 1; // Needs to be updated when a new version is released.
+let fontSize = $state("1em");
+let simplify = $state(true);
+let flatSwitch = $state(true);
+let highlight = $state(true);
+let parsedColorList = undefined;
 const urlParams = new URLSearchParams(window.location.search);
-if (urlParams.has("go")) {
-  languageCode.Go = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("go"),
-  );
-}
-if (urlParams.has("c")) {
-  languageCode.C = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c"),
-  );
-}
-if (urlParams.has("c++")) {
-  languageCode["C++"] = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c++"),
-  );
-}
-if (urlParams.has("python")) {
-  languageCode.Python = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("python"),
-  );
-}
-if (urlParams.has("typescript")) {
-  languageCode.TypeScript = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("typescript"),
-  );
-}
-if (urlParams.has("tsx")) {
-  languageCode.TSX = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("tsx"),
+let selection = $state(
+  languages.find(
+    (lang) =>
+      lang.language.toLowerCase() === urlParams.get("language")?.toLowerCase(),
+  ) ?? languages[0],
+);
+/**
+ * Parses URL parameters according to version 1 format.
+ *
+ * This version expects a single `data` parameter containing a compressed JSON
+ * with all necessary configuration, including:
+ *
+ * - version
+ * - language
+ * - code
+ * - fontSize
+ * - simplify
+ * - flatSwitch
+ * - highlight
+ * - colors
+ *
+ * This format makes the URL more compact and easier to extend in the future.
+ *
+ * Notes:
+ * - If `data` is present, it overrides all other URL parameters.
+ * - If `language` is provided without `data`, the default code sample for that
+ *   language is used.
+ */
+
+if (urlParams.has("data")) {
+  const parsedData = JSON.parse(
+    LZString.decompressFromEncodedURIComponent(urlParams.get("data")),
   );
+  if (parsedData.version === 1) {
+    fontSize = parsedData.fontSize;
+    simplify = parsedData.simplify;
+    flatSwitch = parsedData.flatSwitch;
+    highlight = parsedData.highlight;
+    parsedColorList = parsedData.colors;
+    selection = languages.find(
+      (lang) => lang.language.toLowerCase() === parsedData.language,
+    );
+    if (parsedData.language === "go") {
+      languageCode.Go = parsedData.code;
+    } else if (parsedData.language === "c") {
+      languageCode.C = parsedData.code;
+    } else if (parsedData.language === "c++") {
+      languageCode["C++"] = parsedData.code;
+    } else if (parsedData.language === "python") {
+      languageCode.Python = parsedData.code;
+    } else if (parsedData.language === "typescript") {
+      languageCode.TypeScript = parsedData.code;
+    } else if (parsedData.language === "tsx") {
+      languageCode.TSX = parsedData.code;
+    }
+  }
 }
+onMount(() => {
+  if (parsedColorList) {
+    colorList = parsedColorList;
+  }
+});
 
-let simplify = $state(true);
-let flatSwitch = $state(true);
-let highlight = $state(true);
 let colorPicker = $state(false);
 let verbose = $state(urlParams.has("verbose"));
 let showSegmentation = $state(urlParams.has("segmentation"));
 let showRegions = $state(urlParams.has("showRegions"));
 let debugMode = urlParams.has("debug");
-let fontSize = $state("1em");
 const range = (start: number, end: number) =>
   Array.from({ length: end - start }, (_v, k) => k + start);
 const fontSizes: { label: string; value: string }[] = [
   { label: "Default", value: "1em" },
   ...range(8, 31).map((n) => ({ label: `${n}`, value: `${n}px` })),
 ];
 
-let selection = $state(
-  languages[Number.parseInt(urlParams.get("language"))] ?? languages[0],
-);
-
 function share() {
-  const compressedCode = LZString.compressToEncodedURIComponent(
-    languageCode[selection.language],
-  );
+  const code = languageCode[selection.language];
   const codeName = selection.language.toLowerCase();
-  const language = languages.findIndex((lang) => lang === selection);
-  const query = `?language=${language}&${codeName}=${compressedCode}`;
+  const colorConfig = colorList;
+  const parameters = {
+    version: currentVersion,
+    language: codeName,
+    code,
+    fontSize,
+    simplify,
+    flatSwitch,
+    highlight,
+    colors: colorConfig,
+  };
path: src/components/Demo.svelte
user: login: Nivb1569
body: Yes, of course.
created_at: 2025-04-13T08:13:59Z
author_association: CONTRIBUTOR
diff_hunk: @@ -69,65 +70,106 @@ let languages: {
   },
 ] as const;
 
+let currentVersion: number = 1; // Needs to be updated when a new version is released.
+let fontSize = $state("1em");
+let simplify = $state(true);
+let flatSwitch = $state(true);
+let highlight = $state(true);
+let parsedColorList = undefined;
 const urlParams = new URLSearchParams(window.location.search);
-if (urlParams.has("go")) {
-  languageCode.Go = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("go"),
-  );
-}
-if (urlParams.has("c")) {
-  languageCode.C = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c"),
-  );
-}
-if (urlParams.has("c++")) {
-  languageCode["C++"] = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c++"),
-  );
-}
-if (urlParams.has("python")) {
-  languageCode.Python = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("python"),
-  );
-}
-if (urlParams.has("typescript")) {
-  languageCode.TypeScript = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("typescript"),
-  );
-}
-if (urlParams.has("tsx")) {
-  languageCode.TSX = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("tsx"),
+let selection = $state(
path: src/components/Demo.svelte
user: login: Nivb1569
body: I can make it happen.
I just want to make sure I understand, is this meant for users who want to share a link with a specific language selected, like we discussed earlier?

It makes sense, users won't necessarily know how to format the URL themselves.
created_at: 2025-04-13T08:21:08Z
author_association: CONTRIBUTOR
diff_hunk: @@ -69,65 +70,106 @@ let languages: {
   },
 ] as const;
 
+let currentVersion: number = 1; // Needs to be updated when a new version is released.
+let fontSize = $state("1em");
+let simplify = $state(true);
+let flatSwitch = $state(true);
+let highlight = $state(true);
+let parsedColorList = undefined;
 const urlParams = new URLSearchParams(window.location.search);
-if (urlParams.has("go")) {
-  languageCode.Go = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("go"),
-  );
-}
-if (urlParams.has("c")) {
-  languageCode.C = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c"),
-  );
-}
-if (urlParams.has("c++")) {
-  languageCode["C++"] = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c++"),
-  );
-}
-if (urlParams.has("python")) {
-  languageCode.Python = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("python"),
-  );
-}
-if (urlParams.has("typescript")) {
-  languageCode.TypeScript = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("typescript"),
-  );
-}
-if (urlParams.has("tsx")) {
-  languageCode.TSX = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("tsx"),
+let selection = $state(
+  languages.find(
+    (lang) =>
+      lang.language.toLowerCase() === urlParams.get("language")?.toLowerCase(),
+  ) ?? languages[0],
+);
+/**
+ * Parses URL parameters according to version 1 format.
+ *
+ * This version expects a single `data` parameter containing a compressed JSON
+ * with all necessary configuration, including:
+ *
+ * - version
+ * - language
+ * - code
+ * - fontSize
+ * - simplify
+ * - flatSwitch
+ * - highlight
+ * - colors
+ *
+ * This format makes the URL more compact and easier to extend in the future.
+ *
+ * Notes:
+ * - If `data` is present, it overrides all other URL parameters.
+ * - If `language` is provided without `data`, the default code sample for that
+ *   language is used.
+ */
+
+if (urlParams.has("data")) {
+  const parsedData = JSON.parse(
+    LZString.decompressFromEncodedURIComponent(urlParams.get("data")),
   );
+  if (parsedData.version === 1) {
path: src/components/Demo.svelte
user: login: tmr232
body: Hmm... I suppose you're right.
Given that the links are not generic, but point to _this specific instance_, there will probably not be a need for future-compatibility here.

My thinking was that if we share from a newer version to an older version of the code, we want to make sure it reports the error.
But that's not likely to happen with the current code.
created_at: 2025-04-13T09:59:54Z
author_association: OWNER
diff_hunk: @@ -69,65 +70,106 @@ let languages: {
   },
 ] as const;
 
+let currentVersion: number = 1; // Needs to be updated when a new version is released.
+let fontSize = $state("1em");
+let simplify = $state(true);
+let flatSwitch = $state(true);
+let highlight = $state(true);
+let parsedColorList = undefined;
 const urlParams = new URLSearchParams(window.location.search);
-if (urlParams.has("go")) {
-  languageCode.Go = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("go"),
-  );
-}
-if (urlParams.has("c")) {
-  languageCode.C = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c"),
-  );
-}
-if (urlParams.has("c++")) {
-  languageCode["C++"] = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c++"),
-  );
-}
-if (urlParams.has("python")) {
-  languageCode.Python = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("python"),
-  );
-}
-if (urlParams.has("typescript")) {
-  languageCode.TypeScript = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("typescript"),
-  );
-}
-if (urlParams.has("tsx")) {
-  languageCode.TSX = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("tsx"),
+let selection = $state(
+  languages.find(
+    (lang) =>
+      lang.language.toLowerCase() === urlParams.get("language")?.toLowerCase(),
+  ) ?? languages[0],
+);
+/**
+ * Parses URL parameters according to version 1 format.
+ *
+ * This version expects a single `data` parameter containing a compressed JSON
+ * with all necessary configuration, including:
+ *
+ * - version
+ * - language
+ * - code
+ * - fontSize
+ * - simplify
+ * - flatSwitch
+ * - highlight
+ * - colors
+ *
+ * This format makes the URL more compact and easier to extend in the future.
+ *
+ * Notes:
+ * - If `data` is present, it overrides all other URL parameters.
+ * - If `language` is provided without `data`, the default code sample for that
+ *   language is used.
path: src/components/Demo.svelte
user: login: tmr232
body: I think that's a good choice.
As for handling it - I think we'd want to use the `data` field, and report an error to the console.
created_at: 2025-04-13T10:01:14Z
author_association: OWNER
diff_hunk: @@ -69,65 +70,106 @@ let languages: {
   },
 ] as const;
 
+let currentVersion: number = 1; // Needs to be updated when a new version is released.
+let fontSize = $state("1em");
+let simplify = $state(true);
+let flatSwitch = $state(true);
+let highlight = $state(true);
+let parsedColorList = undefined;
 const urlParams = new URLSearchParams(window.location.search);
-if (urlParams.has("go")) {
-  languageCode.Go = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("go"),
-  );
-}
-if (urlParams.has("c")) {
-  languageCode.C = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c"),
-  );
-}
-if (urlParams.has("c++")) {
-  languageCode["C++"] = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c++"),
-  );
-}
-if (urlParams.has("python")) {
-  languageCode.Python = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("python"),
-  );
-}
-if (urlParams.has("typescript")) {
-  languageCode.TypeScript = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("typescript"),
-  );
-}
-if (urlParams.has("tsx")) {
-  languageCode.TSX = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("tsx"),
+let selection = $state(
path: src/components/Demo.svelte
user: login: tmr232
body: Yes, that is the idea. 
created_at: 2025-04-13T10:01:49Z
author_association: OWNER
diff_hunk: @@ -69,65 +70,148 @@ let languages: {
   },
 ] as const;
 
-const urlParams = new URLSearchParams(window.location.search);
-if (urlParams.has("go")) {
-  languageCode.Go = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("go"),
-  );
-}
-if (urlParams.has("c")) {
-  languageCode.C = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c"),
-  );
-}
-if (urlParams.has("c++")) {
-  languageCode["C++"] = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c++"),
-  );
-}
-if (urlParams.has("python")) {
-  languageCode.Python = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("python"),
-  );
-}
-if (urlParams.has("typescript")) {
-  languageCode.TypeScript = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("typescript"),
-  );
-}
-if (urlParams.has("tsx")) {
-  languageCode.TSX = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("tsx"),
-  );
-}
+type ShareParameters = {
+  version: number;
+  language: string;
+  code: string;
+  fontSize: string;
+  simplify: boolean;
+  flatSwitch: boolean;
+  highlight: boolean;
+  colors: ColorList;
+};
+
+// ADD-LANGUAGES-HERE
+const languageAliases: Record<string, Language> = {
+  go: "Go",
+  c: "C",
+  cpp: "C++",
+  python: "Python",
+  typescript: "TypeScript",
+  tsx: "TSX",
+};
+
+const reverseLanguageAliases = Object.fromEntries(
+  Object.entries(languageAliases).map(([alias, lang]) => [lang, alias]),
+);
 
+const currentVersion: number = 1; // Needs to be updated when a new version is released.
+let fontSize = $state("1em");
 let simplify = $state(true);
 let flatSwitch = $state(true);
 let highlight = $state(true);
+let parsedColorList = undefined;
+const urlParams = new URLSearchParams(window.location.search);
+let isLanguageInURL: boolean = false;
+let selection = $state(languages[0]);
+
+if (urlParams.has("language")) {
+  try {
path: src/components/Demo.svelte
user: login: tmr232
body: I don't think any exception can be thrown in this block.

`.get` does not throw, nor does `.find` or object subscripting.
created_at: 2025-04-14T17:22:57Z
author_association: OWNER
diff_hunk: @@ -69,65 +70,148 @@ let languages: {
   },
 ] as const;
 
-const urlParams = new URLSearchParams(window.location.search);
-if (urlParams.has("go")) {
-  languageCode.Go = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("go"),
-  );
-}
-if (urlParams.has("c")) {
-  languageCode.C = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c"),
-  );
-}
-if (urlParams.has("c++")) {
-  languageCode["C++"] = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c++"),
-  );
-}
-if (urlParams.has("python")) {
-  languageCode.Python = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("python"),
-  );
-}
-if (urlParams.has("typescript")) {
-  languageCode.TypeScript = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("typescript"),
-  );
-}
-if (urlParams.has("tsx")) {
-  languageCode.TSX = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("tsx"),
-  );
-}
+type ShareParameters = {
+  version: number;
+  language: string;
+  code: string;
+  fontSize: string;
+  simplify: boolean;
+  flatSwitch: boolean;
+  highlight: boolean;
+  colors: ColorList;
+};
+
+// ADD-LANGUAGES-HERE
+const languageAliases: Record<string, Language> = {
+  go: "Go",
+  c: "C",
+  cpp: "C++",
+  python: "Python",
+  typescript: "TypeScript",
+  tsx: "TSX",
+};
+
+const reverseLanguageAliases = Object.fromEntries(
+  Object.entries(languageAliases).map(([alias, lang]) => [lang, alias]),
+);
 
+const currentVersion: number = 1; // Needs to be updated when a new version is released.
+let fontSize = $state("1em");
 let simplify = $state(true);
 let flatSwitch = $state(true);
 let highlight = $state(true);
+let parsedColorList = undefined;
+const urlParams = new URLSearchParams(window.location.search);
+let isLanguageInURL: boolean = false;
+let selection = $state(languages[0]);
+
+if (urlParams.has("language")) {
+  try {
+    isLanguageInURL = true;
+    const urlLanguage = urlParams.get("language");
+    const languageAlias = languageAliases[urlLanguage];
path: src/components/Demo.svelte
user: login: tmr232
body: Note that after looking up the language here, we get a language, not an alias.
created_at: 2025-04-14T17:27:07Z
author_association: OWNER
diff_hunk: @@ -69,65 +70,148 @@ let languages: {
   },
 ] as const;
 
-const urlParams = new URLSearchParams(window.location.search);
-if (urlParams.has("go")) {
-  languageCode.Go = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("go"),
-  );
-}
-if (urlParams.has("c")) {
-  languageCode.C = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c"),
-  );
-}
-if (urlParams.has("c++")) {
-  languageCode["C++"] = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c++"),
-  );
-}
-if (urlParams.has("python")) {
-  languageCode.Python = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("python"),
-  );
-}
-if (urlParams.has("typescript")) {
-  languageCode.TypeScript = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("typescript"),
-  );
-}
-if (urlParams.has("tsx")) {
-  languageCode.TSX = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("tsx"),
-  );
-}
+type ShareParameters = {
+  version: number;
+  language: string;
+  code: string;
+  fontSize: string;
+  simplify: boolean;
+  flatSwitch: boolean;
+  highlight: boolean;
+  colors: ColorList;
+};
+
+// ADD-LANGUAGES-HERE
+const languageAliases: Record<string, Language> = {
+  go: "Go",
+  c: "C",
+  cpp: "C++",
+  python: "Python",
+  typescript: "TypeScript",
+  tsx: "TSX",
+};
+
+const reverseLanguageAliases = Object.fromEntries(
+  Object.entries(languageAliases).map(([alias, lang]) => [lang, alias]),
+);
 
+const currentVersion: number = 1; // Needs to be updated when a new version is released.
+let fontSize = $state("1em");
 let simplify = $state(true);
 let flatSwitch = $state(true);
 let highlight = $state(true);
+let parsedColorList = undefined;
+const urlParams = new URLSearchParams(window.location.search);
+let isLanguageInURL: boolean = false;
+let selection = $state(languages[0]);
+
+if (urlParams.has("language")) {
+  try {
+    isLanguageInURL = true;
+    const urlLanguage = urlParams.get("language");
+    const languageAlias = languageAliases[urlLanguage];
+    const languageMatched = languages.find(
path: src/components/Demo.svelte
user: login: tmr232
body: Grammar nitpick - `matchedLanguage` not `languageMatched`.

But, since we care more about the user's intent than the implementing code - maybe `requestedLanguage`?
created_at: 2025-04-14T17:28:51Z
author_association: OWNER
diff_hunk: @@ -69,65 +70,148 @@ let languages: {
   },
 ] as const;
 
-const urlParams = new URLSearchParams(window.location.search);
-if (urlParams.has("go")) {
-  languageCode.Go = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("go"),
-  );
-}
-if (urlParams.has("c")) {
-  languageCode.C = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c"),
-  );
-}
-if (urlParams.has("c++")) {
-  languageCode["C++"] = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c++"),
-  );
-}
-if (urlParams.has("python")) {
-  languageCode.Python = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("python"),
-  );
-}
-if (urlParams.has("typescript")) {
-  languageCode.TypeScript = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("typescript"),
-  );
-}
-if (urlParams.has("tsx")) {
-  languageCode.TSX = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("tsx"),
-  );
-}
+type ShareParameters = {
+  version: number;
+  language: string;
+  code: string;
+  fontSize: string;
+  simplify: boolean;
+  flatSwitch: boolean;
+  highlight: boolean;
+  colors: ColorList;
+};
+
+// ADD-LANGUAGES-HERE
+const languageAliases: Record<string, Language> = {
+  go: "Go",
+  c: "C",
+  cpp: "C++",
+  python: "Python",
+  typescript: "TypeScript",
+  tsx: "TSX",
+};
+
+const reverseLanguageAliases = Object.fromEntries(
+  Object.entries(languageAliases).map(([alias, lang]) => [lang, alias]),
+);
 
+const currentVersion: number = 1; // Needs to be updated when a new version is released.
+let fontSize = $state("1em");
 let simplify = $state(true);
 let flatSwitch = $state(true);
 let highlight = $state(true);
+let parsedColorList = undefined;
+const urlParams = new URLSearchParams(window.location.search);
+let isLanguageInURL: boolean = false;
+let selection = $state(languages[0]);
+
+if (urlParams.has("language")) {
+  try {
+    isLanguageInURL = true;
+    const urlLanguage = urlParams.get("language");
+    const languageAlias = languageAliases[urlLanguage];
+    const languageMatched = languages.find(
+      (lang) => lang.language === languageAlias,
+    );
+    if (languageMatched) {
+      selection = languageMatched;
+    } else {
+      console.error(`Unsupported or unknown language alias: '${urlLanguage}'`);
path: src/components/Demo.svelte
user: login: tmr232
body: It can be unsupported, but can't be unknown here, as it is a result of the alias mapping.
created_at: 2025-04-14T17:29:33Z
author_association: OWNER
diff_hunk: @@ -69,65 +70,148 @@ let languages: {
   },
 ] as const;
 
-const urlParams = new URLSearchParams(window.location.search);
-if (urlParams.has("go")) {
-  languageCode.Go = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("go"),
-  );
-}
-if (urlParams.has("c")) {
-  languageCode.C = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c"),
-  );
-}
-if (urlParams.has("c++")) {
-  languageCode["C++"] = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c++"),
-  );
-}
-if (urlParams.has("python")) {
-  languageCode.Python = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("python"),
-  );
-}
-if (urlParams.has("typescript")) {
-  languageCode.TypeScript = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("typescript"),
-  );
-}
-if (urlParams.has("tsx")) {
-  languageCode.TSX = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("tsx"),
-  );
-}
+type ShareParameters = {
+  version: number;
+  language: string;
+  code: string;
+  fontSize: string;
+  simplify: boolean;
+  flatSwitch: boolean;
+  highlight: boolean;
+  colors: ColorList;
+};
+
+// ADD-LANGUAGES-HERE
+const languageAliases: Record<string, Language> = {
+  go: "Go",
+  c: "C",
+  cpp: "C++",
+  python: "Python",
+  typescript: "TypeScript",
+  tsx: "TSX",
+};
+
+const reverseLanguageAliases = Object.fromEntries(
+  Object.entries(languageAliases).map(([alias, lang]) => [lang, alias]),
+);
 
+const currentVersion: number = 1; // Needs to be updated when a new version is released.
+let fontSize = $state("1em");
 let simplify = $state(true);
 let flatSwitch = $state(true);
 let highlight = $state(true);
+let parsedColorList = undefined;
+const urlParams = new URLSearchParams(window.location.search);
+let isLanguageInURL: boolean = false;
+let selection = $state(languages[0]);
+
+if (urlParams.has("language")) {
+  try {
+    isLanguageInURL = true;
+    const urlLanguage = urlParams.get("language");
+    const languageAlias = languageAliases[urlLanguage];
+    const languageMatched = languages.find(
+      (lang) => lang.language === languageAlias,
+    );
+    if (languageMatched) {
+      selection = languageMatched;
+    } else {
+      console.error(`Unsupported or unknown language alias: '${urlLanguage}'`);
+    }
+  } catch (error) {
+    console.error("Failed to get language from URL:", error);
+  }
+}
+
+/*
+ * Parses URL parameters according to version 1 format.
+ *
+ * This version expects a single `data` parameter containing a compressed JSON
+ * with all necessary configuration, including:
+ *
+ * - version
+ * - language
+ * - code
+ * - fontSize
+ * - simplify
+ * - flatSwitch
+ * - highlight
+ * - colors
+ *
+ * This format makes the URL more compact and easier to extend in the future.
+ *
+ * Notes:
+ * - If `data` is present, it overrides all other URL parameters.
path: src/components/Demo.svelte
user: login: tmr232
body: Please update the docs to say `compressed` and not `data`.
created_at: 2025-04-14T17:30:38Z
author_association: OWNER
diff_hunk: @@ -69,65 +70,148 @@ let languages: {
   },
 ] as const;
 
-const urlParams = new URLSearchParams(window.location.search);
-if (urlParams.has("go")) {
-  languageCode.Go = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("go"),
-  );
-}
-if (urlParams.has("c")) {
-  languageCode.C = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c"),
-  );
-}
-if (urlParams.has("c++")) {
-  languageCode["C++"] = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c++"),
-  );
-}
-if (urlParams.has("python")) {
-  languageCode.Python = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("python"),
-  );
-}
-if (urlParams.has("typescript")) {
-  languageCode.TypeScript = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("typescript"),
-  );
-}
-if (urlParams.has("tsx")) {
-  languageCode.TSX = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("tsx"),
-  );
-}
+type ShareParameters = {
+  version: number;
+  language: string;
+  code: string;
+  fontSize: string;
+  simplify: boolean;
+  flatSwitch: boolean;
+  highlight: boolean;
+  colors: ColorList;
+};
+
+// ADD-LANGUAGES-HERE
+const languageAliases: Record<string, Language> = {
+  go: "Go",
+  c: "C",
+  cpp: "C++",
+  python: "Python",
+  typescript: "TypeScript",
+  tsx: "TSX",
+};
+
+const reverseLanguageAliases = Object.fromEntries(
+  Object.entries(languageAliases).map(([alias, lang]) => [lang, alias]),
+);
 
+const currentVersion: number = 1; // Needs to be updated when a new version is released.
+let fontSize = $state("1em");
 let simplify = $state(true);
 let flatSwitch = $state(true);
 let highlight = $state(true);
+let parsedColorList = undefined;
+const urlParams = new URLSearchParams(window.location.search);
+let isLanguageInURL: boolean = false;
+let selection = $state(languages[0]);
+
+if (urlParams.has("language")) {
+  try {
+    isLanguageInURL = true;
+    const urlLanguage = urlParams.get("language");
+    const languageAlias = languageAliases[urlLanguage];
+    const languageMatched = languages.find(
+      (lang) => lang.language === languageAlias,
+    );
+    if (languageMatched) {
+      selection = languageMatched;
+    } else {
+      console.error(`Unsupported or unknown language alias: '${urlLanguage}'`);
+    }
+  } catch (error) {
+    console.error("Failed to get language from URL:", error);
+  }
+}
+
+/*
+ * Parses URL parameters according to version 1 format.
+ *
+ * This version expects a single `data` parameter containing a compressed JSON
+ * with all necessary configuration, including:
+ *
+ * - version
+ * - language
+ * - code
+ * - fontSize
+ * - simplify
+ * - flatSwitch
+ * - highlight
+ * - colors
+ *
+ * This format makes the URL more compact and easier to extend in the future.
+ *
+ * Notes:
+ * - If `data` is present, it overrides all other URL parameters.
+ * - If `language` is provided without `data`, the default code sample for that
+ *   language is used.
+ */
+
+if (urlParams.has("compressed")) {
+  if (isLanguageInURL) {
+    console.error(
+      "Cannot provide both `language` and `compressed` in the URL.",
+    );
+  } else {
+    try {
+      const parsedData = JSON.parse(
+        LZString.decompressFromEncodedURIComponent(urlParams.get("compressed")),
+      );
+      if (parsedData.version === 1) {
+        fontSize = parsedData.fontSize;
+        simplify = parsedData.simplify;
+        flatSwitch = parsedData.flatSwitch;
+        highlight = parsedData.highlight;
+        parsedColorList = parsedData.colors;
+        const language = languageAliases[parsedData.language];
+        if (language) {
+          selection = languages.find((lang) => lang.language === language);
+          languageCode[language] = parsedData.code;
+        }
+      }
+    } catch (error) {
path: src/components/Demo.svelte
user: login: tmr232
body: A bit more of nitpicking - we catch an "exception" not an "error".
created_at: 2025-04-14T17:32:01Z
author_association: OWNER
diff_hunk: @@ -196,6 +280,15 @@ function onToggleClick(e) {
   toggleTheme();
 }
 
+function onSelectionChanged(e) {
+  console.log(selection);
+  const language = reverseLanguageAliases[selection.language];
+  const query = `?language=${language}`;
+  const newUrl = `${window.location.protocol}//${window.location.host}${window.location.pathname}${query}`;
+  window.history.replaceState(null, "", newUrl);
+  navigator.clipboard.writeText(newUrl);
path: src/components/Demo.svelte
user: login: tmr232
body: Please avoid writing to the clipboard here.
I see how my intention was perhaps interpreted to mean this - sorry.

I just want the URL to change, no changing the clipboard.
created_at: 2025-04-14T17:35:46Z
author_association: OWNER
diff_hunk: @@ -196,6 +280,15 @@ function onToggleClick(e) {
   toggleTheme();
 }
 
+function onSelectionChanged(e) {
+  console.log(selection);
+  const language = reverseLanguageAliases[selection.language];
+  const query = `?language=${language}`;
+  const newUrl = `${window.location.protocol}//${window.location.host}${window.location.pathname}${query}`;
path: src/components/Demo.svelte
user: login: tmr232
body: I think it's better if the language change does not affect other query params (other than removing the `compressed=` one, or maybe not changing it at all if it it exists? What do you think?)

If I add query params by hand, I don't want them to disappear because I changed the language.
created_at: 2025-04-14T17:38:18Z
author_association: OWNER
diff_hunk: @@ -69,65 +70,148 @@ let languages: {
   },
 ] as const;
 
-const urlParams = new URLSearchParams(window.location.search);
-if (urlParams.has("go")) {
-  languageCode.Go = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("go"),
-  );
-}
-if (urlParams.has("c")) {
-  languageCode.C = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c"),
-  );
-}
-if (urlParams.has("c++")) {
-  languageCode["C++"] = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c++"),
-  );
-}
-if (urlParams.has("python")) {
-  languageCode.Python = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("python"),
-  );
-}
-if (urlParams.has("typescript")) {
-  languageCode.TypeScript = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("typescript"),
-  );
-}
-if (urlParams.has("tsx")) {
-  languageCode.TSX = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("tsx"),
-  );
-}
+type ShareParameters = {
+  version: number;
+  language: string;
+  code: string;
+  fontSize: string;
+  simplify: boolean;
+  flatSwitch: boolean;
+  highlight: boolean;
+  colors: ColorList;
+};
+
+// ADD-LANGUAGES-HERE
+const languageAliases: Record<string, Language> = {
+  go: "Go",
+  c: "C",
+  cpp: "C++",
+  python: "Python",
+  typescript: "TypeScript",
+  tsx: "TSX",
+};
+
+const reverseLanguageAliases = Object.fromEntries(
+  Object.entries(languageAliases).map(([alias, lang]) => [lang, alias]),
+);
path: src/components/Demo.svelte
user: login: tmr232
body: I am not a fan of this mapping, as if we have multiple aliases for a language - we'll only get the last one into the mapping.
Alternatively, we can write a function to look for the _first_ match (that's usually what I'd expect at a glance) and use that.

That said, it doesn't really matter now - so up to you.
created_at: 2025-04-14T17:41:42Z
author_association: OWNER
diff_hunk: @@ -69,65 +70,148 @@ let languages: {
   },
 ] as const;
 
-const urlParams = new URLSearchParams(window.location.search);
-if (urlParams.has("go")) {
-  languageCode.Go = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("go"),
-  );
-}
-if (urlParams.has("c")) {
-  languageCode.C = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c"),
-  );
-}
-if (urlParams.has("c++")) {
-  languageCode["C++"] = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c++"),
-  );
-}
-if (urlParams.has("python")) {
-  languageCode.Python = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("python"),
-  );
-}
-if (urlParams.has("typescript")) {
-  languageCode.TypeScript = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("typescript"),
-  );
-}
-if (urlParams.has("tsx")) {
-  languageCode.TSX = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("tsx"),
-  );
-}
+type ShareParameters = {
+  version: number;
+  language: string;
+  code: string;
+  fontSize: string;
+  simplify: boolean;
+  flatSwitch: boolean;
+  highlight: boolean;
+  colors: ColorList;
+};
+
+// ADD-LANGUAGES-HERE
+const languageAliases: Record<string, Language> = {
+  go: "Go",
+  c: "C",
+  cpp: "C++",
+  python: "Python",
+  typescript: "TypeScript",
+  tsx: "TSX",
+};
+
+const reverseLanguageAliases = Object.fromEntries(
+  Object.entries(languageAliases).map(([alias, lang]) => [lang, alias]),
+);
 
+const currentVersion: number = 1; // Needs to be updated when a new version is released.
+let fontSize = $state("1em");
 let simplify = $state(true);
 let flatSwitch = $state(true);
 let highlight = $state(true);
+let parsedColorList = undefined;
+const urlParams = new URLSearchParams(window.location.search);
+let isLanguageInURL: boolean = false;
+let selection = $state(languages[0]);
+
+if (urlParams.has("language")) {
+  try {
path: src/components/Demo.svelte
user: login: Nivb1569
body: You're right, it will be fixed.
created_at: 2025-04-16T06:31:57Z
author_association: CONTRIBUTOR
diff_hunk: @@ -69,65 +70,148 @@ let languages: {
   },
 ] as const;
 
-const urlParams = new URLSearchParams(window.location.search);
-if (urlParams.has("go")) {
-  languageCode.Go = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("go"),
-  );
-}
-if (urlParams.has("c")) {
-  languageCode.C = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c"),
-  );
-}
-if (urlParams.has("c++")) {
-  languageCode["C++"] = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c++"),
-  );
-}
-if (urlParams.has("python")) {
-  languageCode.Python = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("python"),
-  );
-}
-if (urlParams.has("typescript")) {
-  languageCode.TypeScript = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("typescript"),
-  );
-}
-if (urlParams.has("tsx")) {
-  languageCode.TSX = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("tsx"),
-  );
-}
+type ShareParameters = {
+  version: number;
+  language: string;
+  code: string;
+  fontSize: string;
+  simplify: boolean;
+  flatSwitch: boolean;
+  highlight: boolean;
+  colors: ColorList;
+};
+
+// ADD-LANGUAGES-HERE
+const languageAliases: Record<string, Language> = {
+  go: "Go",
+  c: "C",
+  cpp: "C++",
+  python: "Python",
+  typescript: "TypeScript",
+  tsx: "TSX",
+};
+
+const reverseLanguageAliases = Object.fromEntries(
+  Object.entries(languageAliases).map(([alias, lang]) => [lang, alias]),
+);
 
+const currentVersion: number = 1; // Needs to be updated when a new version is released.
+let fontSize = $state("1em");
 let simplify = $state(true);
 let flatSwitch = $state(true);
 let highlight = $state(true);
+let parsedColorList = undefined;
+const urlParams = new URLSearchParams(window.location.search);
+let isLanguageInURL: boolean = false;
+let selection = $state(languages[0]);
+
+if (urlParams.has("language")) {
+  try {
+    isLanguageInURL = true;
+    const urlLanguage = urlParams.get("language");
+    const languageAlias = languageAliases[urlLanguage];
path: src/components/Demo.svelte
user: login: Nivb1569
body: Yes you right, my mistake.
created_at: 2025-04-16T06:33:15Z
author_association: CONTRIBUTOR
diff_hunk: @@ -69,65 +70,148 @@ let languages: {
   },
 ] as const;
 
-const urlParams = new URLSearchParams(window.location.search);
-if (urlParams.has("go")) {
-  languageCode.Go = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("go"),
-  );
-}
-if (urlParams.has("c")) {
-  languageCode.C = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c"),
-  );
-}
-if (urlParams.has("c++")) {
-  languageCode["C++"] = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c++"),
-  );
-}
-if (urlParams.has("python")) {
-  languageCode.Python = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("python"),
-  );
-}
-if (urlParams.has("typescript")) {
-  languageCode.TypeScript = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("typescript"),
-  );
-}
-if (urlParams.has("tsx")) {
-  languageCode.TSX = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("tsx"),
-  );
-}
+type ShareParameters = {
+  version: number;
+  language: string;
+  code: string;
+  fontSize: string;
+  simplify: boolean;
+  flatSwitch: boolean;
+  highlight: boolean;
+  colors: ColorList;
+};
+
+// ADD-LANGUAGES-HERE
+const languageAliases: Record<string, Language> = {
+  go: "Go",
+  c: "C",
+  cpp: "C++",
+  python: "Python",
+  typescript: "TypeScript",
+  tsx: "TSX",
+};
+
+const reverseLanguageAliases = Object.fromEntries(
+  Object.entries(languageAliases).map(([alias, lang]) => [lang, alias]),
+);
 
+const currentVersion: number = 1; // Needs to be updated when a new version is released.
+let fontSize = $state("1em");
 let simplify = $state(true);
 let flatSwitch = $state(true);
 let highlight = $state(true);
+let parsedColorList = undefined;
+const urlParams = new URLSearchParams(window.location.search);
+let isLanguageInURL: boolean = false;
+let selection = $state(languages[0]);
+
+if (urlParams.has("language")) {
+  try {
+    isLanguageInURL = true;
+    const urlLanguage = urlParams.get("language");
+    const languageAlias = languageAliases[urlLanguage];
+    const languageMatched = languages.find(
+      (lang) => lang.language === languageAlias,
+    );
+    if (languageMatched) {
+      selection = languageMatched;
+    } else {
+      console.error(`Unsupported or unknown language alias: '${urlLanguage}'`);
path: src/components/Demo.svelte
user: login: Nivb1569
body: You're right, I will fix the message
created_at: 2025-04-16T06:37:28Z
author_association: CONTRIBUTOR
diff_hunk: @@ -69,65 +70,148 @@ let languages: {
   },
 ] as const;
 
-const urlParams = new URLSearchParams(window.location.search);
-if (urlParams.has("go")) {
-  languageCode.Go = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("go"),
-  );
-}
-if (urlParams.has("c")) {
-  languageCode.C = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c"),
-  );
-}
-if (urlParams.has("c++")) {
-  languageCode["C++"] = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("c++"),
-  );
-}
-if (urlParams.has("python")) {
-  languageCode.Python = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("python"),
-  );
-}
-if (urlParams.has("typescript")) {
-  languageCode.TypeScript = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("typescript"),
-  );
-}
-if (urlParams.has("tsx")) {
-  languageCode.TSX = LZString.decompressFromEncodedURIComponent(
-    urlParams.get("tsx"),
-  );
-}
+type ShareParameters = {
+  version: number;
+  language: string;
+  code: string;
+  fontSize: string;
+  simplify: boolean;
+  flatSwitch: boolean;
+  highlight: boolean;
+  colors: ColorList;
+};
+
+// ADD-LANGUAGES-HERE
+const languageAliases: Record<string, Language> = {
+  go: "Go",
+  c: "C",
+  cpp: "C++",
+  python: "Python",
+  typescript: "TypeScript",
+  tsx: "TSX",
+};
+
+const reverseLanguageAliases = Object.fromEntries(
+  Object.entries(languageAliases).map(([alias, lang]) => [lang, alias]),
+);
 
+const currentVersion: number = 1; // Needs to be updated when a new version is released.
+let fontSize = $state("1em");
 let simplify = $state(true);
 let flatSwitch = $state(true);
 let highlight = $state(true);
+let parsedColorList = undefined;
+const urlParams = new URLSearchParams(window.location.search);
+let isLanguageInURL: boolean = false;
+let selection = $state(languages[0]);
+
+if (urlParams.has("language")) {
+  try {
+    isLanguageInURL = true;
+    const urlLanguage = urlParams.get("language");
+    const languageAlias = languageAliases[urlLanguage];
+    const languageMatched = languages.find(
+      (lang) => lang.language === languageAlias,
+    );
+    if (languageMatched) {
+      selection = languageMatched;
+    } else {
+      console.error(`Unsupported or unknown language alias: '${urlLanguage}'`);
+    }
+  } catch (error) {
+    console.error("Failed to get language from URL:", error);
+  }
+}
+
+/*
+ * Parses URL parameters according to version 1 format.
+ *
+ * This version expects a single `data` parameter containing a compressed JSON
+ * with all necessary configuration, including:
+ *
+ * - version
+ * - language
+ * - code
+ * - fontSize
+ * - simplify
+ * - flatSwitch
+ * - highlight
+ * - colors
+ *
+ * This format makes the URL more compact and easier to extend in the future.
+ *
+ * Notes:
+ * - If `data` is present, it overrides all other URL parameters.
+ * - If `language` is provided without `data`, the default code sample for that
+ *   language is used.
+ */
+
+if (urlParams.has("compressed")) {
+  if (isLanguageInURL) {
+    console.error(
+      "Cannot provide both `language` and `compressed` in the URL.",
+    );
+  } else {
+    try {
+      const parsedData = JSON.parse(
+        LZString.decompressFromEncodedURIComponent(urlParams.get("compressed")),
+      );
+      if (parsedData.version === 1) {
+        fontSize = parsedData.fontSize;
+        simplify = parsedData.simplify;
+        flatSwitch = parsedData.flatSwitch;
+        highlight = parsedData.highlight;
+        parsedColorList = parsedData.colors;
+        const language = languageAliases[parsedData.language];
+        if (language) {
+          selection = languages.find((lang) => lang.language === language);
+          languageCode[language] = parsedData.code;
+        }
+      }
+    } catch (error) {
path: src/components/Demo.svelte
user: login: Nivb1569
body: Sure, no problem
created_at: 2025-04-16T06:37:51Z
author_association: CONTRIBUTOR
diff_hunk: @@ -196,6 +280,15 @@ function onToggleClick(e) {
   toggleTheme();
 }
 
+function onSelectionChanged(e) {
+  console.log(selection);
+  const language = reverseLanguageAliases[selection.language];
+  const query = `?language=${language}`;
+  const newUrl = `${window.location.protocol}//${window.location.host}${window.location.pathname}${query}`;
+  window.history.replaceState(null, "", newUrl);
+  navigator.clipboard.writeText(newUrl);
path: src/components/Demo.svelte
user: login: Nivb1569
body: Got it, I won’t change the clipboard
created_at: 2025-04-16T06:43:37Z
author_association: CONTRIBUTOR
diff_hunk: @@ -196,6 +280,15 @@ function onToggleClick(e) {
   toggleTheme();
 }
 
+function onSelectionChanged(e) {
+  console.log(selection);
+  const language = reverseLanguageAliases[selection.language];
+  const query = `?language=${language}`;
+  const newUrl = `${window.location.protocol}//${window.location.host}${window.location.pathname}${query}`;
path: src/components/Demo.svelte
user: login: Nivb1569
body: As we discussed yesterday, I won’t change the URL queries unless `compressed` appears, in which case it will be removed.
created_at: 2025-04-16T06:48:22Z
author_association: CONTRIBUTOR
diff_hunk: @@ -196,6 +282,21 @@ function onToggleClick(e) {
   toggleTheme();
 }
 
+function onSelectionChanged(e) {
+  try {
+    console.log(selection);
+    const languageAlias = languageToAlias(selection.language);
+    const newUrl = new URL(window.location.href);
path: src/components/Demo.svelte
user: login: tmr232
body: Why is this called `newUrl`? Isn't it the existing URL?
created_at: 2025-04-16T19:12:26Z
author_association: OWNER

PR comments:
user: login: Nivb1569
created_at: 2025-04-04T13:36:46Z
body: Hi Tamir!
Thanks for the feedback. 
We appreciate the time you took to review the PR.
We will make the changes you suggested as soon as we can!
author_association: CONTRIBUTOR
user: login: Nivb1569
created_at: 2025-04-10T20:15:19Z
body: Hi Tamir,
I fixed all the changes you requested and refreshed the PR. Let me know if there's anything else you'd like me to update.
author_association: CONTRIBUTOR
user: login: Nivb1569
created_at: 2025-04-14T13:26:31Z
body: Hi Tamir, how are you?
I’ve implemented all the requested changes.
Please feel free to let me know if anything is missing or need anything else.
author_association: CONTRIBUTOR
user: login: Nivb1569
created_at: 2025-04-16T14:20:51Z
body: Hi Tamir,
I fixed all the changes you requested and refreshed the PR.
Thank you!
author_association: CONTRIBUTOR
user: login: Nivb1569
created_at: 2025-04-16T19:39:20Z
body: Hi Tamir,
I made some tests and everything seems to be working correctly on my side.
Could you share more details about the situation where the color-picker breaks please?
Maybe you have a specific URL I can check on my side?
Thanks.
author_association: CONTRIBUTOR
user: login: tmr232
created_at: 2025-04-16T19:50:43Z
body: If you open the color-picker and change a color, it should update live. When I try your PR locally - it does not.
Later, if I close the color-picker, no color is updated.
When I open it again - the colors are reset to their original values.
author_association: OWNER
user: login: Nivb1569
created_at: 2025-04-17T09:30:14Z
body: It's really weird everything seems to be working fine on my side.
I recorded a quick screen capture to show that the color picker is working correctly:
https://drive.google.com/file/d/1-iiD7di0863vglizxpUHtQd1UwJYXYNS/view?usp=sharing
Let me know if you have any idea what be causing the issue on your side.
Thanks!
author_association: CONTRIBUTOR
user: login: tmr232
created_at: 2025-04-17T16:12:39Z
body: Try running `bun install --frozen-lockfile` to make sure all your deps are up to date, and run it again. Maybe something got out of sync?
author_association: OWNER
user: login: Nivb1569
created_at: 2025-04-17T18:56:27Z
body: I tried running `bun install --frozen-lockfile`, and everything still looks good on my side.
Maybe we can jump on a quick Zoom call whenever you want and try to figure it out together?
author_association: CONTRIBUTOR