diff --git a/.clang-format b/.clang-format
deleted file mode 100644
index 4fa5253..0000000
--- a/.clang-format
+++ /dev/null
@@ -1,11 +0,0 @@
----
-Language: Cpp
-BasedOnStyle: Google
-AllowShortBlocksOnASingleLine: true
-AllowShortCaseLabelsOnASingleLine: true
-AllowShortFunctionsOnASingleLine: All
-AllowShortLoopsOnASingleLine: true
-AllowShortIfStatementsOnASingleLine: true
-BinPackArguments: false
-BinPackParameters: false
-...
diff --git a/.gitattributes b/.gitattributes
deleted file mode 100644
index 1890acc..0000000
--- a/.gitattributes
+++ /dev/null
@@ -1,7 +0,0 @@
-**/*.jpg filter=lfs diff=lfs merge=lfs -text
-**/*.png filter=lfs diff=lfs merge=lfs -text
-**/*.jpeg filter=lfs diff=lfs merge=lfs -text
-**/*.gif filter=lfs diff=lfs merge=lfs -text
-**/*.pdf filter=lfs diff=lfs merge=lfs -text
-**/*.mp4 filter=lfs diff=lfs merge=lfs -text
-**/*.mov filter=lfs diff=lfs merge=lfs -text
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
index a0fe900..f7aecce 100644
--- a/.github/FUNDING.yml
+++ b/.github/FUNDING.yml
@@ -1,3 +1,3 @@
 github: niosus
 patreon: code_for_yourself
-custom: "https://www.paypal.com/donate/?cmd=_s-xclick&hosted_button_id=2QLY7J4Q944HS"
+custom: "https://www.paypal.me/niosus"
diff --git a/.github/mcl_config.json b/.github/mcl_config.json
deleted file mode 100644
index e6d168e..0000000
--- a/.github/mcl_config.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
-  "aliveStatusCodes": [200, 206, 403],
-  "ignorePatterns": [
-    {
-      "bazel": "^https://bazel.build",
-      "make": "^https://makefiletutorial.com"
-    }
-  ]
-}
diff --git a/.github/workflows/action.yml b/.github/workflows/action.yml
index 3ecb439..04a60dc 100644
--- a/.github/workflows/action.yml
+++ b/.github/workflows/action.yml
@@ -1,25 +1,10 @@
-name: Checks
+name: Check Markdown links
 
 on: push
 
 jobs:
   markdown-link-check:
-    name: All Markdown links are valid
     runs-on: ubuntu-latest
     steps:
-    - uses: actions/checkout@v4
+    - uses: actions/checkout@master
     - uses: gaurav-nelson/github-action-markdown-link-check@v1
-      with:
-        config-file: '.github/mcl_config.json'
-
-  check-snippet-compilation:
-    name: All code snippets compile
-    runs-on: ubuntu-latest
-    steps:
-    - uses: actions/checkout@v4
-    - name: Check that all snippets compile
-      run: |
-        pip install pipenv
-        cd scripts
-        pipenv install
-        pipenv run python3 validate_code_snippets.py --project-folder ../
diff --git a/.gitignore b/.gitignore
index d39d4bf..a683bd1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,3 @@
 .DS_Store
 .vscode/
 *.html
-**/build
-*.a
-*.so
-*.o
diff --git a/Slides.code-workspace b/Slides.code-workspace
deleted file mode 100644
index da5a104..0000000
--- a/Slides.code-workspace
+++ /dev/null
@@ -1,91 +0,0 @@
-{
-	"folders": [
-		{
-			"path": "."
-		},
-		{
-			"path": "../../modern-cpp-course"
-		}
-	],
-	"settings": {
-		"markdown.marp.themes": [
-			"theme.css"
-		],
-		"revealjs.css": [
-			"theme-reveal.css"
-		],
-		"revealjs.highlightTheme": "atom-one-dark-reasonable",
-		"revealjs.theme": "black",
-		"revealjs.transitionSpeed": "fast",
-		"revealjs.slideNumber": true,
-		"revealjs.showSlideNumber": "print",
-		"markdown.marp.enableHtml": true,
-		"files.associations": {
-			"iostream": "cpp",
-			"__bit_reference": "cpp",
-			"__bits": "cpp",
-			"__config": "cpp",
-			"__debug": "cpp",
-			"__errc": "cpp",
-			"__hash_table": "cpp",
-			"__locale": "cpp",
-			"__mutex_base": "cpp",
-			"__node_handle": "cpp",
-			"__nullptr": "cpp",
-			"__split_buffer": "cpp",
-			"__string": "cpp",
-			"__threading_support": "cpp",
-			"__tuple": "cpp",
-			"array": "cpp",
-			"atomic": "cpp",
-			"bit": "cpp",
-			"bitset": "cpp",
-			"cctype": "cpp",
-			"chrono": "cpp",
-			"clocale": "cpp",
-			"cmath": "cpp",
-			"compare": "cpp",
-			"complex": "cpp",
-			"concepts": "cpp",
-			"cstdarg": "cpp",
-			"cstddef": "cpp",
-			"cstdint": "cpp",
-			"cstdio": "cpp",
-			"cstdlib": "cpp",
-			"cstring": "cpp",
-			"ctime": "cpp",
-			"cwchar": "cpp",
-			"cwctype": "cpp",
-			"exception": "cpp",
-			"initializer_list": "cpp",
-			"ios": "cpp",
-			"iosfwd": "cpp",
-			"istream": "cpp",
-			"limits": "cpp",
-			"locale": "cpp",
-			"memory": "cpp",
-			"mutex": "cpp",
-			"new": "cpp",
-			"optional": "cpp",
-			"ostream": "cpp",
-			"ratio": "cpp",
-			"sstream": "cpp",
-			"stdexcept": "cpp",
-			"streambuf": "cpp",
-			"string": "cpp",
-			"string_view": "cpp",
-			"system_error": "cpp",
-			"tuple": "cpp",
-			"type_traits": "cpp",
-			"typeinfo": "cpp",
-			"unordered_map": "cpp",
-			"variant": "cpp",
-			"vector": "cpp",
-			"__functional_base": "cpp",
-			"algorithm": "cpp",
-			"functional": "cpp",
-			"iterator": "cpp",
-			"utility": "cpp"
-		}
-	}
-}
\ No newline at end of file
diff --git a/animation/all_or_nothing/.gitignore b/animation/all_or_nothing/.gitignore
deleted file mode 100644
index 829b1c7..0000000
--- a/animation/all_or_nothing/.gitignore
+++ /dev/null
@@ -1,15 +0,0 @@
-# Generated files
-node_modules
-output
-dist
-
-# Editor directories and files
-.vscode/*
-!.vscode/extensions.json
-.idea
-.DS_Store
-*.suo
-*.ntvs*
-*.njsproj
-*.sln
-*.sw?
diff --git a/animation/all_or_nothing/package-lock.json b/animation/all_or_nothing/package-lock.json
deleted file mode 100644
index 9ebec27..0000000
--- a/animation/all_or_nothing/package-lock.json
+++ /dev/null
@@ -1,802 +0,0 @@
-{
-  "name": "value_semantics",
-  "version": "0.0.0",
-  "lockfileVersion": 3,
-  "requires": true,
-  "packages": {
-    "": {
-      "name": "value_semantics",
-      "version": "0.0.0",
-      "dependencies": {
-        "@motion-canvas/2d": "^3.4.0",
-        "@motion-canvas/core": "^3.4.0"
-      },
-      "devDependencies": {
-        "@motion-canvas/ui": "^3.4.0",
-        "@motion-canvas/vite-plugin": "^3.4.0",
-        "typescript": "^4.9.5",
-        "vite": "^4.1.4"
-      }
-    },
-    "node_modules/@esbuild/android-arm": {
-      "version": "0.17.15",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.15.tgz",
-      "integrity": "sha512-sRSOVlLawAktpMvDyJIkdLI/c/kdRTOqo8t6ImVxg8yT7LQDUYV5Rp2FKeEosLr6ZCja9UjYAzyRSxGteSJPYg==",
-      "cpu": [
-        "arm"
-      ],
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/android-arm64": {
-      "version": "0.17.15",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.15.tgz",
-      "integrity": "sha512-0kOB6Y7Br3KDVgHeg8PRcvfLkq+AccreK///B4Z6fNZGr/tNHX0z2VywCc7PTeWp+bPvjA5WMvNXltHw5QjAIA==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/android-x64": {
-      "version": "0.17.15",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.15.tgz",
-      "integrity": "sha512-MzDqnNajQZ63YkaUWVl9uuhcWyEyh69HGpMIrf+acR4otMkfLJ4sUCxqwbCyPGicE9dVlrysI3lMcDBjGiBBcQ==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/darwin-arm64": {
-      "version": "0.17.15",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.15.tgz",
-      "integrity": "sha512-7siLjBc88Z4+6qkMDxPT2juf2e8SJxmsbNVKFY2ifWCDT72v5YJz9arlvBw5oB4W/e61H1+HDB/jnu8nNg0rLA==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/darwin-x64": {
-      "version": "0.17.15",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.15.tgz",
-      "integrity": "sha512-NbImBas2rXwYI52BOKTW342Tm3LTeVlaOQ4QPZ7XuWNKiO226DisFk/RyPk3T0CKZkKMuU69yOvlapJEmax7cg==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/freebsd-arm64": {
-      "version": "0.17.15",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.15.tgz",
-      "integrity": "sha512-Xk9xMDjBVG6CfgoqlVczHAdJnCs0/oeFOspFap5NkYAmRCT2qTn1vJWA2f419iMtsHSLm+O8B6SLV/HlY5cYKg==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "freebsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/freebsd-x64": {
-      "version": "0.17.15",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.15.tgz",
-      "integrity": "sha512-3TWAnnEOdclvb2pnfsTWtdwthPfOz7qAfcwDLcfZyGJwm1SRZIMOeB5FODVhnM93mFSPsHB9b/PmxNNbSnd0RQ==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "freebsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-arm": {
-      "version": "0.17.15",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.15.tgz",
-      "integrity": "sha512-MLTgiXWEMAMr8nmS9Gigx43zPRmEfeBfGCwxFQEMgJ5MC53QKajaclW6XDPjwJvhbebv+RzK05TQjvH3/aM4Xw==",
-      "cpu": [
-        "arm"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-arm64": {
-      "version": "0.17.15",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.15.tgz",
-      "integrity": "sha512-T0MVnYw9KT6b83/SqyznTs/3Jg2ODWrZfNccg11XjDehIved2oQfrX/wVuev9N936BpMRaTR9I1J0tdGgUgpJA==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-ia32": {
-      "version": "0.17.15",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.15.tgz",
-      "integrity": "sha512-wp02sHs015T23zsQtU4Cj57WiteiuASHlD7rXjKUyAGYzlOKDAjqK6bk5dMi2QEl/KVOcsjwL36kD+WW7vJt8Q==",
-      "cpu": [
-        "ia32"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-loong64": {
-      "version": "0.17.15",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.15.tgz",
-      "integrity": "sha512-k7FsUJjGGSxwnBmMh8d7IbObWu+sF/qbwc+xKZkBe/lTAF16RqxRCnNHA7QTd3oS2AfGBAnHlXL67shV5bBThQ==",
-      "cpu": [
-        "loong64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-mips64el": {
-      "version": "0.17.15",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.15.tgz",
-      "integrity": "sha512-ZLWk6czDdog+Q9kE/Jfbilu24vEe/iW/Sj2d8EVsmiixQ1rM2RKH2n36qfxK4e8tVcaXkvuV3mU5zTZviE+NVQ==",
-      "cpu": [
-        "mips64el"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-ppc64": {
-      "version": "0.17.15",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.15.tgz",
-      "integrity": "sha512-mY6dPkIRAiFHRsGfOYZC8Q9rmr8vOBZBme0/j15zFUKM99d4ILY4WpOC7i/LqoY+RE7KaMaSfvY8CqjJtuO4xg==",
-      "cpu": [
-        "ppc64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-riscv64": {
-      "version": "0.17.15",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.15.tgz",
-      "integrity": "sha512-EcyUtxffdDtWjjwIH8sKzpDRLcVtqANooMNASO59y+xmqqRYBBM7xVLQhqF7nksIbm2yHABptoioS9RAbVMWVA==",
-      "cpu": [
-        "riscv64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-s390x": {
-      "version": "0.17.15",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.15.tgz",
-      "integrity": "sha512-BuS6Jx/ezxFuHxgsfvz7T4g4YlVrmCmg7UAwboeyNNg0OzNzKsIZXpr3Sb/ZREDXWgt48RO4UQRDBxJN3B9Rbg==",
-      "cpu": [
-        "s390x"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-x64": {
-      "version": "0.17.15",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.15.tgz",
-      "integrity": "sha512-JsdS0EgEViwuKsw5tiJQo9UdQdUJYuB+Mf6HxtJSPN35vez1hlrNb1KajvKWF5Sa35j17+rW1ECEO9iNrIXbNg==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/netbsd-x64": {
-      "version": "0.17.15",
-      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.15.tgz",
-      "integrity": "sha512-R6fKjtUysYGym6uXf6qyNephVUQAGtf3n2RCsOST/neIwPqRWcnc3ogcielOd6pT+J0RDR1RGcy0ZY7d3uHVLA==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "netbsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/openbsd-x64": {
-      "version": "0.17.15",
-      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.15.tgz",
-      "integrity": "sha512-mVD4PGc26b8PI60QaPUltYKeSX0wxuy0AltC+WCTFwvKCq2+OgLP4+fFd+hZXzO2xW1HPKcytZBdjqL6FQFa7w==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "openbsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/sunos-x64": {
-      "version": "0.17.15",
-      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.15.tgz",
-      "integrity": "sha512-U6tYPovOkw3459t2CBwGcFYfFRjivcJJc1WC8Q3funIwX8x4fP+R6xL/QuTPNGOblbq/EUDxj9GU+dWKX0oWlQ==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "sunos"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/win32-arm64": {
-      "version": "0.17.15",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.15.tgz",
-      "integrity": "sha512-W+Z5F++wgKAleDABemiyXVnzXgvRFs+GVKThSI+mGgleLWluv0D7Diz4oQpgdpNzh4i2nNDzQtWbjJiqutRp6Q==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/win32-ia32": {
-      "version": "0.17.15",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.15.tgz",
-      "integrity": "sha512-Muz/+uGgheShKGqSVS1KsHtCyEzcdOn/W/Xbh6H91Etm+wiIfwZaBn1W58MeGtfI8WA961YMHFYTthBdQs4t+w==",
-      "cpu": [
-        "ia32"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/win32-x64": {
-      "version": "0.17.15",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.15.tgz",
-      "integrity": "sha512-DjDa9ywLUUmjhV2Y9wUTIF+1XsmuFGvZoCmOWkli1XcNAh5t25cc7fgsCx4Zi/Uurep3TTLyDiKATgGEg61pkA==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@motion-canvas/2d": {
-      "version": "3.4.0",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/2d/-/2d-3.4.0.tgz",
-      "integrity": "sha512-3CmB2v6eQiSo7763goTKdAreTC4qIM9Qx/N31/Ov7CVWVZ31nUFGR5pRkfyrnoHHI718cfuZNArITPlB86U+LA==",
-      "dependencies": {
-        "@motion-canvas/core": "^3.4.0",
-        "code-fns": "^0.8.2",
-        "mathjax-full": "^3.2.2"
-      }
-    },
-    "node_modules/@motion-canvas/core": {
-      "version": "3.4.0",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/core/-/core-3.4.0.tgz",
-      "integrity": "sha512-qGLjnhBshnXJqTgtnx/eSJTYmXWo5PtemV4TCczkbDQhvvjNxWwVHIQDNTG4bCg7R1gzKPizFzW63L9q+bIUaw==",
-      "dependencies": {
-        "@types/chroma-js": "^2.1.4",
-        "chroma-js": "^2.4.2"
-      },
-      "peerDependencies": {
-        "vite": "^4.1.4"
-      }
-    },
-    "node_modules/@motion-canvas/ui": {
-      "version": "3.4.0",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/ui/-/ui-3.4.0.tgz",
-      "integrity": "sha512-ntgBqqlZdAiTwpySyjf9UFBYDwXgr61UQDtyAJiQzqy0HqDeO0TZKSIqSgAgkY8GCwR2ELP+ITyEW6H0Mq6ZKw==",
-      "dev": true,
-      "dependencies": {
-        "@motion-canvas/core": "^3.4.0"
-      }
-    },
-    "node_modules/@motion-canvas/vite-plugin": {
-      "version": "3.4.0",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/vite-plugin/-/vite-plugin-3.4.0.tgz",
-      "integrity": "sha512-tzSCw1RruDBJsF3WV6nXkMMUd5P4KMmSQ+j477qqxTIrklE+Pm4Y9Mdn3M2v3q6fr/o2b4nLa5l7QC/iZ2n9PQ==",
-      "dev": true,
-      "dependencies": {
-        "follow-redirects": "^1.15.2",
-        "mime-types": "^2.1.35"
-      },
-      "peerDependencies": {
-        "vite": "4.x"
-      }
-    },
-    "node_modules/@types/chroma-js": {
-      "version": "2.4.0",
-      "resolved": "https://registry.npmjs.org/@types/chroma-js/-/chroma-js-2.4.0.tgz",
-      "integrity": "sha512-JklMxityrwjBTjGY2anH8JaTx3yjRU3/sEHSblLH1ba5lqcSh1LnImXJZO5peJfXyqKYWjHTGy4s5Wz++hARrw=="
-    },
-    "node_modules/@types/hast": {
-      "version": "2.3.4",
-      "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.4.tgz",
-      "integrity": "sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==",
-      "dependencies": {
-        "@types/unist": "*"
-      }
-    },
-    "node_modules/@types/unist": {
-      "version": "2.0.6",
-      "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz",
-      "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ=="
-    },
-    "node_modules/@wooorm/starry-night": {
-      "version": "1.7.0",
-      "resolved": "https://registry.npmjs.org/@wooorm/starry-night/-/starry-night-1.7.0.tgz",
-      "integrity": "sha512-ktO0nkddrovIoNW2jAUT+Cdd9n1bWjy1Ir4CdcmgTaT6E94HLlQfu7Yv62falclBEwvsuVp3bSBw23wtta1fNw==",
-      "dependencies": {
-        "@types/hast": "^2.0.0",
-        "import-meta-resolve": "^2.0.0",
-        "vscode-oniguruma": "^1.0.0",
-        "vscode-textmate": "^9.0.0"
-      },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/wooorm"
-      }
-    },
-    "node_modules/chroma-js": {
-      "version": "2.4.2",
-      "resolved": "https://registry.npmjs.org/chroma-js/-/chroma-js-2.4.2.tgz",
-      "integrity": "sha512-U9eDw6+wt7V8z5NncY2jJfZa+hUH8XEj8FQHgFJTrUFnJfXYf4Ml4adI2vXZOjqRDpFWtYVWypDfZwnJ+HIR4A=="
-    },
-    "node_modules/code-fns": {
-      "version": "0.8.2",
-      "resolved": "https://registry.npmjs.org/code-fns/-/code-fns-0.8.2.tgz",
-      "integrity": "sha512-3VVeq3cnWxWiWKFLsVo+XWsOXBSW2gAx2uv0ViETLNmNuygEPHlCeDAv/Zy7xXqPgXtgLZyvIJZmx+ojTgOIGA==",
-      "dependencies": {
-        "@wooorm/starry-night": "^1.2.0"
-      }
-    },
-    "node_modules/commander": {
-      "version": "9.2.0",
-      "resolved": "https://registry.npmjs.org/commander/-/commander-9.2.0.tgz",
-      "integrity": "sha512-e2i4wANQiSXgnrBlIatyHtP1odfUp0BbV5Y5nEGbxtIrStkEOAAzCUirvLBNXHLr7kwLvJl6V+4V3XV9x7Wd9w==",
-      "engines": {
-        "node": "^12.20.0 || >=14"
-      }
-    },
-    "node_modules/esbuild": {
-      "version": "0.17.15",
-      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.15.tgz",
-      "integrity": "sha512-LBUV2VsUIc/iD9ME75qhT4aJj0r75abCVS0jakhFzOtR7TQsqQA5w0tZ+KTKnwl3kXE0MhskNdHDh/I5aCR1Zw==",
-      "hasInstallScript": true,
-      "bin": {
-        "esbuild": "bin/esbuild"
-      },
-      "engines": {
-        "node": ">=12"
-      },
-      "optionalDependencies": {
-        "@esbuild/android-arm": "0.17.15",
-        "@esbuild/android-arm64": "0.17.15",
-        "@esbuild/android-x64": "0.17.15",
-        "@esbuild/darwin-arm64": "0.17.15",
-        "@esbuild/darwin-x64": "0.17.15",
-        "@esbuild/freebsd-arm64": "0.17.15",
-        "@esbuild/freebsd-x64": "0.17.15",
-        "@esbuild/linux-arm": "0.17.15",
-        "@esbuild/linux-arm64": "0.17.15",
-        "@esbuild/linux-ia32": "0.17.15",
-        "@esbuild/linux-loong64": "0.17.15",
-        "@esbuild/linux-mips64el": "0.17.15",
-        "@esbuild/linux-ppc64": "0.17.15",
-        "@esbuild/linux-riscv64": "0.17.15",
-        "@esbuild/linux-s390x": "0.17.15",
-        "@esbuild/linux-x64": "0.17.15",
-        "@esbuild/netbsd-x64": "0.17.15",
-        "@esbuild/openbsd-x64": "0.17.15",
-        "@esbuild/sunos-x64": "0.17.15",
-        "@esbuild/win32-arm64": "0.17.15",
-        "@esbuild/win32-ia32": "0.17.15",
-        "@esbuild/win32-x64": "0.17.15"
-      }
-    },
-    "node_modules/esm": {
-      "version": "3.2.25",
-      "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz",
-      "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==",
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/follow-redirects": {
-      "version": "1.15.2",
-      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
-      "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "individual",
-          "url": "https://github.com/sponsors/RubenVerborgh"
-        }
-      ],
-      "engines": {
-        "node": ">=4.0"
-      },
-      "peerDependenciesMeta": {
-        "debug": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/fsevents": {
-      "version": "2.3.2",
-      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
-      "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
-      }
-    },
-    "node_modules/function-bind": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
-      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
-    },
-    "node_modules/has": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
-      "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
-      "dependencies": {
-        "function-bind": "^1.1.1"
-      },
-      "engines": {
-        "node": ">= 0.4.0"
-      }
-    },
-    "node_modules/import-meta-resolve": {
-      "version": "2.2.2",
-      "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-2.2.2.tgz",
-      "integrity": "sha512-f8KcQ1D80V7RnqVm+/lirO9zkOxjGxhaTC1IPrBGd3MEfNgmNG67tSUO9gTi2F3Blr2Az6g1vocaxzkVnWl9MA==",
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/wooorm"
-      }
-    },
-    "node_modules/is-core-module": {
-      "version": "2.11.0",
-      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz",
-      "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==",
-      "dependencies": {
-        "has": "^1.0.3"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/mathjax-full": {
-      "version": "3.2.2",
-      "resolved": "https://registry.npmjs.org/mathjax-full/-/mathjax-full-3.2.2.tgz",
-      "integrity": "sha512-+LfG9Fik+OuI8SLwsiR02IVdjcnRCy5MufYLi0C3TdMT56L/pjB0alMVGgoWJF8pN9Rc7FESycZB9BMNWIid5w==",
-      "dependencies": {
-        "esm": "^3.2.25",
-        "mhchemparser": "^4.1.0",
-        "mj-context-menu": "^0.6.1",
-        "speech-rule-engine": "^4.0.6"
-      }
-    },
-    "node_modules/mhchemparser": {
-      "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/mhchemparser/-/mhchemparser-4.1.1.tgz",
-      "integrity": "sha512-R75CUN6O6e1t8bgailrF1qPq+HhVeFTM3XQ0uzI+mXTybmphy3b6h4NbLOYhemViQ3lUs+6CKRkC3Ws1TlYREA=="
-    },
-    "node_modules/mime-db": {
-      "version": "1.52.0",
-      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
-      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/mime-types": {
-      "version": "2.1.35",
-      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
-      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
-      "dev": true,
-      "dependencies": {
-        "mime-db": "1.52.0"
-      },
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/mj-context-menu": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/mj-context-menu/-/mj-context-menu-0.6.1.tgz",
-      "integrity": "sha512-7NO5s6n10TIV96d4g2uDpG7ZDpIhMh0QNfGdJw/W47JswFcosz457wqz/b5sAKvl12sxINGFCn80NZHKwxQEXA=="
-    },
-    "node_modules/nanoid": {
-      "version": "3.3.6",
-      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
-      "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/ai"
-        }
-      ],
-      "bin": {
-        "nanoid": "bin/nanoid.cjs"
-      },
-      "engines": {
-        "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
-      }
-    },
-    "node_modules/path-parse": {
-      "version": "1.0.7",
-      "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
-      "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
-    },
-    "node_modules/picocolors": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
-      "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
-    },
-    "node_modules/postcss": {
-      "version": "8.4.21",
-      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz",
-      "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==",
-      "funding": [
-        {
-          "type": "opencollective",
-          "url": "https://opencollective.com/postcss/"
-        },
-        {
-          "type": "tidelift",
-          "url": "https://tidelift.com/funding/github/npm/postcss"
-        }
-      ],
-      "dependencies": {
-        "nanoid": "^3.3.4",
-        "picocolors": "^1.0.0",
-        "source-map-js": "^1.0.2"
-      },
-      "engines": {
-        "node": "^10 || ^12 || >=14"
-      }
-    },
-    "node_modules/resolve": {
-      "version": "1.22.1",
-      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
-      "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
-      "dependencies": {
-        "is-core-module": "^2.9.0",
-        "path-parse": "^1.0.7",
-        "supports-preserve-symlinks-flag": "^1.0.0"
-      },
-      "bin": {
-        "resolve": "bin/resolve"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/rollup": {
-      "version": "3.20.2",
-      "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.20.2.tgz",
-      "integrity": "sha512-3zwkBQl7Ai7MFYQE0y1MeQ15+9jsi7XxfrqwTb/9EK8D9C9+//EBR4M+CuA1KODRaNbFez/lWxA5vhEGZp4MUg==",
-      "bin": {
-        "rollup": "dist/bin/rollup"
-      },
-      "engines": {
-        "node": ">=14.18.0",
-        "npm": ">=8.0.0"
-      },
-      "optionalDependencies": {
-        "fsevents": "~2.3.2"
-      }
-    },
-    "node_modules/source-map-js": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
-      "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/speech-rule-engine": {
-      "version": "4.0.7",
-      "resolved": "https://registry.npmjs.org/speech-rule-engine/-/speech-rule-engine-4.0.7.tgz",
-      "integrity": "sha512-sJrL3/wHzNwJRLBdf6CjJWIlxC04iYKkyXvYSVsWVOiC2DSkHmxsqOhEeMsBA9XK+CHuNcsdkbFDnoUfAsmp9g==",
-      "dependencies": {
-        "commander": "9.2.0",
-        "wicked-good-xpath": "1.3.0",
-        "xmldom-sre": "0.1.31"
-      },
-      "bin": {
-        "sre": "bin/sre"
-      }
-    },
-    "node_modules/supports-preserve-symlinks-flag": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
-      "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/typescript": {
-      "version": "4.9.5",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
-      "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
-      "dev": true,
-      "bin": {
-        "tsc": "bin/tsc",
-        "tsserver": "bin/tsserver"
-      },
-      "engines": {
-        "node": ">=4.2.0"
-      }
-    },
-    "node_modules/vite": {
-      "version": "4.2.1",
-      "resolved": "https://registry.npmjs.org/vite/-/vite-4.2.1.tgz",
-      "integrity": "sha512-7MKhqdy0ISo4wnvwtqZkjke6XN4taqQ2TBaTccLIpOKv7Vp2h4Y+NpmWCnGDeSvvn45KxvWgGyb0MkHvY1vgbg==",
-      "dependencies": {
-        "esbuild": "^0.17.5",
-        "postcss": "^8.4.21",
-        "resolve": "^1.22.1",
-        "rollup": "^3.18.0"
-      },
-      "bin": {
-        "vite": "bin/vite.js"
-      },
-      "engines": {
-        "node": "^14.18.0 || >=16.0.0"
-      },
-      "optionalDependencies": {
-        "fsevents": "~2.3.2"
-      },
-      "peerDependencies": {
-        "@types/node": ">= 14",
-        "less": "*",
-        "sass": "*",
-        "stylus": "*",
-        "sugarss": "*",
-        "terser": "^5.4.0"
-      },
-      "peerDependenciesMeta": {
-        "@types/node": {
-          "optional": true
-        },
-        "less": {
-          "optional": true
-        },
-        "sass": {
-          "optional": true
-        },
-        "stylus": {
-          "optional": true
-        },
-        "sugarss": {
-          "optional": true
-        },
-        "terser": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/vscode-oniguruma": {
-      "version": "1.7.0",
-      "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz",
-      "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA=="
-    },
-    "node_modules/vscode-textmate": {
-      "version": "9.0.0",
-      "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-9.0.0.tgz",
-      "integrity": "sha512-Cl65diFGxz7gpwbav10HqiY/eVYTO1sjQpmRmV991Bj7wAoOAjGQ97PpQcXorDE2Uc4hnGWLY17xme+5t6MlSg=="
-    },
-    "node_modules/wicked-good-xpath": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/wicked-good-xpath/-/wicked-good-xpath-1.3.0.tgz",
-      "integrity": "sha512-Gd9+TUn5nXdwj/hFsPVx5cuHHiF5Bwuc30jZ4+ronF1qHK5O7HD0sgmXWSEgwKquT3ClLoKPVbO6qGwVwLzvAw=="
-    },
-    "node_modules/xmldom-sre": {
-      "version": "0.1.31",
-      "resolved": "https://registry.npmjs.org/xmldom-sre/-/xmldom-sre-0.1.31.tgz",
-      "integrity": "sha512-f9s+fUkX04BxQf+7mMWAp5zk61pciie+fFLC9hX9UVvCeJQfNHRHXpeo5MPcR0EUf57PYLdt+ZO4f3Ipk2oZUw==",
-      "engines": {
-        "node": ">=0.1"
-      }
-    }
-  }
-}
diff --git a/animation/all_or_nothing/package.json b/animation/all_or_nothing/package.json
deleted file mode 100644
index 4c4a6cf..0000000
--- a/animation/all_or_nothing/package.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "name": "value_semantics",
-  "private": true,
-  "version": "0.0.0",
-  "scripts": {
-    "serve": "vite",
-    "build": "tsc && vite build"
-  },
-  "dependencies": {
-    "@motion-canvas/core": "^3.4.0",
-    "@motion-canvas/2d": "^3.4.0"
-  },
-  "devDependencies": {
-    "@motion-canvas/ui": "^3.4.0",
-    "@motion-canvas/vite-plugin": "^3.4.0",
-    "typescript": "^4.9.5",
-    "vite": "^4.1.4"
-  }
-}
\ No newline at end of file
diff --git a/animation/all_or_nothing/src/motion-canvas.d.ts b/animation/all_or_nothing/src/motion-canvas.d.ts
deleted file mode 100644
index 067c6a4..0000000
--- a/animation/all_or_nothing/src/motion-canvas.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-/// <reference types="@motion-canvas/core/project" />
diff --git a/animation/all_or_nothing/src/project.meta b/animation/all_or_nothing/src/project.meta
deleted file mode 100644
index 95df883..0000000
--- a/animation/all_or_nothing/src/project.meta
+++ /dev/null
@@ -1,32 +0,0 @@
-{
-  "version": 0,
-  "shared": {
-    "background": "rgb(10,20,30)",
-    "range": [
-      0,
-      null
-    ],
-    "size": {
-      "x": 1920,
-      "y": 1080
-    },
-    "audioOffset": 0
-  },
-  "preview": {
-    "fps": 30,
-    "resolutionScale": 1
-  },
-  "rendering": {
-    "fps": 30,
-    "resolutionScale": 2,
-    "colorSpace": "srgb",
-    "exporter": {
-      "name": "image sequence",
-      "options": {
-        "fileType": "image/png",
-        "quality": 100,
-        "groupByScene": true
-      }
-    }
-  }
-}
\ No newline at end of file
diff --git a/animation/all_or_nothing/src/project.ts b/animation/all_or_nothing/src/project.ts
deleted file mode 100644
index a3b95dd..0000000
--- a/animation/all_or_nothing/src/project.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import {makeProject} from '@motion-canvas/core';
-
-import example from './scenes/example?scene';
-import memory from './scenes/memory?scene';
-
-export default makeProject({
-  scenes: [memory, example],
-});
diff --git a/animation/all_or_nothing/src/scenes/example.meta b/animation/all_or_nothing/src/scenes/example.meta
deleted file mode 100644
index 2d62bec..0000000
--- a/animation/all_or_nothing/src/scenes/example.meta
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-  "version": 0,
-  "timeEvents": [],
-  "seed": 1501821170
-}
\ No newline at end of file
diff --git a/animation/all_or_nothing/src/scenes/example.tsx b/animation/all_or_nothing/src/scenes/example.tsx
deleted file mode 100644
index c544e8c..0000000
--- a/animation/all_or_nothing/src/scenes/example.tsx
+++ /dev/null
@@ -1,471 +0,0 @@
-import { makeScene2D } from '@motion-canvas/2d/lib/scenes';
-import { createRef } from '@motion-canvas/core/lib/utils';
-import { Rect, Node } from '@motion-canvas/2d/lib/components';
-import {
-  CodeBlock,
-  edit,
-  insert,
-  lines,
-  word,
-  remove,
-  CodeModification,
-} from '@motion-canvas/2d/lib/components/CodeBlock';
-import { all, waitFor, waitUntil } from '@motion-canvas/core/lib/flow';
-import { DEFAULT } from '@motion-canvas/core/lib/signals';
-import { BBox, Vector2 } from '@motion-canvas/core/lib/types';
-
-export default makeScene2D(function* (view) {
-  const codeRef = createRef<CodeBlock>();
-  const cutRef = createRef<Rect>();
-
-  yield view.add(
-    <Node>
-      <CodeBlock
-        ref={codeRef}
-        language="cpp"
-        fontSize={48}
-      /><Rect
-        ref={cutRef}
-        x={0}
-        y={0}
-        fill={'white'}
-        width={1000}
-        height={1000}
-        opacity={0}
-      />
-    </Node>);
-
-  const duration = 1.5
-
-  const store = (...args: [TemplateStringsArray, ...any]) => args;
-
-  function to_string([strings, ...values]: [TemplateStringsArray, ...any]): string {
-    return strings.reduce((acc, str, i) => {
-      const value = values[i] ?? '';
-      return acc + str + value;
-    }, ' ');
-  }
-
-  function append(
-    template_1: TemplateStringsArray, args_1: string[],
-    template_2: TemplateStringsArray, args_2: string[]): [TemplateStringsArray, ...string[]] {
-    let new_template = Array.from<string>(template_1);
-    let new_args: Array<string> = args_1;
-    new_template[template_1.length - 1] += template_2[0]
-    new_template = new_template.concat(template_2.slice(1))
-    new_args = new_args.concat(args_2)
-    return [new_template as unknown as TemplateStringsArray, ...new_args];
-  }
-
-  const isCodeModification = (code: any): code is CodeModification => (code as CodeModification).from !== undefined;
-
-  function simplify(
-    args_in: [TemplateStringsArray, ...any]): [TemplateStringsArray, ...string[]] {
-    const template = args_in[0]
-    const args = args_in.slice(1)
-    if (args.every((arg) => (typeof (arg) == "string") || isCodeModification(arg))) {
-      return args_in
-    }
-    let new_template: Array<any> = [];
-    let new_args: Array<any> = [];
-    let concatenate = false;
-    for (let i = 0; i <= args.length; i++) {
-      if (concatenate) {
-        concatenate = false;
-        new_template[new_template.length - 1] += template[i];
-      } else {
-        new_template.push(template[i]);
-      }
-      if (i == args.length) { break; }
-      if (typeof (args[i]) == "string" || isCodeModification(args[i])) {
-        new_args.push(args[i])
-        continue;
-      }
-      let simplified_arg = simplify(args[i]);
-      let simplified_template = simplified_arg[0]
-      let simplified_args = simplified_arg.slice(1)
-      const appended = append(
-        new_template as unknown as TemplateStringsArray,
-        new_args,
-        simplified_template,
-        simplified_args as string[]);
-      new_template = Array.from<string>(appended[0])
-      new_args = appended.slice(1)
-      concatenate = true;
-    }
-    return [new_template as unknown as TemplateStringsArray, ...new_args]
-  }
-
-  const getter_code = `\n    std::byte const *ptr() const { return ptr_; }\n`
-
-  const simple_main = (other_object: any = ``, const_word: any = `const `) => store`
-
-  int main() {
-    ${const_word}HugeObject object{42};
-    std::cout << "object data address: "
-              << object.ptr()
-              << std::endl;${other_object}
-    return 0;
-  }`
-
-  const copy_constructor_main_code = (create: any = ``) => store`
-    ${create}
-    std::cout << "other_object data address: "
-              << other_object.ptr()
-              << std::endl;`
-
-  const copy_constructor = `const HugeObject other_object{object};`
-  const move_constructor = `const HugeObject other_object{std::move(object)};
-    std::cout << "object data address: "
-              << object.ptr()
-              << std::endl;`
-  const copy_assignment = `HugeObject other_object{23};
-    other_object = object;`
-
-  const copy_constructor_code = (
-    copying: any = `AllocateMemory(length_)`,
-    std_copy: any = `\nstd::copy(object.ptr_, object.ptr_ + length_, ptr_);\n`) => store`
-    HugeObject(const HugeObject &object)
-        : length_{object.length_}, ptr_{${copying}} {${std_copy}}
-  `
-
-  const code = (
-    main: any = ``,
-    copy_constructor: any = ``,
-    copy_assign: any = ``,
-    move_constructor: any = ``,
-    getter: any = getter_code,
-    class_or_struct: any = `class`,
-    public_keyword: any = `\n  public:`,
-    private_keyword: any = `\n\n  private:`,
-  ) => store`
-  #include <cstddef>
-  #include <iostream>
-
-  // Note that this ${class_or_struct} does not follow best style.
-  ${class_or_struct} HugeObject {${public_keyword}
-    HugeObject() = default;
-
-    explicit HugeObject(std::size_t data_length)
-        : length_{data_length}, ptr_{AllocateMemory(length_)} {}
-    ${copy_constructor}${move_constructor}${copy_assign}${getter}
-    ~HugeObject() { FreeMemory(ptr_); }
-  ${private_keyword}
-    std::size_t length_{};
-    std::byte *ptr_{};
-  };${main}
-  `
-
-  const zoom_fn = (in_zoom: number) => new Vector2(in_zoom, in_zoom);
-
-  // Initial struct -> class
-  yield* cutRef().opacity(1, 0).to(1, 0.5).to(0, 0);
-  yield* codeRef().edit(duration, false)(...simplify(code(
-    ``, ``, ``, ``, ``, `struct`, ``, ``)));
-  yield* codeRef().edit(duration, false)(...simplify(code(
-    ``, ``, ``, ``, ``,
-    edit(`struct`, `class`),
-    insert(`\n  public:`),
-    insert(`\n\n  private:`))));
-  yield* waitFor(duration);
-  yield* codeRef().selection([...lines(8, 9)], duration);
-  yield* codeRef().selection([...word(9, 37, 61 - 38)], duration);
-  yield* waitFor(duration);
-  yield* codeRef().selection([...lines(11)], duration);
-  yield* codeRef().selection([...word(11, 20, 16)], duration);
-  yield* codeRef().edit(duration, true)(...simplify(code(
-    ``, ``, ``, ``,
-    insert(getter_code))));
-
-  // Add getter
-  yield* cutRef().opacity(1, 0).to(1, 0.5).to(0, 0);
-  yield* waitFor(duration);
-  yield* all(
-    codeRef().position([0, -200], duration),
-    codeRef().scale(zoom_fn(2.0), duration),
-    codeRef().selection([...word(11, 20, 4), ...word(11, 42, 4)], duration)
-  );
-  yield* waitFor(duration);
-  yield* all(
-    codeRef().position([1100, -200], duration),
-    codeRef().selection([...word(11, 0, 21)], duration)
-  );
-  yield* waitFor(duration);
-
-  // Add main function
-  yield* cutRef().opacity(1, 0).to(1, 0.5).to(0, 0);
-  yield* all(
-    codeRef().position([0, 0], 0),
-    codeRef().scale(zoom_fn(0.8), 0),
-    codeRef().selection(DEFAULT, 0),
-    waitFor(duration)
-  );
-  yield* all(
-    codeRef().scale(zoom_fn(1.3), duration),
-    codeRef().position([400, -700], duration),
-    codeRef().edit(duration, true)(...simplify(code(
-      insert(to_string(simple_main())), ``, ``, ``)))
-  );
-  yield* waitFor(duration);
-  yield* all(
-    codeRef().position([0, 200], duration),
-    codeRef().scale(zoom_fn(2.0), duration),
-    codeRef().selection([...word(11, 27, 5)], duration)
-  );
-  yield* waitFor(duration);
-
-  // Destructor
-  yield* cutRef().opacity(1, 0).to(1, 0.5).to(0, 0);
-  yield* all(
-    codeRef().position([0, 0], 0),
-    codeRef().scale(zoom_fn(0.8), 0),
-    codeRef().selection(DEFAULT, 0),
-    waitFor(duration)
-  );
-  yield* waitFor(duration);
-  yield* all(
-    codeRef().position([400, 0], duration),
-    codeRef().scale(zoom_fn(1.5), duration),
-    codeRef().selection([...lines(13)], duration)
-  );
-  yield* waitFor(duration);
-
-  // Comment
-  yield* cutRef().opacity(1, 0).to(1, 0.5).to(0, 0);
-  yield* all(
-    codeRef().position([0, 0], 0),
-    codeRef().scale(zoom_fn(0.6), 0),
-    codeRef().selection(DEFAULT, 0),
-    waitFor(duration)
-  );
-  yield* waitFor(duration);
-  yield* all(
-    codeRef().position([200, 800], duration),
-    codeRef().scale(zoom_fn(1.2), duration),
-    codeRef().selection([...lines(3)], duration)
-  );
-  yield* waitFor(duration);
-
-  // Copy constructor
-  yield* cutRef().opacity(1, 0).to(1, 0.5).to(0, 0);
-  yield* all(
-    codeRef().scale(zoom_fn(1.3), 0),
-    codeRef().position([400, -700], 0),
-    codeRef().selection(lines(20, Infinity), 0),
-  );
-  yield* waitFor(duration);
-  yield* all(
-    codeRef().scale(zoom_fn(1.3), duration),
-    codeRef().position([400, -700], duration),
-    codeRef().edit(duration, false)(...simplify(code(
-      simple_main(insert(to_string(copy_constructor_main_code(copy_constructor)))), ``, ``, ``))),
-    codeRef().selection([...lines(25)], duration)
-  );
-  yield* waitFor(duration);
-
-  // Highlight constructors
-  yield* cutRef().opacity(1, 0).to(1, 0.5).to(0, 0);
-  yield* all(
-    codeRef().scale(zoom_fn(0.5), 0),
-    codeRef().position([0, 0], 0),
-    codeRef().selection(DEFAULT, 0),
-  );
-  yield* all(
-    codeRef().scale(zoom_fn(1.3), duration),
-    codeRef().position([200, 800], duration),
-    codeRef().selection([...lines(6)], duration).to([...lines(8)], duration / 2)
-  );
-  yield* waitFor(duration);
-
-  // Add wrong copy constructor
-  yield* cutRef().opacity(1, 0).to(1, 0.5).to(0, 0);
-  yield* all(
-    codeRef().scale(zoom_fn(0.5), 0),
-    codeRef().position([0, 0], 0),
-    codeRef().selection(DEFAULT, 0),
-  );
-  yield* waitFor(duration);
-  yield* all(
-    codeRef().scale(zoom_fn(1.2), duration / 2),
-    codeRef().position([100, 400], duration / 2),
-    codeRef().edit(duration, true)(...simplify(code(
-      simple_main(copy_constructor_main_code(copy_constructor)),
-      insert(to_string(copy_constructor_code(`object.ptr_`, ``))), ``, ``))),
-  );
-  yield* codeRef().selection(word(11, 15, 24), duration);
-  yield* codeRef().selection(word(12, 5, 47), duration);
-  yield* codeRef().selection(
-    [...word(12, 24, 8), ...word(12, 46, 5)], duration);
-  yield* waitFor(duration);
-
-  const allocate_memory_code = `AllocateMemory(length_)`;
-  const copy_memory_code = `
-      std::copy(object.ptr_, object.ptr_ + length_, ptr_);\n    `;
-
-  // Add correct copy constructor
-  yield* cutRef().opacity(1, 0).to(1, 0.5).to(0, 0);
-  yield* codeRef().selection(lines(11, 12), 0);
-  yield* waitFor(duration);
-  yield* all(
-    codeRef().position([0, 400], duration),
-    codeRef().scale(zoom_fn(1.0), duration),
-    codeRef().edit(duration, true)(...simplify(code(
-      simple_main(copy_constructor_main_code(copy_constructor)),
-      copy_constructor_code(
-        edit(`object.ptr_`, allocate_memory_code),
-        edit(``, copy_memory_code)),
-      ``, ``))),
-  );
-  yield* waitFor(duration);
-
-  // Add copy to main
-  yield* cutRef().opacity(1, 0).to(1, 0.5).to(0, 0);
-  yield* all(
-    codeRef().scale(zoom_fn(0.5), 0),
-    codeRef().position([0, 0], 0),
-    codeRef().selection(DEFAULT, 0),
-  );
-  yield* waitFor(duration);
-  yield* all(
-    codeRef().scale(zoom_fn(1.3), duration),
-    codeRef().position([400, -900], duration),
-    codeRef().selection(lines(30), duration),
-  );
-  yield* waitFor(duration);
-  yield* all(
-    codeRef().edit(duration, true)(...simplify(code(
-      simple_main(copy_constructor_main_code(edit(copy_constructor, copy_assignment))),
-      copy_constructor_code(allocate_memory_code, copy_memory_code),
-      ``, ``))),
-  );
-  yield* waitFor(duration);
-
-
-  // Add copy assignment operator
-  yield* cutRef().opacity(1, 0).to(1, 0.5).to(0, 0);
-  const copy_assignment_code = `
-    HugeObject &operator=(const HugeObject &object) {
-      if (this == &object) { return *this; }
-      FreeMemory(ptr_);
-      length_ = object.length_;
-      ptr_ = AllocateMemory(length_);
-      std::copy(object.ptr_, object.ptr_ + length_, ptr_);
-      return *this;
-    }
-  `
-  yield* all(
-    codeRef().scale(zoom_fn(0.5), 0),
-    codeRef().position([0, 0], 0),
-    codeRef().selection(DEFAULT, 0),
-  );
-  yield* waitFor(duration);
-  yield* all(
-    codeRef().scale(zoom_fn(1.15), duration),
-    codeRef().position([100, 200], duration),
-    codeRef().edit(duration, true)(...simplify(code(
-      simple_main(copy_constructor_main_code(copy_assignment)),
-      copy_constructor_code(allocate_memory_code, copy_memory_code),
-      insert(copy_assignment_code), ``))),
-  );
-  yield* waitFor(duration);
-  yield* codeRef().selection(word(16, 0, 16), duration);
-  yield* codeRef().selection(lines(17), duration);
-  yield* codeRef().selection(lines(18), duration);
-  yield* codeRef().selection(lines(19, 21), duration);
-  yield* waitFor(duration);
-
-  // Add std::move
-  yield* cutRef().opacity(1, 0).to(1, 0.5).to(0, 0);
-  yield* all(
-    codeRef().scale(zoom_fn(1.15), 0),
-    codeRef().position([200, -1000], 0),
-    codeRef().selection(lines(34, Infinity), 0),
-    codeRef().edit(0, false)(...simplify(code(
-      simple_main(copy_constructor_main_code(copy_constructor)),
-      copy_constructor_code(allocate_memory_code, copy_memory_code),
-      copy_assignment_code, ``))),
-  );
-  yield* waitFor(duration);
-  yield* all(
-    codeRef().edit(duration, true)(...simplify(code(
-      simple_main(
-        copy_constructor_main_code(edit(copy_constructor, move_constructor)),
-        remove(`const `)),
-      copy_constructor_code(allocate_memory_code, copy_memory_code),
-      copy_assignment_code, ``))),
-  );
-  yield* waitFor(duration);
-
-
-  // Add move constructor
-  yield* cutRef().opacity(1, 0).to(1, 0.5).to(0, 0);
-  const move_constructor_code = `
-
-    HugeObject(HugeObject &&object)
-        : length_{object.length_}, ptr_{object.ptr_} {
-      object.ptr_ = nullptr;
-    }
-  `
-  yield* all(
-    codeRef().scale(zoom_fn(0.3), 0),
-    codeRef().position([0, 0], 0),
-    codeRef().selection(DEFAULT, 0),
-  );
-  yield* waitFor(duration);
-  yield* all(
-    codeRef().scale(zoom_fn(1.15), duration),
-    codeRef().position([200, 600], duration),
-    codeRef().edit(duration, true)(...simplify(code(
-      simple_main(
-        copy_constructor_main_code(edit(copy_constructor, move_constructor)),
-        remove(`const `)),
-      copy_constructor_code(allocate_memory_code, copy_memory_code),
-      copy_assignment_code,
-      insert(move_constructor_code)))),
-  );
-  yield* waitFor(duration);
-  yield* codeRef().selection(word(16, 15, 19), duration);
-  yield* codeRef().selection(word(17, 35, 16), duration);
-  yield* codeRef().selection(lines(18), duration);
-  yield* waitFor(duration);
-
-
-  // Remove comment
-  yield* cutRef().opacity(1, 0).to(1, 0.5).to(0, 0);
-  const comment_text = `// Note that this class does not follow best style.`;
-  const new_code = (comment: any) => store`
-  ${comment}
-  class HugeObject {
-   public:
-    HugeObject() = default;
-
-    explicit HugeObject(std::size_t data_length)
-        : length_{data_length}, ptr_{AllocateMemory(length_)} {}
-
-    HugeObject(const HugeObject &object)
-        : length_{object.length_}, ptr_{AllocateMemory(length_)} {
-      std::copy(object.ptr_, object.ptr_ + length_, ptr_);
-    }
-
-    HugeObject(HugeObject &&object)
-        : length_{object.length_}, ptr_{object.ptr_} {
-      object.ptr_ = nullptr;
-    }
-  }
-  `
-  yield* all(
-    codeRef().scale(zoom_fn(1.0), 0),
-    codeRef().position([0, 100], 0),
-    codeRef().selection(lines(0), 0),
-    codeRef().edit(0, false)(...simplify(new_code(comment_text))),
-  );
-  yield* all(
-    codeRef().scale(zoom_fn(1.2), 5 * duration),
-    codeRef().position([200, 300], 5 * duration),
-    codeRef().selection(lines(0), duration),
-  );
-  yield* all(
-    codeRef().edit(duration, false)(...simplify(new_code(remove(comment_text)))),
-  );
-  yield* waitFor(duration);
-});
diff --git a/animation/all_or_nothing/src/scenes/memory.meta b/animation/all_or_nothing/src/scenes/memory.meta
deleted file mode 100644
index bdef019..0000000
--- a/animation/all_or_nothing/src/scenes/memory.meta
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-  "version": 0,
-  "timeEvents": [],
-  "seed": 3499084582
-}
\ No newline at end of file
diff --git a/animation/all_or_nothing/src/scenes/memory.tsx b/animation/all_or_nothing/src/scenes/memory.tsx
deleted file mode 100644
index 2b0e9e4..0000000
--- a/animation/all_or_nothing/src/scenes/memory.tsx
+++ /dev/null
@@ -1,188 +0,0 @@
-import { makeScene2D } from '@motion-canvas/2d/lib/scenes';
-import { Node, Circle, Rect, Grid, Line } from '@motion-canvas/2d/lib/components';
-import { all, waitFor } from '@motion-canvas/core/lib/flow';
-import { Vector2 } from '@motion-canvas/core/lib/types';
-import { createRef } from '@motion-canvas/core/lib/utils';
-import { createSignal } from '@motion-canvas/core/lib/signals';
-import { CodeBlock } from '@motion-canvas/2d/lib/components/CodeBlock';
-import {Video} from '@motion-canvas/2d/lib/components';
-import travolta from '../../videos/travolta.mp4';
-
-const RED = '#ff6470';
-const GREEN = '#99C47A';
-const BLUE = '#68ABDF';
-
-export default makeScene2D(function* (view) {
-  const data_ref = createRef<CodeBlock>();
-  const other_data_ref = createRef<CodeBlock>();
-  const object_ref = createRef<CodeBlock>();
-  const other_object_ref = createRef<CodeBlock>();
-  const line_1 = createRef<Line>();
-  const line_2 = createRef<Line>();
-  const node_ref = createRef<Node>();
-  const travolta_ref = createRef<Video>();
-
-  const data = `
-  1011011010110
-  1011000100100
-  0010011100000
-  1101000010001
-  0010100111111`
-
-  const error = `
-  binary(78797,0x1e21a6500) malloc: Double free of object 0x155e06ac0
-  binary(78797,0x1e21a6500) malloc: *** set a breakpoint in malloc_error_break to debug`
-
-  const object_code = `object`
-  const member_object_code = `other_object`
-
-  view.add(
-    <Node>
-      <CodeBlock
-        ref={data_ref}
-        fontSize={60}
-        x={0}
-        y={200}
-        code={data}
-        opacity={0.0}
-      />
-      <CodeBlock
-        ref={other_data_ref}
-        fontSize={60}
-        x={400}
-        y={200}
-        code={data}
-        opacity={0.0}
-      />
-      <Node x={0} y={-300} ref={node_ref}>
-        <CodeBlock
-          ref={object_ref}
-          fontSize={60}
-          code={object_code}
-          opacity={0.0}
-        />
-        <Line
-          ref={line_1}
-          stroke={RED}
-          lineWidth={10}
-          endArrow
-          arrowSize={20}
-          opacity={0.0}
-          points={[[0, 50], [0, 300]]}
-        />
-        <Video
-          ref={travolta_ref}
-          opacity={0.0}
-          src={travolta}
-          scale={0.3}
-          position={[200, 300]}
-        />
-        <CodeBlock
-          ref={other_object_ref}
-          fontSize={60}
-          opacity={0.0}
-          code={member_object_code}
-        />
-        <Line
-          ref={line_2}
-          stroke={RED}
-          lineWidth={10}
-          endArrow
-          arrowSize={20}
-          opacity={0.0}
-          points={[[0, 50], [0, 300]]}
-        />
-      </Node>
-    </Node>,
-  );
-
-  // Destructor
-  yield* all(
-    object_ref().opacity(1.0, 1.0),
-    line_1().opacity(1.0, 1.5),
-    data_ref().opacity(1.0, 2.0),
-  );
-  yield* waitFor(2.0);
-  yield* all(
-    object_ref().opacity(0.0, 2.0),
-    line_1().opacity(0.0, 1.5),
-    data_ref().opacity(0.0, 1.0),
-  );
-  yield* waitFor(2.0);
-  yield* all(
-    object_ref().opacity(1.0, 1.0),
-    line_1().opacity(1.0, 1.5),
-    data_ref().opacity(1.0, 2.0),
-  );
-  yield* waitFor(2.0);
-  yield* all(
-    object_ref().opacity(0.0, 1.5),
-    line_1().opacity(0.0, 1.0),
-  );
-  yield* data_ref().scale(1.2, 0.7).to(1.0, 0.7);
-
-  yield* waitFor(2.0);
-  yield* data_ref().opacity(0.0, 0.1);
-  yield* all(
-    object_ref().opacity(1.0, 0.1),
-    line_1().opacity(1.0, 0.1),
-    data_ref().opacity(1.0, 0.1),
-  );
-  yield* waitFor(2.0);
-  yield* all(
-    object_ref().position([-400, 0], 1.0),
-    other_object_ref().position([-400, 0], 1.0),
-    line_1().points([[-400, 50], [-100, 300]], 1.0),
-    line_2().points([[-400, 50], [-100, 300]], 1.0),
-  );
-  yield* all(
-    object_ref().position([-400, 0], 1.0),
-    other_object_ref().opacity(1.0, 1.0),
-    other_object_ref().position([400, 0], 1.0),
-    line_1().points([[-400, 50], [-100, 300]], 1.0),
-    line_2().points([[400, 50], [100, 300]], 1.0),
-    line_2().opacity(1.0, 1.0),
-  );
-  yield* waitFor(2.0);
-  yield* all(
-    data_ref().opacity(0.0, 0.7),
-    other_object_ref().opacity(0.0, 1.5),
-    line_2().opacity(0.0, 1.0),
-  );
-  travolta_ref().play();
-  yield* all(
-    node_ref().scale(1.5, 1.0),
-    travolta_ref().opacity(1.0, 1.0),
-  );
-  yield* waitFor(3.5);
-
-  // Copy assignment fail
-  travolta_ref().pause();
-  yield* all(
-    travolta_ref().opacity(0, 0),
-    object_ref().opacity(0, 0),
-    line_1().opacity(0, 0),
-    data_ref().opacity(0, 0),
-    node_ref().scale(1.0, 0),
-    data_ref().position([-400, 200], 0),
-    line_1().points([[-400, 50], [-400, 300]], 0),
-    line_2().points([[400, 50], [400, 300]], 0),
-  );
-  yield* all(
-    object_ref().opacity(1.0, 1.0),
-    line_1().opacity(1.0, 1.5),
-    data_ref().opacity(1.0, 2.0),
-  );
-  yield* all(
-    other_object_ref().opacity(1.0, 1.0),
-    line_2().opacity(1.0, 1.5),
-    other_data_ref().opacity(1.0, 2.0),
-  );
-  yield* waitFor(2.0);
-  yield* all(
-    line_2().points([[400, 50], [-120, 300]], 1.0),
-  );
-  yield* waitFor(2.0);
-  yield* other_data_ref().scale(1.2, 0.7).to(1.0, 0.7);
-  yield* waitFor(2.0);
-});
diff --git a/animation/all_or_nothing/src/scenes/stealing.meta b/animation/all_or_nothing/src/scenes/stealing.meta
deleted file mode 100644
index 1547019..0000000
--- a/animation/all_or_nothing/src/scenes/stealing.meta
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-  "version": 0,
-  "timeEvents": [],
-  "seed": 1249695661
-}
\ No newline at end of file
diff --git a/animation/all_or_nothing/src/scenes/stealing.tsx b/animation/all_or_nothing/src/scenes/stealing.tsx
deleted file mode 100644
index eb43caa..0000000
--- a/animation/all_or_nothing/src/scenes/stealing.tsx
+++ /dev/null
@@ -1,140 +0,0 @@
-import {makeScene2D} from '@motion-canvas/2d/lib/scenes';
-import {Node, Txt, Rect, Grid, Line} from '@motion-canvas/2d/lib/components';
-import {all, waitFor} from '@motion-canvas/core/lib/flow';
-import {Vector2} from '@motion-canvas/core/lib/types';
-import {createRef} from '@motion-canvas/core/lib/utils';
-import {createSignal} from '@motion-canvas/core/lib/signals';
-import {CodeBlock, edit, insert} from '@motion-canvas/2d/lib/components/CodeBlock';
-
-const RED = '#ff6470';
-const GREEN = '#99C47A';
-const BLUE = '#68ABDF';
-const WHITE = '#FFFFFF';
-
-export default makeScene2D(function* (view) {
-  const gray_line_ref = createRef<Line>();
-  const gray_code_ref = createRef<CodeBlock>();
-  const grid_ref = createRef<Grid>();
-  const data_rect_ref = createRef<Rect>();
-  const a_ref = createRef<CodeBlock>();
-  const b_ref = createRef<CodeBlock>();
-  const line_1 = createRef<Line>();
-  const line_2 = createRef<Line>();
-
-  const data = `
-  10010011`
-
-  const object_code = `Data* a;`
-  const member_object_code = `Data* b;`
-
-  view.add(
-    <Node>
-      <Grid
-        ref = {grid_ref}
-        y = {200}
-        spacing={100}
-        stroke={'#444'}
-        lineWidth={5}
-        opacity={0}
-        cache
-      />
-      <Rect
-        x = {0}
-        y = {250}
-        ref = {data_rect_ref}
-        fill = {BLUE}
-        lineWidth={4}
-        width = {800}
-        height = {100}
-        opacity = {0.0}
-      />
-      <CodeBlock
-          ref={gray_code_ref}
-          fontSize={40}
-          code = {"0x42424242"}
-          x = {-350}
-          y = {430}
-          opacity = {0.0}
-      />
-      <Line
-          ref={gray_line_ref}
-          stroke={'#777'}
-          lineWidth={5}
-          endArrow
-          arrowSize={15}
-          points={[[-350, 400], [-350, 310]]}
-          opacity = {0.0}
-      />
-
-      <Node x = {-400} y = {-300}>
-        <CodeBlock
-          ref = {a_ref}
-          fontSize={80}
-        />
-        <Line
-          ref = {line_1}
-          lineWidth={10}
-          stroke={BLUE}
-          arrowSize={20}
-          endArrow
-          points={[
-            [30, 50],
-            [30, 490],
-          ]}
-          end={0}
-        />,
-      </Node>
-      <Node x = {500} y = {-300}>
-        <CodeBlock
-          ref = {b_ref}
-          fontSize={80}
-        />
-        <Line
-          ref = {line_2}
-          lineWidth={10}
-          stroke={BLUE}
-          endArrow
-          arrowSize={20}
-          points={[
-            [0, 50],
-            [0, 200],
-            [-830, 200],
-            [-830, 490],
-          ]}
-          end={0}
-        />,
-      </Node>
-    </Node>,
-  );
-
-  yield * waitFor(2.0);
-  yield * a_ref().edit(1.0, false)`${insert(object_code)}`;
-  yield * all(
-    grid_ref().height(0, 0.0).to(250, 0.5),
-    grid_ref().width(0, 0.0).to(1920, 0.5),
-    grid_ref().opacity(1.0, 0.1),
-  );
-  yield * all(
-    data_rect_ref().opacity(0.5, 1.0),
-    line_1().end(1, 1.0),
-    gray_line_ref().opacity(1.0, 0.5),
-    gray_code_ref().opacity(1.0, 0.5),
-  );
-  yield * b_ref().edit(1.0, false)`${insert(member_object_code)}`;
-  yield * waitFor(1.0);
-  yield * data_rect_ref().scale(1.2, 1.0);
-  yield * data_rect_ref().position.x(-20, 0.2).to(20, 0.2).to(-20, 0.2).to(20, 0.2).to(0, 0.2);
-  yield * data_rect_ref().scale(1.0, 0.5);
-  yield * waitFor(1.0);
-  yield * line_2().end(1, 1.5);
-  yield * waitFor(1.0);
-  yield * all(
-    data_rect_ref().opacity(0.5, 1.0),
-    line_1().arrowSize(0, 0.5),
-    line_1().end(0, 1.0),
-    a_ref().edit(1.5, false)`Data* a${insert(' = nullptr')};`,
-  );
-
-  yield * waitFor(3.0);
-
-});
diff --git a/animation/all_or_nothing/tsconfig.json b/animation/all_or_nothing/tsconfig.json
deleted file mode 100644
index 789b7d1..0000000
--- a/animation/all_or_nothing/tsconfig.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-  "extends": "@motion-canvas/2d/tsconfig.project.json",
-  "compilerOptions": {
-    "baseUrl": "src"
-  },
-  "include": ["src"]
-}
diff --git a/animation/all_or_nothing/videos/travolta.mp4 b/animation/all_or_nothing/videos/travolta.mp4
deleted file mode 100644
index 9d6b4ee..0000000
--- a/animation/all_or_nothing/videos/travolta.mp4
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:5b300b8896b6062071238fde2ea43584797b3bbc93280e331b219a86380b11f1
-size 1181848
diff --git a/animation/all_or_nothing/vite.config.ts b/animation/all_or_nothing/vite.config.ts
deleted file mode 100644
index bf32088..0000000
--- a/animation/all_or_nothing/vite.config.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-import {defineConfig} from 'vite';
-import motionCanvas from '@motion-canvas/vite-plugin';
-
-export default defineConfig({
-  plugins: [motionCanvas()],
-});
diff --git a/animation/class_headers/.gitignore b/animation/class_headers/.gitignore
deleted file mode 100644
index 829b1c7..0000000
--- a/animation/class_headers/.gitignore
+++ /dev/null
@@ -1,15 +0,0 @@
-# Generated files
-node_modules
-output
-dist
-
-# Editor directories and files
-.vscode/*
-!.vscode/extensions.json
-.idea
-.DS_Store
-*.suo
-*.ntvs*
-*.njsproj
-*.sln
-*.sw?
diff --git a/animation/class_headers/package-lock.json b/animation/class_headers/package-lock.json
deleted file mode 100644
index 9ebec27..0000000
--- a/animation/class_headers/package-lock.json
+++ /dev/null
@@ -1,802 +0,0 @@
-{
-  "name": "value_semantics",
-  "version": "0.0.0",
-  "lockfileVersion": 3,
-  "requires": true,
-  "packages": {
-    "": {
-      "name": "value_semantics",
-      "version": "0.0.0",
-      "dependencies": {
-        "@motion-canvas/2d": "^3.4.0",
-        "@motion-canvas/core": "^3.4.0"
-      },
-      "devDependencies": {
-        "@motion-canvas/ui": "^3.4.0",
-        "@motion-canvas/vite-plugin": "^3.4.0",
-        "typescript": "^4.9.5",
-        "vite": "^4.1.4"
-      }
-    },
-    "node_modules/@esbuild/android-arm": {
-      "version": "0.17.15",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.15.tgz",
-      "integrity": "sha512-sRSOVlLawAktpMvDyJIkdLI/c/kdRTOqo8t6ImVxg8yT7LQDUYV5Rp2FKeEosLr6ZCja9UjYAzyRSxGteSJPYg==",
-      "cpu": [
-        "arm"
-      ],
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/android-arm64": {
-      "version": "0.17.15",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.15.tgz",
-      "integrity": "sha512-0kOB6Y7Br3KDVgHeg8PRcvfLkq+AccreK///B4Z6fNZGr/tNHX0z2VywCc7PTeWp+bPvjA5WMvNXltHw5QjAIA==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/android-x64": {
-      "version": "0.17.15",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.15.tgz",
-      "integrity": "sha512-MzDqnNajQZ63YkaUWVl9uuhcWyEyh69HGpMIrf+acR4otMkfLJ4sUCxqwbCyPGicE9dVlrysI3lMcDBjGiBBcQ==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/darwin-arm64": {
-      "version": "0.17.15",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.15.tgz",
-      "integrity": "sha512-7siLjBc88Z4+6qkMDxPT2juf2e8SJxmsbNVKFY2ifWCDT72v5YJz9arlvBw5oB4W/e61H1+HDB/jnu8nNg0rLA==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/darwin-x64": {
-      "version": "0.17.15",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.15.tgz",
-      "integrity": "sha512-NbImBas2rXwYI52BOKTW342Tm3LTeVlaOQ4QPZ7XuWNKiO226DisFk/RyPk3T0CKZkKMuU69yOvlapJEmax7cg==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/freebsd-arm64": {
-      "version": "0.17.15",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.15.tgz",
-      "integrity": "sha512-Xk9xMDjBVG6CfgoqlVczHAdJnCs0/oeFOspFap5NkYAmRCT2qTn1vJWA2f419iMtsHSLm+O8B6SLV/HlY5cYKg==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "freebsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/freebsd-x64": {
-      "version": "0.17.15",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.15.tgz",
-      "integrity": "sha512-3TWAnnEOdclvb2pnfsTWtdwthPfOz7qAfcwDLcfZyGJwm1SRZIMOeB5FODVhnM93mFSPsHB9b/PmxNNbSnd0RQ==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "freebsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-arm": {
-      "version": "0.17.15",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.15.tgz",
-      "integrity": "sha512-MLTgiXWEMAMr8nmS9Gigx43zPRmEfeBfGCwxFQEMgJ5MC53QKajaclW6XDPjwJvhbebv+RzK05TQjvH3/aM4Xw==",
-      "cpu": [
-        "arm"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-arm64": {
-      "version": "0.17.15",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.15.tgz",
-      "integrity": "sha512-T0MVnYw9KT6b83/SqyznTs/3Jg2ODWrZfNccg11XjDehIved2oQfrX/wVuev9N936BpMRaTR9I1J0tdGgUgpJA==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-ia32": {
-      "version": "0.17.15",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.15.tgz",
-      "integrity": "sha512-wp02sHs015T23zsQtU4Cj57WiteiuASHlD7rXjKUyAGYzlOKDAjqK6bk5dMi2QEl/KVOcsjwL36kD+WW7vJt8Q==",
-      "cpu": [
-        "ia32"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-loong64": {
-      "version": "0.17.15",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.15.tgz",
-      "integrity": "sha512-k7FsUJjGGSxwnBmMh8d7IbObWu+sF/qbwc+xKZkBe/lTAF16RqxRCnNHA7QTd3oS2AfGBAnHlXL67shV5bBThQ==",
-      "cpu": [
-        "loong64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-mips64el": {
-      "version": "0.17.15",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.15.tgz",
-      "integrity": "sha512-ZLWk6czDdog+Q9kE/Jfbilu24vEe/iW/Sj2d8EVsmiixQ1rM2RKH2n36qfxK4e8tVcaXkvuV3mU5zTZviE+NVQ==",
-      "cpu": [
-        "mips64el"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-ppc64": {
-      "version": "0.17.15",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.15.tgz",
-      "integrity": "sha512-mY6dPkIRAiFHRsGfOYZC8Q9rmr8vOBZBme0/j15zFUKM99d4ILY4WpOC7i/LqoY+RE7KaMaSfvY8CqjJtuO4xg==",
-      "cpu": [
-        "ppc64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-riscv64": {
-      "version": "0.17.15",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.15.tgz",
-      "integrity": "sha512-EcyUtxffdDtWjjwIH8sKzpDRLcVtqANooMNASO59y+xmqqRYBBM7xVLQhqF7nksIbm2yHABptoioS9RAbVMWVA==",
-      "cpu": [
-        "riscv64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-s390x": {
-      "version": "0.17.15",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.15.tgz",
-      "integrity": "sha512-BuS6Jx/ezxFuHxgsfvz7T4g4YlVrmCmg7UAwboeyNNg0OzNzKsIZXpr3Sb/ZREDXWgt48RO4UQRDBxJN3B9Rbg==",
-      "cpu": [
-        "s390x"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-x64": {
-      "version": "0.17.15",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.15.tgz",
-      "integrity": "sha512-JsdS0EgEViwuKsw5tiJQo9UdQdUJYuB+Mf6HxtJSPN35vez1hlrNb1KajvKWF5Sa35j17+rW1ECEO9iNrIXbNg==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/netbsd-x64": {
-      "version": "0.17.15",
-      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.15.tgz",
-      "integrity": "sha512-R6fKjtUysYGym6uXf6qyNephVUQAGtf3n2RCsOST/neIwPqRWcnc3ogcielOd6pT+J0RDR1RGcy0ZY7d3uHVLA==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "netbsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/openbsd-x64": {
-      "version": "0.17.15",
-      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.15.tgz",
-      "integrity": "sha512-mVD4PGc26b8PI60QaPUltYKeSX0wxuy0AltC+WCTFwvKCq2+OgLP4+fFd+hZXzO2xW1HPKcytZBdjqL6FQFa7w==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "openbsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/sunos-x64": {
-      "version": "0.17.15",
-      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.15.tgz",
-      "integrity": "sha512-U6tYPovOkw3459t2CBwGcFYfFRjivcJJc1WC8Q3funIwX8x4fP+R6xL/QuTPNGOblbq/EUDxj9GU+dWKX0oWlQ==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "sunos"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/win32-arm64": {
-      "version": "0.17.15",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.15.tgz",
-      "integrity": "sha512-W+Z5F++wgKAleDABemiyXVnzXgvRFs+GVKThSI+mGgleLWluv0D7Diz4oQpgdpNzh4i2nNDzQtWbjJiqutRp6Q==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/win32-ia32": {
-      "version": "0.17.15",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.15.tgz",
-      "integrity": "sha512-Muz/+uGgheShKGqSVS1KsHtCyEzcdOn/W/Xbh6H91Etm+wiIfwZaBn1W58MeGtfI8WA961YMHFYTthBdQs4t+w==",
-      "cpu": [
-        "ia32"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/win32-x64": {
-      "version": "0.17.15",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.15.tgz",
-      "integrity": "sha512-DjDa9ywLUUmjhV2Y9wUTIF+1XsmuFGvZoCmOWkli1XcNAh5t25cc7fgsCx4Zi/Uurep3TTLyDiKATgGEg61pkA==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@motion-canvas/2d": {
-      "version": "3.4.0",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/2d/-/2d-3.4.0.tgz",
-      "integrity": "sha512-3CmB2v6eQiSo7763goTKdAreTC4qIM9Qx/N31/Ov7CVWVZ31nUFGR5pRkfyrnoHHI718cfuZNArITPlB86U+LA==",
-      "dependencies": {
-        "@motion-canvas/core": "^3.4.0",
-        "code-fns": "^0.8.2",
-        "mathjax-full": "^3.2.2"
-      }
-    },
-    "node_modules/@motion-canvas/core": {
-      "version": "3.4.0",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/core/-/core-3.4.0.tgz",
-      "integrity": "sha512-qGLjnhBshnXJqTgtnx/eSJTYmXWo5PtemV4TCczkbDQhvvjNxWwVHIQDNTG4bCg7R1gzKPizFzW63L9q+bIUaw==",
-      "dependencies": {
-        "@types/chroma-js": "^2.1.4",
-        "chroma-js": "^2.4.2"
-      },
-      "peerDependencies": {
-        "vite": "^4.1.4"
-      }
-    },
-    "node_modules/@motion-canvas/ui": {
-      "version": "3.4.0",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/ui/-/ui-3.4.0.tgz",
-      "integrity": "sha512-ntgBqqlZdAiTwpySyjf9UFBYDwXgr61UQDtyAJiQzqy0HqDeO0TZKSIqSgAgkY8GCwR2ELP+ITyEW6H0Mq6ZKw==",
-      "dev": true,
-      "dependencies": {
-        "@motion-canvas/core": "^3.4.0"
-      }
-    },
-    "node_modules/@motion-canvas/vite-plugin": {
-      "version": "3.4.0",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/vite-plugin/-/vite-plugin-3.4.0.tgz",
-      "integrity": "sha512-tzSCw1RruDBJsF3WV6nXkMMUd5P4KMmSQ+j477qqxTIrklE+Pm4Y9Mdn3M2v3q6fr/o2b4nLa5l7QC/iZ2n9PQ==",
-      "dev": true,
-      "dependencies": {
-        "follow-redirects": "^1.15.2",
-        "mime-types": "^2.1.35"
-      },
-      "peerDependencies": {
-        "vite": "4.x"
-      }
-    },
-    "node_modules/@types/chroma-js": {
-      "version": "2.4.0",
-      "resolved": "https://registry.npmjs.org/@types/chroma-js/-/chroma-js-2.4.0.tgz",
-      "integrity": "sha512-JklMxityrwjBTjGY2anH8JaTx3yjRU3/sEHSblLH1ba5lqcSh1LnImXJZO5peJfXyqKYWjHTGy4s5Wz++hARrw=="
-    },
-    "node_modules/@types/hast": {
-      "version": "2.3.4",
-      "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.4.tgz",
-      "integrity": "sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==",
-      "dependencies": {
-        "@types/unist": "*"
-      }
-    },
-    "node_modules/@types/unist": {
-      "version": "2.0.6",
-      "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz",
-      "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ=="
-    },
-    "node_modules/@wooorm/starry-night": {
-      "version": "1.7.0",
-      "resolved": "https://registry.npmjs.org/@wooorm/starry-night/-/starry-night-1.7.0.tgz",
-      "integrity": "sha512-ktO0nkddrovIoNW2jAUT+Cdd9n1bWjy1Ir4CdcmgTaT6E94HLlQfu7Yv62falclBEwvsuVp3bSBw23wtta1fNw==",
-      "dependencies": {
-        "@types/hast": "^2.0.0",
-        "import-meta-resolve": "^2.0.0",
-        "vscode-oniguruma": "^1.0.0",
-        "vscode-textmate": "^9.0.0"
-      },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/wooorm"
-      }
-    },
-    "node_modules/chroma-js": {
-      "version": "2.4.2",
-      "resolved": "https://registry.npmjs.org/chroma-js/-/chroma-js-2.4.2.tgz",
-      "integrity": "sha512-U9eDw6+wt7V8z5NncY2jJfZa+hUH8XEj8FQHgFJTrUFnJfXYf4Ml4adI2vXZOjqRDpFWtYVWypDfZwnJ+HIR4A=="
-    },
-    "node_modules/code-fns": {
-      "version": "0.8.2",
-      "resolved": "https://registry.npmjs.org/code-fns/-/code-fns-0.8.2.tgz",
-      "integrity": "sha512-3VVeq3cnWxWiWKFLsVo+XWsOXBSW2gAx2uv0ViETLNmNuygEPHlCeDAv/Zy7xXqPgXtgLZyvIJZmx+ojTgOIGA==",
-      "dependencies": {
-        "@wooorm/starry-night": "^1.2.0"
-      }
-    },
-    "node_modules/commander": {
-      "version": "9.2.0",
-      "resolved": "https://registry.npmjs.org/commander/-/commander-9.2.0.tgz",
-      "integrity": "sha512-e2i4wANQiSXgnrBlIatyHtP1odfUp0BbV5Y5nEGbxtIrStkEOAAzCUirvLBNXHLr7kwLvJl6V+4V3XV9x7Wd9w==",
-      "engines": {
-        "node": "^12.20.0 || >=14"
-      }
-    },
-    "node_modules/esbuild": {
-      "version": "0.17.15",
-      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.15.tgz",
-      "integrity": "sha512-LBUV2VsUIc/iD9ME75qhT4aJj0r75abCVS0jakhFzOtR7TQsqQA5w0tZ+KTKnwl3kXE0MhskNdHDh/I5aCR1Zw==",
-      "hasInstallScript": true,
-      "bin": {
-        "esbuild": "bin/esbuild"
-      },
-      "engines": {
-        "node": ">=12"
-      },
-      "optionalDependencies": {
-        "@esbuild/android-arm": "0.17.15",
-        "@esbuild/android-arm64": "0.17.15",
-        "@esbuild/android-x64": "0.17.15",
-        "@esbuild/darwin-arm64": "0.17.15",
-        "@esbuild/darwin-x64": "0.17.15",
-        "@esbuild/freebsd-arm64": "0.17.15",
-        "@esbuild/freebsd-x64": "0.17.15",
-        "@esbuild/linux-arm": "0.17.15",
-        "@esbuild/linux-arm64": "0.17.15",
-        "@esbuild/linux-ia32": "0.17.15",
-        "@esbuild/linux-loong64": "0.17.15",
-        "@esbuild/linux-mips64el": "0.17.15",
-        "@esbuild/linux-ppc64": "0.17.15",
-        "@esbuild/linux-riscv64": "0.17.15",
-        "@esbuild/linux-s390x": "0.17.15",
-        "@esbuild/linux-x64": "0.17.15",
-        "@esbuild/netbsd-x64": "0.17.15",
-        "@esbuild/openbsd-x64": "0.17.15",
-        "@esbuild/sunos-x64": "0.17.15",
-        "@esbuild/win32-arm64": "0.17.15",
-        "@esbuild/win32-ia32": "0.17.15",
-        "@esbuild/win32-x64": "0.17.15"
-      }
-    },
-    "node_modules/esm": {
-      "version": "3.2.25",
-      "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz",
-      "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==",
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/follow-redirects": {
-      "version": "1.15.2",
-      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
-      "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "individual",
-          "url": "https://github.com/sponsors/RubenVerborgh"
-        }
-      ],
-      "engines": {
-        "node": ">=4.0"
-      },
-      "peerDependenciesMeta": {
-        "debug": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/fsevents": {
-      "version": "2.3.2",
-      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
-      "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
-      }
-    },
-    "node_modules/function-bind": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
-      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
-    },
-    "node_modules/has": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
-      "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
-      "dependencies": {
-        "function-bind": "^1.1.1"
-      },
-      "engines": {
-        "node": ">= 0.4.0"
-      }
-    },
-    "node_modules/import-meta-resolve": {
-      "version": "2.2.2",
-      "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-2.2.2.tgz",
-      "integrity": "sha512-f8KcQ1D80V7RnqVm+/lirO9zkOxjGxhaTC1IPrBGd3MEfNgmNG67tSUO9gTi2F3Blr2Az6g1vocaxzkVnWl9MA==",
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/wooorm"
-      }
-    },
-    "node_modules/is-core-module": {
-      "version": "2.11.0",
-      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz",
-      "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==",
-      "dependencies": {
-        "has": "^1.0.3"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/mathjax-full": {
-      "version": "3.2.2",
-      "resolved": "https://registry.npmjs.org/mathjax-full/-/mathjax-full-3.2.2.tgz",
-      "integrity": "sha512-+LfG9Fik+OuI8SLwsiR02IVdjcnRCy5MufYLi0C3TdMT56L/pjB0alMVGgoWJF8pN9Rc7FESycZB9BMNWIid5w==",
-      "dependencies": {
-        "esm": "^3.2.25",
-        "mhchemparser": "^4.1.0",
-        "mj-context-menu": "^0.6.1",
-        "speech-rule-engine": "^4.0.6"
-      }
-    },
-    "node_modules/mhchemparser": {
-      "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/mhchemparser/-/mhchemparser-4.1.1.tgz",
-      "integrity": "sha512-R75CUN6O6e1t8bgailrF1qPq+HhVeFTM3XQ0uzI+mXTybmphy3b6h4NbLOYhemViQ3lUs+6CKRkC3Ws1TlYREA=="
-    },
-    "node_modules/mime-db": {
-      "version": "1.52.0",
-      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
-      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/mime-types": {
-      "version": "2.1.35",
-      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
-      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
-      "dev": true,
-      "dependencies": {
-        "mime-db": "1.52.0"
-      },
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/mj-context-menu": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/mj-context-menu/-/mj-context-menu-0.6.1.tgz",
-      "integrity": "sha512-7NO5s6n10TIV96d4g2uDpG7ZDpIhMh0QNfGdJw/W47JswFcosz457wqz/b5sAKvl12sxINGFCn80NZHKwxQEXA=="
-    },
-    "node_modules/nanoid": {
-      "version": "3.3.6",
-      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
-      "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/ai"
-        }
-      ],
-      "bin": {
-        "nanoid": "bin/nanoid.cjs"
-      },
-      "engines": {
-        "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
-      }
-    },
-    "node_modules/path-parse": {
-      "version": "1.0.7",
-      "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
-      "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
-    },
-    "node_modules/picocolors": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
-      "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
-    },
-    "node_modules/postcss": {
-      "version": "8.4.21",
-      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz",
-      "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==",
-      "funding": [
-        {
-          "type": "opencollective",
-          "url": "https://opencollective.com/postcss/"
-        },
-        {
-          "type": "tidelift",
-          "url": "https://tidelift.com/funding/github/npm/postcss"
-        }
-      ],
-      "dependencies": {
-        "nanoid": "^3.3.4",
-        "picocolors": "^1.0.0",
-        "source-map-js": "^1.0.2"
-      },
-      "engines": {
-        "node": "^10 || ^12 || >=14"
-      }
-    },
-    "node_modules/resolve": {
-      "version": "1.22.1",
-      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
-      "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
-      "dependencies": {
-        "is-core-module": "^2.9.0",
-        "path-parse": "^1.0.7",
-        "supports-preserve-symlinks-flag": "^1.0.0"
-      },
-      "bin": {
-        "resolve": "bin/resolve"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/rollup": {
-      "version": "3.20.2",
-      "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.20.2.tgz",
-      "integrity": "sha512-3zwkBQl7Ai7MFYQE0y1MeQ15+9jsi7XxfrqwTb/9EK8D9C9+//EBR4M+CuA1KODRaNbFez/lWxA5vhEGZp4MUg==",
-      "bin": {
-        "rollup": "dist/bin/rollup"
-      },
-      "engines": {
-        "node": ">=14.18.0",
-        "npm": ">=8.0.0"
-      },
-      "optionalDependencies": {
-        "fsevents": "~2.3.2"
-      }
-    },
-    "node_modules/source-map-js": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
-      "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/speech-rule-engine": {
-      "version": "4.0.7",
-      "resolved": "https://registry.npmjs.org/speech-rule-engine/-/speech-rule-engine-4.0.7.tgz",
-      "integrity": "sha512-sJrL3/wHzNwJRLBdf6CjJWIlxC04iYKkyXvYSVsWVOiC2DSkHmxsqOhEeMsBA9XK+CHuNcsdkbFDnoUfAsmp9g==",
-      "dependencies": {
-        "commander": "9.2.0",
-        "wicked-good-xpath": "1.3.0",
-        "xmldom-sre": "0.1.31"
-      },
-      "bin": {
-        "sre": "bin/sre"
-      }
-    },
-    "node_modules/supports-preserve-symlinks-flag": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
-      "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/typescript": {
-      "version": "4.9.5",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
-      "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
-      "dev": true,
-      "bin": {
-        "tsc": "bin/tsc",
-        "tsserver": "bin/tsserver"
-      },
-      "engines": {
-        "node": ">=4.2.0"
-      }
-    },
-    "node_modules/vite": {
-      "version": "4.2.1",
-      "resolved": "https://registry.npmjs.org/vite/-/vite-4.2.1.tgz",
-      "integrity": "sha512-7MKhqdy0ISo4wnvwtqZkjke6XN4taqQ2TBaTccLIpOKv7Vp2h4Y+NpmWCnGDeSvvn45KxvWgGyb0MkHvY1vgbg==",
-      "dependencies": {
-        "esbuild": "^0.17.5",
-        "postcss": "^8.4.21",
-        "resolve": "^1.22.1",
-        "rollup": "^3.18.0"
-      },
-      "bin": {
-        "vite": "bin/vite.js"
-      },
-      "engines": {
-        "node": "^14.18.0 || >=16.0.0"
-      },
-      "optionalDependencies": {
-        "fsevents": "~2.3.2"
-      },
-      "peerDependencies": {
-        "@types/node": ">= 14",
-        "less": "*",
-        "sass": "*",
-        "stylus": "*",
-        "sugarss": "*",
-        "terser": "^5.4.0"
-      },
-      "peerDependenciesMeta": {
-        "@types/node": {
-          "optional": true
-        },
-        "less": {
-          "optional": true
-        },
-        "sass": {
-          "optional": true
-        },
-        "stylus": {
-          "optional": true
-        },
-        "sugarss": {
-          "optional": true
-        },
-        "terser": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/vscode-oniguruma": {
-      "version": "1.7.0",
-      "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz",
-      "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA=="
-    },
-    "node_modules/vscode-textmate": {
-      "version": "9.0.0",
-      "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-9.0.0.tgz",
-      "integrity": "sha512-Cl65diFGxz7gpwbav10HqiY/eVYTO1sjQpmRmV991Bj7wAoOAjGQ97PpQcXorDE2Uc4hnGWLY17xme+5t6MlSg=="
-    },
-    "node_modules/wicked-good-xpath": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/wicked-good-xpath/-/wicked-good-xpath-1.3.0.tgz",
-      "integrity": "sha512-Gd9+TUn5nXdwj/hFsPVx5cuHHiF5Bwuc30jZ4+ronF1qHK5O7HD0sgmXWSEgwKquT3ClLoKPVbO6qGwVwLzvAw=="
-    },
-    "node_modules/xmldom-sre": {
-      "version": "0.1.31",
-      "resolved": "https://registry.npmjs.org/xmldom-sre/-/xmldom-sre-0.1.31.tgz",
-      "integrity": "sha512-f9s+fUkX04BxQf+7mMWAp5zk61pciie+fFLC9hX9UVvCeJQfNHRHXpeo5MPcR0EUf57PYLdt+ZO4f3Ipk2oZUw==",
-      "engines": {
-        "node": ">=0.1"
-      }
-    }
-  }
-}
diff --git a/animation/class_headers/package.json b/animation/class_headers/package.json
deleted file mode 100644
index 4c4a6cf..0000000
--- a/animation/class_headers/package.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "name": "value_semantics",
-  "private": true,
-  "version": "0.0.0",
-  "scripts": {
-    "serve": "vite",
-    "build": "tsc && vite build"
-  },
-  "dependencies": {
-    "@motion-canvas/core": "^3.4.0",
-    "@motion-canvas/2d": "^3.4.0"
-  },
-  "devDependencies": {
-    "@motion-canvas/ui": "^3.4.0",
-    "@motion-canvas/vite-plugin": "^3.4.0",
-    "typescript": "^4.9.5",
-    "vite": "^4.1.4"
-  }
-}
\ No newline at end of file
diff --git a/animation/class_headers/src/motion-canvas.d.ts b/animation/class_headers/src/motion-canvas.d.ts
deleted file mode 100644
index 067c6a4..0000000
--- a/animation/class_headers/src/motion-canvas.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-/// <reference types="@motion-canvas/core/project" />
diff --git a/animation/class_headers/src/project.meta b/animation/class_headers/src/project.meta
deleted file mode 100644
index 87f7ea3..0000000
--- a/animation/class_headers/src/project.meta
+++ /dev/null
@@ -1,32 +0,0 @@
-{
-  "version": 0,
-  "shared": {
-    "background": "rgb(10,20,30)",
-    "range": [
-      0,
-      72.66437828883343
-    ],
-    "size": {
-      "x": 1920,
-      "y": 1080
-    },
-    "audioOffset": 0
-  },
-  "preview": {
-    "fps": 30,
-    "resolutionScale": 1
-  },
-  "rendering": {
-    "fps": 30,
-    "resolutionScale": 2,
-    "colorSpace": "srgb",
-    "exporter": {
-      "name": "image sequence",
-      "options": {
-        "fileType": "image/png",
-        "quality": 100,
-        "groupByScene": true
-      }
-    }
-  }
-}
\ No newline at end of file
diff --git a/animation/class_headers/src/project.ts b/animation/class_headers/src/project.ts
deleted file mode 100644
index ecfbbeb..0000000
--- a/animation/class_headers/src/project.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import {makeProject} from '@motion-canvas/core';
-
-import example from './scenes/example?scene';
-
-export default makeProject({
-  scenes: [example],
-});
diff --git a/animation/class_headers/src/scenes/example.meta b/animation/class_headers/src/scenes/example.meta
deleted file mode 100644
index 2d62bec..0000000
--- a/animation/class_headers/src/scenes/example.meta
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-  "version": 0,
-  "timeEvents": [],
-  "seed": 1501821170
-}
\ No newline at end of file
diff --git a/animation/class_headers/src/scenes/example.tsx b/animation/class_headers/src/scenes/example.tsx
deleted file mode 100644
index e2a2003..0000000
--- a/animation/class_headers/src/scenes/example.tsx
+++ /dev/null
@@ -1,655 +0,0 @@
-import { makeScene2D } from '@motion-canvas/2d/lib/scenes';
-import { Circle, Rect, Layout, Txt } from '@motion-canvas/2d/lib/components';
-import { createRef } from '@motion-canvas/core/lib/utils';
-import { waitFor, all, chain } from '@motion-canvas/core/lib/flow';
-import { DEFAULT, createSignal } from '@motion-canvas/core/lib/signals';
-import {
-  CodeBlock,
-  edit,
-  insert,
-  lines,
-  word,
-  remove,
-  CodeModification,
-} from '@motion-canvas/2d/lib/components/CodeBlock';
-
-export default makeScene2D(function* (view) {
-  const main_ref = createRef<Layout>();
-  const filename_left_ref = createRef<CodeBlock>();
-  const code_block_left_ref = createRef<CodeBlock>();
-  const filename_right_ref = createRef<CodeBlock>();
-  const code_block_right_ref = createRef<CodeBlock>();
-
-  const grow_factor = createSignal(0.0);
-
-  function CreateCodeBlock(reference: any, grow_int: number, color: any = "#242424") {
-    return <Rect
-      grow={grow_int}
-      radius={4}
-      fill={color}
-      clip={true}
-      marginLeft={10}
-      marginRight={10}
-      marginBottom={10}
-      marginTop={10}
-    >
-      <CodeBlock
-        layout={false}
-        language="cpp"
-        fontSize={48}
-        ref={reference} />
-    </Rect>;
-  }
-
-  function CreateColumn(filename: any, code: any, grow_factor: any) {
-    return <Rect layout
-      direction="column"
-      grow={grow_factor}
-      lineWidth={40}
-      clip={true}
-    >
-      {filename}
-      {code}
-    </Rect>
-  }
-
-  const code_block_left = CreateCodeBlock(code_block_left_ref, 10);
-  const filename_left = CreateCodeBlock(filename_left_ref, 1);
-  const code_block_right = CreateCodeBlock(code_block_right_ref, 10);
-  const filename_right = CreateCodeBlock(filename_right_ref, 1);
-
-  const column_left = CreateColumn(filename_left, code_block_left, () => 1.0 - grow_factor());
-  const column_right = CreateColumn(filename_right, code_block_right, () => grow_factor());
-
-  view.add(
-    <Layout layout width={1920} height={1080} ref={main_ref}>
-      {column_left}
-      {column_right}
-    </Layout>
-  );
-
-  const duration = 1.5
-
-  const store = (...args: [TemplateStringsArray, ...any]) => args;
-
-  function to_string([strings, ...values]: [TemplateStringsArray, ...any]): string {
-    return strings.reduce((acc, str, i) => {
-      const value = values[i] ?? '';
-      return acc + str + value;
-    }, '');
-  }
-
-  function append(
-    template_1: TemplateStringsArray, args_1: string[],
-    template_2: TemplateStringsArray, args_2: string[]): [TemplateStringsArray, ...string[]] {
-    let new_template = Array.from<string>(template_1);
-    let new_args: Array<string> = args_1;
-    new_template[template_1.length - 1] += template_2[0]
-    new_template = new_template.concat(template_2.slice(1))
-    new_args = new_args.concat(args_2)
-    return [new_template as unknown as TemplateStringsArray, ...new_args];
-  }
-
-  const isCodeModification = (code: any): code is CodeModification => (code as CodeModification).from !== undefined;
-
-  function simplify(
-    args_in: [TemplateStringsArray, ...any]): [TemplateStringsArray, ...string[]] {
-    const template = args_in[0]
-    const args = args_in.slice(1)
-    if (args.every((arg) => (typeof (arg) == "string") || isCodeModification(arg))) {
-      return args_in
-    }
-    let new_template: Array<any> = [];
-    let new_args: Array<any> = [];
-    let concatenate = false;
-    for (let i = 0; i <= args.length; i++) {
-      if (concatenate) {
-        concatenate = false;
-        new_template[new_template.length - 1] += template[i];
-      } else {
-        new_template.push(template[i]);
-      }
-      if (i == args.length) { break; }
-      if (typeof (args[i]) == "string" || isCodeModification(args[i])) {
-        new_args.push(args[i])
-        continue;
-      }
-      let simplified_arg = simplify(args[i]);
-      let simplified_template = simplified_arg[0]
-      let simplified_args = simplified_arg.slice(1)
-      const appended = append(
-        new_template as unknown as TemplateStringsArray,
-        new_args,
-        simplified_template,
-        simplified_args as string[]);
-      new_template = Array.from<string>(appended[0])
-      new_args = appended.slice(1)
-      concatenate = true;
-    }
-    return [new_template as unknown as TemplateStringsArray, ...new_args]
-  }
-
-  const answer_struct = `  struct Answer {
-    float probability{};
-    std::string text{};
-  };\n\n`
-
-
-  const data_struct_is_valid_impl = ` {
-      return questions.size() == correct_answers.size();
-    }
-  `
-  const data_struct = (
-    { impl = `;` }: {
-      impl?: any
-    },
-  ) => store`  struct Data {
-    bool IsValid() const${impl}
-    std::vector<std::string> questions{};
-    std::vector<std::string> correct_answers{};
-  };\n\n`
-
-  const train_method_impl = ` {
-    if (!data.IsValid()) { return; }
-    IngestData(data);
-  }`
-
-  const train_method = (
-    { impl = `;` }: {
-      impl?: any
-    },
-  ) => store`\n  void Train(const Data &data)${impl}\n`
-
-  const get_answer_impl = ` {
-    if (smartness_ < 1) { return Answer{0.1, "I don't know"}; }
-    if (smartness_ < 5) { return Answer{0.8, "Yes."}; }
-    if (question.length() > 10) {
-      return Answer{1.0, "You will regret this question..."};
-    }
-    return Answer{1.0, "Can't you ask anything more important?"};
-  }`
-
-  const get_answer_method_code = (
-    { impl = `;` }: {
-      impl?: any
-    },
-  ) => store`  Answer GetAnswer(const std::string &question) const${impl}\n`
-
-  const ingest_data_impl = `\n  void IngestData(const Data &data) {
-    // Definitely not the smartest way...
-    smartness_ += data.correct_answers.size();
-  }\n`
-
-  const private_part = (
-    { ingest_data = `` }: {
-      ingest_data?: any
-    },
-  ) => store`\n private:${ingest_data}\n  int smartness_{};\n`
-
-  const main = `
-int main() {
-  Chatbot chatbot{};
-  chatbot.Train({{
-      "How much is 2 + 2?",
-      "What color is the sky?",
-      "What is the answer to life and everything?"},
-    {"4", "It depends", "42"}});
-  const auto question = "Are you self aware?";
-  std::cout << "Asking chatbot: "
-            << question << std::endl;
-  std::cout << "Chatbot answered: "
-            << chatbot.GetAnswer(question).text
-            << std::endl;
-  return 0;
-}`
-
-  const includes = (
-    { pragma_once = ``,
-      string = ``,
-      vector = ``,
-      iostream = `` }: {
-        pragma_once?: any,
-        string?: any,
-        vector?: any,
-        iostream?: any
-      },
-  ) => store`${pragma_once}${iostream}${string}${vector}
-  `
-
-  const code = (
-    { includes = ``,
-      public_keyword = ``,
-      answer_struct = ``,
-      data_struct = ``,
-      train_method = ``,
-      get_answer_method = ``,
-      private_part = ``,
-      main = `` }: {
-        includes?: any,
-        public_keyword?: any,
-        answer_struct?: any,
-        data_struct?: any,
-        train_method?: any,
-        get_answer_method?: any,
-        private_part?: any,
-        main?: any,
-      },
-  ) => store`${includes}\nclass Chatbot {${public_keyword}${answer_struct}${data_struct}${get_answer_method}${train_method}${private_part}};\n${main}
-  `
-
-  const code_separate_main = (
-    { includes = ``,
-      main = `` }: {
-        includes?: any,
-        main?: any,
-      },
-  ) => store`${includes}${main}`
-
-  const code_cpp_file = (
-    { includes = ``,
-      data_method = ``,
-      train_method = ``,
-      get_answer_method = ``,
-      ingest_data_method = ``,
-    }: {
-      includes?: any,
-      data_method?: any,
-      train_method?: any,
-      get_answer_method?: any,
-      ingest_data_method?: any
-    },
-  ) => store`${includes}
-  ${data_method}
-  ${get_answer_method}
-  ${train_method}
-  ${ingest_data_method}
-  `
-
-  const includes_cpp = `#include <chatbot/chatbot.hpp>`
-  const data_method_cpp = `
-bool Chatbot::Data::IsValid() const {
-  return questions.size() == correct_answers.size();
-}`
-  const train_method_cpp = `
-void Chatbot::Train(const Data &data) {
-  if (!data.IsValid()) { return; }
-  IngestData(data);
-}`
-  const get_answer_method_cpp = `
-Chatbot::Answer
-Chatbot::GetAnswer(const std::string &question) const {
-  if (smartness_ < 1) { return Answer{0.1, "I don't know"}; }
-  if (smartness_ < 5) { return Answer{0.8, "Yes."}; }
-  if (question.length() > 10) {
-    return Answer{1.0, "You will regret this question..."};
-  }
-  return Answer{1.0, "Can't you ask anything more important?"};
-}`
-  const ingest_data_method_cpp = `
-void Chatbot::IngestData(const Data &data) {
-  smartness_ += data.correct_answers.size();
-}`
-
-
-  yield* filename_left_ref().edit(0, false)`chatbot.cpp`;
-  yield* filename_right_ref().edit(0, false)`chatbot.hpp`;
-  yield* code_block_left_ref().edit(0, false)(...simplify(code({})));
-  yield* code_block_right_ref().edit(0, false)(...simplify(code({ main: insert(main) })));
-
-
-  yield* all(
-    code_block_left_ref().edit(duration, false)(...simplify(code({
-      includes: insert(to_string(includes({ string: "#include <string>" }))),
-      public_keyword: insert("\n public:\n"),
-      get_answer_method: insert(to_string(get_answer_method_code({}))),
-    }))),
-    code_block_left_ref().selection([...lines(4)], duration),
-    waitFor(duration * 2)
-  );
-
-  yield* all(
-    code_block_left_ref().edit(duration, true)(...simplify(code({
-      includes: includes({ string: "#include <string>" }),
-      public_keyword: "\n public:\n",
-      get_answer_method: get_answer_method_code({}),
-      train_method: insert(to_string(train_method({}))),
-    }))),
-    waitFor(duration * 2)
-  );
-
-  yield* all(
-    code_block_left_ref().edit(duration, true)(...simplify(code({
-      includes: includes({ string: "#include <string>" }),
-      public_keyword: "\n public:\n",
-      get_answer_method: get_answer_method_code({}),
-      train_method: train_method({}),
-      answer_struct: insert(answer_struct),
-    }))),
-    waitFor(duration * 2)
-  );
-
-  yield* all(
-    code_block_left_ref().edit(duration, true)(...simplify(code({
-      includes: includes({
-        string: "#include <string>",
-        vector: insert("\n#include <vector>")
-      }),
-      public_keyword: "\n public:\n",
-      get_answer_method: get_answer_method_code({}),
-      train_method: train_method({}),
-      answer_struct: answer_struct,
-      data_struct: insert(to_string(data_struct({}))),
-    }))),
-    code_block_left_ref().position([0, 150], duration),
-    waitFor(duration * 2)
-  );
-
-  yield* all(
-    code_block_left_ref().edit(duration, false)(...simplify(code({
-      includes: includes({
-        string: "#include <string>",
-        vector: "\n#include <vector>"
-      }),
-      public_keyword: "\n public:\n",
-      get_answer_method: get_answer_method_code({}),
-      train_method: train_method({ impl: insert(train_method_impl) }),
-      answer_struct: answer_struct,
-      data_struct: data_struct({}),
-      private_part: insert(to_string(private_part({ ingest_data: ingest_data_impl }))),
-    }))),
-    code_block_left_ref().position([0, -450], duration),
-    code_block_left_ref().selection([...lines(18, Infinity)], duration),
-    waitFor(duration * 2)
-  );
-
-  yield* all(
-    code_block_left_ref().edit(duration, false)(...simplify(code({
-      includes: includes({
-        string: "#include <string>",
-        vector: "\n#include <vector>"
-      }),
-      public_keyword: "\n public:\n",
-      get_answer_method: get_answer_method_code({ impl: edit(';', get_answer_impl) }),
-      train_method: train_method({ impl: train_method_impl }),
-      answer_struct: answer_struct,
-      data_struct: data_struct({ impl: edit(';', data_struct_is_valid_impl) }),
-      private_part: private_part({ ingest_data: ingest_data_impl }),
-    }))),
-    code_block_left_ref().position([0, 0], 0),
-    code_block_left_ref().scale(0.35, 0),
-    code_block_left_ref().selection(DEFAULT, 0),
-    waitFor(duration * 2)
-  );
-
-  yield* all(
-    code_block_left_ref().scale(0.9, duration),
-    code_block_left_ref().position([0, 800], duration),
-    waitFor(duration * 2)
-  );
-  yield* all(
-    code_block_left_ref().position([0, -800], 2 * duration),
-  );
-
-  yield* all(
-    code_block_left_ref().edit(duration, true)(...simplify(code({
-      includes: includes({
-        string: "#include <string>",
-        vector: "\n#include <vector>",
-        iostream: insert("\n#include <iostream>")
-      }),
-      public_keyword: "\n public:\n",
-      get_answer_method: get_answer_method_code({ impl: get_answer_impl }),
-      train_method: train_method({ impl: train_method_impl }),
-      answer_struct: answer_struct,
-      data_struct: data_struct({ impl: data_struct_is_valid_impl }),
-      private_part: private_part({ ingest_data: ingest_data_impl }),
-      main: insert(main),
-    }))),
-    code_block_left_ref().position([0, -1100], duration),
-    code_block_left_ref().selection(DEFAULT, 0),
-    waitFor(duration * 2)
-  );
-
-  yield* all(
-    code_block_left_ref().edit(duration, false)(...simplify(code({
-      includes: includes({
-        string: "\n#include <string>",
-        vector: "\n#include <vector>",
-        iostream: "#include <iostream>"
-      }),
-      public_keyword: "\n public:\n",
-      get_answer_method: get_answer_method_code({ impl: get_answer_impl }),
-      train_method: train_method({ impl: train_method_impl }),
-      answer_struct: answer_struct,
-      data_struct: data_struct({ impl: data_struct_is_valid_impl }),
-      private_part: private_part({ ingest_data: ingest_data_impl }),
-      main: main,
-    }))),
-    code_block_left_ref().scale(0.25, 0),
-    code_block_left_ref().position([0, 0], 0),
-    code_block_left_ref().selection(DEFAULT, 0),
-    waitFor(duration * 2)
-  );
-
-  yield* all(
-    filename_left_ref().edit(duration, true)`chatbot.${edit(`cpp`, `hpp`)}`,
-    waitFor(duration * 2)
-  );
-
-  yield* all(
-    filename_left_ref().selection(DEFAULT, duration),
-    code_block_left_ref().scale(0.9, duration),
-    code_block_left_ref().position([0, 1300], duration),
-    code_block_left_ref().edit(duration, true)(...simplify(code({
-      includes: includes({
-        pragma_once: insert("#pragma once\n"),
-        string: "\n#include <string>",
-        vector: "\n#include <vector>",
-        iostream: "\n#include <iostream>"
-      }),
-      public_keyword: "\n public:\n",
-      get_answer_method: get_answer_method_code({ impl: get_answer_impl }),
-      train_method: train_method({ impl: train_method_impl }),
-      answer_struct: answer_struct,
-      data_struct: data_struct({ impl: data_struct_is_valid_impl }),
-      private_part: private_part({ ingest_data: ingest_data_impl }),
-      main: main,
-    }))),
-    waitFor(duration * 2)
-  );
-
-  yield* all(
-    code_block_left_ref().selection(DEFAULT, duration),
-    code_block_left_ref().position([0, -1150], duration),
-    waitFor(duration * 2)
-  );
-
-  yield* all(
-    grow_factor(0.5, duration),
-    filename_right_ref().edit(0, false)`main.cpp`,
-    code_block_left_ref().position([5, -160], duration),
-    code_block_left_ref().scale(0.49, duration),
-    code_block_left_ref().edit(duration, false)(...simplify(code({
-      includes: includes({
-        pragma_once: "#pragma once\n",
-        string: "\n#include <string>",
-        vector: "\n#include <vector>",
-        iostream: remove("\n#include <iostream>")
-      }),
-      public_keyword: "\n public:\n",
-      get_answer_method: get_answer_method_code({ impl: get_answer_impl }),
-      train_method: train_method({ impl: train_method_impl }),
-      answer_struct: answer_struct,
-      data_struct: data_struct({ impl: data_struct_is_valid_impl }),
-      private_part: private_part({ ingest_data: ingest_data_impl }),
-      main: remove(main),
-    }))),
-    code_block_right_ref().scale(0.6, duration),
-    code_block_right_ref().position([0, 0], duration),
-    code_block_right_ref().edit(duration, true)(...simplify(code_separate_main({
-      includes: includes({
-        vector: insert("#include <iostream>"),
-        string: insert("#include <chatbot/chatbot.hpp>\n"),
-      }),
-      main: insert(main),
-    }))),
-    waitFor(duration * 3)
-  );
-
-  // Copying the data into cpp file
-  yield* all(
-    grow_factor(0, 0),
-    code_block_left_ref().scale(0.5, 0),
-    code_block_right_ref().scale(0.5, 0),
-    code_block_left_ref().position([20, 200], 0),
-    filename_right_ref().edit(0, false)`chatbot.cpp`,
-    code_block_right_ref().edit(0, false)``,
-    waitFor(duration * 2)
-  );
-
-  yield* all(
-    grow_factor(0.5, duration),
-    filename_right_ref().edit(0, false)`chatbot.cpp`,
-    code_block_right_ref().edit(duration, true)(...simplify(code_cpp_file({
-      includes: insert(includes_cpp),
-    }))),
-    waitFor(duration * 2)
-  );
-
-  yield* all(
-    code_block_left_ref().position.y(0, duration * 5),
-    chain(
-      all(
-        code_block_left_ref().edit(duration, false)(...simplify(code({
-          includes: includes({
-            pragma_once: "#pragma once\n",
-            string: "\n#include <string>",
-            vector: "\n#include <vector>",
-          }),
-          public_keyword: "\n public:\n",
-          get_answer_method: get_answer_method_code({ impl: get_answer_impl }),
-          train_method: train_method({ impl: train_method_impl }),
-          answer_struct: answer_struct,
-          data_struct: data_struct({ impl: edit(data_struct_is_valid_impl, ';') }),
-          private_part: private_part({ ingest_data: ingest_data_impl }),
-        }))),
-        code_block_right_ref().edit(duration, true)(...simplify(code_cpp_file({
-          includes: includes_cpp,
-          data_method: insert(data_method_cpp),
-        }))),
-      ),
-      all(
-        code_block_left_ref().edit(duration, false)(...simplify(code({
-          includes: includes({
-            pragma_once: "#pragma once\n",
-            string: "\n#include <string>",
-            vector: "\n#include <vector>",
-          }),
-          public_keyword: "\n public:\n",
-          get_answer_method: get_answer_method_code({ impl: edit(get_answer_impl, ';') }),
-          train_method: train_method({ impl: train_method_impl }),
-          answer_struct: answer_struct,
-          data_struct: data_struct({}),
-          private_part: private_part({ ingest_data: ingest_data_impl }),
-        }))),
-        code_block_right_ref().edit(duration, true)(...simplify(code_cpp_file({
-          includes: includes_cpp,
-          data_method: data_method_cpp,
-          get_answer_method: insert(get_answer_method_cpp),
-        }))),
-      ),
-      all(
-        code_block_left_ref().edit(duration, false)(...simplify(code({
-          includes: includes({
-            pragma_once: "#pragma once\n",
-            string: "\n#include <string>",
-            vector: "\n#include <vector>",
-          }),
-          public_keyword: "\n public:\n",
-          get_answer_method: get_answer_method_code({}),
-          train_method: train_method({ impl: edit(train_method_impl, ';') }),
-          answer_struct: answer_struct,
-          data_struct: data_struct({}),
-          private_part: private_part({ ingest_data: ingest_data_impl }),
-        }))),
-        code_block_right_ref().edit(duration, true)(...simplify(code_cpp_file({
-          includes: includes_cpp,
-          data_method: data_method_cpp,
-          get_answer_method: get_answer_method_cpp,
-          train_method: insert(train_method_cpp),
-        }))),
-      ),
-      all(
-        code_block_left_ref().edit(duration, false)(...simplify(code({
-          includes: includes({
-            pragma_once: "#pragma once\n",
-            string: "\n#include <string>",
-            vector: "\n#include <vector>",
-          }),
-          public_keyword: "\n public:\n",
-          get_answer_method: get_answer_method_code({}),
-          train_method: train_method({}),
-          answer_struct: answer_struct,
-          data_struct: data_struct({}),
-          private_part: private_part({ ingest_data: edit(ingest_data_impl, '\n  void IngestData(const Data& data);\n') }),
-        }))),
-        code_block_right_ref().edit(duration, true)(...simplify(code_cpp_file({
-          includes: includes_cpp,
-          data_method: data_method_cpp,
-          get_answer_method: get_answer_method_cpp,
-          train_method: train_method_cpp,
-          ingest_data_method: insert(ingest_data_method_cpp),
-        }))),
-      )
-    )
-  );
-
-  yield* all(
-    grow_factor(1.0, duration),
-    code_block_right_ref().scale(0.6, duration),
-    code_block_right_ref().selection([
-      ...word(2, 5, 15),
-      ...word(7, 0, 9),
-      ...word(16, 5, 9),
-      ...word(21, 5, 9)], duration),
-    waitFor(duration * 2)
-  );
-
-  yield* all(
-    code_block_right_ref().selection([
-      ...word(6, 0, 15)], duration),
-    waitFor(duration * 2)
-  );
-
-  yield* all(
-    code_block_right_ref().selection([
-      ...word(8, 30, 7),
-      ...word(9, 30, 7),
-      ...word(11, 10, 7),
-      ...word(13, 8, 7),
-      ...word(16, 25, 5),
-      ...word(21, 30, 5),
-    ], duration),
-    waitFor(duration * 2)
-  );
-
-  yield* all(
-    grow_factor(0.5, duration),
-    code_block_right_ref().scale(0.5, duration),
-    code_block_right_ref().selection([
-      ...word(7, 48, 6),
-      ...word(2, 30, 6),
-    ], duration),
-    code_block_left_ref().selection([
-      ...word(13, 19, 5),
-      ...word(18, 48, 5),
-    ], duration),
-  );
-  yield* all(
-    code_block_right_ref().scale(0.8, duration * 2),
-    code_block_right_ref().position([-200, 340], duration * 2),
-    code_block_left_ref().scale(0.8, duration * 2),
-    code_block_left_ref().position([-200, -100], duration * 2),
-    waitFor(duration * 3)
-  );
-});
diff --git a/animation/class_headers/src/scenes/stealing.meta b/animation/class_headers/src/scenes/stealing.meta
deleted file mode 100644
index 1547019..0000000
--- a/animation/class_headers/src/scenes/stealing.meta
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-  "version": 0,
-  "timeEvents": [],
-  "seed": 1249695661
-}
\ No newline at end of file
diff --git a/animation/class_headers/src/scenes/stealing.tsx b/animation/class_headers/src/scenes/stealing.tsx
deleted file mode 100644
index eb43caa..0000000
--- a/animation/class_headers/src/scenes/stealing.tsx
+++ /dev/null
@@ -1,140 +0,0 @@
-import {makeScene2D} from '@motion-canvas/2d/lib/scenes';
-import {Node, Txt, Rect, Grid, Line} from '@motion-canvas/2d/lib/components';
-import {all, waitFor} from '@motion-canvas/core/lib/flow';
-import {Vector2} from '@motion-canvas/core/lib/types';
-import {createRef} from '@motion-canvas/core/lib/utils';
-import {createSignal} from '@motion-canvas/core/lib/signals';
-import {CodeBlock, edit, insert} from '@motion-canvas/2d/lib/components/CodeBlock';
-
-const RED = '#ff6470';
-const GREEN = '#99C47A';
-const BLUE = '#68ABDF';
-const WHITE = '#FFFFFF';
-
-export default makeScene2D(function* (view) {
-  const gray_line_ref = createRef<Line>();
-  const gray_code_ref = createRef<CodeBlock>();
-  const grid_ref = createRef<Grid>();
-  const data_rect_ref = createRef<Rect>();
-  const a_ref = createRef<CodeBlock>();
-  const b_ref = createRef<CodeBlock>();
-  const line_1 = createRef<Line>();
-  const line_2 = createRef<Line>();
-
-  const data = `
-  10010011`
-
-  const object_code = `Data* a;`
-  const member_object_code = `Data* b;`
-
-  view.add(
-    <Node>
-      <Grid
-        ref = {grid_ref}
-        y = {200}
-        spacing={100}
-        stroke={'#444'}
-        lineWidth={5}
-        opacity={0}
-        cache
-      />
-      <Rect
-        x = {0}
-        y = {250}
-        ref = {data_rect_ref}
-        fill = {BLUE}
-        lineWidth={4}
-        width = {800}
-        height = {100}
-        opacity = {0.0}
-      />
-      <CodeBlock
-          ref={gray_code_ref}
-          fontSize={40}
-          code = {"0x42424242"}
-          x = {-350}
-          y = {430}
-          opacity = {0.0}
-      />
-      <Line
-          ref={gray_line_ref}
-          stroke={'#777'}
-          lineWidth={5}
-          endArrow
-          arrowSize={15}
-          points={[[-350, 400], [-350, 310]]}
-          opacity = {0.0}
-      />
-
-      <Node x = {-400} y = {-300}>
-        <CodeBlock
-          ref = {a_ref}
-          fontSize={80}
-        />
-        <Line
-          ref = {line_1}
-          lineWidth={10}
-          stroke={BLUE}
-          arrowSize={20}
-          endArrow
-          points={[
-            [30, 50],
-            [30, 490],
-          ]}
-          end={0}
-        />,
-      </Node>
-      <Node x = {500} y = {-300}>
-        <CodeBlock
-          ref = {b_ref}
-          fontSize={80}
-        />
-        <Line
-          ref = {line_2}
-          lineWidth={10}
-          stroke={BLUE}
-          endArrow
-          arrowSize={20}
-          points={[
-            [0, 50],
-            [0, 200],
-            [-830, 200],
-            [-830, 490],
-          ]}
-          end={0}
-        />,
-      </Node>
-    </Node>,
-  );
-
-  yield * waitFor(2.0);
-  yield * a_ref().edit(1.0, false)`${insert(object_code)}`;
-  yield * all(
-    grid_ref().height(0, 0.0).to(250, 0.5),
-    grid_ref().width(0, 0.0).to(1920, 0.5),
-    grid_ref().opacity(1.0, 0.1),
-  );
-  yield * all(
-    data_rect_ref().opacity(0.5, 1.0),
-    line_1().end(1, 1.0),
-    gray_line_ref().opacity(1.0, 0.5),
-    gray_code_ref().opacity(1.0, 0.5),
-  );
-  yield * b_ref().edit(1.0, false)`${insert(member_object_code)}`;
-  yield * waitFor(1.0);
-  yield * data_rect_ref().scale(1.2, 1.0);
-  yield * data_rect_ref().position.x(-20, 0.2).to(20, 0.2).to(-20, 0.2).to(20, 0.2).to(0, 0.2);
-  yield * data_rect_ref().scale(1.0, 0.5);
-  yield * waitFor(1.0);
-  yield * line_2().end(1, 1.5);
-  yield * waitFor(1.0);
-  yield * all(
-    data_rect_ref().opacity(0.5, 1.0),
-    line_1().arrowSize(0, 0.5),
-    line_1().end(0, 1.0),
-    a_ref().edit(1.5, false)`Data* a${insert(' = nullptr')};`,
-  );
-
-  yield * waitFor(3.0);
-
-});
diff --git a/animation/class_headers/tsconfig.json b/animation/class_headers/tsconfig.json
deleted file mode 100644
index 789b7d1..0000000
--- a/animation/class_headers/tsconfig.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-  "extends": "@motion-canvas/2d/tsconfig.project.json",
-  "compilerOptions": {
-    "baseUrl": "src"
-  },
-  "include": ["src"]
-}
diff --git a/animation/class_headers/vite.config.ts b/animation/class_headers/vite.config.ts
deleted file mode 100644
index bf32088..0000000
--- a/animation/class_headers/vite.config.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-import {defineConfig} from 'vite';
-import motionCanvas from '@motion-canvas/vite-plugin';
-
-export default defineConfig({
-  plugins: [motionCanvas()],
-});
diff --git a/animation/class_templates_why/.gitignore b/animation/class_templates_why/.gitignore
deleted file mode 100644
index 829b1c7..0000000
--- a/animation/class_templates_why/.gitignore
+++ /dev/null
@@ -1,15 +0,0 @@
-# Generated files
-node_modules
-output
-dist
-
-# Editor directories and files
-.vscode/*
-!.vscode/extensions.json
-.idea
-.DS_Store
-*.suo
-*.ntvs*
-*.njsproj
-*.sln
-*.sw?
diff --git a/animation/class_templates_why/package-lock.json b/animation/class_templates_why/package-lock.json
deleted file mode 100644
index a21bf05..0000000
--- a/animation/class_templates_why/package-lock.json
+++ /dev/null
@@ -1,1366 +0,0 @@
-{
-  "name": "class_templates_why",
-  "version": "0.0.0",
-  "lockfileVersion": 3,
-  "requires": true,
-  "packages": {
-    "": {
-      "name": "class_templates_why",
-      "version": "0.0.0",
-      "dependencies": {
-        "@lezer/cpp": "^1.1.2",
-        "@motion-canvas/2d": "^3.15.2",
-        "@motion-canvas/core": "^3.15.2",
-        "@motion-canvas/ffmpeg": "^1.1.0"
-      },
-      "devDependencies": {
-        "@motion-canvas/ui": "^3.15.2",
-        "@motion-canvas/vite-plugin": "^3.15.1",
-        "typescript": "^5.2.2",
-        "vite": "^4.0.0"
-      }
-    },
-    "node_modules/@codemirror/language": {
-      "version": "6.10.1",
-      "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.10.1.tgz",
-      "integrity": "sha512-5GrXzrhq6k+gL5fjkAwt90nYDmjlzTIJV8THnxNFtNKWotMIlzzN+CpqxqwXOECnUdOndmSeWntVrVcv5axWRQ==",
-      "dependencies": {
-        "@codemirror/state": "^6.0.0",
-        "@codemirror/view": "^6.23.0",
-        "@lezer/common": "^1.1.0",
-        "@lezer/highlight": "^1.0.0",
-        "@lezer/lr": "^1.0.0",
-        "style-mod": "^4.0.0"
-      }
-    },
-    "node_modules/@codemirror/state": {
-      "version": "6.4.1",
-      "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.4.1.tgz",
-      "integrity": "sha512-QkEyUiLhsJoZkbumGZlswmAhA7CBU02Wrz7zvH4SrcifbsqwlXShVXg65f3v/ts57W3dqyamEriMhij1Z3Zz4A=="
-    },
-    "node_modules/@codemirror/view": {
-      "version": "6.26.3",
-      "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.26.3.tgz",
-      "integrity": "sha512-gmqxkPALZjkgSxIeeweY/wGQXBfwTUaLs8h7OKtSwfbj9Ct3L11lD+u1sS7XHppxFQoMDiMDp07P9f3I2jWOHw==",
-      "dependencies": {
-        "@codemirror/state": "^6.4.0",
-        "style-mod": "^4.1.0",
-        "w3c-keyname": "^2.2.4"
-      }
-    },
-    "node_modules/@esbuild/android-arm": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
-      "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==",
-      "cpu": [
-        "arm"
-      ],
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/android-arm64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz",
-      "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/android-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz",
-      "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/darwin-arm64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz",
-      "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/darwin-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz",
-      "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/freebsd-arm64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz",
-      "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "freebsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/freebsd-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz",
-      "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "freebsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-arm": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz",
-      "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==",
-      "cpu": [
-        "arm"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-arm64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz",
-      "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-ia32": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz",
-      "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==",
-      "cpu": [
-        "ia32"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-loong64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz",
-      "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==",
-      "cpu": [
-        "loong64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-mips64el": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz",
-      "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==",
-      "cpu": [
-        "mips64el"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-ppc64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz",
-      "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==",
-      "cpu": [
-        "ppc64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-riscv64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz",
-      "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==",
-      "cpu": [
-        "riscv64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-s390x": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz",
-      "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==",
-      "cpu": [
-        "s390x"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz",
-      "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/netbsd-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz",
-      "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "netbsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/openbsd-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz",
-      "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "openbsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/sunos-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz",
-      "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "sunos"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/win32-arm64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz",
-      "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/win32-ia32": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz",
-      "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==",
-      "cpu": [
-        "ia32"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/win32-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz",
-      "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@ffmpeg-installer/darwin-arm64": {
-      "version": "4.1.5",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/darwin-arm64/-/darwin-arm64-4.1.5.tgz",
-      "integrity": "sha512-hYqTiP63mXz7wSQfuqfFwfLOfwwFChUedeCVKkBtl/cliaTM7/ePI9bVzfZ2c+dWu3TqCwLDRWNSJ5pqZl8otA==",
-      "cpu": [
-        "arm64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/darwin-x64": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/darwin-x64/-/darwin-x64-4.1.0.tgz",
-      "integrity": "sha512-Z4EyG3cIFjdhlY8wI9aLUXuH8nVt7E9SlMVZtWvSPnm2sm37/yC2CwjUzyCQbJbySnef1tQwGG2Sx+uWhd9IAw==",
-      "cpu": [
-        "x64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/ffmpeg": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/ffmpeg/-/ffmpeg-1.1.0.tgz",
-      "integrity": "sha512-Uq4rmwkdGxIa9A6Bd/VqqYbT7zqh1GrT5/rFwCwKM70b42W5gIjWeVETq6SdcL0zXqDtY081Ws/iJWhr1+xvQg==",
-      "optionalDependencies": {
-        "@ffmpeg-installer/darwin-arm64": "4.1.5",
-        "@ffmpeg-installer/darwin-x64": "4.1.0",
-        "@ffmpeg-installer/linux-arm": "4.1.3",
-        "@ffmpeg-installer/linux-arm64": "4.1.4",
-        "@ffmpeg-installer/linux-ia32": "4.1.0",
-        "@ffmpeg-installer/linux-x64": "4.1.0",
-        "@ffmpeg-installer/win32-ia32": "4.1.0",
-        "@ffmpeg-installer/win32-x64": "4.1.0"
-      }
-    },
-    "node_modules/@ffmpeg-installer/linux-arm": {
-      "version": "4.1.3",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/linux-arm/-/linux-arm-4.1.3.tgz",
-      "integrity": "sha512-NDf5V6l8AfzZ8WzUGZ5mV8O/xMzRag2ETR6+TlGIsMHp81agx51cqpPItXPib/nAZYmo55Bl2L6/WOMI3A5YRg==",
-      "cpu": [
-        "arm"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/linux-arm64": {
-      "version": "4.1.4",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/linux-arm64/-/linux-arm64-4.1.4.tgz",
-      "integrity": "sha512-dljEqAOD0oIM6O6DxBW9US/FkvqvQwgJ2lGHOwHDDwu/pX8+V0YsDL1xqHbj1DMX/+nP9rxw7G7gcUvGspSoKg==",
-      "cpu": [
-        "arm64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/linux-ia32": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/linux-ia32/-/linux-ia32-4.1.0.tgz",
-      "integrity": "sha512-0LWyFQnPf+Ij9GQGD034hS6A90URNu9HCtQ5cTqo5MxOEc7Rd8gLXrJvn++UmxhU0J5RyRE9KRYstdCVUjkNOQ==",
-      "cpu": [
-        "ia32"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/linux-x64": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/linux-x64/-/linux-x64-4.1.0.tgz",
-      "integrity": "sha512-Y5BWhGLU/WpQjOArNIgXD3z5mxxdV8c41C+U15nsE5yF8tVcdCGet5zPs5Zy3Ta6bU7haGpIzryutqCGQA/W8A==",
-      "cpu": [
-        "x64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/win32-ia32": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/win32-ia32/-/win32-ia32-4.1.0.tgz",
-      "integrity": "sha512-FV2D7RlaZv/lrtdhaQ4oETwoFUsUjlUiasiZLDxhEUPdNDWcH1OU9K1xTvqz+OXLdsmYelUDuBS/zkMOTtlUAw==",
-      "cpu": [
-        "ia32"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/win32-x64": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/win32-x64/-/win32-x64-4.1.0.tgz",
-      "integrity": "sha512-Drt5u2vzDnIONf4ZEkKtFlbvwj6rI3kxw1Ck9fpudmtgaZIHD4ucsWB2lCZBXRxJgXR+2IMSti+4rtM4C4rXgg==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ]
-    },
-    "node_modules/@ffprobe-installer/darwin-arm64": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/darwin-arm64/-/darwin-arm64-5.0.1.tgz",
-      "integrity": "sha512-vwNCNjokH8hfkbl6m95zICHwkSzhEvDC3GVBcUp5HX8+4wsX10SP3B+bGur7XUzTIZ4cQpgJmEIAx6TUwRepMg==",
-      "cpu": [
-        "arm64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ]
-    },
-    "node_modules/@ffprobe-installer/darwin-x64": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/darwin-x64/-/darwin-x64-5.1.0.tgz",
-      "integrity": "sha512-J+YGscZMpQclFg31O4cfVRGmDpkVsQ2fZujoUdMAAYcP0NtqpC49Hs3SWJpBdsGB4VeqOt5TTm1vSZQzs1NkhA==",
-      "cpu": [
-        "x64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ]
-    },
-    "node_modules/@ffprobe-installer/ffprobe": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/ffprobe/-/ffprobe-2.1.2.tgz",
-      "integrity": "sha512-ZNvwk4f2magF42Zji2Ese16SMj9BS7Fui4kRjg6gTYTxY3gWZNpg85n4MIfQyI9nimHg4x/gT6FVkp/bBDuBwg==",
-      "engines": {
-        "node": ">=14.21.2"
-      },
-      "optionalDependencies": {
-        "@ffprobe-installer/darwin-arm64": "5.0.1",
-        "@ffprobe-installer/darwin-x64": "5.1.0",
-        "@ffprobe-installer/linux-arm": "5.2.0",
-        "@ffprobe-installer/linux-arm64": "5.2.0",
-        "@ffprobe-installer/linux-ia32": "5.2.0",
-        "@ffprobe-installer/linux-x64": "5.2.0",
-        "@ffprobe-installer/win32-ia32": "5.1.0",
-        "@ffprobe-installer/win32-x64": "5.1.0"
-      }
-    },
-    "node_modules/@ffprobe-installer/linux-arm": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/linux-arm/-/linux-arm-5.2.0.tgz",
-      "integrity": "sha512-PF5HqEhCY7WTWHtLDYbA/+rLS+rhslWvyBlAG1Fk8VzVlnRdl93o6hy7DE2kJgxWQbFaR3ZktPQGEzfkrmQHvQ==",
-      "cpu": [
-        "arm"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffprobe-installer/linux-arm64": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/linux-arm64/-/linux-arm64-5.2.0.tgz",
-      "integrity": "sha512-X1VvWtlLs6ScP73biVLuHD5ohKJKsMTa0vafCESOen4mOoNeLAYbxOVxDWAdFz9cpZgRiloFj5QD6nDj8E28yQ==",
-      "cpu": [
-        "arm64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffprobe-installer/linux-ia32": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/linux-ia32/-/linux-ia32-5.2.0.tgz",
-      "integrity": "sha512-TFVK5sasXyXhbIG7LtPRDmtkrkOsInwKcL43iEvEw+D9vCS2rc//mn9/0Q+BR0UoJEiMK4+ApYr/3LLVUBPOCQ==",
-      "cpu": [
-        "ia32"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffprobe-installer/linux-x64": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/linux-x64/-/linux-x64-5.2.0.tgz",
-      "integrity": "sha512-D3UeqTLYPNs7pBWPLUYGehPdRVqU8eACox4OZy3pZUZatxye2YKlvBwEfaLdL1v2Z4FOAlLUhms0kY8m8kqSRA==",
-      "cpu": [
-        "x64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffprobe-installer/win32-ia32": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/win32-ia32/-/win32-ia32-5.1.0.tgz",
-      "integrity": "sha512-5O3vOoNRxmut0/Nu9vSazTdSHasrr+zPT2B3Hm7kjmO3QVFcIfVImS6ReQnZeSy8JPJOqXts5kX5x/3KOX54XQ==",
-      "cpu": [
-        "ia32"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ]
-    },
-    "node_modules/@ffprobe-installer/win32-x64": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/win32-x64/-/win32-x64-5.1.0.tgz",
-      "integrity": "sha512-jMGYeAgkrdn4e2vvYt/qakgHRE3CPju4bn5TmdPfoAm1BlX1mY9cyMd8gf5vSzI8gH8Zq5WQAyAkmekX/8TSTg==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ]
-    },
-    "node_modules/@lezer/common": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.2.1.tgz",
-      "integrity": "sha512-yemX0ZD2xS/73llMZIK6KplkjIjf2EvAHcinDi/TfJ9hS25G0388+ClHt6/3but0oOxinTcQHJLDXh6w1crzFQ=="
-    },
-    "node_modules/@lezer/cpp": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@lezer/cpp/-/cpp-1.1.2.tgz",
-      "integrity": "sha512-macwKtyeUO0EW86r3xWQCzOV9/CF8imJLpJlPv3sDY57cPGeUZ8gXWOWNlJr52TVByMV3PayFQCA5SHEERDmVQ==",
-      "dependencies": {
-        "@lezer/common": "^1.2.0",
-        "@lezer/highlight": "^1.0.0",
-        "@lezer/lr": "^1.0.0"
-      }
-    },
-    "node_modules/@lezer/highlight": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.0.tgz",
-      "integrity": "sha512-WrS5Mw51sGrpqjlh3d4/fOwpEV2Hd3YOkp9DBt4k8XZQcoTHZFB7sx030A6OcahF4J1nDQAa3jXlTVVYH50IFA==",
-      "dependencies": {
-        "@lezer/common": "^1.0.0"
-      }
-    },
-    "node_modules/@lezer/lr": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.0.tgz",
-      "integrity": "sha512-Wst46p51km8gH0ZUmeNrtpRYmdlRHUpN1DQd3GFAyKANi8WVz8c2jHYTf1CVScFaCjQw1iO3ZZdqGDxQPRErTg==",
-      "dependencies": {
-        "@lezer/common": "^1.0.0"
-      }
-    },
-    "node_modules/@motion-canvas/2d": {
-      "version": "3.15.2",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/2d/-/2d-3.15.2.tgz",
-      "integrity": "sha512-IZAloNOxmTWq3AMi+xqPRAFAuGaDVAfFxZXjy9xVS942a5hZiu+uIJV1zmphbs+elImF1VbqQzAYpEylRpm5OQ==",
-      "dependencies": {
-        "@codemirror/language": "^6.10.1",
-        "@lezer/common": "^1.2.1",
-        "@lezer/highlight": "^1.2.0",
-        "@motion-canvas/core": "^3.15.2",
-        "code-fns": "^0.8.2",
-        "mathjax-full": "^3.2.2",
-        "parse-svg-path": "^0.1.2"
-      }
-    },
-    "node_modules/@motion-canvas/core": {
-      "version": "3.15.2",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/core/-/core-3.15.2.tgz",
-      "integrity": "sha512-Fj1JQbAm2cevy9p/wRzMJ59k+v4u/jOOPoqZMRuOspaXupy3KcUo2tTIzvmbe5/S3QcPcNDlK/8vIjmywHcyQg==",
-      "dependencies": {
-        "@types/chroma-js": "^2.1.4",
-        "chroma-js": "^2.4.2"
-      }
-    },
-    "node_modules/@motion-canvas/ffmpeg": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/ffmpeg/-/ffmpeg-1.1.1.tgz",
-      "integrity": "sha512-w2d7oFfR3hYHXeYtFGoHp6goY+vVL0LoZ2h1b/veTH5KvE7jrLp2Kl/XPHsYJ5ZDRHUT0Nhl05DBLdXYqdSqgg==",
-      "dependencies": {
-        "@ffmpeg-installer/ffmpeg": "^1.1.0",
-        "@ffprobe-installer/ffprobe": "^2.0.0",
-        "fluent-ffmpeg": "^2.1.2"
-      },
-      "peerDependencies": {
-        "@motion-canvas/core": "^3.7.0",
-        "@motion-canvas/vite-plugin": "^3.7.0",
-        "vite": "4.x"
-      }
-    },
-    "node_modules/@motion-canvas/ui": {
-      "version": "3.15.2",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/ui/-/ui-3.15.2.tgz",
-      "integrity": "sha512-p7gj5Gi0j/AswO1ltdVWLakGIRDAlLiQCqaRkj7/U3PzL/8dsWy9Ak1gvzdR56Pe+3X8xMFe4+Rg8Ia5v5lxcA==",
-      "dev": true,
-      "dependencies": {
-        "@motion-canvas/core": "^3.15.2",
-        "@preact/signals": "^1.2.1",
-        "preact": "^10.19.2"
-      }
-    },
-    "node_modules/@motion-canvas/vite-plugin": {
-      "version": "3.15.1",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/vite-plugin/-/vite-plugin-3.15.1.tgz",
-      "integrity": "sha512-yeRMJQxTcYVZGVMnNXQPm0SySQzJXnaRrggGJ2bnDHMsqxCRJt/RfIioK0LMvBaUB+UWlPsJUTMltHuq+J64JA==",
-      "dependencies": {
-        "fast-glob": "^3.3.1",
-        "follow-redirects": "^1.15.2",
-        "mime-types": "^2.1.35",
-        "source-map": "^0.6.1"
-      },
-      "peerDependencies": {
-        "vite": "4.x || 5.x"
-      }
-    },
-    "node_modules/@nodelib/fs.scandir": {
-      "version": "2.1.5",
-      "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
-      "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
-      "dependencies": {
-        "@nodelib/fs.stat": "2.0.5",
-        "run-parallel": "^1.1.9"
-      },
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/@nodelib/fs.stat": {
-      "version": "2.0.5",
-      "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
-      "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/@nodelib/fs.walk": {
-      "version": "1.2.8",
-      "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
-      "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
-      "dependencies": {
-        "@nodelib/fs.scandir": "2.1.5",
-        "fastq": "^1.6.0"
-      },
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/@preact/signals": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/@preact/signals/-/signals-1.2.3.tgz",
-      "integrity": "sha512-M2DXse3Wi8HwjI1d2vQWOLJ3lHogvqTsJYvl4ofXRXgMFQzJ7kmlZvlt5i8x5S5VwgZu0ghru4HkLqOoFfU2JQ==",
-      "dev": true,
-      "dependencies": {
-        "@preact/signals-core": "^1.6.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/preact"
-      },
-      "peerDependencies": {
-        "preact": "10.x"
-      }
-    },
-    "node_modules/@preact/signals-core": {
-      "version": "1.6.0",
-      "resolved": "https://registry.npmjs.org/@preact/signals-core/-/signals-core-1.6.0.tgz",
-      "integrity": "sha512-O/XGxwP85h1F7+ouqTMOIZ3+V1whfaV9ToIVcuyGriD4JkSD00cQo54BKdqjvBJxbenvp7ynfqRHEwI6e+NIhw==",
-      "dev": true,
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/preact"
-      }
-    },
-    "node_modules/@types/chroma-js": {
-      "version": "2.4.4",
-      "resolved": "https://registry.npmjs.org/@types/chroma-js/-/chroma-js-2.4.4.tgz",
-      "integrity": "sha512-/DTccpHTaKomqussrn+ciEvfW4k6NAHzNzs/sts1TCqg333qNxOhy8TNIoQCmbGG3Tl8KdEhkGAssb1n3mTXiQ=="
-    },
-    "node_modules/@types/hast": {
-      "version": "2.3.10",
-      "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz",
-      "integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==",
-      "dependencies": {
-        "@types/unist": "^2"
-      }
-    },
-    "node_modules/@types/unist": {
-      "version": "2.0.10",
-      "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz",
-      "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA=="
-    },
-    "node_modules/@wooorm/starry-night": {
-      "version": "1.7.0",
-      "resolved": "https://registry.npmjs.org/@wooorm/starry-night/-/starry-night-1.7.0.tgz",
-      "integrity": "sha512-ktO0nkddrovIoNW2jAUT+Cdd9n1bWjy1Ir4CdcmgTaT6E94HLlQfu7Yv62falclBEwvsuVp3bSBw23wtta1fNw==",
-      "dependencies": {
-        "@types/hast": "^2.0.0",
-        "import-meta-resolve": "^2.0.0",
-        "vscode-oniguruma": "^1.0.0",
-        "vscode-textmate": "^9.0.0"
-      },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/wooorm"
-      }
-    },
-    "node_modules/async": {
-      "version": "3.2.5",
-      "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz",
-      "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg=="
-    },
-    "node_modules/braces": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
-      "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
-      "dependencies": {
-        "fill-range": "^7.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/chroma-js": {
-      "version": "2.4.2",
-      "resolved": "https://registry.npmjs.org/chroma-js/-/chroma-js-2.4.2.tgz",
-      "integrity": "sha512-U9eDw6+wt7V8z5NncY2jJfZa+hUH8XEj8FQHgFJTrUFnJfXYf4Ml4adI2vXZOjqRDpFWtYVWypDfZwnJ+HIR4A=="
-    },
-    "node_modules/code-fns": {
-      "version": "0.8.2",
-      "resolved": "https://registry.npmjs.org/code-fns/-/code-fns-0.8.2.tgz",
-      "integrity": "sha512-3VVeq3cnWxWiWKFLsVo+XWsOXBSW2gAx2uv0ViETLNmNuygEPHlCeDAv/Zy7xXqPgXtgLZyvIJZmx+ojTgOIGA==",
-      "dependencies": {
-        "@wooorm/starry-night": "^1.2.0"
-      }
-    },
-    "node_modules/commander": {
-      "version": "9.2.0",
-      "resolved": "https://registry.npmjs.org/commander/-/commander-9.2.0.tgz",
-      "integrity": "sha512-e2i4wANQiSXgnrBlIatyHtP1odfUp0BbV5Y5nEGbxtIrStkEOAAzCUirvLBNXHLr7kwLvJl6V+4V3XV9x7Wd9w==",
-      "engines": {
-        "node": "^12.20.0 || >=14"
-      }
-    },
-    "node_modules/esbuild": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz",
-      "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==",
-      "hasInstallScript": true,
-      "bin": {
-        "esbuild": "bin/esbuild"
-      },
-      "engines": {
-        "node": ">=12"
-      },
-      "optionalDependencies": {
-        "@esbuild/android-arm": "0.18.20",
-        "@esbuild/android-arm64": "0.18.20",
-        "@esbuild/android-x64": "0.18.20",
-        "@esbuild/darwin-arm64": "0.18.20",
-        "@esbuild/darwin-x64": "0.18.20",
-        "@esbuild/freebsd-arm64": "0.18.20",
-        "@esbuild/freebsd-x64": "0.18.20",
-        "@esbuild/linux-arm": "0.18.20",
-        "@esbuild/linux-arm64": "0.18.20",
-        "@esbuild/linux-ia32": "0.18.20",
-        "@esbuild/linux-loong64": "0.18.20",
-        "@esbuild/linux-mips64el": "0.18.20",
-        "@esbuild/linux-ppc64": "0.18.20",
-        "@esbuild/linux-riscv64": "0.18.20",
-        "@esbuild/linux-s390x": "0.18.20",
-        "@esbuild/linux-x64": "0.18.20",
-        "@esbuild/netbsd-x64": "0.18.20",
-        "@esbuild/openbsd-x64": "0.18.20",
-        "@esbuild/sunos-x64": "0.18.20",
-        "@esbuild/win32-arm64": "0.18.20",
-        "@esbuild/win32-ia32": "0.18.20",
-        "@esbuild/win32-x64": "0.18.20"
-      }
-    },
-    "node_modules/esm": {
-      "version": "3.2.25",
-      "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz",
-      "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==",
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/fast-glob": {
-      "version": "3.3.2",
-      "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
-      "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
-      "dependencies": {
-        "@nodelib/fs.stat": "^2.0.2",
-        "@nodelib/fs.walk": "^1.2.3",
-        "glob-parent": "^5.1.2",
-        "merge2": "^1.3.0",
-        "micromatch": "^4.0.4"
-      },
-      "engines": {
-        "node": ">=8.6.0"
-      }
-    },
-    "node_modules/fastq": {
-      "version": "1.17.1",
-      "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz",
-      "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==",
-      "dependencies": {
-        "reusify": "^1.0.4"
-      }
-    },
-    "node_modules/fill-range": {
-      "version": "7.0.1",
-      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
-      "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
-      "dependencies": {
-        "to-regex-range": "^5.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/fluent-ffmpeg": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/fluent-ffmpeg/-/fluent-ffmpeg-2.1.2.tgz",
-      "integrity": "sha512-IZTB4kq5GK0DPp7sGQ0q/BWurGHffRtQQwVkiqDgeO6wYJLLV5ZhgNOQ65loZxxuPMKZKZcICCUnaGtlxBiR0Q==",
-      "dependencies": {
-        "async": ">=0.2.9",
-        "which": "^1.1.1"
-      },
-      "engines": {
-        "node": ">=0.8.0"
-      }
-    },
-    "node_modules/follow-redirects": {
-      "version": "1.15.6",
-      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
-      "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
-      "funding": [
-        {
-          "type": "individual",
-          "url": "https://github.com/sponsors/RubenVerborgh"
-        }
-      ],
-      "engines": {
-        "node": ">=4.0"
-      },
-      "peerDependenciesMeta": {
-        "debug": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/fsevents": {
-      "version": "2.3.3",
-      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
-      "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
-      }
-    },
-    "node_modules/glob-parent": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
-      "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
-      "dependencies": {
-        "is-glob": "^4.0.1"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "node_modules/import-meta-resolve": {
-      "version": "2.2.2",
-      "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-2.2.2.tgz",
-      "integrity": "sha512-f8KcQ1D80V7RnqVm+/lirO9zkOxjGxhaTC1IPrBGd3MEfNgmNG67tSUO9gTi2F3Blr2Az6g1vocaxzkVnWl9MA==",
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/wooorm"
-      }
-    },
-    "node_modules/is-extglob": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
-      "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/is-glob": {
-      "version": "4.0.3",
-      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
-      "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
-      "dependencies": {
-        "is-extglob": "^2.1.1"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/is-number": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
-      "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
-      "engines": {
-        "node": ">=0.12.0"
-      }
-    },
-    "node_modules/isexe": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
-      "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
-    },
-    "node_modules/mathjax-full": {
-      "version": "3.2.2",
-      "resolved": "https://registry.npmjs.org/mathjax-full/-/mathjax-full-3.2.2.tgz",
-      "integrity": "sha512-+LfG9Fik+OuI8SLwsiR02IVdjcnRCy5MufYLi0C3TdMT56L/pjB0alMVGgoWJF8pN9Rc7FESycZB9BMNWIid5w==",
-      "dependencies": {
-        "esm": "^3.2.25",
-        "mhchemparser": "^4.1.0",
-        "mj-context-menu": "^0.6.1",
-        "speech-rule-engine": "^4.0.6"
-      }
-    },
-    "node_modules/merge2": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
-      "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/mhchemparser": {
-      "version": "4.2.1",
-      "resolved": "https://registry.npmjs.org/mhchemparser/-/mhchemparser-4.2.1.tgz",
-      "integrity": "sha512-kYmyrCirqJf3zZ9t/0wGgRZ4/ZJw//VwaRVGA75C4nhE60vtnIzhl9J9ndkX/h6hxSN7pjg/cE0VxbnNM+bnDQ=="
-    },
-    "node_modules/micromatch": {
-      "version": "4.0.5",
-      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
-      "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
-      "dependencies": {
-        "braces": "^3.0.2",
-        "picomatch": "^2.3.1"
-      },
-      "engines": {
-        "node": ">=8.6"
-      }
-    },
-    "node_modules/mime-db": {
-      "version": "1.52.0",
-      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
-      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/mime-types": {
-      "version": "2.1.35",
-      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
-      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
-      "dependencies": {
-        "mime-db": "1.52.0"
-      },
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/mj-context-menu": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/mj-context-menu/-/mj-context-menu-0.6.1.tgz",
-      "integrity": "sha512-7NO5s6n10TIV96d4g2uDpG7ZDpIhMh0QNfGdJw/W47JswFcosz457wqz/b5sAKvl12sxINGFCn80NZHKwxQEXA=="
-    },
-    "node_modules/nanoid": {
-      "version": "3.3.7",
-      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
-      "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/ai"
-        }
-      ],
-      "bin": {
-        "nanoid": "bin/nanoid.cjs"
-      },
-      "engines": {
-        "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
-      }
-    },
-    "node_modules/parse-svg-path": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/parse-svg-path/-/parse-svg-path-0.1.2.tgz",
-      "integrity": "sha512-JyPSBnkTJ0AI8GGJLfMXvKq42cj5c006fnLz6fXy6zfoVjJizi8BNTpu8on8ziI1cKy9d9DGNuY17Ce7wuejpQ=="
-    },
-    "node_modules/picocolors": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
-      "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
-    },
-    "node_modules/picomatch": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
-      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
-      "engines": {
-        "node": ">=8.6"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/jonschlinkert"
-      }
-    },
-    "node_modules/postcss": {
-      "version": "8.4.38",
-      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz",
-      "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==",
-      "funding": [
-        {
-          "type": "opencollective",
-          "url": "https://opencollective.com/postcss/"
-        },
-        {
-          "type": "tidelift",
-          "url": "https://tidelift.com/funding/github/npm/postcss"
-        },
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/ai"
-        }
-      ],
-      "dependencies": {
-        "nanoid": "^3.3.7",
-        "picocolors": "^1.0.0",
-        "source-map-js": "^1.2.0"
-      },
-      "engines": {
-        "node": "^10 || ^12 || >=14"
-      }
-    },
-    "node_modules/preact": {
-      "version": "10.21.0",
-      "resolved": "https://registry.npmjs.org/preact/-/preact-10.21.0.tgz",
-      "integrity": "sha512-aQAIxtzWEwH8ou+OovWVSVNlFImL7xUCwJX3YMqA3U8iKCNC34999fFOnWjYNsylgfPgMexpbk7WYOLtKr/mxg==",
-      "dev": true,
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/preact"
-      }
-    },
-    "node_modules/queue-microtask": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
-      "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/feross"
-        },
-        {
-          "type": "patreon",
-          "url": "https://www.patreon.com/feross"
-        },
-        {
-          "type": "consulting",
-          "url": "https://feross.org/support"
-        }
-      ]
-    },
-    "node_modules/reusify": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
-      "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
-      "engines": {
-        "iojs": ">=1.0.0",
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/rollup": {
-      "version": "3.29.4",
-      "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz",
-      "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==",
-      "bin": {
-        "rollup": "dist/bin/rollup"
-      },
-      "engines": {
-        "node": ">=14.18.0",
-        "npm": ">=8.0.0"
-      },
-      "optionalDependencies": {
-        "fsevents": "~2.3.2"
-      }
-    },
-    "node_modules/run-parallel": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
-      "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/feross"
-        },
-        {
-          "type": "patreon",
-          "url": "https://www.patreon.com/feross"
-        },
-        {
-          "type": "consulting",
-          "url": "https://feross.org/support"
-        }
-      ],
-      "dependencies": {
-        "queue-microtask": "^1.2.2"
-      }
-    },
-    "node_modules/source-map": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
-      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/source-map-js": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
-      "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/speech-rule-engine": {
-      "version": "4.0.7",
-      "resolved": "https://registry.npmjs.org/speech-rule-engine/-/speech-rule-engine-4.0.7.tgz",
-      "integrity": "sha512-sJrL3/wHzNwJRLBdf6CjJWIlxC04iYKkyXvYSVsWVOiC2DSkHmxsqOhEeMsBA9XK+CHuNcsdkbFDnoUfAsmp9g==",
-      "dependencies": {
-        "commander": "9.2.0",
-        "wicked-good-xpath": "1.3.0",
-        "xmldom-sre": "0.1.31"
-      },
-      "bin": {
-        "sre": "bin/sre"
-      }
-    },
-    "node_modules/style-mod": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.2.tgz",
-      "integrity": "sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw=="
-    },
-    "node_modules/to-regex-range": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
-      "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
-      "dependencies": {
-        "is-number": "^7.0.0"
-      },
-      "engines": {
-        "node": ">=8.0"
-      }
-    },
-    "node_modules/typescript": {
-      "version": "5.4.5",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz",
-      "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==",
-      "dev": true,
-      "bin": {
-        "tsc": "bin/tsc",
-        "tsserver": "bin/tsserver"
-      },
-      "engines": {
-        "node": ">=14.17"
-      }
-    },
-    "node_modules/vite": {
-      "version": "4.5.3",
-      "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.3.tgz",
-      "integrity": "sha512-kQL23kMeX92v3ph7IauVkXkikdDRsYMGTVl5KY2E9OY4ONLvkHf04MDTbnfo6NKxZiDLWzVpP5oTa8hQD8U3dg==",
-      "dependencies": {
-        "esbuild": "^0.18.10",
-        "postcss": "^8.4.27",
-        "rollup": "^3.27.1"
-      },
-      "bin": {
-        "vite": "bin/vite.js"
-      },
-      "engines": {
-        "node": "^14.18.0 || >=16.0.0"
-      },
-      "funding": {
-        "url": "https://github.com/vitejs/vite?sponsor=1"
-      },
-      "optionalDependencies": {
-        "fsevents": "~2.3.2"
-      },
-      "peerDependencies": {
-        "@types/node": ">= 14",
-        "less": "*",
-        "lightningcss": "^1.21.0",
-        "sass": "*",
-        "stylus": "*",
-        "sugarss": "*",
-        "terser": "^5.4.0"
-      },
-      "peerDependenciesMeta": {
-        "@types/node": {
-          "optional": true
-        },
-        "less": {
-          "optional": true
-        },
-        "lightningcss": {
-          "optional": true
-        },
-        "sass": {
-          "optional": true
-        },
-        "stylus": {
-          "optional": true
-        },
-        "sugarss": {
-          "optional": true
-        },
-        "terser": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/vscode-oniguruma": {
-      "version": "1.7.0",
-      "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz",
-      "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA=="
-    },
-    "node_modules/vscode-textmate": {
-      "version": "9.0.0",
-      "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-9.0.0.tgz",
-      "integrity": "sha512-Cl65diFGxz7gpwbav10HqiY/eVYTO1sjQpmRmV991Bj7wAoOAjGQ97PpQcXorDE2Uc4hnGWLY17xme+5t6MlSg=="
-    },
-    "node_modules/w3c-keyname": {
-      "version": "2.2.8",
-      "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz",
-      "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ=="
-    },
-    "node_modules/which": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
-      "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
-      "dependencies": {
-        "isexe": "^2.0.0"
-      },
-      "bin": {
-        "which": "bin/which"
-      }
-    },
-    "node_modules/wicked-good-xpath": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/wicked-good-xpath/-/wicked-good-xpath-1.3.0.tgz",
-      "integrity": "sha512-Gd9+TUn5nXdwj/hFsPVx5cuHHiF5Bwuc30jZ4+ronF1qHK5O7HD0sgmXWSEgwKquT3ClLoKPVbO6qGwVwLzvAw=="
-    },
-    "node_modules/xmldom-sre": {
-      "version": "0.1.31",
-      "resolved": "https://registry.npmjs.org/xmldom-sre/-/xmldom-sre-0.1.31.tgz",
-      "integrity": "sha512-f9s+fUkX04BxQf+7mMWAp5zk61pciie+fFLC9hX9UVvCeJQfNHRHXpeo5MPcR0EUf57PYLdt+ZO4f3Ipk2oZUw==",
-      "engines": {
-        "node": ">=0.1"
-      }
-    }
-  }
-}
diff --git a/animation/class_templates_why/package.json b/animation/class_templates_why/package.json
deleted file mode 100644
index f84bb7a..0000000
--- a/animation/class_templates_why/package.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
-  "name": "class_templates_why",
-  "private": true,
-  "version": "0.0.0",
-  "scripts": {
-    "start": "vite",
-    "serve": "vite",
-    "build": "tsc && vite build"
-  },
-  "dependencies": {
-    "@lezer/cpp": "^1.1.2",
-    "@motion-canvas/2d": "^3.15.2",
-    "@motion-canvas/core": "^3.15.2",
-    "@motion-canvas/ffmpeg": "^1.1.0"
-  },
-  "devDependencies": {
-    "@motion-canvas/ui": "^3.15.2",
-    "@motion-canvas/vite-plugin": "^3.15.1",
-    "typescript": "^5.2.2",
-    "vite": "^4.0.0"
-  }
-}
diff --git a/animation/class_templates_why/src/functions/functions.tsx b/animation/class_templates_why/src/functions/functions.tsx
deleted file mode 100644
index 458fb31..0000000
--- a/animation/class_templates_why/src/functions/functions.tsx
+++ /dev/null
@@ -1,64 +0,0 @@
-import {
-  CodeModification,
-} from '@motion-canvas/2d/lib/components/CodeBlock';
-
-const store = (...args: [TemplateStringsArray, ...any]) => args;
-
-function to_string([strings, ...values]: [TemplateStringsArray, ...any]): string {
-  return strings.reduce((acc, str, i) => {
-    const value = values[i] ?? '';
-    return acc + str + value;
-  }, '');
-}
-
-function append(
-  template_1: TemplateStringsArray, args_1: string[],
-  template_2: TemplateStringsArray, args_2: string[]): [TemplateStringsArray, ...string[]] {
-  let new_template = Array.from<string>(template_1);
-  let new_args: Array<string> = args_1;
-  new_template[template_1.length - 1] += template_2[0]
-  new_template = new_template.concat(template_2.slice(1))
-  new_args = new_args.concat(args_2)
-  return [new_template as unknown as TemplateStringsArray, ...new_args];
-}
-
-const isCodeModification = (code: any): code is CodeModification => (code as CodeModification).from !== undefined;
-
-function simplify(
-  args_in: [TemplateStringsArray, ...any]): [TemplateStringsArray, ...string[]] {
-  const template = args_in[0]
-  const args = args_in.slice(1)
-  if (args.every((arg) => (typeof (arg) == "string") || isCodeModification(arg))) {
-    return args_in
-  }
-  let new_template: Array<any> = [];
-  let new_args: Array<any> = [];
-  let concatenate = false;
-  for (let i = 0; i <= args.length; i++) {
-    if (concatenate) {
-      concatenate = false;
-      new_template[new_template.length - 1] += template[i];
-    } else {
-      new_template.push(template[i]);
-    }
-    if (i == args.length) { break; }
-    if (typeof (args[i]) == "string" || isCodeModification(args[i])) {
-      new_args.push(args[i])
-      continue;
-    }
-    let simplified_arg = simplify(args[i]);
-    let simplified_template = simplified_arg[0]
-    let simplified_args = simplified_arg.slice(1)
-    const appended = append(
-      new_template as unknown as TemplateStringsArray,
-      new_args,
-      simplified_template,
-      simplified_args as string[]);
-    new_template = Array.from<string>(appended[0])
-    new_args = appended.slice(1)
-    concatenate = true;
-  }
-  return [new_template as unknown as TemplateStringsArray, ...new_args]
-}
-
-export {store, simplify, to_string};
diff --git a/animation/class_templates_why/src/global.css b/animation/class_templates_why/src/global.css
deleted file mode 100644
index 201f5ff..0000000
--- a/animation/class_templates_why/src/global.css
+++ /dev/null
@@ -1 +0,0 @@
-@import url('https://fonts.googleapis.com/css2?family=Fira+Mono:wght@400;500;700&display=swap');
diff --git a/animation/class_templates_why/src/motion-canvas.d.ts b/animation/class_templates_why/src/motion-canvas.d.ts
deleted file mode 100644
index 067c6a4..0000000
--- a/animation/class_templates_why/src/motion-canvas.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-/// <reference types="@motion-canvas/core/project" />
diff --git a/animation/class_templates_why/src/project.meta b/animation/class_templates_why/src/project.meta
deleted file mode 100644
index 5f34ffe..0000000
--- a/animation/class_templates_why/src/project.meta
+++ /dev/null
@@ -1,31 +0,0 @@
-{
-  "version": 0,
-  "shared": {
-    "background": "rgb(10,15,20)",
-    "range": [
-      0,
-      null
-    ],
-    "size": {
-      "x": 1920,
-      "y": 1080
-    },
-    "audioOffset": 0
-  },
-  "preview": {
-    "fps": 30,
-    "resolutionScale": 2
-  },
-  "rendering": {
-    "fps": 30,
-    "resolutionScale": 1,
-    "colorSpace": "srgb",
-    "exporter": {
-      "name": "@motion-canvas/ffmpeg",
-      "options": {
-        "fastStart": true,
-        "includeAudio": true
-      }
-    }
-  }
-}
\ No newline at end of file
diff --git a/animation/class_templates_why/src/project.ts b/animation/class_templates_why/src/project.ts
deleted file mode 100644
index 82ee0bd..0000000
--- a/animation/class_templates_why/src/project.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-import { makeProject } from '@motion-canvas/core';
-import { Code, LezerHighlighter } from '@motion-canvas/2d';
-import { parser } from '@lezer/cpp';
-import { tags } from '@lezer/highlight';
-import { HighlightStyle } from '@codemirror/language';
-
-const MyStyle = HighlightStyle.define([
-  { tag: tags.keyword, color: '#569CD6' }, // VSCode Keyword color
-  { tag: tags.controlKeyword, color: '#C586C0' }, // VSCode Control Keyword color
-  { tag: tags.operatorKeyword, color: '#C586C0' }, // VSCode Control Keyword color
-  { tag: tags.comment, color: 'gray' }, // VSCode Comment color
-  { tag: tags.className, color: '#4EC9B0' }, // VSCode Class Name color
-  { tag: tags.constant(tags.variableName), color: '#B5CEA8' }, // VSCode Constant color
-  { tag: tags.function(tags.variableName), color: '#DCDCAA' }, // VSCode Function color
-  { tag: tags.function(tags.propertyName), color: '#DCDCAA' }, // VSCode Function color
-  // { tag: tags.propertyName, color: '#DCDCAA' }, // VSCode Function color
-  { tag: tags.number, color: '#B5CEA8' }, // VSCode Number color
-  { tag: tags.string, color: '#CE9178' }, // VSCode String color
-  { tag: tags.typeName, color: '#4EC9B0' }, // VSCode Type Name color
-  { tag: tags.squareBracket, color: '#C586C0' }, // VSCode Square Bracket color
-  { tag: tags.bracket, color: '#C586C0' }, // VSCode Bracket color
-  { tag: tags.brace, color: '#DDDD22' }, // VSCode Brace color
-  { tag: tags.processingInstruction, color: '#C586C0' }, // VSCode Brace color
-  { tag: tags.arithmeticOperator, color: '#D16969' }, // VSCode Arithmetic Operator color
-]);
-
-Code.defaultHighlighter = new LezerHighlighter(parser, MyStyle);
-
-import './global.css';
-
-import example from './scenes/example?scene';
-
-
-export default makeProject({
-  scenes: [example],
-});
diff --git a/animation/class_templates_why/src/scenes/example.meta b/animation/class_templates_why/src/scenes/example.meta
deleted file mode 100644
index c31dca6..0000000
--- a/animation/class_templates_why/src/scenes/example.meta
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-  "version": 0,
-  "timeEvents": [],
-  "seed": 1820440022
-}
\ No newline at end of file
diff --git a/animation/class_templates_why/src/scenes/example.tsx b/animation/class_templates_why/src/scenes/example.tsx
deleted file mode 100644
index ff6d84f..0000000
--- a/animation/class_templates_why/src/scenes/example.tsx
+++ /dev/null
@@ -1,794 +0,0 @@
-import { createRef } from '@motion-canvas/core/lib/utils';
-import { makeScene2D, Code, lines } from '@motion-canvas/2d';
-import { all, waitFor, waitUntil } from '@motion-canvas/core/lib/flow';
-import { DEFAULT } from '@motion-canvas/core/lib/signals';
-import { BBox, Vector2 } from '@motion-canvas/core/lib/types';
-
-import { store, simplify } from '../functions/functions'
-
-export default makeScene2D(function* (view) {
-  const codeRef = createRef<Code>();
-
-  yield view.add(<Code
-    ref={codeRef}
-    fontSize={35}
-    fontFamily={'Fira Mono'}
-    fontWeight={500}
-  />);
-
-
-  const code = `
-  struct Foo {
-    template <typename ClassT>
-    void Bar(ClassT value) {}  // 1️⃣
-    void Bar(int value) {}     // 2️⃣
-
-    template <typename ClassT>
-    static void StaticBar(ClassT value) {}   // 3️⃣
-    static void StaticBar(double value) {}   // 4️⃣
-  };
-
-  int main() {
-    Foo foo{};
-    // What gets called in every case?
-    foo.Bar(42);
-    foo.Bar(42.42);
-    Foo::StaticBar(42);
-    Foo::StaticBar(42.42);
-  }`
-
-  const code2 = `
-  struct Foo {
-    template <typename ClassT>
-    void Bar(ClassT value) {}  // 1️⃣
-    void Bar(int value) {}     // 2️⃣
-
-    template <typename ClassT>
-    static void StaticBar(ClassT value) {}   // 3️⃣
-    static void StaticBar(double value) {}   // 4️⃣
-  };
-
-  // Specialize our template out-of-class anywhere
-  // in the code after the class declaration.
-  template<>
-  void Foo::Bar(double value) {}  // 5️⃣
-
-  int main() {
-    Foo foo{};
-    // What gets called in every case?
-    foo.Bar(42);
-    foo.Bar(42.42);
-    Foo::StaticBar(42);
-    Foo::StaticBar(42.42);
-  }`
-
-  const code_coordinate = `
-  #include <iostream>
-
-  class Coordinate {
-    public:
-      Coordinate(int row, int col) : row_{row}, col_{col} {}
-
-      int row() const { return row_; }
-      int col() const { return col_; }
-
-      void Print() const {
-        std::cout << "int coordinate: [" << row_ << ", " << col_ << "]" << std::endl;
-      }
-
-    private:
-      int row_{};
-      int col_{};
-  };
-
-  int main() {
-      const Coordinate coordinate{42, 23};
-      coordinate.Print();
-      return 0;
-  }`
-
-  const code_float_coordinate = `
-  #include <iostream>
-
-  class Coordinate {
-     public:
-      Coordinate(int row, int col) : row_{row}, col_{col} {}
-
-      int row() const { return row_; }
-      int col() const { return col_; }
-
-      void Print() const {
-        std::cout << "int coordinate: [" << row_ << ", " << col_ << "]" << std::endl;
-      }
-
-     private:
-      int row_{};
-      int col_{};
-  };
-
-  class FloatCoordinate {
-     public:
-      FloatCoordinate(float row, float col) : row_{row}, col_{col} {}
-
-      float row() const { return row_; }
-      float col() const { return col_; }
-
-      void Print() const {
-        std::cout << "float coordinate: [" << row_ << ", " << col_ << "]" << std::endl;
-      }
-
-     private:
-      float row_{};
-      float col_{};
-  };
-
-  int main() {
-      const Coordinate coordinate{42, 23};
-      coordinate.Print();
-      const FloatCoordinate other_coordinate{42.42F, 23.23F};
-      other_coordinate.Print();
-      return 0;
-  }`
-
-  const code_template_coordinate = `
-  #include <iostream>
-
-  template <typename ScalarT>
-  class Coordinate {
-     public:
-      Coordinate(ScalarT row, ScalarT col) : row_{row}, col_{col} {}
-
-      ScalarT row() const { return row_; }
-      ScalarT col() const { return col_; }
-
-      void Print() const {
-        std::cout << "Generic coordinate: [" << row_ << ", " << col_ << "]" << std::endl;
-      }
-
-     private:
-      ScalarT row_{};
-      ScalarT col_{};
-  };
-
-  int main() {
-    const Coordinate<int> coordinate{42, 23};
-    coordinate.Print();
-    const Coordinate<float> other_coordinate{42.42F, 23.23F};
-    other_coordinate.Print();
-    return 0;
-  }`
-
-  const code_template_coordinate_ctad = `
-  #include <iostream>
-
-  template <typename ScalarT>
-  class Coordinate {
-     public:
-      Coordinate(ScalarT row, ScalarT col) : row_{row}, col_{col} {}
-
-      ScalarT row() const { return row_; }
-      ScalarT col() const { return col_; }
-
-      void Print() const {
-        std::cout << "Generic coordinate: [" << row_ << ", " << col_ << "]" << std::endl;
-      }
-
-     private:
-      ScalarT row_{};
-      ScalarT col_{};
-  };
-
-  int main() {
-    // In C++17 the compiler is able to figure out the types
-    const Coordinate coordinate{42, 23};
-    coordinate.Print();
-    const Coordinate other_coordinate{42.42F, 23.23F};
-    other_coordinate.Print();
-    return 0;
-  }`
-
-  const code_template_coordinate_specialization = `
-  #include <iostream>
-
-  template <typename ScalarT>
-  class Coordinate {
-     public:
-      Coordinate(ScalarT row, ScalarT col) : row_{row}, col_{col} {}
-
-      ScalarT row() const { return row_; }
-      ScalarT col() const { return col_; }
-
-      void Print() const {
-        std::cout << "Generic coordinate: [" << row_ << ", " << col_ << "]" << std::endl;
-      }
-
-     private:
-      ScalarT row_{};
-      ScalarT col_{};
-  };
-
-  // Full class template specialization for ScalarT = float.
-  template<>
-  class Coordinate<float> {
-     public:
-      Coordinate(float row, float col) : row_{row}, col_{col} {}
-
-      float row() const { return row_; }
-      float col() const { return col_; }
-
-      void Print() const {
-        std::cout << "float coordinate: [" << row_ << ", " << col_ << "]" << std::endl;
-      }
-
-     private:
-      float row_{};
-      float col_{};
-  };
-
-  int main() {
-      // Creates a new implicit instantiation of Coordinate<int>
-      const Coordinate coordinate{42, 23};
-      coordinate.Print();
-      // Uses the explicit instantiation of Coordinate<float>
-      const Coordinate other_coordinate{42.42F, 23.23F};
-      other_coordinate.Print();
-      return 0;
-  }`
-
-  const code_template_coordinate_specialization_no_print = `
-  #include <iostream>
-
-  template <typename ScalarT>
-  class Coordinate {
-     public:
-      Coordinate(ScalarT row, ScalarT col) : row_{row}, col_{col} {}
-
-      ScalarT row() const { return row_; }
-      ScalarT col() const { return col_; }
-
-      void Print() const {
-        std::cout << "Generic coordinate: [" << row_ << ", " << col_ << "]" << std::endl;
-      }
-
-     private:
-      ScalarT row_{};
-      ScalarT col_{};
-  };
-
-  // Full class template specialization for ScalarT = float.
-  template<>
-  class Coordinate<float> {
-     public:
-      Coordinate(float row, float col) : row_{row}, col_{col} {}
-
-      float row() const { return row_; }
-      float col() const { return col_; }
-
-     private:
-      float row_{};
-      float col_{};
-  };
-
-  int main() {
-      // Creates a new implicit instantiation of Coordinate<int>
-      const Coordinate coordinate{42, 23};
-      coordinate.Print();
-      // Uses the explicit instantiation of Coordinate<float>
-      const Coordinate other_coordinate{42.42F, 23.23F};
-      // ❌ Won't compile! No Print() function in explicit specialization
-      other_coordinate.Print();
-      return 0;
-  }`
-
-  const code_class_function_specialization = `
-  #include <iostream>
-
-  template <typename ScalarT>
-  class Coordinate {
-     public:
-      Coordinate(ScalarT row, ScalarT col) : row_{row}, col_{col} {}
-
-      ScalarT row() const { return row_; }
-      ScalarT col() const { return col_; }
-
-      void Print() const {
-        std::cout << "Generic coordinate: [" << row_ << ", " << col_ << "]" << std::endl;
-      }
-
-     private:
-      ScalarT row_{};
-      ScalarT col_{};
-  };
-
-  template<>
-  void Coordinate<float>::Print() const {
-      std::cout << "float coordinate: [" << row_ << ", " << col_ << "]" << std::endl;
-  }
-
-  int main() {
-      // In C++17 the compiler is able to figure out the types
-      const Coordinate coordinate{42, 23};
-      coordinate.Print();
-      const Coordinate other_coordinate{42.42F, 23.23F};
-      other_coordinate.Print();
-      return 0;
-  }`
-
-  const code_cast_to = `
-  #include <iostream>
-
-  template <typename ScalarT>
-  class Coordinate {
-     public:
-      Coordinate(ScalarT row, ScalarT col) : row_{row}, col_{col} {}
-
-      ScalarT row() const { return row_; }
-      ScalarT col() const { return col_; }
-
-      void Print() const {
-        std::cout << "Generic coordinate: [" << row_ << ", " << col_ << "]" << std::endl;
-      }
-
-      template <typename OtherScalarT>
-      Coordinate<OtherScalarT> CastTo() const {
-          std::cout << "Non-trivial cast" << std::endl;
-          return Coordinate<OtherScalarT>{
-            static_cast<OtherScalarT>(row_), static_cast<OtherScalarT>(col_)};
-      }
-
-     private:
-      ScalarT row_{};
-      ScalarT col_{};
-  };
-
-  template<>
-  void Coordinate<float>::Print() const {
-      std::cout << "float coordinate: [" << row_ << ", " << col_ << "]" << std::endl;
-  }
-
-  int main() {
-      // In C++17 the compiler is able to figure out the types
-      const Coordinate coordinate{42, 23};
-      coordinate.Print();
-      const Coordinate other_coordinate{42.42F, 23.23F};
-      other_coordinate.Print();
-      return 0;
-  }`
-
-  const code_cast_to_specialization = `
-  #include <iostream>
-
-  template <typename ScalarT>
-  class Coordinate {
-     public:
-      Coordinate(ScalarT row, ScalarT col) : row_{row}, col_{col} {}
-
-      ScalarT row() const { return row_; }
-      ScalarT col() const { return col_; }
-
-      void Print() const {
-        std::cout << "Generic coordinate: [" << row_ << ", " << col_ << "]" << std::endl;
-      }
-
-      template <typename OtherScalarT>
-      Coordinate<OtherScalarT> CastTo() const {
-          std::cout << "Non-trivial cast" << std::endl;
-          return Coordinate<OtherScalarT>{
-            static_cast<OtherScalarT>(row_), static_cast<OtherScalarT>(col_)};
-      }
-
-     private:
-      ScalarT row_{};
-      ScalarT col_{};
-  };
-
-  template<>
-  void Coordinate<float>::Print() const {
-      std::cout << "float coordinate: [" << row_ << ", " << col_ << "]" << std::endl;
-  }
-
-  template <>
-  template <>
-  Coordinate<int> Coordinate<int>::CastTo<int>() const {
-      std::cout << "Trivial cast" << std::endl;
-      return *this;
-  }
-
-  int main() {
-      // In C++17 the compiler is able to figure out the types
-      const Coordinate coordinate{42, 23};
-      coordinate.Print();
-      const Coordinate other_coordinate{42.42F, 23.23F};
-      other_coordinate.Print();
-      return 0;
-  }`
-
-  const code_cast_to_specialization_main = `
-  #include <iostream>
-
-  template <typename ScalarT>
-  class Coordinate {
-     public:
-      Coordinate(ScalarT row, ScalarT col) : row_{row}, col_{col} {}
-
-      ScalarT row() const { return row_; }
-      ScalarT col() const { return col_; }
-
-      void Print() const {
-        std::cout << "Generic coordinate: [" << row_ << ", " << col_ << "]" << std::endl;
-      }
-
-      template <typename OtherScalarT>
-      Coordinate<OtherScalarT> CastTo() const {
-          std::cout << "Non-trivial cast" << std::endl;
-          return Coordinate<OtherScalarT>{
-            static_cast<OtherScalarT>(row_), static_cast<OtherScalarT>(col_)};
-      }
-
-     private:
-      ScalarT row_{};
-      ScalarT col_{};
-  };
-
-  template<>
-  void Coordinate<float>::Print() const {
-      std::cout << "float coordinate: [" << row_ << ", " << col_ << "]" << std::endl;
-  }
-
-  template <>
-  template <>
-  Coordinate<int> Coordinate<int>::CastTo<int>() const {
-      std::cout << "Trivial cast" << std::endl;
-      return *this;
-  }
-
-  int main() {
-      // In C++17 the compiler is able to figure out the types
-      const Coordinate coordinate{42.42F, 23.23F};
-      coordinate.Print();
-      const auto int_coordinate = coordinate.CastTo<int>();
-      int_coordinate.Print();
-      const auto another_int_coordinate = int_coordinate.CastTo<int>();
-      another_int_coordinate.Print();
-      return 0;
-  }`
-
-  const zoom_fn = (in_zoom: number) => new Vector2(in_zoom, in_zoom);
-
-  const duration = 1.0
-
-  yield* codeRef().code(code, 0).wait(duration);
-  yield* codeRef().code(code2, duration);
-  yield* waitFor(duration);
-
-  yield* codeRef().code(code_coordinate, 0).wait(duration);
-  yield* all(
-    codeRef().code(code_float_coordinate, duration),
-    codeRef().fontSize(20, duration)
-  );
-  yield* waitFor(duration);
-  yield* all(
-    codeRef().code(code_template_coordinate, duration),
-    codeRef().fontSize(30, duration)
-  );
-  yield* waitFor(duration);
-  yield* codeRef().selection(codeRef().findAllRanges(/template/g), duration);
-  yield* waitFor(duration);
-  yield* codeRef().selection(codeRef().findFirstRange(/ScalarT/g), duration);
-  yield* waitFor(duration);
-  yield* codeRef().selection(codeRef().findFirstRange(/typename/g), duration);
-  yield* waitFor(duration);
-  yield* codeRef().selection(codeRef().findAllRanges(/ScalarT/g), duration);
-  yield* waitFor(duration);
-  yield* codeRef().selection(codeRef().findAllRanges(/Coordinate<\w*>/g), duration);
-  yield* waitFor(duration);
-
-  yield* codeRef().selection(DEFAULT);
-  yield* waitFor(duration);
-  yield* all(
-    codeRef().code(code_template_coordinate_ctad, duration),
-    codeRef().fontSize(30, duration)
-  );
-  yield* waitFor(duration);
-  yield* all(
-    codeRef().code(code_template_coordinate_specialization, duration),
-    codeRef().y(-350, duration),
-    codeRef().selection(lines(20, Infinity), duration)
-  );
-  yield* waitFor(duration);
-  yield* all(
-    codeRef().code(code_template_coordinate_specialization_no_print, duration),
-    codeRef().y(-350, duration)
-  );
-  yield* waitFor(duration);
-
-  yield* codeRef().selection(DEFAULT);
-  yield* all(
-    codeRef().code(code_template_coordinate_ctad, 0),
-    codeRef().y(0, 0)
-  );
-  yield* waitFor(duration);
-  yield* all(
-    codeRef().code(code_class_function_specialization, duration),
-    codeRef().fontSize(25, duration)
-  );
-  yield* waitFor(duration);
-  yield* codeRef().selection(codeRef().findAllRanges(/template<>/g), duration);
-  yield* waitFor(duration);
-  yield* codeRef().selection(codeRef().findAllRanges(/Coordinate<float>::/g), duration);
-  yield* waitFor(duration);
-
-
-  yield* codeRef().selection(DEFAULT);
-  yield* waitFor(duration);
-  yield* all(
-    codeRef().code(code_cast_to, duration),
-    codeRef().fontSize(35, duration)
-  );
-  yield* waitFor(duration);
-  yield* all(
-    codeRef().code(code_cast_to_specialization, duration),
-    codeRef().fontSize(30, duration),
-    codeRef().y(-150, duration)
-  );
-  yield* waitFor(duration);
-  yield* all(
-    codeRef().fontSize(35, duration),
-    codeRef().y(-650, duration)
-  );
-  yield* all(
-    codeRef().code(code_cast_to_specialization_main, duration),
-  );
-  yield* waitFor(duration);
-
-
-
-  const is_integral_base = `
-  template <typename T>
-  struct is_integral {
-    static constexpr inline bool value{};
-  };`
-
-
-  yield* all(
-    codeRef().code(is_integral_base, 0),
-    codeRef().fontSize(45, 0),
-    codeRef().y(0, 0)
-  );
-  yield* waitFor(duration);
-
-  const is_integral_not_working = `
-  template <typename T>
-  struct is_integral {
-    static constexpr inline bool value{};
-  };
-
-  // ❌ Does not compile!
-  static_assert(is_integral<int>::value);
-  static_assert(!is_integral<double>::value);`
-
-  yield* all(
-    codeRef().code(is_integral_not_working, duration),
-  );
-  yield* waitFor(duration);
-
-  const is_integral_specialization_int = `
-  template <typename T>
-  struct is_integral {
-    static constexpr inline bool value{};
-  };
-
-  template <>
-  struct is_integral<int> {
-    static constexpr inline bool value{true};
-  };
-
-  // ✅ Compiles now!
-  static_assert(is_integral<int>::value);
-  static_assert(!is_integral<double>::value);`
-
-  yield* all(
-    codeRef().code(is_integral_specialization_int, duration),
-  );
-  yield* waitFor(duration);
-
-  const code_is_valid = `
-  #include <vector>
-
-  template<typename ScalarT>
-  [[nodiscard]] bool IsValid(const Coordinate<ScalarT>& coordinate) {
-    return true; // Actually do something useful here!
-  }
-
-  template<typename CoordinateT>
-  [[nodiscard]] bool ValidateCoordinates(const std::vector<CoordinateT>& coordinates) {
-    for (const auto& coordinate : coordinates) {
-      if (!IsValid(coordinate)) return false;
-    }
-    return true;
-  }`
-
-  yield* all(
-    codeRef().code(code_is_valid, 0),
-    codeRef().fontSize(35, 0),
-    codeRef().y(0, 0)
-  );
-  yield* waitFor(duration);
-
-  const code_is_valid_main = `
-  #include <iostream>
-  #include <vector>
-
-  template<typename ScalarT>
-  [[nodiscard]] bool IsValid(const Coordinate<ScalarT>& coordinate) {
-    return true; // Actually do something useful here!
-  }
-
-  template<typename CoordinateT>
-  [[nodiscard]] bool ValidateCoordinates(const std::vector<CoordinateT>& coordinates) {
-    for (const auto& coordinate : coordinates) {
-      if (!IsValid(coordinate)) return false;
-    }
-    return true;
-  }
-
-  int main() {
-    const std::vector<int> wrong_input{1, 2, 3};
-    std::cout << ValidateCoordinates(wrong_input) << std::endl;
-  }`
-
-  yield* all(
-    codeRef().code(code_is_valid_main, duration),
-  );
-  yield* waitFor(duration);
-
-  const code_is_valid_static_assert = `
-  #include <iostream>
-  #include <vector>
-
-  template<typename ScalarT>
-  [[nodiscard]] bool IsValid(const Coordinate<ScalarT>& coordinate) {
-    return true; // Actually do something useful here!
-  }
-
-  template<typename CoordinateT>
-  [[nodiscard]] bool ValidateCoordinates(const std::vector<CoordinateT>& coordinates) {
-    static_assert(
-      IsCoordinate<CoordinateT>::value,
-      "Contents of the container are not coordinates");
-    for (const auto& coordinate : coordinates) {
-      if (!IsValid(coordinate)) return false;
-    }
-    return true;
-  }
-
-  int main() {
-    const std::vector<int> wrong_input{1, 2, 3};
-    std::cout << ValidateCoordinates(wrong_input) << std::endl;
-  }`
-
-  yield* all(
-    codeRef().code(code_is_valid_static_assert, duration),
-    codeRef().y(-20, duration)
-  );
-  yield* waitFor(duration);
-
-  const code_is_valid_concept = `
-  #include <iostream>
-  #include <vector>
-
-  template<typename ScalarT>
-  [[nodiscard]] bool IsValid(const Coordinate<ScalarT>& coordinate) {
-    return true; // Actually do something useful here!
-  }
-
-  // Requires C++20!
-  template <CoordinateLike CoordinateT>
-  [[nodiscard]] bool ValidateCoordinates(const std::vector<CoordinateT>& coordinates) {
-    for (const auto& coordinate : coordinates) {
-      if (!IsValid(coordinate)) return false;
-    }
-    return true;
-  }
-
-  int main() {
-    const std::vector<int> wrong_input{1, 2, 3};
-    std::cout << ValidateCoordinates(wrong_input) << std::endl;
-  }`
-
-  yield* all(
-    codeRef().code(code_is_valid_concept, duration),
-    codeRef().y(-20, duration)
-  );
-  yield* waitFor(duration);
-
-  const is_coordinate = `
-  template <typename T>
-  struct IsCoordinate {
-    static constexpr inline bool value{};
-  };`
-
-  const is_coordinate_specialization = `  \n
-  template <>
-  struct IsCoordinate<Coordinate<int>> {
-    static constexpr inline bool value{true};
-  };
-
-  template <>
-  struct IsCoordinate<Coordinate<float>> {
-    static constexpr inline bool value{true};
-  };`
-
-  const is_coordinate_asserts = `  \n
-  static_assert (
-      !IsCoordinate<void>::value &&
-      !IsCoordinate<int>::value &&
-      !IsCoordinate<float>::value &&
-      IsCoordinate<Coordinate<int>>::value &&
-      IsCoordinate<Coordinate<float>>::value
-  );`
-
-  yield* all(
-    codeRef().code(is_coordinate, 0),
-    codeRef().y(0, 0)
-  );
-  yield* waitFor(duration);
-  yield* all(
-    codeRef().code.append(is_coordinate_specialization, duration),
-  );
-  yield* waitFor(duration);
-  yield* all(
-    codeRef().code.append(is_coordinate_asserts, duration),
-  );
-  yield* waitFor(duration);
-
-  const is_coordinate_partial = `
-  template <typename T>
-  struct IsCoordinate {
-    static constexpr inline bool value{};
-  };
-
-  template <typename T>
-  struct IsCoordinate<Coordinate<T>> {
-    static constexpr inline bool value{true};
-  };
-
-  static_assert (
-      !IsCoordinate<void>::value &&
-      !IsCoordinate<int>::value &&
-      !IsCoordinate<float>::value &&
-      IsCoordinate<Coordinate<int>>::value &&
-      IsCoordinate<Coordinate<float>>::value
-  );`
-
-  yield* all(
-    codeRef().code(is_coordinate_partial, duration),
-  );
-  yield* waitFor(duration);
-  yield* codeRef().selection(codeRef().findLastRange(/template <typename T>/g), duration / 2);
-  yield* waitFor(duration);
-  yield* codeRef().selection(DEFAULT, duration / 2);
-  yield* waitFor(duration);
-  yield* codeRef().selection(codeRef().findLastRange(/<Coordinate<T>/g), duration / 2);
-  yield* waitFor(duration);
-  yield* codeRef().selection(codeRef().findLastRange(/IsCoordinate<Coordinate<T>>/g), duration / 2);
-  yield* waitFor(duration);
-  yield* codeRef().selection(DEFAULT, duration / 2);
-  yield* waitFor(duration);
-  yield* codeRef().selection(codeRef().findLastRange(/typename T/g), duration / 2);
-  yield* waitFor(duration);
-  yield* codeRef().selection(codeRef().findLastRange(/Coordinate<T>/g), duration / 2);
-  yield* waitFor(duration);
-  yield* codeRef().selection(codeRef().findLastRange(/IsCoordinate<Coordinate<T>>/g), duration / 2);
-  yield* waitFor(duration);
-  yield* codeRef().selection(DEFAULT, duration / 2);
-  yield* waitFor(duration);
-  yield* codeRef().selection(codeRef().findLastRange(/IsCoordinate<Coordinate<int>>::value/g), duration / 2);
-  yield* waitFor(duration);
-  yield* codeRef().selection(lines(1, 4), duration / 2);
-  yield* waitFor(duration);
-  yield* codeRef().selection([lines(1, 4), lines(5, 9)], duration / 2);
-  yield* waitFor(duration);
-
-  yield* waitFor(duration * 3);
-});
diff --git a/animation/class_templates_why/tsconfig.json b/animation/class_templates_why/tsconfig.json
deleted file mode 100644
index e7d5347..0000000
--- a/animation/class_templates_why/tsconfig.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
-  "extends": "@motion-canvas/2d/tsconfig.project.json",
-  "include": ["src"]
-}
diff --git a/animation/class_templates_why/vite.config.ts b/animation/class_templates_why/vite.config.ts
deleted file mode 100644
index 42d9d68..0000000
--- a/animation/class_templates_why/vite.config.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import {defineConfig} from 'vite';
-import motionCanvas from '@motion-canvas/vite-plugin';
-import ffmpeg from '@motion-canvas/ffmpeg';
-
-export default defineConfig({
-  plugins: [
-    motionCanvas(),
-    ffmpeg(),
-  ],
-});
diff --git a/animation/error_handling/.gitignore b/animation/error_handling/.gitignore
deleted file mode 100644
index 829b1c7..0000000
--- a/animation/error_handling/.gitignore
+++ /dev/null
@@ -1,15 +0,0 @@
-# Generated files
-node_modules
-output
-dist
-
-# Editor directories and files
-.vscode/*
-!.vscode/extensions.json
-.idea
-.DS_Store
-*.suo
-*.ntvs*
-*.njsproj
-*.sln
-*.sw?
diff --git a/animation/error_handling/package-lock.json b/animation/error_handling/package-lock.json
deleted file mode 100644
index cc9813a..0000000
--- a/animation/error_handling/package-lock.json
+++ /dev/null
@@ -1,1492 +0,0 @@
-{
-  "name": "error_handling",
-  "version": "0.0.0",
-  "lockfileVersion": 3,
-  "requires": true,
-  "packages": {
-    "": {
-      "name": "error_handling",
-      "version": "0.0.0",
-      "dependencies": {
-        "@lezer/cpp": "^1.1.2",
-        "@motion-canvas/2d": "^3.17.2",
-        "@motion-canvas/core": "^3.17.2",
-        "@motion-canvas/ffmpeg": "^1.1.0"
-      },
-      "devDependencies": {
-        "@motion-canvas/ui": "^3.17.2",
-        "@motion-canvas/vite-plugin": "^3.17.2",
-        "typescript": "^5.2.2",
-        "vite": "^4.0.0"
-      }
-    },
-    "node_modules/@codemirror/language": {
-      "version": "6.11.1",
-      "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.11.1.tgz",
-      "integrity": "sha512-5kS1U7emOGV84vxC+ruBty5sUgcD0te6dyupyRVG2zaSjhTDM73LhVKUtVwiqSe6QwmEoA4SCiU8AKPFyumAWQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@codemirror/state": "^6.0.0",
-        "@codemirror/view": "^6.23.0",
-        "@lezer/common": "^1.1.0",
-        "@lezer/highlight": "^1.0.0",
-        "@lezer/lr": "^1.0.0",
-        "style-mod": "^4.0.0"
-      }
-    },
-    "node_modules/@codemirror/state": {
-      "version": "6.5.2",
-      "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.5.2.tgz",
-      "integrity": "sha512-FVqsPqtPWKVVL3dPSxy8wEF/ymIEuVzF1PK3VbUgrxXpJUSHQWWZz4JMToquRxnkw+36LTamCZG2iua2Ptq0fA==",
-      "license": "MIT",
-      "dependencies": {
-        "@marijn/find-cluster-break": "^1.0.0"
-      }
-    },
-    "node_modules/@codemirror/view": {
-      "version": "6.37.2",
-      "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.37.2.tgz",
-      "integrity": "sha512-XD3LdgQpxQs5jhOOZ2HRVT+Rj59O4Suc7g2ULvZ+Yi8eCkickrkZ5JFuoDhs2ST1mNI5zSsNYgR3NGa4OUrbnw==",
-      "license": "MIT",
-      "dependencies": {
-        "@codemirror/state": "^6.5.0",
-        "crelt": "^1.0.6",
-        "style-mod": "^4.1.0",
-        "w3c-keyname": "^2.2.4"
-      }
-    },
-    "node_modules/@esbuild/android-arm": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
-      "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==",
-      "cpu": [
-        "arm"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/android-arm64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz",
-      "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==",
-      "cpu": [
-        "arm64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/android-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz",
-      "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==",
-      "cpu": [
-        "x64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/darwin-arm64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz",
-      "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==",
-      "cpu": [
-        "arm64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/darwin-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz",
-      "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==",
-      "cpu": [
-        "x64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/freebsd-arm64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz",
-      "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==",
-      "cpu": [
-        "arm64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "freebsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/freebsd-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz",
-      "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==",
-      "cpu": [
-        "x64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "freebsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-arm": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz",
-      "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==",
-      "cpu": [
-        "arm"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-arm64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz",
-      "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==",
-      "cpu": [
-        "arm64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-ia32": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz",
-      "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==",
-      "cpu": [
-        "ia32"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-loong64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz",
-      "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==",
-      "cpu": [
-        "loong64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-mips64el": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz",
-      "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==",
-      "cpu": [
-        "mips64el"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-ppc64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz",
-      "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==",
-      "cpu": [
-        "ppc64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-riscv64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz",
-      "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==",
-      "cpu": [
-        "riscv64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-s390x": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz",
-      "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==",
-      "cpu": [
-        "s390x"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz",
-      "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==",
-      "cpu": [
-        "x64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/netbsd-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz",
-      "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==",
-      "cpu": [
-        "x64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "netbsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/openbsd-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz",
-      "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==",
-      "cpu": [
-        "x64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "openbsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/sunos-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz",
-      "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==",
-      "cpu": [
-        "x64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "sunos"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/win32-arm64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz",
-      "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==",
-      "cpu": [
-        "arm64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/win32-ia32": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz",
-      "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==",
-      "cpu": [
-        "ia32"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/win32-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz",
-      "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==",
-      "cpu": [
-        "x64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@ffmpeg-installer/darwin-arm64": {
-      "version": "4.1.5",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/darwin-arm64/-/darwin-arm64-4.1.5.tgz",
-      "integrity": "sha512-hYqTiP63mXz7wSQfuqfFwfLOfwwFChUedeCVKkBtl/cliaTM7/ePI9bVzfZ2c+dWu3TqCwLDRWNSJ5pqZl8otA==",
-      "cpu": [
-        "arm64"
-      ],
-      "hasInstallScript": true,
-      "license": "https://git.ffmpeg.org/gitweb/ffmpeg.git/blob_plain/HEAD:/LICENSE.md",
-      "optional": true,
-      "os": [
-        "darwin"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/darwin-x64": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/darwin-x64/-/darwin-x64-4.1.0.tgz",
-      "integrity": "sha512-Z4EyG3cIFjdhlY8wI9aLUXuH8nVt7E9SlMVZtWvSPnm2sm37/yC2CwjUzyCQbJbySnef1tQwGG2Sx+uWhd9IAw==",
-      "cpu": [
-        "x64"
-      ],
-      "hasInstallScript": true,
-      "license": "LGPL-2.1",
-      "optional": true,
-      "os": [
-        "darwin"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/ffmpeg": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/ffmpeg/-/ffmpeg-1.1.0.tgz",
-      "integrity": "sha512-Uq4rmwkdGxIa9A6Bd/VqqYbT7zqh1GrT5/rFwCwKM70b42W5gIjWeVETq6SdcL0zXqDtY081Ws/iJWhr1+xvQg==",
-      "license": "LGPL-2.1",
-      "optionalDependencies": {
-        "@ffmpeg-installer/darwin-arm64": "4.1.5",
-        "@ffmpeg-installer/darwin-x64": "4.1.0",
-        "@ffmpeg-installer/linux-arm": "4.1.3",
-        "@ffmpeg-installer/linux-arm64": "4.1.4",
-        "@ffmpeg-installer/linux-ia32": "4.1.0",
-        "@ffmpeg-installer/linux-x64": "4.1.0",
-        "@ffmpeg-installer/win32-ia32": "4.1.0",
-        "@ffmpeg-installer/win32-x64": "4.1.0"
-      }
-    },
-    "node_modules/@ffmpeg-installer/linux-arm": {
-      "version": "4.1.3",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/linux-arm/-/linux-arm-4.1.3.tgz",
-      "integrity": "sha512-NDf5V6l8AfzZ8WzUGZ5mV8O/xMzRag2ETR6+TlGIsMHp81agx51cqpPItXPib/nAZYmo55Bl2L6/WOMI3A5YRg==",
-      "cpu": [
-        "arm"
-      ],
-      "hasInstallScript": true,
-      "license": "GPLv3",
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/linux-arm64": {
-      "version": "4.1.4",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/linux-arm64/-/linux-arm64-4.1.4.tgz",
-      "integrity": "sha512-dljEqAOD0oIM6O6DxBW9US/FkvqvQwgJ2lGHOwHDDwu/pX8+V0YsDL1xqHbj1DMX/+nP9rxw7G7gcUvGspSoKg==",
-      "cpu": [
-        "arm64"
-      ],
-      "hasInstallScript": true,
-      "license": "GPLv3",
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/linux-ia32": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/linux-ia32/-/linux-ia32-4.1.0.tgz",
-      "integrity": "sha512-0LWyFQnPf+Ij9GQGD034hS6A90URNu9HCtQ5cTqo5MxOEc7Rd8gLXrJvn++UmxhU0J5RyRE9KRYstdCVUjkNOQ==",
-      "cpu": [
-        "ia32"
-      ],
-      "hasInstallScript": true,
-      "license": "GPLv3",
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/linux-x64": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/linux-x64/-/linux-x64-4.1.0.tgz",
-      "integrity": "sha512-Y5BWhGLU/WpQjOArNIgXD3z5mxxdV8c41C+U15nsE5yF8tVcdCGet5zPs5Zy3Ta6bU7haGpIzryutqCGQA/W8A==",
-      "cpu": [
-        "x64"
-      ],
-      "hasInstallScript": true,
-      "license": "GPLv3",
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/win32-ia32": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/win32-ia32/-/win32-ia32-4.1.0.tgz",
-      "integrity": "sha512-FV2D7RlaZv/lrtdhaQ4oETwoFUsUjlUiasiZLDxhEUPdNDWcH1OU9K1xTvqz+OXLdsmYelUDuBS/zkMOTtlUAw==",
-      "cpu": [
-        "ia32"
-      ],
-      "license": "GPLv3",
-      "optional": true,
-      "os": [
-        "win32"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/win32-x64": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/win32-x64/-/win32-x64-4.1.0.tgz",
-      "integrity": "sha512-Drt5u2vzDnIONf4ZEkKtFlbvwj6rI3kxw1Ck9fpudmtgaZIHD4ucsWB2lCZBXRxJgXR+2IMSti+4rtM4C4rXgg==",
-      "cpu": [
-        "x64"
-      ],
-      "license": "GPLv3",
-      "optional": true,
-      "os": [
-        "win32"
-      ]
-    },
-    "node_modules/@ffprobe-installer/darwin-arm64": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/darwin-arm64/-/darwin-arm64-5.0.1.tgz",
-      "integrity": "sha512-vwNCNjokH8hfkbl6m95zICHwkSzhEvDC3GVBcUp5HX8+4wsX10SP3B+bGur7XUzTIZ4cQpgJmEIAx6TUwRepMg==",
-      "cpu": [
-        "arm64"
-      ],
-      "hasInstallScript": true,
-      "license": "LGPL-2.1",
-      "optional": true,
-      "os": [
-        "darwin"
-      ]
-    },
-    "node_modules/@ffprobe-installer/darwin-x64": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/darwin-x64/-/darwin-x64-5.1.0.tgz",
-      "integrity": "sha512-J+YGscZMpQclFg31O4cfVRGmDpkVsQ2fZujoUdMAAYcP0NtqpC49Hs3SWJpBdsGB4VeqOt5TTm1vSZQzs1NkhA==",
-      "cpu": [
-        "x64"
-      ],
-      "hasInstallScript": true,
-      "license": "GPL-3.0",
-      "optional": true,
-      "os": [
-        "darwin"
-      ]
-    },
-    "node_modules/@ffprobe-installer/ffprobe": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/ffprobe/-/ffprobe-2.1.2.tgz",
-      "integrity": "sha512-ZNvwk4f2magF42Zji2Ese16SMj9BS7Fui4kRjg6gTYTxY3gWZNpg85n4MIfQyI9nimHg4x/gT6FVkp/bBDuBwg==",
-      "license": "LGPL-2.1",
-      "engines": {
-        "node": ">=14.21.2"
-      },
-      "optionalDependencies": {
-        "@ffprobe-installer/darwin-arm64": "5.0.1",
-        "@ffprobe-installer/darwin-x64": "5.1.0",
-        "@ffprobe-installer/linux-arm": "5.2.0",
-        "@ffprobe-installer/linux-arm64": "5.2.0",
-        "@ffprobe-installer/linux-ia32": "5.2.0",
-        "@ffprobe-installer/linux-x64": "5.2.0",
-        "@ffprobe-installer/win32-ia32": "5.1.0",
-        "@ffprobe-installer/win32-x64": "5.1.0"
-      }
-    },
-    "node_modules/@ffprobe-installer/linux-arm": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/linux-arm/-/linux-arm-5.2.0.tgz",
-      "integrity": "sha512-PF5HqEhCY7WTWHtLDYbA/+rLS+rhslWvyBlAG1Fk8VzVlnRdl93o6hy7DE2kJgxWQbFaR3ZktPQGEzfkrmQHvQ==",
-      "cpu": [
-        "arm"
-      ],
-      "hasInstallScript": true,
-      "license": "GPL-3.0",
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffprobe-installer/linux-arm64": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/linux-arm64/-/linux-arm64-5.2.0.tgz",
-      "integrity": "sha512-X1VvWtlLs6ScP73biVLuHD5ohKJKsMTa0vafCESOen4mOoNeLAYbxOVxDWAdFz9cpZgRiloFj5QD6nDj8E28yQ==",
-      "cpu": [
-        "arm64"
-      ],
-      "hasInstallScript": true,
-      "license": "GPL-3.0",
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffprobe-installer/linux-ia32": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/linux-ia32/-/linux-ia32-5.2.0.tgz",
-      "integrity": "sha512-TFVK5sasXyXhbIG7LtPRDmtkrkOsInwKcL43iEvEw+D9vCS2rc//mn9/0Q+BR0UoJEiMK4+ApYr/3LLVUBPOCQ==",
-      "cpu": [
-        "ia32"
-      ],
-      "hasInstallScript": true,
-      "license": "GPL-3.0",
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffprobe-installer/linux-x64": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/linux-x64/-/linux-x64-5.2.0.tgz",
-      "integrity": "sha512-D3UeqTLYPNs7pBWPLUYGehPdRVqU8eACox4OZy3pZUZatxye2YKlvBwEfaLdL1v2Z4FOAlLUhms0kY8m8kqSRA==",
-      "cpu": [
-        "x64"
-      ],
-      "hasInstallScript": true,
-      "license": "GPL-3.0",
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffprobe-installer/win32-ia32": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/win32-ia32/-/win32-ia32-5.1.0.tgz",
-      "integrity": "sha512-5O3vOoNRxmut0/Nu9vSazTdSHasrr+zPT2B3Hm7kjmO3QVFcIfVImS6ReQnZeSy8JPJOqXts5kX5x/3KOX54XQ==",
-      "cpu": [
-        "ia32"
-      ],
-      "license": "GPL-3.0",
-      "optional": true,
-      "os": [
-        "win32"
-      ]
-    },
-    "node_modules/@ffprobe-installer/win32-x64": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/win32-x64/-/win32-x64-5.1.0.tgz",
-      "integrity": "sha512-jMGYeAgkrdn4e2vvYt/qakgHRE3CPju4bn5TmdPfoAm1BlX1mY9cyMd8gf5vSzI8gH8Zq5WQAyAkmekX/8TSTg==",
-      "cpu": [
-        "x64"
-      ],
-      "license": "GPL-3.0",
-      "optional": true,
-      "os": [
-        "win32"
-      ]
-    },
-    "node_modules/@lezer/common": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.2.3.tgz",
-      "integrity": "sha512-w7ojc8ejBqr2REPsWxJjrMFsA/ysDCFICn8zEOR9mrqzOu2amhITYuLD8ag6XZf0CFXDrhKqw7+tW8cX66NaDA==",
-      "license": "MIT"
-    },
-    "node_modules/@lezer/cpp": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/@lezer/cpp/-/cpp-1.1.3.tgz",
-      "integrity": "sha512-ykYvuFQKGsRi6IcE+/hCSGUhb/I4WPjd3ELhEblm2wS2cOznDFzO+ubK2c+ioysOnlZ3EduV+MVQFCPzAIoY3w==",
-      "license": "MIT",
-      "dependencies": {
-        "@lezer/common": "^1.2.0",
-        "@lezer/highlight": "^1.0.0",
-        "@lezer/lr": "^1.0.0"
-      }
-    },
-    "node_modules/@lezer/highlight": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.1.tgz",
-      "integrity": "sha512-Z5duk4RN/3zuVO7Jq0pGLJ3qynpxUVsh7IbUbGj88+uV2ApSAn6kWg2au3iJb+0Zi7kKtqffIESgNcRXWZWmSA==",
-      "license": "MIT",
-      "dependencies": {
-        "@lezer/common": "^1.0.0"
-      }
-    },
-    "node_modules/@lezer/lr": {
-      "version": "1.4.2",
-      "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.2.tgz",
-      "integrity": "sha512-pu0K1jCIdnQ12aWNaAVU5bzi7Bd1w54J3ECgANPmYLtQKP0HBj2cE/5coBD66MT10xbtIuUr7tg0Shbsvk0mDA==",
-      "license": "MIT",
-      "dependencies": {
-        "@lezer/common": "^1.0.0"
-      }
-    },
-    "node_modules/@marijn/find-cluster-break": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/@marijn/find-cluster-break/-/find-cluster-break-1.0.2.tgz",
-      "integrity": "sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==",
-      "license": "MIT"
-    },
-    "node_modules/@motion-canvas/2d": {
-      "version": "3.17.2",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/2d/-/2d-3.17.2.tgz",
-      "integrity": "sha512-Q2DMYSmJMTN8vvLcpofHEMuYEjx60z4hjlwbWJnWx3xnb7DU5suovJ47qM2sk46al/RDXJIz6rfALTr33brKaw==",
-      "license": "MIT",
-      "dependencies": {
-        "@codemirror/language": "^6.10.1",
-        "@lezer/common": "^1.2.1",
-        "@lezer/highlight": "^1.2.0",
-        "@motion-canvas/core": "^3.17.2",
-        "code-fns": "^0.8.2",
-        "mathjax-full": "^3.2.2",
-        "parse-svg-path": "^0.1.2"
-      }
-    },
-    "node_modules/@motion-canvas/core": {
-      "version": "3.17.2",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/core/-/core-3.17.2.tgz",
-      "integrity": "sha512-9M4NxNVR9LLxZ+ykTznMcbMlKjbe2NkmDIlFDl2uOyVkK5wFiRwF7k13a1I/n3BVxJJoKPt9UOQF/wn3LrBXJA==",
-      "license": "MIT",
-      "dependencies": {
-        "@types/chroma-js": "2.4.4",
-        "chroma-js": "2.4.2"
-      }
-    },
-    "node_modules/@motion-canvas/ffmpeg": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/ffmpeg/-/ffmpeg-1.1.1.tgz",
-      "integrity": "sha512-w2d7oFfR3hYHXeYtFGoHp6goY+vVL0LoZ2h1b/veTH5KvE7jrLp2Kl/XPHsYJ5ZDRHUT0Nhl05DBLdXYqdSqgg==",
-      "license": "MIT",
-      "dependencies": {
-        "@ffmpeg-installer/ffmpeg": "^1.1.0",
-        "@ffprobe-installer/ffprobe": "^2.0.0",
-        "fluent-ffmpeg": "^2.1.2"
-      },
-      "peerDependencies": {
-        "@motion-canvas/core": "^3.7.0",
-        "@motion-canvas/vite-plugin": "^3.7.0",
-        "vite": "4.x"
-      }
-    },
-    "node_modules/@motion-canvas/ui": {
-      "version": "3.17.2",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/ui/-/ui-3.17.2.tgz",
-      "integrity": "sha512-gbsdbFP60IhgckZei7NDuqQWekfLX+mUjyYpAEOe4OZSyIhoavZo+jako+liD9E7+dYu67E9YRjT+/BesLV7Pg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@motion-canvas/core": "^3.17.2",
-        "@preact/signals": "^1.2.1",
-        "preact": "^10.19.2"
-      }
-    },
-    "node_modules/@motion-canvas/vite-plugin": {
-      "version": "3.17.2",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/vite-plugin/-/vite-plugin-3.17.2.tgz",
-      "integrity": "sha512-7XrGFoyS6XWdvQN9J6Ch8ehLWD3eBX+sv4L6xxH5As5kF5YA+1MAPZ+QxMNUCcW0tp1VjE+rQkQWsZfXa7BR/g==",
-      "license": "MIT",
-      "dependencies": {
-        "fast-glob": "^3.3.1",
-        "follow-redirects": "^1.15.2",
-        "mime-types": "^2.1.35",
-        "source-map": "^0.6.1"
-      },
-      "peerDependencies": {
-        "vite": "4.x || 5.x"
-      }
-    },
-    "node_modules/@nodelib/fs.scandir": {
-      "version": "2.1.5",
-      "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
-      "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
-      "license": "MIT",
-      "dependencies": {
-        "@nodelib/fs.stat": "2.0.5",
-        "run-parallel": "^1.1.9"
-      },
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/@nodelib/fs.stat": {
-      "version": "2.0.5",
-      "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
-      "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
-      "license": "MIT",
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/@nodelib/fs.walk": {
-      "version": "1.2.8",
-      "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
-      "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
-      "license": "MIT",
-      "dependencies": {
-        "@nodelib/fs.scandir": "2.1.5",
-        "fastq": "^1.6.0"
-      },
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/@preact/signals": {
-      "version": "1.3.2",
-      "resolved": "https://registry.npmjs.org/@preact/signals/-/signals-1.3.2.tgz",
-      "integrity": "sha512-naxcJgUJ6BTOROJ7C3QML7KvwKwCXQJYTc5L/b0eEsdYgPB6SxwoQ1vDGcS0Q7GVjAenVq/tXrybVdFShHYZWg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@preact/signals-core": "^1.7.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/preact"
-      },
-      "peerDependencies": {
-        "preact": "10.x"
-      }
-    },
-    "node_modules/@preact/signals-core": {
-      "version": "1.10.0",
-      "resolved": "https://registry.npmjs.org/@preact/signals-core/-/signals-core-1.10.0.tgz",
-      "integrity": "sha512-qlKeXlfqtlC+sjxCPHt6Sk0/dXBrKZVcPlianqjNc/vW263YBFiP5mRrgKpHoO0q222Thm1TdYQWfCKpbbgvwA==",
-      "dev": true,
-      "license": "MIT",
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/preact"
-      }
-    },
-    "node_modules/@types/chroma-js": {
-      "version": "2.4.4",
-      "resolved": "https://registry.npmjs.org/@types/chroma-js/-/chroma-js-2.4.4.tgz",
-      "integrity": "sha512-/DTccpHTaKomqussrn+ciEvfW4k6NAHzNzs/sts1TCqg333qNxOhy8TNIoQCmbGG3Tl8KdEhkGAssb1n3mTXiQ==",
-      "license": "MIT"
-    },
-    "node_modules/@types/hast": {
-      "version": "2.3.10",
-      "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz",
-      "integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==",
-      "license": "MIT",
-      "dependencies": {
-        "@types/unist": "^2"
-      }
-    },
-    "node_modules/@types/unist": {
-      "version": "2.0.11",
-      "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz",
-      "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==",
-      "license": "MIT"
-    },
-    "node_modules/@wooorm/starry-night": {
-      "version": "1.7.0",
-      "resolved": "https://registry.npmjs.org/@wooorm/starry-night/-/starry-night-1.7.0.tgz",
-      "integrity": "sha512-ktO0nkddrovIoNW2jAUT+Cdd9n1bWjy1Ir4CdcmgTaT6E94HLlQfu7Yv62falclBEwvsuVp3bSBw23wtta1fNw==",
-      "license": "MIT",
-      "dependencies": {
-        "@types/hast": "^2.0.0",
-        "import-meta-resolve": "^2.0.0",
-        "vscode-oniguruma": "^1.0.0",
-        "vscode-textmate": "^9.0.0"
-      },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/wooorm"
-      }
-    },
-    "node_modules/@xmldom/xmldom": {
-      "version": "0.9.8",
-      "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.9.8.tgz",
-      "integrity": "sha512-p96FSY54r+WJ50FIOsCOjyj/wavs8921hG5+kVMmZgKcvIKxMXHTrjNJvRgWa/zuX3B6t2lijLNFaOyuxUH+2A==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=14.6"
-      }
-    },
-    "node_modules/async": {
-      "version": "0.2.10",
-      "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz",
-      "integrity": "sha512-eAkdoKxU6/LkKDBzLpT+t6Ff5EtfSF4wx1WfJiPEEV7WNLnDaRXk0oVysiEPm262roaachGexwUv94WhSgN5TQ=="
-    },
-    "node_modules/braces": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
-      "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
-      "license": "MIT",
-      "dependencies": {
-        "fill-range": "^7.1.1"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/chroma-js": {
-      "version": "2.4.2",
-      "resolved": "https://registry.npmjs.org/chroma-js/-/chroma-js-2.4.2.tgz",
-      "integrity": "sha512-U9eDw6+wt7V8z5NncY2jJfZa+hUH8XEj8FQHgFJTrUFnJfXYf4Ml4adI2vXZOjqRDpFWtYVWypDfZwnJ+HIR4A==",
-      "license": "(BSD-3-Clause AND Apache-2.0)"
-    },
-    "node_modules/code-fns": {
-      "version": "0.8.2",
-      "resolved": "https://registry.npmjs.org/code-fns/-/code-fns-0.8.2.tgz",
-      "integrity": "sha512-3VVeq3cnWxWiWKFLsVo+XWsOXBSW2gAx2uv0ViETLNmNuygEPHlCeDAv/Zy7xXqPgXtgLZyvIJZmx+ojTgOIGA==",
-      "license": "MIT",
-      "dependencies": {
-        "@wooorm/starry-night": "^1.2.0"
-      }
-    },
-    "node_modules/commander": {
-      "version": "13.1.0",
-      "resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz",
-      "integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/crelt": {
-      "version": "1.0.6",
-      "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz",
-      "integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==",
-      "license": "MIT"
-    },
-    "node_modules/esbuild": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz",
-      "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==",
-      "hasInstallScript": true,
-      "license": "MIT",
-      "bin": {
-        "esbuild": "bin/esbuild"
-      },
-      "engines": {
-        "node": ">=12"
-      },
-      "optionalDependencies": {
-        "@esbuild/android-arm": "0.18.20",
-        "@esbuild/android-arm64": "0.18.20",
-        "@esbuild/android-x64": "0.18.20",
-        "@esbuild/darwin-arm64": "0.18.20",
-        "@esbuild/darwin-x64": "0.18.20",
-        "@esbuild/freebsd-arm64": "0.18.20",
-        "@esbuild/freebsd-x64": "0.18.20",
-        "@esbuild/linux-arm": "0.18.20",
-        "@esbuild/linux-arm64": "0.18.20",
-        "@esbuild/linux-ia32": "0.18.20",
-        "@esbuild/linux-loong64": "0.18.20",
-        "@esbuild/linux-mips64el": "0.18.20",
-        "@esbuild/linux-ppc64": "0.18.20",
-        "@esbuild/linux-riscv64": "0.18.20",
-        "@esbuild/linux-s390x": "0.18.20",
-        "@esbuild/linux-x64": "0.18.20",
-        "@esbuild/netbsd-x64": "0.18.20",
-        "@esbuild/openbsd-x64": "0.18.20",
-        "@esbuild/sunos-x64": "0.18.20",
-        "@esbuild/win32-arm64": "0.18.20",
-        "@esbuild/win32-ia32": "0.18.20",
-        "@esbuild/win32-x64": "0.18.20"
-      }
-    },
-    "node_modules/esm": {
-      "version": "3.2.25",
-      "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz",
-      "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/fast-glob": {
-      "version": "3.3.3",
-      "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
-      "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
-      "license": "MIT",
-      "dependencies": {
-        "@nodelib/fs.stat": "^2.0.2",
-        "@nodelib/fs.walk": "^1.2.3",
-        "glob-parent": "^5.1.2",
-        "merge2": "^1.3.0",
-        "micromatch": "^4.0.8"
-      },
-      "engines": {
-        "node": ">=8.6.0"
-      }
-    },
-    "node_modules/fastq": {
-      "version": "1.19.1",
-      "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz",
-      "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==",
-      "license": "ISC",
-      "dependencies": {
-        "reusify": "^1.0.4"
-      }
-    },
-    "node_modules/fill-range": {
-      "version": "7.1.1",
-      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
-      "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
-      "license": "MIT",
-      "dependencies": {
-        "to-regex-range": "^5.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/fluent-ffmpeg": {
-      "version": "2.1.3",
-      "resolved": "https://registry.npmjs.org/fluent-ffmpeg/-/fluent-ffmpeg-2.1.3.tgz",
-      "integrity": "sha512-Be3narBNt2s6bsaqP6Jzq91heDgOEaDCJAXcE3qcma/EJBSy5FB4cvO31XBInuAuKBx8Kptf8dkhjK0IOru39Q==",
-      "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.",
-      "license": "MIT",
-      "dependencies": {
-        "async": "^0.2.9",
-        "which": "^1.1.1"
-      },
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/follow-redirects": {
-      "version": "1.15.9",
-      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
-      "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
-      "funding": [
-        {
-          "type": "individual",
-          "url": "https://github.com/sponsors/RubenVerborgh"
-        }
-      ],
-      "license": "MIT",
-      "engines": {
-        "node": ">=4.0"
-      },
-      "peerDependenciesMeta": {
-        "debug": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/fsevents": {
-      "version": "2.3.3",
-      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
-      "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
-      "hasInstallScript": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
-      }
-    },
-    "node_modules/glob-parent": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
-      "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
-      "license": "ISC",
-      "dependencies": {
-        "is-glob": "^4.0.1"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "node_modules/import-meta-resolve": {
-      "version": "2.2.2",
-      "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-2.2.2.tgz",
-      "integrity": "sha512-f8KcQ1D80V7RnqVm+/lirO9zkOxjGxhaTC1IPrBGd3MEfNgmNG67tSUO9gTi2F3Blr2Az6g1vocaxzkVnWl9MA==",
-      "license": "MIT",
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/wooorm"
-      }
-    },
-    "node_modules/is-extglob": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
-      "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/is-glob": {
-      "version": "4.0.3",
-      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
-      "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
-      "license": "MIT",
-      "dependencies": {
-        "is-extglob": "^2.1.1"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/is-number": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
-      "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=0.12.0"
-      }
-    },
-    "node_modules/isexe": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
-      "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
-      "license": "ISC"
-    },
-    "node_modules/mathjax-full": {
-      "version": "3.2.2",
-      "resolved": "https://registry.npmjs.org/mathjax-full/-/mathjax-full-3.2.2.tgz",
-      "integrity": "sha512-+LfG9Fik+OuI8SLwsiR02IVdjcnRCy5MufYLi0C3TdMT56L/pjB0alMVGgoWJF8pN9Rc7FESycZB9BMNWIid5w==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "esm": "^3.2.25",
-        "mhchemparser": "^4.1.0",
-        "mj-context-menu": "^0.6.1",
-        "speech-rule-engine": "^4.0.6"
-      }
-    },
-    "node_modules/merge2": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
-      "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
-      "license": "MIT",
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/mhchemparser": {
-      "version": "4.2.1",
-      "resolved": "https://registry.npmjs.org/mhchemparser/-/mhchemparser-4.2.1.tgz",
-      "integrity": "sha512-kYmyrCirqJf3zZ9t/0wGgRZ4/ZJw//VwaRVGA75C4nhE60vtnIzhl9J9ndkX/h6hxSN7pjg/cE0VxbnNM+bnDQ==",
-      "license": "Apache-2.0"
-    },
-    "node_modules/micromatch": {
-      "version": "4.0.8",
-      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
-      "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
-      "license": "MIT",
-      "dependencies": {
-        "braces": "^3.0.3",
-        "picomatch": "^2.3.1"
-      },
-      "engines": {
-        "node": ">=8.6"
-      }
-    },
-    "node_modules/mime-db": {
-      "version": "1.52.0",
-      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
-      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
-      "license": "MIT",
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/mime-types": {
-      "version": "2.1.35",
-      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
-      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
-      "license": "MIT",
-      "dependencies": {
-        "mime-db": "1.52.0"
-      },
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/mj-context-menu": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/mj-context-menu/-/mj-context-menu-0.6.1.tgz",
-      "integrity": "sha512-7NO5s6n10TIV96d4g2uDpG7ZDpIhMh0QNfGdJw/W47JswFcosz457wqz/b5sAKvl12sxINGFCn80NZHKwxQEXA==",
-      "license": "Apache-2.0"
-    },
-    "node_modules/nanoid": {
-      "version": "3.3.11",
-      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
-      "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/ai"
-        }
-      ],
-      "license": "MIT",
-      "bin": {
-        "nanoid": "bin/nanoid.cjs"
-      },
-      "engines": {
-        "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
-      }
-    },
-    "node_modules/parse-svg-path": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/parse-svg-path/-/parse-svg-path-0.1.2.tgz",
-      "integrity": "sha512-JyPSBnkTJ0AI8GGJLfMXvKq42cj5c006fnLz6fXy6zfoVjJizi8BNTpu8on8ziI1cKy9d9DGNuY17Ce7wuejpQ==",
-      "license": "MIT"
-    },
-    "node_modules/picocolors": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
-      "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
-      "license": "ISC"
-    },
-    "node_modules/picomatch": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
-      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=8.6"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/jonschlinkert"
-      }
-    },
-    "node_modules/postcss": {
-      "version": "8.5.6",
-      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
-      "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
-      "funding": [
-        {
-          "type": "opencollective",
-          "url": "https://opencollective.com/postcss/"
-        },
-        {
-          "type": "tidelift",
-          "url": "https://tidelift.com/funding/github/npm/postcss"
-        },
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/ai"
-        }
-      ],
-      "license": "MIT",
-      "dependencies": {
-        "nanoid": "^3.3.11",
-        "picocolors": "^1.1.1",
-        "source-map-js": "^1.2.1"
-      },
-      "engines": {
-        "node": "^10 || ^12 || >=14"
-      }
-    },
-    "node_modules/preact": {
-      "version": "10.26.9",
-      "resolved": "https://registry.npmjs.org/preact/-/preact-10.26.9.tgz",
-      "integrity": "sha512-SSjF9vcnF27mJK1XyFMNJzFd5u3pQiATFqoaDy03XuN00u4ziveVVEGt5RKJrDR8MHE/wJo9Nnad56RLzS2RMA==",
-      "dev": true,
-      "license": "MIT",
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/preact"
-      }
-    },
-    "node_modules/queue-microtask": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
-      "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/feross"
-        },
-        {
-          "type": "patreon",
-          "url": "https://www.patreon.com/feross"
-        },
-        {
-          "type": "consulting",
-          "url": "https://feross.org/support"
-        }
-      ],
-      "license": "MIT"
-    },
-    "node_modules/reusify": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
-      "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
-      "license": "MIT",
-      "engines": {
-        "iojs": ">=1.0.0",
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/rollup": {
-      "version": "3.29.5",
-      "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.5.tgz",
-      "integrity": "sha512-GVsDdsbJzzy4S/v3dqWPJ7EfvZJfCHiDqe80IyrF59LYuP+e6U1LJoUqeuqRbwAWoMNoXivMNeNAOf5E22VA1w==",
-      "license": "MIT",
-      "bin": {
-        "rollup": "dist/bin/rollup"
-      },
-      "engines": {
-        "node": ">=14.18.0",
-        "npm": ">=8.0.0"
-      },
-      "optionalDependencies": {
-        "fsevents": "~2.3.2"
-      }
-    },
-    "node_modules/run-parallel": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
-      "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/feross"
-        },
-        {
-          "type": "patreon",
-          "url": "https://www.patreon.com/feross"
-        },
-        {
-          "type": "consulting",
-          "url": "https://feross.org/support"
-        }
-      ],
-      "license": "MIT",
-      "dependencies": {
-        "queue-microtask": "^1.2.2"
-      }
-    },
-    "node_modules/source-map": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
-      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
-      "license": "BSD-3-Clause",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/source-map-js": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
-      "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
-      "license": "BSD-3-Clause",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/speech-rule-engine": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmjs.org/speech-rule-engine/-/speech-rule-engine-4.1.2.tgz",
-      "integrity": "sha512-S6ji+flMEga+1QU79NDbwZ8Ivf0S/MpupQQiIC0rTpU/ZTKgcajijJJb1OcByBQDjrXCN1/DJtGz4ZJeBMPGJw==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@xmldom/xmldom": "0.9.8",
-        "commander": "13.1.0",
-        "wicked-good-xpath": "1.3.0"
-      },
-      "bin": {
-        "sre": "bin/sre"
-      }
-    },
-    "node_modules/style-mod": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.2.tgz",
-      "integrity": "sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==",
-      "license": "MIT"
-    },
-    "node_modules/to-regex-range": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
-      "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
-      "license": "MIT",
-      "dependencies": {
-        "is-number": "^7.0.0"
-      },
-      "engines": {
-        "node": ">=8.0"
-      }
-    },
-    "node_modules/typescript": {
-      "version": "5.8.3",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
-      "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
-      "dev": true,
-      "license": "Apache-2.0",
-      "bin": {
-        "tsc": "bin/tsc",
-        "tsserver": "bin/tsserver"
-      },
-      "engines": {
-        "node": ">=14.17"
-      }
-    },
-    "node_modules/vite": {
-      "version": "4.5.14",
-      "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.14.tgz",
-      "integrity": "sha512-+v57oAaoYNnO3hIu5Z/tJRZjq5aHM2zDve9YZ8HngVHbhk66RStobhb1sqPMIPEleV6cNKYK4eGrAbE9Ulbl2g==",
-      "license": "MIT",
-      "dependencies": {
-        "esbuild": "^0.18.10",
-        "postcss": "^8.4.27",
-        "rollup": "^3.27.1"
-      },
-      "bin": {
-        "vite": "bin/vite.js"
-      },
-      "engines": {
-        "node": "^14.18.0 || >=16.0.0"
-      },
-      "funding": {
-        "url": "https://github.com/vitejs/vite?sponsor=1"
-      },
-      "optionalDependencies": {
-        "fsevents": "~2.3.2"
-      },
-      "peerDependencies": {
-        "@types/node": ">= 14",
-        "less": "*",
-        "lightningcss": "^1.21.0",
-        "sass": "*",
-        "stylus": "*",
-        "sugarss": "*",
-        "terser": "^5.4.0"
-      },
-      "peerDependenciesMeta": {
-        "@types/node": {
-          "optional": true
-        },
-        "less": {
-          "optional": true
-        },
-        "lightningcss": {
-          "optional": true
-        },
-        "sass": {
-          "optional": true
-        },
-        "stylus": {
-          "optional": true
-        },
-        "sugarss": {
-          "optional": true
-        },
-        "terser": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/vscode-oniguruma": {
-      "version": "1.7.0",
-      "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz",
-      "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==",
-      "license": "MIT"
-    },
-    "node_modules/vscode-textmate": {
-      "version": "9.2.0",
-      "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-9.2.0.tgz",
-      "integrity": "sha512-rkvG4SraZQaPSN/5XjwKswdU0OP9MF28QjrYzUBbhb8QyG3ljB1Ky996m++jiI7KdiAP2CkBiQZd9pqEDTClqA==",
-      "license": "MIT"
-    },
-    "node_modules/w3c-keyname": {
-      "version": "2.2.8",
-      "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz",
-      "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==",
-      "license": "MIT"
-    },
-    "node_modules/which": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
-      "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
-      "license": "ISC",
-      "dependencies": {
-        "isexe": "^2.0.0"
-      },
-      "bin": {
-        "which": "bin/which"
-      }
-    },
-    "node_modules/wicked-good-xpath": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/wicked-good-xpath/-/wicked-good-xpath-1.3.0.tgz",
-      "integrity": "sha512-Gd9+TUn5nXdwj/hFsPVx5cuHHiF5Bwuc30jZ4+ronF1qHK5O7HD0sgmXWSEgwKquT3ClLoKPVbO6qGwVwLzvAw==",
-      "license": "MIT"
-    }
-  }
-}
diff --git a/animation/error_handling/package.json b/animation/error_handling/package.json
deleted file mode 100644
index 0d7e59a..0000000
--- a/animation/error_handling/package.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
-  "name": "error_handling",
-  "private": true,
-  "version": "0.0.0",
-  "scripts": {
-    "start": "vite",
-    "serve": "vite",
-    "build": "tsc && vite build"
-  },
-  "dependencies": {
-    "@lezer/cpp": "^1.1.2",
-    "@motion-canvas/core": "^3.17.2",
-    "@motion-canvas/2d": "^3.17.2",
-    "@motion-canvas/ffmpeg": "^1.1.0"
-  },
-  "devDependencies": {
-    "@motion-canvas/ui": "^3.17.2",
-    "@motion-canvas/vite-plugin": "^3.17.2",
-    "typescript": "^5.2.2",
-    "vite": "^4.0.0"
-  }
-}
diff --git a/animation/error_handling/src/global.css b/animation/error_handling/src/global.css
deleted file mode 100644
index 201f5ff..0000000
--- a/animation/error_handling/src/global.css
+++ /dev/null
@@ -1 +0,0 @@
-@import url('https://fonts.googleapis.com/css2?family=Fira+Mono:wght@400;500;700&display=swap');
diff --git a/animation/error_handling/src/motion-canvas.d.ts b/animation/error_handling/src/motion-canvas.d.ts
deleted file mode 100644
index 067c6a4..0000000
--- a/animation/error_handling/src/motion-canvas.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-/// <reference types="@motion-canvas/core/project" />
diff --git a/animation/error_handling/src/project.meta b/animation/error_handling/src/project.meta
deleted file mode 100644
index f3604ae..0000000
--- a/animation/error_handling/src/project.meta
+++ /dev/null
@@ -1,31 +0,0 @@
-{
-  "version": 0,
-  "shared": {
-    "background": "rgb(10,15,20)",
-    "range": [
-      0,
-      null
-    ],
-    "size": {
-      "x": 1920,
-      "y": 1080
-    },
-    "audioOffset": 0
-  },
-  "preview": {
-    "fps": 30,
-    "resolutionScale": 1
-  },
-  "rendering": {
-    "fps": 30,
-    "resolutionScale": 2,
-    "colorSpace": "srgb",
-    "exporter": {
-      "name": "@motion-canvas/ffmpeg",
-      "options": {
-        "fastStart": true,
-        "includeAudio": true
-      }
-    }
-  }
-}
\ No newline at end of file
diff --git a/animation/error_handling/src/project.ts b/animation/error_handling/src/project.ts
deleted file mode 100644
index 186e055..0000000
--- a/animation/error_handling/src/project.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-import { makeProject } from '@motion-canvas/core';
-import { Code, LezerHighlighter } from '@motion-canvas/2d';
-import { parser } from '@lezer/cpp';
-import { tags } from '@lezer/highlight';
-import { HighlightStyle } from '@codemirror/language';
-
-const MyStyle = HighlightStyle.define([
-  { tag: tags.keyword, color: '#569CD6' }, // VSCode Keyword color
-  { tag: tags.controlKeyword, color: '#C586C0' }, // VSCode Control Keyword color
-  { tag: tags.operatorKeyword, color: '#C586C0' }, // VSCode Control Keyword color
-  { tag: tags.comment, color: 'gray' }, // VSCode Comment color
-  { tag: tags.className, color: '#4EC9B0' }, // VSCode Class Name color
-  { tag: tags.constant(tags.variableName), color: '#B5CEA8' }, // VSCode Constant color
-  { tag: tags.function(tags.variableName), color: '#DCDCAA' }, // VSCode Function color
-  { tag: tags.function(tags.propertyName), color: '#DCDCAA' }, // VSCode Function color
-  // { tag: tags.propertyName, color: '#DCDCAA' }, // VSCode Function color
-  { tag: tags.number, color: '#B5CEA8' }, // VSCode Number color
-  { tag: tags.string, color: '#CE9178' }, // VSCode String color
-  { tag: tags.typeName, color: '#4EC9B0' }, // VSCode Type Name color
-  { tag: tags.squareBracket, color: '#C586C0' }, // VSCode Square Bracket color
-  { tag: tags.bracket, color: '#C586C0' }, // VSCode Bracket color
-  { tag: tags.brace, color: '#DDDD22' }, // VSCode Brace color
-  { tag: tags.processingInstruction, color: '#C586C0' }, // VSCode Brace color
-  { tag: tags.arithmeticOperator, color: '#D16969' }, // VSCode Arithmetic Operator color
-]);
-
-Code.defaultHighlighter = new LezerHighlighter(parser, MyStyle);
-
-import './global.css';
-
-import example from './scenes/example?scene';
-
-export default makeProject({
-  scenes: [example],
-});
diff --git a/animation/error_handling/src/scenes/example.meta b/animation/error_handling/src/scenes/example.meta
deleted file mode 100644
index 7458970..0000000
--- a/animation/error_handling/src/scenes/example.meta
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-  "version": 0,
-  "timeEvents": [],
-  "seed": 29846135
-}
\ No newline at end of file
diff --git a/animation/error_handling/src/scenes/example.tsx b/animation/error_handling/src/scenes/example.tsx
deleted file mode 100644
index 8c3860e..0000000
--- a/animation/error_handling/src/scenes/example.tsx
+++ /dev/null
@@ -1,1611 +0,0 @@
-import { createRef } from '@motion-canvas/core/lib/utils';
-import { makeScene2D, Code, Camera, Node, lines } from '@motion-canvas/2d';
-import { all, waitFor, waitUntil } from '@motion-canvas/core/lib/flow';
-import { DEFAULT } from '@motion-canvas/core/lib/signals';
-import { BBox, Vector2 } from '@motion-canvas/core/lib/types';
-import { Stage } from '@motion-canvas/core';
-
-export default makeScene2D(function* (view) {
-  const codeRef = createRef<Code>();
-  const camera_1 = createRef<Camera>();
-  const camera_2 = createRef<Camera>();
-  const stage_2 = createRef<Node>();
-
-  const scene = (
-    <Node>
-      <Code
-        ref={codeRef}
-        fontSize={50}
-        fontFamily={'Fira Mono'}
-        fontWeight={500}
-        offsetX={0}
-        x={0} />
-    </Node>
-  );
-
-  view.add(
-    <>
-      <Camera.Stage
-        cameraRef={camera_1}
-        scene={scene}
-        size={[1920, 1080]}
-        position={[0, 0]}
-      />
-      <Node
-        ref={stage_2}
-        position={[900, 0]}
-      >
-        <Camera.Stage
-          ref={stage_2}
-          cameraRef={camera_2}
-          scene={scene}
-          size={[600, 200]}
-          position={[500, -350]}
-          fill={'#123'}
-          radius={10}
-          smoothCorners
-        />
-      </Node>
-
-    </>,
-  );
-
-  const duration = 1.0
-
-  const game_1 = `\
-#include <vector>
-
-// 😱 Warning! No error handling!
-class Game {
- public:
-  Game(std::vector<int>&& ref_numbers,
-       std::vector<int>&& player_numbers,
-       int budget)
-      : ref_numbers_{std::move(ref_numbers)},
-        player_numbers_{std::move(player_numbers)},
-        budget_{budget} {}
-
-  const std::vector<int>& ref_numbers() const { return ref_numbers_; }
-  const std::vector<int>& player_numbers() const { return player_numbers_; }
-  bool UserHasBudget() const { return budget_ > 0; }
-
- private:
-  std::vector<int> ref_numbers_{};
-  std::vector<int> player_numbers_{};
-  int budget_{};
-};`
-
-  yield* all(
-    codeRef().code(game_1, 0.0).wait(duration),
-    camera_1().zoom(0.7, 0.0),
-  );
-
-  const game_2 = `\
-#include <iostream>
-#include <vector>
-
-// 😱 Warning! No error handling!
-class Game {
- public:
-  Game(std::vector<int>&& ref_numbers,
-       std::vector<int>&& player_numbers,
-       int budget)
-      : ref_numbers_{std::move(ref_numbers)},
-        player_numbers_{std::move(player_numbers)},
-        budget_{budget} {}
-
-  void Print() const {
-    std::cout << "Budget: " << budget_ << std::endl;
-    std::cout << "Reference numbers: ";
-    for (auto number : ref_numbers_) { std::cout << number << "\\t"; }
-    std::cout << std::endl;
-    std::cout << "Player numbers:    ";
-    for (auto number : player_numbers_) { std::cout << number << "\\t"; }
-    std::cout << std::endl;
-  }
-
-  const std::vector<int>& ref_numbers() const { return ref_numbers_; }
-  const std::vector<int>& player_numbers() const { return player_numbers_; }
-  bool UserHasBudget() const { return budget_ > 0; }
-
- private:
-  std::vector<int> ref_numbers_{};
-  std::vector<int> player_numbers_{};
-  int budget_{};
-};`
-
-
-  yield* all(
-    codeRef().code(game_2, duration).wait(duration),
-    camera_1().zoom(0.5, duration),
-    codeRef().selection([
-      lines(0, 0),
-      lines(13, 13 + 9),
-    ], duration)
-  );
-
-
-  const game_3 = `\
-#include <iostream>
-#include <vector>
-
-// 😱 Warning! No error handling!
-class Game {
- public:
-  Game(std::vector<int>&& ref_numbers,
-       std::vector<int>&& player_numbers,
-       int budget)
-      : ref_numbers_{std::move(ref_numbers)},
-        player_numbers_{std::move(player_numbers)},
-        budget_{budget} {}
-
-  void Print() const {
-    std::cout << "Budget: " << budget_ << std::endl;
-    std::cout << "Reference numbers: ";
-    for (auto number : ref_numbers_) { std::cout << number << "\\t"; }
-    std::cout << std::endl;
-    std::cout << "Player numbers:    ";
-    for (auto number : player_numbers_) { std::cout << number << "\\t"; }
-    std::cout << std::endl;
-  }
-
-  bool CheckIfPlayerWon() const {
-    int win_loss_counter{};
-    for (auto i = 0UL; i < player_numbers_.size(); ++i) {
-      const auto difference = player_numbers_[i] - ref_numbers_[i];
-      if (difference > 0) win_loss_counter++;
-      if (difference < 0) win_loss_counter--;
-    }
-    return win_loss_counter > 0;
-  }
-
-  const std::vector<int>& ref_numbers() const { return ref_numbers_; }
-  const std::vector<int>& player_numbers() const { return player_numbers_; }
-  bool UserHasBudget() const { return budget_ > 0; }
-
- private:
-  std::vector<int> ref_numbers_{};
-  std::vector<int> player_numbers_{};
-  int budget_{};
-};`
-
-  yield* all(
-    codeRef().code(game_3, duration).wait(duration),
-    camera_1().centerOn([0, 500], duration),
-    codeRef().selection([
-      lines(154 - 131, 162 - 131),
-    ], duration)
-  );
-
-  const game_4 = `\
-#include <algorithm>
-#include <iostream>
-#include <vector>
-
-struct ChangeEntry {
-  int index{};
-  int value{};
-};
-
-// 😱 Warning! No error handling!
-class Game {
- public:
-  Game(std::vector<int>&& ref_numbers,
-       std::vector<int>&& player_numbers,
-       int budget)
-      : ref_numbers_{std::move(ref_numbers)},
-        player_numbers_{std::move(player_numbers)},
-        budget_{budget} {}
-
-  void Print() const {
-    std::cout << "Budget: " << budget_ << std::endl;
-    std::cout << "Reference numbers: ";
-    for (auto number : ref_numbers_) { std::cout << number << "\\t"; }
-    std::cout << std::endl;
-    std::cout << "Player numbers:    ";
-    for (auto number : player_numbers_) { std::cout << number << "\\t"; }
-    std::cout << std::endl;
-  }
-
-  bool CheckIfPlayerWon() const {
-    int win_loss_counter{};
-    for (auto i = 0UL; i < player_numbers_.size(); ++i) {
-      const auto difference = player_numbers_[i] - ref_numbers_[i];
-      if (difference > 0) win_loss_counter++;
-      if (difference < 0) win_loss_counter--;
-    }
-    return win_loss_counter > 0;
-  }
-
-  void ChangePlayerNumberIfPossible(const ChangeEntry& change_entry) {
-    auto& player_number = player_numbers_[change_entry.index];
-    const auto difference = std::abs(change_entry.value - player_number);
-    if (difference > budget_) { return; }
-    player_number = change_entry.value;
-    budget_ -= difference;
-  }
-
-  const std::vector<int>& ref_numbers() const { return ref_numbers_; }
-  const std::vector<int>& player_numbers() const { return player_numbers_; }
-  bool UserHasBudget() const { return budget_ > 0; }
-
- private:
-  std::vector<int> ref_numbers_{};
-  std::vector<int> player_numbers_{};
-  int budget_{};
-};`
-
-  yield* all(
-    camera_2().centerOn([-800, -1200], 0),
-    camera_2().zoom(0.6, 0),
-  );
-
-  yield* all(
-    stage_2().position.x(0, duration / 2),
-  );
-
-  yield* all(
-    codeRef().code(game_4, duration).wait(duration),
-    stage_2().scale(1.3, duration),
-    stage_2().position([-150, 150], duration),
-    camera_2().zoom(0.35, duration),
-    camera_2().centerOn([-800, -1450], duration),
-    camera_1().centerOn([0, 700], duration),
-    codeRef().selection([
-      lines(0, 0),
-      lines(4, 7),
-      lines(221 - 183, 228 - 183),
-    ], duration)
-  );
-
-  const game_5 = `\
-#include <algorithm>
-#include <iostream>
-#include <vector>
-
-struct ChangeEntry {
-  int index{};
-  int value{};
-};
-
-// 😱 Warning! No error handling!
-class Game {
- public:
-  Game(std::vector<int>&& ref_numbers,
-       std::vector<int>&& player_numbers,
-       int budget)
-      : ref_numbers_{std::move(ref_numbers)},
-        player_numbers_{std::move(player_numbers)},
-        budget_{budget} {}
-
-  void Print() const {
-    std::cout << "Budget: " << budget_ << std::endl;
-    std::cout << "Reference numbers: ";
-    for (auto number : ref_numbers_) { std::cout << number << "\\t"; }
-    std::cout << std::endl;
-    std::cout << "Player numbers:    ";
-    for (auto number : player_numbers_) { std::cout << number << "\\t"; }
-    std::cout << std::endl;
-  }
-
-  bool CheckIfPlayerWon() const {
-    int win_loss_counter{};
-    for (auto i = 0UL; i < player_numbers_.size(); ++i) {
-      const auto difference = player_numbers_[i] - ref_numbers_[i];
-      if (difference > 0) win_loss_counter++;
-      if (difference < 0) win_loss_counter--;
-    }
-    return win_loss_counter > 0;
-  }
-
-  void ChangePlayerNumberIfPossible(const ChangeEntry& change_entry) {
-    auto& player_number = player_numbers_[change_entry.index];
-    const auto difference = std::abs(change_entry.value - player_number);
-    if (difference > budget_) { return; }
-    player_number = change_entry.value;
-    budget_ -= difference;
-  }
-
-  const std::vector<int>& ref_numbers() const { return ref_numbers_; }
-  const std::vector<int>& player_numbers() const { return player_numbers_; }
-  bool UserHasBudget() const { return budget_ > 0; }
-
- private:
-  std::vector<int> ref_numbers_{};
-  std::vector<int> player_numbers_{};
-  int budget_{};
-};
-
-// 😱 We should handle failure to get a proper value.
-ChangeEntry GetNextChangeEntryFromUser(const Game& game) {
-  game.Print();
-  ChangeEntry entry{};
-  std::cout << "Please enter number to change: ";
-  std::cin >> entry.index;
-  std::cout << "Please provide a new value: ";
-  std::cin >> entry.value;
-  return entry;
-}`
-
-  yield* all(
-    stage_2().position.x(900, duration / 2),
-    codeRef().code(game_5, duration).wait(duration),
-    camera_1().centerOn([0, 1500], duration),
-    codeRef().selection([
-      lines(306 - 250, 316 - 250),
-    ], duration)
-  );
-
-  yield* all(
-    camera_2().centerOn([-800, -1200], 0),
-    camera_2().zoom(0.6, 0),
-    stage_2().scale(1.0, 0),
-    stage_2().position([900, 0], 0),
-  );
-
-  const game_6 = `\
-#include <algorithm>
-#include <iostream>
-#include <vector>
-
-struct ChangeEntry {
-  int index{};
-  int value{};
-};
-
-// 😱 Warning! No error handling!
-class Game {
- public:
-  Game(std::vector<int>&& ref_numbers,
-       std::vector<int>&& player_numbers,
-       int budget)
-      : ref_numbers_{std::move(ref_numbers)},
-        player_numbers_{std::move(player_numbers)},
-        budget_{budget} {}
-
-  void Print() const {
-    std::cout << "Budget: " << budget_ << std::endl;
-    std::cout << "Reference numbers: ";
-    for (auto number : ref_numbers_) { std::cout << number << "\\t"; }
-    std::cout << std::endl;
-    std::cout << "Player numbers:    ";
-    for (auto number : player_numbers_) { std::cout << number << "\\t"; }
-    std::cout << std::endl;
-  }
-
-  bool CheckIfPlayerWon() const {
-    int win_loss_counter{};
-    for (auto i = 0UL; i < player_numbers_.size(); ++i) {
-      const auto difference = player_numbers_[i] - ref_numbers_[i];
-      if (difference > 0) win_loss_counter++;
-      if (difference < 0) win_loss_counter--;
-    }
-    return win_loss_counter > 0;
-  }
-
-  void ChangePlayerNumberIfPossible(const ChangeEntry& change_entry) {
-    auto& player_number = player_numbers_[change_entry.index];
-    const auto difference = std::abs(change_entry.value - player_number);
-    if (difference > budget_) { return; }
-    player_number = change_entry.value;
-    budget_ -= difference;
-  }
-
-  const std::vector<int>& ref_numbers() const { return ref_numbers_; }
-  const std::vector<int>& player_numbers() const { return player_numbers_; }
-  bool UserHasBudget() const { return budget_ > 0; }
-
- private:
-  std::vector<int> ref_numbers_{};
-  std::vector<int> player_numbers_{};
-  int budget_{};
-};
-
-// 😱 We should handle failure to get a proper value.
-ChangeEntry GetNextChangeEntryFromUser(const Game& game) {
-  game.Print();
-  ChangeEntry entry{};
-  std::cout << "Please enter number to change: ";
-  std::cin >> entry.index;
-  std::cout << "Please provide a new value: ";
-  std::cin >> entry.value;
-  return entry;
-}
-
-int main() {
-  Game game{{42, 49, 23}, {10, 40, 24}, 10};
-  while (game.UserHasBudget()) {
-    const auto change_entry = GetNextChangeEntryFromUser(game);
-    game.ChangePlayerNumberIfPossible(change_entry);
-  }
-  game.Print();
-  if (game.CheckIfPlayerWon()) {
-    std::cout << "You win!\\n";
-  } else {
-    std::cout << "Not win today. Try again!\\n";
-  }
-}`
-
-  yield* all(
-    codeRef().code(game_6, duration).wait(duration),
-    camera_1().centerOn([0, 1800], duration),
-    codeRef().selection([
-      lines(390 - 323, 403 - 323),
-    ], duration)
-  );
-
-  yield* all(
-    camera_1().centerOn([0, 0], 0),
-    camera_1().zoom(0.2, 0),
-    codeRef().selection(DEFAULT, 0),
-    waitFor(duration)
-  );
-
-  const game_check = `\
-#include <absl/log/check.h>
-
-#include <algorithm>
-#include <iostream>
-#include <vector>
-
-struct ChangeEntry {
-  int index{};
-  int value{};
-};
-
-// 😱 Warning! No error handling!
-class Game {
- public:
-  Game(std::vector<int>&& ref_numbers,
-       std::vector<int>&& player_numbers,
-       int budget)
-      : ref_numbers_{std::move(ref_numbers)},
-        player_numbers_{std::move(player_numbers)},
-        budget_{budget} {}
-
-  void Print() const {
-    std::cout << "Budget: " << budget_ << std::endl;
-    std::cout << "Reference numbers: ";
-    for (auto number : ref_numbers_) { std::cout << number << "\\t"; }
-    std::cout << std::endl;
-    std::cout << "Player numbers:    ";
-    for (auto number : player_numbers_) { std::cout << number << "\\t"; }
-    std::cout << std::endl;
-  }
-
-  bool CheckIfPlayerWon() const {
-    int win_loss_counter{};
-    for (auto i = 0UL; i < player_numbers_.size(); ++i) {
-      const auto difference = player_numbers_[i] - ref_numbers_[i];
-      if (difference > 0) win_loss_counter++;
-      if (difference < 0) win_loss_counter--;
-    }
-    return win_loss_counter > 0;
-  }
-
-  void ChangePlayerNumberIfPossible(const ChangeEntry& change_entry) {
-    // Checking:
-    //   (change_entry.index >= 0)
-    //   (change_entry.index < player_numbers_.size())
-    CHECK_GE(change_entry.index, 0);
-    CHECK_LT(change_entry.index, player_numbers_.size());
-    auto& player_number = player_numbers_[change_entry.index];
-    const auto difference = std::abs(change_entry.value - player_number);
-    if (difference > budget_) { return; }
-    player_number = change_entry.value;
-    budget_ -= difference;
-  }
-
-  const std::vector<int>& ref_numbers() const { return ref_numbers_; }
-  const std::vector<int>& player_numbers() const { return player_numbers_; }
-  bool UserHasBudget() const { return budget_ > 0; }
-
- private:
-  std::vector<int> ref_numbers_{};
-  std::vector<int> player_numbers_{};
-  int budget_{};
-};
-
-// 😱 We should handle failure to get a proper value.
-ChangeEntry GetNextChangeEntryFromUser(const Game& game) {
-  game.Print();
-  ChangeEntry entry{};
-  std::cout << "Please enter number to change: ";
-  std::cin >> entry.index;
-  std::cout << "Please provide a new value: ";
-  std::cin >> entry.value;
-  return entry;
-}
-
-int main() {
-  Game game{{42, 49, 23}, {10, 40, 24}, 10};
-  while (game.UserHasBudget()) {
-    const auto change_entry = GetNextChangeEntryFromUser(game);
-    game.ChangePlayerNumberIfPossible(change_entry);
-  }
-  game.Print();
-  if (game.CheckIfPlayerWon()) {
-    std::cout << "You win!\\n";
-  } else {
-    std::cout << "Not win today. Try again!\\n";
-  }
-}`
-
-  yield* all(
-    camera_2().centerOn([-700, -2400], 0),
-    camera_1().centerOn([100, -100], duration),
-    camera_1().zoom(0.7, duration),
-    codeRef().selection([
-      lines(454 - 416, 462 - 416),
-    ], duration)
-  );
-
-  yield* waitFor(0.5 * duration);
-
-  yield* all(
-    codeRef().code(game_check, duration).wait(duration),
-    stage_2().position.x(0, duration / 2),
-    camera_2().centerOn([-700, -2600], duration),
-    codeRef().selection([
-      lines(0, 0),
-      lines(456 - 416, 468 - 416),
-    ], duration)
-  );
-
-  const game_assert = `\
-#include <cassert>
-
-#include <algorithm>
-#include <iostream>
-#include <vector>
-
-struct ChangeEntry {
-  int index{};
-  int value{};
-};
-
-// 😱 Warning! No error handling!
-class Game {
- public:
-  Game(std::vector<int>&& ref_numbers,
-       std::vector<int>&& player_numbers,
-       int budget)
-      : ref_numbers_{std::move(ref_numbers)},
-        player_numbers_{std::move(player_numbers)},
-        budget_{budget} {}
-
-  void Print() const {
-    std::cout << "Budget: " << budget_ << std::endl;
-    std::cout << "Reference numbers: ";
-    for (auto number : ref_numbers_) { std::cout << number << "\\t"; }
-    std::cout << std::endl;
-    std::cout << "Player numbers:    ";
-    for (auto number : player_numbers_) { std::cout << number << "\\t"; }
-    std::cout << std::endl;
-  }
-
-  bool CheckIfPlayerWon() const {
-    int win_loss_counter{};
-    for (auto i = 0UL; i < player_numbers_.size(); ++i) {
-      const auto difference = player_numbers_[i] - ref_numbers_[i];
-      if (difference > 0) win_loss_counter++;
-      if (difference < 0) win_loss_counter--;
-    }
-    return win_loss_counter > 0;
-  }
-
-  // 😱 Beware of using asserts in release code.
-  void ChangePlayerNumberIfPossible(const ChangeEntry& change_entry) {
-    assert(change_entry.index >= 0);
-    assert(change_entry.index < player_numbers_.size());
-    auto& player_number = player_numbers_[change_entry.index];
-    const auto difference = std::abs(change_entry.value - player_number);
-    if (difference > budget_) { return; }
-    player_number = change_entry.value;
-    budget_ -= difference;
-  }
-
-  const std::vector<int>& ref_numbers() const { return ref_numbers_; }
-  const std::vector<int>& player_numbers() const { return player_numbers_; }
-  bool UserHasBudget() const { return budget_ > 0; }
-
- private:
-  std::vector<int> ref_numbers_{};
-  std::vector<int> player_numbers_{};
-  int budget_{};
-};
-
-// 😱 We should handle failure to get a proper value.
-ChangeEntry GetNextChangeEntryFromUser(const Game& game) {
-  game.Print();
-  ChangeEntry entry{};
-  std::cout << "Please enter number to change: ";
-  std::cin >> entry.index;
-  std::cout << "Please provide a new value: ";
-  std::cin >> entry.value;
-  return entry;
-}
-
-int main() {
-  Game game{{42, 49, 23}, {10, 40, 24}, 10};
-  while (game.UserHasBudget()) {
-    const auto change_entry = GetNextChangeEntryFromUser(game);
-    game.ChangePlayerNumberIfPossible(change_entry);
-  }
-  game.Print();
-  if (game.CheckIfPlayerWon()) {
-    std::cout << "You win!\\n";
-  } else {
-    std::cout << "Not win today. Try again!\\n";
-  }
-}`
-
-  yield* all(
-    codeRef().code(game_assert, duration).wait(duration),
-    camera_2().centerOn([-700, -2550], duration),
-    codeRef().selection([
-      lines(0, 0),
-      lines(597 - 556, 606 - 556),
-    ], duration)
-  );
-
-  yield* all(
-    stage_2().position.x(900, 0),
-    waitFor(duration),
-  );
-
-  yield* all(
-    camera_1().centerOn([0, -600], duration),
-    waitFor(duration * 2),
-    codeRef().selection([
-      lines(0, 0),
-      lines(587 - 556, 595 - 556),
-    ], duration)
-  );
-
-  yield* all(
-    codeRef().code(game_check, 0).wait(duration),
-    camera_1().centerOn([0, 0], 0),
-    codeRef().selection(DEFAULT, 0),
-    camera_1().zoom(0.2, 0),
-  );
-
-  yield* all(
-    camera_1().centerOn([0, 1300], duration),
-    camera_1().zoom(0.7, duration),
-    codeRef().selection([
-      lines(702 - 639, 712 - 639),
-    ], duration)
-  );
-
-  const game_before_recoverable = `\
-#include <absl/log/check.h>
-
-#include <algorithm>
-#include <iostream>
-#include <vector>
-
-struct ChangeEntry {
-  int index{};
-  int value{};
-};
-
-// 😱 Warning! No error handling!
-class Game {
- public:
-  Game(std::vector<int>&& ref_numbers,
-       std::vector<int>&& player_numbers,
-       int budget)
-      : ref_numbers_{std::move(ref_numbers)},
-        player_numbers_{std::move(player_numbers)},
-        budget_{budget} {}
-
-  void Print() const {
-    std::cout << "Budget: " << budget_ << std::endl;
-    std::cout << "Reference numbers: ";
-    for (auto number : ref_numbers_) { std::cout << number << "\\t"; }
-    std::cout << std::endl;
-    std::cout << "Player numbers:    ";
-    for (auto number : player_numbers_) { std::cout << number << "\\t"; }
-    std::cout << std::endl;
-  }
-
-  bool CheckIfPlayerWon() const {
-    int win_loss_counter{};
-    for (auto i = 0UL; i < player_numbers_.size(); ++i) {
-      const auto difference = player_numbers_[i] - ref_numbers_[i];
-      if (difference > 0) win_loss_counter++;
-      if (difference < 0) win_loss_counter--;
-    }
-    return win_loss_counter > 0;
-  }
-
-  void ChangePlayerNumberIfPossible(const ChangeEntry& change_entry) {
-    // Checking:
-    //   (change_entry.index >= 0)
-    //   (change_entry.index < player_numbers_.size())
-    CHECK_GE(change_entry.index, 0);
-    CHECK_LT(change_entry.index, player_numbers_.size());
-    auto& player_number = player_numbers_[change_entry.index];
-    const auto difference = std::abs(change_entry.value - player_number);
-    if (difference > budget_) { return; }
-    player_number = change_entry.value;
-    budget_ -= difference;
-  }
-
-  const std::vector<int>& ref_numbers() const { return ref_numbers_; }
-  const std::vector<int>& player_numbers() const { return player_numbers_; }
-  bool UserHasBudget() const { return budget_ > 0; }
-
- private:
-  std::vector<int> ref_numbers_{};
-  std::vector<int> player_numbers_{};
-  int budget_{};
-};
-
-// 😱 We should handle failure to get a proper value.
-ChangeEntry GetNextChangeEntryFromUser(const Game& game) {
-  game.Print();
-  ChangeEntry entry{};
-  std::cout << "Please enter number to change: ";
-  std::cin >> entry.index;  // <-- This value is NOT arbitrary!
-  std::cout << "Please provide a new value: ";
-  std::cin >> entry.value;
-  return entry;
-}
-
-int main() {
-  Game game{{42, 49, 23}, {10, 40, 24}, 10};
-  while (game.UserHasBudget()) {
-    const auto change_entry = GetNextChangeEntryFromUser(game);
-    game.ChangePlayerNumberIfPossible(change_entry);
-  }
-  game.Print();
-  if (game.CheckIfPlayerWon()) {
-    std::cout << "You win!\\n";
-  } else {
-    std::cout << "Not win today. Try again!\\n";
-  }
-}`
-
-  yield* all(
-    codeRef().code(game_before_recoverable, duration).wait(duration),
-    codeRef().selection([
-      lines(702 - 639, 712 - 639),
-    ], duration)
-  );
-  yield* waitFor(duration);
-
-  const game_exceptions_func = `\
-#include <absl/log/check.h>
-
-#include <algorithm>
-#include <iostream>
-#include <stdexcept>
-#include <vector>
-
-struct ChangeEntry {
-  int index{};
-  int value{};
-};
-
-class Game {
- public:
-  Game(std::vector<int>&& ref_numbers,
-       std::vector<int>&& player_numbers,
-       int budget)
-      : ref_numbers_{std::move(ref_numbers)},
-        player_numbers_{std::move(player_numbers)},
-        budget_{budget} {}
-
-  void Print() const {
-    std::cout << "Budget: " << budget_ << std::endl;
-    std::cout << "Reference numbers: ";
-    for (auto number : ref_numbers_) { std::cout << number << "\\t"; }
-    std::cout << std::endl;
-    std::cout << "Player numbers:    ";
-    for (auto number : player_numbers_) { std::cout << number << "\\t"; }
-    std::cout << std::endl;
-  }
-
-  bool CheckIfPlayerWon() const {
-    int win_loss_counter{};
-    for (auto i = 0UL; i < player_numbers_.size(); ++i) {
-      const auto difference = player_numbers_[i] - ref_numbers_[i];
-      if (difference > 0) win_loss_counter++;
-      if (difference < 0) win_loss_counter--;
-    }
-    return win_loss_counter > 0;
-  }
-
-  void ChangePlayerNumberIfPossible(const ChangeEntry& change_entry) {
-    // Checking:
-    //   (change_entry.index >= 0)
-    //   (change_entry.index < player_numbers_.size())
-    CHECK_GE(change_entry.index, 0);
-    CHECK_LT(change_entry.index, player_numbers_.size());
-    auto& player_number = player_numbers_[change_entry.index];
-    const auto difference = std::abs(change_entry.value - player_number);
-    if (difference > budget_) { return; }
-    player_number = change_entry.value;
-    budget_ -= difference;
-  }
-
-  const std::vector<int>& ref_numbers() const { return ref_numbers_; }
-  const std::vector<int>& player_numbers() const { return player_numbers_; }
-  bool UserHasBudget() const { return budget_ > 0; }
-
- private:
-  std::vector<int> ref_numbers_{};
-  std::vector<int> player_numbers_{};
-  int budget_{};
-};
-
-// 😱 I'm not a fan of using exceptions.
-ChangeEntry GetNextChangeEntryFromUser(const Game& game) {
-  game.Print();
-  ChangeEntry entry{};
-  std::cout << "Please enter number to change: ";
-  std::cin >> entry.index;
-  if ((entry.index < 0) || (entry.index >= game.player_numbers().size())) {
-    throw std::out_of_range("Wrong number index provided.");
-  }
-  std::cout << "Please provide a new value: ";
-  std::cin >> entry.value;
-  return entry;
-}
-
-int main() {
-  Game game{{42, 49, 23}, {10, 40, 24}, 10};
-  while (game.UserHasBudget()) {
-    const auto change_entry = GetNextChangeEntryFromUser(game);
-    game.ChangePlayerNumberIfPossible(change_entry);
-  }
-  game.Print();
-  if (game.CheckIfPlayerWon()) {
-    std::cout << "You win!\\n";
-  } else {
-    std::cout << "Not win today. Try again!\\n";
-  }
-}`
-
-  yield* all(
-    stage_2().position.x(0, duration / 2),
-    camera_2().centerOn([-700, -2450], 0),
-  );
-
-  yield* all(
-    codeRef().code(game_exceptions_func, duration).wait(duration),
-    codeRef().selection([
-      lines(4, 4),
-      lines(795 - 732, 808 - 732),
-    ], duration),
-    camera_2().centerOn([-700, -2450], duration),
-  );
-  yield* waitFor(duration);
-
-  const game_exceptions = `\
-#include <absl/log/check.h>
-
-#include <algorithm>
-#include <iostream>
-#include <stdexcept>
-#include <vector>
-
-struct ChangeEntry {
-  int index{};
-  int value{};
-};
-
-class Game {
- public:
-  Game(std::vector<int>&& ref_numbers,
-       std::vector<int>&& player_numbers,
-       int budget)
-      : ref_numbers_{std::move(ref_numbers)},
-        player_numbers_{std::move(player_numbers)},
-        budget_{budget} {}
-
-  void Print() const {
-    std::cout << "Budget: " << budget_ << std::endl;
-    std::cout << "Reference numbers: ";
-    for (auto number : ref_numbers_) { std::cout << number << "\\t"; }
-    std::cout << std::endl;
-    std::cout << "Player numbers:    ";
-    for (auto number : player_numbers_) { std::cout << number << "\\t"; }
-    std::cout << std::endl;
-  }
-
-  bool CheckIfPlayerWon() const {
-    int win_loss_counter{};
-    for (auto i = 0UL; i < player_numbers_.size(); ++i) {
-      const auto difference = player_numbers_[i] - ref_numbers_[i];
-      if (difference > 0) win_loss_counter++;
-      if (difference < 0) win_loss_counter--;
-    }
-    return win_loss_counter > 0;
-  }
-
-  void ChangePlayerNumberIfPossible(const ChangeEntry& change_entry) {
-    // Checking:
-    //   (change_entry.index >= 0)
-    //   (change_entry.index < player_numbers_.size())
-    CHECK_GE(change_entry.index, 0);
-    CHECK_LT(change_entry.index, player_numbers_.size());
-    auto& player_number = player_numbers_[change_entry.index];
-    const auto difference = std::abs(change_entry.value - player_number);
-    if (difference > budget_) { return; }
-    player_number = change_entry.value;
-    budget_ -= difference;
-  }
-
-  const std::vector<int>& ref_numbers() const { return ref_numbers_; }
-  const std::vector<int>& player_numbers() const { return player_numbers_; }
-  bool UserHasBudget() const { return budget_ > 0; }
-
- private:
-  std::vector<int> ref_numbers_{};
-  std::vector<int> player_numbers_{};
-  int budget_{};
-};
-
-// 😱 I'm not a fan of using exceptions.
-ChangeEntry GetNextChangeEntryFromUser(const Game& game) {
-  game.Print();
-  ChangeEntry entry{};
-  std::cout << "Please enter number to change: ";
-  std::cin >> entry.index;
-  if ((entry.index < 0) || (entry.index >= game.player_numbers().size())) {
-    throw std::out_of_range("Wrong number index provided.");
-  }
-  std::cout << "Please provide a new value: ";
-  std::cin >> entry.value;
-  return entry;
-}
-
-int main() {
-  Game game{{42, 49, 23}, {10, 40, 24}, 10};
-  while (game.UserHasBudget()) {
-    try {
-      const auto change_entry = GetNextChangeEntryFromUser(game);
-      game.ChangePlayerNumberIfPossible(change_entry);
-    } catch (const std::out_of_range& e) {
-      std::cerr << e.what() << std::endl;
-    }
-  }
-  game.Print();
-  if (game.CheckIfPlayerWon()) {
-    std::cout << "You win!\\n";
-  } else {
-    std::cout << "Not win today. Try again!\\n";
-  }
-}`
-
-  yield* all(
-    camera_1().centerOn([0, 1900], duration),
-    camera_1().zoom(0.45, duration),
-    stage_2().position.x(900, duration / 2),
-    codeRef().selection([
-      lines(891 - 828, 922 - 828),
-    ], duration),
-    codeRef().code(game_exceptions, duration).wait(duration),
-  );
-
-  yield* waitFor(duration);
-
-  const game_exceptions_catch_all = `\
-#include <absl/log/check.h>
-
-#include <algorithm>
-#include <iostream>
-#include <stdexcept>
-#include <vector>
-
-struct ChangeEntry {
-  int index{};
-  int value{};
-};
-
-class Game {
- public:
-  Game(std::vector<int>&& ref_numbers,
-       std::vector<int>&& player_numbers,
-       int budget)
-      : ref_numbers_{std::move(ref_numbers)},
-        player_numbers_{std::move(player_numbers)},
-        budget_{budget} {}
-
-  void Print() const {
-    std::cout << "Budget: " << budget_ << std::endl;
-    std::cout << "Reference numbers: ";
-    for (auto number : ref_numbers_) { std::cout << number << "\\t"; }
-    std::cout << std::endl;
-    std::cout << "Player numbers:    ";
-    for (auto number : player_numbers_) { std::cout << number << "\\t"; }
-    std::cout << std::endl;
-  }
-
-  bool CheckIfPlayerWon() const {
-    int win_loss_counter{};
-    for (auto i = 0UL; i < player_numbers_.size(); ++i) {
-      const auto difference = player_numbers_[i] - ref_numbers_[i];
-      if (difference > 0) win_loss_counter++;
-      if (difference < 0) win_loss_counter--;
-    }
-    return win_loss_counter > 0;
-  }
-
-  void ChangePlayerNumberIfPossible(const ChangeEntry& change_entry) {
-    // Checking:
-    //   (change_entry.index >= 0)
-    //   (change_entry.index < player_numbers_.size())
-    CHECK_GE(change_entry.index, 0);
-    CHECK_LT(change_entry.index, player_numbers_.size());
-    auto& player_number = player_numbers_[change_entry.index];
-    const auto difference = std::abs(change_entry.value - player_number);
-    if (difference > budget_) { return; }
-    player_number = change_entry.value;
-    budget_ -= difference;
-  }
-
-  const std::vector<int>& ref_numbers() const { return ref_numbers_; }
-  const std::vector<int>& player_numbers() const { return player_numbers_; }
-  bool UserHasBudget() const { return budget_ > 0; }
-
- private:
-  std::vector<int> ref_numbers_{};
-  std::vector<int> player_numbers_{};
-  int budget_{};
-};
-
-// 😱 I'm not a fan of using exceptions.
-ChangeEntry GetNextChangeEntryFromUser(const Game& game) {
-  game.Print();
-  ChangeEntry entry{};
-  std::cout << "Please enter number to change: ";
-  std::cin >> entry.index;
-  if ((entry.index < 0) || (entry.index >= game.player_numbers().size())) {
-    throw std::out_of_range("Wrong number index provided.");
-  }
-  std::cout << "Please provide a new value: ";
-  std::cin >> entry.value;
-  return entry;
-}
-
-int main() {
-  Game game{{42, 49, 23}, {10, 40, 24}, 10};
-  while (game.UserHasBudget()) {
-    try {
-      const auto change_entry = GetNextChangeEntryFromUser(game);
-      game.ChangePlayerNumberIfPossible(change_entry);
-    } catch (const std::out_of_range& e) {
-      std::cerr << e.what() << std::endl;
-    } catch (...) {
-      // 😱 Not very useful, is it?
-      std::cerr << "Oops, something happened.\\n";
-    }
-  }
-  game.Print();
-  if (game.CheckIfPlayerWon()) {
-    std::cout << "You win!\\n";
-  } else {
-    std::cout << "Not win today. Try again!\\n";
-  }
-}`
-
-  yield* all(
-    codeRef().code(game_exceptions_catch_all, duration).wait(duration),
-    codeRef().selection([
-      lines(891 - 828, 925 - 828),
-    ], duration),
-  );
-  yield* waitFor(duration);
-
-
-  // Recoverable errors
-  yield* all(
-    codeRef().selection(DEFAULT, 0).wait(duration),
-    camera_1().centerOn([0, 1200], 0),
-    camera_2().centerOn([-700, -2700], 0),
-    camera_1().zoom(0.7, 0),
-    codeRef().selection([
-      lines(1, 5),
-      lines(1111 - 1047, 1124 - 1047),
-    ], 0),
-  );
-
-  const recoverable_value = `\
-#include <absl/log/check.h>
-
-#include <algorithm>
-#include <iostream>
-#include <vector>
-
-struct ChangeEntry {
-  int index{};
-  int value{};
-};
-
-class Game {
- public:
-  Game(std::vector<int>&& ref_numbers,
-       std::vector<int>&& player_numbers,
-       int budget)
-      : ref_numbers_{std::move(ref_numbers)},
-        player_numbers_{std::move(player_numbers)},
-        budget_{budget} {}
-
-  void Print() const {
-    std::cout << "Budget: " << budget_ << std::endl;
-    std::cout << "Reference numbers: ";
-    for (auto number : ref_numbers_) { std::cout << number << "\\t"; }
-    std::cout << std::endl;
-    std::cout << "Player numbers:    ";
-    for (auto number : player_numbers_) { std::cout << number << "\\t"; }
-    std::cout << std::endl;
-  }
-
-  bool CheckIfPlayerWon() const {
-    int win_loss_counter{};
-    for (auto i = 0UL; i < player_numbers_.size(); ++i) {
-      const auto difference = player_numbers_[i] - ref_numbers_[i];
-      if (difference > 0) win_loss_counter++;
-      if (difference < 0) win_loss_counter--;
-    }
-    return win_loss_counter > 0;
-  }
-
-  void ChangePlayerNumberIfPossible(const ChangeEntry& change_entry) {
-    // Checking:
-    //   (change_entry.index >= 0)
-    //   (change_entry.index < player_numbers_.size())
-    CHECK_GE(change_entry.index, 0);
-    CHECK_LT(change_entry.index, player_numbers_.size());
-    auto& player_number = player_numbers_[change_entry.index];
-    const auto difference = std::abs(change_entry.value - player_number);
-    if (difference > budget_) { return; }
-    player_number = change_entry.value;
-    budget_ -= difference;
-  }
-
-  const std::vector<int>& ref_numbers() const { return ref_numbers_; }
-  const std::vector<int>& player_numbers() const { return player_numbers_; }
-  bool UserHasBudget() const { return budget_ > 0; }
-
- private:
-  std::vector<int> ref_numbers_{};
-  std::vector<int> player_numbers_{};
-  int budget_{};
-};
-
-// 😱 Not a great idea!
-ChangeEntry GetNextChangeEntryFromUser(const Game& game) {
-  game.Print();
-  ChangeEntry entry{};
-  std::cout << "Please enter number to change: ";
-  std::cin >> entry.index;
-  if ((entry.index < 0) || (entry.index >= game.player_numbers().size())) {
-    return {};  // 😱 How do we know this value indicates an error?
-  }
-  std::cout << "Please provide a new value: ";
-  std::cin >> entry.value;
-  return entry;
-}
-
-int main() {
-  Game game{{42, 49, 23}, {10, 40, 24}, 10};
-  while (game.UserHasBudget()) {
-    const auto change_entry = GetNextChangeEntryFromUser(game);
-    game.ChangePlayerNumberIfPossible(change_entry);
-  }
-  game.Print();
-  if (game.CheckIfPlayerWon()) {
-    std::cout << "You win!\\n";
-  } else {
-    std::cout << "Not win today. Try again!\\n";
-  }
-}`
-  yield* all(
-    stage_2().position.x(0, duration / 2),
-  );
-
-  yield* all(
-    stage_2().position.x(0, duration / 2),
-    camera_1().centerOn([0, 1400], duration),
-    camera_2().centerOn([-700, -2500], duration),
-    codeRef().selection([
-      lines(1, 4),
-      lines(1109 - 1047, 1122 - 1047),
-    ], duration),
-    codeRef().code(recoverable_value, duration).wait(duration),
-  );
-
-  yield* all(
-    stage_2().position.x(900, duration / 2),
-  );
-
-  // Error codes
-
-  const recoverable_error_codes = `\
-#include <absl/log/check.h>
-
-#include <algorithm>
-#include <iostream>
-#include <vector>
-
-struct ChangeEntry {
-  int index{};
-  int value{};
-};
-
-class Game {
- public:
-  Game(std::vector<int>&& ref_numbers,
-       std::vector<int>&& player_numbers,
-       int budget)
-      : ref_numbers_{std::move(ref_numbers)},
-        player_numbers_{std::move(player_numbers)},
-        budget_{budget} {}
-
-  void Print() const {
-    std::cout << "Budget: " << budget_ << std::endl;
-    std::cout << "Reference numbers: ";
-    for (auto number : ref_numbers_) { std::cout << number << "\\t"; }
-    std::cout << std::endl;
-    std::cout << "Player numbers:    ";
-    for (auto number : player_numbers_) { std::cout << number << "\\t"; }
-    std::cout << std::endl;
-  }
-
-  bool CheckIfPlayerWon() const {
-    int win_loss_counter{};
-    for (auto i = 0UL; i < player_numbers_.size(); ++i) {
-      const auto difference = player_numbers_[i] - ref_numbers_[i];
-      if (difference > 0) win_loss_counter++;
-      if (difference < 0) win_loss_counter--;
-    }
-    return win_loss_counter > 0;
-  }
-
-  void ChangePlayerNumberIfPossible(const ChangeEntry& change_entry) {
-    // Checking:
-    //   (change_entry.index >= 0)
-    //   (change_entry.index < player_numbers_.size())
-    CHECK_GE(change_entry.index, 0);
-    CHECK_LT(change_entry.index, player_numbers_.size());
-    auto& player_number = player_numbers_[change_entry.index];
-    const auto difference = std::abs(change_entry.value - player_number);
-    if (difference > budget_) { return; }
-    player_number = change_entry.value;
-    budget_ -= difference;
-  }
-
-  const std::vector<int>& ref_numbers() const { return ref_numbers_; }
-  const std::vector<int>& player_numbers() const { return player_numbers_; }
-  bool UserHasBudget() const { return budget_ > 0; }
-
- private:
-  std::vector<int> ref_numbers_{};
-  std::vector<int> player_numbers_{};
-  int budget_{};
-};
-
-// 😱 Mostly not a great idea in C++.
-int GetNextChangeEntryFromUser(const Game& game, ChangeEntry& result) {
-  game.Print();
-  std::cout << "Please enter number to change: ";
-  int index{};
-  std::cin >> index;
-  if ((index < 0) || (index >= game.player_numbers().size())) {
-    return kError;  // Usually some constant defined elsewhere.
-  }
-  result.index = index;
-  std::cout << "Please provide a new value: ";
-  std::cin >> result.value;
-  return kSuccess;  // Typically a 0, but using a constant is better.
-}
-
-std::string GetFailureReason(int constant) {
-  // Some logic to return a message.
-  if (constant == kError) { return "Provided index is out of range."; }
-  return "Unknown error encountered.";
-}
-
-int main() {
-  Game game{{42, 49, 23}, {10, 40, 24}, 10};
-  while (game.UserHasBudget()) {
-    // Cannot be const, cannot use auto, has to allocate.
-    ChangeEntry change_entry{};
-    const auto error_code = GetNextChangeEntryFromUser(game, change_entry);
-    if (error_code != kSuccess) {
-      std::cerr << GetFailureReason(error_code) << std::endl;
-      continue;
-    }
-    game.ChangePlayerNumberIfPossible(change_entry);
-  }
-  game.Print();
-  if (game.CheckIfPlayerWon()) {
-    std::cout << "You win!\\n";
-  } else {
-    std::cout << "Not win today. Try again!\\n";
-  }
-}`
-
-  yield* all(
-    codeRef().selection([
-      lines(1, 4),
-      lines(1220 - 1158, 1234 - 1158),
-    ], duration),
-    camera_1().centerOn([0, 1000], duration),
-    codeRef().code(recoverable_error_codes, duration).wait(duration),
-  );
-
-  yield* all(
-    camera_1().zoom(0.6, duration),
-    camera_1().centerOn([0, 2300], duration),
-    codeRef().selection([
-      lines(1, 4),
-      lines(1235 - 1158, 1260 - 1158),
-    ], duration),
-    codeRef().code(recoverable_error_codes, duration).wait(duration),
-  );
-
-
-  // Optional
-
-  const recoverable_optional = `\
-#include <absl/log/check.h>
-
-#include <algorithm>
-#include <iostream>
-#include <optional>
-#include <vector>
-
-struct ChangeEntry {
-  int index{};
-  int value{};
-};
-
-class Game {
- public:
-  Game(std::vector<int>&& ref_numbers,
-       std::vector<int>&& player_numbers,
-       int budget)
-      : ref_numbers_{std::move(ref_numbers)},
-        player_numbers_{std::move(player_numbers)},
-        budget_{budget} {}
-
-  void Print() const {
-    std::cout << "Budget: " << budget_ << std::endl;
-    std::cout << "Reference numbers: ";
-    for (auto number : ref_numbers_) { std::cout << number << "\\t"; }
-    std::cout << std::endl;
-    std::cout << "Player numbers:    ";
-    for (auto number : player_numbers_) { std::cout << number << "\\t"; }
-    std::cout << std::endl;
-  }
-
-  bool CheckIfPlayerWon() const {
-    int win_loss_counter{};
-    for (auto i = 0UL; i < player_numbers_.size(); ++i) {
-      const auto difference = player_numbers_[i] - ref_numbers_[i];
-      if (difference > 0) win_loss_counter++;
-      if (difference < 0) win_loss_counter--;
-    }
-    return win_loss_counter > 0;
-  }
-
-  void ChangePlayerNumberIfPossible(const ChangeEntry& change_entry) {
-    // Checking:
-    //   (change_entry.index >= 0)
-    //   (change_entry.index < player_numbers_.size())
-    CHECK_GE(change_entry.index, 0);
-    CHECK_LT(change_entry.index, player_numbers_.size());
-    auto& player_number = player_numbers_[change_entry.index];
-    const auto difference = std::abs(change_entry.value - player_number);
-    if (difference > budget_) { return; }
-    player_number = change_entry.value;
-    budget_ -= difference;
-  }
-
-  const std::vector<int>& ref_numbers() const { return ref_numbers_; }
-  const std::vector<int>& player_numbers() const { return player_numbers_; }
-  bool UserHasBudget() const { return budget_ > 0; }
-
- private:
-  std::vector<int> ref_numbers_{};
-  std::vector<int> player_numbers_{};
-  int budget_{};
-};
-
-std::optional<ChangeEntry>
-GetNextChangeEntryFromUser(const Game& game) {
-  game.Print();
-  ChangeEntry entry{};
-  std::cout << "Please enter number to change: ";
-  std::cin >> entry.index;
-  if ((entry.index < 0) || (entry.index >= game.player_numbers().size())) {
-    return {};   // <-- Create an empty optional, or std:nullopt.
-  }
-  std::cout << "Please provide a new value: ";
-  std::cin >> entry.value;
-  return entry;  // <-- Optional filled with a ChangeEntry object.
-}
-
-int main() {
-  Game game{{42, 49, 23}, {10, 40, 24}, 10};
-  while (game.UserHasBudget()) {
-    const auto change_entry = GetNextChangeEntryFromUser(game);
-    if (!change_entry) {  // Also possible: change_entry.has_value().
-      std::cerr << "Error when getting a number index." << std::endl;
-      continue;
-    }
-    game.ChangePlayerNumberIfPossible(change_entry.value());
-  }
-  game.Print();
-  if (game.CheckIfPlayerWon()) {
-    std::cout << "You win!\\n";
-  } else {
-    std::cout << "Not win today. Try again!\\n";
-  }
-}`
-
-  yield* all(
-    camera_1().centerOn([0, 900], 0),
-    camera_2().centerOn([-700, -2850], 0),
-    codeRef().selection([
-      lines(1, 4),
-      lines(1109 - 1047, 1123 - 1047),
-    ], 0),
-    waitFor(duration)
-  );
-
-  yield* all(
-    stage_2().position.x(0, duration / 2),
-  );
-
-  yield* all(
-    camera_1().zoom(0.6, duration),
-    camera_1().centerOn([0, 1200], duration),
-    camera_2().centerOn([-700, -2550], duration),
-    codeRef().selection([
-      lines(4, 4),
-      lines(1110 - 1047, 1123 - 1047),
-    ], duration),
-    codeRef().code(recoverable_optional, duration).wait(duration),
-  );
-
-  yield* all(
-    stage_2().position.x(900, duration / 2),
-    camera_1().zoom(0.5, duration),
-    camera_1().centerOn([200, 1850], duration),
-    camera_2().centerOn([-700, -2550], duration),
-    codeRef().selection([
-      lines(4, 4),
-      lines(1110 - 1047, 1223 - 1047),
-    ], duration),
-    codeRef().code(recoverable_optional, duration).wait(duration),
-  );
-
-  // Expected
-
-  const recoverable_expected = `\
-#include <absl/log/check.h>
-
-#include <algorithm>
-#include <expected>
-#include <format>
-#include <iostream>
-#include <vector>
-
-struct ChangeEntry {
-  int index{};
-  int value{};
-};
-
-class Game {
- public:
-  Game(std::vector<int>&& ref_numbers,
-       std::vector<int>&& player_numbers,
-       int budget)
-      : ref_numbers_{std::move(ref_numbers)},
-        player_numbers_{std::move(player_numbers)},
-        budget_{budget} {}
-
-  void Print() const {
-    std::cout << "Budget: " << budget_ << std::endl;
-    std::cout << "Reference numbers: ";
-    for (auto number : ref_numbers_) { std::cout << number << "\\t"; }
-    std::cout << std::endl;
-    std::cout << "Player numbers:    ";
-    for (auto number : player_numbers_) { std::cout << number << "\\t"; }
-    std::cout << std::endl;
-  }
-
-  bool CheckIfPlayerWon() const {
-    int win_loss_counter{};
-    for (auto i = 0UL; i < player_numbers_.size(); ++i) {
-      const auto difference = player_numbers_[i] - ref_numbers_[i];
-      if (difference > 0) win_loss_counter++;
-      if (difference < 0) win_loss_counter--;
-    }
-    return win_loss_counter > 0;
-  }
-
-  void ChangePlayerNumberIfPossible(const ChangeEntry& change_entry) {
-    // Checking:
-    //   (change_entry.index >= 0)
-    //   (change_entry.index < player_numbers_.size())
-    CHECK_GE(change_entry.index, 0);
-    CHECK_LT(change_entry.index, player_numbers_.size());
-    auto& player_number = player_numbers_[change_entry.index];
-    const auto difference = std::abs(change_entry.value - player_number);
-    if (difference > budget_) { return; }
-    player_number = change_entry.value;
-    budget_ -= difference;
-  }
-
-  const std::vector<int>& ref_numbers() const { return ref_numbers_; }
-  const std::vector<int>& player_numbers() const { return player_numbers_; }
-  bool UserHasBudget() const { return budget_ > 0; }
-
- private:
-  std::vector<int> ref_numbers_{};
-  std::vector<int> player_numbers_{};
-  int budget_{};
-};
-
-// Requires C++23
-std::expected<ChangeEntry, std::string>
-GetNextChangeEntryFromUser(const Game& game) {
-  game.Print();
-  ChangeEntry entry{};
-  std::cout << "Please enter number to change: ";
-  std::cin >> entry.index;
-  if ((entry.index < 0) || (entry.index >= game.player_numbers().size())) {
-    return std::unexpected(
-      std::format("Index {} must be in [0, {}) interval",
-                  entry.index, game.player_numbers().size()));
-  }
-  std::cout << "Please provide a new value: ";
-  std::cin >> entry.value;
-  return entry;
-}
-
-int main() {
-  Game game{{42, 49, 23}, {10, 40, 24}, 10};
-  while (game.UserHasBudget()) {
-    const auto change_entry = GetNextChangeEntryFromUser(game);
-    if (!change_entry) {  // Also possible: change_entry.has_value().
-      std::cerr << change_entry.error() << std::endl;
-      continue;
-    }
-    game.ChangePlayerNumberIfPossible(change_entry.value());
-  }
-  game.Print();
-  if (game.CheckIfPlayerWon()) {
-    std::cout << "You win!\\n";
-  } else {
-    std::cout << "Not win today. Try again!\\n";
-  }
-}`
-
-  yield* all(
-    stage_2().position.y(-60, 0),
-    stage_2().position.x(100, duration / 2),
-  );
-
-  yield* all(
-    camera_1().zoom(0.45, duration),
-    camera_1().centerOn([200, 1850], duration),
-    camera_2().centerOn([-700, -2750], duration),
-    codeRef().selection([
-      lines(3, 4),
-      lines(1111 - 1047, 1218 - 1047),
-    ], duration),
-    codeRef().code(recoverable_expected, duration).wait(duration),
-  );
-
-
-  yield* waitFor(duration * 3);
-});
diff --git a/animation/error_handling/tsconfig.json b/animation/error_handling/tsconfig.json
deleted file mode 100644
index e7d5347..0000000
--- a/animation/error_handling/tsconfig.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
-  "extends": "@motion-canvas/2d/tsconfig.project.json",
-  "include": ["src"]
-}
diff --git a/animation/error_handling/vite.config.ts b/animation/error_handling/vite.config.ts
deleted file mode 100644
index 42d9d68..0000000
--- a/animation/error_handling/vite.config.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import {defineConfig} from 'vite';
-import motionCanvas from '@motion-canvas/vite-plugin';
-import ffmpeg from '@motion-canvas/ffmpeg';
-
-export default defineConfig({
-  plugins: [
-    motionCanvas(),
-    ffmpeg(),
-  ],
-});
diff --git a/animation/forwarding_references/.gitignore b/animation/forwarding_references/.gitignore
deleted file mode 100644
index 829b1c7..0000000
--- a/animation/forwarding_references/.gitignore
+++ /dev/null
@@ -1,15 +0,0 @@
-# Generated files
-node_modules
-output
-dist
-
-# Editor directories and files
-.vscode/*
-!.vscode/extensions.json
-.idea
-.DS_Store
-*.suo
-*.ntvs*
-*.njsproj
-*.sln
-*.sw?
diff --git a/animation/forwarding_references/package-lock.json b/animation/forwarding_references/package-lock.json
deleted file mode 100644
index 4959bff..0000000
--- a/animation/forwarding_references/package-lock.json
+++ /dev/null
@@ -1,1366 +0,0 @@
-{
-  "name": "class_templates_why",
-  "version": "0.0.0",
-  "lockfileVersion": 3,
-  "requires": true,
-  "packages": {
-    "": {
-      "name": "class_templates_why",
-      "version": "0.0.0",
-      "dependencies": {
-        "@lezer/cpp": "^1.1.2",
-        "@motion-canvas/2d": "^3.16.0",
-        "@motion-canvas/core": "^3.16.0",
-        "@motion-canvas/ffmpeg": "^1.1.0"
-      },
-      "devDependencies": {
-        "@motion-canvas/ui": "^3.16.0",
-        "@motion-canvas/vite-plugin": "^3.15.1",
-        "typescript": "^5.2.2",
-        "vite": "^4.0.0"
-      }
-    },
-    "node_modules/@codemirror/language": {
-      "version": "6.10.1",
-      "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.10.1.tgz",
-      "integrity": "sha512-5GrXzrhq6k+gL5fjkAwt90nYDmjlzTIJV8THnxNFtNKWotMIlzzN+CpqxqwXOECnUdOndmSeWntVrVcv5axWRQ==",
-      "dependencies": {
-        "@codemirror/state": "^6.0.0",
-        "@codemirror/view": "^6.23.0",
-        "@lezer/common": "^1.1.0",
-        "@lezer/highlight": "^1.0.0",
-        "@lezer/lr": "^1.0.0",
-        "style-mod": "^4.0.0"
-      }
-    },
-    "node_modules/@codemirror/state": {
-      "version": "6.4.1",
-      "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.4.1.tgz",
-      "integrity": "sha512-QkEyUiLhsJoZkbumGZlswmAhA7CBU02Wrz7zvH4SrcifbsqwlXShVXg65f3v/ts57W3dqyamEriMhij1Z3Zz4A=="
-    },
-    "node_modules/@codemirror/view": {
-      "version": "6.26.3",
-      "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.26.3.tgz",
-      "integrity": "sha512-gmqxkPALZjkgSxIeeweY/wGQXBfwTUaLs8h7OKtSwfbj9Ct3L11lD+u1sS7XHppxFQoMDiMDp07P9f3I2jWOHw==",
-      "dependencies": {
-        "@codemirror/state": "^6.4.0",
-        "style-mod": "^4.1.0",
-        "w3c-keyname": "^2.2.4"
-      }
-    },
-    "node_modules/@esbuild/android-arm": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
-      "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==",
-      "cpu": [
-        "arm"
-      ],
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/android-arm64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz",
-      "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/android-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz",
-      "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/darwin-arm64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz",
-      "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/darwin-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz",
-      "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/freebsd-arm64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz",
-      "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "freebsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/freebsd-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz",
-      "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "freebsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-arm": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz",
-      "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==",
-      "cpu": [
-        "arm"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-arm64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz",
-      "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-ia32": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz",
-      "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==",
-      "cpu": [
-        "ia32"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-loong64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz",
-      "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==",
-      "cpu": [
-        "loong64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-mips64el": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz",
-      "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==",
-      "cpu": [
-        "mips64el"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-ppc64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz",
-      "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==",
-      "cpu": [
-        "ppc64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-riscv64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz",
-      "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==",
-      "cpu": [
-        "riscv64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-s390x": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz",
-      "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==",
-      "cpu": [
-        "s390x"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz",
-      "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/netbsd-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz",
-      "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "netbsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/openbsd-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz",
-      "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "openbsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/sunos-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz",
-      "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "sunos"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/win32-arm64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz",
-      "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/win32-ia32": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz",
-      "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==",
-      "cpu": [
-        "ia32"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/win32-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz",
-      "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@ffmpeg-installer/darwin-arm64": {
-      "version": "4.1.5",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/darwin-arm64/-/darwin-arm64-4.1.5.tgz",
-      "integrity": "sha512-hYqTiP63mXz7wSQfuqfFwfLOfwwFChUedeCVKkBtl/cliaTM7/ePI9bVzfZ2c+dWu3TqCwLDRWNSJ5pqZl8otA==",
-      "cpu": [
-        "arm64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/darwin-x64": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/darwin-x64/-/darwin-x64-4.1.0.tgz",
-      "integrity": "sha512-Z4EyG3cIFjdhlY8wI9aLUXuH8nVt7E9SlMVZtWvSPnm2sm37/yC2CwjUzyCQbJbySnef1tQwGG2Sx+uWhd9IAw==",
-      "cpu": [
-        "x64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/ffmpeg": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/ffmpeg/-/ffmpeg-1.1.0.tgz",
-      "integrity": "sha512-Uq4rmwkdGxIa9A6Bd/VqqYbT7zqh1GrT5/rFwCwKM70b42W5gIjWeVETq6SdcL0zXqDtY081Ws/iJWhr1+xvQg==",
-      "optionalDependencies": {
-        "@ffmpeg-installer/darwin-arm64": "4.1.5",
-        "@ffmpeg-installer/darwin-x64": "4.1.0",
-        "@ffmpeg-installer/linux-arm": "4.1.3",
-        "@ffmpeg-installer/linux-arm64": "4.1.4",
-        "@ffmpeg-installer/linux-ia32": "4.1.0",
-        "@ffmpeg-installer/linux-x64": "4.1.0",
-        "@ffmpeg-installer/win32-ia32": "4.1.0",
-        "@ffmpeg-installer/win32-x64": "4.1.0"
-      }
-    },
-    "node_modules/@ffmpeg-installer/linux-arm": {
-      "version": "4.1.3",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/linux-arm/-/linux-arm-4.1.3.tgz",
-      "integrity": "sha512-NDf5V6l8AfzZ8WzUGZ5mV8O/xMzRag2ETR6+TlGIsMHp81agx51cqpPItXPib/nAZYmo55Bl2L6/WOMI3A5YRg==",
-      "cpu": [
-        "arm"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/linux-arm64": {
-      "version": "4.1.4",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/linux-arm64/-/linux-arm64-4.1.4.tgz",
-      "integrity": "sha512-dljEqAOD0oIM6O6DxBW9US/FkvqvQwgJ2lGHOwHDDwu/pX8+V0YsDL1xqHbj1DMX/+nP9rxw7G7gcUvGspSoKg==",
-      "cpu": [
-        "arm64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/linux-ia32": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/linux-ia32/-/linux-ia32-4.1.0.tgz",
-      "integrity": "sha512-0LWyFQnPf+Ij9GQGD034hS6A90URNu9HCtQ5cTqo5MxOEc7Rd8gLXrJvn++UmxhU0J5RyRE9KRYstdCVUjkNOQ==",
-      "cpu": [
-        "ia32"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/linux-x64": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/linux-x64/-/linux-x64-4.1.0.tgz",
-      "integrity": "sha512-Y5BWhGLU/WpQjOArNIgXD3z5mxxdV8c41C+U15nsE5yF8tVcdCGet5zPs5Zy3Ta6bU7haGpIzryutqCGQA/W8A==",
-      "cpu": [
-        "x64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/win32-ia32": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/win32-ia32/-/win32-ia32-4.1.0.tgz",
-      "integrity": "sha512-FV2D7RlaZv/lrtdhaQ4oETwoFUsUjlUiasiZLDxhEUPdNDWcH1OU9K1xTvqz+OXLdsmYelUDuBS/zkMOTtlUAw==",
-      "cpu": [
-        "ia32"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/win32-x64": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/win32-x64/-/win32-x64-4.1.0.tgz",
-      "integrity": "sha512-Drt5u2vzDnIONf4ZEkKtFlbvwj6rI3kxw1Ck9fpudmtgaZIHD4ucsWB2lCZBXRxJgXR+2IMSti+4rtM4C4rXgg==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ]
-    },
-    "node_modules/@ffprobe-installer/darwin-arm64": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/darwin-arm64/-/darwin-arm64-5.0.1.tgz",
-      "integrity": "sha512-vwNCNjokH8hfkbl6m95zICHwkSzhEvDC3GVBcUp5HX8+4wsX10SP3B+bGur7XUzTIZ4cQpgJmEIAx6TUwRepMg==",
-      "cpu": [
-        "arm64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ]
-    },
-    "node_modules/@ffprobe-installer/darwin-x64": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/darwin-x64/-/darwin-x64-5.1.0.tgz",
-      "integrity": "sha512-J+YGscZMpQclFg31O4cfVRGmDpkVsQ2fZujoUdMAAYcP0NtqpC49Hs3SWJpBdsGB4VeqOt5TTm1vSZQzs1NkhA==",
-      "cpu": [
-        "x64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ]
-    },
-    "node_modules/@ffprobe-installer/ffprobe": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/ffprobe/-/ffprobe-2.1.2.tgz",
-      "integrity": "sha512-ZNvwk4f2magF42Zji2Ese16SMj9BS7Fui4kRjg6gTYTxY3gWZNpg85n4MIfQyI9nimHg4x/gT6FVkp/bBDuBwg==",
-      "engines": {
-        "node": ">=14.21.2"
-      },
-      "optionalDependencies": {
-        "@ffprobe-installer/darwin-arm64": "5.0.1",
-        "@ffprobe-installer/darwin-x64": "5.1.0",
-        "@ffprobe-installer/linux-arm": "5.2.0",
-        "@ffprobe-installer/linux-arm64": "5.2.0",
-        "@ffprobe-installer/linux-ia32": "5.2.0",
-        "@ffprobe-installer/linux-x64": "5.2.0",
-        "@ffprobe-installer/win32-ia32": "5.1.0",
-        "@ffprobe-installer/win32-x64": "5.1.0"
-      }
-    },
-    "node_modules/@ffprobe-installer/linux-arm": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/linux-arm/-/linux-arm-5.2.0.tgz",
-      "integrity": "sha512-PF5HqEhCY7WTWHtLDYbA/+rLS+rhslWvyBlAG1Fk8VzVlnRdl93o6hy7DE2kJgxWQbFaR3ZktPQGEzfkrmQHvQ==",
-      "cpu": [
-        "arm"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffprobe-installer/linux-arm64": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/linux-arm64/-/linux-arm64-5.2.0.tgz",
-      "integrity": "sha512-X1VvWtlLs6ScP73biVLuHD5ohKJKsMTa0vafCESOen4mOoNeLAYbxOVxDWAdFz9cpZgRiloFj5QD6nDj8E28yQ==",
-      "cpu": [
-        "arm64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffprobe-installer/linux-ia32": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/linux-ia32/-/linux-ia32-5.2.0.tgz",
-      "integrity": "sha512-TFVK5sasXyXhbIG7LtPRDmtkrkOsInwKcL43iEvEw+D9vCS2rc//mn9/0Q+BR0UoJEiMK4+ApYr/3LLVUBPOCQ==",
-      "cpu": [
-        "ia32"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffprobe-installer/linux-x64": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/linux-x64/-/linux-x64-5.2.0.tgz",
-      "integrity": "sha512-D3UeqTLYPNs7pBWPLUYGehPdRVqU8eACox4OZy3pZUZatxye2YKlvBwEfaLdL1v2Z4FOAlLUhms0kY8m8kqSRA==",
-      "cpu": [
-        "x64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffprobe-installer/win32-ia32": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/win32-ia32/-/win32-ia32-5.1.0.tgz",
-      "integrity": "sha512-5O3vOoNRxmut0/Nu9vSazTdSHasrr+zPT2B3Hm7kjmO3QVFcIfVImS6ReQnZeSy8JPJOqXts5kX5x/3KOX54XQ==",
-      "cpu": [
-        "ia32"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ]
-    },
-    "node_modules/@ffprobe-installer/win32-x64": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/win32-x64/-/win32-x64-5.1.0.tgz",
-      "integrity": "sha512-jMGYeAgkrdn4e2vvYt/qakgHRE3CPju4bn5TmdPfoAm1BlX1mY9cyMd8gf5vSzI8gH8Zq5WQAyAkmekX/8TSTg==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ]
-    },
-    "node_modules/@lezer/common": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.2.1.tgz",
-      "integrity": "sha512-yemX0ZD2xS/73llMZIK6KplkjIjf2EvAHcinDi/TfJ9hS25G0388+ClHt6/3but0oOxinTcQHJLDXh6w1crzFQ=="
-    },
-    "node_modules/@lezer/cpp": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@lezer/cpp/-/cpp-1.1.2.tgz",
-      "integrity": "sha512-macwKtyeUO0EW86r3xWQCzOV9/CF8imJLpJlPv3sDY57cPGeUZ8gXWOWNlJr52TVByMV3PayFQCA5SHEERDmVQ==",
-      "dependencies": {
-        "@lezer/common": "^1.2.0",
-        "@lezer/highlight": "^1.0.0",
-        "@lezer/lr": "^1.0.0"
-      }
-    },
-    "node_modules/@lezer/highlight": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.0.tgz",
-      "integrity": "sha512-WrS5Mw51sGrpqjlh3d4/fOwpEV2Hd3YOkp9DBt4k8XZQcoTHZFB7sx030A6OcahF4J1nDQAa3jXlTVVYH50IFA==",
-      "dependencies": {
-        "@lezer/common": "^1.0.0"
-      }
-    },
-    "node_modules/@lezer/lr": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.0.tgz",
-      "integrity": "sha512-Wst46p51km8gH0ZUmeNrtpRYmdlRHUpN1DQd3GFAyKANi8WVz8c2jHYTf1CVScFaCjQw1iO3ZZdqGDxQPRErTg==",
-      "dependencies": {
-        "@lezer/common": "^1.0.0"
-      }
-    },
-    "node_modules/@motion-canvas/2d": {
-      "version": "3.16.0",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/2d/-/2d-3.16.0.tgz",
-      "integrity": "sha512-8vyCSNE9ZCkGB4Wz8yS48h0xQ79mbmbCkhpxu4ARBrFtSVLqgo/6kz2yifJi4wPK4pCDFw5knABjukOKtMaPMQ==",
-      "dependencies": {
-        "@codemirror/language": "^6.10.1",
-        "@lezer/common": "^1.2.1",
-        "@lezer/highlight": "^1.2.0",
-        "@motion-canvas/core": "^3.16.0",
-        "code-fns": "^0.8.2",
-        "mathjax-full": "^3.2.2",
-        "parse-svg-path": "^0.1.2"
-      }
-    },
-    "node_modules/@motion-canvas/core": {
-      "version": "3.16.0",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/core/-/core-3.16.0.tgz",
-      "integrity": "sha512-egOrQjVOHWf+HMFH+AOLLSV/djf+YGGPxbz0Jbnva3C3VTH2l6MMKTdoYyGRI3w02gJO1pIo7bcePq3erlxulw==",
-      "dependencies": {
-        "@types/chroma-js": "^2.1.4",
-        "chroma-js": "^2.4.2"
-      }
-    },
-    "node_modules/@motion-canvas/ffmpeg": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/ffmpeg/-/ffmpeg-1.1.1.tgz",
-      "integrity": "sha512-w2d7oFfR3hYHXeYtFGoHp6goY+vVL0LoZ2h1b/veTH5KvE7jrLp2Kl/XPHsYJ5ZDRHUT0Nhl05DBLdXYqdSqgg==",
-      "dependencies": {
-        "@ffmpeg-installer/ffmpeg": "^1.1.0",
-        "@ffprobe-installer/ffprobe": "^2.0.0",
-        "fluent-ffmpeg": "^2.1.2"
-      },
-      "peerDependencies": {
-        "@motion-canvas/core": "^3.7.0",
-        "@motion-canvas/vite-plugin": "^3.7.0",
-        "vite": "4.x"
-      }
-    },
-    "node_modules/@motion-canvas/ui": {
-      "version": "3.16.0",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/ui/-/ui-3.16.0.tgz",
-      "integrity": "sha512-PJZnbkiJKED4nNDnN649zojfPMVRTvFOqxUExi6TdrckiLFsTJFy+dYbyMML223ekDrkmHuQU35tcs3svwfYrw==",
-      "dev": true,
-      "dependencies": {
-        "@motion-canvas/core": "^3.16.0",
-        "@preact/signals": "^1.2.1",
-        "preact": "^10.19.2"
-      }
-    },
-    "node_modules/@motion-canvas/vite-plugin": {
-      "version": "3.15.1",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/vite-plugin/-/vite-plugin-3.15.1.tgz",
-      "integrity": "sha512-yeRMJQxTcYVZGVMnNXQPm0SySQzJXnaRrggGJ2bnDHMsqxCRJt/RfIioK0LMvBaUB+UWlPsJUTMltHuq+J64JA==",
-      "dependencies": {
-        "fast-glob": "^3.3.1",
-        "follow-redirects": "^1.15.2",
-        "mime-types": "^2.1.35",
-        "source-map": "^0.6.1"
-      },
-      "peerDependencies": {
-        "vite": "4.x || 5.x"
-      }
-    },
-    "node_modules/@nodelib/fs.scandir": {
-      "version": "2.1.5",
-      "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
-      "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
-      "dependencies": {
-        "@nodelib/fs.stat": "2.0.5",
-        "run-parallel": "^1.1.9"
-      },
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/@nodelib/fs.stat": {
-      "version": "2.0.5",
-      "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
-      "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/@nodelib/fs.walk": {
-      "version": "1.2.8",
-      "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
-      "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
-      "dependencies": {
-        "@nodelib/fs.scandir": "2.1.5",
-        "fastq": "^1.6.0"
-      },
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/@preact/signals": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/@preact/signals/-/signals-1.2.3.tgz",
-      "integrity": "sha512-M2DXse3Wi8HwjI1d2vQWOLJ3lHogvqTsJYvl4ofXRXgMFQzJ7kmlZvlt5i8x5S5VwgZu0ghru4HkLqOoFfU2JQ==",
-      "dev": true,
-      "dependencies": {
-        "@preact/signals-core": "^1.6.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/preact"
-      },
-      "peerDependencies": {
-        "preact": "10.x"
-      }
-    },
-    "node_modules/@preact/signals-core": {
-      "version": "1.6.0",
-      "resolved": "https://registry.npmjs.org/@preact/signals-core/-/signals-core-1.6.0.tgz",
-      "integrity": "sha512-O/XGxwP85h1F7+ouqTMOIZ3+V1whfaV9ToIVcuyGriD4JkSD00cQo54BKdqjvBJxbenvp7ynfqRHEwI6e+NIhw==",
-      "dev": true,
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/preact"
-      }
-    },
-    "node_modules/@types/chroma-js": {
-      "version": "2.4.4",
-      "resolved": "https://registry.npmjs.org/@types/chroma-js/-/chroma-js-2.4.4.tgz",
-      "integrity": "sha512-/DTccpHTaKomqussrn+ciEvfW4k6NAHzNzs/sts1TCqg333qNxOhy8TNIoQCmbGG3Tl8KdEhkGAssb1n3mTXiQ=="
-    },
-    "node_modules/@types/hast": {
-      "version": "2.3.10",
-      "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz",
-      "integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==",
-      "dependencies": {
-        "@types/unist": "^2"
-      }
-    },
-    "node_modules/@types/unist": {
-      "version": "2.0.10",
-      "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz",
-      "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA=="
-    },
-    "node_modules/@wooorm/starry-night": {
-      "version": "1.7.0",
-      "resolved": "https://registry.npmjs.org/@wooorm/starry-night/-/starry-night-1.7.0.tgz",
-      "integrity": "sha512-ktO0nkddrovIoNW2jAUT+Cdd9n1bWjy1Ir4CdcmgTaT6E94HLlQfu7Yv62falclBEwvsuVp3bSBw23wtta1fNw==",
-      "dependencies": {
-        "@types/hast": "^2.0.0",
-        "import-meta-resolve": "^2.0.0",
-        "vscode-oniguruma": "^1.0.0",
-        "vscode-textmate": "^9.0.0"
-      },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/wooorm"
-      }
-    },
-    "node_modules/async": {
-      "version": "3.2.5",
-      "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz",
-      "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg=="
-    },
-    "node_modules/braces": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
-      "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
-      "dependencies": {
-        "fill-range": "^7.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/chroma-js": {
-      "version": "2.4.2",
-      "resolved": "https://registry.npmjs.org/chroma-js/-/chroma-js-2.4.2.tgz",
-      "integrity": "sha512-U9eDw6+wt7V8z5NncY2jJfZa+hUH8XEj8FQHgFJTrUFnJfXYf4Ml4adI2vXZOjqRDpFWtYVWypDfZwnJ+HIR4A=="
-    },
-    "node_modules/code-fns": {
-      "version": "0.8.2",
-      "resolved": "https://registry.npmjs.org/code-fns/-/code-fns-0.8.2.tgz",
-      "integrity": "sha512-3VVeq3cnWxWiWKFLsVo+XWsOXBSW2gAx2uv0ViETLNmNuygEPHlCeDAv/Zy7xXqPgXtgLZyvIJZmx+ojTgOIGA==",
-      "dependencies": {
-        "@wooorm/starry-night": "^1.2.0"
-      }
-    },
-    "node_modules/commander": {
-      "version": "9.2.0",
-      "resolved": "https://registry.npmjs.org/commander/-/commander-9.2.0.tgz",
-      "integrity": "sha512-e2i4wANQiSXgnrBlIatyHtP1odfUp0BbV5Y5nEGbxtIrStkEOAAzCUirvLBNXHLr7kwLvJl6V+4V3XV9x7Wd9w==",
-      "engines": {
-        "node": "^12.20.0 || >=14"
-      }
-    },
-    "node_modules/esbuild": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz",
-      "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==",
-      "hasInstallScript": true,
-      "bin": {
-        "esbuild": "bin/esbuild"
-      },
-      "engines": {
-        "node": ">=12"
-      },
-      "optionalDependencies": {
-        "@esbuild/android-arm": "0.18.20",
-        "@esbuild/android-arm64": "0.18.20",
-        "@esbuild/android-x64": "0.18.20",
-        "@esbuild/darwin-arm64": "0.18.20",
-        "@esbuild/darwin-x64": "0.18.20",
-        "@esbuild/freebsd-arm64": "0.18.20",
-        "@esbuild/freebsd-x64": "0.18.20",
-        "@esbuild/linux-arm": "0.18.20",
-        "@esbuild/linux-arm64": "0.18.20",
-        "@esbuild/linux-ia32": "0.18.20",
-        "@esbuild/linux-loong64": "0.18.20",
-        "@esbuild/linux-mips64el": "0.18.20",
-        "@esbuild/linux-ppc64": "0.18.20",
-        "@esbuild/linux-riscv64": "0.18.20",
-        "@esbuild/linux-s390x": "0.18.20",
-        "@esbuild/linux-x64": "0.18.20",
-        "@esbuild/netbsd-x64": "0.18.20",
-        "@esbuild/openbsd-x64": "0.18.20",
-        "@esbuild/sunos-x64": "0.18.20",
-        "@esbuild/win32-arm64": "0.18.20",
-        "@esbuild/win32-ia32": "0.18.20",
-        "@esbuild/win32-x64": "0.18.20"
-      }
-    },
-    "node_modules/esm": {
-      "version": "3.2.25",
-      "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz",
-      "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==",
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/fast-glob": {
-      "version": "3.3.2",
-      "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
-      "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
-      "dependencies": {
-        "@nodelib/fs.stat": "^2.0.2",
-        "@nodelib/fs.walk": "^1.2.3",
-        "glob-parent": "^5.1.2",
-        "merge2": "^1.3.0",
-        "micromatch": "^4.0.4"
-      },
-      "engines": {
-        "node": ">=8.6.0"
-      }
-    },
-    "node_modules/fastq": {
-      "version": "1.17.1",
-      "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz",
-      "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==",
-      "dependencies": {
-        "reusify": "^1.0.4"
-      }
-    },
-    "node_modules/fill-range": {
-      "version": "7.0.1",
-      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
-      "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
-      "dependencies": {
-        "to-regex-range": "^5.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/fluent-ffmpeg": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/fluent-ffmpeg/-/fluent-ffmpeg-2.1.2.tgz",
-      "integrity": "sha512-IZTB4kq5GK0DPp7sGQ0q/BWurGHffRtQQwVkiqDgeO6wYJLLV5ZhgNOQ65loZxxuPMKZKZcICCUnaGtlxBiR0Q==",
-      "dependencies": {
-        "async": ">=0.2.9",
-        "which": "^1.1.1"
-      },
-      "engines": {
-        "node": ">=0.8.0"
-      }
-    },
-    "node_modules/follow-redirects": {
-      "version": "1.15.6",
-      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
-      "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
-      "funding": [
-        {
-          "type": "individual",
-          "url": "https://github.com/sponsors/RubenVerborgh"
-        }
-      ],
-      "engines": {
-        "node": ">=4.0"
-      },
-      "peerDependenciesMeta": {
-        "debug": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/fsevents": {
-      "version": "2.3.3",
-      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
-      "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
-      }
-    },
-    "node_modules/glob-parent": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
-      "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
-      "dependencies": {
-        "is-glob": "^4.0.1"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "node_modules/import-meta-resolve": {
-      "version": "2.2.2",
-      "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-2.2.2.tgz",
-      "integrity": "sha512-f8KcQ1D80V7RnqVm+/lirO9zkOxjGxhaTC1IPrBGd3MEfNgmNG67tSUO9gTi2F3Blr2Az6g1vocaxzkVnWl9MA==",
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/wooorm"
-      }
-    },
-    "node_modules/is-extglob": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
-      "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/is-glob": {
-      "version": "4.0.3",
-      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
-      "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
-      "dependencies": {
-        "is-extglob": "^2.1.1"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/is-number": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
-      "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
-      "engines": {
-        "node": ">=0.12.0"
-      }
-    },
-    "node_modules/isexe": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
-      "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
-    },
-    "node_modules/mathjax-full": {
-      "version": "3.2.2",
-      "resolved": "https://registry.npmjs.org/mathjax-full/-/mathjax-full-3.2.2.tgz",
-      "integrity": "sha512-+LfG9Fik+OuI8SLwsiR02IVdjcnRCy5MufYLi0C3TdMT56L/pjB0alMVGgoWJF8pN9Rc7FESycZB9BMNWIid5w==",
-      "dependencies": {
-        "esm": "^3.2.25",
-        "mhchemparser": "^4.1.0",
-        "mj-context-menu": "^0.6.1",
-        "speech-rule-engine": "^4.0.6"
-      }
-    },
-    "node_modules/merge2": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
-      "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/mhchemparser": {
-      "version": "4.2.1",
-      "resolved": "https://registry.npmjs.org/mhchemparser/-/mhchemparser-4.2.1.tgz",
-      "integrity": "sha512-kYmyrCirqJf3zZ9t/0wGgRZ4/ZJw//VwaRVGA75C4nhE60vtnIzhl9J9ndkX/h6hxSN7pjg/cE0VxbnNM+bnDQ=="
-    },
-    "node_modules/micromatch": {
-      "version": "4.0.5",
-      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
-      "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
-      "dependencies": {
-        "braces": "^3.0.2",
-        "picomatch": "^2.3.1"
-      },
-      "engines": {
-        "node": ">=8.6"
-      }
-    },
-    "node_modules/mime-db": {
-      "version": "1.52.0",
-      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
-      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/mime-types": {
-      "version": "2.1.35",
-      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
-      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
-      "dependencies": {
-        "mime-db": "1.52.0"
-      },
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/mj-context-menu": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/mj-context-menu/-/mj-context-menu-0.6.1.tgz",
-      "integrity": "sha512-7NO5s6n10TIV96d4g2uDpG7ZDpIhMh0QNfGdJw/W47JswFcosz457wqz/b5sAKvl12sxINGFCn80NZHKwxQEXA=="
-    },
-    "node_modules/nanoid": {
-      "version": "3.3.7",
-      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
-      "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/ai"
-        }
-      ],
-      "bin": {
-        "nanoid": "bin/nanoid.cjs"
-      },
-      "engines": {
-        "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
-      }
-    },
-    "node_modules/parse-svg-path": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/parse-svg-path/-/parse-svg-path-0.1.2.tgz",
-      "integrity": "sha512-JyPSBnkTJ0AI8GGJLfMXvKq42cj5c006fnLz6fXy6zfoVjJizi8BNTpu8on8ziI1cKy9d9DGNuY17Ce7wuejpQ=="
-    },
-    "node_modules/picocolors": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
-      "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
-    },
-    "node_modules/picomatch": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
-      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
-      "engines": {
-        "node": ">=8.6"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/jonschlinkert"
-      }
-    },
-    "node_modules/postcss": {
-      "version": "8.4.38",
-      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz",
-      "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==",
-      "funding": [
-        {
-          "type": "opencollective",
-          "url": "https://opencollective.com/postcss/"
-        },
-        {
-          "type": "tidelift",
-          "url": "https://tidelift.com/funding/github/npm/postcss"
-        },
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/ai"
-        }
-      ],
-      "dependencies": {
-        "nanoid": "^3.3.7",
-        "picocolors": "^1.0.0",
-        "source-map-js": "^1.2.0"
-      },
-      "engines": {
-        "node": "^10 || ^12 || >=14"
-      }
-    },
-    "node_modules/preact": {
-      "version": "10.21.0",
-      "resolved": "https://registry.npmjs.org/preact/-/preact-10.21.0.tgz",
-      "integrity": "sha512-aQAIxtzWEwH8ou+OovWVSVNlFImL7xUCwJX3YMqA3U8iKCNC34999fFOnWjYNsylgfPgMexpbk7WYOLtKr/mxg==",
-      "dev": true,
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/preact"
-      }
-    },
-    "node_modules/queue-microtask": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
-      "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/feross"
-        },
-        {
-          "type": "patreon",
-          "url": "https://www.patreon.com/feross"
-        },
-        {
-          "type": "consulting",
-          "url": "https://feross.org/support"
-        }
-      ]
-    },
-    "node_modules/reusify": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
-      "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
-      "engines": {
-        "iojs": ">=1.0.0",
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/rollup": {
-      "version": "3.29.4",
-      "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz",
-      "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==",
-      "bin": {
-        "rollup": "dist/bin/rollup"
-      },
-      "engines": {
-        "node": ">=14.18.0",
-        "npm": ">=8.0.0"
-      },
-      "optionalDependencies": {
-        "fsevents": "~2.3.2"
-      }
-    },
-    "node_modules/run-parallel": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
-      "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/feross"
-        },
-        {
-          "type": "patreon",
-          "url": "https://www.patreon.com/feross"
-        },
-        {
-          "type": "consulting",
-          "url": "https://feross.org/support"
-        }
-      ],
-      "dependencies": {
-        "queue-microtask": "^1.2.2"
-      }
-    },
-    "node_modules/source-map": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
-      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/source-map-js": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
-      "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/speech-rule-engine": {
-      "version": "4.0.7",
-      "resolved": "https://registry.npmjs.org/speech-rule-engine/-/speech-rule-engine-4.0.7.tgz",
-      "integrity": "sha512-sJrL3/wHzNwJRLBdf6CjJWIlxC04iYKkyXvYSVsWVOiC2DSkHmxsqOhEeMsBA9XK+CHuNcsdkbFDnoUfAsmp9g==",
-      "dependencies": {
-        "commander": "9.2.0",
-        "wicked-good-xpath": "1.3.0",
-        "xmldom-sre": "0.1.31"
-      },
-      "bin": {
-        "sre": "bin/sre"
-      }
-    },
-    "node_modules/style-mod": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.2.tgz",
-      "integrity": "sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw=="
-    },
-    "node_modules/to-regex-range": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
-      "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
-      "dependencies": {
-        "is-number": "^7.0.0"
-      },
-      "engines": {
-        "node": ">=8.0"
-      }
-    },
-    "node_modules/typescript": {
-      "version": "5.4.5",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz",
-      "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==",
-      "dev": true,
-      "bin": {
-        "tsc": "bin/tsc",
-        "tsserver": "bin/tsserver"
-      },
-      "engines": {
-        "node": ">=14.17"
-      }
-    },
-    "node_modules/vite": {
-      "version": "4.5.3",
-      "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.3.tgz",
-      "integrity": "sha512-kQL23kMeX92v3ph7IauVkXkikdDRsYMGTVl5KY2E9OY4ONLvkHf04MDTbnfo6NKxZiDLWzVpP5oTa8hQD8U3dg==",
-      "dependencies": {
-        "esbuild": "^0.18.10",
-        "postcss": "^8.4.27",
-        "rollup": "^3.27.1"
-      },
-      "bin": {
-        "vite": "bin/vite.js"
-      },
-      "engines": {
-        "node": "^14.18.0 || >=16.0.0"
-      },
-      "funding": {
-        "url": "https://github.com/vitejs/vite?sponsor=1"
-      },
-      "optionalDependencies": {
-        "fsevents": "~2.3.2"
-      },
-      "peerDependencies": {
-        "@types/node": ">= 14",
-        "less": "*",
-        "lightningcss": "^1.21.0",
-        "sass": "*",
-        "stylus": "*",
-        "sugarss": "*",
-        "terser": "^5.4.0"
-      },
-      "peerDependenciesMeta": {
-        "@types/node": {
-          "optional": true
-        },
-        "less": {
-          "optional": true
-        },
-        "lightningcss": {
-          "optional": true
-        },
-        "sass": {
-          "optional": true
-        },
-        "stylus": {
-          "optional": true
-        },
-        "sugarss": {
-          "optional": true
-        },
-        "terser": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/vscode-oniguruma": {
-      "version": "1.7.0",
-      "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz",
-      "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA=="
-    },
-    "node_modules/vscode-textmate": {
-      "version": "9.0.0",
-      "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-9.0.0.tgz",
-      "integrity": "sha512-Cl65diFGxz7gpwbav10HqiY/eVYTO1sjQpmRmV991Bj7wAoOAjGQ97PpQcXorDE2Uc4hnGWLY17xme+5t6MlSg=="
-    },
-    "node_modules/w3c-keyname": {
-      "version": "2.2.8",
-      "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz",
-      "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ=="
-    },
-    "node_modules/which": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
-      "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
-      "dependencies": {
-        "isexe": "^2.0.0"
-      },
-      "bin": {
-        "which": "bin/which"
-      }
-    },
-    "node_modules/wicked-good-xpath": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/wicked-good-xpath/-/wicked-good-xpath-1.3.0.tgz",
-      "integrity": "sha512-Gd9+TUn5nXdwj/hFsPVx5cuHHiF5Bwuc30jZ4+ronF1qHK5O7HD0sgmXWSEgwKquT3ClLoKPVbO6qGwVwLzvAw=="
-    },
-    "node_modules/xmldom-sre": {
-      "version": "0.1.31",
-      "resolved": "https://registry.npmjs.org/xmldom-sre/-/xmldom-sre-0.1.31.tgz",
-      "integrity": "sha512-f9s+fUkX04BxQf+7mMWAp5zk61pciie+fFLC9hX9UVvCeJQfNHRHXpeo5MPcR0EUf57PYLdt+ZO4f3Ipk2oZUw==",
-      "engines": {
-        "node": ">=0.1"
-      }
-    }
-  }
-}
diff --git a/animation/forwarding_references/package.json b/animation/forwarding_references/package.json
deleted file mode 100644
index 88b8e4d..0000000
--- a/animation/forwarding_references/package.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
-  "name": "class_templates_why",
-  "private": true,
-  "version": "0.0.0",
-  "scripts": {
-    "start": "vite",
-    "serve": "vite",
-    "build": "tsc && vite build"
-  },
-  "dependencies": {
-    "@lezer/cpp": "^1.1.2",
-    "@motion-canvas/2d": "^3.16.0",
-    "@motion-canvas/core": "^3.16.0",
-    "@motion-canvas/ffmpeg": "^1.1.0"
-  },
-  "devDependencies": {
-    "@motion-canvas/ui": "^3.16.0",
-    "@motion-canvas/vite-plugin": "^3.15.1",
-    "typescript": "^5.2.2",
-    "vite": "^4.0.0"
-  }
-}
diff --git a/animation/forwarding_references/src/functions/functions.tsx b/animation/forwarding_references/src/functions/functions.tsx
deleted file mode 100644
index 458fb31..0000000
--- a/animation/forwarding_references/src/functions/functions.tsx
+++ /dev/null
@@ -1,64 +0,0 @@
-import {
-  CodeModification,
-} from '@motion-canvas/2d/lib/components/CodeBlock';
-
-const store = (...args: [TemplateStringsArray, ...any]) => args;
-
-function to_string([strings, ...values]: [TemplateStringsArray, ...any]): string {
-  return strings.reduce((acc, str, i) => {
-    const value = values[i] ?? '';
-    return acc + str + value;
-  }, '');
-}
-
-function append(
-  template_1: TemplateStringsArray, args_1: string[],
-  template_2: TemplateStringsArray, args_2: string[]): [TemplateStringsArray, ...string[]] {
-  let new_template = Array.from<string>(template_1);
-  let new_args: Array<string> = args_1;
-  new_template[template_1.length - 1] += template_2[0]
-  new_template = new_template.concat(template_2.slice(1))
-  new_args = new_args.concat(args_2)
-  return [new_template as unknown as TemplateStringsArray, ...new_args];
-}
-
-const isCodeModification = (code: any): code is CodeModification => (code as CodeModification).from !== undefined;
-
-function simplify(
-  args_in: [TemplateStringsArray, ...any]): [TemplateStringsArray, ...string[]] {
-  const template = args_in[0]
-  const args = args_in.slice(1)
-  if (args.every((arg) => (typeof (arg) == "string") || isCodeModification(arg))) {
-    return args_in
-  }
-  let new_template: Array<any> = [];
-  let new_args: Array<any> = [];
-  let concatenate = false;
-  for (let i = 0; i <= args.length; i++) {
-    if (concatenate) {
-      concatenate = false;
-      new_template[new_template.length - 1] += template[i];
-    } else {
-      new_template.push(template[i]);
-    }
-    if (i == args.length) { break; }
-    if (typeof (args[i]) == "string" || isCodeModification(args[i])) {
-      new_args.push(args[i])
-      continue;
-    }
-    let simplified_arg = simplify(args[i]);
-    let simplified_template = simplified_arg[0]
-    let simplified_args = simplified_arg.slice(1)
-    const appended = append(
-      new_template as unknown as TemplateStringsArray,
-      new_args,
-      simplified_template,
-      simplified_args as string[]);
-    new_template = Array.from<string>(appended[0])
-    new_args = appended.slice(1)
-    concatenate = true;
-  }
-  return [new_template as unknown as TemplateStringsArray, ...new_args]
-}
-
-export {store, simplify, to_string};
diff --git a/animation/forwarding_references/src/global.css b/animation/forwarding_references/src/global.css
deleted file mode 100644
index 201f5ff..0000000
--- a/animation/forwarding_references/src/global.css
+++ /dev/null
@@ -1 +0,0 @@
-@import url('https://fonts.googleapis.com/css2?family=Fira+Mono:wght@400;500;700&display=swap');
diff --git a/animation/forwarding_references/src/motion-canvas.d.ts b/animation/forwarding_references/src/motion-canvas.d.ts
deleted file mode 100644
index 067c6a4..0000000
--- a/animation/forwarding_references/src/motion-canvas.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-/// <reference types="@motion-canvas/core/project" />
diff --git a/animation/forwarding_references/src/project.meta b/animation/forwarding_references/src/project.meta
deleted file mode 100644
index 5f34ffe..0000000
--- a/animation/forwarding_references/src/project.meta
+++ /dev/null
@@ -1,31 +0,0 @@
-{
-  "version": 0,
-  "shared": {
-    "background": "rgb(10,15,20)",
-    "range": [
-      0,
-      null
-    ],
-    "size": {
-      "x": 1920,
-      "y": 1080
-    },
-    "audioOffset": 0
-  },
-  "preview": {
-    "fps": 30,
-    "resolutionScale": 2
-  },
-  "rendering": {
-    "fps": 30,
-    "resolutionScale": 1,
-    "colorSpace": "srgb",
-    "exporter": {
-      "name": "@motion-canvas/ffmpeg",
-      "options": {
-        "fastStart": true,
-        "includeAudio": true
-      }
-    }
-  }
-}
\ No newline at end of file
diff --git a/animation/forwarding_references/src/project.ts b/animation/forwarding_references/src/project.ts
deleted file mode 100644
index 82ee0bd..0000000
--- a/animation/forwarding_references/src/project.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-import { makeProject } from '@motion-canvas/core';
-import { Code, LezerHighlighter } from '@motion-canvas/2d';
-import { parser } from '@lezer/cpp';
-import { tags } from '@lezer/highlight';
-import { HighlightStyle } from '@codemirror/language';
-
-const MyStyle = HighlightStyle.define([
-  { tag: tags.keyword, color: '#569CD6' }, // VSCode Keyword color
-  { tag: tags.controlKeyword, color: '#C586C0' }, // VSCode Control Keyword color
-  { tag: tags.operatorKeyword, color: '#C586C0' }, // VSCode Control Keyword color
-  { tag: tags.comment, color: 'gray' }, // VSCode Comment color
-  { tag: tags.className, color: '#4EC9B0' }, // VSCode Class Name color
-  { tag: tags.constant(tags.variableName), color: '#B5CEA8' }, // VSCode Constant color
-  { tag: tags.function(tags.variableName), color: '#DCDCAA' }, // VSCode Function color
-  { tag: tags.function(tags.propertyName), color: '#DCDCAA' }, // VSCode Function color
-  // { tag: tags.propertyName, color: '#DCDCAA' }, // VSCode Function color
-  { tag: tags.number, color: '#B5CEA8' }, // VSCode Number color
-  { tag: tags.string, color: '#CE9178' }, // VSCode String color
-  { tag: tags.typeName, color: '#4EC9B0' }, // VSCode Type Name color
-  { tag: tags.squareBracket, color: '#C586C0' }, // VSCode Square Bracket color
-  { tag: tags.bracket, color: '#C586C0' }, // VSCode Bracket color
-  { tag: tags.brace, color: '#DDDD22' }, // VSCode Brace color
-  { tag: tags.processingInstruction, color: '#C586C0' }, // VSCode Brace color
-  { tag: tags.arithmeticOperator, color: '#D16969' }, // VSCode Arithmetic Operator color
-]);
-
-Code.defaultHighlighter = new LezerHighlighter(parser, MyStyle);
-
-import './global.css';
-
-import example from './scenes/example?scene';
-
-
-export default makeProject({
-  scenes: [example],
-});
diff --git a/animation/forwarding_references/src/scenes/example.meta b/animation/forwarding_references/src/scenes/example.meta
deleted file mode 100644
index c31dca6..0000000
--- a/animation/forwarding_references/src/scenes/example.meta
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-  "version": 0,
-  "timeEvents": [],
-  "seed": 1820440022
-}
\ No newline at end of file
diff --git a/animation/forwarding_references/src/scenes/example.tsx b/animation/forwarding_references/src/scenes/example.tsx
deleted file mode 100644
index 2a3bf2c..0000000
--- a/animation/forwarding_references/src/scenes/example.tsx
+++ /dev/null
@@ -1,1061 +0,0 @@
-import { createRef } from '@motion-canvas/core/lib/utils';
-import { makeScene2D, Code, lines } from '@motion-canvas/2d';
-import { all, waitFor, waitUntil } from '@motion-canvas/core/lib/flow';
-import { DEFAULT } from '@motion-canvas/core/lib/signals';
-import { BBox, Vector2 } from '@motion-canvas/core/lib/types';
-
-import { store, simplify } from '../functions/functions'
-
-export default makeScene2D(function* (view) {
-  const codeRef = createRef<Code>();
-
-  yield view.add(<Code
-    ref={codeRef}
-    fontSize={50}
-    fontFamily={'Fira Mono'}
-    fontWeight={500}
-    offsetX={-1}
-    x={-600}
-  />);
-
-
-  const code_move = `\
-  void DoSmth(SomeType&& value);`
-
-
-
-  const duration = 1.0
-
-  yield* codeRef().code(code_move, 0).wait(duration);
-
-  const code_forward = `\
-  template <class SomeType>
-  void DoSmth(SomeType&& value);`
-
-  yield* codeRef().code(code_forward, duration).wait(duration);
-
-  const code_forward_with_body = `\
-  #include <utility>
-
-  template <class SomeType>
-  void DoSmth(SomeType&& value) {
-    DoSmthElse(std::forward<SomeType>(value));
-  }`
-
-  yield* all(
-    codeRef().x(-600, duration),
-    codeRef().code(code_forward_with_body, duration).wait(duration)
-  );
-
-  const forwarding_code = `\
-  class Container {
-     public:
-      void Put(const Data& data) { data_ = data; }
-
-     private:
-      Data data_{};
-  };`
-
-  yield* all(
-    codeRef().code(forwarding_code, 0).wait(duration),
-    codeRef().fontSize(30, 0)
-  );
-
-  const forwarding_code_with_data = `\
-  #include <iostream>
-
-  // 😱 Missing other special class methods!
-  struct Data {
-      Data& operator=(const Data& other) {
-          std::cout << "Copy assignment" << std::endl;
-          return *this;
-      }
-
-      Data& operator=(Data&& other) {
-          std::cout << "Move assignment" << std::endl;
-          return *this;
-      }
-  };
-
-  class Container {
-     public:
-      void Put(const Data& data) { data_ = data; }
-
-     private:
-      Data data_{};
-  };`
-
-  yield* all(
-    codeRef().code(forwarding_code_with_data, duration).wait(duration)
-  );
-
-  const forwarding_code_with_data_and_main = `\
-  #include <iostream>
-
-  // 😱 Missing other special class methods!
-  struct Data {
-      Data& operator=(const Data& other) {
-          std::cout << "Copy assignment" << std::endl;
-          return *this;
-      }
-
-      Data& operator=(Data&& other) {
-          std::cout << "Move assignment" << std::endl;
-          return *this;
-      }
-  };
-
-  class Container {
-     public:
-      void Put(const Data& data) { data_ = data; }
-
-     private:
-      Data data_{};
-  };
-
-  int main() {
-      Container container{};
-      Data data{};
-      container.Put(data);
-  }`
-
-  yield* all(
-    codeRef().fontSize(28, duration),
-    codeRef().code(forwarding_code_with_data_and_main, duration).wait(duration)
-  );
-
-  yield* all(
-    codeRef().selection([lines(4, 7)], duration).wait(duration),
-  );
-
-  const forwarding_code_with_data_and_main_temp = `\
-  #include <iostream>
-
-  // 😱 Missing other special class methods!
-  struct Data {
-      Data& operator=(const Data& other) {
-          std::cout << "Copy assignment" << std::endl;
-          return *this;
-      }
-
-      Data& operator=(Data&& other) {
-          std::cout << "Move assignment" << std::endl;
-          return *this;
-      }
-  };
-
-  class Container {
-     public:
-      void Put(const Data& data) { data_ = data; }
-
-     private:
-      Data data_{};
-  };
-
-  int main() {
-      Container container{};
-      container.Put(Data{});
-  }`
-  yield* all(
-    codeRef().selection(DEFAULT, 0).wait(duration),
-  );
-  yield* all(
-    codeRef().selection(lines(23, 27), duration),
-  );
-  yield* all(
-    codeRef().fontSize(28, duration),
-    codeRef().selection(lines(23, 26), duration),
-    codeRef().code(forwarding_code_with_data_and_main_temp, duration).wait(duration)
-  );
-
-  yield* all(
-    codeRef().selection([lines(23, 26), lines(4, 7)], duration).wait(duration),
-  );
-  yield* all(
-    codeRef().selection([lines(23, 26), lines(4, 7), lines(17, 18)], duration).wait(duration),
-  );
-
-  const forwarding_code_with_moving_data_and_main_temp = `\
-  #include <iostream>
-  #include <utility>
-
-  // 😱 Missing other special class methods!
-  struct Data {
-      Data& operator=(const Data& other) {
-          std::cout << "Copy assignment" << std::endl;
-          return *this;
-      }
-
-      Data& operator=(Data&& other) {
-          std::cout << "Move assignment" << std::endl;
-          return *this;
-      }
-  };
-
-  class Container {
-     public:
-      void Put(const Data& data) { data_ = data; }
-
-      void Put(Data&& data) { data_ = std::move(data); }
-
-     private:
-      Data data_{};
-  };
-
-  int main() {
-      Container container{};
-      container.Put(Data{});
-  }`
-
-  yield* all(
-    codeRef().selection(DEFAULT, 0).wait(duration),
-  );
-
-  yield* all(
-    codeRef().fontSize(28, duration),
-    codeRef().selection(lines(20, 21), duration),
-    codeRef().code(forwarding_code_with_moving_data_and_main_temp, duration).wait(duration)
-  );
-
-  yield* all(
-    codeRef().selection(codeRef().findAllRanges(/std::move\(data\)/g), duration).wait(duration)
-  );
-
-  const forwarding_code_with_moving_data_and_main_move = `\
-  #include <iostream>
-  #include <utility>
-
-  // 😱 Missing other special class methods!
-  struct Data {
-      Data& operator=(const Data& other) {
-          std::cout << "Copy assignment" << std::endl;
-          return *this;
-      }
-
-      Data& operator=(Data&& other) {
-          std::cout << "Move assignment" << std::endl;
-          return *this;
-      }
-  };
-
-  class Container {
-     public:
-      void Put(const Data& data) { data_ = data; }
-
-      void Put(Data&& data) { data_ = std::move(data); }
-
-     private:
-      Data data_{};
-  };
-
-  int main() {
-      Container container{};
-      Data data{};
-      container.Put(data);
-      container.Put(Data{});
-  }`
-
-  yield* all(
-    codeRef().fontSize(26, duration),
-    codeRef().selection(lines(25, 31), duration),
-    codeRef().code(forwarding_code_with_moving_data_and_main_move, duration).wait(duration)
-  );
-
-  const container_overloads_code = `\
-  // Assume Data is defined in this header
-  #include "data.hpp"
-  // Needed for std::move
-  #include <utility>
-
-  class Container {
-     public:
-      void Put(const Data& data) { data_ = data; }
-
-      void Put(Data&& data) { data_ = std::move(data); }
-
-     private:
-      Data data_{};
-  };`
-
-  yield* all(
-    codeRef().fontSize(35, 0),
-    codeRef().selection(DEFAULT, 0),
-    codeRef().code(container_overloads_code, 0).wait(duration)
-  );
-
-  const container_overloads_code_no_const = `\
-  // Assume Data is defined in this header
-  #include "data.hpp"
-  // Needed for std::move
-  #include <utility>
-
-  class Container {
-     public:
-      void Put(Data&& data) { data_ = std::move(data); }
-
-     private:
-      Data data_{};
-  };`
-
-  yield* all(
-    codeRef().code(container_overloads_code_no_const, duration).wait(duration)
-  );
-
-  const container_overloads_code_template = `\
-  // Assume Data is defined in this header
-  #include "data.hpp"
-  // Needed for std::move
-  #include <utility>
-
-  class Container {
-     public:
-      template <typename T>
-      void Put(T&& data) { data_ = std::move(data); }
-
-     private:
-      Data data_{};
-  };`
-
-  yield* all(
-    codeRef().code(container_overloads_code_template, duration).wait(duration)
-  );
-
-  const container_forward_code = `\
-  // Assume Data is defined in this header
-  #include "data.hpp"
-  // Needed for std::forward
-  #include <utility>
-
-  class Container {
-     public:
-      template <typename T>
-      void Put(T&& data) { data_ = std::forward<T>(data); }
-
-     private:
-      Data data_{};
-  };`
-
-  yield* all(
-    codeRef().code(container_forward_code, duration).wait(duration)
-  );
-
-  const container_forward_code_with_main = `\
-  // Needed for std::forward
-  #include <utility>
-
-  // 😱 Missing other special class methods!
-  struct Data {
-      Data& operator=(const Data& other) {
-          std::cout << "Copy assignment" << std::endl;
-          return *this;
-      }
-
-      Data& operator=(Data&& other) {
-          std::cout << "Move assignment" << std::endl;
-          return *this;
-      }
-  };
-
-  class Container {
-     public:
-      template <typename T>
-      void Put(T&& data) { data_ = std::forward<T>(data); }
-
-     private:
-      Data data_{};
-  };
-
-  int main() {
-      Container container{};
-      Data data{};
-      container.Put(data);
-      container.Put(Data{});
-  }`
-
-  yield* all(
-    codeRef().fontSize(26, duration),
-    codeRef().code(container_forward_code_with_main, duration).wait(duration)
-  );
-  yield* waitFor(duration);
-
-
-  yield* all(
-    codeRef().fontSize(55, duration),
-    codeRef().y(-250, duration),
-    codeRef().selection(codeRef().findAllRanges(/template/g), duration).wait(duration)
-  );
-
-  yield* all(
-    codeRef().y(-750, duration),
-    codeRef().selection(lines(25, 30), duration).wait(duration)
-  );
-
-  const container_forward_code_with_main_42 = `\
-  // Needed for std::forward
-  #include <utility>
-
-  // 😱 Missing other special class methods!
-  struct Data {
-      Data& operator=(const Data& other) {
-          std::cout << "Copy assignment" << std::endl;
-          return *this;
-      }
-
-      Data& operator=(Data&& other) {
-          std::cout << "Move assignment" << std::endl;
-          return *this;
-      }
-  };
-
-  class Container {
-     public:
-      template <typename T>
-      void Put(T&& data) { data_ = std::forward<T>(data); }
-
-     private:
-      Data data_{};
-  };
-
-  int main() {
-      Container container{};
-      container.Put(42);  // ❌ Won't compile.
-  }`
-
-  yield* all(
-    codeRef().fontSize(55, duration),
-    codeRef().selection(lines(25, 28), duration),
-    codeRef().x(-700, duration),
-    codeRef().code(container_forward_code_with_main_42, duration).wait(duration)
-  );
-  yield* waitFor(duration);
-
-
-  const container_forward_multi_param = `\
-  // Assume Data is defined in this header
-  #include "data.hpp"
-  // Needed for std::forward
-  #include <utility>
-
-  class Container {
-     public:
-      template <typename T, typename S>
-      void Put(T&& data_1, S&& data_2) {
-        data_1_ = std::forward<T>(data_1);
-        data_2_ = std::forward<S>(data_2);
-      }
-
-     private:
-      Data data_1_{};
-      Data data_2_{};
-  };`
-
-  yield* all(
-    codeRef().selection(DEFAULT, 0),
-    codeRef().y(0, 0),
-    codeRef().x(-800, 0),
-    codeRef().fontSize(40, 0),
-    codeRef().code(container_forward_code, 0).wait(duration)
-  );
-  yield* all(
-    codeRef().code(container_forward_multi_param, duration).wait(duration)
-  );
-  yield* all(
-    codeRef().selection(codeRef().findAllRanges(/Data data_\d_{};/g), duration).wait(duration)
-  );
-  yield* all(
-    codeRef().selection(lines(7, 11), duration).wait(duration)
-  );
-
-  const container_forward_multi_param_with_main = `\
-  // Needed for std::forward
-  #include <utility>
-
-  // 😱 Missing other special class methods!
-  struct Data {
-      Data& operator=(const Data& other) {
-          std::cout << "Copy assignment" << std::endl;
-          return *this;
-      }
-
-      Data& operator=(Data&& other) {
-          std::cout << "Move assignment" << std::endl;
-          return *this;
-      }
-  };
-
-  class Container {
-     public:
-      template <typename T, typename S>
-      void Put(T&& data_1, S&& data_2) {
-        data_1_ = std::forward<T>(data_1);
-        data_2_ = std::forward<S>(data_2);
-      }
-
-     private:
-      Data data_1_{};
-      Data data_2_{};
-  };
-
-  int main() {
-      Container container{};
-      Data data{};
-      container.Put(data, Data{});
-      std::cout << "-----" << std::endl;
-      container.Put(Data{}, data);
-      std::cout << "-----" << std::endl;
-      container.Put(Data{}, std::move(data));
-  }`
-
-  yield* all(
-    codeRef().selection(lines(15, Infinity), duration),
-    codeRef().y(-300, duration),
-    codeRef().x(-800, duration),
-    codeRef().fontSize(35, duration),
-    codeRef().code(container_forward_multi_param_with_main, duration).wait(duration)
-  );
-
-  yield* all(
-    codeRef().selection(lines(15, 27), duration),
-    codeRef().y(-100, duration),
-    codeRef().fontSize(35, duration).wait(duration),
-  );
-
-  const container_forward_multi_param_explicit_with_main = `\
-  // Needed for std::forward
-  #include <utility>
-
-  // 😱 Missing other special class methods!
-  struct Data {
-      Data& operator=(const Data& other) {
-          std::cout << "Copy assignment" << std::endl;
-          return *this;
-      }
-
-      Data& operator=(Data&& other) {
-          std::cout << "Move assignment" << std::endl;
-          return *this;
-      }
-  };
-
-  class Container {
-     public:
-      void Put(Data&& data_1, Data&& data_2) {
-        data_1_ = std::move(data_1);
-        data_2_ = std::move(data_2);
-      }
-      void Put(const Data& data_1, Data&& data_2) {
-        data_1_ = data_1;
-        data_2_ = std::move(data_2);
-      }
-      void Put(Data&& data_1, const Data& data_2) {
-        data_1_ = std::move(data_1);
-        data_2_ = data_2;
-      }
-      void Put(const Data& data_1, const Data& data_2) {
-        data_1_ = data_1;
-        data_2_ = data_2;
-      }
-
-     private:
-      Data data_1_{};
-      Data data_2_{};
-  };
-
-  int main() {
-      Container container{};
-      Data data{};
-      container.Put(data, Data{});
-      std::cout << "-----" << std::endl;
-      container.Put(Data{}, data);
-      std::cout << "-----" << std::endl;
-      container.Put(Data{}, std::move(data));
-  }`
-
-  yield* all(
-    codeRef().y(-150, duration),
-    codeRef().selection(lines(15, 38), duration),
-    codeRef().fontSize(35, duration),
-    codeRef().code(container_forward_multi_param_explicit_with_main, duration).wait(duration)
-  );
-
-  yield* waitFor(duration);
-
-  const forward_explained_code = `\
-  #include <type_traits>
-
-  template <class T>
-  T&& forward(std::remove_reference_t<T>& t) {
-    return static_cast<T&&>(t);
-  }
-
-  template <class T>
-  T&& forward(std::remove_reference_t<T>&& t) {
-    return static_cast<T&&>(t);
-  }`
-
-  yield* all(
-    codeRef().y(0, 0),
-    codeRef().selection(DEFAULT, 0),
-    codeRef().fontSize(50, 0),
-    codeRef().code(forward_explained_code, 0).wait(duration)
-  );
-
-  yield* all(
-    codeRef().selection(codeRef().findAllRanges(/std::remove_reference_t[\w<>&\s]*/g), duration).wait(duration)
-  );
-
-  yield* all(
-    codeRef().selection(codeRef().findAllRanges(/std::remove_reference_t/g), duration).wait(duration)
-  );
-
-
-  const forward_explained_code_with_print = `\
-  #include <iostream>
-  #include <type_traits>
-  #include <utility>
-
-  template <class T>
-  T&& forward(std::remove_reference_t<T>& t) {
-    return static_cast<T&&>(t);
-  }
-
-  template <class T>
-  T&& forward(std::remove_reference_t<T>&& t) {
-    return static_cast<T&&>(t);
-  }
-
-  void Print(int&) { std::cout << "lvalue" << std::endl; }
-
-  void Print(int&&) { std::cout << "rvalue" << std::endl; }
-
-  template <class SomeType>
-  void DoSmth(SomeType&& value) {
-    Print(forward<SomeType>(value));
-  }
-
-  int main() {
-    int number{};
-    DoSmth(number);             // DoSmth(int&)
-    DoSmth(42);                 // DoSmth(int&&)
-    DoSmth(std::move(number));  // DoSmth(int&&)
-  }`
-
-  yield* all(
-    codeRef().selection(DEFAULT, 0).wait(duration),
-  );
-
-  yield* all(
-    codeRef().selection(DEFAULT, duration),
-    codeRef().fontSize(25, duration),
-    codeRef().code(forward_explained_code_with_print, duration).wait(duration)
-  );
-
-  yield* all(
-    codeRef().fontSize(55, duration),
-    codeRef().y(-500, duration),
-    codeRef().selection([
-      ...codeRef().findAllRanges(/int number.*/g),
-      ...codeRef().findAllRanges(/DoSmth\(number\);.*/g),
-    ], duration).wait(duration),
-  );
-
-  yield* all(
-    codeRef().selection([
-      ...codeRef().findAllRanges(/int number.*/g),
-      ...codeRef().findAllRanges(/DoSmth\(number\);.*/g),
-      lines(17, 21)
-    ], duration).wait(duration),
-  );
-
-
-
-  const forward_explained_code_with_print_do_smth_explicit = `\
-  #include <iostream>
-  #include <type_traits>
-  #include <utility>
-
-  template <class T>
-  T&& forward(std::remove_reference_t<T>& t) {
-    return static_cast<T&&>(t);
-  }
-
-  template <class T>
-  T&& forward(std::remove_reference_t<T>&& t) {
-    return static_cast<T&&>(t);
-  }
-
-  void Print(int&) { std::cout << "lvalue" << std::endl; }
-
-  void Print(int&&) { std::cout << "rvalue" << std::endl; }
-
-  template <>
-  void DoSmth<int&>(int& && value) {
-    Print(forward<int&>(value));
-  }
-
-  int main() {
-    int number{};
-    DoSmth(number);             // DoSmth(int&)
-    DoSmth(42);                 // DoSmth(int&&)
-    DoSmth(std::move(number));  // DoSmth(int&&)
-  }`
-
-  yield* all(
-    codeRef().fontSize(55, duration),
-    codeRef().y(-500, duration),
-    codeRef().code(forward_explained_code_with_print_do_smth_explicit, duration).wait(duration)
-  );
-
-  const forward_explained_code_with_print_do_smth_explicit_collapsed = `\
-  #include <iostream>
-  #include <type_traits>
-  #include <utility>
-
-  template <class T>
-  T&& forward(std::remove_reference_t<T>& t) {
-    return static_cast<T&&>(t);
-  }
-
-  template <class T>
-  T&& forward(std::remove_reference_t<T>&& t) {
-    return static_cast<T&&>(t);
-  }
-
-  void Print(int&) { std::cout << "lvalue" << std::endl; }
-
-  void Print(int&&) { std::cout << "rvalue" << std::endl; }
-
-  template <>
-  void DoSmth<int&>(int& value) {
-    Print(forward<int&>(value));
-  }
-
-  int main() {
-    int number{};
-    DoSmth(number);             // DoSmth(int&)
-    DoSmth(42);                 // DoSmth(int&&)
-    DoSmth(std::move(number));  // DoSmth(int&&)
-  }`
-
-  yield* all(
-    codeRef().fontSize(55, duration),
-    codeRef().y(-500, duration),
-    codeRef().code(forward_explained_code_with_print_do_smth_explicit_collapsed, duration).wait(duration)
-  );
-
-  yield* all(
-    codeRef().fontSize(45, duration),
-    codeRef().y(100, duration),
-    codeRef().selection([lines(4, 12), ...codeRef().findAllRanges(/forward<int&>\(value\)/g)], duration).wait(duration),
-  );
-
-  const forward_explained_code_forward_explicit = `\
-  #include <iostream>
-  #include <type_traits>
-  #include <utility>
-
-  template <>
-  int& && forward<int&>(std::remove_reference_t<int&>& t) {
-    return static_cast<int& &&>(t);
-  }
-
-  template <>
-  int& && forward<int&>(std::remove_reference_t<int&>&& t) {
-    return static_cast<int& &&>(t);
-  }
-
-  void Print(int&) { std::cout << "lvalue" << std::endl; }
-
-  void Print(int&&) { std::cout << "rvalue" << std::endl; }
-
-  template <>
-  void DoSmth<int&>(int& value) {
-    Print(forward<int&>(value));
-  }
-
-  int main() {
-    int number{};
-    DoSmth(number);             // DoSmth(int&)
-    DoSmth(42);                 // DoSmth(int&&)
-    DoSmth(std::move(number));  // DoSmth(int&&)
-  }`
-
-
-  yield* all(
-    codeRef().code(forward_explained_code_forward_explicit, duration).wait(duration),
-  );
-
-  const forward_explained_code_forward_explicit_no_refs = `\
-  #include <iostream>
-  #include <type_traits>
-  #include <utility>
-
-  template <>
-  int& && forward<int&>(int& t) {
-    return static_cast<int& &&>(t);
-  }
-
-  template <>
-  int& && forward<int&>(int&& t) {
-    return static_cast<int& &&>(t);
-  }
-
-  void Print(int&) { std::cout << "lvalue" << std::endl; }
-
-  void Print(int&&) { std::cout << "rvalue" << std::endl; }
-
-  template <>
-  void DoSmth<int&>(int& value) {
-    Print(forward<int&>(value));
-  }
-
-  int main() {
-    int number{};
-    DoSmth(number);             // DoSmth(int&)
-    DoSmth(42);                 // DoSmth(int&&)
-    DoSmth(std::move(number));  // DoSmth(int&&)
-  }`
-
-
-  yield* all(
-    codeRef().selection([lines(4, 8), ...codeRef().findAllRanges(/forward<int&>\(value\)/g)], duration).wait(duration),
-    codeRef().code(forward_explained_code_forward_explicit_no_refs, duration).wait(duration),
-  );
-
-  const forward_explained_code_forward_explicit_no_refs_collapsed = `\
-  #include <iostream>
-  #include <type_traits>
-  #include <utility>
-
-  template <>
-  int& forward<int&>(int& t) {
-    return static_cast<int&>(t);
-  }
-
-  template <>
-  int& forward<int&>(int&& t) {
-    return static_cast<int&>(t);
-  }
-
-  void Print(int&) { std::cout << "lvalue" << std::endl; }
-
-  void Print(int&&) { std::cout << "rvalue" << std::endl; }
-
-  template <>
-  void DoSmth<int&>(int& value) {
-    Print(forward<int&>(value));
-  }
-
-  int main() {
-    int number{};
-    DoSmth(number);             // DoSmth(int&)
-    DoSmth(42);                 // DoSmth(int&&)
-    DoSmth(std::move(number));  // DoSmth(int&&)
-  }`
-
-
-  yield* all(
-    codeRef().selection([lines(4, 8), ...codeRef().findAllRanges(/forward<int&>\(value\)/g)], duration).wait(duration),
-    codeRef().code(forward_explained_code_forward_explicit_no_refs_collapsed, duration).wait(duration),
-  );
-
-  yield* all(
-    codeRef().selection([
-      lines(4, 8),
-      lines(14, 15),
-      ...codeRef().findAllRanges(/Print\(forward<int&>\(value\)\);/g)
-    ], duration).wait(duration),
-  );
-
-
-  // ----------------------
-  yield* all(
-    codeRef().y(0, 0),
-    codeRef().selection(DEFAULT, 0),
-    codeRef().fontSize(25, 0),
-    codeRef().code(forward_explained_code_with_print, 0).wait(duration)
-  );
-
-  yield* all(
-    codeRef().fontSize(55, duration),
-    codeRef().y(-500, duration),
-    codeRef().selection([
-      ...codeRef().findAllRanges(/int number.*/g),
-      ...codeRef().findAllRanges(/DoSmth\(42\);.*/g),
-      ...codeRef().findAllRanges(/DoSmth\(std::move\(number\)\);.*/g),
-    ], duration).wait(duration),
-  );
-
-  yield* all(
-    codeRef().selection([
-      ...codeRef().findAllRanges(/int number.*/g),
-      ...codeRef().findAllRanges(/DoSmth\(42\);.*/g),
-      ...codeRef().findAllRanges(/DoSmth\(std::move\(number\)\);.*/g),
-      lines(17, 21)
-    ], duration).wait(duration),
-  );
-
-
-
-  const forward_explained_code_with_print_do_smth_explicit_rvalue = `\
-  #include <iostream>
-  #include <type_traits>
-  #include <utility>
-
-  template <class T>
-  T&& forward(std::remove_reference_t<T>& t) {
-    return static_cast<T&&>(t);
-  }
-
-  template <class T>
-  T&& forward(std::remove_reference_t<T>&& t) {
-    return static_cast<T&&>(t);
-  }
-
-  void Print(int&) { std::cout << "lvalue" << std::endl; }
-
-  void Print(int&&) { std::cout << "rvalue" << std::endl; }
-
-  template <>
-  void DoSmth<int>(int&& value) {
-    Print(forward<int>(value));
-  }
-
-  int main() {
-    int number{};
-    DoSmth(number);             // DoSmth(int&)
-    DoSmth(42);                 // DoSmth(int&&)
-    DoSmth(std::move(number));  // DoSmth(int&&)
-  }`
-
-  yield* all(
-    codeRef().fontSize(55, duration),
-    codeRef().y(-500, duration),
-    codeRef().code(forward_explained_code_with_print_do_smth_explicit_rvalue, duration).wait(duration)
-  );
-
-  yield* all(
-    codeRef().fontSize(45, duration),
-    codeRef().y(100, duration),
-    codeRef().selection([
-      lines(4, 12),
-      ...codeRef().findAllRanges(/forward<int>\(value\)/g)], duration).wait(duration),
-  );
-
-  const forward_explained_code_forward_explicit_rvalue = `\
-  #include <iostream>
-  #include <type_traits>
-  #include <utility>
-
-  template <>
-  int&& forward<int>(std::remove_reference_t<int>& t) {
-    return static_cast<int&&>(t);
-  }
-
-  template <>
-  int&& forward<int>(std::remove_reference_t<int>&& t) {
-    return static_cast<int&&>(t);
-  }
-
-  void Print(int&) { std::cout << "lvalue" << std::endl; }
-
-  void Print(int&&) { std::cout << "rvalue" << std::endl; }
-
-  template <>
-  void DoSmth<int>(int&& value) {
-    Print(forward<int>(value));
-  }
-
-  int main() {
-    int number{};
-    DoSmth(number);             // DoSmth(int&)
-    DoSmth(42);                 // DoSmth(int&&)
-    DoSmth(std::move(number));  // DoSmth(int&&)
-  }`
-
-
-  yield* all(
-    codeRef().code(forward_explained_code_forward_explicit_rvalue, duration).wait(duration),
-  );
-
-  const forward_explained_code_forward_explicit_no_refs_rvalue = `\
-  #include <iostream>
-  #include <type_traits>
-  #include <utility>
-
-  template <>
-  int&& forward<int>(int& t) {
-    return static_cast<int&&>(t);
-  }
-
-  template <>
-  int&& forward<int>(int&& t) {
-    return static_cast<int&&>(t);
-  }
-
-  void Print(int&) { std::cout << "lvalue" << std::endl; }
-
-  void Print(int&&) { std::cout << "rvalue" << std::endl; }
-
-  template <>
-  void DoSmth<int>(int&& value) {
-    Print(forward<int>(value));
-  }
-
-  int main() {
-    int number{};
-    DoSmth(number);             // DoSmth(int&)
-    DoSmth(42);                 // DoSmth(int&&)
-    DoSmth(std::move(number));  // DoSmth(int&&)
-  }`
-
-
-  yield* all(
-    codeRef().code(forward_explained_code_forward_explicit_no_refs_rvalue, duration).wait(duration),
-  );
-
-  yield* all(
-    codeRef().selection([
-      lines(4, 8),
-      ...codeRef().findAllRanges(/forward<int>\(value\)/g)], duration).wait(duration),
-  );
-
-  yield* all(
-    codeRef().selection([
-      lines(4, 8),
-      lines(16, 17),
-      ...codeRef().findAllRanges(/Print\(forward<int>\(value\)\);/g)
-    ], duration).wait(duration),
-  );
-
-  const forward_second_overload = `\
-  #include <type_traits>
-  #include <utility>
-
-  template <class T>
-  T&& forward(std::remove_reference_t<T>& t) {
-    return static_cast<T&&>(t);
-  }
-
-  template <class T>
-  T&& forward(std::remove_reference_t<T>&& t) {
-    return static_cast<T&&>(t);
-  }
-
-  int main() {
-    // We can also use std::forward here of course.
-    forward<int>(42);
-    int number{};
-    forward<int>(std::move(number));
-  }`
-
-  yield* all(
-    codeRef().fontSize(42, duration),
-    codeRef().y(0, duration),
-    codeRef().selection(DEFAULT, duration).wait(duration),
-    codeRef().code(forward_second_overload, duration).wait(duration),
-  );
-
-
-  yield* waitFor(duration * 3);
-});
diff --git a/animation/forwarding_references/tsconfig.json b/animation/forwarding_references/tsconfig.json
deleted file mode 100644
index e7d5347..0000000
--- a/animation/forwarding_references/tsconfig.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
-  "extends": "@motion-canvas/2d/tsconfig.project.json",
-  "include": ["src"]
-}
diff --git a/animation/forwarding_references/vite.config.ts b/animation/forwarding_references/vite.config.ts
deleted file mode 100644
index 42d9d68..0000000
--- a/animation/forwarding_references/vite.config.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import {defineConfig} from 'vite';
-import motionCanvas from '@motion-canvas/vite-plugin';
-import ffmpeg from '@motion-canvas/ffmpeg';
-
-export default defineConfig({
-  plugins: [
-    motionCanvas(),
-    ffmpeg(),
-  ],
-});
diff --git a/animation/inheritance/.gitignore b/animation/inheritance/.gitignore
deleted file mode 100644
index 829b1c7..0000000
--- a/animation/inheritance/.gitignore
+++ /dev/null
@@ -1,15 +0,0 @@
-# Generated files
-node_modules
-output
-dist
-
-# Editor directories and files
-.vscode/*
-!.vscode/extensions.json
-.idea
-.DS_Store
-*.suo
-*.ntvs*
-*.njsproj
-*.sln
-*.sw?
diff --git a/animation/inheritance/package-lock.json b/animation/inheritance/package-lock.json
deleted file mode 100644
index 4959bff..0000000
--- a/animation/inheritance/package-lock.json
+++ /dev/null
@@ -1,1366 +0,0 @@
-{
-  "name": "class_templates_why",
-  "version": "0.0.0",
-  "lockfileVersion": 3,
-  "requires": true,
-  "packages": {
-    "": {
-      "name": "class_templates_why",
-      "version": "0.0.0",
-      "dependencies": {
-        "@lezer/cpp": "^1.1.2",
-        "@motion-canvas/2d": "^3.16.0",
-        "@motion-canvas/core": "^3.16.0",
-        "@motion-canvas/ffmpeg": "^1.1.0"
-      },
-      "devDependencies": {
-        "@motion-canvas/ui": "^3.16.0",
-        "@motion-canvas/vite-plugin": "^3.15.1",
-        "typescript": "^5.2.2",
-        "vite": "^4.0.0"
-      }
-    },
-    "node_modules/@codemirror/language": {
-      "version": "6.10.1",
-      "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.10.1.tgz",
-      "integrity": "sha512-5GrXzrhq6k+gL5fjkAwt90nYDmjlzTIJV8THnxNFtNKWotMIlzzN+CpqxqwXOECnUdOndmSeWntVrVcv5axWRQ==",
-      "dependencies": {
-        "@codemirror/state": "^6.0.0",
-        "@codemirror/view": "^6.23.0",
-        "@lezer/common": "^1.1.0",
-        "@lezer/highlight": "^1.0.0",
-        "@lezer/lr": "^1.0.0",
-        "style-mod": "^4.0.0"
-      }
-    },
-    "node_modules/@codemirror/state": {
-      "version": "6.4.1",
-      "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.4.1.tgz",
-      "integrity": "sha512-QkEyUiLhsJoZkbumGZlswmAhA7CBU02Wrz7zvH4SrcifbsqwlXShVXg65f3v/ts57W3dqyamEriMhij1Z3Zz4A=="
-    },
-    "node_modules/@codemirror/view": {
-      "version": "6.26.3",
-      "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.26.3.tgz",
-      "integrity": "sha512-gmqxkPALZjkgSxIeeweY/wGQXBfwTUaLs8h7OKtSwfbj9Ct3L11lD+u1sS7XHppxFQoMDiMDp07P9f3I2jWOHw==",
-      "dependencies": {
-        "@codemirror/state": "^6.4.0",
-        "style-mod": "^4.1.0",
-        "w3c-keyname": "^2.2.4"
-      }
-    },
-    "node_modules/@esbuild/android-arm": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
-      "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==",
-      "cpu": [
-        "arm"
-      ],
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/android-arm64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz",
-      "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/android-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz",
-      "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/darwin-arm64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz",
-      "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/darwin-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz",
-      "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/freebsd-arm64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz",
-      "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "freebsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/freebsd-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz",
-      "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "freebsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-arm": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz",
-      "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==",
-      "cpu": [
-        "arm"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-arm64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz",
-      "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-ia32": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz",
-      "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==",
-      "cpu": [
-        "ia32"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-loong64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz",
-      "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==",
-      "cpu": [
-        "loong64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-mips64el": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz",
-      "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==",
-      "cpu": [
-        "mips64el"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-ppc64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz",
-      "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==",
-      "cpu": [
-        "ppc64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-riscv64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz",
-      "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==",
-      "cpu": [
-        "riscv64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-s390x": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz",
-      "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==",
-      "cpu": [
-        "s390x"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz",
-      "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/netbsd-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz",
-      "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "netbsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/openbsd-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz",
-      "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "openbsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/sunos-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz",
-      "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "sunos"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/win32-arm64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz",
-      "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/win32-ia32": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz",
-      "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==",
-      "cpu": [
-        "ia32"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/win32-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz",
-      "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@ffmpeg-installer/darwin-arm64": {
-      "version": "4.1.5",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/darwin-arm64/-/darwin-arm64-4.1.5.tgz",
-      "integrity": "sha512-hYqTiP63mXz7wSQfuqfFwfLOfwwFChUedeCVKkBtl/cliaTM7/ePI9bVzfZ2c+dWu3TqCwLDRWNSJ5pqZl8otA==",
-      "cpu": [
-        "arm64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/darwin-x64": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/darwin-x64/-/darwin-x64-4.1.0.tgz",
-      "integrity": "sha512-Z4EyG3cIFjdhlY8wI9aLUXuH8nVt7E9SlMVZtWvSPnm2sm37/yC2CwjUzyCQbJbySnef1tQwGG2Sx+uWhd9IAw==",
-      "cpu": [
-        "x64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/ffmpeg": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/ffmpeg/-/ffmpeg-1.1.0.tgz",
-      "integrity": "sha512-Uq4rmwkdGxIa9A6Bd/VqqYbT7zqh1GrT5/rFwCwKM70b42W5gIjWeVETq6SdcL0zXqDtY081Ws/iJWhr1+xvQg==",
-      "optionalDependencies": {
-        "@ffmpeg-installer/darwin-arm64": "4.1.5",
-        "@ffmpeg-installer/darwin-x64": "4.1.0",
-        "@ffmpeg-installer/linux-arm": "4.1.3",
-        "@ffmpeg-installer/linux-arm64": "4.1.4",
-        "@ffmpeg-installer/linux-ia32": "4.1.0",
-        "@ffmpeg-installer/linux-x64": "4.1.0",
-        "@ffmpeg-installer/win32-ia32": "4.1.0",
-        "@ffmpeg-installer/win32-x64": "4.1.0"
-      }
-    },
-    "node_modules/@ffmpeg-installer/linux-arm": {
-      "version": "4.1.3",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/linux-arm/-/linux-arm-4.1.3.tgz",
-      "integrity": "sha512-NDf5V6l8AfzZ8WzUGZ5mV8O/xMzRag2ETR6+TlGIsMHp81agx51cqpPItXPib/nAZYmo55Bl2L6/WOMI3A5YRg==",
-      "cpu": [
-        "arm"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/linux-arm64": {
-      "version": "4.1.4",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/linux-arm64/-/linux-arm64-4.1.4.tgz",
-      "integrity": "sha512-dljEqAOD0oIM6O6DxBW9US/FkvqvQwgJ2lGHOwHDDwu/pX8+V0YsDL1xqHbj1DMX/+nP9rxw7G7gcUvGspSoKg==",
-      "cpu": [
-        "arm64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/linux-ia32": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/linux-ia32/-/linux-ia32-4.1.0.tgz",
-      "integrity": "sha512-0LWyFQnPf+Ij9GQGD034hS6A90URNu9HCtQ5cTqo5MxOEc7Rd8gLXrJvn++UmxhU0J5RyRE9KRYstdCVUjkNOQ==",
-      "cpu": [
-        "ia32"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/linux-x64": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/linux-x64/-/linux-x64-4.1.0.tgz",
-      "integrity": "sha512-Y5BWhGLU/WpQjOArNIgXD3z5mxxdV8c41C+U15nsE5yF8tVcdCGet5zPs5Zy3Ta6bU7haGpIzryutqCGQA/W8A==",
-      "cpu": [
-        "x64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/win32-ia32": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/win32-ia32/-/win32-ia32-4.1.0.tgz",
-      "integrity": "sha512-FV2D7RlaZv/lrtdhaQ4oETwoFUsUjlUiasiZLDxhEUPdNDWcH1OU9K1xTvqz+OXLdsmYelUDuBS/zkMOTtlUAw==",
-      "cpu": [
-        "ia32"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/win32-x64": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/win32-x64/-/win32-x64-4.1.0.tgz",
-      "integrity": "sha512-Drt5u2vzDnIONf4ZEkKtFlbvwj6rI3kxw1Ck9fpudmtgaZIHD4ucsWB2lCZBXRxJgXR+2IMSti+4rtM4C4rXgg==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ]
-    },
-    "node_modules/@ffprobe-installer/darwin-arm64": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/darwin-arm64/-/darwin-arm64-5.0.1.tgz",
-      "integrity": "sha512-vwNCNjokH8hfkbl6m95zICHwkSzhEvDC3GVBcUp5HX8+4wsX10SP3B+bGur7XUzTIZ4cQpgJmEIAx6TUwRepMg==",
-      "cpu": [
-        "arm64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ]
-    },
-    "node_modules/@ffprobe-installer/darwin-x64": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/darwin-x64/-/darwin-x64-5.1.0.tgz",
-      "integrity": "sha512-J+YGscZMpQclFg31O4cfVRGmDpkVsQ2fZujoUdMAAYcP0NtqpC49Hs3SWJpBdsGB4VeqOt5TTm1vSZQzs1NkhA==",
-      "cpu": [
-        "x64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ]
-    },
-    "node_modules/@ffprobe-installer/ffprobe": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/ffprobe/-/ffprobe-2.1.2.tgz",
-      "integrity": "sha512-ZNvwk4f2magF42Zji2Ese16SMj9BS7Fui4kRjg6gTYTxY3gWZNpg85n4MIfQyI9nimHg4x/gT6FVkp/bBDuBwg==",
-      "engines": {
-        "node": ">=14.21.2"
-      },
-      "optionalDependencies": {
-        "@ffprobe-installer/darwin-arm64": "5.0.1",
-        "@ffprobe-installer/darwin-x64": "5.1.0",
-        "@ffprobe-installer/linux-arm": "5.2.0",
-        "@ffprobe-installer/linux-arm64": "5.2.0",
-        "@ffprobe-installer/linux-ia32": "5.2.0",
-        "@ffprobe-installer/linux-x64": "5.2.0",
-        "@ffprobe-installer/win32-ia32": "5.1.0",
-        "@ffprobe-installer/win32-x64": "5.1.0"
-      }
-    },
-    "node_modules/@ffprobe-installer/linux-arm": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/linux-arm/-/linux-arm-5.2.0.tgz",
-      "integrity": "sha512-PF5HqEhCY7WTWHtLDYbA/+rLS+rhslWvyBlAG1Fk8VzVlnRdl93o6hy7DE2kJgxWQbFaR3ZktPQGEzfkrmQHvQ==",
-      "cpu": [
-        "arm"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffprobe-installer/linux-arm64": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/linux-arm64/-/linux-arm64-5.2.0.tgz",
-      "integrity": "sha512-X1VvWtlLs6ScP73biVLuHD5ohKJKsMTa0vafCESOen4mOoNeLAYbxOVxDWAdFz9cpZgRiloFj5QD6nDj8E28yQ==",
-      "cpu": [
-        "arm64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffprobe-installer/linux-ia32": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/linux-ia32/-/linux-ia32-5.2.0.tgz",
-      "integrity": "sha512-TFVK5sasXyXhbIG7LtPRDmtkrkOsInwKcL43iEvEw+D9vCS2rc//mn9/0Q+BR0UoJEiMK4+ApYr/3LLVUBPOCQ==",
-      "cpu": [
-        "ia32"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffprobe-installer/linux-x64": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/linux-x64/-/linux-x64-5.2.0.tgz",
-      "integrity": "sha512-D3UeqTLYPNs7pBWPLUYGehPdRVqU8eACox4OZy3pZUZatxye2YKlvBwEfaLdL1v2Z4FOAlLUhms0kY8m8kqSRA==",
-      "cpu": [
-        "x64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffprobe-installer/win32-ia32": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/win32-ia32/-/win32-ia32-5.1.0.tgz",
-      "integrity": "sha512-5O3vOoNRxmut0/Nu9vSazTdSHasrr+zPT2B3Hm7kjmO3QVFcIfVImS6ReQnZeSy8JPJOqXts5kX5x/3KOX54XQ==",
-      "cpu": [
-        "ia32"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ]
-    },
-    "node_modules/@ffprobe-installer/win32-x64": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/win32-x64/-/win32-x64-5.1.0.tgz",
-      "integrity": "sha512-jMGYeAgkrdn4e2vvYt/qakgHRE3CPju4bn5TmdPfoAm1BlX1mY9cyMd8gf5vSzI8gH8Zq5WQAyAkmekX/8TSTg==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ]
-    },
-    "node_modules/@lezer/common": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.2.1.tgz",
-      "integrity": "sha512-yemX0ZD2xS/73llMZIK6KplkjIjf2EvAHcinDi/TfJ9hS25G0388+ClHt6/3but0oOxinTcQHJLDXh6w1crzFQ=="
-    },
-    "node_modules/@lezer/cpp": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@lezer/cpp/-/cpp-1.1.2.tgz",
-      "integrity": "sha512-macwKtyeUO0EW86r3xWQCzOV9/CF8imJLpJlPv3sDY57cPGeUZ8gXWOWNlJr52TVByMV3PayFQCA5SHEERDmVQ==",
-      "dependencies": {
-        "@lezer/common": "^1.2.0",
-        "@lezer/highlight": "^1.0.0",
-        "@lezer/lr": "^1.0.0"
-      }
-    },
-    "node_modules/@lezer/highlight": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.0.tgz",
-      "integrity": "sha512-WrS5Mw51sGrpqjlh3d4/fOwpEV2Hd3YOkp9DBt4k8XZQcoTHZFB7sx030A6OcahF4J1nDQAa3jXlTVVYH50IFA==",
-      "dependencies": {
-        "@lezer/common": "^1.0.0"
-      }
-    },
-    "node_modules/@lezer/lr": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.0.tgz",
-      "integrity": "sha512-Wst46p51km8gH0ZUmeNrtpRYmdlRHUpN1DQd3GFAyKANi8WVz8c2jHYTf1CVScFaCjQw1iO3ZZdqGDxQPRErTg==",
-      "dependencies": {
-        "@lezer/common": "^1.0.0"
-      }
-    },
-    "node_modules/@motion-canvas/2d": {
-      "version": "3.16.0",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/2d/-/2d-3.16.0.tgz",
-      "integrity": "sha512-8vyCSNE9ZCkGB4Wz8yS48h0xQ79mbmbCkhpxu4ARBrFtSVLqgo/6kz2yifJi4wPK4pCDFw5knABjukOKtMaPMQ==",
-      "dependencies": {
-        "@codemirror/language": "^6.10.1",
-        "@lezer/common": "^1.2.1",
-        "@lezer/highlight": "^1.2.0",
-        "@motion-canvas/core": "^3.16.0",
-        "code-fns": "^0.8.2",
-        "mathjax-full": "^3.2.2",
-        "parse-svg-path": "^0.1.2"
-      }
-    },
-    "node_modules/@motion-canvas/core": {
-      "version": "3.16.0",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/core/-/core-3.16.0.tgz",
-      "integrity": "sha512-egOrQjVOHWf+HMFH+AOLLSV/djf+YGGPxbz0Jbnva3C3VTH2l6MMKTdoYyGRI3w02gJO1pIo7bcePq3erlxulw==",
-      "dependencies": {
-        "@types/chroma-js": "^2.1.4",
-        "chroma-js": "^2.4.2"
-      }
-    },
-    "node_modules/@motion-canvas/ffmpeg": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/ffmpeg/-/ffmpeg-1.1.1.tgz",
-      "integrity": "sha512-w2d7oFfR3hYHXeYtFGoHp6goY+vVL0LoZ2h1b/veTH5KvE7jrLp2Kl/XPHsYJ5ZDRHUT0Nhl05DBLdXYqdSqgg==",
-      "dependencies": {
-        "@ffmpeg-installer/ffmpeg": "^1.1.0",
-        "@ffprobe-installer/ffprobe": "^2.0.0",
-        "fluent-ffmpeg": "^2.1.2"
-      },
-      "peerDependencies": {
-        "@motion-canvas/core": "^3.7.0",
-        "@motion-canvas/vite-plugin": "^3.7.0",
-        "vite": "4.x"
-      }
-    },
-    "node_modules/@motion-canvas/ui": {
-      "version": "3.16.0",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/ui/-/ui-3.16.0.tgz",
-      "integrity": "sha512-PJZnbkiJKED4nNDnN649zojfPMVRTvFOqxUExi6TdrckiLFsTJFy+dYbyMML223ekDrkmHuQU35tcs3svwfYrw==",
-      "dev": true,
-      "dependencies": {
-        "@motion-canvas/core": "^3.16.0",
-        "@preact/signals": "^1.2.1",
-        "preact": "^10.19.2"
-      }
-    },
-    "node_modules/@motion-canvas/vite-plugin": {
-      "version": "3.15.1",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/vite-plugin/-/vite-plugin-3.15.1.tgz",
-      "integrity": "sha512-yeRMJQxTcYVZGVMnNXQPm0SySQzJXnaRrggGJ2bnDHMsqxCRJt/RfIioK0LMvBaUB+UWlPsJUTMltHuq+J64JA==",
-      "dependencies": {
-        "fast-glob": "^3.3.1",
-        "follow-redirects": "^1.15.2",
-        "mime-types": "^2.1.35",
-        "source-map": "^0.6.1"
-      },
-      "peerDependencies": {
-        "vite": "4.x || 5.x"
-      }
-    },
-    "node_modules/@nodelib/fs.scandir": {
-      "version": "2.1.5",
-      "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
-      "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
-      "dependencies": {
-        "@nodelib/fs.stat": "2.0.5",
-        "run-parallel": "^1.1.9"
-      },
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/@nodelib/fs.stat": {
-      "version": "2.0.5",
-      "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
-      "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/@nodelib/fs.walk": {
-      "version": "1.2.8",
-      "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
-      "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
-      "dependencies": {
-        "@nodelib/fs.scandir": "2.1.5",
-        "fastq": "^1.6.0"
-      },
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/@preact/signals": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/@preact/signals/-/signals-1.2.3.tgz",
-      "integrity": "sha512-M2DXse3Wi8HwjI1d2vQWOLJ3lHogvqTsJYvl4ofXRXgMFQzJ7kmlZvlt5i8x5S5VwgZu0ghru4HkLqOoFfU2JQ==",
-      "dev": true,
-      "dependencies": {
-        "@preact/signals-core": "^1.6.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/preact"
-      },
-      "peerDependencies": {
-        "preact": "10.x"
-      }
-    },
-    "node_modules/@preact/signals-core": {
-      "version": "1.6.0",
-      "resolved": "https://registry.npmjs.org/@preact/signals-core/-/signals-core-1.6.0.tgz",
-      "integrity": "sha512-O/XGxwP85h1F7+ouqTMOIZ3+V1whfaV9ToIVcuyGriD4JkSD00cQo54BKdqjvBJxbenvp7ynfqRHEwI6e+NIhw==",
-      "dev": true,
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/preact"
-      }
-    },
-    "node_modules/@types/chroma-js": {
-      "version": "2.4.4",
-      "resolved": "https://registry.npmjs.org/@types/chroma-js/-/chroma-js-2.4.4.tgz",
-      "integrity": "sha512-/DTccpHTaKomqussrn+ciEvfW4k6NAHzNzs/sts1TCqg333qNxOhy8TNIoQCmbGG3Tl8KdEhkGAssb1n3mTXiQ=="
-    },
-    "node_modules/@types/hast": {
-      "version": "2.3.10",
-      "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz",
-      "integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==",
-      "dependencies": {
-        "@types/unist": "^2"
-      }
-    },
-    "node_modules/@types/unist": {
-      "version": "2.0.10",
-      "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz",
-      "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA=="
-    },
-    "node_modules/@wooorm/starry-night": {
-      "version": "1.7.0",
-      "resolved": "https://registry.npmjs.org/@wooorm/starry-night/-/starry-night-1.7.0.tgz",
-      "integrity": "sha512-ktO0nkddrovIoNW2jAUT+Cdd9n1bWjy1Ir4CdcmgTaT6E94HLlQfu7Yv62falclBEwvsuVp3bSBw23wtta1fNw==",
-      "dependencies": {
-        "@types/hast": "^2.0.0",
-        "import-meta-resolve": "^2.0.0",
-        "vscode-oniguruma": "^1.0.0",
-        "vscode-textmate": "^9.0.0"
-      },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/wooorm"
-      }
-    },
-    "node_modules/async": {
-      "version": "3.2.5",
-      "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz",
-      "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg=="
-    },
-    "node_modules/braces": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
-      "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
-      "dependencies": {
-        "fill-range": "^7.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/chroma-js": {
-      "version": "2.4.2",
-      "resolved": "https://registry.npmjs.org/chroma-js/-/chroma-js-2.4.2.tgz",
-      "integrity": "sha512-U9eDw6+wt7V8z5NncY2jJfZa+hUH8XEj8FQHgFJTrUFnJfXYf4Ml4adI2vXZOjqRDpFWtYVWypDfZwnJ+HIR4A=="
-    },
-    "node_modules/code-fns": {
-      "version": "0.8.2",
-      "resolved": "https://registry.npmjs.org/code-fns/-/code-fns-0.8.2.tgz",
-      "integrity": "sha512-3VVeq3cnWxWiWKFLsVo+XWsOXBSW2gAx2uv0ViETLNmNuygEPHlCeDAv/Zy7xXqPgXtgLZyvIJZmx+ojTgOIGA==",
-      "dependencies": {
-        "@wooorm/starry-night": "^1.2.0"
-      }
-    },
-    "node_modules/commander": {
-      "version": "9.2.0",
-      "resolved": "https://registry.npmjs.org/commander/-/commander-9.2.0.tgz",
-      "integrity": "sha512-e2i4wANQiSXgnrBlIatyHtP1odfUp0BbV5Y5nEGbxtIrStkEOAAzCUirvLBNXHLr7kwLvJl6V+4V3XV9x7Wd9w==",
-      "engines": {
-        "node": "^12.20.0 || >=14"
-      }
-    },
-    "node_modules/esbuild": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz",
-      "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==",
-      "hasInstallScript": true,
-      "bin": {
-        "esbuild": "bin/esbuild"
-      },
-      "engines": {
-        "node": ">=12"
-      },
-      "optionalDependencies": {
-        "@esbuild/android-arm": "0.18.20",
-        "@esbuild/android-arm64": "0.18.20",
-        "@esbuild/android-x64": "0.18.20",
-        "@esbuild/darwin-arm64": "0.18.20",
-        "@esbuild/darwin-x64": "0.18.20",
-        "@esbuild/freebsd-arm64": "0.18.20",
-        "@esbuild/freebsd-x64": "0.18.20",
-        "@esbuild/linux-arm": "0.18.20",
-        "@esbuild/linux-arm64": "0.18.20",
-        "@esbuild/linux-ia32": "0.18.20",
-        "@esbuild/linux-loong64": "0.18.20",
-        "@esbuild/linux-mips64el": "0.18.20",
-        "@esbuild/linux-ppc64": "0.18.20",
-        "@esbuild/linux-riscv64": "0.18.20",
-        "@esbuild/linux-s390x": "0.18.20",
-        "@esbuild/linux-x64": "0.18.20",
-        "@esbuild/netbsd-x64": "0.18.20",
-        "@esbuild/openbsd-x64": "0.18.20",
-        "@esbuild/sunos-x64": "0.18.20",
-        "@esbuild/win32-arm64": "0.18.20",
-        "@esbuild/win32-ia32": "0.18.20",
-        "@esbuild/win32-x64": "0.18.20"
-      }
-    },
-    "node_modules/esm": {
-      "version": "3.2.25",
-      "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz",
-      "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==",
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/fast-glob": {
-      "version": "3.3.2",
-      "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
-      "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
-      "dependencies": {
-        "@nodelib/fs.stat": "^2.0.2",
-        "@nodelib/fs.walk": "^1.2.3",
-        "glob-parent": "^5.1.2",
-        "merge2": "^1.3.0",
-        "micromatch": "^4.0.4"
-      },
-      "engines": {
-        "node": ">=8.6.0"
-      }
-    },
-    "node_modules/fastq": {
-      "version": "1.17.1",
-      "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz",
-      "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==",
-      "dependencies": {
-        "reusify": "^1.0.4"
-      }
-    },
-    "node_modules/fill-range": {
-      "version": "7.0.1",
-      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
-      "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
-      "dependencies": {
-        "to-regex-range": "^5.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/fluent-ffmpeg": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/fluent-ffmpeg/-/fluent-ffmpeg-2.1.2.tgz",
-      "integrity": "sha512-IZTB4kq5GK0DPp7sGQ0q/BWurGHffRtQQwVkiqDgeO6wYJLLV5ZhgNOQ65loZxxuPMKZKZcICCUnaGtlxBiR0Q==",
-      "dependencies": {
-        "async": ">=0.2.9",
-        "which": "^1.1.1"
-      },
-      "engines": {
-        "node": ">=0.8.0"
-      }
-    },
-    "node_modules/follow-redirects": {
-      "version": "1.15.6",
-      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
-      "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
-      "funding": [
-        {
-          "type": "individual",
-          "url": "https://github.com/sponsors/RubenVerborgh"
-        }
-      ],
-      "engines": {
-        "node": ">=4.0"
-      },
-      "peerDependenciesMeta": {
-        "debug": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/fsevents": {
-      "version": "2.3.3",
-      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
-      "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
-      }
-    },
-    "node_modules/glob-parent": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
-      "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
-      "dependencies": {
-        "is-glob": "^4.0.1"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "node_modules/import-meta-resolve": {
-      "version": "2.2.2",
-      "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-2.2.2.tgz",
-      "integrity": "sha512-f8KcQ1D80V7RnqVm+/lirO9zkOxjGxhaTC1IPrBGd3MEfNgmNG67tSUO9gTi2F3Blr2Az6g1vocaxzkVnWl9MA==",
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/wooorm"
-      }
-    },
-    "node_modules/is-extglob": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
-      "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/is-glob": {
-      "version": "4.0.3",
-      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
-      "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
-      "dependencies": {
-        "is-extglob": "^2.1.1"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/is-number": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
-      "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
-      "engines": {
-        "node": ">=0.12.0"
-      }
-    },
-    "node_modules/isexe": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
-      "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
-    },
-    "node_modules/mathjax-full": {
-      "version": "3.2.2",
-      "resolved": "https://registry.npmjs.org/mathjax-full/-/mathjax-full-3.2.2.tgz",
-      "integrity": "sha512-+LfG9Fik+OuI8SLwsiR02IVdjcnRCy5MufYLi0C3TdMT56L/pjB0alMVGgoWJF8pN9Rc7FESycZB9BMNWIid5w==",
-      "dependencies": {
-        "esm": "^3.2.25",
-        "mhchemparser": "^4.1.0",
-        "mj-context-menu": "^0.6.1",
-        "speech-rule-engine": "^4.0.6"
-      }
-    },
-    "node_modules/merge2": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
-      "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/mhchemparser": {
-      "version": "4.2.1",
-      "resolved": "https://registry.npmjs.org/mhchemparser/-/mhchemparser-4.2.1.tgz",
-      "integrity": "sha512-kYmyrCirqJf3zZ9t/0wGgRZ4/ZJw//VwaRVGA75C4nhE60vtnIzhl9J9ndkX/h6hxSN7pjg/cE0VxbnNM+bnDQ=="
-    },
-    "node_modules/micromatch": {
-      "version": "4.0.5",
-      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
-      "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
-      "dependencies": {
-        "braces": "^3.0.2",
-        "picomatch": "^2.3.1"
-      },
-      "engines": {
-        "node": ">=8.6"
-      }
-    },
-    "node_modules/mime-db": {
-      "version": "1.52.0",
-      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
-      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/mime-types": {
-      "version": "2.1.35",
-      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
-      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
-      "dependencies": {
-        "mime-db": "1.52.0"
-      },
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/mj-context-menu": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/mj-context-menu/-/mj-context-menu-0.6.1.tgz",
-      "integrity": "sha512-7NO5s6n10TIV96d4g2uDpG7ZDpIhMh0QNfGdJw/W47JswFcosz457wqz/b5sAKvl12sxINGFCn80NZHKwxQEXA=="
-    },
-    "node_modules/nanoid": {
-      "version": "3.3.7",
-      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
-      "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/ai"
-        }
-      ],
-      "bin": {
-        "nanoid": "bin/nanoid.cjs"
-      },
-      "engines": {
-        "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
-      }
-    },
-    "node_modules/parse-svg-path": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/parse-svg-path/-/parse-svg-path-0.1.2.tgz",
-      "integrity": "sha512-JyPSBnkTJ0AI8GGJLfMXvKq42cj5c006fnLz6fXy6zfoVjJizi8BNTpu8on8ziI1cKy9d9DGNuY17Ce7wuejpQ=="
-    },
-    "node_modules/picocolors": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
-      "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
-    },
-    "node_modules/picomatch": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
-      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
-      "engines": {
-        "node": ">=8.6"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/jonschlinkert"
-      }
-    },
-    "node_modules/postcss": {
-      "version": "8.4.38",
-      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz",
-      "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==",
-      "funding": [
-        {
-          "type": "opencollective",
-          "url": "https://opencollective.com/postcss/"
-        },
-        {
-          "type": "tidelift",
-          "url": "https://tidelift.com/funding/github/npm/postcss"
-        },
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/ai"
-        }
-      ],
-      "dependencies": {
-        "nanoid": "^3.3.7",
-        "picocolors": "^1.0.0",
-        "source-map-js": "^1.2.0"
-      },
-      "engines": {
-        "node": "^10 || ^12 || >=14"
-      }
-    },
-    "node_modules/preact": {
-      "version": "10.21.0",
-      "resolved": "https://registry.npmjs.org/preact/-/preact-10.21.0.tgz",
-      "integrity": "sha512-aQAIxtzWEwH8ou+OovWVSVNlFImL7xUCwJX3YMqA3U8iKCNC34999fFOnWjYNsylgfPgMexpbk7WYOLtKr/mxg==",
-      "dev": true,
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/preact"
-      }
-    },
-    "node_modules/queue-microtask": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
-      "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/feross"
-        },
-        {
-          "type": "patreon",
-          "url": "https://www.patreon.com/feross"
-        },
-        {
-          "type": "consulting",
-          "url": "https://feross.org/support"
-        }
-      ]
-    },
-    "node_modules/reusify": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
-      "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
-      "engines": {
-        "iojs": ">=1.0.0",
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/rollup": {
-      "version": "3.29.4",
-      "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz",
-      "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==",
-      "bin": {
-        "rollup": "dist/bin/rollup"
-      },
-      "engines": {
-        "node": ">=14.18.0",
-        "npm": ">=8.0.0"
-      },
-      "optionalDependencies": {
-        "fsevents": "~2.3.2"
-      }
-    },
-    "node_modules/run-parallel": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
-      "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/feross"
-        },
-        {
-          "type": "patreon",
-          "url": "https://www.patreon.com/feross"
-        },
-        {
-          "type": "consulting",
-          "url": "https://feross.org/support"
-        }
-      ],
-      "dependencies": {
-        "queue-microtask": "^1.2.2"
-      }
-    },
-    "node_modules/source-map": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
-      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/source-map-js": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
-      "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/speech-rule-engine": {
-      "version": "4.0.7",
-      "resolved": "https://registry.npmjs.org/speech-rule-engine/-/speech-rule-engine-4.0.7.tgz",
-      "integrity": "sha512-sJrL3/wHzNwJRLBdf6CjJWIlxC04iYKkyXvYSVsWVOiC2DSkHmxsqOhEeMsBA9XK+CHuNcsdkbFDnoUfAsmp9g==",
-      "dependencies": {
-        "commander": "9.2.0",
-        "wicked-good-xpath": "1.3.0",
-        "xmldom-sre": "0.1.31"
-      },
-      "bin": {
-        "sre": "bin/sre"
-      }
-    },
-    "node_modules/style-mod": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.2.tgz",
-      "integrity": "sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw=="
-    },
-    "node_modules/to-regex-range": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
-      "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
-      "dependencies": {
-        "is-number": "^7.0.0"
-      },
-      "engines": {
-        "node": ">=8.0"
-      }
-    },
-    "node_modules/typescript": {
-      "version": "5.4.5",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz",
-      "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==",
-      "dev": true,
-      "bin": {
-        "tsc": "bin/tsc",
-        "tsserver": "bin/tsserver"
-      },
-      "engines": {
-        "node": ">=14.17"
-      }
-    },
-    "node_modules/vite": {
-      "version": "4.5.3",
-      "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.3.tgz",
-      "integrity": "sha512-kQL23kMeX92v3ph7IauVkXkikdDRsYMGTVl5KY2E9OY4ONLvkHf04MDTbnfo6NKxZiDLWzVpP5oTa8hQD8U3dg==",
-      "dependencies": {
-        "esbuild": "^0.18.10",
-        "postcss": "^8.4.27",
-        "rollup": "^3.27.1"
-      },
-      "bin": {
-        "vite": "bin/vite.js"
-      },
-      "engines": {
-        "node": "^14.18.0 || >=16.0.0"
-      },
-      "funding": {
-        "url": "https://github.com/vitejs/vite?sponsor=1"
-      },
-      "optionalDependencies": {
-        "fsevents": "~2.3.2"
-      },
-      "peerDependencies": {
-        "@types/node": ">= 14",
-        "less": "*",
-        "lightningcss": "^1.21.0",
-        "sass": "*",
-        "stylus": "*",
-        "sugarss": "*",
-        "terser": "^5.4.0"
-      },
-      "peerDependenciesMeta": {
-        "@types/node": {
-          "optional": true
-        },
-        "less": {
-          "optional": true
-        },
-        "lightningcss": {
-          "optional": true
-        },
-        "sass": {
-          "optional": true
-        },
-        "stylus": {
-          "optional": true
-        },
-        "sugarss": {
-          "optional": true
-        },
-        "terser": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/vscode-oniguruma": {
-      "version": "1.7.0",
-      "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz",
-      "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA=="
-    },
-    "node_modules/vscode-textmate": {
-      "version": "9.0.0",
-      "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-9.0.0.tgz",
-      "integrity": "sha512-Cl65diFGxz7gpwbav10HqiY/eVYTO1sjQpmRmV991Bj7wAoOAjGQ97PpQcXorDE2Uc4hnGWLY17xme+5t6MlSg=="
-    },
-    "node_modules/w3c-keyname": {
-      "version": "2.2.8",
-      "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz",
-      "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ=="
-    },
-    "node_modules/which": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
-      "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
-      "dependencies": {
-        "isexe": "^2.0.0"
-      },
-      "bin": {
-        "which": "bin/which"
-      }
-    },
-    "node_modules/wicked-good-xpath": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/wicked-good-xpath/-/wicked-good-xpath-1.3.0.tgz",
-      "integrity": "sha512-Gd9+TUn5nXdwj/hFsPVx5cuHHiF5Bwuc30jZ4+ronF1qHK5O7HD0sgmXWSEgwKquT3ClLoKPVbO6qGwVwLzvAw=="
-    },
-    "node_modules/xmldom-sre": {
-      "version": "0.1.31",
-      "resolved": "https://registry.npmjs.org/xmldom-sre/-/xmldom-sre-0.1.31.tgz",
-      "integrity": "sha512-f9s+fUkX04BxQf+7mMWAp5zk61pciie+fFLC9hX9UVvCeJQfNHRHXpeo5MPcR0EUf57PYLdt+ZO4f3Ipk2oZUw==",
-      "engines": {
-        "node": ">=0.1"
-      }
-    }
-  }
-}
diff --git a/animation/inheritance/package.json b/animation/inheritance/package.json
deleted file mode 100644
index 88b8e4d..0000000
--- a/animation/inheritance/package.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
-  "name": "class_templates_why",
-  "private": true,
-  "version": "0.0.0",
-  "scripts": {
-    "start": "vite",
-    "serve": "vite",
-    "build": "tsc && vite build"
-  },
-  "dependencies": {
-    "@lezer/cpp": "^1.1.2",
-    "@motion-canvas/2d": "^3.16.0",
-    "@motion-canvas/core": "^3.16.0",
-    "@motion-canvas/ffmpeg": "^1.1.0"
-  },
-  "devDependencies": {
-    "@motion-canvas/ui": "^3.16.0",
-    "@motion-canvas/vite-plugin": "^3.15.1",
-    "typescript": "^5.2.2",
-    "vite": "^4.0.0"
-  }
-}
diff --git a/animation/inheritance/src/functions/functions.tsx b/animation/inheritance/src/functions/functions.tsx
deleted file mode 100644
index 458fb31..0000000
--- a/animation/inheritance/src/functions/functions.tsx
+++ /dev/null
@@ -1,64 +0,0 @@
-import {
-  CodeModification,
-} from '@motion-canvas/2d/lib/components/CodeBlock';
-
-const store = (...args: [TemplateStringsArray, ...any]) => args;
-
-function to_string([strings, ...values]: [TemplateStringsArray, ...any]): string {
-  return strings.reduce((acc, str, i) => {
-    const value = values[i] ?? '';
-    return acc + str + value;
-  }, '');
-}
-
-function append(
-  template_1: TemplateStringsArray, args_1: string[],
-  template_2: TemplateStringsArray, args_2: string[]): [TemplateStringsArray, ...string[]] {
-  let new_template = Array.from<string>(template_1);
-  let new_args: Array<string> = args_1;
-  new_template[template_1.length - 1] += template_2[0]
-  new_template = new_template.concat(template_2.slice(1))
-  new_args = new_args.concat(args_2)
-  return [new_template as unknown as TemplateStringsArray, ...new_args];
-}
-
-const isCodeModification = (code: any): code is CodeModification => (code as CodeModification).from !== undefined;
-
-function simplify(
-  args_in: [TemplateStringsArray, ...any]): [TemplateStringsArray, ...string[]] {
-  const template = args_in[0]
-  const args = args_in.slice(1)
-  if (args.every((arg) => (typeof (arg) == "string") || isCodeModification(arg))) {
-    return args_in
-  }
-  let new_template: Array<any> = [];
-  let new_args: Array<any> = [];
-  let concatenate = false;
-  for (let i = 0; i <= args.length; i++) {
-    if (concatenate) {
-      concatenate = false;
-      new_template[new_template.length - 1] += template[i];
-    } else {
-      new_template.push(template[i]);
-    }
-    if (i == args.length) { break; }
-    if (typeof (args[i]) == "string" || isCodeModification(args[i])) {
-      new_args.push(args[i])
-      continue;
-    }
-    let simplified_arg = simplify(args[i]);
-    let simplified_template = simplified_arg[0]
-    let simplified_args = simplified_arg.slice(1)
-    const appended = append(
-      new_template as unknown as TemplateStringsArray,
-      new_args,
-      simplified_template,
-      simplified_args as string[]);
-    new_template = Array.from<string>(appended[0])
-    new_args = appended.slice(1)
-    concatenate = true;
-  }
-  return [new_template as unknown as TemplateStringsArray, ...new_args]
-}
-
-export {store, simplify, to_string};
diff --git a/animation/inheritance/src/global.css b/animation/inheritance/src/global.css
deleted file mode 100644
index 201f5ff..0000000
--- a/animation/inheritance/src/global.css
+++ /dev/null
@@ -1 +0,0 @@
-@import url('https://fonts.googleapis.com/css2?family=Fira+Mono:wght@400;500;700&display=swap');
diff --git a/animation/inheritance/src/motion-canvas.d.ts b/animation/inheritance/src/motion-canvas.d.ts
deleted file mode 100644
index 067c6a4..0000000
--- a/animation/inheritance/src/motion-canvas.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-/// <reference types="@motion-canvas/core/project" />
diff --git a/animation/inheritance/src/project.meta b/animation/inheritance/src/project.meta
deleted file mode 100644
index 5f34ffe..0000000
--- a/animation/inheritance/src/project.meta
+++ /dev/null
@@ -1,31 +0,0 @@
-{
-  "version": 0,
-  "shared": {
-    "background": "rgb(10,15,20)",
-    "range": [
-      0,
-      null
-    ],
-    "size": {
-      "x": 1920,
-      "y": 1080
-    },
-    "audioOffset": 0
-  },
-  "preview": {
-    "fps": 30,
-    "resolutionScale": 2
-  },
-  "rendering": {
-    "fps": 30,
-    "resolutionScale": 1,
-    "colorSpace": "srgb",
-    "exporter": {
-      "name": "@motion-canvas/ffmpeg",
-      "options": {
-        "fastStart": true,
-        "includeAudio": true
-      }
-    }
-  }
-}
\ No newline at end of file
diff --git a/animation/inheritance/src/project.ts b/animation/inheritance/src/project.ts
deleted file mode 100644
index 82ee0bd..0000000
--- a/animation/inheritance/src/project.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-import { makeProject } from '@motion-canvas/core';
-import { Code, LezerHighlighter } from '@motion-canvas/2d';
-import { parser } from '@lezer/cpp';
-import { tags } from '@lezer/highlight';
-import { HighlightStyle } from '@codemirror/language';
-
-const MyStyle = HighlightStyle.define([
-  { tag: tags.keyword, color: '#569CD6' }, // VSCode Keyword color
-  { tag: tags.controlKeyword, color: '#C586C0' }, // VSCode Control Keyword color
-  { tag: tags.operatorKeyword, color: '#C586C0' }, // VSCode Control Keyword color
-  { tag: tags.comment, color: 'gray' }, // VSCode Comment color
-  { tag: tags.className, color: '#4EC9B0' }, // VSCode Class Name color
-  { tag: tags.constant(tags.variableName), color: '#B5CEA8' }, // VSCode Constant color
-  { tag: tags.function(tags.variableName), color: '#DCDCAA' }, // VSCode Function color
-  { tag: tags.function(tags.propertyName), color: '#DCDCAA' }, // VSCode Function color
-  // { tag: tags.propertyName, color: '#DCDCAA' }, // VSCode Function color
-  { tag: tags.number, color: '#B5CEA8' }, // VSCode Number color
-  { tag: tags.string, color: '#CE9178' }, // VSCode String color
-  { tag: tags.typeName, color: '#4EC9B0' }, // VSCode Type Name color
-  { tag: tags.squareBracket, color: '#C586C0' }, // VSCode Square Bracket color
-  { tag: tags.bracket, color: '#C586C0' }, // VSCode Bracket color
-  { tag: tags.brace, color: '#DDDD22' }, // VSCode Brace color
-  { tag: tags.processingInstruction, color: '#C586C0' }, // VSCode Brace color
-  { tag: tags.arithmeticOperator, color: '#D16969' }, // VSCode Arithmetic Operator color
-]);
-
-Code.defaultHighlighter = new LezerHighlighter(parser, MyStyle);
-
-import './global.css';
-
-import example from './scenes/example?scene';
-
-
-export default makeProject({
-  scenes: [example],
-});
diff --git a/animation/inheritance/src/scenes/example.meta b/animation/inheritance/src/scenes/example.meta
deleted file mode 100644
index c31dca6..0000000
--- a/animation/inheritance/src/scenes/example.meta
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-  "version": 0,
-  "timeEvents": [],
-  "seed": 1820440022
-}
\ No newline at end of file
diff --git a/animation/inheritance/src/scenes/example.tsx b/animation/inheritance/src/scenes/example.tsx
deleted file mode 100644
index 9506e29..0000000
--- a/animation/inheritance/src/scenes/example.tsx
+++ /dev/null
@@ -1,890 +0,0 @@
-import { createRef } from '@motion-canvas/core/lib/utils';
-import { makeScene2D, Code, lines } from '@motion-canvas/2d';
-import { all, waitFor, waitUntil } from '@motion-canvas/core/lib/flow';
-import { DEFAULT } from '@motion-canvas/core/lib/signals';
-import { BBox, Vector2 } from '@motion-canvas/core/lib/types';
-
-import { store, simplify } from '../functions/functions'
-
-export default makeScene2D(function* (view) {
-  const codeRef = createRef<Code>();
-
-  yield view.add(<Code
-    ref={codeRef}
-    fontSize={30}
-    fontFamily={'Fira Mono'}
-    fontWeight={500}
-    offsetX={-1}
-    x={-600}
-  />);
-
-
-  const duration = 1.0
-
-  const code_image_jpeg = `\
-#include <filesystem>
-#include <vector>
-
-// Assuming JpegIo is defined.
-
-class Image {
- public:
-  Image(const std::filesystem::path& path, const JpegIo& io) {
-    colors_ = io.Read(path);
-  }
-
-  void Save(const std::filesystem::path& path, const JpegIo& io) const {
-    io.Write(path, colors_);
-  }
-
- private:
-  std::vector<Color> colors_{};
-};
-
-int main() {
-  const Image image{"path.jpeg", JpegIo{}};
-  image.Save("other_path.jpeg", JpegIo{});
-  return 0;
-}`
-
-
-  yield* codeRef().code(code_image_jpeg, 0).wait(duration);
-  yield* waitFor(duration);
-
-  const code_image_png = `\
-#include <filesystem>
-#include <vector>
-
-// Assuming PngIo is defined.
-
-class Image {
- public:
-  Image(const std::filesystem::path& path, const PngIo& io) {
-    colors_ = io.Read(path);
-  }
-
-  void Save(const std::filesystem::path& path, const PngIo& io) const {
-    io.Write(path, colors_);
-  }
-
- private:
-  std::vector<Color> colors_{};
-};
-
-int main() {
-  const Image image{"path.png", PngIo{}};
-  image.Save("other_path.png", PngIo{});
-  return 0;
-}`
-  yield* codeRef().code(code_image_png, duration).wait(duration);
-  yield* waitFor(duration);
-
-  const code_image_png_jpeg = `\
-#include <filesystem>
-#include <vector>
-
-// Assuming PngIo, JpegIo are defined.
-
-class Image {
- public:
-  Image(const std::filesystem::path& path, const PngIo& io) {
-    colors_ = io.Read(path);
-  }
-
-  void Save(const std::filesystem::path& path, const PngIo& io) const {
-    io.Write(path, colors_);
-  }
-
-  Image(const std::filesystem::path& path, const JpegIo& io) {
-    colors_ = io.Read(path);
-  }
-
-  void Save(const std::filesystem::path& path, const JpegIo& io) const {
-    io.Write(path, colors_);
-  }
-
- private:
-  std::vector<Color> colors_{};
-};
-
-int main() {
-  const Image image{"path.jpeg", JpegIo{}};
-  image.Save("other_path.png", PngIo{});
-  return 0;
-}`
-
-  yield* all(
-    codeRef().code(code_image_png_jpeg, duration).wait(duration),
-    codeRef().fontSize(25, duration)
-  );
-  yield* waitFor(duration);
-
-
-  const code_image_interface = `\
-#include <filesystem>
-#include <vector>
-
-// Assuming IoInterface, PngIo, JpegIo are defined.
-
-class Image {
- public:
-  Image(const std::filesystem::path& path, const IoInterface& io) {
-    colors_ = io.Read(path);
-  }
-
-  void Save(const std::filesystem::path& path, const IoInterface& io) const {
-    io.Write(path, colors_);
-  }
-
- private:
-  std::vector<Color> colors_{};
-};
-
-int main() {
-  const Image image{"path.jpeg", JpegIo{}};
-  image.Save("other_path.png", PngIo{});
-  return 0;
-}`
-  yield* all(
-    codeRef().code(code_image_interface, duration).wait(duration),
-    codeRef().fontSize(30, duration)
-  );
-  yield* waitFor(duration);
-
-  const code_image_interface_jpeg = `\
-#include <filesystem>
-#include <vector>
-
-// Assuming IoInterface, PngIo, JpegIo are defined.
-
-class Image {
- public:
-  Image(const std::filesystem::path& path, const IoInterface& io) {
-    colors_ = io.Read(path);
-  }
-
-  void Save(const std::filesystem::path& path, const IoInterface& io) const {
-    io.Write(path, colors_);
-  }
-
- private:
-  std::vector<Color> colors_{};
-};
-
-int main() {
-  const Image image{"path.jpeg", JpegIo{}};
-  image.Save("other_path.jpeg", JpegIo{});
-  return 0;
-}`
-  yield* all(
-    codeRef().code(code_image_interface_jpeg, duration).wait(duration),
-    codeRef().fontSize(30, duration)
-  );
-
-  const code_image_interface_png = `\
-#include <filesystem>
-#include <vector>
-
-// Assuming IoInterface, PngIo, JpegIo are defined.
-
-class Image {
- public:
-  Image(const std::filesystem::path& path, const IoInterface& io) {
-    colors_ = io.Read(path);
-  }
-
-  void Save(const std::filesystem::path& path, const IoInterface& io) const {
-    io.Write(path, colors_);
-  }
-
- private:
-  std::vector<Color> colors_{};
-};
-
-int main() {
-  const Image image{"path.png", PngIo{}};
-  image.Save("other_path.png", PngIo{});
-  return 0;
-}`
-  yield* all(
-    codeRef().code(code_image_interface_png, duration).wait(duration),
-    codeRef().fontSize(30, duration)
-  );
-
-  yield* all(
-    codeRef().code(code_image_interface, duration).wait(duration),
-    codeRef().fontSize(30, duration)
-  );
-  yield* waitFor(duration);
-
-  const code_image_template = `\
-#include <vector>
-
-// Assuming the JpegSavingStrategy is implemented.
-
-class Image {
- public:
-  template <typename SavingStrategy>
-  void Save(const SavingStrategy& strategy) const {
-    strategy.Save(pixels_);
-  }
-
- private:
-  std::vector<Color> pixels_{};
-};
-
-int main() {
-  Image image{}; // Somehow create an image.
-  image.Save(JpegSavingStrategy{"image.jpg"});
-  return 0;
-}`
-
-  yield* all(
-    codeRef().code(code_image_template, 0).wait(duration),
-    codeRef().fontSize(30, 0)
-  );
-  yield* waitFor(duration);
-
-  const code_base_derived = `\
-#include <iostream>
-
-// Using struct here but the same holds for classes
-struct Base {
-  void DoSmth() const { std::cout << "Base DoSmth" << std::endl; }
-  void BaseMethod() const { std::cout << "BaseMethod" << std::endl; }
-  // Doesn't have to be int
-  int base_data{};
-};
-
-// Using struct here but the same holds for classes
-struct Derived : public Base {
-  void DoSmth() const { std::cout << "Derived DoSmth" << std::endl; }
-  void DerivedMethod() const { std::cout << "DerivedMethod" << std::endl; }
-  // Also can be any other type
-  float derived_data{};
-};
-
-int main() {
-  const Derived object{};
-  object.BaseMethod();
-  object.DerivedMethod();
-  object.DoSmth();
-  std::cout << "&object.base_data:    " << &object.base_data << std::endl;
-  std::cout << "&object.derived_data: " << &object.derived_data << std::endl;
-}`
-
-  yield* all(
-    codeRef().code(code_base_derived, 0).wait(duration),
-    codeRef().fontSize(30, 0)
-  );
-  yield* waitFor(duration);
-
-  const code_base_derived_base_ref = `\
-#include <iostream>
-
-// Using struct here but the same holds for classes
-struct Base {
-  void DoSmth() const { std::cout << "Base DoSmth" << std::endl; }
-  void BaseMethod() const { std::cout << "BaseMethod" << std::endl; }
-  // Doesn't have to be int
-  int base_data{};
-};
-
-// Using struct here but the same holds for classes
-struct Derived : public Base {
-  void DoSmth() const { std::cout << "Derived DoSmth" << std::endl; }
-  void DerivedMethod() const { std::cout << "DerivedMethod" << std::endl; }
-  // Also can be any other type
-  float derived_data{};
-};
-
-int main() {
-  const Derived derived{};
-  const Base& base{derived};
-  base.BaseMethod();
-  base.DoSmth();
-}`
-
-  yield* all(
-    codeRef().code(code_base_derived_base_ref, duration).wait(duration),
-    codeRef().fontSize(30, duration)
-  );
-  yield* waitFor(duration);
-
-  const code_is_integral_old = `\
-template <typename T>
-struct is_integral {
-  static constexpr inline bool value{};
-};`
-
-  yield* all(
-    codeRef().code(code_is_integral_old, 0).wait(duration),
-    codeRef().fontSize(30, 0)
-  );
-  yield* waitFor(duration);
-
-  const code_is_integral_and_const = `\
-template<class T, T v>
-struct integral_constant {
-    static constexpr inline T value = v;
-};
-
-template <typename T>
-struct is_integral {
-  static constexpr inline bool value{};
-};`
-
-  yield* all(
-    codeRef().code(code_is_integral_and_const, duration).wait(duration),
-    codeRef().fontSize(30, duration)
-  );
-  yield* waitFor(duration);
-
-  const code_is_integral_and_const_true_false = `\
-template<class T, T v>
-struct integral_constant {
-    static constexpr inline T value = v;
-};
-
-using true_type = integral_constant<bool, true>;
-using false_type = integral_constant<bool, false>;
-
-template <typename T>
-struct is_integral {
-  static constexpr inline bool value{};
-};`
-
-  yield* all(
-    codeRef().code(code_is_integral_and_const_true_false, duration).wait(duration),
-    codeRef().fontSize(30, duration)
-  );
-  yield* waitFor(duration);
-
-  const code_is_integral_final = `\
-template<class T, T v>
-struct integral_constant {
-    static constexpr inline T value = v;
-};
-
-using true_type = integral_constant<bool, true>;
-using false_type = integral_constant<bool, false>;
-
-template <typename T>
-struct is_integral : public false_type {};
-
-// Specializations for any types we deem integral.
-template <>
-struct is_integral<int> : public true_type {};
-
-static_assert(is_integral<int>::value);
-static_assert(is_integral<float>::value == false);`
-
-  yield* all(
-    codeRef().code(code_is_integral_final, duration).wait(duration),
-    codeRef().fontSize(30, duration)
-  );
-  yield* waitFor(duration);
-
-  const code_virtual_initial = `\
-#include <iostream>
-
-// 😱 We do not follow best practices for simplicity here.
-// This struct misses lots of special functions.
-// Some of them must be virtual, some deleted. Stay tuned.
-struct Base {
-  virtual void DoSmth() const { std::cout << "Base DoSmth" << std::endl; }
-};
-
-// 😱 We do not follow best practices for simplicity here.
-// This struct misses lots of special functions.
-// Some of them must be virtual, some deleted. Stay tuned.
-struct Derived : public Base {
-  void DoSmth() const override { std::cout << "Derived DoSmth" << std::endl; }
-};
-
-int main() {
-  const Derived derived{};
-  const Base base{};
-  const Base& base_ref = derived;
-  base.DoSmth();      // Calls Base implementation.
-  derived.DoSmth();   // Calls Derived implementation.
-  base_ref.DoSmth();  // Calls Derived implementation.
-}`
-
-  yield* all(
-    codeRef().code(code_virtual_initial, 0).wait(duration),
-    codeRef().fontSize(30, 0)
-  );
-  yield* waitFor(duration);
-
-  const base_derived_no_virtual = `\
-#include <iostream>
-
-struct Base {
-  // 😱 Careful! No virtual destructor! Other methods missing!
-  ~Base() { std::cout << "Base cleanup" << std::endl; }
-};
-
-struct Derived : public Base {
-  ~Derived() { std::cout << "Important cleanup" << std::endl; }
-};
-
-int main() {
-  // 😱 Code for illustrating a memory leak only! Avoid using new!
-  Base* ptr = new Derived;
-  delete ptr;  // Important cleanup is never printed!
-}`
-
-  yield* all(
-    codeRef().code(base_derived_no_virtual, 0).wait(duration),
-    codeRef().fontSize(30, 0)
-  );
-  yield* waitFor(duration);
-
-  const base_derived_virtual = `\
-#include <iostream>
-
-struct Base {
-  // 😱 Still other methods missing!
-  virtual ~Base() { std::cout << "Base cleanup" << std::endl; }
-};
-
-struct Derived : public Base {
-  ~Derived() override { std::cout << "Important cleanup" << std::endl; }
-};
-
-int main() {
-  // 😱 This will work but please don't use new!
-  Base* ptr = new Derived;
-  delete ptr;
-}`
-
-  yield* all(
-    codeRef().code(base_derived_virtual, duration).wait(duration),
-    codeRef().fontSize(30, duration)
-  );
-  yield* waitFor(duration);
-
-
-  yield* all(
-    codeRef().code(code_virtual_initial, 0).wait(duration),
-    codeRef().fontSize(30, 0)
-  );
-  yield* waitFor(duration);
-
-  const code_virtual_better = `\
-#include <iostream>
-
-struct Base {
-  virtual void DoSmth() { std::cout << "Base DoSmth" << std::endl; }
-
-  Base() = default;
-
-  Base(const Base&) = delete;
-  Base(Base&&) = delete;
-  Base& operator=(const Base&) = delete;
-  Base& operator=(Base&&) = delete;
-  virtual ~Base() = default;
-};
-
-struct Derived : public Base {
-  void DoSmth() override { std::cout << "Derived DoSmth" << std::endl; }
-};
-
-int main() {
-  Derived derived{};
-  Base base{};
-  Base& base_ref = derived;
-  base.DoSmth();      // Calls Base implementation.
-  derived.DoSmth();   // Calls Derived implementation.
-  base_ref.DoSmth();  // Calls Derived implementation.
-}`
-
-  yield* all(
-    codeRef().code(code_virtual_better, duration).wait(duration),
-    codeRef().fontSize(30, duration)
-  );
-  yield* waitFor(duration);
-
-  const code_virtual_better_noncopyable = `\
-#include <iostream>
-
-struct Noncopyable {
-  Noncopyable() = default;
-  Noncopyable(const Noncopyable&) = delete;
-  Noncopyable(Noncopyable&&) = delete;
-  Noncopyable& operator=(const Noncopyable&) = delete;
-  Noncopyable& operator=(Noncopyable&&) = delete;
-  ~Noncopyable() = default;
-};
-
-struct Base : public Noncopyable {
-  virtual void DoSmth() const { std::cout << "Base DoSmth" << std::endl; }
-  virtual ~Base() = default;
-};
-
-struct Derived : public Base {
-  void DoSmth() const override { std::cout << "Derived DoSmth" << std::endl; }
-};
-
-int main() {
-  const Derived derived{};
-  const Base base{};
-  const Base& base_ref = derived;
-  base.DoSmth();      // Calls Base implementation.
-  derived.DoSmth();   // Calls Derived implementation.
-  base_ref.DoSmth();  // Calls Derived implementation.
-}`
-
-  yield* all(
-    codeRef().code(code_virtual_better_noncopyable, duration).wait(duration),
-    codeRef().fontSize(30, duration)
-  );
-  yield* waitFor(duration);
-
-  const dynamic_cast = `\
-#include <iostream>
-
-struct Base : public Noncopyable {
-  virtual ~Base() {}
-};
-
-struct OtherBase : public Noncopyable {
-  virtual ~OtherBase() {}
-};
-
-struct Derived : public Base {};
-
-int main() {
-  const Derived object{};
-  const Base& base_ref{object};
-  const OtherBase other_base{};
-  const OtherBase& other_base_ref{other_base};
-  const Derived& derived_ref = dynamic_cast<const Derived&>(base_ref);
-  // other_derived_ptr will be nullptr because it is not derived from OtherBase.
-  const Derived* other_derived_ptr =
-      dynamic_cast<const Derived*>(&other_base_ref);
-  // ❌ The following will throw a std::bad_cast.
-  // const Derived& other_derived_ref = dynamic_cast<const
-  // Derived&>(other_base_ref);
-}`
-
-  yield* all(
-    codeRef().code(dynamic_cast, 0).wait(duration),
-    codeRef().fontSize(30, 0)
-  );
-  yield* waitFor(duration);
-
-  yield* all(
-    codeRef().code(code_virtual_better_noncopyable, 0).wait(duration),
-    codeRef().fontSize(30, 0)
-  );
-  yield* waitFor(duration);
-
-  const code_virtual_better_noncopyable_interface = `\
-#include <iostream>
-
-struct Noncopyable {
-  Noncopyable() = default;
-  Noncopyable(const Noncopyable&) = delete;
-  Noncopyable(Noncopyable&&) = delete;
-  Noncopyable& operator=(const Noncopyable&) = delete;
-  Noncopyable& operator=(Noncopyable&&) = delete;
-  ~Noncopyable() = default;
-};
-
-struct Base : public Noncopyable {
-  virtual void DoSmth() const = 0;
-  virtual ~Base() = default;
-};
-
-struct Derived final : public Base {
-  void DoSmth() const override { std::cout << "Derived DoSmth" << std::endl; }
-};
-
-struct AnotherDerived final : public Base {
-  void DoSmth() const override { std::cout << "AnotherDerived DoSmth" << std::endl; }
-};
-
-int main() {
-  const Derived derived{};
-  const AnotherDerived another_derived{};
-  const Base* base_ptr = &derived;
-  base_ptr->DoSmth();  // Calls Derived implementation.
-  base_ptr = &another_derived;
-  base_ptr->DoSmth();  // Calls AnotherDerived implementation.
-}`
-
-  yield* all(
-    codeRef().code(code_virtual_better_noncopyable_interface, duration).wait(duration),
-    codeRef().fontSize(25, duration)
-  );
-  yield* waitFor(duration);
-
-  yield* all(
-    codeRef().code(code_image_interface, 0).wait(duration),
-    codeRef().fontSize(30, 0)
-  );
-  yield* waitFor(duration);
-
-  const code_image_interface_noncopyable = `\
-#include <filesystem>
-#include <vector>
-
-// Assuming IoInterface, PngIo, JpegIo are defined.
-
-struct Noncopyable {
-  Noncopyable() = default;
-  Noncopyable(const Noncopyable&) = delete;
-  Noncopyable(Noncopyable&&) = delete;
-  Noncopyable& operator=(const Noncopyable&) = delete;
-  Noncopyable& operator=(Noncopyable&&) = delete;
-  ~Noncopyable() = default;
-};
-
-class Image {
- public:
-  Image(const std::filesystem::path& path, const IoInterface& io) {
-    colors_ = io.Read(path);
-  }
-
-  void Save(const std::filesystem::path& path, const IoInterface& io) const {
-    io.Write(path, colors_);
-  }
-
- private:
-  std::vector<Color> colors_{};
-};
-
-int main() {
-  const Image image{"path.jpeg", JpegIo{}};
-  image.Save("other_path.png", PngIo{});
-  return 0;
-}`
-  yield* all(
-    codeRef().code(code_image_interface_noncopyable, duration),
-    codeRef().fontSize(30, duration),
-    codeRef().y(150, duration)
-  );
-
-  const code_image_interface_defined = `\
-#include <filesystem>
-#include <vector>
-
-// Assuming PngIo, JpegIo are defined.
-
-struct Noncopyable {
-  Noncopyable() = default;
-  Noncopyable(const Noncopyable&) = delete;
-  Noncopyable(Noncopyable&&) = delete;
-  Noncopyable& operator=(const Noncopyable&) = delete;
-  Noncopyable& operator=(Noncopyable&&) = delete;
-  ~Noncopyable() = default;
-};
-
-struct IoInterface : public Noncopyable {
-  virtual std::vector<Color> Read(const std::filesystem::path& path) const = 0;
-  virtual void Write(const std::filesystem::path& path,
-                     const std::vector<Color>& data) const = 0;
-  virtual ~IoInterface() = default;
-};
-
-class Image {
- public:
-  Image(const std::filesystem::path& path, const IoInterface& io) {
-    colors_ = io.Read(path);
-  }
-
-  void Save(const std::filesystem::path& path, const IoInterface& io) const {
-    io.Write(path, colors_);
-  }
-
- private:
-  std::vector<Color> colors_{};
-};
-
-int main() {
-  const Image image{"path.jpeg", JpegIo{}};
-  image.Save("other_path.png", PngIo{});
-  return 0;
-}`
-  yield* all(
-    codeRef().code(code_image_interface_defined, duration),
-    codeRef().fontSize(30, duration),
-    codeRef().y(250, duration)
-  );
-  yield* waitFor(duration);
-
-  const code_image_interface_and_strategies = `\
-#include <filesystem>
-#include <iostream>
-#include <vector>
-
-// Assuming PngIo, JpegIo are defined.
-
-struct Noncopyable {
-  Noncopyable() = default;
-  Noncopyable(const Noncopyable&) = delete;
-  Noncopyable(Noncopyable&&) = delete;
-  Noncopyable& operator=(const Noncopyable&) = delete;
-  Noncopyable& operator=(Noncopyable&&) = delete;
-  ~Noncopyable() = default;
-};
-
-struct IoInterface : public Noncopyable {
-  virtual std::vector<Color> Read(const std::filesystem::path& path) const = 0;
-  virtual void Write(const std::filesystem::path& path,
-                     const std::vector<Color>& data) const = 0;
-  virtual ~IoInterface() = default;
-};
-
-struct JpegIo final : public IoInterface {
-  std::vector<Color> Read(const std::filesystem::path& path) const override {
-    std::cout << "Reading JPEG from path: " << path << std::endl;
-    return {};
-  }
-  void Write(const std::filesystem::path& path,
-                     const std::vector<Color>& data) const override {
-    std::cout << "Writing JPEG to path: " << path << std::endl;
-  }
-};
-
-struct PngIo final : public IoInterface {
-  std::vector<Color> Read(const std::filesystem::path& path) const override {
-    std::cout << "Reading PNG from path: " << path << std::endl;
-    return {};
-  }
-  void Write(const std::filesystem::path& path,
-                     const std::vector<Color>& data) const override {
-    std::cout << "Writing PNG to path: " << path << std::endl;
-  }
-};
-
-class Image {
- public:
-  Image(const std::filesystem::path& path, const IoInterface& io) {
-    colors_ = io.Read(path);
-  }
-
-  void Save(const std::filesystem::path& path, const IoInterface& io) const {
-    io.Write(path, colors_);
-  }
-
- private:
-  std::vector<Color> colors_{};
-};
-
-int main() {
-  const Image image{"path.jpeg", JpegIo{}};
-  image.Save("other_path.png", PngIo{});
-  return 0;
-}`
-  yield* all(
-    codeRef().code(code_image_interface_and_strategies, duration),
-    codeRef().fontSize(25, duration),
-    codeRef().y(50, duration)
-  );
-  yield* waitFor(duration);
-
-  yield* all(
-    codeRef().y(-600, duration)
-  );
-  yield* waitFor(duration);
-
-  yield* all(
-    codeRef().fontSize(12, duration),
-    codeRef().y(0, duration)
-  );
-  yield* waitFor(duration);
-
-
-  const code_virtual_explanation_1 = `\
-#include <iostream>
-
-// 😱 This struct misses some special functions. Stay tuned.
-struct Base {
-  virtual void DoSmth() const {}
-  virtual void DoSmthElse() const {}
-};
-
-// 😱 This struct misses some special functions. Stay tuned.
-struct Derived : public Base {
-  void DoSmth() const override {}
-};
-
-int main() {
-  const Derived derived{};
-  const Base& base_ref = derived;
-  base_ref.DoSmth();  // Calls Derived implementation.
-  base_ref.DoSmthElse();  // Calls Base implementation as Derived has no override.
-}`
-
-  yield* all(
-    codeRef().code(code_virtual_explanation_1, 0),
-    codeRef().fontSize(25, 0),
-    codeRef().x(-800, 0)
-  );
-  yield* waitFor(duration);
-
-  const code_virtual_explanation_2 = `\
-#include <iostream>
-
-// 😱 This struct misses some special functions. Stay tuned.
-struct Base {
-  virtual void DoSmth() const {}
-  virtual void DoSmthElse() const {}
-
-  vTable* v_ptr;  // Added by the compiler.
-};
-
-// 😱 This struct misses some special functions. Stay tuned.
-struct Derived : public Base {
-  void DoSmth() const override {}
-};
-
-int main() {
-  const Derived derived{};
-  const Base& base_ref = derived;
-  base_ref.DoSmth();  // Calls Derived implementation.
-  base_ref.DoSmthElse();  // Calls Base implementation as Derived has no override.
-}`
-
-  yield* all(
-    codeRef().code(code_virtual_explanation_2, duration),
-    codeRef().fontSize(25, duration),
-    codeRef().y(0, duration)
-  );
-  yield* waitFor(duration);
-
-  const code_virtual_explanation_base_ref = `\
-#include <iostream>
-
-// 😱 This struct misses some special functions. Stay tuned.
-struct Base {
-  virtual void DoSmth() const {}
-  virtual void DoSmthElse() const {}
-
-  vTable* v_ptr;  // Added by the compiler.
-};
-
-// 😱 This struct misses some special functions. Stay tuned.
-struct Derived : public Base {
-  void DoSmth() const override {}
-};
-
-int main() {
-  const Base base{};
-  const Base& base_ref = base;
-  base_ref.DoSmth();  // What is called here?
-  base_ref.DoSmthElse();  // What is called here?
-}`
-
-  yield* all(
-    codeRef().code(code_virtual_explanation_base_ref, duration),
-    codeRef().fontSize(25, duration),
-    codeRef().y(0, duration)
-  );
-  yield* waitFor(duration);
-
-  yield* waitFor(duration * 3);
-});
diff --git a/animation/inheritance/tsconfig.json b/animation/inheritance/tsconfig.json
deleted file mode 100644
index e7d5347..0000000
--- a/animation/inheritance/tsconfig.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
-  "extends": "@motion-canvas/2d/tsconfig.project.json",
-  "include": ["src"]
-}
diff --git a/animation/inheritance/vite.config.ts b/animation/inheritance/vite.config.ts
deleted file mode 100644
index 42d9d68..0000000
--- a/animation/inheritance/vite.config.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import {defineConfig} from 'vite';
-import motionCanvas from '@motion-canvas/vite-plugin';
-import ffmpeg from '@motion-canvas/ffmpeg';
-
-export default defineConfig({
-  plugins: [
-    motionCanvas(),
-    ffmpeg(),
-  ],
-});
diff --git a/animation/lambdas/.gitignore b/animation/lambdas/.gitignore
deleted file mode 100644
index 829b1c7..0000000
--- a/animation/lambdas/.gitignore
+++ /dev/null
@@ -1,15 +0,0 @@
-# Generated files
-node_modules
-output
-dist
-
-# Editor directories and files
-.vscode/*
-!.vscode/extensions.json
-.idea
-.DS_Store
-*.suo
-*.ntvs*
-*.njsproj
-*.sln
-*.sw?
diff --git a/animation/lambdas/package-lock.json b/animation/lambdas/package-lock.json
deleted file mode 100644
index dad2ff3..0000000
--- a/animation/lambdas/package-lock.json
+++ /dev/null
@@ -1,1366 +0,0 @@
-{
-  "name": "value_semantics",
-  "version": "0.0.0",
-  "lockfileVersion": 3,
-  "requires": true,
-  "packages": {
-    "": {
-      "name": "value_semantics",
-      "version": "0.0.0",
-      "dependencies": {
-        "@lezer/cpp": "^1.1.2",
-        "@motion-canvas/2d": "^3.16.0",
-        "@motion-canvas/core": "^3.16.0",
-        "@motion-canvas/ffmpeg": "^1.1.1"
-      },
-      "devDependencies": {
-        "@motion-canvas/ui": "^3.16.0",
-        "@motion-canvas/vite-plugin": "^3.15.1",
-        "typescript": "^5.2.2",
-        "vite": "^4.0.0"
-      }
-    },
-    "node_modules/@codemirror/language": {
-      "version": "6.10.2",
-      "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.10.2.tgz",
-      "integrity": "sha512-kgbTYTo0Au6dCSc/TFy7fK3fpJmgHDv1sG1KNQKJXVi+xBTEeBPY/M30YXiU6mMXeH+YIDLsbrT4ZwNRdtF+SA==",
-      "dependencies": {
-        "@codemirror/state": "^6.0.0",
-        "@codemirror/view": "^6.23.0",
-        "@lezer/common": "^1.1.0",
-        "@lezer/highlight": "^1.0.0",
-        "@lezer/lr": "^1.0.0",
-        "style-mod": "^4.0.0"
-      }
-    },
-    "node_modules/@codemirror/state": {
-      "version": "6.4.1",
-      "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.4.1.tgz",
-      "integrity": "sha512-QkEyUiLhsJoZkbumGZlswmAhA7CBU02Wrz7zvH4SrcifbsqwlXShVXg65f3v/ts57W3dqyamEriMhij1Z3Zz4A=="
-    },
-    "node_modules/@codemirror/view": {
-      "version": "6.32.0",
-      "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.32.0.tgz",
-      "integrity": "sha512-AgVNvED2QTsZp5e3syoHLsrWtwJFYWdx1Vr/m3f4h1ATQz0ax60CfXF3Htdmk69k2MlYZw8gXesnQdHtzyVmAw==",
-      "dependencies": {
-        "@codemirror/state": "^6.4.0",
-        "style-mod": "^4.1.0",
-        "w3c-keyname": "^2.2.4"
-      }
-    },
-    "node_modules/@esbuild/android-arm": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
-      "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==",
-      "cpu": [
-        "arm"
-      ],
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/android-arm64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz",
-      "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/android-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz",
-      "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/darwin-arm64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz",
-      "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/darwin-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz",
-      "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/freebsd-arm64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz",
-      "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "freebsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/freebsd-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz",
-      "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "freebsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-arm": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz",
-      "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==",
-      "cpu": [
-        "arm"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-arm64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz",
-      "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-ia32": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz",
-      "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==",
-      "cpu": [
-        "ia32"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-loong64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz",
-      "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==",
-      "cpu": [
-        "loong64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-mips64el": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz",
-      "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==",
-      "cpu": [
-        "mips64el"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-ppc64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz",
-      "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==",
-      "cpu": [
-        "ppc64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-riscv64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz",
-      "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==",
-      "cpu": [
-        "riscv64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-s390x": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz",
-      "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==",
-      "cpu": [
-        "s390x"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz",
-      "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/netbsd-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz",
-      "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "netbsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/openbsd-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz",
-      "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "openbsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/sunos-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz",
-      "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "sunos"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/win32-arm64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz",
-      "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/win32-ia32": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz",
-      "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==",
-      "cpu": [
-        "ia32"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/win32-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz",
-      "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@ffmpeg-installer/darwin-arm64": {
-      "version": "4.1.5",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/darwin-arm64/-/darwin-arm64-4.1.5.tgz",
-      "integrity": "sha512-hYqTiP63mXz7wSQfuqfFwfLOfwwFChUedeCVKkBtl/cliaTM7/ePI9bVzfZ2c+dWu3TqCwLDRWNSJ5pqZl8otA==",
-      "cpu": [
-        "arm64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/darwin-x64": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/darwin-x64/-/darwin-x64-4.1.0.tgz",
-      "integrity": "sha512-Z4EyG3cIFjdhlY8wI9aLUXuH8nVt7E9SlMVZtWvSPnm2sm37/yC2CwjUzyCQbJbySnef1tQwGG2Sx+uWhd9IAw==",
-      "cpu": [
-        "x64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/ffmpeg": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/ffmpeg/-/ffmpeg-1.1.0.tgz",
-      "integrity": "sha512-Uq4rmwkdGxIa9A6Bd/VqqYbT7zqh1GrT5/rFwCwKM70b42W5gIjWeVETq6SdcL0zXqDtY081Ws/iJWhr1+xvQg==",
-      "optionalDependencies": {
-        "@ffmpeg-installer/darwin-arm64": "4.1.5",
-        "@ffmpeg-installer/darwin-x64": "4.1.0",
-        "@ffmpeg-installer/linux-arm": "4.1.3",
-        "@ffmpeg-installer/linux-arm64": "4.1.4",
-        "@ffmpeg-installer/linux-ia32": "4.1.0",
-        "@ffmpeg-installer/linux-x64": "4.1.0",
-        "@ffmpeg-installer/win32-ia32": "4.1.0",
-        "@ffmpeg-installer/win32-x64": "4.1.0"
-      }
-    },
-    "node_modules/@ffmpeg-installer/linux-arm": {
-      "version": "4.1.3",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/linux-arm/-/linux-arm-4.1.3.tgz",
-      "integrity": "sha512-NDf5V6l8AfzZ8WzUGZ5mV8O/xMzRag2ETR6+TlGIsMHp81agx51cqpPItXPib/nAZYmo55Bl2L6/WOMI3A5YRg==",
-      "cpu": [
-        "arm"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/linux-arm64": {
-      "version": "4.1.4",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/linux-arm64/-/linux-arm64-4.1.4.tgz",
-      "integrity": "sha512-dljEqAOD0oIM6O6DxBW9US/FkvqvQwgJ2lGHOwHDDwu/pX8+V0YsDL1xqHbj1DMX/+nP9rxw7G7gcUvGspSoKg==",
-      "cpu": [
-        "arm64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/linux-ia32": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/linux-ia32/-/linux-ia32-4.1.0.tgz",
-      "integrity": "sha512-0LWyFQnPf+Ij9GQGD034hS6A90URNu9HCtQ5cTqo5MxOEc7Rd8gLXrJvn++UmxhU0J5RyRE9KRYstdCVUjkNOQ==",
-      "cpu": [
-        "ia32"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/linux-x64": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/linux-x64/-/linux-x64-4.1.0.tgz",
-      "integrity": "sha512-Y5BWhGLU/WpQjOArNIgXD3z5mxxdV8c41C+U15nsE5yF8tVcdCGet5zPs5Zy3Ta6bU7haGpIzryutqCGQA/W8A==",
-      "cpu": [
-        "x64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/win32-ia32": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/win32-ia32/-/win32-ia32-4.1.0.tgz",
-      "integrity": "sha512-FV2D7RlaZv/lrtdhaQ4oETwoFUsUjlUiasiZLDxhEUPdNDWcH1OU9K1xTvqz+OXLdsmYelUDuBS/zkMOTtlUAw==",
-      "cpu": [
-        "ia32"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/win32-x64": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/win32-x64/-/win32-x64-4.1.0.tgz",
-      "integrity": "sha512-Drt5u2vzDnIONf4ZEkKtFlbvwj6rI3kxw1Ck9fpudmtgaZIHD4ucsWB2lCZBXRxJgXR+2IMSti+4rtM4C4rXgg==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ]
-    },
-    "node_modules/@ffprobe-installer/darwin-arm64": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/darwin-arm64/-/darwin-arm64-5.0.1.tgz",
-      "integrity": "sha512-vwNCNjokH8hfkbl6m95zICHwkSzhEvDC3GVBcUp5HX8+4wsX10SP3B+bGur7XUzTIZ4cQpgJmEIAx6TUwRepMg==",
-      "cpu": [
-        "arm64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ]
-    },
-    "node_modules/@ffprobe-installer/darwin-x64": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/darwin-x64/-/darwin-x64-5.1.0.tgz",
-      "integrity": "sha512-J+YGscZMpQclFg31O4cfVRGmDpkVsQ2fZujoUdMAAYcP0NtqpC49Hs3SWJpBdsGB4VeqOt5TTm1vSZQzs1NkhA==",
-      "cpu": [
-        "x64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ]
-    },
-    "node_modules/@ffprobe-installer/ffprobe": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/ffprobe/-/ffprobe-2.1.2.tgz",
-      "integrity": "sha512-ZNvwk4f2magF42Zji2Ese16SMj9BS7Fui4kRjg6gTYTxY3gWZNpg85n4MIfQyI9nimHg4x/gT6FVkp/bBDuBwg==",
-      "engines": {
-        "node": ">=14.21.2"
-      },
-      "optionalDependencies": {
-        "@ffprobe-installer/darwin-arm64": "5.0.1",
-        "@ffprobe-installer/darwin-x64": "5.1.0",
-        "@ffprobe-installer/linux-arm": "5.2.0",
-        "@ffprobe-installer/linux-arm64": "5.2.0",
-        "@ffprobe-installer/linux-ia32": "5.2.0",
-        "@ffprobe-installer/linux-x64": "5.2.0",
-        "@ffprobe-installer/win32-ia32": "5.1.0",
-        "@ffprobe-installer/win32-x64": "5.1.0"
-      }
-    },
-    "node_modules/@ffprobe-installer/linux-arm": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/linux-arm/-/linux-arm-5.2.0.tgz",
-      "integrity": "sha512-PF5HqEhCY7WTWHtLDYbA/+rLS+rhslWvyBlAG1Fk8VzVlnRdl93o6hy7DE2kJgxWQbFaR3ZktPQGEzfkrmQHvQ==",
-      "cpu": [
-        "arm"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffprobe-installer/linux-arm64": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/linux-arm64/-/linux-arm64-5.2.0.tgz",
-      "integrity": "sha512-X1VvWtlLs6ScP73biVLuHD5ohKJKsMTa0vafCESOen4mOoNeLAYbxOVxDWAdFz9cpZgRiloFj5QD6nDj8E28yQ==",
-      "cpu": [
-        "arm64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffprobe-installer/linux-ia32": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/linux-ia32/-/linux-ia32-5.2.0.tgz",
-      "integrity": "sha512-TFVK5sasXyXhbIG7LtPRDmtkrkOsInwKcL43iEvEw+D9vCS2rc//mn9/0Q+BR0UoJEiMK4+ApYr/3LLVUBPOCQ==",
-      "cpu": [
-        "ia32"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffprobe-installer/linux-x64": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/linux-x64/-/linux-x64-5.2.0.tgz",
-      "integrity": "sha512-D3UeqTLYPNs7pBWPLUYGehPdRVqU8eACox4OZy3pZUZatxye2YKlvBwEfaLdL1v2Z4FOAlLUhms0kY8m8kqSRA==",
-      "cpu": [
-        "x64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffprobe-installer/win32-ia32": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/win32-ia32/-/win32-ia32-5.1.0.tgz",
-      "integrity": "sha512-5O3vOoNRxmut0/Nu9vSazTdSHasrr+zPT2B3Hm7kjmO3QVFcIfVImS6ReQnZeSy8JPJOqXts5kX5x/3KOX54XQ==",
-      "cpu": [
-        "ia32"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ]
-    },
-    "node_modules/@ffprobe-installer/win32-x64": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/win32-x64/-/win32-x64-5.1.0.tgz",
-      "integrity": "sha512-jMGYeAgkrdn4e2vvYt/qakgHRE3CPju4bn5TmdPfoAm1BlX1mY9cyMd8gf5vSzI8gH8Zq5WQAyAkmekX/8TSTg==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ]
-    },
-    "node_modules/@lezer/common": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.2.1.tgz",
-      "integrity": "sha512-yemX0ZD2xS/73llMZIK6KplkjIjf2EvAHcinDi/TfJ9hS25G0388+ClHt6/3but0oOxinTcQHJLDXh6w1crzFQ=="
-    },
-    "node_modules/@lezer/cpp": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@lezer/cpp/-/cpp-1.1.2.tgz",
-      "integrity": "sha512-macwKtyeUO0EW86r3xWQCzOV9/CF8imJLpJlPv3sDY57cPGeUZ8gXWOWNlJr52TVByMV3PayFQCA5SHEERDmVQ==",
-      "dependencies": {
-        "@lezer/common": "^1.2.0",
-        "@lezer/highlight": "^1.0.0",
-        "@lezer/lr": "^1.0.0"
-      }
-    },
-    "node_modules/@lezer/highlight": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.0.tgz",
-      "integrity": "sha512-WrS5Mw51sGrpqjlh3d4/fOwpEV2Hd3YOkp9DBt4k8XZQcoTHZFB7sx030A6OcahF4J1nDQAa3jXlTVVYH50IFA==",
-      "dependencies": {
-        "@lezer/common": "^1.0.0"
-      }
-    },
-    "node_modules/@lezer/lr": {
-      "version": "1.4.2",
-      "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.2.tgz",
-      "integrity": "sha512-pu0K1jCIdnQ12aWNaAVU5bzi7Bd1w54J3ECgANPmYLtQKP0HBj2cE/5coBD66MT10xbtIuUr7tg0Shbsvk0mDA==",
-      "dependencies": {
-        "@lezer/common": "^1.0.0"
-      }
-    },
-    "node_modules/@motion-canvas/2d": {
-      "version": "3.16.0",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/2d/-/2d-3.16.0.tgz",
-      "integrity": "sha512-8vyCSNE9ZCkGB4Wz8yS48h0xQ79mbmbCkhpxu4ARBrFtSVLqgo/6kz2yifJi4wPK4pCDFw5knABjukOKtMaPMQ==",
-      "dependencies": {
-        "@codemirror/language": "^6.10.1",
-        "@lezer/common": "^1.2.1",
-        "@lezer/highlight": "^1.2.0",
-        "@motion-canvas/core": "^3.16.0",
-        "code-fns": "^0.8.2",
-        "mathjax-full": "^3.2.2",
-        "parse-svg-path": "^0.1.2"
-      }
-    },
-    "node_modules/@motion-canvas/core": {
-      "version": "3.16.0",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/core/-/core-3.16.0.tgz",
-      "integrity": "sha512-egOrQjVOHWf+HMFH+AOLLSV/djf+YGGPxbz0Jbnva3C3VTH2l6MMKTdoYyGRI3w02gJO1pIo7bcePq3erlxulw==",
-      "dependencies": {
-        "@types/chroma-js": "^2.1.4",
-        "chroma-js": "^2.4.2"
-      }
-    },
-    "node_modules/@motion-canvas/ffmpeg": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/ffmpeg/-/ffmpeg-1.1.1.tgz",
-      "integrity": "sha512-w2d7oFfR3hYHXeYtFGoHp6goY+vVL0LoZ2h1b/veTH5KvE7jrLp2Kl/XPHsYJ5ZDRHUT0Nhl05DBLdXYqdSqgg==",
-      "dependencies": {
-        "@ffmpeg-installer/ffmpeg": "^1.1.0",
-        "@ffprobe-installer/ffprobe": "^2.0.0",
-        "fluent-ffmpeg": "^2.1.2"
-      },
-      "peerDependencies": {
-        "@motion-canvas/core": "^3.7.0",
-        "@motion-canvas/vite-plugin": "^3.7.0",
-        "vite": "4.x"
-      }
-    },
-    "node_modules/@motion-canvas/ui": {
-      "version": "3.16.0",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/ui/-/ui-3.16.0.tgz",
-      "integrity": "sha512-PJZnbkiJKED4nNDnN649zojfPMVRTvFOqxUExi6TdrckiLFsTJFy+dYbyMML223ekDrkmHuQU35tcs3svwfYrw==",
-      "dev": true,
-      "dependencies": {
-        "@motion-canvas/core": "^3.16.0",
-        "@preact/signals": "^1.2.1",
-        "preact": "^10.19.2"
-      }
-    },
-    "node_modules/@motion-canvas/vite-plugin": {
-      "version": "3.15.1",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/vite-plugin/-/vite-plugin-3.15.1.tgz",
-      "integrity": "sha512-yeRMJQxTcYVZGVMnNXQPm0SySQzJXnaRrggGJ2bnDHMsqxCRJt/RfIioK0LMvBaUB+UWlPsJUTMltHuq+J64JA==",
-      "dependencies": {
-        "fast-glob": "^3.3.1",
-        "follow-redirects": "^1.15.2",
-        "mime-types": "^2.1.35",
-        "source-map": "^0.6.1"
-      },
-      "peerDependencies": {
-        "vite": "4.x || 5.x"
-      }
-    },
-    "node_modules/@nodelib/fs.scandir": {
-      "version": "2.1.5",
-      "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
-      "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
-      "dependencies": {
-        "@nodelib/fs.stat": "2.0.5",
-        "run-parallel": "^1.1.9"
-      },
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/@nodelib/fs.stat": {
-      "version": "2.0.5",
-      "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
-      "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/@nodelib/fs.walk": {
-      "version": "1.2.8",
-      "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
-      "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
-      "dependencies": {
-        "@nodelib/fs.scandir": "2.1.5",
-        "fastq": "^1.6.0"
-      },
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/@preact/signals": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/@preact/signals/-/signals-1.3.0.tgz",
-      "integrity": "sha512-EOMeg42SlLS72dhoq6Vjq08havnLseWmPQ8A0YsgIAqMgWgx7V1a39+Pxo6i7SY5NwJtH4849JogFq3M67AzWg==",
-      "dev": true,
-      "dependencies": {
-        "@preact/signals-core": "^1.7.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/preact"
-      },
-      "peerDependencies": {
-        "preact": "10.x"
-      }
-    },
-    "node_modules/@preact/signals-core": {
-      "version": "1.8.0",
-      "resolved": "https://registry.npmjs.org/@preact/signals-core/-/signals-core-1.8.0.tgz",
-      "integrity": "sha512-OBvUsRZqNmjzCZXWLxkZfhcgT+Fk8DDcT/8vD6a1xhDemodyy87UJRJfASMuSD8FaAIeGgGm85ydXhm7lr4fyA==",
-      "dev": true,
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/preact"
-      }
-    },
-    "node_modules/@types/chroma-js": {
-      "version": "2.4.0",
-      "resolved": "https://registry.npmjs.org/@types/chroma-js/-/chroma-js-2.4.0.tgz",
-      "integrity": "sha512-JklMxityrwjBTjGY2anH8JaTx3yjRU3/sEHSblLH1ba5lqcSh1LnImXJZO5peJfXyqKYWjHTGy4s5Wz++hARrw=="
-    },
-    "node_modules/@types/hast": {
-      "version": "2.3.4",
-      "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.4.tgz",
-      "integrity": "sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==",
-      "dependencies": {
-        "@types/unist": "*"
-      }
-    },
-    "node_modules/@types/unist": {
-      "version": "2.0.6",
-      "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz",
-      "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ=="
-    },
-    "node_modules/@wooorm/starry-night": {
-      "version": "1.7.0",
-      "resolved": "https://registry.npmjs.org/@wooorm/starry-night/-/starry-night-1.7.0.tgz",
-      "integrity": "sha512-ktO0nkddrovIoNW2jAUT+Cdd9n1bWjy1Ir4CdcmgTaT6E94HLlQfu7Yv62falclBEwvsuVp3bSBw23wtta1fNw==",
-      "dependencies": {
-        "@types/hast": "^2.0.0",
-        "import-meta-resolve": "^2.0.0",
-        "vscode-oniguruma": "^1.0.0",
-        "vscode-textmate": "^9.0.0"
-      },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/wooorm"
-      }
-    },
-    "node_modules/async": {
-      "version": "0.2.10",
-      "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz",
-      "integrity": "sha512-eAkdoKxU6/LkKDBzLpT+t6Ff5EtfSF4wx1WfJiPEEV7WNLnDaRXk0oVysiEPm262roaachGexwUv94WhSgN5TQ=="
-    },
-    "node_modules/braces": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
-      "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
-      "dependencies": {
-        "fill-range": "^7.1.1"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/chroma-js": {
-      "version": "2.4.2",
-      "resolved": "https://registry.npmjs.org/chroma-js/-/chroma-js-2.4.2.tgz",
-      "integrity": "sha512-U9eDw6+wt7V8z5NncY2jJfZa+hUH8XEj8FQHgFJTrUFnJfXYf4Ml4adI2vXZOjqRDpFWtYVWypDfZwnJ+HIR4A=="
-    },
-    "node_modules/code-fns": {
-      "version": "0.8.2",
-      "resolved": "https://registry.npmjs.org/code-fns/-/code-fns-0.8.2.tgz",
-      "integrity": "sha512-3VVeq3cnWxWiWKFLsVo+XWsOXBSW2gAx2uv0ViETLNmNuygEPHlCeDAv/Zy7xXqPgXtgLZyvIJZmx+ojTgOIGA==",
-      "dependencies": {
-        "@wooorm/starry-night": "^1.2.0"
-      }
-    },
-    "node_modules/commander": {
-      "version": "9.2.0",
-      "resolved": "https://registry.npmjs.org/commander/-/commander-9.2.0.tgz",
-      "integrity": "sha512-e2i4wANQiSXgnrBlIatyHtP1odfUp0BbV5Y5nEGbxtIrStkEOAAzCUirvLBNXHLr7kwLvJl6V+4V3XV9x7Wd9w==",
-      "engines": {
-        "node": "^12.20.0 || >=14"
-      }
-    },
-    "node_modules/esbuild": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz",
-      "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==",
-      "hasInstallScript": true,
-      "bin": {
-        "esbuild": "bin/esbuild"
-      },
-      "engines": {
-        "node": ">=12"
-      },
-      "optionalDependencies": {
-        "@esbuild/android-arm": "0.18.20",
-        "@esbuild/android-arm64": "0.18.20",
-        "@esbuild/android-x64": "0.18.20",
-        "@esbuild/darwin-arm64": "0.18.20",
-        "@esbuild/darwin-x64": "0.18.20",
-        "@esbuild/freebsd-arm64": "0.18.20",
-        "@esbuild/freebsd-x64": "0.18.20",
-        "@esbuild/linux-arm": "0.18.20",
-        "@esbuild/linux-arm64": "0.18.20",
-        "@esbuild/linux-ia32": "0.18.20",
-        "@esbuild/linux-loong64": "0.18.20",
-        "@esbuild/linux-mips64el": "0.18.20",
-        "@esbuild/linux-ppc64": "0.18.20",
-        "@esbuild/linux-riscv64": "0.18.20",
-        "@esbuild/linux-s390x": "0.18.20",
-        "@esbuild/linux-x64": "0.18.20",
-        "@esbuild/netbsd-x64": "0.18.20",
-        "@esbuild/openbsd-x64": "0.18.20",
-        "@esbuild/sunos-x64": "0.18.20",
-        "@esbuild/win32-arm64": "0.18.20",
-        "@esbuild/win32-ia32": "0.18.20",
-        "@esbuild/win32-x64": "0.18.20"
-      }
-    },
-    "node_modules/esm": {
-      "version": "3.2.25",
-      "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz",
-      "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==",
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/fast-glob": {
-      "version": "3.3.2",
-      "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
-      "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
-      "dependencies": {
-        "@nodelib/fs.stat": "^2.0.2",
-        "@nodelib/fs.walk": "^1.2.3",
-        "glob-parent": "^5.1.2",
-        "merge2": "^1.3.0",
-        "micromatch": "^4.0.4"
-      },
-      "engines": {
-        "node": ">=8.6.0"
-      }
-    },
-    "node_modules/fastq": {
-      "version": "1.17.1",
-      "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz",
-      "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==",
-      "dependencies": {
-        "reusify": "^1.0.4"
-      }
-    },
-    "node_modules/fill-range": {
-      "version": "7.1.1",
-      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
-      "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
-      "dependencies": {
-        "to-regex-range": "^5.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/fluent-ffmpeg": {
-      "version": "2.1.3",
-      "resolved": "https://registry.npmjs.org/fluent-ffmpeg/-/fluent-ffmpeg-2.1.3.tgz",
-      "integrity": "sha512-Be3narBNt2s6bsaqP6Jzq91heDgOEaDCJAXcE3qcma/EJBSy5FB4cvO31XBInuAuKBx8Kptf8dkhjK0IOru39Q==",
-      "dependencies": {
-        "async": "^0.2.9",
-        "which": "^1.1.1"
-      },
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/follow-redirects": {
-      "version": "1.15.6",
-      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
-      "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
-      "funding": [
-        {
-          "type": "individual",
-          "url": "https://github.com/sponsors/RubenVerborgh"
-        }
-      ],
-      "engines": {
-        "node": ">=4.0"
-      },
-      "peerDependenciesMeta": {
-        "debug": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/fsevents": {
-      "version": "2.3.3",
-      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
-      "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
-      }
-    },
-    "node_modules/glob-parent": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
-      "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
-      "dependencies": {
-        "is-glob": "^4.0.1"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "node_modules/import-meta-resolve": {
-      "version": "2.2.2",
-      "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-2.2.2.tgz",
-      "integrity": "sha512-f8KcQ1D80V7RnqVm+/lirO9zkOxjGxhaTC1IPrBGd3MEfNgmNG67tSUO9gTi2F3Blr2Az6g1vocaxzkVnWl9MA==",
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/wooorm"
-      }
-    },
-    "node_modules/is-extglob": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
-      "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/is-glob": {
-      "version": "4.0.3",
-      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
-      "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
-      "dependencies": {
-        "is-extglob": "^2.1.1"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/is-number": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
-      "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
-      "engines": {
-        "node": ">=0.12.0"
-      }
-    },
-    "node_modules/isexe": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
-      "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
-    },
-    "node_modules/mathjax-full": {
-      "version": "3.2.2",
-      "resolved": "https://registry.npmjs.org/mathjax-full/-/mathjax-full-3.2.2.tgz",
-      "integrity": "sha512-+LfG9Fik+OuI8SLwsiR02IVdjcnRCy5MufYLi0C3TdMT56L/pjB0alMVGgoWJF8pN9Rc7FESycZB9BMNWIid5w==",
-      "dependencies": {
-        "esm": "^3.2.25",
-        "mhchemparser": "^4.1.0",
-        "mj-context-menu": "^0.6.1",
-        "speech-rule-engine": "^4.0.6"
-      }
-    },
-    "node_modules/merge2": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
-      "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/mhchemparser": {
-      "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/mhchemparser/-/mhchemparser-4.1.1.tgz",
-      "integrity": "sha512-R75CUN6O6e1t8bgailrF1qPq+HhVeFTM3XQ0uzI+mXTybmphy3b6h4NbLOYhemViQ3lUs+6CKRkC3Ws1TlYREA=="
-    },
-    "node_modules/micromatch": {
-      "version": "4.0.8",
-      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
-      "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
-      "dependencies": {
-        "braces": "^3.0.3",
-        "picomatch": "^2.3.1"
-      },
-      "engines": {
-        "node": ">=8.6"
-      }
-    },
-    "node_modules/mime-db": {
-      "version": "1.52.0",
-      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
-      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/mime-types": {
-      "version": "2.1.35",
-      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
-      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
-      "dependencies": {
-        "mime-db": "1.52.0"
-      },
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/mj-context-menu": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/mj-context-menu/-/mj-context-menu-0.6.1.tgz",
-      "integrity": "sha512-7NO5s6n10TIV96d4g2uDpG7ZDpIhMh0QNfGdJw/W47JswFcosz457wqz/b5sAKvl12sxINGFCn80NZHKwxQEXA=="
-    },
-    "node_modules/nanoid": {
-      "version": "3.3.6",
-      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
-      "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/ai"
-        }
-      ],
-      "bin": {
-        "nanoid": "bin/nanoid.cjs"
-      },
-      "engines": {
-        "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
-      }
-    },
-    "node_modules/parse-svg-path": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/parse-svg-path/-/parse-svg-path-0.1.2.tgz",
-      "integrity": "sha512-JyPSBnkTJ0AI8GGJLfMXvKq42cj5c006fnLz6fXy6zfoVjJizi8BNTpu8on8ziI1cKy9d9DGNuY17Ce7wuejpQ=="
-    },
-    "node_modules/picocolors": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
-      "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
-    },
-    "node_modules/picomatch": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
-      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
-      "engines": {
-        "node": ">=8.6"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/jonschlinkert"
-      }
-    },
-    "node_modules/postcss": {
-      "version": "8.4.31",
-      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
-      "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
-      "funding": [
-        {
-          "type": "opencollective",
-          "url": "https://opencollective.com/postcss/"
-        },
-        {
-          "type": "tidelift",
-          "url": "https://tidelift.com/funding/github/npm/postcss"
-        },
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/ai"
-        }
-      ],
-      "dependencies": {
-        "nanoid": "^3.3.6",
-        "picocolors": "^1.0.0",
-        "source-map-js": "^1.0.2"
-      },
-      "engines": {
-        "node": "^10 || ^12 || >=14"
-      }
-    },
-    "node_modules/preact": {
-      "version": "10.23.2",
-      "resolved": "https://registry.npmjs.org/preact/-/preact-10.23.2.tgz",
-      "integrity": "sha512-kKYfePf9rzKnxOAKDpsWhg/ysrHPqT+yQ7UW4JjdnqjFIeNUnNcEJvhuA8fDenxAGWzUqtd51DfVg7xp/8T9NA==",
-      "dev": true,
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/preact"
-      }
-    },
-    "node_modules/queue-microtask": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
-      "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/feross"
-        },
-        {
-          "type": "patreon",
-          "url": "https://www.patreon.com/feross"
-        },
-        {
-          "type": "consulting",
-          "url": "https://feross.org/support"
-        }
-      ]
-    },
-    "node_modules/reusify": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
-      "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
-      "engines": {
-        "iojs": ">=1.0.0",
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/rollup": {
-      "version": "3.29.4",
-      "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz",
-      "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==",
-      "bin": {
-        "rollup": "dist/bin/rollup"
-      },
-      "engines": {
-        "node": ">=14.18.0",
-        "npm": ">=8.0.0"
-      },
-      "optionalDependencies": {
-        "fsevents": "~2.3.2"
-      }
-    },
-    "node_modules/run-parallel": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
-      "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/feross"
-        },
-        {
-          "type": "patreon",
-          "url": "https://www.patreon.com/feross"
-        },
-        {
-          "type": "consulting",
-          "url": "https://feross.org/support"
-        }
-      ],
-      "dependencies": {
-        "queue-microtask": "^1.2.2"
-      }
-    },
-    "node_modules/source-map": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
-      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/source-map-js": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
-      "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/speech-rule-engine": {
-      "version": "4.0.7",
-      "resolved": "https://registry.npmjs.org/speech-rule-engine/-/speech-rule-engine-4.0.7.tgz",
-      "integrity": "sha512-sJrL3/wHzNwJRLBdf6CjJWIlxC04iYKkyXvYSVsWVOiC2DSkHmxsqOhEeMsBA9XK+CHuNcsdkbFDnoUfAsmp9g==",
-      "dependencies": {
-        "commander": "9.2.0",
-        "wicked-good-xpath": "1.3.0",
-        "xmldom-sre": "0.1.31"
-      },
-      "bin": {
-        "sre": "bin/sre"
-      }
-    },
-    "node_modules/style-mod": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.2.tgz",
-      "integrity": "sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw=="
-    },
-    "node_modules/to-regex-range": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
-      "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
-      "dependencies": {
-        "is-number": "^7.0.0"
-      },
-      "engines": {
-        "node": ">=8.0"
-      }
-    },
-    "node_modules/typescript": {
-      "version": "5.5.4",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz",
-      "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==",
-      "dev": true,
-      "bin": {
-        "tsc": "bin/tsc",
-        "tsserver": "bin/tsserver"
-      },
-      "engines": {
-        "node": ">=14.17"
-      }
-    },
-    "node_modules/vite": {
-      "version": "4.5.3",
-      "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.3.tgz",
-      "integrity": "sha512-kQL23kMeX92v3ph7IauVkXkikdDRsYMGTVl5KY2E9OY4ONLvkHf04MDTbnfo6NKxZiDLWzVpP5oTa8hQD8U3dg==",
-      "dependencies": {
-        "esbuild": "^0.18.10",
-        "postcss": "^8.4.27",
-        "rollup": "^3.27.1"
-      },
-      "bin": {
-        "vite": "bin/vite.js"
-      },
-      "engines": {
-        "node": "^14.18.0 || >=16.0.0"
-      },
-      "funding": {
-        "url": "https://github.com/vitejs/vite?sponsor=1"
-      },
-      "optionalDependencies": {
-        "fsevents": "~2.3.2"
-      },
-      "peerDependencies": {
-        "@types/node": ">= 14",
-        "less": "*",
-        "lightningcss": "^1.21.0",
-        "sass": "*",
-        "stylus": "*",
-        "sugarss": "*",
-        "terser": "^5.4.0"
-      },
-      "peerDependenciesMeta": {
-        "@types/node": {
-          "optional": true
-        },
-        "less": {
-          "optional": true
-        },
-        "lightningcss": {
-          "optional": true
-        },
-        "sass": {
-          "optional": true
-        },
-        "stylus": {
-          "optional": true
-        },
-        "sugarss": {
-          "optional": true
-        },
-        "terser": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/vscode-oniguruma": {
-      "version": "1.7.0",
-      "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz",
-      "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA=="
-    },
-    "node_modules/vscode-textmate": {
-      "version": "9.0.0",
-      "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-9.0.0.tgz",
-      "integrity": "sha512-Cl65diFGxz7gpwbav10HqiY/eVYTO1sjQpmRmV991Bj7wAoOAjGQ97PpQcXorDE2Uc4hnGWLY17xme+5t6MlSg=="
-    },
-    "node_modules/w3c-keyname": {
-      "version": "2.2.8",
-      "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz",
-      "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ=="
-    },
-    "node_modules/which": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
-      "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
-      "dependencies": {
-        "isexe": "^2.0.0"
-      },
-      "bin": {
-        "which": "bin/which"
-      }
-    },
-    "node_modules/wicked-good-xpath": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/wicked-good-xpath/-/wicked-good-xpath-1.3.0.tgz",
-      "integrity": "sha512-Gd9+TUn5nXdwj/hFsPVx5cuHHiF5Bwuc30jZ4+ronF1qHK5O7HD0sgmXWSEgwKquT3ClLoKPVbO6qGwVwLzvAw=="
-    },
-    "node_modules/xmldom-sre": {
-      "version": "0.1.31",
-      "resolved": "https://registry.npmjs.org/xmldom-sre/-/xmldom-sre-0.1.31.tgz",
-      "integrity": "sha512-f9s+fUkX04BxQf+7mMWAp5zk61pciie+fFLC9hX9UVvCeJQfNHRHXpeo5MPcR0EUf57PYLdt+ZO4f3Ipk2oZUw==",
-      "engines": {
-        "node": ">=0.1"
-      }
-    }
-  }
-}
diff --git a/animation/lambdas/package.json b/animation/lambdas/package.json
deleted file mode 100644
index 9955e40..0000000
--- a/animation/lambdas/package.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
-  "name": "value_semantics",
-  "private": true,
-  "version": "0.0.0",
-  "scripts": {
-    "start": "vite",
-    "serve": "vite",
-    "build": "tsc && vite build"
-  },
-  "dependencies": {
-    "@lezer/cpp": "^1.1.2",
-    "@motion-canvas/2d": "^3.16.0",
-    "@motion-canvas/core": "^3.16.0",
-    "@motion-canvas/ffmpeg": "^1.1.1"
-  },
-  "devDependencies": {
-    "@motion-canvas/ui": "^3.16.0",
-    "@motion-canvas/vite-plugin": "^3.15.1",
-    "typescript": "^5.2.2",
-    "vite": "^4.0.0"
-  }
-}
diff --git a/animation/lambdas/src/global.css b/animation/lambdas/src/global.css
deleted file mode 100644
index 201f5ff..0000000
--- a/animation/lambdas/src/global.css
+++ /dev/null
@@ -1 +0,0 @@
-@import url('https://fonts.googleapis.com/css2?family=Fira+Mono:wght@400;500;700&display=swap');
diff --git a/animation/lambdas/src/motion-canvas.d.ts b/animation/lambdas/src/motion-canvas.d.ts
deleted file mode 100644
index 067c6a4..0000000
--- a/animation/lambdas/src/motion-canvas.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-/// <reference types="@motion-canvas/core/project" />
diff --git a/animation/lambdas/src/project.meta b/animation/lambdas/src/project.meta
deleted file mode 100644
index e6d28f9..0000000
--- a/animation/lambdas/src/project.meta
+++ /dev/null
@@ -1,31 +0,0 @@
-{
-  "version": 0,
-  "shared": {
-    "background": "rgb(10,20,30)",
-    "range": [
-      0,
-      null
-    ],
-    "size": {
-      "x": 1920,
-      "y": 1080
-    },
-    "audioOffset": 0
-  },
-  "preview": {
-    "fps": 60,
-    "resolutionScale": 1
-  },
-  "rendering": {
-    "fps": 30,
-    "resolutionScale": 2,
-    "colorSpace": "srgb",
-    "exporter": {
-      "name": "@motion-canvas/ffmpeg",
-      "options": {
-        "fastStart": false,
-        "includeAudio": true
-      }
-    }
-  }
-}
\ No newline at end of file
diff --git a/animation/lambdas/src/project.ts b/animation/lambdas/src/project.ts
deleted file mode 100644
index f2112ba..0000000
--- a/animation/lambdas/src/project.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import { makeProject } from '@motion-canvas/core';
-
-import './global.css';
-
-import code from './scenes/code?scene';
-
-export default makeProject({
-  scenes: [code],
-});
diff --git a/animation/lambdas/src/scenes/code.meta b/animation/lambdas/src/scenes/code.meta
deleted file mode 100644
index f0654cf..0000000
--- a/animation/lambdas/src/scenes/code.meta
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-  "version": 0,
-  "timeEvents": [],
-  "seed": 2771218248
-}
\ No newline at end of file
diff --git a/animation/lambdas/src/scenes/code.tsx b/animation/lambdas/src/scenes/code.tsx
deleted file mode 100644
index 9c9770c..0000000
--- a/animation/lambdas/src/scenes/code.tsx
+++ /dev/null
@@ -1,876 +0,0 @@
-import { createRef } from '@motion-canvas/core/lib/utils';
-import { makeScene2D, Code, LezerHighlighter, lines } from '@motion-canvas/2d';
-import { all, waitFor, waitUntil } from '@motion-canvas/core/lib/flow';
-import { DEFAULT } from '@motion-canvas/core/lib/signals';
-import { BBox, Vector2 } from '@motion-canvas/core/lib/types';
-import { tags } from '@lezer/highlight';
-import { HighlightStyle } from '@codemirror/language';
-
-import { parser as parser_css } from '@lezer/css';
-import { parser as parser_cpp } from '@lezer/cpp';
-
-const MyStyle = HighlightStyle.define([
-  { tag: tags.keyword, color: '#569CD6' }, // VSCode Keyword color
-  { tag: tags.controlKeyword, color: '#C586C0' }, // VSCode Control Keyword color
-  { tag: tags.operatorKeyword, color: '#C586C0' }, // VSCode Control Keyword color
-  { tag: tags.comment, color: 'gray' }, // VSCode Comment color
-  { tag: tags.className, color: '#4EC9B0' }, // VSCode Class Name color
-  { tag: tags.constant(tags.variableName), color: '#B5CEA8' }, // VSCode Constant color
-  { tag: tags.function(tags.variableName), color: '#DCDCAA' }, // VSCode Function color
-  { tag: tags.function(tags.propertyName), color: '#DCDCAA' }, // VSCode Function color
-  { tag: tags.propertyName, color: '#DCDCAA' }, // VSCode Function color
-  { tag: tags.number, color: '#B5CEA8' }, // VSCode Number color
-  { tag: tags.string, color: '#CE9178' }, // VSCode String color
-  { tag: tags.typeName, color: '#4EC9B0' }, // VSCode Type Name color
-  { tag: tags.squareBracket, color: '#C586C0' }, // VSCode Square Bracket color
-  { tag: tags.bracket, color: '#C586C0' }, // VSCode Bracket color
-  { tag: tags.brace, color: '#DDDD22' }, // VSCode Brace color
-  { tag: tags.processingInstruction, color: '#C586C0' }, // VSCode Brace color
-  { tag: tags.arithmeticOperator, color: '#D16969' }, // VSCode Arithmetic Operator color
-]);
-
-const CssHighlighter = new LezerHighlighter(parser_css, MyStyle);
-const CppHighlighter = new LezerHighlighter(parser_cpp, MyStyle);
-
-export default makeScene2D(function* (view) {
-  const codeRef = createRef<Code>();
-
-  yield view.add(<Code
-    ref={codeRef}
-    fontSize={25}
-    fontFamily={'Fira Mono'}
-    fontWeight={500}
-    offsetX={-1}
-    x={-600}
-    highlighter={CppHighlighter}
-  />);
-
-  const duration = 1.0
-
-  const lambda_intro_1 = `\
-#include <string>
-#include <vector>
-
-struct Person {
-  std::string name;
-  int age;
-};
-
-int main() {
-  std::vector<Person> people{
-      {"Gandalf", 55'000}, {"Frodo", 33}, {"Legolas", 2'931}, {"Gimli", 139}};
-}`
-  const lambda_intro_2 = `\
-#include <algorithm>
-#include <string>
-#include <vector>
-
-struct Person {
-  std::string name;
-  int age;
-};
-
-int main() {
-  std::vector<Person> people{
-      {"Gandalf", 55'000}, {"Frodo", 33}, {"Legolas", 2'931}, {"Gimli", 139}};
-  std::sort(people.begin(), people.end());
-}`
-
-  const lambda_intro_3 = `\
-#include <algorithm>
-#include <string>
-#include <vector>
-
-struct Person {
-  std::string name;
-  int age;
-};
-
-int main() {
-  std::vector<Person> people{
-      {"Gandalf", 55'000}, {"Frodo", 33}, {"Legolas", 2'931}, {"Gimli", 139}};
-  // ❌ Won't compile, cannot compare Person objects.
-  std::sort(people.begin(), people.end());
-}`
-
-  yield* codeRef().code(lambda_intro_1, duration).wait(duration);
-  yield* codeRef().code(lambda_intro_2, duration).to(lambda_intro_3, duration).wait(duration);
-
-
-  const error_message = `\
-In file included from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algobase.h:71,
-                 from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/algorithm:61,
-                 from <source>:1:
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/predefined_ops.h: In instantiation of 'constexpr bool __gnu_cxx::__ops::_Iter_less_iter::operator()(_Iterator1, _Iterator2) const [with _Iterator1 = __gnu_cxx::__normal_iterator<Person*, std::vector<Person> >; _Iterator2 = __gnu_cxx::__normal_iterator<Person*, std::vector<Person> >]':
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algo.h:82:17:   required from 'void std::__move_median_to_first(_Iterator, _Iterator, _Iterator, _Iterator, _Compare) [with _Iterator = __gnu_cxx::__normal_iterator<Person*, std::vector<Person> >; _Compare = __gnu_cxx::__ops::_Iter_less_iter]'
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algo.h:1924:34:   required from '_RandomAccessIterator std::__unguarded_partition_pivot(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Person*, std::vector<Person> >; _Compare = __gnu_cxx::__ops::_Iter_less_iter]'
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algo.h:1958:38:   required from 'void std::__introsort_loop(_RandomAccessIterator, _RandomAccessIterator, _Size, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Person*, std::vector<Person> >; _Size = long int; _Compare = __gnu_cxx::__ops::_Iter_less_iter]'
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algo.h:1974:25:   required from 'void std::__sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Person*, std::vector<Person> >; _Compare = __gnu_cxx::__ops::_Iter_less_iter]'
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algo.h:4859:18:   required from 'void std::sort(_RAIter, _RAIter) [with _RAIter = __gnu_cxx::__normal_iterator<Person*, std::vector<Person> >]'
-<source>:14:41:   required from here
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/predefined_ops.h:43:23: error: no match for 'operator<' (operand types are 'Person' and 'Person')
-   43 |       { return *__it1 < *__it2; }
-      |                ~~~~~~~^~~~~~~~
-In file included from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algobase.h:67,
-                 from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/algorithm:61,
-                 from <source>:1:
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_iterator.h:1096:5: note: candidate: 'template<class _IteratorL, class _IteratorR, class _Container> bool __gnu_cxx::operator<(const __gnu_cxx::__normal_iterator<_IteratorL, _Container>&, const __gnu_cxx::__normal_iterator<_IteratorR, _Container>&)'
- 1096 |     operator<(const __normal_iterator<_IteratorL, _Container>& __lhs,
-      |     ^~~~~~~~
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_iterator.h:1096:5: note:   template argument deduction/substitution failed:
-In file included from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algobase.h:71,
-                 from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/algorithm:61,
-                 from <source>:1:
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/predefined_ops.h:43:23: note:   'Person' is not derived from 'const __gnu_cxx::__normal_iterator<_IteratorL, _Container>'
-   43 |       { return *__it1 < *__it2; }
-      |                ~~~~~~~^~~~~~~~
-In file included from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algobase.h:67,
-                 from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/algorithm:61,
-                 from <source>:1:
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_iterator.h:1104:5: note: candidate: 'template<class _Iterator, class _Container> bool __gnu_cxx::operator<(const __gnu_cxx::__normal_iterator<_Iterator, _Container>&, const __gnu_cxx::__normal_iterator<_Iterator, _Container>&)'
- 1104 |     operator<(const __normal_iterator<_Iterator, _Container>& __lhs,
-      |     ^~~~~~~~
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_iterator.h:1104:5: note:   template argument deduction/substitution failed:
-In file included from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algobase.h:71,
-                 from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/algorithm:61,
-                 from <source>:1:
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/predefined_ops.h:43:23: note:   'Person' is not derived from 'const __gnu_cxx::__normal_iterator<_Iterator, _Container>'
-   43 |       { return *__it1 < *__it2; }
-      |                ~~~~~~~^~~~~~~~
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/predefined_ops.h: In instantiation of 'bool __gnu_cxx::__ops::_Val_less_iter::operator()(_Value&, _Iterator) const [with _Value = Person; _Iterator = __gnu_cxx::__normal_iterator<Person*, std::vector<Person> >]':
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algo.h:1826:20:   required from 'void std::__unguarded_linear_insert(_RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Person*, std::vector<Person> >; _Compare = __gnu_cxx::__ops::_Val_less_iter]'
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algo.h:1854:36:   required from 'void std::__insertion_sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Person*, std::vector<Person> >; _Compare = __gnu_cxx::__ops::_Iter_less_iter]'
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algo.h:1886:25:   required from 'void std::__final_insertion_sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Person*, std::vector<Person> >; _Compare = __gnu_cxx::__ops::_Iter_less_iter]'
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algo.h:1977:31:   required from 'void std::__sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Person*, std::vector<Person> >; _Compare = __gnu_cxx::__ops::_Iter_less_iter]'
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algo.h:4859:18:   required from 'void std::sort(_RAIter, _RAIter) [with _RAIter = __gnu_cxx::__normal_iterator<Person*, std::vector<Person> >]'
-<source>:14:41:   required from here
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/predefined_ops.h:96:22: error: no match for 'operator<' (operand types are 'Person' and 'Person')
-   96 |       { return __val < *__it; }
-      |                ~~~~~~^~~~~~~
-In file included from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algobase.h:67,
-                 from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/algorithm:61,
-                 from <source>:1:
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_iterator.h:1096:5: note: candidate: 'template<class _IteratorL, class _IteratorR, class _Container> bool __gnu_cxx::operator<(const __gnu_cxx::__normal_iterator<_IteratorL, _Container>&, const __gnu_cxx::__normal_iterator<_IteratorR, _Container>&)'
- 1096 |     operator<(const __normal_iterator<_IteratorL, _Container>& __lhs,
-      |     ^~~~~~~~
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_iterator.h:1096:5: note:   template argument deduction/substitution failed:
-In file included from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algobase.h:71,
-                 from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/algorithm:61,
-                 from <source>:1:
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/predefined_ops.h:96:22: note:   'Person' is not derived from 'const __gnu_cxx::__normal_iterator<_IteratorL, _Container>'
-   96 |       { return __val < *__it; }
-      |                ~~~~~~^~~~~~~
-In file included from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algobase.h:67,
-                 from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/algorithm:61,
-                 from <source>:1:
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_iterator.h:1104:5: note: candidate: 'template<class _Iterator, class _Container> bool __gnu_cxx::operator<(const __gnu_cxx::__normal_iterator<_Iterator, _Container>&, const __gnu_cxx::__normal_iterator<_Iterator, _Container>&)'
- 1104 |     operator<(const __normal_iterator<_Iterator, _Container>& __lhs,
-      |     ^~~~~~~~
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_iterator.h:1104:5: note:   template argument deduction/substitution failed:
-In file included from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algobase.h:71,
-                 from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/algorithm:61,
-                 from <source>:1:
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/predefined_ops.h:96:22: note:   'Person' is not derived from 'const __gnu_cxx::__normal_iterator<_Iterator, _Container>'
-   96 |       { return __val < *__it; }
-      |                ~~~~~~^~~~~~~
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/predefined_ops.h: In instantiation of 'bool __gnu_cxx::__ops::_Iter_less_val::operator()(_Iterator, _Value&) const [with _Iterator = __gnu_cxx::__normal_iterator<Person*, std::vector<Person> >; _Value = Person]':
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_heap.h:139:48:   required from 'void std::__push_heap(_RandomAccessIterator, _Distance, _Distance, _Tp, _Compare&) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Person*, std::vector<Person> >; _Distance = long int; _Tp = Person; _Compare = __gnu_cxx::__ops::_Iter_less_val]'
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_heap.h:246:23:   required from 'void std::__adjust_heap(_RandomAccessIterator, _Distance, _Distance, _Tp, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Person*, std::vector<Person> >; _Distance = long int; _Tp = Person; _Compare = __gnu_cxx::__ops::_Iter_less_iter]'
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_heap.h:355:22:   required from 'void std::__make_heap(_RandomAccessIterator, _RandomAccessIterator, _Compare&) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Person*, std::vector<Person> >; _Compare = __gnu_cxx::__ops::_Iter_less_iter]'
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algo.h:1666:23:   required from 'void std::__heap_select(_RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Person*, std::vector<Person> >; _Compare = __gnu_cxx::__ops::_Iter_less_iter]'
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algo.h:1937:25:   required from 'void std::__partial_sort(_RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Person*, std::vector<Person> >; _Compare = __gnu_cxx::__ops::_Iter_less_iter]'
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algo.h:1953:27:   required from 'void std::__introsort_loop(_RandomAccessIterator, _RandomAccessIterator, _Size, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Person*, std::vector<Person> >; _Size = long int; _Compare = __gnu_cxx::__ops::_Iter_less_iter]'
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algo.h:1974:25:   required from 'void std::__sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Person*, std::vector<Person> >; _Compare = __gnu_cxx::__ops::_Iter_less_iter]'
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algo.h:4859:18:   required from 'void std::sort(_RAIter, _RAIter) [with _RAIter = __gnu_cxx::__normal_iterator<Person*, std::vector<Person> >]'
-<source>:14:41:   required from here
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/predefined_ops.h:67:22: error: no match for 'operator<' (operand types are 'Person' and 'Person')
-   67 |       { return *__it < __val; }
-      |                ~~~~~~^~~~~~~
-In file included from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algobase.h:67,
-                 from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/algorithm:61,
-                 from <source>:1:
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_iterator.h:1096:5: note: candidate: 'template<class _IteratorL, class _IteratorR, class _Container> bool __gnu_cxx::operator<(const __gnu_cxx::__normal_iterator<_IteratorL, _Container>&, const __gnu_cxx::__normal_iterator<_IteratorR, _Container>&)'
- 1096 |     operator<(const __normal_iterator<_IteratorL, _Container>& __lhs,
-      |     ^~~~~~~~
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_iterator.h:1096:5: note:   template argument deduction/substitution failed:
-In file included from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algobase.h:71,
-                 from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/algorithm:61,
-                 from <source>:1:
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/predefined_ops.h:67:22: note:   'Person' is not derived from 'const __gnu_cxx::__normal_iterator<_IteratorL, _Container>'
-   67 |       { return *__it < __val; }
-      |                ~~~~~~^~~~~~~
-In file included from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algobase.h:67,
-                 from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/algorithm:61,
-                 from <source>:1:
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_iterator.h:1104:5: note: candidate: 'template<class _Iterator, class _Container> bool __gnu_cxx::operator<(const __gnu_cxx::__normal_iterator<_Iterator, _Container>&, const __gnu_cxx::__normal_iterator<_Iterator, _Container>&)'
- 1104 |     operator<(const __normal_iterator<_Iterator, _Container>& __lhs,
-      |     ^~~~~~~~
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_iterator.h:1104:5: note:   template argument deduction/substitution failed:
-In file included from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algobase.h:71,
-                 from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/algorithm:61,
-                 from <source>:1:
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/predefined_ops.h:67:22: note:   'Person' is not derived from 'const __gnu_cxx::__normal_iterator<_Iterator, _Container>'
-   67 |       { return *__it < __val; }
-      |                ~~~~~~^~~~~~~
-Compiler returned: 1`
-
-  yield* all(
-    codeRef().highlighter(CssHighlighter, 0),
-    codeRef().fontSize(7, 0),
-    codeRef().x(-900, 0),
-    codeRef().y(1100, 0),
-    codeRef().code(error_message, 0),
-  );
-  yield* waitFor(duration);
-
-  yield* all(
-    codeRef().y(0, duration),
-  );
-  yield* waitFor(duration);
-
-  yield* all(
-    codeRef().fontSize(35, duration),
-    codeRef().x(-2400, duration),
-    codeRef().y(2000, duration),
-  );
-  yield* waitFor(duration);
-
-  yield* all(
-    codeRef().highlighter(CppHighlighter, 0),
-    codeRef().fontSize(25, 0),
-    codeRef().x(-600, 0),
-    codeRef().y(0, 0),
-    codeRef().code(lambda_intro_3, 0),
-  );
-  yield* waitFor(duration);
-
-  const lambda_intro_4 = `\
-#include <algorithm>
-#include <string>
-#include <vector>
-
-struct Person {
-  std::string name;
-  int age;
-};
-
-int main() {
-  std::vector<Person> people{
-      {"Gandalf", 55'000}, {"Frodo", 33}, {"Legolas", 2'931}, {"Gimli", 139}};
-  std::sort(
-      people.begin(), people.end(),
-      [](const auto& left, const auto& right) { return left.age < right.age; });
-}`
-  yield* all(
-    codeRef().code(lambda_intro_4, duration),
-  );
-  yield* waitFor(duration);
-
-  const lambda_intro_5 = `\
-#include <algorithm>
-#include <iostream>
-#include <string>
-#include <vector>
-
-struct Person {
-  std::string name;
-  int age;
-};
-
-void Print(const std::vector<Person>& persons, const std::string& tag) {
-  std::cout << tag << std::endl;
-  for (const auto& person : persons) {
-    std::cout << person.name << " " << person.age << "\\n";
-  }
-}
-
-int main() {
-  std::vector<Person> people{
-      {"Gandalf", 55'000}, {"Frodo", 33}, {"Legolas", 2'931}, {"Gimli", 139}};
-  Print(people, "> Before sorting:");
-  std::sort(
-      people.begin(), people.end(),
-      [](const auto& left, const auto& right) { return left.age < right.age; });
-  Print(people, "> Sorted by age ascending:");
-}`
-  yield* all(
-    codeRef().code(lambda_intro_5, duration),
-  );
-  yield* waitFor(duration);
-
-  yield* all(
-    codeRef().code('', 0),
-    codeRef().fontSize(70, 0),
-  );
-  const lambda_simple_1 = `\
-int main() {
-  [](){}();
-}`
-  yield* all(
-    codeRef().code(lambda_simple_1, duration),
-  );
-  yield* waitFor(duration);
-
-  const lambda_simple_2 = `\
-// ✅ Yep, this compiles 🙃
-int main() {
-  [](){}();
-}`
-  yield* all(
-    codeRef().code(lambda_simple_2, duration),
-  );
-  yield* waitFor(duration);
-
-  yield* all(
-    codeRef().code(lambda_intro_5, 0),
-    codeRef().fontSize(25, 0),
-  );
-  yield* waitFor(duration);
-
-  const function_ptr = `\
-#include <algorithm>
-#include <iostream>
-#include <string>
-#include <vector>
-
-struct Person {
-  std::string name;
-  int age;
-};
-
-void Print(const std::vector<Person>& persons, const std::string& tag) {
-  std::cout << tag << std::endl;
-  for (const auto& person : persons) {
-    std::cout << person.name << " " << person.age << "\\n";
-  }
-}
-
-bool less(const Person& p1, const Person& p2) { return p1.age < p2.age; }
-
-int main() {
-  std::vector<Person> people{
-      {"Gandalf", 55'000}, {"Frodo", 33}, {"Legolas", 2'931}, {"Gimli", 139}};
-  Print(people, "> Before sorting:");
-  std::sort(people.begin(), people.end(), &less);
-  Print(people, "> Sorted by age ascending:");
-}`
-  yield* all(
-    codeRef().code(function_ptr, duration),
-    codeRef().fontSize(25, duration),
-  );
-  yield* waitFor(duration);
-
-  const function_ptr_1 = `\
-#include <algorithm>
-#include <iostream>
-#include <string>
-#include <vector>
-
-struct Person {
-  std::string name;
-  int age;
-};
-
-void Print(const std::vector<Person>& persons, const std::string& tag) {
-  std::cout << tag << std::endl;
-  for (const auto& person : persons) {
-    std::cout << person.name << " " << person.age << "\\n";
-  }
-}
-
-bool less(const Person& p1, const Person& p2) { return p1.age < p2.age; }
-
-int main() {
-  std::vector<Person> people{
-      {"Gandalf", 55'000}, {"Frodo", 33}, {"Legolas", 2'931}, {"Gimli", 139}};
-  Print(people, "> Before sorting:");
-  std::sort(people.begin(), people.end(), less);
-  Print(people, "> Sorted by age ascending:");
-}`
-  yield* all(
-    codeRef().code(function_ptr_1, duration),
-    codeRef().fontSize(25, duration),
-  );
-  yield* waitFor(duration);
-
-  const functor = `\
-#include <algorithm>
-#include <iostream>
-#include <string>
-#include <vector>
-
-struct Person {
-  std::string name;
-  int age;
-};
-
-void Print(const std::vector<Person>& persons, const std::string& tag) {
-  std::cout << tag << std::endl;
-  for (const auto& person : persons) {
-    std::cout << person.name << " " << person.age << "\\n";
-  }
-}
-
-class ComparisonToQueryAge {
- public:
-  explicit ComparisonToQueryAge(int query_age) : query_age_{query_age} {}
-
-  bool operator()(const Person& p1, const Person& p2) const {
-    return std::abs(p1.age - query_age_) < std::abs(p2.age - query_age_);
-  }
-
- private:
-  int query_age_{};
-};
-
-int main() {
-  std::vector<Person> people{
-      {"Gandalf", 55'000}, {"Frodo", 33}, {"Legolas", 2'931}, {"Gimli", 139}};
-  Print(people, "> Before sorting:");
-  std::sort(people.begin(), people.end(), ComparisonToQueryAge{4242});
-  Print(people, "> Sorted by age difference to 4242, ascending:");
-}`
-  yield* all(
-    codeRef().code(functor, duration),
-    codeRef().fontSize(22, duration),
-  );
-  yield* waitFor(duration);
-
-  const my_sort = `\
-#include <iostream>
-#include <string>
-#include <vector>
-
-struct Person {
-  std::string name;
-  int age;
-};
-
-void Print(const std::vector<Person>& persons, const std::string& tag) {
-  std::cout << tag << std::endl;
-  for (const auto& person : persons) {
-    std::cout << person.name << " " << person.age << "\\n";
-  }
-}
-
-template <class Iterator, class Comparator>
-void MySort(Iterator begin, Iterator end, Comparator comparator) {
-  // The actual algorithm is not important here.
-  for (Iterator i = begin + 1; i != end; ++i) {
-    Iterator j = i;
-    // We call comparator(*iter_1, *iter_2) somewhere in our algorithm.
-    while (j != begin && comparator(*j, *(j - 1))) {
-      std::iter_swap(j, j - 1);
-      --j;
-    }
-  }
-}
-
-int main() {
-  std::vector<Person> people{
-      {"Gandalf", 55'000}, {"Frodo", 33}, {"Legolas", 2'931}, {"Gimli", 139}};
-  Print(people, "> Before sorting:");
-}`
-
-  yield* all(
-    codeRef().code(my_sort, 0),
-    codeRef().fontSize(22, 0),
-  );
-  yield* waitFor(duration);
-
-  const my_sort_2 = `\
-#include <iostream>
-#include <string>
-#include <vector>
-
-struct Person {
-  std::string name;
-  int age;
-};
-
-void Print(const std::vector<Person>& persons, const std::string& tag) {
-  std::cout << tag << std::endl;
-  for (const auto& person : persons) {
-    std::cout << person.name << " " << person.age << "\\n";
-  }
-}
-
-bool less(const Person& p1, const Person& p2) { return p1.age < p2.age; }
-
-template <class Iterator, class Comparator>
-void MySort(Iterator begin, Iterator end, Comparator comparator) {
-  // The actual algorithm is not important here.
-  for (Iterator i = begin + 1; i != end; ++i) {
-    Iterator j = i;
-    // We call comparator(*iter_1, *iter_2) somewhere in our algorithm.
-    while (j != begin && comparator(*j, *(j - 1))) {
-      std::iter_swap(j, j - 1);
-      --j;
-    }
-  }
-}
-
-int main() {
-  std::vector<Person> people{
-      {"Gandalf", 55'000}, {"Frodo", 33}, {"Legolas", 2'931}, {"Gimli", 139}};
-  Print(people, "> Before sorting:");
-  MySort(people.begin(), people.end(), less);
-  Print(people, "> Sorted by age ascending:");
-  MySort(people.begin(), people.end(), &less);
-  Print(people, "> Sorted by age ascending:");
-}`
-
-  yield* all(
-    codeRef().code(my_sort_2, duration),
-    codeRef().fontSize(20, duration),
-  );
-  yield* waitFor(duration);
-
-  const my_sort_3 = `\
-#include <iostream>
-#include <string>
-#include <vector>
-
-struct Person {
-  std::string name;
-  int age;
-};
-
-void Print(const std::vector<Person>& persons, const std::string& tag) {
-  std::cout << tag << std::endl;
-  for (const auto& person : persons) {
-    std::cout << person.name << " " << person.age << "\\n";
-  }
-}
-
-class ComparisonToQueryAge {
- public:
-  explicit ComparisonToQueryAge(int query_age) : query_age_{query_age} {}
-
-  bool operator()(const Person& p1, const Person& p2) const {
-    return std::abs(p1.age - query_age_) < std::abs(p2.age - query_age_);
-  }
-
- private:
-  int query_age_{};
-};
-
-bool less(const Person& p1, const Person& p2) { return p1.age < p2.age; }
-
-template <class Iterator, class Comparator>
-void MySort(Iterator begin, Iterator end, Comparator comparator) {
-  // The actual algorithm is not important here.
-  for (Iterator i = begin + 1; i != end; ++i) {
-    Iterator j = i;
-    // We call comparator(*iter_1, *iter_2) somewhere in our algorithm.
-    while (j != begin && comparator(*j, *(j - 1))) {
-      std::iter_swap(j, j - 1);
-      --j;
-    }
-  }
-}
-
-int main() {
-  std::vector<Person> people{
-      {"Gandalf", 55'000}, {"Frodo", 33}, {"Legolas", 2'931}, {"Gimli", 139}};
-  Print(people, "> Before sorting:");
-  MySort(people.begin(), people.end(), less);
-  Print(people, "> Sorted by age ascending:");
-  MySort(people.begin(), people.end(), ComparisonToQueryAge{4242});
-  Print(people, "> Sorted by age difference to 4242, ascending:");
-  MySort(people.begin(), people.end(), &less);
-  Print(people, "> Sorted by age ascending:");
-}`
-
-  yield* all(
-    codeRef().code(my_sort_3, duration),
-    codeRef().fontSize(15, duration),
-  );
-  yield* waitFor(duration);
-
-  yield* all(
-    codeRef().code(functor, 0),
-    codeRef().fontSize(22, 0),
-  );
-  yield* waitFor(duration);
-
-  const lambdas = `\
-#include <algorithm>
-#include <iostream>
-#include <string>
-#include <vector>
-
-struct Person {
-  std::string name;
-  int age;
-};
-
-int main() {
-  const auto Print = [](const auto& persons, const auto& tag) {
-    std::cout << tag << std::endl;
-    for (const auto& person : persons) {
-      std::cout << person.name << " " << person.age << "\\n";
-    }
-  };
-
-  std::vector<Person> people{
-      {"Gandalf", 55'000}, {"Frodo", 33}, {"Legolas", 2'931}, {"Gimli", 139}};
-  Print(people, "> Before sorting:");
-
-  std::sort(people.begin(), people.end(),
-            [](const auto& p1, const auto& p2) { return p1.age < p2.age; });
-  Print(people, "> Sorted by age ascending:");
-
-  const int query_age = 4242;
-  std::sort(people.begin(), people.end(),
-            [query_age](const auto& p1, const auto& p2) -> bool {
-              return std::abs(p1.age - query_age) < std::abs(p2.age - query_age);
-            });
-  Print(people, "> Sorted by age difference to 4242, ascending:");
-}`
-  yield* all(
-    codeRef().code(lambdas, duration),
-  );
-  yield* waitFor(duration);
-
-  const lambdas_by_ref = `\
-#include <algorithm>
-#include <iostream>
-#include <string>
-#include <vector>
-
-struct Person {
-  std::string name;
-  int age;
-};
-
-int main() {
-  const auto Print = [](const auto& persons, const auto& tag) {
-    std::cout << tag << std::endl;
-    for (const auto& person : persons) {
-      std::cout << person.name << " " << person.age << "\\n";
-    }
-  };
-
-  std::vector<Person> people{
-      {"Gandalf", 55'000}, {"Frodo", 33}, {"Legolas", 2'931}, {"Gimli", 139}};
-  Print(people, "> Before sorting:");
-
-  std::sort(people.begin(), people.end(),
-            [](const auto& p1, const auto& p2) { return p1.age < p2.age; });
-  Print(people, "> Sorted by age ascending:");
-
-  const int query_age = 4242;
-  std::sort(people.begin(), people.end(),
-            [&query_age](const auto& p1, const auto& p2) -> bool {
-              return std::abs(p1.age - query_age) < std::abs(p2.age - query_age);
-            });
-  Print(people, "> Sorted by age difference to 4242, ascending:");
-}`
-  yield* all(
-    codeRef().code(lambdas_by_ref, duration),
-  );
-  yield* waitFor(duration);
-
-  const lambda_capturing = `\
-#include <iostream>
-
-int main() {
-  int one{};
-  float two{};
-  double three{};
-  const auto Lambda = [&one, two, &three] {
-    // Do something with one, two, three.
-    std::cout << one << " " << two << " " << three << std::endl;
-  };
-  Lambda();
-}`
-  yield* all(
-    codeRef().code(lambda_capturing, 0),
-    codeRef().fontSize(25, 0),
-  );
-  yield* waitFor(duration);
-
-  const lambda_capturing_all = `\
-#include <iostream>
-
-int main() {
-  int one{};
-  float two{};
-  double three{};
-  const auto Lambda = [=] {
-    // All variables are captured by copy.
-    std::cout << one << " " << two << " " << three << std::endl;
-  };
-  Lambda();
-}`
-  yield* all(
-    codeRef().code(lambda_capturing_all, duration),
-    codeRef().fontSize(25, duration),
-  );
-  yield* waitFor(duration);
-
-  const lambda_capturing_all_with_some = `\
-#include <iostream>
-
-int main() {
-  int one{};
-  float two{};
-  double three{};
-  const auto Lambda = [=, &two] {
-    // two is captured by reference, all the others by copy.
-    std::cout << one << " " << two << " " << three << std::endl;
-  };
-  Lambda();
-}`
-  yield* all(
-    codeRef().code(lambda_capturing_all_with_some, duration),
-    codeRef().fontSize(25, duration),
-  );
-  yield* waitFor(duration);
-
-  const lambda_capturing_all_by_ref = `\
-#include <iostream>
-
-int main() {
-  int one{};
-  float two{};
-  double three{};
-  const auto Lambda = [&] {
-    // All variables are captured by reference.
-    std::cout << one << " " << two << " " << three << std::endl;
-  };
-  Lambda();
-}`
-  yield* all(
-    codeRef().code(lambda_capturing_all_by_ref, duration),
-    codeRef().fontSize(25, duration),
-  );
-  yield* waitFor(duration);
-
-  const lambda_capturing_all_by_ref_some_by_copy = `\
-#include <iostream>
-
-int main() {
-  int one{};
-  float two{};
-  double three{};
-  const auto Lambda = [&, two] {
-    // two is captured by copy, all the others by reference.
-    std::cout << one << " " << two << " " << three << std::endl;
-  };
-  Lambda();
-}`
-  yield* all(
-    codeRef().code(lambda_capturing_all_by_ref_some_by_copy, duration),
-    codeRef().fontSize(25, duration),
-  );
-  yield* waitFor(duration);
-
-  const lambda_capturing_this = `\
-#include <iostream>
-
-struct Foo {
-  void Bar() {
-    [this] {
-      // The whole current object is captured by reference.
-      std::cout << one << " " << two << " " << three << std::endl;
-    }();  // We call this lambda in-place for illustration purposes.
-  }
-
-  int one{};
-  float two{};
-  double three{};
-};
-
-int main() {
-  Foo foo{};
-  foo.Bar();
-}`
-  yield* all(
-    codeRef().code(lambda_capturing_this, duration),
-    codeRef().fontSize(25, duration),
-  );
-  yield* waitFor(duration);
-
-  const sandwich_bad = `\
-#include <iostream>
-#include <string>
-
-// 😱 Comments tend to drift out of sync with code.
-Sandwich MakeGourmetSandwich() {
-    Sandwich sandwich{};
-
-    // Step 1: Prepare the bread
-    sandwich += "Choosing the finest sourdough...\\n";
-    sandwich += "Lightly toasting it to perfection...\\n";
-    sandwich += "Spreading a generous amount of garlic aioli...\\n";
-
-    // Step 2: Prepare the ingredients
-    sandwich += "Grilling marinated chicken...\\n";
-    sandwich += "Adding fresh arugula and juicy tomatoes...\\n";
-    sandwich += "Topping it off with caramelized onions...\\n";
-
-    // Step 3: Assemble the masterpiece
-    sandwich += "Assembling the sandwich with care...\\n";
-    sandwich += "Adding a drizzle of truffle oil...\\n";
-    sandwich += "Plating it elegantly...\\n";
-
-    return sandwich;
-}`
-  yield* all(
-    codeRef().code(sandwich_bad, 0),
-    codeRef().fontSize(25, 0),
-  );
-  yield* waitFor(duration);
-
-  const sandwich_better = `\
-#include <iostream>
-#include <string>
-
-// ✅ Every step is encapsulated in a lambda.
-Sandwich MakeGourmetSandwich() {
-    Sandwich sandwich{};
-
-    const auto PrepareBread = [&sandwich]() {
-        sandwich += "Choosing the finest sourdough...\\n";
-        sandwich += "Lightly toasting it to perfection...\\n";
-        sandwich += "Spreading a generous amount of garlic aioli...\\n";
-    };
-
-    const auto PrepareIngredients = [&sandwich]() {
-        sandwich += "Grilling marinated chicken...\\n";
-        sandwich += "Adding fresh arugula and juicy tomatoes...\\n";
-        sandwich += "Topping it off with caramelized onions...\\n";
-    };
-
-    const auto PlateSandwich = [&sandwich]() {
-        sandwich += "Assembling the sandwich with care...\\n";
-        sandwich += "Adding a drizzle of truffle oil...\\n";
-        sandwich += "Plating it elegantly...\\n";
-    };
-
-    PrepareBread();
-    PrepareIngredients();
-    PlateSandwich();
-
-    return sandwich;
-}`
-  yield* all(
-    codeRef().code(sandwich_better, duration),
-    codeRef().fontSize(25, duration),
-  );
-  yield* waitFor(duration);
-
-  const funny_lambda = `\
-[](){}();`
-  yield* all(
-    codeRef().code(funny_lambda, 0),
-    codeRef().fontSize(85, 0),
-    codeRef().x(-200, 0),
-  );
-  yield* waitFor(duration);
-
-  yield* waitFor(duration);
-
-});
diff --git a/animation/lambdas/tsconfig.json b/animation/lambdas/tsconfig.json
deleted file mode 100644
index 789b7d1..0000000
--- a/animation/lambdas/tsconfig.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-  "extends": "@motion-canvas/2d/tsconfig.project.json",
-  "compilerOptions": {
-    "baseUrl": "src"
-  },
-  "include": ["src"]
-}
diff --git a/animation/lambdas/videos/travolta.mp4 b/animation/lambdas/videos/travolta.mp4
deleted file mode 100644
index 9d6b4ee..0000000
--- a/animation/lambdas/videos/travolta.mp4
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:5b300b8896b6062071238fde2ea43584797b3bbc93280e331b219a86380b11f1
-size 1181848
diff --git a/animation/lambdas/vite.config.ts b/animation/lambdas/vite.config.ts
deleted file mode 100644
index 4e353f3..0000000
--- a/animation/lambdas/vite.config.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import { defineConfig } from 'vite';
-import ffmpeg from '@motion-canvas/ffmpeg';
-import motionCanvas from '@motion-canvas/vite-plugin';
-
-export default defineConfig({
-  plugins: [motionCanvas(), ffmpeg()],
-
-});
diff --git a/animation/memory_and_smart_pointers/.gitignore b/animation/memory_and_smart_pointers/.gitignore
deleted file mode 100644
index 829b1c7..0000000
--- a/animation/memory_and_smart_pointers/.gitignore
+++ /dev/null
@@ -1,15 +0,0 @@
-# Generated files
-node_modules
-output
-dist
-
-# Editor directories and files
-.vscode/*
-!.vscode/extensions.json
-.idea
-.DS_Store
-*.suo
-*.ntvs*
-*.njsproj
-*.sln
-*.sw?
diff --git a/animation/memory_and_smart_pointers/package-lock.json b/animation/memory_and_smart_pointers/package-lock.json
deleted file mode 100644
index dad2ff3..0000000
--- a/animation/memory_and_smart_pointers/package-lock.json
+++ /dev/null
@@ -1,1366 +0,0 @@
-{
-  "name": "value_semantics",
-  "version": "0.0.0",
-  "lockfileVersion": 3,
-  "requires": true,
-  "packages": {
-    "": {
-      "name": "value_semantics",
-      "version": "0.0.0",
-      "dependencies": {
-        "@lezer/cpp": "^1.1.2",
-        "@motion-canvas/2d": "^3.16.0",
-        "@motion-canvas/core": "^3.16.0",
-        "@motion-canvas/ffmpeg": "^1.1.1"
-      },
-      "devDependencies": {
-        "@motion-canvas/ui": "^3.16.0",
-        "@motion-canvas/vite-plugin": "^3.15.1",
-        "typescript": "^5.2.2",
-        "vite": "^4.0.0"
-      }
-    },
-    "node_modules/@codemirror/language": {
-      "version": "6.10.2",
-      "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.10.2.tgz",
-      "integrity": "sha512-kgbTYTo0Au6dCSc/TFy7fK3fpJmgHDv1sG1KNQKJXVi+xBTEeBPY/M30YXiU6mMXeH+YIDLsbrT4ZwNRdtF+SA==",
-      "dependencies": {
-        "@codemirror/state": "^6.0.0",
-        "@codemirror/view": "^6.23.0",
-        "@lezer/common": "^1.1.0",
-        "@lezer/highlight": "^1.0.0",
-        "@lezer/lr": "^1.0.0",
-        "style-mod": "^4.0.0"
-      }
-    },
-    "node_modules/@codemirror/state": {
-      "version": "6.4.1",
-      "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.4.1.tgz",
-      "integrity": "sha512-QkEyUiLhsJoZkbumGZlswmAhA7CBU02Wrz7zvH4SrcifbsqwlXShVXg65f3v/ts57W3dqyamEriMhij1Z3Zz4A=="
-    },
-    "node_modules/@codemirror/view": {
-      "version": "6.32.0",
-      "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.32.0.tgz",
-      "integrity": "sha512-AgVNvED2QTsZp5e3syoHLsrWtwJFYWdx1Vr/m3f4h1ATQz0ax60CfXF3Htdmk69k2MlYZw8gXesnQdHtzyVmAw==",
-      "dependencies": {
-        "@codemirror/state": "^6.4.0",
-        "style-mod": "^4.1.0",
-        "w3c-keyname": "^2.2.4"
-      }
-    },
-    "node_modules/@esbuild/android-arm": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
-      "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==",
-      "cpu": [
-        "arm"
-      ],
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/android-arm64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz",
-      "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/android-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz",
-      "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/darwin-arm64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz",
-      "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/darwin-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz",
-      "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/freebsd-arm64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz",
-      "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "freebsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/freebsd-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz",
-      "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "freebsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-arm": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz",
-      "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==",
-      "cpu": [
-        "arm"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-arm64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz",
-      "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-ia32": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz",
-      "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==",
-      "cpu": [
-        "ia32"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-loong64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz",
-      "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==",
-      "cpu": [
-        "loong64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-mips64el": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz",
-      "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==",
-      "cpu": [
-        "mips64el"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-ppc64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz",
-      "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==",
-      "cpu": [
-        "ppc64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-riscv64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz",
-      "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==",
-      "cpu": [
-        "riscv64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-s390x": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz",
-      "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==",
-      "cpu": [
-        "s390x"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz",
-      "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/netbsd-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz",
-      "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "netbsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/openbsd-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz",
-      "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "openbsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/sunos-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz",
-      "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "sunos"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/win32-arm64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz",
-      "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/win32-ia32": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz",
-      "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==",
-      "cpu": [
-        "ia32"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/win32-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz",
-      "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@ffmpeg-installer/darwin-arm64": {
-      "version": "4.1.5",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/darwin-arm64/-/darwin-arm64-4.1.5.tgz",
-      "integrity": "sha512-hYqTiP63mXz7wSQfuqfFwfLOfwwFChUedeCVKkBtl/cliaTM7/ePI9bVzfZ2c+dWu3TqCwLDRWNSJ5pqZl8otA==",
-      "cpu": [
-        "arm64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/darwin-x64": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/darwin-x64/-/darwin-x64-4.1.0.tgz",
-      "integrity": "sha512-Z4EyG3cIFjdhlY8wI9aLUXuH8nVt7E9SlMVZtWvSPnm2sm37/yC2CwjUzyCQbJbySnef1tQwGG2Sx+uWhd9IAw==",
-      "cpu": [
-        "x64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/ffmpeg": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/ffmpeg/-/ffmpeg-1.1.0.tgz",
-      "integrity": "sha512-Uq4rmwkdGxIa9A6Bd/VqqYbT7zqh1GrT5/rFwCwKM70b42W5gIjWeVETq6SdcL0zXqDtY081Ws/iJWhr1+xvQg==",
-      "optionalDependencies": {
-        "@ffmpeg-installer/darwin-arm64": "4.1.5",
-        "@ffmpeg-installer/darwin-x64": "4.1.0",
-        "@ffmpeg-installer/linux-arm": "4.1.3",
-        "@ffmpeg-installer/linux-arm64": "4.1.4",
-        "@ffmpeg-installer/linux-ia32": "4.1.0",
-        "@ffmpeg-installer/linux-x64": "4.1.0",
-        "@ffmpeg-installer/win32-ia32": "4.1.0",
-        "@ffmpeg-installer/win32-x64": "4.1.0"
-      }
-    },
-    "node_modules/@ffmpeg-installer/linux-arm": {
-      "version": "4.1.3",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/linux-arm/-/linux-arm-4.1.3.tgz",
-      "integrity": "sha512-NDf5V6l8AfzZ8WzUGZ5mV8O/xMzRag2ETR6+TlGIsMHp81agx51cqpPItXPib/nAZYmo55Bl2L6/WOMI3A5YRg==",
-      "cpu": [
-        "arm"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/linux-arm64": {
-      "version": "4.1.4",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/linux-arm64/-/linux-arm64-4.1.4.tgz",
-      "integrity": "sha512-dljEqAOD0oIM6O6DxBW9US/FkvqvQwgJ2lGHOwHDDwu/pX8+V0YsDL1xqHbj1DMX/+nP9rxw7G7gcUvGspSoKg==",
-      "cpu": [
-        "arm64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/linux-ia32": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/linux-ia32/-/linux-ia32-4.1.0.tgz",
-      "integrity": "sha512-0LWyFQnPf+Ij9GQGD034hS6A90URNu9HCtQ5cTqo5MxOEc7Rd8gLXrJvn++UmxhU0J5RyRE9KRYstdCVUjkNOQ==",
-      "cpu": [
-        "ia32"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/linux-x64": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/linux-x64/-/linux-x64-4.1.0.tgz",
-      "integrity": "sha512-Y5BWhGLU/WpQjOArNIgXD3z5mxxdV8c41C+U15nsE5yF8tVcdCGet5zPs5Zy3Ta6bU7haGpIzryutqCGQA/W8A==",
-      "cpu": [
-        "x64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/win32-ia32": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/win32-ia32/-/win32-ia32-4.1.0.tgz",
-      "integrity": "sha512-FV2D7RlaZv/lrtdhaQ4oETwoFUsUjlUiasiZLDxhEUPdNDWcH1OU9K1xTvqz+OXLdsmYelUDuBS/zkMOTtlUAw==",
-      "cpu": [
-        "ia32"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/win32-x64": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/win32-x64/-/win32-x64-4.1.0.tgz",
-      "integrity": "sha512-Drt5u2vzDnIONf4ZEkKtFlbvwj6rI3kxw1Ck9fpudmtgaZIHD4ucsWB2lCZBXRxJgXR+2IMSti+4rtM4C4rXgg==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ]
-    },
-    "node_modules/@ffprobe-installer/darwin-arm64": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/darwin-arm64/-/darwin-arm64-5.0.1.tgz",
-      "integrity": "sha512-vwNCNjokH8hfkbl6m95zICHwkSzhEvDC3GVBcUp5HX8+4wsX10SP3B+bGur7XUzTIZ4cQpgJmEIAx6TUwRepMg==",
-      "cpu": [
-        "arm64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ]
-    },
-    "node_modules/@ffprobe-installer/darwin-x64": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/darwin-x64/-/darwin-x64-5.1.0.tgz",
-      "integrity": "sha512-J+YGscZMpQclFg31O4cfVRGmDpkVsQ2fZujoUdMAAYcP0NtqpC49Hs3SWJpBdsGB4VeqOt5TTm1vSZQzs1NkhA==",
-      "cpu": [
-        "x64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ]
-    },
-    "node_modules/@ffprobe-installer/ffprobe": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/ffprobe/-/ffprobe-2.1.2.tgz",
-      "integrity": "sha512-ZNvwk4f2magF42Zji2Ese16SMj9BS7Fui4kRjg6gTYTxY3gWZNpg85n4MIfQyI9nimHg4x/gT6FVkp/bBDuBwg==",
-      "engines": {
-        "node": ">=14.21.2"
-      },
-      "optionalDependencies": {
-        "@ffprobe-installer/darwin-arm64": "5.0.1",
-        "@ffprobe-installer/darwin-x64": "5.1.0",
-        "@ffprobe-installer/linux-arm": "5.2.0",
-        "@ffprobe-installer/linux-arm64": "5.2.0",
-        "@ffprobe-installer/linux-ia32": "5.2.0",
-        "@ffprobe-installer/linux-x64": "5.2.0",
-        "@ffprobe-installer/win32-ia32": "5.1.0",
-        "@ffprobe-installer/win32-x64": "5.1.0"
-      }
-    },
-    "node_modules/@ffprobe-installer/linux-arm": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/linux-arm/-/linux-arm-5.2.0.tgz",
-      "integrity": "sha512-PF5HqEhCY7WTWHtLDYbA/+rLS+rhslWvyBlAG1Fk8VzVlnRdl93o6hy7DE2kJgxWQbFaR3ZktPQGEzfkrmQHvQ==",
-      "cpu": [
-        "arm"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffprobe-installer/linux-arm64": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/linux-arm64/-/linux-arm64-5.2.0.tgz",
-      "integrity": "sha512-X1VvWtlLs6ScP73biVLuHD5ohKJKsMTa0vafCESOen4mOoNeLAYbxOVxDWAdFz9cpZgRiloFj5QD6nDj8E28yQ==",
-      "cpu": [
-        "arm64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffprobe-installer/linux-ia32": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/linux-ia32/-/linux-ia32-5.2.0.tgz",
-      "integrity": "sha512-TFVK5sasXyXhbIG7LtPRDmtkrkOsInwKcL43iEvEw+D9vCS2rc//mn9/0Q+BR0UoJEiMK4+ApYr/3LLVUBPOCQ==",
-      "cpu": [
-        "ia32"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffprobe-installer/linux-x64": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/linux-x64/-/linux-x64-5.2.0.tgz",
-      "integrity": "sha512-D3UeqTLYPNs7pBWPLUYGehPdRVqU8eACox4OZy3pZUZatxye2YKlvBwEfaLdL1v2Z4FOAlLUhms0kY8m8kqSRA==",
-      "cpu": [
-        "x64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffprobe-installer/win32-ia32": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/win32-ia32/-/win32-ia32-5.1.0.tgz",
-      "integrity": "sha512-5O3vOoNRxmut0/Nu9vSazTdSHasrr+zPT2B3Hm7kjmO3QVFcIfVImS6ReQnZeSy8JPJOqXts5kX5x/3KOX54XQ==",
-      "cpu": [
-        "ia32"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ]
-    },
-    "node_modules/@ffprobe-installer/win32-x64": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/win32-x64/-/win32-x64-5.1.0.tgz",
-      "integrity": "sha512-jMGYeAgkrdn4e2vvYt/qakgHRE3CPju4bn5TmdPfoAm1BlX1mY9cyMd8gf5vSzI8gH8Zq5WQAyAkmekX/8TSTg==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ]
-    },
-    "node_modules/@lezer/common": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.2.1.tgz",
-      "integrity": "sha512-yemX0ZD2xS/73llMZIK6KplkjIjf2EvAHcinDi/TfJ9hS25G0388+ClHt6/3but0oOxinTcQHJLDXh6w1crzFQ=="
-    },
-    "node_modules/@lezer/cpp": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@lezer/cpp/-/cpp-1.1.2.tgz",
-      "integrity": "sha512-macwKtyeUO0EW86r3xWQCzOV9/CF8imJLpJlPv3sDY57cPGeUZ8gXWOWNlJr52TVByMV3PayFQCA5SHEERDmVQ==",
-      "dependencies": {
-        "@lezer/common": "^1.2.0",
-        "@lezer/highlight": "^1.0.0",
-        "@lezer/lr": "^1.0.0"
-      }
-    },
-    "node_modules/@lezer/highlight": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.0.tgz",
-      "integrity": "sha512-WrS5Mw51sGrpqjlh3d4/fOwpEV2Hd3YOkp9DBt4k8XZQcoTHZFB7sx030A6OcahF4J1nDQAa3jXlTVVYH50IFA==",
-      "dependencies": {
-        "@lezer/common": "^1.0.0"
-      }
-    },
-    "node_modules/@lezer/lr": {
-      "version": "1.4.2",
-      "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.2.tgz",
-      "integrity": "sha512-pu0K1jCIdnQ12aWNaAVU5bzi7Bd1w54J3ECgANPmYLtQKP0HBj2cE/5coBD66MT10xbtIuUr7tg0Shbsvk0mDA==",
-      "dependencies": {
-        "@lezer/common": "^1.0.0"
-      }
-    },
-    "node_modules/@motion-canvas/2d": {
-      "version": "3.16.0",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/2d/-/2d-3.16.0.tgz",
-      "integrity": "sha512-8vyCSNE9ZCkGB4Wz8yS48h0xQ79mbmbCkhpxu4ARBrFtSVLqgo/6kz2yifJi4wPK4pCDFw5knABjukOKtMaPMQ==",
-      "dependencies": {
-        "@codemirror/language": "^6.10.1",
-        "@lezer/common": "^1.2.1",
-        "@lezer/highlight": "^1.2.0",
-        "@motion-canvas/core": "^3.16.0",
-        "code-fns": "^0.8.2",
-        "mathjax-full": "^3.2.2",
-        "parse-svg-path": "^0.1.2"
-      }
-    },
-    "node_modules/@motion-canvas/core": {
-      "version": "3.16.0",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/core/-/core-3.16.0.tgz",
-      "integrity": "sha512-egOrQjVOHWf+HMFH+AOLLSV/djf+YGGPxbz0Jbnva3C3VTH2l6MMKTdoYyGRI3w02gJO1pIo7bcePq3erlxulw==",
-      "dependencies": {
-        "@types/chroma-js": "^2.1.4",
-        "chroma-js": "^2.4.2"
-      }
-    },
-    "node_modules/@motion-canvas/ffmpeg": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/ffmpeg/-/ffmpeg-1.1.1.tgz",
-      "integrity": "sha512-w2d7oFfR3hYHXeYtFGoHp6goY+vVL0LoZ2h1b/veTH5KvE7jrLp2Kl/XPHsYJ5ZDRHUT0Nhl05DBLdXYqdSqgg==",
-      "dependencies": {
-        "@ffmpeg-installer/ffmpeg": "^1.1.0",
-        "@ffprobe-installer/ffprobe": "^2.0.0",
-        "fluent-ffmpeg": "^2.1.2"
-      },
-      "peerDependencies": {
-        "@motion-canvas/core": "^3.7.0",
-        "@motion-canvas/vite-plugin": "^3.7.0",
-        "vite": "4.x"
-      }
-    },
-    "node_modules/@motion-canvas/ui": {
-      "version": "3.16.0",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/ui/-/ui-3.16.0.tgz",
-      "integrity": "sha512-PJZnbkiJKED4nNDnN649zojfPMVRTvFOqxUExi6TdrckiLFsTJFy+dYbyMML223ekDrkmHuQU35tcs3svwfYrw==",
-      "dev": true,
-      "dependencies": {
-        "@motion-canvas/core": "^3.16.0",
-        "@preact/signals": "^1.2.1",
-        "preact": "^10.19.2"
-      }
-    },
-    "node_modules/@motion-canvas/vite-plugin": {
-      "version": "3.15.1",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/vite-plugin/-/vite-plugin-3.15.1.tgz",
-      "integrity": "sha512-yeRMJQxTcYVZGVMnNXQPm0SySQzJXnaRrggGJ2bnDHMsqxCRJt/RfIioK0LMvBaUB+UWlPsJUTMltHuq+J64JA==",
-      "dependencies": {
-        "fast-glob": "^3.3.1",
-        "follow-redirects": "^1.15.2",
-        "mime-types": "^2.1.35",
-        "source-map": "^0.6.1"
-      },
-      "peerDependencies": {
-        "vite": "4.x || 5.x"
-      }
-    },
-    "node_modules/@nodelib/fs.scandir": {
-      "version": "2.1.5",
-      "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
-      "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
-      "dependencies": {
-        "@nodelib/fs.stat": "2.0.5",
-        "run-parallel": "^1.1.9"
-      },
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/@nodelib/fs.stat": {
-      "version": "2.0.5",
-      "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
-      "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/@nodelib/fs.walk": {
-      "version": "1.2.8",
-      "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
-      "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
-      "dependencies": {
-        "@nodelib/fs.scandir": "2.1.5",
-        "fastq": "^1.6.0"
-      },
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/@preact/signals": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/@preact/signals/-/signals-1.3.0.tgz",
-      "integrity": "sha512-EOMeg42SlLS72dhoq6Vjq08havnLseWmPQ8A0YsgIAqMgWgx7V1a39+Pxo6i7SY5NwJtH4849JogFq3M67AzWg==",
-      "dev": true,
-      "dependencies": {
-        "@preact/signals-core": "^1.7.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/preact"
-      },
-      "peerDependencies": {
-        "preact": "10.x"
-      }
-    },
-    "node_modules/@preact/signals-core": {
-      "version": "1.8.0",
-      "resolved": "https://registry.npmjs.org/@preact/signals-core/-/signals-core-1.8.0.tgz",
-      "integrity": "sha512-OBvUsRZqNmjzCZXWLxkZfhcgT+Fk8DDcT/8vD6a1xhDemodyy87UJRJfASMuSD8FaAIeGgGm85ydXhm7lr4fyA==",
-      "dev": true,
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/preact"
-      }
-    },
-    "node_modules/@types/chroma-js": {
-      "version": "2.4.0",
-      "resolved": "https://registry.npmjs.org/@types/chroma-js/-/chroma-js-2.4.0.tgz",
-      "integrity": "sha512-JklMxityrwjBTjGY2anH8JaTx3yjRU3/sEHSblLH1ba5lqcSh1LnImXJZO5peJfXyqKYWjHTGy4s5Wz++hARrw=="
-    },
-    "node_modules/@types/hast": {
-      "version": "2.3.4",
-      "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.4.tgz",
-      "integrity": "sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==",
-      "dependencies": {
-        "@types/unist": "*"
-      }
-    },
-    "node_modules/@types/unist": {
-      "version": "2.0.6",
-      "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz",
-      "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ=="
-    },
-    "node_modules/@wooorm/starry-night": {
-      "version": "1.7.0",
-      "resolved": "https://registry.npmjs.org/@wooorm/starry-night/-/starry-night-1.7.0.tgz",
-      "integrity": "sha512-ktO0nkddrovIoNW2jAUT+Cdd9n1bWjy1Ir4CdcmgTaT6E94HLlQfu7Yv62falclBEwvsuVp3bSBw23wtta1fNw==",
-      "dependencies": {
-        "@types/hast": "^2.0.0",
-        "import-meta-resolve": "^2.0.0",
-        "vscode-oniguruma": "^1.0.0",
-        "vscode-textmate": "^9.0.0"
-      },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/wooorm"
-      }
-    },
-    "node_modules/async": {
-      "version": "0.2.10",
-      "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz",
-      "integrity": "sha512-eAkdoKxU6/LkKDBzLpT+t6Ff5EtfSF4wx1WfJiPEEV7WNLnDaRXk0oVysiEPm262roaachGexwUv94WhSgN5TQ=="
-    },
-    "node_modules/braces": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
-      "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
-      "dependencies": {
-        "fill-range": "^7.1.1"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/chroma-js": {
-      "version": "2.4.2",
-      "resolved": "https://registry.npmjs.org/chroma-js/-/chroma-js-2.4.2.tgz",
-      "integrity": "sha512-U9eDw6+wt7V8z5NncY2jJfZa+hUH8XEj8FQHgFJTrUFnJfXYf4Ml4adI2vXZOjqRDpFWtYVWypDfZwnJ+HIR4A=="
-    },
-    "node_modules/code-fns": {
-      "version": "0.8.2",
-      "resolved": "https://registry.npmjs.org/code-fns/-/code-fns-0.8.2.tgz",
-      "integrity": "sha512-3VVeq3cnWxWiWKFLsVo+XWsOXBSW2gAx2uv0ViETLNmNuygEPHlCeDAv/Zy7xXqPgXtgLZyvIJZmx+ojTgOIGA==",
-      "dependencies": {
-        "@wooorm/starry-night": "^1.2.0"
-      }
-    },
-    "node_modules/commander": {
-      "version": "9.2.0",
-      "resolved": "https://registry.npmjs.org/commander/-/commander-9.2.0.tgz",
-      "integrity": "sha512-e2i4wANQiSXgnrBlIatyHtP1odfUp0BbV5Y5nEGbxtIrStkEOAAzCUirvLBNXHLr7kwLvJl6V+4V3XV9x7Wd9w==",
-      "engines": {
-        "node": "^12.20.0 || >=14"
-      }
-    },
-    "node_modules/esbuild": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz",
-      "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==",
-      "hasInstallScript": true,
-      "bin": {
-        "esbuild": "bin/esbuild"
-      },
-      "engines": {
-        "node": ">=12"
-      },
-      "optionalDependencies": {
-        "@esbuild/android-arm": "0.18.20",
-        "@esbuild/android-arm64": "0.18.20",
-        "@esbuild/android-x64": "0.18.20",
-        "@esbuild/darwin-arm64": "0.18.20",
-        "@esbuild/darwin-x64": "0.18.20",
-        "@esbuild/freebsd-arm64": "0.18.20",
-        "@esbuild/freebsd-x64": "0.18.20",
-        "@esbuild/linux-arm": "0.18.20",
-        "@esbuild/linux-arm64": "0.18.20",
-        "@esbuild/linux-ia32": "0.18.20",
-        "@esbuild/linux-loong64": "0.18.20",
-        "@esbuild/linux-mips64el": "0.18.20",
-        "@esbuild/linux-ppc64": "0.18.20",
-        "@esbuild/linux-riscv64": "0.18.20",
-        "@esbuild/linux-s390x": "0.18.20",
-        "@esbuild/linux-x64": "0.18.20",
-        "@esbuild/netbsd-x64": "0.18.20",
-        "@esbuild/openbsd-x64": "0.18.20",
-        "@esbuild/sunos-x64": "0.18.20",
-        "@esbuild/win32-arm64": "0.18.20",
-        "@esbuild/win32-ia32": "0.18.20",
-        "@esbuild/win32-x64": "0.18.20"
-      }
-    },
-    "node_modules/esm": {
-      "version": "3.2.25",
-      "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz",
-      "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==",
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/fast-glob": {
-      "version": "3.3.2",
-      "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
-      "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
-      "dependencies": {
-        "@nodelib/fs.stat": "^2.0.2",
-        "@nodelib/fs.walk": "^1.2.3",
-        "glob-parent": "^5.1.2",
-        "merge2": "^1.3.0",
-        "micromatch": "^4.0.4"
-      },
-      "engines": {
-        "node": ">=8.6.0"
-      }
-    },
-    "node_modules/fastq": {
-      "version": "1.17.1",
-      "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz",
-      "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==",
-      "dependencies": {
-        "reusify": "^1.0.4"
-      }
-    },
-    "node_modules/fill-range": {
-      "version": "7.1.1",
-      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
-      "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
-      "dependencies": {
-        "to-regex-range": "^5.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/fluent-ffmpeg": {
-      "version": "2.1.3",
-      "resolved": "https://registry.npmjs.org/fluent-ffmpeg/-/fluent-ffmpeg-2.1.3.tgz",
-      "integrity": "sha512-Be3narBNt2s6bsaqP6Jzq91heDgOEaDCJAXcE3qcma/EJBSy5FB4cvO31XBInuAuKBx8Kptf8dkhjK0IOru39Q==",
-      "dependencies": {
-        "async": "^0.2.9",
-        "which": "^1.1.1"
-      },
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/follow-redirects": {
-      "version": "1.15.6",
-      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
-      "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
-      "funding": [
-        {
-          "type": "individual",
-          "url": "https://github.com/sponsors/RubenVerborgh"
-        }
-      ],
-      "engines": {
-        "node": ">=4.0"
-      },
-      "peerDependenciesMeta": {
-        "debug": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/fsevents": {
-      "version": "2.3.3",
-      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
-      "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
-      }
-    },
-    "node_modules/glob-parent": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
-      "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
-      "dependencies": {
-        "is-glob": "^4.0.1"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "node_modules/import-meta-resolve": {
-      "version": "2.2.2",
-      "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-2.2.2.tgz",
-      "integrity": "sha512-f8KcQ1D80V7RnqVm+/lirO9zkOxjGxhaTC1IPrBGd3MEfNgmNG67tSUO9gTi2F3Blr2Az6g1vocaxzkVnWl9MA==",
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/wooorm"
-      }
-    },
-    "node_modules/is-extglob": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
-      "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/is-glob": {
-      "version": "4.0.3",
-      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
-      "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
-      "dependencies": {
-        "is-extglob": "^2.1.1"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/is-number": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
-      "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
-      "engines": {
-        "node": ">=0.12.0"
-      }
-    },
-    "node_modules/isexe": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
-      "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
-    },
-    "node_modules/mathjax-full": {
-      "version": "3.2.2",
-      "resolved": "https://registry.npmjs.org/mathjax-full/-/mathjax-full-3.2.2.tgz",
-      "integrity": "sha512-+LfG9Fik+OuI8SLwsiR02IVdjcnRCy5MufYLi0C3TdMT56L/pjB0alMVGgoWJF8pN9Rc7FESycZB9BMNWIid5w==",
-      "dependencies": {
-        "esm": "^3.2.25",
-        "mhchemparser": "^4.1.0",
-        "mj-context-menu": "^0.6.1",
-        "speech-rule-engine": "^4.0.6"
-      }
-    },
-    "node_modules/merge2": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
-      "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/mhchemparser": {
-      "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/mhchemparser/-/mhchemparser-4.1.1.tgz",
-      "integrity": "sha512-R75CUN6O6e1t8bgailrF1qPq+HhVeFTM3XQ0uzI+mXTybmphy3b6h4NbLOYhemViQ3lUs+6CKRkC3Ws1TlYREA=="
-    },
-    "node_modules/micromatch": {
-      "version": "4.0.8",
-      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
-      "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
-      "dependencies": {
-        "braces": "^3.0.3",
-        "picomatch": "^2.3.1"
-      },
-      "engines": {
-        "node": ">=8.6"
-      }
-    },
-    "node_modules/mime-db": {
-      "version": "1.52.0",
-      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
-      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/mime-types": {
-      "version": "2.1.35",
-      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
-      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
-      "dependencies": {
-        "mime-db": "1.52.0"
-      },
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/mj-context-menu": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/mj-context-menu/-/mj-context-menu-0.6.1.tgz",
-      "integrity": "sha512-7NO5s6n10TIV96d4g2uDpG7ZDpIhMh0QNfGdJw/W47JswFcosz457wqz/b5sAKvl12sxINGFCn80NZHKwxQEXA=="
-    },
-    "node_modules/nanoid": {
-      "version": "3.3.6",
-      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
-      "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/ai"
-        }
-      ],
-      "bin": {
-        "nanoid": "bin/nanoid.cjs"
-      },
-      "engines": {
-        "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
-      }
-    },
-    "node_modules/parse-svg-path": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/parse-svg-path/-/parse-svg-path-0.1.2.tgz",
-      "integrity": "sha512-JyPSBnkTJ0AI8GGJLfMXvKq42cj5c006fnLz6fXy6zfoVjJizi8BNTpu8on8ziI1cKy9d9DGNuY17Ce7wuejpQ=="
-    },
-    "node_modules/picocolors": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
-      "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
-    },
-    "node_modules/picomatch": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
-      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
-      "engines": {
-        "node": ">=8.6"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/jonschlinkert"
-      }
-    },
-    "node_modules/postcss": {
-      "version": "8.4.31",
-      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
-      "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
-      "funding": [
-        {
-          "type": "opencollective",
-          "url": "https://opencollective.com/postcss/"
-        },
-        {
-          "type": "tidelift",
-          "url": "https://tidelift.com/funding/github/npm/postcss"
-        },
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/ai"
-        }
-      ],
-      "dependencies": {
-        "nanoid": "^3.3.6",
-        "picocolors": "^1.0.0",
-        "source-map-js": "^1.0.2"
-      },
-      "engines": {
-        "node": "^10 || ^12 || >=14"
-      }
-    },
-    "node_modules/preact": {
-      "version": "10.23.2",
-      "resolved": "https://registry.npmjs.org/preact/-/preact-10.23.2.tgz",
-      "integrity": "sha512-kKYfePf9rzKnxOAKDpsWhg/ysrHPqT+yQ7UW4JjdnqjFIeNUnNcEJvhuA8fDenxAGWzUqtd51DfVg7xp/8T9NA==",
-      "dev": true,
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/preact"
-      }
-    },
-    "node_modules/queue-microtask": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
-      "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/feross"
-        },
-        {
-          "type": "patreon",
-          "url": "https://www.patreon.com/feross"
-        },
-        {
-          "type": "consulting",
-          "url": "https://feross.org/support"
-        }
-      ]
-    },
-    "node_modules/reusify": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
-      "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
-      "engines": {
-        "iojs": ">=1.0.0",
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/rollup": {
-      "version": "3.29.4",
-      "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz",
-      "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==",
-      "bin": {
-        "rollup": "dist/bin/rollup"
-      },
-      "engines": {
-        "node": ">=14.18.0",
-        "npm": ">=8.0.0"
-      },
-      "optionalDependencies": {
-        "fsevents": "~2.3.2"
-      }
-    },
-    "node_modules/run-parallel": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
-      "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/feross"
-        },
-        {
-          "type": "patreon",
-          "url": "https://www.patreon.com/feross"
-        },
-        {
-          "type": "consulting",
-          "url": "https://feross.org/support"
-        }
-      ],
-      "dependencies": {
-        "queue-microtask": "^1.2.2"
-      }
-    },
-    "node_modules/source-map": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
-      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/source-map-js": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
-      "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/speech-rule-engine": {
-      "version": "4.0.7",
-      "resolved": "https://registry.npmjs.org/speech-rule-engine/-/speech-rule-engine-4.0.7.tgz",
-      "integrity": "sha512-sJrL3/wHzNwJRLBdf6CjJWIlxC04iYKkyXvYSVsWVOiC2DSkHmxsqOhEeMsBA9XK+CHuNcsdkbFDnoUfAsmp9g==",
-      "dependencies": {
-        "commander": "9.2.0",
-        "wicked-good-xpath": "1.3.0",
-        "xmldom-sre": "0.1.31"
-      },
-      "bin": {
-        "sre": "bin/sre"
-      }
-    },
-    "node_modules/style-mod": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.2.tgz",
-      "integrity": "sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw=="
-    },
-    "node_modules/to-regex-range": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
-      "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
-      "dependencies": {
-        "is-number": "^7.0.0"
-      },
-      "engines": {
-        "node": ">=8.0"
-      }
-    },
-    "node_modules/typescript": {
-      "version": "5.5.4",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz",
-      "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==",
-      "dev": true,
-      "bin": {
-        "tsc": "bin/tsc",
-        "tsserver": "bin/tsserver"
-      },
-      "engines": {
-        "node": ">=14.17"
-      }
-    },
-    "node_modules/vite": {
-      "version": "4.5.3",
-      "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.3.tgz",
-      "integrity": "sha512-kQL23kMeX92v3ph7IauVkXkikdDRsYMGTVl5KY2E9OY4ONLvkHf04MDTbnfo6NKxZiDLWzVpP5oTa8hQD8U3dg==",
-      "dependencies": {
-        "esbuild": "^0.18.10",
-        "postcss": "^8.4.27",
-        "rollup": "^3.27.1"
-      },
-      "bin": {
-        "vite": "bin/vite.js"
-      },
-      "engines": {
-        "node": "^14.18.0 || >=16.0.0"
-      },
-      "funding": {
-        "url": "https://github.com/vitejs/vite?sponsor=1"
-      },
-      "optionalDependencies": {
-        "fsevents": "~2.3.2"
-      },
-      "peerDependencies": {
-        "@types/node": ">= 14",
-        "less": "*",
-        "lightningcss": "^1.21.0",
-        "sass": "*",
-        "stylus": "*",
-        "sugarss": "*",
-        "terser": "^5.4.0"
-      },
-      "peerDependenciesMeta": {
-        "@types/node": {
-          "optional": true
-        },
-        "less": {
-          "optional": true
-        },
-        "lightningcss": {
-          "optional": true
-        },
-        "sass": {
-          "optional": true
-        },
-        "stylus": {
-          "optional": true
-        },
-        "sugarss": {
-          "optional": true
-        },
-        "terser": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/vscode-oniguruma": {
-      "version": "1.7.0",
-      "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz",
-      "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA=="
-    },
-    "node_modules/vscode-textmate": {
-      "version": "9.0.0",
-      "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-9.0.0.tgz",
-      "integrity": "sha512-Cl65diFGxz7gpwbav10HqiY/eVYTO1sjQpmRmV991Bj7wAoOAjGQ97PpQcXorDE2Uc4hnGWLY17xme+5t6MlSg=="
-    },
-    "node_modules/w3c-keyname": {
-      "version": "2.2.8",
-      "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz",
-      "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ=="
-    },
-    "node_modules/which": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
-      "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
-      "dependencies": {
-        "isexe": "^2.0.0"
-      },
-      "bin": {
-        "which": "bin/which"
-      }
-    },
-    "node_modules/wicked-good-xpath": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/wicked-good-xpath/-/wicked-good-xpath-1.3.0.tgz",
-      "integrity": "sha512-Gd9+TUn5nXdwj/hFsPVx5cuHHiF5Bwuc30jZ4+ronF1qHK5O7HD0sgmXWSEgwKquT3ClLoKPVbO6qGwVwLzvAw=="
-    },
-    "node_modules/xmldom-sre": {
-      "version": "0.1.31",
-      "resolved": "https://registry.npmjs.org/xmldom-sre/-/xmldom-sre-0.1.31.tgz",
-      "integrity": "sha512-f9s+fUkX04BxQf+7mMWAp5zk61pciie+fFLC9hX9UVvCeJQfNHRHXpeo5MPcR0EUf57PYLdt+ZO4f3Ipk2oZUw==",
-      "engines": {
-        "node": ">=0.1"
-      }
-    }
-  }
-}
diff --git a/animation/memory_and_smart_pointers/package.json b/animation/memory_and_smart_pointers/package.json
deleted file mode 100644
index 9955e40..0000000
--- a/animation/memory_and_smart_pointers/package.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
-  "name": "value_semantics",
-  "private": true,
-  "version": "0.0.0",
-  "scripts": {
-    "start": "vite",
-    "serve": "vite",
-    "build": "tsc && vite build"
-  },
-  "dependencies": {
-    "@lezer/cpp": "^1.1.2",
-    "@motion-canvas/2d": "^3.16.0",
-    "@motion-canvas/core": "^3.16.0",
-    "@motion-canvas/ffmpeg": "^1.1.1"
-  },
-  "devDependencies": {
-    "@motion-canvas/ui": "^3.16.0",
-    "@motion-canvas/vite-plugin": "^3.15.1",
-    "typescript": "^5.2.2",
-    "vite": "^4.0.0"
-  }
-}
diff --git a/animation/memory_and_smart_pointers/src/global.css b/animation/memory_and_smart_pointers/src/global.css
deleted file mode 100644
index 201f5ff..0000000
--- a/animation/memory_and_smart_pointers/src/global.css
+++ /dev/null
@@ -1 +0,0 @@
-@import url('https://fonts.googleapis.com/css2?family=Fira+Mono:wght@400;500;700&display=swap');
diff --git a/animation/memory_and_smart_pointers/src/motion-canvas.d.ts b/animation/memory_and_smart_pointers/src/motion-canvas.d.ts
deleted file mode 100644
index 067c6a4..0000000
--- a/animation/memory_and_smart_pointers/src/motion-canvas.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-/// <reference types="@motion-canvas/core/project" />
diff --git a/animation/memory_and_smart_pointers/src/project.meta b/animation/memory_and_smart_pointers/src/project.meta
deleted file mode 100644
index 68d1eac..0000000
--- a/animation/memory_and_smart_pointers/src/project.meta
+++ /dev/null
@@ -1,31 +0,0 @@
-{
-  "version": 0,
-  "shared": {
-    "background": "rgb(10,20,30)",
-    "range": [
-      0,
-      null
-    ],
-    "size": {
-      "x": 1920,
-      "y": 1080
-    },
-    "audioOffset": 0
-  },
-  "preview": {
-    "fps": 30,
-    "resolutionScale": 1
-  },
-  "rendering": {
-    "fps": 30,
-    "resolutionScale": 2,
-    "colorSpace": "srgb",
-    "exporter": {
-      "name": "@motion-canvas/ffmpeg",
-      "options": {
-        "fastStart": false,
-        "includeAudio": true
-      }
-    }
-  }
-}
\ No newline at end of file
diff --git a/animation/memory_and_smart_pointers/src/project.ts b/animation/memory_and_smart_pointers/src/project.ts
deleted file mode 100644
index 3a4de14..0000000
--- a/animation/memory_and_smart_pointers/src/project.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-import { makeProject } from '@motion-canvas/core';
-import { Code, LezerHighlighter } from '@motion-canvas/2d';
-import { parser } from '@lezer/cpp';
-import { tags } from '@lezer/highlight';
-import { HighlightStyle } from '@codemirror/language';
-
-const MyStyle = HighlightStyle.define([
-  { tag: tags.keyword, color: '#569CD6' }, // VSCode Keyword color
-  { tag: tags.controlKeyword, color: '#C586C0' }, // VSCode Control Keyword color
-  { tag: tags.operatorKeyword, color: '#C586C0' }, // VSCode Control Keyword color
-  { tag: tags.comment, color: 'gray' }, // VSCode Comment color
-  { tag: tags.className, color: '#4EC9B0' }, // VSCode Class Name color
-  { tag: tags.constant(tags.variableName), color: '#B5CEA8' }, // VSCode Constant color
-  { tag: tags.function(tags.variableName), color: '#DCDCAA' }, // VSCode Function color
-  { tag: tags.function(tags.propertyName), color: '#DCDCAA' }, // VSCode Function color
-  { tag: tags.propertyName, color: '#DCDCAA' }, // VSCode Function color
-  { tag: tags.number, color: '#B5CEA8' }, // VSCode Number color
-  { tag: tags.string, color: '#CE9178' }, // VSCode String color
-  { tag: tags.typeName, color: '#4EC9B0' }, // VSCode Type Name color
-  { tag: tags.squareBracket, color: '#C586C0' }, // VSCode Square Bracket color
-  { tag: tags.bracket, color: '#C586C0' }, // VSCode Bracket color
-  { tag: tags.brace, color: '#DDDD22' }, // VSCode Brace color
-  { tag: tags.processingInstruction, color: '#C586C0' }, // VSCode Brace color
-  { tag: tags.arithmeticOperator, color: '#D16969' }, // VSCode Arithmetic Operator color
-]);
-
-Code.defaultHighlighter = new LezerHighlighter(parser, MyStyle);
-
-import './global.css';
-
-import memory from './scenes/memory?scene';
-import stack from './scenes/stack?scene';
-import stack_persistent from './scenes/stack_persistent?scene';
-import heap from './scenes/heap?scene';
-import code from './scenes/code?scene';
-import memory_show from './scenes/memory_show?scene';
-
-export default makeProject({
-  scenes: [
-    code],
-});
diff --git a/animation/memory_and_smart_pointers/src/scenes/code.meta b/animation/memory_and_smart_pointers/src/scenes/code.meta
deleted file mode 100644
index f0654cf..0000000
--- a/animation/memory_and_smart_pointers/src/scenes/code.meta
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-  "version": 0,
-  "timeEvents": [],
-  "seed": 2771218248
-}
\ No newline at end of file
diff --git a/animation/memory_and_smart_pointers/src/scenes/code.tsx b/animation/memory_and_smart_pointers/src/scenes/code.tsx
deleted file mode 100644
index c4e696a..0000000
--- a/animation/memory_and_smart_pointers/src/scenes/code.tsx
+++ /dev/null
@@ -1,310 +0,0 @@
-import { createRef } from '@motion-canvas/core/lib/utils';
-import { makeScene2D, Code, lines } from '@motion-canvas/2d';
-import { all, waitFor, waitUntil } from '@motion-canvas/core/lib/flow';
-import { DEFAULT } from '@motion-canvas/core/lib/signals';
-import { BBox, Vector2 } from '@motion-canvas/core/lib/types';
-
-export default makeScene2D(function* (view) {
-  const codeRef = createRef<Code>();
-  const code2Ref = createRef<Code>();
-
-  yield view.add(<Code
-    ref={codeRef}
-    fontSize={25}
-    fontFamily={'Fira Mono'}
-    fontWeight={500}
-    offsetX={-1}
-    x={-600}
-  />);
-
-  yield view.add(<Code
-    ref={code2Ref}
-    fontSize={25}
-    fontFamily={'Fira Mono'}
-    fontWeight={500}
-    offsetX={-1}
-    x={100}
-  />);
-
-
-  const duration = 1.0
-
-  const code_good_names = `\
-// 😱 Manual allocation is bad, especially in functions!
-namespace {
-
-struct Pool {
-  static int* GetPtr() { return &data_; }
-  inline static int data_{};
-};
-
-int* AllocateVariable() {
-  return new int;
-}
-
-int* AllocateArray(int size) {
-  return new int[size];
-}
-
-int* BorrowDataFromPool() {
-  return Pool::GetPtr();
-}
-
-}  // namespace
-
-int main() {
-  auto* ptr_1 = AllocateVariable();
-  auto* ptr_2 = AllocateArray(20);
-  auto* ptr_3 = BorrowDataFromPool();
-  delete ptr_1;
-  delete[] ptr_2;
-  return 0;
-}`
-
-  const code_flipped_names_1 = `\
-// 😱 Manual allocation is bad, especially in functions!
-namespace {
-
-struct Pool {
-  static int* GetPtr() { return &data_; }
-  inline static int data_{};
-};
-
-// 😱 Implementation changed, but not the name!
-int* AllocateVariable() {
-  return Pool::GetPtr();
-}
-
-int* AllocateArray(int size) {
-  return new int[size];
-}
-
-int* BorrowDataFromPool() {
-  return Pool::GetPtr();
-}
-
-}  // namespace
-
-int main() {
-  auto* ptr_1 = AllocateVariable();
-  auto* ptr_2 = AllocateArray(20);
-  auto* ptr_3 = BorrowDataFromPool();
-  delete[] ptr_2;
-  return 0;
-}`
-
-  const code_flipped_names_2 = `\
-// 😱 Manual allocation is bad, especially in functions!
-namespace {
-
-struct Pool {
-  static int* GetPtr() { return &data_; }
-  inline static int data_{};
-};
-
-// 😱 Implementation changed, but not the name!
-int* AllocateVariable() {
-  return Pool::GetPtr();
-}
-
-int* AllocateArray(int size) {
-  return new int[size];
-}
-
-// 😱 Implementation changed, but not the name!
-int* BorrowDataFromPool() {
-  return new int;
-}
-
-}  // namespace
-
-int main() {
-  auto* ptr_1 = AllocateVariable();
-  auto* ptr_2 = AllocateArray(20);
-  auto* ptr_3 = BorrowDataFromPool();
-  delete ptr_3;
-  delete[] ptr_2;
-  return 0;
-}`
-
-  const code_bad_names = `\
-namespace {
-
-struct Pool {
-  static int* GetPtr() { return &data_; }
-  inline static int data_{};
-};
-
-int* Foo() {
-  return Pool::GetPtr();
-}
-
-int* Bar(int size) {
-  return new int[size];
-}
-
-int* Buzz() {
-  return new int;
-}
-
-}  // namespace
-
-int main() {
-  auto* ptr_1 = Foo();
-  auto* ptr_2 = Bar(20);
-  auto* ptr_3 = Buzz();
-  delete ptr_3;
-  delete[] ptr_2;
-  return 0;
-}`
-
-  const code_with_include = `\
-#include "lib.hpp"
-
-int main() {
-  auto* ptr_1 = Foo();
-  auto* ptr_2 = Bar(20);
-  auto* ptr_3 = Buzz();
-  // 😱 What should we do with these pointers?
-  return 0;
-}`
-
-  const code_declarations = `\
-int* Foo();
-int* Bar(int number);
-int* Buzz();`
-
-
-  yield* codeRef().code(code_good_names, 0).wait(duration);
-  yield* waitFor(duration);
-
-  yield* codeRef().code(code_flipped_names_1, duration);
-  yield* codeRef().code(code_flipped_names_2, duration).wait(duration);
-  yield* waitFor(duration);
-
-  yield* codeRef().code(code_bad_names, duration).wait(duration);
-  yield* waitFor(duration);
-
-  yield* all(
-    code2Ref().code(code_with_include, duration).wait(duration),
-    codeRef().code(code_declarations, duration).wait(duration)
-  );
-  yield* waitFor(duration);
-
-  const code_object_empty = `\
-class Object {
- private:
-  int* data_{};
-};`
-
-  yield* code2Ref().code('', 0);
-  yield* codeRef().code(code_object_empty, 0);
-  yield* codeRef().fontSize(35, 0);
-  yield* codeRef().x(-200, 0);
-  yield* waitFor(duration);
-
-  const code_object_construct = `\
-// 😱 Missing crucial special functions.
-class Object {
- public:
-  explicit Object(int number) : data_{new int{number}} {}
-
- private:
-  int* data_{};
-};`
-
-  yield* all(
-    codeRef().code(code_object_construct, duration).wait(duration),
-    codeRef().x(-450, duration)
-  );
-  yield* waitFor(duration);
-
-  const code_object_destroy = `\
-// 😱 Missing crucial special functions.
-class Object {
- public:
-  explicit Object(int number) : data_{new int{number}} {}
-
-  ~Object() { delete data_; }
-
- private:
-  int* data_{};
-};`
-
-  yield* all(
-    codeRef().code(code_object_destroy, duration).wait(duration),
-    codeRef().x(-450, duration)
-  );
-  yield* waitFor(duration);
-
-  const code_object_copy_move_complete = `\
-class Object {
- public:
-  explicit Object(int number) : data_{new int{number}} {}
-
-  ~Object() { delete data_; }
-
-  Object(const Object& other)
-      : data_{other.data_ ? new int{*other.data_} : nullptr} {}
-
-  Object(Object&& other) : data_{other.data_} { other.data_ = nullptr; }
-
-  Object& operator=(const Object& other) {
-    if (other.data_) {
-      data_ = new int{*other.data_};
-    }
-    return *this;
-  }
-
-  Object& operator=(Object&& other) {
-    data_ = other.data_;
-    other.data_ = nullptr;
-    return *this;
-  }
-
- private:
-  int* data_{};
-};`
-
-  yield* all(
-    codeRef().code(code_object_copy_move_complete, duration).wait(duration),
-    codeRef().x(-600, duration),
-    codeRef().fontSize(30, duration)
-  );
-  yield* waitFor(duration);
-
-
-  const unique_ptr = `\
-// Simplified.
-template<typename T>
-class unique_ptr {
- public:
-  explicit unique_ptr(T* ptr) : ptr_{ptr} {}
-
-  ~unique_ptr() { delete ptr_; }
-
-  unique_ptr(const unique_ptr& other) = delete;
-  unique_ptr& operator=(const unique_ptr& other) = delete;
-
-  unique_ptr(unique_ptr&& other) : ptr_{other.ptr_} { other.ptr_ = nullptr; }
-  unique_ptr& operator=(unique_ptr&& other) {
-    ptr_ = other.ptr_;
-    other.ptr_ = nullptr;
-    return *this;
-  }
-
-  // Missing getters and some other functions like reset.
-
- private:
-  T* ptr_{};
-};
-`
-
-  yield* all(
-    codeRef().code(unique_ptr, 0).wait(duration),
-    codeRef().x(-600, duration),
-    codeRef().fontSize(30, duration)
-  );
-  yield* waitFor(duration);
-
-});
diff --git a/animation/memory_and_smart_pointers/src/scenes/example.meta b/animation/memory_and_smart_pointers/src/scenes/example.meta
deleted file mode 100644
index 2d62bec..0000000
--- a/animation/memory_and_smart_pointers/src/scenes/example.meta
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-  "version": 0,
-  "timeEvents": [],
-  "seed": 1501821170
-}
\ No newline at end of file
diff --git a/animation/memory_and_smart_pointers/src/scenes/example.tsx b/animation/memory_and_smart_pointers/src/scenes/example.tsx
deleted file mode 100644
index 5ec127c..0000000
--- a/animation/memory_and_smart_pointers/src/scenes/example.tsx
+++ /dev/null
@@ -1,400 +0,0 @@
-import {makeScene2D} from '@motion-canvas/2d/lib/scenes';
-import {createRef} from '@motion-canvas/core/lib/utils';
-import {
-  CodeBlock,
-  edit,
-  insert,
-  lines,
-  word,
-  remove,
-  CodeModification,
-} from '@motion-canvas/2d/lib/components/CodeBlock';
-import {all, waitFor, waitUntil} from '@motion-canvas/core/lib/flow';
-import { DEFAULT } from '@motion-canvas/core/lib/signals';
-import { BBox, Vector2 } from '@motion-canvas/core/lib/types';
-
-export default makeScene2D(function* (view) {
-  const codeRef = createRef<CodeBlock>();
-
-  yield view.add(<CodeBlock
-    ref={codeRef}
-    language="cpp"
-    fontSize={50}
-  />);
-
-
-  const duration = 1.5
-
-  const store = (...args: [TemplateStringsArray, ...any]) => args;
-
-  function to_string([strings, ...values]: [TemplateStringsArray, ...any]): string {
-    return strings.reduce((acc, str, i) => {
-      const value = values[i] ?? '';
-      return acc + str + value;
-    }, ' ');
-  }
-
-  function append(
-    template_1: TemplateStringsArray, args_1: string[],
-    template_2: TemplateStringsArray, args_2: string[]) : [TemplateStringsArray, ...string[]] {
-      let new_template = Array.from<string>(template_1);
-      let new_args: Array<string> = args_1;
-      new_template[template_1.length - 1] += template_2[0]
-      new_template = new_template.concat(template_2.slice(1))
-      new_args = new_args.concat(args_2)
-      return [new_template as unknown as TemplateStringsArray, ...new_args];
-  }
-
-  const isCodeModification = (code: any): code is CodeModification => (code as CodeModification).from !== undefined;
-
-  function simplify(
-    args_in: [TemplateStringsArray, ...any]) : [TemplateStringsArray, ...string[]] {
-      const template = args_in[0]
-      const args = args_in.slice(1)
-      if (args.every((arg) => (typeof(arg) == "string") || isCodeModification(arg))) {
-          return args_in
-      }
-      let new_template: Array<any> = [];
-      let new_args: Array<any> = [];
-      let concatenate = false;
-      for (let i = 0; i <= args.length; i++) {
-          if (concatenate) {
-              concatenate = false;
-              new_template[new_template.length - 1] += template[i];
-          } else {
-              new_template.push(template[i]);
-          }
-          if (i == args.length) { break; }
-          if (typeof(args[i]) == "string" || isCodeModification(args[i])) {
-              new_args.push(args[i])
-              continue;
-          }
-          let simplified_arg = simplify(args[i]);
-          let simplified_template = simplified_arg[0]
-          let simplified_args = simplified_arg.slice(1)
-          const appended = append(
-              new_template as unknown as TemplateStringsArray,
-              new_args,
-              simplified_template,
-              simplified_args as string[]);
-          new_template = Array.from<string>(appended[0])
-          new_args = appended.slice(1)
-          concatenate = true;
-      }
-      return [new_template as unknown as TemplateStringsArray, ...new_args]
-  }
-
-
-  const code = (operator:any = ``, main:any = ``, operator_move:any=``) => store`
-  #include <cstddef>
-  #include <algorithm>
-
-  struct HugeObject {
-    HugeObject() = default;
-
-    explicit HugeObject(std::size_t data_length)
-        : length{data_length}, ptr{AllocateMemory(length)} {}
-    ${operator}${operator_move}
-    ~HugeObject() { FreeMemory(ptr); }
-
-    std::size_t length{};
-    std::byte *ptr{};
-  };
-  ${main}
-  `
-
-  const copy = `ptr = AllocateMemory(length);
-      std::copy(object.ptr, object.ptr + length, ptr);`
-  const steal = `ptr = object.ptr;
-      object.ptr = nullptr;`
-
-  const operator_copy = (
-      const_word:any = `const `,
-      copy_or_steal:any = copy,
-      ) => store`
-    HugeObject &operator=(${const_word}HugeObject& object) {
-      if (this == &object) { return *this; }
-      FreeMemory(ptr);
-      length = object.length;
-      ${copy_or_steal}
-      return *this;
-    }
-    `
-
-  const operator_move = `
-
-  HugeObject &operator=(HugeObject&& object) {
-    if (this == &object) { return *this; }
-    FreeMemory(ptr);
-    length = object.length;
-    ptr = object.ptr;
-    object.ptr = nullptr;
-    return *this;
-  }
-  `
-
-  const assign_fail = `
-    // ❌ Does not compile.
-    storage.member_object = HugeObject{200};`
-
-  const assign_int_fail = `
-    // ❌ Does not compile either.
-    int& answer = 42;`
-
-  const main_fn = (comment:any = ``, assign_temp:any = ``) => store`
-  struct HugeObjectStorage {
-    HugeObject member_object;
-  };
-
-  int main() {
-    HugeObject object{100};
-    HugeObjectStorage storage{};
-    storage.member_object = object;${assign_temp}
-    return 0;
-  } ${comment}`
-
-  const comment = ` // storage and object are destroyed`
-
-  const zoom_fn = (in_zoom: number) => new Vector2(in_zoom, in_zoom);
-
-  yield * codeRef().edit(duration, false)(...simplify(code()));
-  yield * codeRef().selection([...word(7, 30, 28)], duration);
-  yield * waitFor(duration);
-  yield * codeRef().selection([...word(9, 20, 15)], duration);
-  yield * waitFor(duration);
-  yield * codeRef().edit(duration, true)(...code(edit(``, to_string(operator_copy()))));
-  yield * waitFor(duration);
-  yield * codeRef().selection([...lines(9)], duration);
-  yield * waitFor(duration);
-  yield * all(
-    codeRef().selection([...word(9, 26, 24)], duration),
-    codeRef().scale(zoom_fn(1.5), duration),
-    codeRef().position(new Vector2(-500, 200), duration),
-  );
-  yield * waitFor(duration);
-  yield * all(
-    codeRef().selection([...lines(14)], duration),
-    codeRef().scale(zoom_fn(1.2), duration),
-    codeRef().position(new Vector2(50, -200), duration),
-  );
-  yield * waitFor(duration);
-  yield * all(
-    codeRef().selection(DEFAULT, duration),
-    codeRef().scale(zoom_fn(0.7), duration),
-    codeRef().position(new Vector2(0, 0), duration),
-  );
-  yield * waitFor(duration);
-  yield * all(
-    codeRef().position(new Vector2(0, -300), duration),
-    codeRef().edit(duration, true)(...simplify(code(operator_copy(), edit(``, to_string(main_fn()))))),
-  );
-  yield * all(
-    codeRef().scale(zoom_fn(1.2), duration),
-    codeRef().position(new Vector2(400, -800), duration),
-  );
-  yield * codeRef().selection([...lines(29)], duration);
-  yield * codeRef().selection([...lines(30)], duration);
-  yield * codeRef().selection([...lines(31)], duration);
-  yield * codeRef().edit(duration, true)(...simplify(code(operator_copy(), main_fn(insert(comment)))));
-  yield * waitFor(duration);
-
-  // Show destructor
-  yield * all(
-    codeRef().selection(DEFAULT, duration),
-    codeRef().scale(zoom_fn(0.5), duration),
-    codeRef().position(new Vector2(0, 0), duration),
-  );
-  yield * waitFor(duration);
-  yield * all(
-    codeRef().selection(DEFAULT, duration),
-    codeRef().scale(zoom_fn(1.2), duration),
-    codeRef().selection([...lines(18 )], duration),
-    codeRef().position(new Vector2(200, 0), duration),
-  );
-  yield * waitFor(duration);
-
-  // Show const
-  yield * all(
-    codeRef().selection(DEFAULT, duration),
-    codeRef().scale(zoom_fn(0.5), duration),
-    codeRef().position(new Vector2(0, 0), duration),
-  );
-  yield * waitFor(duration);
-  yield * all(
-    codeRef().scale(zoom_fn(1.2), duration),
-    codeRef().selection([...lines(9, 16)], duration),
-    codeRef().position(new Vector2(50, 400), duration),
-  );
-  yield * waitFor(duration);
-  yield * all(
-    codeRef().scale(zoom_fn(3.0), duration),
-    codeRef().selection([...word(9, 26, 5)], duration),
-    codeRef().position(new Vector2(100, 1400), duration),
-  );
-  yield * waitFor(duration);
-
-  // Remove const
-  yield * all(
-    codeRef().edit(duration, false)(...simplify(code(operator_copy(edit('const ', '')), main_fn(comment)))),
-    codeRef().selection([...word(9, 26, 12)], duration),
-  );
-  yield * all(
-    codeRef().scale(zoom_fn(1.2), duration),
-    codeRef().position(new Vector2(50, 400), duration),
-    codeRef().selection([...lines(9, 16)], duration),
-  );
-  yield *codeRef().selection([...lines(13, 14)], duration);
-  yield * codeRef().edit(duration, true)(...simplify(code(operator_copy('', edit(copy, steal)), main_fn(comment))));
-  yield * waitFor(duration);
-
-  // Look at the main again
-  yield * all(
-    codeRef().selection(DEFAULT, duration),
-    codeRef().scale(zoom_fn(0.5), duration),
-    codeRef().position(new Vector2(0, 0), duration),
-  );
-  yield * waitFor(duration);
-  yield * all(
-    codeRef().scale(zoom_fn(1.2), duration),
-    codeRef().position(new Vector2(400, -800), duration),
-  );
-  yield * codeRef().selection([...lines(29)], duration);
-  yield * codeRef().selection([...lines(30)], duration);
-  yield * codeRef().selection([...lines(31)], duration);
-  yield * codeRef().selection(DEFAULT, duration);
-
-  yield * waitFor(duration);
-  // Assign temp
-  yield * all(
-    codeRef().scale(zoom_fn(1.3), duration),
-    codeRef().edit(duration, true)(
-      ...simplify(
-        code(
-          operator_copy('', steal),
-          main_fn(comment, insert(assign_fail))))),
-    codeRef().position(new Vector2(200, -1100), duration),
-  );
-  yield * waitFor(duration);
-  yield * codeRef().edit(duration, true)(
-    ...simplify(
-      code(
-        operator_copy('', steal),
-        main_fn(comment, edit(assign_fail, assign_int_fail)))));
-  yield * waitFor(duration);
-
-  yield * all(
-    codeRef().selection(DEFAULT, duration),
-    codeRef().scale(zoom_fn(0.5), duration),
-    codeRef().position(new Vector2(0, 0), duration),
-    codeRef().edit(duration, false)(
-      ...simplify(
-        code(
-          operator_copy('', steal),
-          main_fn(comment, remove(assign_int_fail))))),
-  );
-
-  // Add move operator
-  yield * waitFor(duration);
-  yield * all(
-    codeRef().scale(zoom_fn(1.0), duration),
-    codeRef().position([0, 260], duration),
-    codeRef().edit(duration, true)(
-      ...simplify(
-        code(
-          operator_copy(insert('const '),
-          edit(steal, copy)),
-          main_fn(comment),
-          insert(operator_move)))),
-  );
-  yield * waitFor(duration);
-  yield * codeRef().selection([...word(9, 26, 24), ...lines(13, 14)], duration);
-  yield * waitFor(duration);
-  yield * codeRef().selection([...word(18, 26, 19), ...lines(22, 23)], duration);
-  yield * waitFor(duration);
-
-  const comment_temp_bind = `// Can be bound to a temporary`
-  const comment_pick_overload = ` // The compiler picks Blah(int&&)`
-
-  const blah_code = (
-    comment_temp:any = ``,
-    comment_pick:any = ``,
-    blah_answer:any = ``,
-    blah_answer_comment:any = ``,
-    blah_move_answer:any = ``,
-    blah_move_answer_comment:any = ``,
-  ) => store`
-  #include <iostream>
-
-  void Blah(int&) {
-    std::cout << "&" << std::endl;
-  }
-
-  void Blah(int&&) {
-    std::cout << "&&" << std::endl;
-  }
-
-  int main() {
-    int&& answer = 42;  ${comment_temp}
-    Blah(42);${comment_pick}${blah_answer}${blah_answer_comment}${blah_move_answer}${blah_move_answer_comment}
-  }`
-
-
-  yield * waitFor(duration);
-  yield * all(
-    codeRef().edit(duration, false)(...blah_code()),
-    codeRef().selection(DEFAULT, duration),
-    codeRef().scale(zoom_fn(1.0), 0),
-    codeRef().position(new Vector2(0, 0), 0),
-  );
-  yield * waitFor(duration);
-  yield * codeRef().selection([...lines(11)], duration);
-  yield * codeRef().edit(duration, false)(...simplify(blah_code(insert(comment_temp_bind))));
-  yield * waitFor(duration);
-  yield * codeRef().selection([...lines(12)], duration);
-  yield * codeRef().edit(duration, false)(...simplify(blah_code(comment_temp_bind, insert(comment_pick_overload))));
-  yield * waitFor(duration);
-  yield * waitFor(duration);
-
-
-  const final_main = `
-  int main() {
-    HugeObject object{100};
-    HugeObjectStorage storage{};
-    storage.member_object = object;
-    storage.member_object = HugeObject{200};
-    storage.member_object = std::move(object);
-    return 0;
-  }`
-
-  yield * codeRef().selection(DEFAULT, 0),
-  yield * codeRef().edit(duration, false)`${final_main}`;
-  yield * waitFor(duration);
-  yield * codeRef().selection([...lines(4)], duration);
-  yield * codeRef().selection([...lines(5)], duration);
-  yield * codeRef().selection([...lines(6)], duration);
-  yield * waitFor(duration);
-
-  const rref_comment = `  // Prints "&&"`
-  const lref_comment = `  // Prints "&"`
-  const blah_answer_ref = `
-    Blah(answer);`
-  const blah_answer_rref = `
-    Blah(std::move(answer));`
-
-  // Final rref example
-  yield * codeRef().selection(DEFAULT, 0),
-  yield * codeRef().edit(duration, false)(...blah_code());
-  yield * codeRef().edit(duration, false)(...blah_code('', insert(rref_comment)));
-  yield * codeRef().edit(duration, false)(...blah_code('', rref_comment, insert(blah_answer_ref)));
-  yield * codeRef().edit(duration, false)(...blah_code(
-    '', rref_comment, blah_answer_ref, insert(lref_comment)));
-  yield * codeRef().edit(duration, false)(...blah_code(
-    '', rref_comment, blah_answer_ref, lref_comment, insert(blah_answer_rref)));
-  yield * codeRef().edit(duration, false)(...blah_code(
-    '', rref_comment, blah_answer_ref, lref_comment, blah_answer_rref, insert(rref_comment)));
-
-  yield * waitFor(duration);
-
-  yield * waitFor(duration);
-
-});
diff --git a/animation/memory_and_smart_pointers/src/scenes/heap.meta b/animation/memory_and_smart_pointers/src/scenes/heap.meta
deleted file mode 100644
index 41ae958..0000000
--- a/animation/memory_and_smart_pointers/src/scenes/heap.meta
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-  "version": 0,
-  "timeEvents": [],
-  "seed": 4149161514
-}
\ No newline at end of file
diff --git a/animation/memory_and_smart_pointers/src/scenes/heap.tsx b/animation/memory_and_smart_pointers/src/scenes/heap.tsx
deleted file mode 100644
index acbaf66..0000000
--- a/animation/memory_and_smart_pointers/src/scenes/heap.tsx
+++ /dev/null
@@ -1,346 +0,0 @@
-import { Node, lines, word, makeScene2D, Code, Txt, Rect, Grid, Line, Layout } from '@motion-canvas/2d';
-import { all, sequence, waitFor } from '@motion-canvas/core/lib/flow';
-import { Vector2 } from '@motion-canvas/core/lib/types';
-import { createRef } from '@motion-canvas/core/lib/utils';
-import { createSignal, DEFAULT } from '@motion-canvas/core/lib/signals';
-import { CodeBlock, edit, insert, range } from '@motion-canvas/2d/lib/components/CodeBlock';
-
-const RED = '#ff6470';
-const GREEN = '#99C47A';
-const BLUE = '#68ABDF';
-const WHITE = '#FFFFFF';
-
-export default makeScene2D(function* (view) {
-
-  const grid_ref = createRef<Grid>();
-  const address_ref = createRef<Txt>();
-  const data_rect_ref_1 = createRef<Rect>();
-  const data_rect_ref_2 = createRef<Rect>();
-
-  const table_layout =
-    <Layout
-      direction={'column'}
-      alignItems={'end'}
-      x={-1300}
-      layout />
-  table_layout.add(
-    <Txt
-      text={"heap memory"}
-      fontFamily={"Fira Mono"}
-      alignSelf={'start'}
-      fill={WHITE}
-      padding={10}
-    />)
-  table_layout.add(
-    <Rect
-      width={550}
-      height={80}
-      clip={true}
-    >
-      <Grid
-        ref={grid_ref}
-        spacing={50}
-        stroke={'#444'}
-        lineWidth={4}
-        start={0.3}
-        end={0.3}
-        width={550}
-        height={130}
-        cache
-      />
-    </Rect>)
-  table_layout.add(
-    <Txt
-      ref={address_ref}
-      text={""}
-      fontFamily={"Fira Mono"}
-      alignSelf={'start'}
-      fill={'#666'}
-      fontSize={32}
-      marginBottom={20}
-      paddingLeft={70}
-      padding={10}
-    />)
-  table_layout.add(
-    <Txt
-      text={"stack"}
-      fontFamily={"Fira Mono"}
-      alignSelf={'start'}
-      fill={WHITE}
-      padding={10}
-    />)
-
-  var stack_refs = []
-  var line_refs = []
-
-  for (let i = 4; i >= 0; i--) {
-    const text_ref = createRef<Txt>();
-    const line_ref = createRef<Line>();
-    stack_refs.push(text_ref);
-    line_refs.push(line_ref);
-    table_layout.add(
-      <Rect layout direction={'row'}>
-        <Txt
-          text={i == 4 ? '...' : String(i)}
-          fontFamily={"Fira Mono"}
-          fontSize={35}
-          fill={'gray'}
-          paddingRight={30}
-          margin={10}
-        />
-        <Rect layout direction={'column'}>
-          <Code
-            ref={text_ref}
-            code={"⁉️"}
-            fontFamily={"Fira Mono"}
-            alignSelf={'center'}
-            fontSize={35}
-            fontWeight={500}
-            margin={15}
-          />
-          <Line
-            ref={line_ref}
-            stroke={'#777'}
-            lineWidth={5}
-            points={[[0, 0], [400, 0]]}
-          />
-        </Rect>
-      </Rect>
-
-    );
-  }
-  stack_refs.reverse();
-
-  const command_txt_ref = createRef<Txt>()
-
-  table_layout.add(
-    <Rect layout direction={'column'} alignSelf={'start'} minHeight={250}>
-      <Txt
-        text={"command:"}
-        fontFamily={"Fira Mono"}
-        fill={'#777'}
-        marginTop={100}
-      />
-      <Txt
-        ref={command_txt_ref}
-        text={""}
-        fontFamily={"Fira Mono"}
-        marginTop={10}
-        marginLeft={100}
-        fill={WHITE}
-      />
-    </Rect>)
-
-  view.add(table_layout)
-  view.add(<Rect
-    x={-700}
-    y={-345}
-    ref={data_rect_ref_1}
-    stroke={BLUE}
-    lineWidth={4}
-    width={190}
-    height={40}
-    opacity={0.0}
-  />)
-  view.add(<Rect
-    x={-500}
-    y={-345}
-    ref={data_rect_ref_2}
-    stroke={BLUE}
-    lineWidth={4}
-    width={190}
-    height={40}
-    opacity={0.0}
-  />)
-  const code_stack = `\
-#include <iostream>
-
-int main() {
-  int size = 2;
-  int* ptr = nullptr;
-  {
-    int array[size];  // 😱 Don't use C-style arrays!
-    array[0] = 42;
-    array[1] = 23;
-    ptr = array;
-    std::cout << "Before stack cleanup.\\n";
-    for (int i = 0; i < size; ++i) {
-      std::cout << ptr[i] << std::endl;
-    }
-  }
-  // 😱 Code below leads to undefined behavior!
-  std::cout << "After stack cleanup.\\n";
-  for (int i = 0; i < size; ++i) {
-    std::cout << ptr[i] << std::endl;
-  }
-  return 0;
-}`
-
-  const code_heap = `\
-#include <iostream>
-
-int main() {
-  int size = 2;
-  int* ptr = nullptr;
-  {
-    // 😱 Don't use unprotected new and new[]!
-    int* array = new int[size];
-    array[0] = 42;
-    array[1] = 23;
-    ptr = array;
-    std::cout << "Before stack cleanup.\\n";
-    for (int i = 0; i < size; ++i) {
-      std::cout << ptr[i] << std::endl;
-    }
-  }
-  std::cout << "After stack cleanup.\\n";
-  for (int i = 0; i < size; ++i) {
-    std::cout << ptr[i] << std::endl;
-  }
-  delete[] ptr;  // 😱 What points to our data?
-  return 0;
-}`
-  const code_ref = createRef<Code>()
-
-  yield view.add(
-    <Code
-      ref={code_ref}
-      fontSize={35}
-      fontFamily={'Fira Mono'}
-      fontWeight={500}
-      offsetX={-1}
-      x={-200}
-    />);
-
-  const duration = 1.0
-
-  // Frame
-  yield* all(
-    code_ref().code(code_stack, duration),
-    waitFor(3 * duration)
-  );
-
-  // Frame
-  yield* all(
-    code_ref().code(code_heap, duration),
-    waitFor(3 * duration)
-  );
-
-  yield* all(
-    table_layout.x(-600, duration),
-    grid_ref().end(1, 2 * duration),
-    grid_ref().start(0, 2 * duration),
-    waitFor(3 * duration)
-  );
-
-  // Frame
-  yield* all(
-    stack_refs[0]().code(`size = 2`, duration),
-    code_ref().selection(lines(3), duration),
-    command_txt_ref().text('push(int)', duration / 3),
-    waitFor(3 * duration)
-  );
-
-  // Frame
-  yield* all(
-    stack_refs[1]().code(`ptr = nullptr`, duration),
-    code_ref().selection(lines(4), duration),
-    command_txt_ref().text('', duration / 3).to('push(int*)', duration / 3),
-    waitFor(3 * duration)
-  );
-
-  // Frame
-  yield* all(
-    command_txt_ref().text('', duration / 3).to('malloc(8)', duration / 3),
-    code_ref().selection(word(7, 16, 15), duration),
-    sequence(0.1,
-      address_ref().text('0x8eceb0', duration / 2),
-      data_rect_ref_1().opacity(0.8, duration),
-      data_rect_ref_2().opacity(0.8, duration),
-    ),
-    waitFor(3 * duration)
-  );
-
-  // Frame
-  yield* all(
-    stack_refs[2]().code(`array = 0x8eceb0`, duration),
-    command_txt_ref().text('', duration / 3).to('push(int*)', duration / 3),
-    code_ref().selection(lines(7), duration),
-    waitFor(3 * duration)
-  );
-
-  // Frame
-  yield* all(
-    command_txt_ref().text('', duration / 3),
-    code_ref().selection(lines(8), duration),
-    data_rect_ref_1().fill(BLUE, duration),
-    waitFor(duration)
-  );
-
-  // Frame
-  yield* all(
-    code_ref().selection(lines(8, 9), duration),
-    data_rect_ref_2().fill(BLUE, duration),
-    waitFor(3 * duration)
-  );
-
-  // Frame
-  yield* all(
-    stack_refs[1]().code(`ptr = 0x8eceb0`, duration),
-    code_ref().selection(lines(10), duration),
-    waitFor(3 * duration)
-  );
-
-  // Frame
-  yield* all(
-    code_ref().selection(lines(11, 14), duration),
-    waitFor(3 * duration)
-  );
-
-  // Frame
-  yield* all(
-    sequence(0.1,
-      stack_refs[2]().code('⁉️', duration)),
-    code_ref().selection(lines(15), duration),
-    command_txt_ref().text('', duration / 3).to('pop()', duration / 3),
-    waitFor(3 * duration)
-  );
-
-  // Frame
-  yield* all(
-    code_ref().selection(lines(16, 19), duration),
-    command_txt_ref().text('', duration / 3),
-    waitFor(3 * duration)
-  );
-
-  // Frame
-  yield* all(
-    sequence(0.1,
-      data_rect_ref_1().opacity(0, duration),
-      data_rect_ref_2().opacity(0, duration)),
-    code_ref().selection(lines(20), duration),
-    waitFor(3 * duration)
-  );
-
-  // Frame
-  yield* all(
-    sequence(0.1,
-      stack_refs[1]().code('⁉️', duration),
-      stack_refs[0]().code('⁉️', duration)),
-    code_ref().selection(lines(22), duration),
-    command_txt_ref().text('', duration / 3),
-    waitFor(3 * duration)
-  );
-
-
-
-  // Frame
-  yield* all(
-    code_ref().selection(DEFAULT, duration),
-    command_txt_ref().text('', duration / 3),
-    waitFor(3 * duration)
-  );
-
-  yield* waitFor(3.0);
-
-});
diff --git a/animation/memory_and_smart_pointers/src/scenes/memory.meta b/animation/memory_and_smart_pointers/src/scenes/memory.meta
deleted file mode 100644
index 5ce0a4c..0000000
--- a/animation/memory_and_smart_pointers/src/scenes/memory.meta
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-  "version": 0,
-  "timeEvents": [],
-  "seed": 1938444845
-}
\ No newline at end of file
diff --git a/animation/memory_and_smart_pointers/src/scenes/memory.tsx b/animation/memory_and_smart_pointers/src/scenes/memory.tsx
deleted file mode 100644
index 15ce6ee..0000000
--- a/animation/memory_and_smart_pointers/src/scenes/memory.tsx
+++ /dev/null
@@ -1,188 +0,0 @@
-import { makeScene2D } from '@motion-canvas/2d/lib/scenes';
-import { Node, Circle, Rect, Grid, Line } from '@motion-canvas/2d/lib/components';
-import { all, waitFor } from '@motion-canvas/core/lib/flow';
-import { Vector2 } from '@motion-canvas/core/lib/types';
-import { createRef } from '@motion-canvas/core/lib/utils';
-import { createSignal } from '@motion-canvas/core/lib/signals';
-import { CodeBlock } from '@motion-canvas/2d/lib/components/CodeBlock';
-import {Video} from '@motion-canvas/2d/lib/components';
-import travolta from '../../videos/travolta.mp4';
-
-const RED = '#ff6470';
-const GREEN = '#99C47A';
-const BLUE = '#68ABDF';
-
-export default makeScene2D(function* (view) {
-  const data_ref = createRef<CodeBlock>();
-  const other_data_ref = createRef<CodeBlock>();
-  const object_ref = createRef<CodeBlock>();
-  const other_object_ref = createRef<CodeBlock>();
-  const line_1 = createRef<Line>();
-  const line_2 = createRef<Line>();
-  const node_ref = createRef<Node>();
-  const travolta_ref = createRef<Video>();
-
-  const data = `
-  1011011010110
-  1011000100100
-  0010011100000
-  1101000010001
-  0010100111111`
-
-  const error = `
-  binary(78797,0x1e21a6500) malloc: Double free of object 0x155e06ac0
-  binary(78797,0x1e21a6500) malloc: *** set a breakpoint in malloc_error_break to debug`
-
-  const object_code = `ptr_1`
-  const member_object_code = `ptr_2`
-
-  view.add(
-    <Node>
-      <CodeBlock
-        ref={data_ref}
-        fontSize={60}
-        x={0}
-        y={200}
-        code={data}
-        opacity={0.0}
-      />
-      <CodeBlock
-        ref={other_data_ref}
-        fontSize={60}
-        x={400}
-        y={200}
-        code={data}
-        opacity={0.0}
-      />
-      <Node x={0} y={-300} ref={node_ref}>
-        <CodeBlock
-          ref={object_ref}
-          fontSize={60}
-          code={object_code}
-          opacity={0.0}
-        />
-        <Line
-          ref={line_1}
-          stroke={RED}
-          lineWidth={10}
-          endArrow
-          arrowSize={20}
-          opacity={0.0}
-          points={[[0, 50], [0, 300]]}
-        />
-        <Video
-          ref={travolta_ref}
-          opacity={0.0}
-          src={travolta}
-          scale={0.3}
-          position={[200, 300]}
-        />
-        <CodeBlock
-          ref={other_object_ref}
-          fontSize={60}
-          opacity={0.0}
-          code={member_object_code}
-        />
-        <Line
-          ref={line_2}
-          stroke={RED}
-          lineWidth={10}
-          endArrow
-          arrowSize={20}
-          opacity={0.0}
-          points={[[0, 50], [0, 300]]}
-        />
-      </Node>
-    </Node>,
-  );
-
-  // Destructor
-  yield* all(
-    object_ref().opacity(1.0, 1.0),
-    line_1().opacity(1.0, 1.5),
-    data_ref().opacity(1.0, 2.0),
-  );
-  yield* waitFor(2.0);
-  yield* all(
-    object_ref().opacity(0.0, 2.0),
-    line_1().opacity(0.0, 1.5),
-    data_ref().opacity(0.0, 1.0),
-  );
-  yield* waitFor(2.0);
-  yield* all(
-    object_ref().opacity(1.0, 1.0),
-    line_1().opacity(1.0, 1.5),
-    data_ref().opacity(1.0, 2.0),
-  );
-  yield* waitFor(2.0);
-  yield* all(
-    object_ref().opacity(0.0, 1.5),
-    line_1().opacity(0.0, 1.0),
-  );
-  yield* data_ref().scale(1.2, 0.7).to(1.0, 0.7);
-
-  yield* waitFor(2.0);
-  yield* data_ref().opacity(0.0, 0.1);
-  yield* all(
-    object_ref().opacity(1.0, 0.1),
-    line_1().opacity(1.0, 0.1),
-    data_ref().opacity(1.0, 0.1),
-  );
-  yield* waitFor(2.0);
-  yield* all(
-    object_ref().position([-400, 0], 1.0),
-    other_object_ref().position([-400, 0], 1.0),
-    line_1().points([[-400, 50], [-100, 300]], 1.0),
-    line_2().points([[-300, 50], [-100, 300]], 1.0),
-  );
-  yield* all(
-    object_ref().position([-400, 0], 1.0),
-    other_object_ref().opacity(1.0, 1.0),
-    other_object_ref().position([400, 0], 1.0),
-    line_1().points([[-400, 50], [-100, 300]], 1.0),
-    line_2().points([[400, 50], [100, 300]], 1.0),
-    line_2().opacity(1.0, 1.0),
-  );
-  yield* waitFor(2.0);
-  yield* all(
-    data_ref().opacity(0.0, 0.7),
-    other_object_ref().opacity(0.0, 1.5),
-    line_2().opacity(0.0, 1.0),
-  );
-  travolta_ref().play();
-  yield* all(
-    node_ref().scale(1.5, 1.0),
-    travolta_ref().opacity(1.0, 1.0),
-  );
-  yield* waitFor(3.5);
-
-  // Copy assignment fail
-  travolta_ref().pause();
-  yield* all(
-    travolta_ref().opacity(0, 0),
-    object_ref().opacity(0, 0),
-    line_1().opacity(0, 0),
-    data_ref().opacity(0, 0),
-    node_ref().scale(1.0, 0),
-    data_ref().position([-400, 200], 0),
-    line_1().points([[-400, 50], [-400, 300]], 0),
-    line_2().points([[400, 50], [400, 300]], 0),
-  );
-  yield* all(
-    object_ref().opacity(1.0, 1.0),
-    line_1().opacity(1.0, 1.5),
-    data_ref().opacity(1.0, 2.0),
-  );
-  yield* all(
-    other_object_ref().opacity(1.0, 1.0),
-    line_2().opacity(1.0, 1.5),
-    other_data_ref().opacity(1.0, 2.0),
-  );
-  yield* waitFor(2.0);
-  yield* all(
-    line_2().points([[400, 50], [-120, 300]], 1.0),
-  );
-  yield* waitFor(2.0);
-  yield* other_data_ref().scale(1.2, 0.7).to(1.0, 0.7);
-  yield* waitFor(2.0);
-});
diff --git a/animation/memory_and_smart_pointers/src/scenes/memory_show.meta b/animation/memory_and_smart_pointers/src/scenes/memory_show.meta
deleted file mode 100644
index ac23d38..0000000
--- a/animation/memory_and_smart_pointers/src/scenes/memory_show.meta
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-  "version": 0,
-  "timeEvents": [],
-  "seed": 3444419084
-}
\ No newline at end of file
diff --git a/animation/memory_and_smart_pointers/src/scenes/memory_show.tsx b/animation/memory_and_smart_pointers/src/scenes/memory_show.tsx
deleted file mode 100644
index 4994b92..0000000
--- a/animation/memory_and_smart_pointers/src/scenes/memory_show.tsx
+++ /dev/null
@@ -1,262 +0,0 @@
-import { makeScene2D } from '@motion-canvas/2d/lib/scenes';
-import { Node, Txt, Rect, Grid, Line, Camera } from '@motion-canvas/2d/lib/components';
-import { all, sequence, waitFor } from '@motion-canvas/core/lib/flow';
-import { Vector2 } from '@motion-canvas/core/lib/types';
-import { createRef } from '@motion-canvas/core/lib/utils';
-import { createSignal } from '@motion-canvas/core/lib/signals';
-import { CodeBlock, edit, insert } from '@motion-canvas/2d/lib/components/CodeBlock';
-
-const RED = '#ff6470';
-const GREEN = '#99C47A';
-const BLUE = '#68ABDF';
-const WHITE = '#FFFFFF';
-
-export default makeScene2D(function* (view) {
-  const memory_grid_ref = createRef<Grid>();
-  const grid_txt_ref = createRef<Txt>();
-  const camera = createRef<Camera>();
-
-  const spacing = 100;
-  const wiggle_room = 20;
-  const grid_width = 1800;
-  const grid_height = 2 * spacing;
-  view.add(
-    <Grid
-      ref={memory_grid_ref}
-      y={0}
-      width={grid_width}
-      height={grid_height}
-      spacing={spacing}
-      stroke={'#444'}
-      lineWidth={5}
-      end={0.5}
-      start={0.5}
-      cache
-    />
-  );
-
-  view.add(
-    <Txt
-      ref={grid_txt_ref}
-      x={810}
-      y={memory_grid_ref().y() + grid_height / 2 + 30}
-      text={""}
-      fill={'#666'}
-    />
-  )
-
-  let rect_refs = []
-  for (let i = 0; i < 12; ++i) {
-    const rect_ref = createRef<Rect>();
-    rect_refs.push(rect_ref);
-    view.add(
-      <Rect
-        ref={rect_ref}
-        fill={BLUE}
-        y={-1000}
-        opacity={0}
-        width={2 * spacing - wiggle_room}
-        height={spacing - wiggle_room}
-        stroke={WHITE}
-        lineWidth={5}
-      />
-    )
-  }
-
-  rect_refs[1]().width(4 * spacing - wiggle_room);
-  rect_refs[3]().width(6 * spacing - wiggle_room);
-  rect_refs[6]().width(4 * spacing - wiggle_room);
-  rect_refs[7]().width(1 * spacing - wiggle_room);
-  rect_refs[8]().width(4 * spacing - wiggle_room);
-  rect_refs[11]().width(4 * spacing - wiggle_room);
-  console.log(rect_refs[1]().width());
-
-  rect_refs[11]().shadowBlur(20);
-  rect_refs[11]().shadowColor('#222');
-  rect_refs[11]().shadowOffset(5);
-
-
-
-  const duration = 1.0;
-  const half_wiggle = wiggle_room / 2;
-  const half_wiggle_vector = new Vector2(half_wiggle, half_wiggle);
-
-  yield* waitFor(duration);
-
-  yield* all(
-    memory_grid_ref().start(0, duration / 2),
-    memory_grid_ref().end(1, duration / 2),
-    grid_txt_ref().text("memory", duration / 2),
-  );
-
-  yield*
-    all(
-      sequence(0.1,
-        ...rect_refs.slice(0, 10).map(rect => rect().opacity(1, duration)),
-      ),
-      sequence(0.1,
-        rect_refs[0]().topLeft(
-          memory_grid_ref().topLeft().add(half_wiggle_vector), duration),
-        rect_refs[1]().topLeft(
-          memory_grid_ref().topLeft()
-            .add(half_wiggle_vector)
-            .addX(rect_refs[0]().width())
-            .addX(wiggle_room), duration),
-        rect_refs[2]().topLeft(
-          memory_grid_ref().topLeft()
-            .add(half_wiggle_vector)
-            .addX(rect_refs[0]().width())
-            .addX(rect_refs[1]().width())
-            .addX(2 * wiggle_room), duration),
-        rect_refs[3]().topLeft(
-          memory_grid_ref().topLeft()
-            .add(half_wiggle_vector)
-            .addX(rect_refs[0]().width())
-            .addX(rect_refs[1]().width())
-            .addX(rect_refs[2]().width())
-            .addX(3 * wiggle_room), duration),
-        rect_refs[4]().topLeft(
-          memory_grid_ref().topLeft()
-            .add(half_wiggle_vector)
-            .addX(rect_refs[0]().width())
-            .addX(rect_refs[1]().width())
-            .addX(rect_refs[2]().width())
-            .addX(rect_refs[3]().width())
-            .addX(4 * wiggle_room), duration),
-        rect_refs[5]().topLeft(
-          memory_grid_ref().topLeft()
-            .add(half_wiggle_vector)
-            .addX(rect_refs[0]().width())
-            .addX(rect_refs[1]().width())
-            .addX(rect_refs[2]().width())
-            .addX(rect_refs[3]().width())
-            .addX(rect_refs[4]().width())
-            .addX(5 * wiggle_room), duration),
-
-        rect_refs[6]().topLeft(
-          memory_grid_ref().topLeft()
-            .add(half_wiggle_vector)
-            .addY(spacing), duration),
-        rect_refs[7]().topLeft(
-          memory_grid_ref().topLeft()
-            .add(half_wiggle_vector)
-            .addX(rect_refs[6]().width())
-            .addX(wiggle_room)
-            .addY(spacing), duration),
-        rect_refs[8]().topLeft(
-          memory_grid_ref().topLeft()
-            .add(half_wiggle_vector)
-            .addX(rect_refs[6]().width())
-            .addX(rect_refs[7]().width())
-            .addX(2 * wiggle_room)
-            .addY(spacing), duration),
-        rect_refs[9]().topLeft(
-          memory_grid_ref().topLeft()
-            .add(half_wiggle_vector)
-            .addX(rect_refs[6]().width())
-            .addX(rect_refs[7]().width())
-            .addX(rect_refs[8]().width())
-            .addX(3 * wiggle_room)
-            .addY(spacing), duration),
-        rect_refs[10]().topLeft(
-          memory_grid_ref().topLeft()
-            .add(half_wiggle_vector)
-            .addX(rect_refs[6]().width())
-            .addX(rect_refs[7]().width())
-            .addX(rect_refs[8]().width())
-            .addX(rect_refs[9]().width())
-            .addX(4 * wiggle_room)
-            .addY(spacing), duration),
-      ),
-      waitFor(3 * duration)
-    );
-
-  yield* all(
-    rect_refs[3]().fill(RED, duration / 2).wait(duration).to(BLUE, duration / 2),
-    rect_refs[7]().fill(GREEN, duration / 2).wait(duration).to(BLUE, duration / 2),
-    waitFor(3 * duration)
-  );
-
-  yield* all(
-    rect_refs[6]().fill(RED, duration / 2),
-    rect_refs[6]().topLeft(rect_refs[6]().topLeft().addX(spacing), duration),
-
-    rect_refs[7]().fill(RED, duration / 2),
-    rect_refs[7]().topLeft(rect_refs[7]().topLeft().addX(2 * spacing), duration),
-
-    rect_refs[8]().fill(RED, duration / 2),
-    rect_refs[8]().topLeft(rect_refs[8]().topLeft().addX(3 * spacing), duration),
-
-    rect_refs[9]().fill(RED, duration / 2),
-    rect_refs[9]().topLeft(rect_refs[9]().topLeft().addX(5 * spacing), duration),
-
-    waitFor(3 * duration)
-  );
-
-  rect_refs[11]().x(-1500);
-  rect_refs[11]().y(-100);
-  rect_refs[11]().fill(GREEN);
-
-  yield* all(
-    rect_refs[11]().x(-750, duration),
-    rect_refs[11]().y(-100, duration),
-    rect_refs[11]().opacity(1, duration / 2),
-  );
-  yield* all(
-    rect_refs[11]().y(rect_refs[11]().y(), duration * 2)
-      .to(rect_refs[11]().y() + spacing, duration / 2)
-      .to(rect_refs[11]().y() + spacing, duration * 2)
-      .to(rect_refs[11]().y() + 4 * spacing, duration * 2),
-    rect_refs[11]().x(rect_refs[11]().x() + 15 * spacing, duration * 2)
-      .to(rect_refs[11]().x(), duration / 2)
-      .to(rect_refs[11]().x() + 15 * spacing, duration * 2)
-      .to(rect_refs[11]().x() + 7.5 * spacing, duration * 2),
-  );
-  yield* waitFor(duration);
-
-
-  yield* all(
-    rect_refs[6]().fill(BLUE, duration / 2),
-    rect_refs[6]().topLeft(rect_refs[6]().topLeft().addX(-spacing), duration),
-
-    rect_refs[7]().fill(BLUE, duration / 2),
-    rect_refs[7]().topLeft(rect_refs[7]().topLeft().addX(-2 * spacing), duration),
-
-    rect_refs[8]().fill(BLUE, duration / 2),
-    rect_refs[8]().topLeft(rect_refs[8]().topLeft().addX(-3 * spacing), duration),
-
-    rect_refs[9]().fill(BLUE, duration / 2),
-    rect_refs[9]().topLeft(rect_refs[9]().topLeft().addX(-5 * spacing), duration),
-
-    rect_refs[11]().topLeft(
-      memory_grid_ref().topLeft()
-        .add(half_wiggle_vector)
-        .addX(rect_refs[6]().width())
-        .addX(rect_refs[7]().width())
-        .addX(rect_refs[8]().width())
-        .addX(rect_refs[9]().width())
-        .addX(4 * wiggle_room)
-        .addY(spacing), duration),
-  );
-  yield* waitFor(3 * duration);
-
-  rect_refs[11]().opacity(0);
-  rect_refs[1]().opacity(0);
-  rect_refs[11]().topLeft(rect_refs[1]().topLeft().addY(-1.2 * spacing));
-  yield* waitFor(duration);
-
-  yield* all(
-    rect_refs[11]().y(rect_refs[11]().y() + 1.2 * spacing, duration),
-    rect_refs[11]().opacity(1, duration),
-  );
-  yield* waitFor(duration);
-
-  yield* all(
-    rect_refs[11]().y(rect_refs[11]().y() - 1.2 * spacing, duration),
-    rect_refs[11]().opacity(0, duration),
-  );
-  yield* waitFor(duration);
-
-
-
-});
diff --git a/animation/memory_and_smart_pointers/src/scenes/stack.meta b/animation/memory_and_smart_pointers/src/scenes/stack.meta
deleted file mode 100644
index 5f80b88..0000000
--- a/animation/memory_and_smart_pointers/src/scenes/stack.meta
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-  "version": 0,
-  "timeEvents": [],
-  "seed": 4180355539
-}
\ No newline at end of file
diff --git a/animation/memory_and_smart_pointers/src/scenes/stack.tsx b/animation/memory_and_smart_pointers/src/scenes/stack.tsx
deleted file mode 100644
index a9bf35d..0000000
--- a/animation/memory_and_smart_pointers/src/scenes/stack.tsx
+++ /dev/null
@@ -1,231 +0,0 @@
-import { Node, lines, makeScene2D, Code, Txt, Rect, Grid, Line, Layout } from '@motion-canvas/2d';
-import { all, sequence, waitFor } from '@motion-canvas/core/lib/flow';
-import { Vector2 } from '@motion-canvas/core/lib/types';
-import { createRef } from '@motion-canvas/core/lib/utils';
-import { createSignal, DEFAULT } from '@motion-canvas/core/lib/signals';
-import { CodeBlock, edit, insert, range } from '@motion-canvas/2d/lib/components/CodeBlock';
-
-const RED = '#ff6470';
-const GREEN = '#99C47A';
-const BLUE = '#68ABDF';
-const WHITE = '#FFFFFF';
-
-export default makeScene2D(function* (view) {
-
-  const table_layout =
-    <Layout
-      direction={'column'}
-      alignItems={'end'}
-      x={-1300}
-      layout />
-  table_layout.add(
-    <Txt
-      text={"stack"}
-      fontFamily={"Fira Mono"}
-      alignSelf={'start'}
-      fill={WHITE}
-      padding={10}
-    />)
-
-  var stack_refs = []
-  var line_refs = []
-
-  for (let i = 6; i >= 0; i--) {
-    const text_ref = createRef<Txt>();
-    const line_ref = createRef<Line>();
-    stack_refs.push(text_ref);
-    line_refs.push(line_ref);
-    table_layout.add(
-      <Rect layout direction={'row'}>
-        <Txt
-          text={i == 6 ? '...' : String(i)}
-          fontFamily={"Fira Mono"}
-          fontSize={35}
-          fill={'gray'}
-          paddingRight={30}
-          margin={10}
-        />
-        <Rect layout direction={'column'}>
-          <Code
-            ref={text_ref}
-            code={"⁉️"}
-            fontFamily={"Fira Mono"}
-            alignSelf={'center'}
-            fontSize={35}
-            fontWeight={500}
-            margin={15}
-          />
-          <Line
-            ref={line_ref}
-            stroke={'#777'}
-            lineWidth={5}
-            points={[[0, 0], [400, 0]]}
-          />
-        </Rect>
-      </Rect>
-
-    );
-  }
-  stack_refs.reverse();
-
-  const command_txt_ref = createRef<Txt>()
-
-  table_layout.add(
-    <Rect layout direction={'column'} alignSelf={'start'} minHeight={250}>
-      <Txt
-        text={"command:"}
-        fontFamily={"Fira Mono"}
-        fill={'#777'}
-        marginTop={100}
-      />
-      <Txt
-        ref={command_txt_ref}
-        text={""}
-        fontFamily={"Fira Mono"}
-        marginTop={10}
-        marginLeft={100}
-        fill={WHITE}
-      />
-    </Rect>)
-
-  view.add(table_layout)
-
-  const code_stack = `\
-#include <iostream>
-
-int main() {
-  int size = 2;
-  int* ptr = nullptr;
-  {
-    int array[size];  // 😱 Don't use C-style arrays!
-    array[0] = 42;
-    array[1] = 23;
-    ptr = array;
-    std::cout << "Before stack cleanup.\\n";
-    for (int i = 0; i < size; ++i) {
-      std::cout << ptr[i] << std::endl;
-    }
-  }
-  // 😱 Code below leads to undefined behavior!
-  std::cout << "After stack cleanup.\\n";
-  for (int i = 0; i < size; ++i) {
-    std::cout << ptr[i] << std::endl;
-  }
-  return 0;
-}`
-  const code_ref = createRef<Code>()
-
-  yield view.add(
-    <Code
-      ref={code_ref}
-      fontSize={35}
-      fontFamily={'Fira Mono'}
-      fontWeight={500}
-      offsetX={-1}
-      x={-200}
-    />);
-
-  const duration = 1.0
-
-  // Frame
-  yield* all(
-    code_ref().code(code_stack, duration),
-    waitFor(duration)
-  );
-
-  yield* all(
-    table_layout.x(-600, duration),
-    waitFor(3 * duration)
-  );
-
-  // Frame
-  yield* all(
-    stack_refs[0]().code(`size = 2`, duration),
-    code_ref().selection(lines(3), duration),
-    command_txt_ref().text('push(int)', duration / 3),
-    waitFor(3 * duration)
-  );
-
-  // Frame
-  yield* all(
-    stack_refs[1]().code(`ptr = nullptr`, duration),
-    code_ref().selection(lines(4), duration),
-    command_txt_ref().text('', duration / 3).to('push(int*)', duration / 3),
-    waitFor(3 * duration)
-  );
-
-  // Frame
-  yield* all(
-    sequence(0.1,
-      stack_refs[2]().code(`array[0] = ⁉️`, duration),
-      stack_refs[3]().code(`array[1] = ⁉️`, duration)),
-    command_txt_ref().text('', duration / 3).to('2 x push(int)', duration / 3),
-    code_ref().selection(lines(6), duration),
-    waitFor(3 * duration)
-  );
-
-  // Frame
-  yield* all(
-    stack_refs[2]().code(`array[0] = 42`, duration),
-    code_ref().selection(lines(7), duration),
-    command_txt_ref().text('', duration / 3),
-    waitFor(duration)
-  );
-
-  // Frame
-  yield* all(
-    stack_refs[3]().code(`array[1] = 23`, duration),
-    code_ref().selection(lines(7, 8), duration),
-    waitFor(3 * duration)
-  );
-
-  // Frame
-  yield* all(
-    stack_refs[1]().code(`ptr = &stack[2]`, duration),
-    code_ref().selection(lines(9), duration),
-    waitFor(3 * duration)
-  );
-
-  // Frame
-  yield* all(
-    code_ref().selection(lines(10, 13), duration),
-    waitFor(3 * duration)
-  );
-
-  // Frame
-  yield* all(
-    sequence(0.1,
-      stack_refs[3]().code('⁉️', duration),
-      stack_refs[2]().code('⁉️', duration)),
-    code_ref().selection(lines(14), duration),
-    command_txt_ref().text('', duration / 3).to('2 x pop()', duration / 3),
-    waitFor(3 * duration)
-  );
-
-  // Frame
-  yield* all(
-    code_ref().selection(lines(15, 19), duration),
-    command_txt_ref().text('', duration / 3),
-    waitFor(3 * duration)
-  );
-
-  // Frame
-  yield* all(
-    sequence(0.1,
-      stack_refs[1]().code('⁉️', duration),
-      stack_refs[0]().code('⁉️', duration)),
-    code_ref().selection(lines(21), duration),
-    command_txt_ref().text('', duration / 3).to('2 x pop()', duration / 3),
-    waitFor(3 * duration)
-  );
-
-  // Frame
-  yield* all(
-    code_ref().selection(DEFAULT, duration),
-    command_txt_ref().text('', duration / 3),
-    waitFor(3 * duration)
-  );
-
-  yield* waitFor(3.0);
-
-});
diff --git a/animation/memory_and_smart_pointers/src/scenes/stack_persistent.meta b/animation/memory_and_smart_pointers/src/scenes/stack_persistent.meta
deleted file mode 100644
index 8db8c16..0000000
--- a/animation/memory_and_smart_pointers/src/scenes/stack_persistent.meta
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-  "version": 0,
-  "timeEvents": [],
-  "seed": 183430437
-}
\ No newline at end of file
diff --git a/animation/memory_and_smart_pointers/src/scenes/stack_persistent.tsx b/animation/memory_and_smart_pointers/src/scenes/stack_persistent.tsx
deleted file mode 100644
index 7d2c4ff..0000000
--- a/animation/memory_and_smart_pointers/src/scenes/stack_persistent.tsx
+++ /dev/null
@@ -1,167 +0,0 @@
-import { Node, lines, word, makeScene2D, Code, Txt, Rect, Grid, Line, Layout } from '@motion-canvas/2d';
-import { all, sequence, waitFor } from '@motion-canvas/core/lib/flow';
-import { Vector2 } from '@motion-canvas/core/lib/types';
-import { createRef } from '@motion-canvas/core/lib/utils';
-import { createSignal, DEFAULT } from '@motion-canvas/core/lib/signals';
-import { CodeBlock, edit, insert, range } from '@motion-canvas/2d/lib/components/CodeBlock';
-
-const RED = '#ff6470';
-const GREEN = '#99C47A';
-const BLUE = '#68ABDF';
-const WHITE = '#FFFFFF';
-
-export default makeScene2D(function* (view) {
-
-
-  const table_layout =
-    <Layout
-      direction={'column'}
-      alignItems={'start'}
-      alignSelf={'end'}
-      offset={[-1, 1]}
-      y={320}
-      x={-210}
-      layout />
-
-  var rect_refs = []
-  for (let i = 0; i < 8; i++) {
-    const rect_ref = createRef<Txt>();
-    rect_refs.push(rect_ref);
-    const color = i == 4 ? RED : BLUE;
-    table_layout.add(
-      <Rect
-        ref={rect_ref}
-        width={400}
-        height={60}
-        fill={color}
-        opacity={0}
-        margin={10}
-      />)
-  }
-  rect_refs.reverse();
-  view.add(table_layout)
-
-  const duration = 1.0
-
-
-  const moved_rect = createRef<Txt>();
-  const line_scope = createRef<Line>();
-  const text_scope = createRef<Txt>();
-
-  view.add(
-    <Rect
-      ref={moved_rect}
-      width={400}
-      height={60}
-      x={rect_refs[0]().x() + 20}
-      y={rect_refs[0]().y() + 20}
-      fill={BLUE}
-      opacity={0}
-      margin={10}
-    />
-  )
-
-  view.add(
-    <Layout
-      x={-300}
-      y={-40}
-    >
-      <Txt
-        ref={text_scope}
-        fill={'#FFF'}
-        rotation={-90}
-        opacity={0}
-        x={-30}
-        y={210}
-      />
-      <Line
-        ref={line_scope}
-        stroke={'#aaa'}
-        lineWidth={10}
-        opacity={1}
-        points={[[20, 280], [20, 280]]}
-      />
-
-    </Layout>
-
-  )
-  yield* waitFor(duration);
-
-  yield* all(
-    text_scope().opacity(1, duration),
-    text_scope().text('scope', duration * 2),
-    line_scope().points([[20, 280], [20, -270]], duration * 3),
-    sequence(duration / 4,
-      ...rect_refs.map(rect => rect().opacity(1, duration / 2)),
-    ),
-    waitFor(4 * duration)
-  );
-
-  yield* all(
-    sequence(duration / 4,
-      ...rect_refs.reverse().slice(0, 4).map(rect => rect().opacity(0, duration / 2), 2),
-    ),
-    waitFor(2 * duration)
-  );
-
-  yield* all(
-    moved_rect().opacity(1, 0),
-    moved_rect().fill(RED, 0),
-    moved_rect().position(rect_refs[4]().position(), 0),
-    rect_refs[4]().opacity(0, 0)
-  );
-
-  yield* all(
-    moved_rect().x(rect_refs[1]().x() + 500, duration),
-    waitFor(2 * duration)
-  );
-
-  yield* all(
-    sequence(duration / 4,
-      ...rect_refs.slice(4, 7).map(rect => rect().opacity(0, duration / 2), 2),
-    ),
-    waitFor(2 * duration)
-  );
-
-  yield* all(
-    text_scope().opacity(0, duration),
-    text_scope().text('', duration),
-    line_scope().points([[20, 280], [20, 280]], duration),
-    moved_rect().position(rect_refs[6]().position(), duration),
-    waitFor(3 * duration)
-  );
-
-
-  yield* all(
-    moved_rect().opacity(0, 0),
-    text_scope().opacity(1, 0),
-    text_scope().text('scope', 0),
-    line_scope().points([[20, 280], [20, -270]], 0),
-    all(
-      ...rect_refs.map(rect => rect().opacity(1, 0)),
-    ),
-    waitFor(3 * duration)
-  );
-
-  yield* all(
-    all(
-      ...rect_refs.slice(0, 4).map(rect => rect().margin([10, 500], duration)),
-    ),
-    waitFor(2 * duration)
-  );
-
-  yield* all(
-    rect_refs[4]().opacity(0, duration),
-    waitFor(2 * duration)
-  );
-
-  yield* all(
-    rect_refs[4]().height(0, duration),
-    rect_refs[4]().margin(0, duration),
-    all(
-      ...rect_refs.slice(0, 4).map(rect => rect().margin(10, duration / 2)),
-    ),
-    line_scope().points([[20, 280], [20, -200]], duration),
-    waitFor(5 * duration)
-  );
-});
diff --git a/animation/memory_and_smart_pointers/src/scenes/stealing.meta b/animation/memory_and_smart_pointers/src/scenes/stealing.meta
deleted file mode 100644
index 1547019..0000000
--- a/animation/memory_and_smart_pointers/src/scenes/stealing.meta
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-  "version": 0,
-  "timeEvents": [],
-  "seed": 1249695661
-}
\ No newline at end of file
diff --git a/animation/memory_and_smart_pointers/src/scenes/stealing.tsx b/animation/memory_and_smart_pointers/src/scenes/stealing.tsx
deleted file mode 100644
index eb43caa..0000000
--- a/animation/memory_and_smart_pointers/src/scenes/stealing.tsx
+++ /dev/null
@@ -1,140 +0,0 @@
-import {makeScene2D} from '@motion-canvas/2d/lib/scenes';
-import {Node, Txt, Rect, Grid, Line} from '@motion-canvas/2d/lib/components';
-import {all, waitFor} from '@motion-canvas/core/lib/flow';
-import {Vector2} from '@motion-canvas/core/lib/types';
-import {createRef} from '@motion-canvas/core/lib/utils';
-import {createSignal} from '@motion-canvas/core/lib/signals';
-import {CodeBlock, edit, insert} from '@motion-canvas/2d/lib/components/CodeBlock';
-
-const RED = '#ff6470';
-const GREEN = '#99C47A';
-const BLUE = '#68ABDF';
-const WHITE = '#FFFFFF';
-
-export default makeScene2D(function* (view) {
-  const gray_line_ref = createRef<Line>();
-  const gray_code_ref = createRef<CodeBlock>();
-  const grid_ref = createRef<Grid>();
-  const data_rect_ref = createRef<Rect>();
-  const a_ref = createRef<CodeBlock>();
-  const b_ref = createRef<CodeBlock>();
-  const line_1 = createRef<Line>();
-  const line_2 = createRef<Line>();
-
-  const data = `
-  10010011`
-
-  const object_code = `Data* a;`
-  const member_object_code = `Data* b;`
-
-  view.add(
-    <Node>
-      <Grid
-        ref = {grid_ref}
-        y = {200}
-        spacing={100}
-        stroke={'#444'}
-        lineWidth={5}
-        opacity={0}
-        cache
-      />
-      <Rect
-        x = {0}
-        y = {250}
-        ref = {data_rect_ref}
-        fill = {BLUE}
-        lineWidth={4}
-        width = {800}
-        height = {100}
-        opacity = {0.0}
-      />
-      <CodeBlock
-          ref={gray_code_ref}
-          fontSize={40}
-          code = {"0x42424242"}
-          x = {-350}
-          y = {430}
-          opacity = {0.0}
-      />
-      <Line
-          ref={gray_line_ref}
-          stroke={'#777'}
-          lineWidth={5}
-          endArrow
-          arrowSize={15}
-          points={[[-350, 400], [-350, 310]]}
-          opacity = {0.0}
-      />
-
-      <Node x = {-400} y = {-300}>
-        <CodeBlock
-          ref = {a_ref}
-          fontSize={80}
-        />
-        <Line
-          ref = {line_1}
-          lineWidth={10}
-          stroke={BLUE}
-          arrowSize={20}
-          endArrow
-          points={[
-            [30, 50],
-            [30, 490],
-          ]}
-          end={0}
-        />,
-      </Node>
-      <Node x = {500} y = {-300}>
-        <CodeBlock
-          ref = {b_ref}
-          fontSize={80}
-        />
-        <Line
-          ref = {line_2}
-          lineWidth={10}
-          stroke={BLUE}
-          endArrow
-          arrowSize={20}
-          points={[
-            [0, 50],
-            [0, 200],
-            [-830, 200],
-            [-830, 490],
-          ]}
-          end={0}
-        />,
-      </Node>
-    </Node>,
-  );
-
-  yield * waitFor(2.0);
-  yield * a_ref().edit(1.0, false)`${insert(object_code)}`;
-  yield * all(
-    grid_ref().height(0, 0.0).to(250, 0.5),
-    grid_ref().width(0, 0.0).to(1920, 0.5),
-    grid_ref().opacity(1.0, 0.1),
-  );
-  yield * all(
-    data_rect_ref().opacity(0.5, 1.0),
-    line_1().end(1, 1.0),
-    gray_line_ref().opacity(1.0, 0.5),
-    gray_code_ref().opacity(1.0, 0.5),
-  );
-  yield * b_ref().edit(1.0, false)`${insert(member_object_code)}`;
-  yield * waitFor(1.0);
-  yield * data_rect_ref().scale(1.2, 1.0);
-  yield * data_rect_ref().position.x(-20, 0.2).to(20, 0.2).to(-20, 0.2).to(20, 0.2).to(0, 0.2);
-  yield * data_rect_ref().scale(1.0, 0.5);
-  yield * waitFor(1.0);
-  yield * line_2().end(1, 1.5);
-  yield * waitFor(1.0);
-  yield * all(
-    data_rect_ref().opacity(0.5, 1.0),
-    line_1().arrowSize(0, 0.5),
-    line_1().end(0, 1.0),
-    a_ref().edit(1.5, false)`Data* a${insert(' = nullptr')};`,
-  );
-
-  yield * waitFor(3.0);
-
-});
diff --git a/animation/memory_and_smart_pointers/tsconfig.json b/animation/memory_and_smart_pointers/tsconfig.json
deleted file mode 100644
index 789b7d1..0000000
--- a/animation/memory_and_smart_pointers/tsconfig.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-  "extends": "@motion-canvas/2d/tsconfig.project.json",
-  "compilerOptions": {
-    "baseUrl": "src"
-  },
-  "include": ["src"]
-}
diff --git a/animation/memory_and_smart_pointers/videos/travolta.mp4 b/animation/memory_and_smart_pointers/videos/travolta.mp4
deleted file mode 100644
index 9d6b4ee..0000000
--- a/animation/memory_and_smart_pointers/videos/travolta.mp4
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:5b300b8896b6062071238fde2ea43584797b3bbc93280e331b219a86380b11f1
-size 1181848
diff --git a/animation/memory_and_smart_pointers/vite.config.ts b/animation/memory_and_smart_pointers/vite.config.ts
deleted file mode 100644
index 4e353f3..0000000
--- a/animation/memory_and_smart_pointers/vite.config.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import { defineConfig } from 'vite';
-import ffmpeg from '@motion-canvas/ffmpeg';
-import motionCanvas from '@motion-canvas/vite-plugin';
-
-export default defineConfig({
-  plugins: [motionCanvas(), ffmpeg()],
-
-});
diff --git a/animation/object_lifecycle/.gitignore b/animation/object_lifecycle/.gitignore
deleted file mode 100644
index 829b1c7..0000000
--- a/animation/object_lifecycle/.gitignore
+++ /dev/null
@@ -1,15 +0,0 @@
-# Generated files
-node_modules
-output
-dist
-
-# Editor directories and files
-.vscode/*
-!.vscode/extensions.json
-.idea
-.DS_Store
-*.suo
-*.ntvs*
-*.njsproj
-*.sln
-*.sw?
diff --git a/animation/object_lifecycle/package-lock.json b/animation/object_lifecycle/package-lock.json
deleted file mode 100644
index 8fa3de2..0000000
--- a/animation/object_lifecycle/package-lock.json
+++ /dev/null
@@ -1,796 +0,0 @@
-{
-  "name": "object_lifecycle",
-  "version": "0.0.0",
-  "lockfileVersion": 3,
-  "requires": true,
-  "packages": {
-    "": {
-      "name": "object_lifecycle",
-      "version": "0.0.0",
-      "dependencies": {
-        "@motion-canvas/2d": "^3.3.4",
-        "@motion-canvas/core": "^3.3.4"
-      },
-      "devDependencies": {
-        "@motion-canvas/ui": "^3.3.4",
-        "@motion-canvas/vite-plugin": "^3.3.0",
-        "typescript": "^4.9.5",
-        "vite": "^4.1.4"
-      }
-    },
-    "node_modules/@esbuild/android-arm": {
-      "version": "0.17.12",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.12.tgz",
-      "integrity": "sha512-E/sgkvwoIfj4aMAPL2e35VnUJspzVYl7+M1B2cqeubdBhADV4uPon0KCc8p2G+LqSJ6i8ocYPCqY3A4GGq0zkQ==",
-      "cpu": [
-        "arm"
-      ],
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/android-arm64": {
-      "version": "0.17.12",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.12.tgz",
-      "integrity": "sha512-WQ9p5oiXXYJ33F2EkE3r0FRDFVpEdcDiwNX3u7Xaibxfx6vQE0Sb8ytrfQsA5WO6kDn6mDfKLh6KrPBjvkk7xA==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/android-x64": {
-      "version": "0.17.12",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.12.tgz",
-      "integrity": "sha512-m4OsaCr5gT+se25rFPHKQXARMyAehHTQAz4XX1Vk3d27VtqiX0ALMBPoXZsGaB6JYryCLfgGwUslMqTfqeLU0w==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/darwin-arm64": {
-      "version": "0.17.12",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.12.tgz",
-      "integrity": "sha512-O3GCZghRIx+RAN0NDPhyyhRgwa19MoKlzGonIb5hgTj78krqp9XZbYCvFr9N1eUxg0ZQEpiiZ4QvsOQwBpP+lg==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/darwin-x64": {
-      "version": "0.17.12",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.12.tgz",
-      "integrity": "sha512-5D48jM3tW27h1qjaD9UNRuN+4v0zvksqZSPZqeSWggfMlsVdAhH3pwSfQIFJwcs9QJ9BRibPS4ViZgs3d2wsCA==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/freebsd-arm64": {
-      "version": "0.17.12",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.12.tgz",
-      "integrity": "sha512-OWvHzmLNTdF1erSvrfoEBGlN94IE6vCEaGEkEH29uo/VoONqPnoDFfShi41Ew+yKimx4vrmmAJEGNoyyP+OgOQ==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "freebsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/freebsd-x64": {
-      "version": "0.17.12",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.12.tgz",
-      "integrity": "sha512-A0Xg5CZv8MU9xh4a+7NUpi5VHBKh1RaGJKqjxe4KG87X+mTjDE6ZvlJqpWoeJxgfXHT7IMP9tDFu7IZ03OtJAw==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "freebsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-arm": {
-      "version": "0.17.12",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.12.tgz",
-      "integrity": "sha512-WsHyJ7b7vzHdJ1fv67Yf++2dz3D726oO3QCu8iNYik4fb5YuuReOI9OtA+n7Mk0xyQivNTPbl181s+5oZ38gyA==",
-      "cpu": [
-        "arm"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-arm64": {
-      "version": "0.17.12",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.12.tgz",
-      "integrity": "sha512-cK3AjkEc+8v8YG02hYLQIQlOznW+v9N+OI9BAFuyqkfQFR+DnDLhEM5N8QRxAUz99cJTo1rLNXqRrvY15gbQUg==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-ia32": {
-      "version": "0.17.12",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.12.tgz",
-      "integrity": "sha512-jdOBXJqcgHlah/nYHnj3Hrnl9l63RjtQ4vn9+bohjQPI2QafASB5MtHAoEv0JQHVb/xYQTFOeuHnNYE1zF7tYw==",
-      "cpu": [
-        "ia32"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-loong64": {
-      "version": "0.17.12",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.12.tgz",
-      "integrity": "sha512-GTOEtj8h9qPKXCyiBBnHconSCV9LwFyx/gv3Phw0pa25qPYjVuuGZ4Dk14bGCfGX3qKF0+ceeQvwmtI+aYBbVA==",
-      "cpu": [
-        "loong64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-mips64el": {
-      "version": "0.17.12",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.12.tgz",
-      "integrity": "sha512-o8CIhfBwKcxmEENOH9RwmUejs5jFiNoDw7YgS0EJTF6kgPgcqLFjgoc5kDey5cMHRVCIWc6kK2ShUePOcc7RbA==",
-      "cpu": [
-        "mips64el"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-ppc64": {
-      "version": "0.17.12",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.12.tgz",
-      "integrity": "sha512-biMLH6NR/GR4z+ap0oJYb877LdBpGac8KfZoEnDiBKd7MD/xt8eaw1SFfYRUeMVx519kVkAOL2GExdFmYnZx3A==",
-      "cpu": [
-        "ppc64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-riscv64": {
-      "version": "0.17.12",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.12.tgz",
-      "integrity": "sha512-jkphYUiO38wZGeWlfIBMB72auOllNA2sLfiZPGDtOBb1ELN8lmqBrlMiucgL8awBw1zBXN69PmZM6g4yTX84TA==",
-      "cpu": [
-        "riscv64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-s390x": {
-      "version": "0.17.12",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.12.tgz",
-      "integrity": "sha512-j3ucLdeY9HBcvODhCY4b+Ds3hWGO8t+SAidtmWu/ukfLLG/oYDMaA+dnugTVAg5fnUOGNbIYL9TOjhWgQB8W5g==",
-      "cpu": [
-        "s390x"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-x64": {
-      "version": "0.17.12",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.12.tgz",
-      "integrity": "sha512-uo5JL3cgaEGotaqSaJdRfFNSCUJOIliKLnDGWaVCgIKkHxwhYMm95pfMbWZ9l7GeW9kDg0tSxcy9NYdEtjwwmA==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/netbsd-x64": {
-      "version": "0.17.12",
-      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.12.tgz",
-      "integrity": "sha512-DNdoRg8JX+gGsbqt2gPgkgb00mqOgOO27KnrWZtdABl6yWTST30aibGJ6geBq3WM2TIeW6COs5AScnC7GwtGPg==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "netbsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/openbsd-x64": {
-      "version": "0.17.12",
-      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.12.tgz",
-      "integrity": "sha512-aVsENlr7B64w8I1lhHShND5o8cW6sB9n9MUtLumFlPhG3elhNWtE7M1TFpj3m7lT3sKQUMkGFjTQBrvDDO1YWA==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "openbsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/sunos-x64": {
-      "version": "0.17.12",
-      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.12.tgz",
-      "integrity": "sha512-qbHGVQdKSwi0JQJuZznS4SyY27tYXYF0mrgthbxXrZI3AHKuRvU+Eqbg/F0rmLDpW/jkIZBlCO1XfHUBMNJ1pg==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "sunos"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/win32-arm64": {
-      "version": "0.17.12",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.12.tgz",
-      "integrity": "sha512-zsCp8Ql+96xXTVTmm6ffvoTSZSV2B/LzzkUXAY33F/76EajNw1m+jZ9zPfNJlJ3Rh4EzOszNDHsmG/fZOhtqDg==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/win32-ia32": {
-      "version": "0.17.12",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.12.tgz",
-      "integrity": "sha512-FfrFjR4id7wcFYOdqbDfDET3tjxCozUgbqdkOABsSFzoZGFC92UK7mg4JKRc/B3NNEf1s2WHxJ7VfTdVDPN3ng==",
-      "cpu": [
-        "ia32"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/win32-x64": {
-      "version": "0.17.12",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.12.tgz",
-      "integrity": "sha512-JOOxw49BVZx2/5tW3FqkdjSD/5gXYeVGPDcB0lvap0gLQshkh1Nyel1QazC+wNxus3xPlsYAgqU1BUmrmCvWtw==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@motion-canvas/2d": {
-      "version": "3.3.4",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/2d/-/2d-3.3.4.tgz",
-      "integrity": "sha512-kOC8rBJUhkhpf8Ax6o7oBs2AicfALji2I+NX6tO84kcQGk547DaSARSRvip8mmbG2NIsLUL5dhSAHthBCGz8tA==",
-      "dependencies": {
-        "@motion-canvas/core": "^3.3.4",
-        "code-fns": "^0.8.2",
-        "mathjax-full": "^3.2.2"
-      }
-    },
-    "node_modules/@motion-canvas/core": {
-      "version": "3.3.4",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/core/-/core-3.3.4.tgz",
-      "integrity": "sha512-irRlacBRbXgJjsPObZLzicw5b8zXHDrjjxskH7paaBJbwc29M5LkyGOTXNZw3kl+ofPiHnLR2ZN+xMeDg5GtVw==",
-      "dependencies": {
-        "@types/chroma-js": "^2.1.4",
-        "chroma-js": "^2.4.2"
-      },
-      "peerDependencies": {
-        "vite": "^4.1.4"
-      }
-    },
-    "node_modules/@motion-canvas/ui": {
-      "version": "3.3.4",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/ui/-/ui-3.3.4.tgz",
-      "integrity": "sha512-6LvO9shr87eIYgTEx9Ex+DPqZf6vjFYqMt2kFZDeXAPrRNlnNXSyXhGa9YE3HRYr1SG4p/F3kqNpEVyFCuEIrA==",
-      "dev": true,
-      "dependencies": {
-        "@motion-canvas/core": "^3.3.4"
-      }
-    },
-    "node_modules/@motion-canvas/vite-plugin": {
-      "version": "3.3.0",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/vite-plugin/-/vite-plugin-3.3.0.tgz",
-      "integrity": "sha512-l+wWs01xM7U2ERrF/ipYZAOIu5OpGYA7GHAPdUo/rZJn7VJQ3X/K2c9FV80Yot80X2IpAn2ilUjKOyc4u1Gy+g==",
-      "dev": true,
-      "dependencies": {
-        "follow-redirects": "^1.15.2",
-        "mime-types": "^2.1.35"
-      },
-      "peerDependencies": {
-        "vite": "4.x"
-      }
-    },
-    "node_modules/@types/chroma-js": {
-      "version": "2.4.0",
-      "resolved": "https://registry.npmjs.org/@types/chroma-js/-/chroma-js-2.4.0.tgz",
-      "integrity": "sha512-JklMxityrwjBTjGY2anH8JaTx3yjRU3/sEHSblLH1ba5lqcSh1LnImXJZO5peJfXyqKYWjHTGy4s5Wz++hARrw=="
-    },
-    "node_modules/@types/hast": {
-      "version": "2.3.4",
-      "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.4.tgz",
-      "integrity": "sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==",
-      "dependencies": {
-        "@types/unist": "*"
-      }
-    },
-    "node_modules/@types/unist": {
-      "version": "2.0.6",
-      "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz",
-      "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ=="
-    },
-    "node_modules/@wooorm/starry-night": {
-      "version": "1.6.0",
-      "resolved": "https://registry.npmjs.org/@wooorm/starry-night/-/starry-night-1.6.0.tgz",
-      "integrity": "sha512-Ue7RCm+lAzJY8w7y4AphweIJxoRPdP63jRp32Qv0zPGxKE3rgg5D0AIr3iDHUtiSsmJrXVd4LOupd0/aC+cjMw==",
-      "dependencies": {
-        "@types/hast": "^2.0.0",
-        "import-meta-resolve": "^2.0.0",
-        "vscode-oniguruma": "^1.0.0",
-        "vscode-textmate": "^8.0.0"
-      },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/wooorm"
-      }
-    },
-    "node_modules/chroma-js": {
-      "version": "2.4.2",
-      "resolved": "https://registry.npmjs.org/chroma-js/-/chroma-js-2.4.2.tgz",
-      "integrity": "sha512-U9eDw6+wt7V8z5NncY2jJfZa+hUH8XEj8FQHgFJTrUFnJfXYf4Ml4adI2vXZOjqRDpFWtYVWypDfZwnJ+HIR4A=="
-    },
-    "node_modules/code-fns": {
-      "version": "0.8.2",
-      "resolved": "https://registry.npmjs.org/code-fns/-/code-fns-0.8.2.tgz",
-      "integrity": "sha512-3VVeq3cnWxWiWKFLsVo+XWsOXBSW2gAx2uv0ViETLNmNuygEPHlCeDAv/Zy7xXqPgXtgLZyvIJZmx+ojTgOIGA==",
-      "dependencies": {
-        "@wooorm/starry-night": "^1.2.0"
-      }
-    },
-    "node_modules/commander": {
-      "version": "9.2.0",
-      "resolved": "https://registry.npmjs.org/commander/-/commander-9.2.0.tgz",
-      "integrity": "sha512-e2i4wANQiSXgnrBlIatyHtP1odfUp0BbV5Y5nEGbxtIrStkEOAAzCUirvLBNXHLr7kwLvJl6V+4V3XV9x7Wd9w==",
-      "engines": {
-        "node": "^12.20.0 || >=14"
-      }
-    },
-    "node_modules/esbuild": {
-      "version": "0.17.12",
-      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.12.tgz",
-      "integrity": "sha512-bX/zHl7Gn2CpQwcMtRogTTBf9l1nl+H6R8nUbjk+RuKqAE3+8FDulLA+pHvX7aA7Xe07Iwa+CWvy9I8Y2qqPKQ==",
-      "hasInstallScript": true,
-      "bin": {
-        "esbuild": "bin/esbuild"
-      },
-      "engines": {
-        "node": ">=12"
-      },
-      "optionalDependencies": {
-        "@esbuild/android-arm": "0.17.12",
-        "@esbuild/android-arm64": "0.17.12",
-        "@esbuild/android-x64": "0.17.12",
-        "@esbuild/darwin-arm64": "0.17.12",
-        "@esbuild/darwin-x64": "0.17.12",
-        "@esbuild/freebsd-arm64": "0.17.12",
-        "@esbuild/freebsd-x64": "0.17.12",
-        "@esbuild/linux-arm": "0.17.12",
-        "@esbuild/linux-arm64": "0.17.12",
-        "@esbuild/linux-ia32": "0.17.12",
-        "@esbuild/linux-loong64": "0.17.12",
-        "@esbuild/linux-mips64el": "0.17.12",
-        "@esbuild/linux-ppc64": "0.17.12",
-        "@esbuild/linux-riscv64": "0.17.12",
-        "@esbuild/linux-s390x": "0.17.12",
-        "@esbuild/linux-x64": "0.17.12",
-        "@esbuild/netbsd-x64": "0.17.12",
-        "@esbuild/openbsd-x64": "0.17.12",
-        "@esbuild/sunos-x64": "0.17.12",
-        "@esbuild/win32-arm64": "0.17.12",
-        "@esbuild/win32-ia32": "0.17.12",
-        "@esbuild/win32-x64": "0.17.12"
-      }
-    },
-    "node_modules/esm": {
-      "version": "3.2.25",
-      "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz",
-      "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==",
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/follow-redirects": {
-      "version": "1.15.2",
-      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
-      "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "individual",
-          "url": "https://github.com/sponsors/RubenVerborgh"
-        }
-      ],
-      "engines": {
-        "node": ">=4.0"
-      },
-      "peerDependenciesMeta": {
-        "debug": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/fsevents": {
-      "version": "2.3.2",
-      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
-      "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
-      }
-    },
-    "node_modules/function-bind": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
-      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
-    },
-    "node_modules/has": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
-      "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
-      "dependencies": {
-        "function-bind": "^1.1.1"
-      },
-      "engines": {
-        "node": ">= 0.4.0"
-      }
-    },
-    "node_modules/import-meta-resolve": {
-      "version": "2.2.2",
-      "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-2.2.2.tgz",
-      "integrity": "sha512-f8KcQ1D80V7RnqVm+/lirO9zkOxjGxhaTC1IPrBGd3MEfNgmNG67tSUO9gTi2F3Blr2Az6g1vocaxzkVnWl9MA==",
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/wooorm"
-      }
-    },
-    "node_modules/is-core-module": {
-      "version": "2.11.0",
-      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz",
-      "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==",
-      "dependencies": {
-        "has": "^1.0.3"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/mathjax-full": {
-      "version": "3.2.2",
-      "resolved": "https://registry.npmjs.org/mathjax-full/-/mathjax-full-3.2.2.tgz",
-      "integrity": "sha512-+LfG9Fik+OuI8SLwsiR02IVdjcnRCy5MufYLi0C3TdMT56L/pjB0alMVGgoWJF8pN9Rc7FESycZB9BMNWIid5w==",
-      "dependencies": {
-        "esm": "^3.2.25",
-        "mhchemparser": "^4.1.0",
-        "mj-context-menu": "^0.6.1",
-        "speech-rule-engine": "^4.0.6"
-      }
-    },
-    "node_modules/mhchemparser": {
-      "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/mhchemparser/-/mhchemparser-4.1.1.tgz",
-      "integrity": "sha512-R75CUN6O6e1t8bgailrF1qPq+HhVeFTM3XQ0uzI+mXTybmphy3b6h4NbLOYhemViQ3lUs+6CKRkC3Ws1TlYREA=="
-    },
-    "node_modules/mime-db": {
-      "version": "1.52.0",
-      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
-      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/mime-types": {
-      "version": "2.1.35",
-      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
-      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
-      "dev": true,
-      "dependencies": {
-        "mime-db": "1.52.0"
-      },
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/mj-context-menu": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/mj-context-menu/-/mj-context-menu-0.6.1.tgz",
-      "integrity": "sha512-7NO5s6n10TIV96d4g2uDpG7ZDpIhMh0QNfGdJw/W47JswFcosz457wqz/b5sAKvl12sxINGFCn80NZHKwxQEXA=="
-    },
-    "node_modules/nanoid": {
-      "version": "3.3.4",
-      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
-      "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==",
-      "bin": {
-        "nanoid": "bin/nanoid.cjs"
-      },
-      "engines": {
-        "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
-      }
-    },
-    "node_modules/path-parse": {
-      "version": "1.0.7",
-      "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
-      "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
-    },
-    "node_modules/picocolors": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
-      "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
-    },
-    "node_modules/postcss": {
-      "version": "8.4.21",
-      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz",
-      "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==",
-      "funding": [
-        {
-          "type": "opencollective",
-          "url": "https://opencollective.com/postcss/"
-        },
-        {
-          "type": "tidelift",
-          "url": "https://tidelift.com/funding/github/npm/postcss"
-        }
-      ],
-      "dependencies": {
-        "nanoid": "^3.3.4",
-        "picocolors": "^1.0.0",
-        "source-map-js": "^1.0.2"
-      },
-      "engines": {
-        "node": "^10 || ^12 || >=14"
-      }
-    },
-    "node_modules/resolve": {
-      "version": "1.22.1",
-      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
-      "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
-      "dependencies": {
-        "is-core-module": "^2.9.0",
-        "path-parse": "^1.0.7",
-        "supports-preserve-symlinks-flag": "^1.0.0"
-      },
-      "bin": {
-        "resolve": "bin/resolve"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/rollup": {
-      "version": "3.19.1",
-      "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.19.1.tgz",
-      "integrity": "sha512-lAbrdN7neYCg/8WaoWn/ckzCtz+jr70GFfYdlf50OF7387HTg+wiuiqJRFYawwSPpqfqDNYqK7smY/ks2iAudg==",
-      "bin": {
-        "rollup": "dist/bin/rollup"
-      },
-      "engines": {
-        "node": ">=14.18.0",
-        "npm": ">=8.0.0"
-      },
-      "optionalDependencies": {
-        "fsevents": "~2.3.2"
-      }
-    },
-    "node_modules/source-map-js": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
-      "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/speech-rule-engine": {
-      "version": "4.0.7",
-      "resolved": "https://registry.npmjs.org/speech-rule-engine/-/speech-rule-engine-4.0.7.tgz",
-      "integrity": "sha512-sJrL3/wHzNwJRLBdf6CjJWIlxC04iYKkyXvYSVsWVOiC2DSkHmxsqOhEeMsBA9XK+CHuNcsdkbFDnoUfAsmp9g==",
-      "dependencies": {
-        "commander": "9.2.0",
-        "wicked-good-xpath": "1.3.0",
-        "xmldom-sre": "0.1.31"
-      },
-      "bin": {
-        "sre": "bin/sre"
-      }
-    },
-    "node_modules/supports-preserve-symlinks-flag": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
-      "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/typescript": {
-      "version": "4.9.5",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
-      "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
-      "dev": true,
-      "bin": {
-        "tsc": "bin/tsc",
-        "tsserver": "bin/tsserver"
-      },
-      "engines": {
-        "node": ">=4.2.0"
-      }
-    },
-    "node_modules/vite": {
-      "version": "4.2.0",
-      "resolved": "https://registry.npmjs.org/vite/-/vite-4.2.0.tgz",
-      "integrity": "sha512-AbDTyzzwuKoRtMIRLGNxhLRuv1FpRgdIw+1y6AQG73Q5+vtecmvzKo/yk8X/vrHDpETRTx01ABijqUHIzBXi0g==",
-      "dependencies": {
-        "esbuild": "^0.17.5",
-        "postcss": "^8.4.21",
-        "resolve": "^1.22.1",
-        "rollup": "^3.18.0"
-      },
-      "bin": {
-        "vite": "bin/vite.js"
-      },
-      "engines": {
-        "node": "^14.18.0 || >=16.0.0"
-      },
-      "optionalDependencies": {
-        "fsevents": "~2.3.2"
-      },
-      "peerDependencies": {
-        "@types/node": ">= 14",
-        "less": "*",
-        "sass": "*",
-        "stylus": "*",
-        "sugarss": "*",
-        "terser": "^5.4.0"
-      },
-      "peerDependenciesMeta": {
-        "@types/node": {
-          "optional": true
-        },
-        "less": {
-          "optional": true
-        },
-        "sass": {
-          "optional": true
-        },
-        "stylus": {
-          "optional": true
-        },
-        "sugarss": {
-          "optional": true
-        },
-        "terser": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/vscode-oniguruma": {
-      "version": "1.7.0",
-      "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz",
-      "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA=="
-    },
-    "node_modules/vscode-textmate": {
-      "version": "8.0.0",
-      "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-8.0.0.tgz",
-      "integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg=="
-    },
-    "node_modules/wicked-good-xpath": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/wicked-good-xpath/-/wicked-good-xpath-1.3.0.tgz",
-      "integrity": "sha512-Gd9+TUn5nXdwj/hFsPVx5cuHHiF5Bwuc30jZ4+ronF1qHK5O7HD0sgmXWSEgwKquT3ClLoKPVbO6qGwVwLzvAw=="
-    },
-    "node_modules/xmldom-sre": {
-      "version": "0.1.31",
-      "resolved": "https://registry.npmjs.org/xmldom-sre/-/xmldom-sre-0.1.31.tgz",
-      "integrity": "sha512-f9s+fUkX04BxQf+7mMWAp5zk61pciie+fFLC9hX9UVvCeJQfNHRHXpeo5MPcR0EUf57PYLdt+ZO4f3Ipk2oZUw==",
-      "engines": {
-        "node": ">=0.1"
-      }
-    }
-  }
-}
diff --git a/animation/object_lifecycle/package.json b/animation/object_lifecycle/package.json
deleted file mode 100644
index ce760f7..0000000
--- a/animation/object_lifecycle/package.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "name": "object_lifecycle",
-  "private": true,
-  "version": "0.0.0",
-  "scripts": {
-    "serve": "vite",
-    "build": "tsc && vite build"
-  },
-  "dependencies": {
-    "@motion-canvas/core": "^3.3.4",
-    "@motion-canvas/2d": "^3.3.4"
-  },
-  "devDependencies": {
-    "@motion-canvas/ui": "^3.3.4",
-    "@motion-canvas/vite-plugin": "^3.3.0",
-    "typescript": "^4.9.5",
-    "vite": "^4.1.4"
-  }
-}
\ No newline at end of file
diff --git a/animation/object_lifecycle/src/motion-canvas.d.ts b/animation/object_lifecycle/src/motion-canvas.d.ts
deleted file mode 100644
index 067c6a4..0000000
--- a/animation/object_lifecycle/src/motion-canvas.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-/// <reference types="@motion-canvas/core/project" />
diff --git a/animation/object_lifecycle/src/project.meta b/animation/object_lifecycle/src/project.meta
deleted file mode 100644
index 7177929..0000000
--- a/animation/object_lifecycle/src/project.meta
+++ /dev/null
@@ -1,27 +0,0 @@
-{
-  "version": 0,
-  "shared": {
-    "background": "rgb(20,20,20)",
-    "range": [
-      0,
-      null
-    ],
-    "size": {
-      "x": 1920,
-      "y": 1080
-    },
-    "audioOffset": 0
-  },
-  "preview": {
-    "fps": 30,
-    "resolutionScale": 1
-  },
-  "rendering": {
-    "fps": 30,
-    "resolutionScale": 2,
-    "colorSpace": "srgb",
-    "fileType": "image/png",
-    "quality": 1,
-    "groupByScene": false
-  }
-}
\ No newline at end of file
diff --git a/animation/object_lifecycle/src/project.ts b/animation/object_lifecycle/src/project.ts
deleted file mode 100644
index d28c5f9..0000000
--- a/animation/object_lifecycle/src/project.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import {makeProject} from '@motion-canvas/core';
-
-import cat from './scenes/cat?scene';
-
-export default makeProject({
-  scenes: [cat],
-});
diff --git a/animation/object_lifecycle/src/scenes/cat.meta b/animation/object_lifecycle/src/scenes/cat.meta
deleted file mode 100644
index c8d0a82..0000000
--- a/animation/object_lifecycle/src/scenes/cat.meta
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-  "version": 0,
-  "timeEvents": [],
-  "seed": 3048189825
-}
\ No newline at end of file
diff --git a/animation/object_lifecycle/src/scenes/cat.tsx b/animation/object_lifecycle/src/scenes/cat.tsx
deleted file mode 100644
index aeed179..0000000
--- a/animation/object_lifecycle/src/scenes/cat.tsx
+++ /dev/null
@@ -1,261 +0,0 @@
-import {makeScene2D} from '@motion-canvas/2d/lib/scenes';
-import {createRef, useDuration} from '@motion-canvas/core/lib/utils';
-import {
-  CodeBlock,
-  edit,
-  insert,
-  lines,
-  word,
-  remove,
-  CodeModification,
-} from '@motion-canvas/2d/lib/components/CodeBlock';
-import {all, waitFor, waitUntil} from '@motion-canvas/core/lib/flow';
-import { DEFAULT } from '@motion-canvas/core/lib/signals';
-
-export default makeScene2D(function* (view) {
-  const codeRef = createRef<CodeBlock>();
-
-  yield view.add(<CodeBlock
-    ref={codeRef}
-    language="cpp"
-    fontSize={40}
-  />);
-
-
-  // const code_split = code.split(/\r?\n/);
-  const duration = 1.5
-
-  const store_one = (...args: [TemplateStringsArray, any]) => args;
-  const store_two = (...args: [TemplateStringsArray, any, any, any]) => args;
-
-  const default_code = (tag: any) => store_one`
-  class Foo {
-  public:
-    ${tag}
-  };`
-
-  const default_constructor_stupid = `Foo() {}  // Default constructor`
-  const default_constructor_better =
-  `// Even better default constructor
-  Foo() = default;`
-
-
-  const code_cat = (def:any, explicit: any, main: any) => store_two`
-  constexpr int kDefaultNumberOfLives = 9;
-
-  class Cat {
-  public:${def}
-    ${explicit}Cat(int happiness)
-      : happiness_{happiness} {}
-
-    Cat(int number_of_lives, int happiness)
-      : number_of_lives_{number_of_lives}, happiness_{happiness} {}
-
-  private:
-    int number_of_lives_{kDefaultNumberOfLives};
-    int happiness_{};
-  };
-
-  ${main}
-  `
-
-  const code_cat_destructor = (destructor: any) => store_one`
-  class Cat {
-  public:
-    explicit Cat(int happiness)
-        : happiness_{happiness} {}
-    ${destructor}
-  private:
-    int happiness_{};
-  };
-
-  int main() { const Cat cat{9}; }
-  `
-
-  const cat_destructor = `
-  ~Cat() {
-    // Nothing to do here, so not really needed...
-  }
-  `
-
-  const cat_default = `
-    Cat() = default;
-  `
-
-  const cat_main = `
-  int main() {
-    const Cat cat_1{42};
-    const Cat cat_2{9, 100};
-    return 0;
-  }`
-
-  const foo_main = `
-  void Foo(const Cat &cat) {}
-
-  int main() { Foo(42); }`
-
-  const foo_main_compiles = `
-  void Foo(const Cat &cat) {}
-
-  int main() { Foo(42); }  // ???!!! Surprisingly compiles!`
-
-  const foo_main_does_not_compile = `
-  void Foo(const Cat &cat) {}
-
-  int main() { Foo(42); }  // ✅ Does not compile anymore!`
-
-  const cat_default_main = `
-  int main()
-    Cat cat{}; // ❌  Won't compile when custom constructors present
-    return 0;
-  }`
-
-  const cat_default_main_works = `
-  int main()
-    Cat cat{}; // ✅ Compiles now
-    return 0;
-  }`
-
-  // Default constructor
-  yield * codeRef().fontSize(60)
-  yield * codeRef().edit(duration, false)(...default_code(default_constructor_stupid));
-  yield * codeRef().selection(lines(2), 0.5);
-  yield * waitFor(duration);
-  yield * codeRef().edit(duration)(...default_code(edit(default_constructor_stupid, default_constructor_better)));
-  yield * waitFor(duration);
-
-  // Uninitialized
-  const uninitialized = (priv: any) => store_one`
-  class Foo {
-  public:
-    Foo() = default;${priv}
-  };
-  `
-
-  const priv = `
-
-private:
-  int uninitialized;
-  int initialized{};`
-
-  yield * codeRef().selection(DEFAULT);
-  yield * codeRef().edit(duration, false)(...uninitialized(``));
-  yield * waitFor(duration);
-  yield * codeRef().edit(duration, true)(...uninitialized(insert(priv)));
-  yield * waitFor(duration);
-
-  // Cat class
-  yield * codeRef().fontSize(35)
-  yield * codeRef().selection(DEFAULT);
-  yield * codeRef().edit(duration, false)(...code_cat(``, `explicit `, cat_main));
-  yield * waitFor(duration);
-
-  // Highlight member init lists
-  yield * codeRef().selection([...lines(5), ...lines(8)], duration);
-  yield * waitFor(duration);
-  yield * codeRef().selection(DEFAULT);
-  yield * waitFor(duration);
-
-
-  // Show that we need default
-  yield * codeRef().edit(duration, true)(...code_cat(``, `explicit `, edit(cat_main, cat_default_main)));
-  yield * waitFor(duration);
-  yield * codeRef().edit(duration, true)(...code_cat(insert(cat_default), `explicit `, edit(cat_default_main, cat_default_main_works)));
-  yield * waitFor(duration);
-  yield * codeRef().selection(DEFAULT);
-  yield * waitFor(duration);
-
-  // Removing explicit
-  yield * codeRef().edit(duration, false)(...code_cat(cat_default, `explicit `, cat_main));
-  yield * all (
-  codeRef().selection(lines(6), 0.5),
-  codeRef().edit(duration, false)(...code_cat(cat_default, remove(`explicit `), cat_main)),
-  );
-  yield * codeRef().selection(DEFAULT, 0.5);
-
-  yield * all (
-    codeRef().selection([...lines(6), ...lines(17, Infinity)], duration),
-    codeRef().edit(duration, false)(...code_cat(cat_default, ``, edit(cat_main, foo_main))),
-  );
-  yield * waitFor(duration);
-  yield * codeRef().selection(DEFAULT, 0.5);
-  yield * waitFor(duration);
-  yield * codeRef().edit(duration, false)(...code_cat(cat_default, ``, edit(foo_main, foo_main_compiles)));
-  yield * waitFor(duration);
-  yield * codeRef().edit(duration, true)(...code_cat(cat_default, insert(`explicit `), edit(foo_main_compiles, foo_main_does_not_compile)));
-  yield * waitFor(duration);
-  yield * codeRef().selection(DEFAULT, 0.5);
-  yield * waitFor(duration);
-
-  // Code cat destructor
-  yield * codeRef().fontSize(45)
-  yield * codeRef().edit(duration, false)(...code_cat_destructor(``));
-  yield * waitFor(duration);
-  yield * codeRef().edit(duration, false)(...code_cat_destructor(insert(cat_destructor)));
-  yield * waitFor(duration);
-
-
-
-
-  // Using object
-  const use_object = (constructor: any, do_smth: any, destructor: any) => store_two`
-  int main() {${constructor}${do_smth}
-    return 0;
-  } ${destructor}
-  `
-  const cat_constructor = `
-  Cat cat{100};  // Cat(int happiness) is called`
-
-  const cat_mischief = `
-  cat.RunAround();
-  cat.BeAwesome();
-  cat.ThrowThingsFromAbove();`
-
-  const cat_destroy = `// Destructor cat.~Cat(); is called.`
-
-  yield * codeRef().fontSize(60)
-  yield * codeRef().edit(duration, false)(...use_object(``, ``, ``));
-  yield * waitFor(duration);
-  yield * codeRef().edit(duration, false)(...use_object(insert(cat_constructor), ``, ``));
-  yield * waitFor(duration);
-  yield * codeRef().edit(duration, false)(...use_object(cat_constructor, insert(cat_mischief), ``));
-  yield * waitFor(duration);
-  yield * codeRef().edit(duration, false)(...use_object(cat_constructor, cat_mischief, insert(cat_destroy)));
-  yield * waitFor(duration);
-
-  yield * waitFor(duration);
-
-
-  // yield * waitUntil('member_init_list');
-  // yield * codeRef().selection(word(6, 8, 23), 1.2);
-  // yield * codeRef().selection(word(9, 8, 58), 1.2);
-  // yield * waitUntil('remove_all');
-  // yield * all (
-  //   codeRef().selection(lines(0, Infinity), 1.2),
-  //   codeRef().edit(1.2, false)`${edit(code, code_lists)}`,
-  // );
-  // yield * waitUntil('add_all_back');
-  // yield* codeRef().edit(1.2, false)`${edit(code_lists, code)}`;
-
-  // yield * waitUntil('order');
-  // yield * codeRef().selection(lines(12), 1.2);
-  // yield * codeRef().selection(lines(13), 1.2);
-  // yield * codeRef().selection(lines(0, Infinity), 1.2);
-
-  // yield * waitFor(2);
-
-
-  // yield* waitFor(0.6);
-  // yield* all(
-  //   codeRef().selection(lines(0, Infinity), 1.2),
-  //   codeRef().edit(1.2, false)`var my${edit('Bool', 'Number')} = ${edit(
-  //     'false',
-  //     '42',
-  //   )};`,
-  // );
-  // yield* waitFor(0.6);
-  // yield* codeRef().edit(1.2, false)`var myNumber${remove(' = 42')};`;
-  // yield* waitFor(0.6);
-  // yield* codeRef().edit(1.2, false)`var my${edit('Number', 'Bool')};`;
-  // yield* waitFor(0.6);
-});
diff --git a/animation/object_lifecycle/tsconfig.json b/animation/object_lifecycle/tsconfig.json
deleted file mode 100644
index 789b7d1..0000000
--- a/animation/object_lifecycle/tsconfig.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-  "extends": "@motion-canvas/2d/tsconfig.project.json",
-  "compilerOptions": {
-    "baseUrl": "src"
-  },
-  "include": ["src"]
-}
diff --git a/animation/object_lifecycle/vite.config.ts b/animation/object_lifecycle/vite.config.ts
deleted file mode 100644
index bf32088..0000000
--- a/animation/object_lifecycle/vite.config.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-import {defineConfig} from 'vite';
-import motionCanvas from '@motion-canvas/vite-plugin';
-
-export default defineConfig({
-  plugins: [motionCanvas()],
-});
diff --git a/animation/static_no_classes/.gitignore b/animation/static_no_classes/.gitignore
deleted file mode 100644
index 829b1c7..0000000
--- a/animation/static_no_classes/.gitignore
+++ /dev/null
@@ -1,15 +0,0 @@
-# Generated files
-node_modules
-output
-dist
-
-# Editor directories and files
-.vscode/*
-!.vscode/extensions.json
-.idea
-.DS_Store
-*.suo
-*.ntvs*
-*.njsproj
-*.sln
-*.sw?
diff --git a/animation/static_no_classes/package-lock.json b/animation/static_no_classes/package-lock.json
deleted file mode 100644
index 0de87c1..0000000
--- a/animation/static_no_classes/package-lock.json
+++ /dev/null
@@ -1,1041 +0,0 @@
-{
-  "name": "value_semantics",
-  "version": "0.0.0",
-  "lockfileVersion": 3,
-  "requires": true,
-  "packages": {
-    "": {
-      "name": "value_semantics",
-      "version": "0.0.0",
-      "dependencies": {
-        "@motion-canvas/2d": "^3.11.0",
-        "@motion-canvas/core": "^3.11.0",
-        "@motion-canvas/ffmpeg": "^1.1.1"
-      },
-      "devDependencies": {
-        "@motion-canvas/ui": "^3.11.0",
-        "@motion-canvas/vite-plugin": "^3.11.0",
-        "typescript": "^4.9.5",
-        "vite": "^4.1.4"
-      }
-    },
-    "node_modules/@esbuild/android-arm": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
-      "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==",
-      "cpu": [
-        "arm"
-      ],
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/android-arm64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz",
-      "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/android-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz",
-      "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/darwin-arm64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz",
-      "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/darwin-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz",
-      "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/freebsd-arm64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz",
-      "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "freebsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/freebsd-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz",
-      "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "freebsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-arm": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz",
-      "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==",
-      "cpu": [
-        "arm"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-arm64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz",
-      "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-ia32": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz",
-      "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==",
-      "cpu": [
-        "ia32"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-loong64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz",
-      "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==",
-      "cpu": [
-        "loong64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-mips64el": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz",
-      "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==",
-      "cpu": [
-        "mips64el"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-ppc64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz",
-      "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==",
-      "cpu": [
-        "ppc64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-riscv64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz",
-      "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==",
-      "cpu": [
-        "riscv64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-s390x": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz",
-      "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==",
-      "cpu": [
-        "s390x"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz",
-      "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/netbsd-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz",
-      "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "netbsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/openbsd-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz",
-      "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "openbsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/sunos-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz",
-      "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "sunos"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/win32-arm64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz",
-      "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/win32-ia32": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz",
-      "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==",
-      "cpu": [
-        "ia32"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/win32-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz",
-      "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@ffmpeg-installer/darwin-arm64": {
-      "version": "4.1.5",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/darwin-arm64/-/darwin-arm64-4.1.5.tgz",
-      "integrity": "sha512-hYqTiP63mXz7wSQfuqfFwfLOfwwFChUedeCVKkBtl/cliaTM7/ePI9bVzfZ2c+dWu3TqCwLDRWNSJ5pqZl8otA==",
-      "cpu": [
-        "arm64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/darwin-x64": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/darwin-x64/-/darwin-x64-4.1.0.tgz",
-      "integrity": "sha512-Z4EyG3cIFjdhlY8wI9aLUXuH8nVt7E9SlMVZtWvSPnm2sm37/yC2CwjUzyCQbJbySnef1tQwGG2Sx+uWhd9IAw==",
-      "cpu": [
-        "x64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/ffmpeg": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/ffmpeg/-/ffmpeg-1.1.0.tgz",
-      "integrity": "sha512-Uq4rmwkdGxIa9A6Bd/VqqYbT7zqh1GrT5/rFwCwKM70b42W5gIjWeVETq6SdcL0zXqDtY081Ws/iJWhr1+xvQg==",
-      "optionalDependencies": {
-        "@ffmpeg-installer/darwin-arm64": "4.1.5",
-        "@ffmpeg-installer/darwin-x64": "4.1.0",
-        "@ffmpeg-installer/linux-arm": "4.1.3",
-        "@ffmpeg-installer/linux-arm64": "4.1.4",
-        "@ffmpeg-installer/linux-ia32": "4.1.0",
-        "@ffmpeg-installer/linux-x64": "4.1.0",
-        "@ffmpeg-installer/win32-ia32": "4.1.0",
-        "@ffmpeg-installer/win32-x64": "4.1.0"
-      }
-    },
-    "node_modules/@ffmpeg-installer/linux-arm": {
-      "version": "4.1.3",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/linux-arm/-/linux-arm-4.1.3.tgz",
-      "integrity": "sha512-NDf5V6l8AfzZ8WzUGZ5mV8O/xMzRag2ETR6+TlGIsMHp81agx51cqpPItXPib/nAZYmo55Bl2L6/WOMI3A5YRg==",
-      "cpu": [
-        "arm"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/linux-arm64": {
-      "version": "4.1.4",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/linux-arm64/-/linux-arm64-4.1.4.tgz",
-      "integrity": "sha512-dljEqAOD0oIM6O6DxBW9US/FkvqvQwgJ2lGHOwHDDwu/pX8+V0YsDL1xqHbj1DMX/+nP9rxw7G7gcUvGspSoKg==",
-      "cpu": [
-        "arm64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/linux-ia32": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/linux-ia32/-/linux-ia32-4.1.0.tgz",
-      "integrity": "sha512-0LWyFQnPf+Ij9GQGD034hS6A90URNu9HCtQ5cTqo5MxOEc7Rd8gLXrJvn++UmxhU0J5RyRE9KRYstdCVUjkNOQ==",
-      "cpu": [
-        "ia32"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/linux-x64": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/linux-x64/-/linux-x64-4.1.0.tgz",
-      "integrity": "sha512-Y5BWhGLU/WpQjOArNIgXD3z5mxxdV8c41C+U15nsE5yF8tVcdCGet5zPs5Zy3Ta6bU7haGpIzryutqCGQA/W8A==",
-      "cpu": [
-        "x64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/win32-ia32": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/win32-ia32/-/win32-ia32-4.1.0.tgz",
-      "integrity": "sha512-FV2D7RlaZv/lrtdhaQ4oETwoFUsUjlUiasiZLDxhEUPdNDWcH1OU9K1xTvqz+OXLdsmYelUDuBS/zkMOTtlUAw==",
-      "cpu": [
-        "ia32"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/win32-x64": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/win32-x64/-/win32-x64-4.1.0.tgz",
-      "integrity": "sha512-Drt5u2vzDnIONf4ZEkKtFlbvwj6rI3kxw1Ck9fpudmtgaZIHD4ucsWB2lCZBXRxJgXR+2IMSti+4rtM4C4rXgg==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ]
-    },
-    "node_modules/@ffprobe-installer/darwin-arm64": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/darwin-arm64/-/darwin-arm64-5.0.1.tgz",
-      "integrity": "sha512-vwNCNjokH8hfkbl6m95zICHwkSzhEvDC3GVBcUp5HX8+4wsX10SP3B+bGur7XUzTIZ4cQpgJmEIAx6TUwRepMg==",
-      "cpu": [
-        "arm64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ]
-    },
-    "node_modules/@ffprobe-installer/darwin-x64": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/darwin-x64/-/darwin-x64-5.1.0.tgz",
-      "integrity": "sha512-J+YGscZMpQclFg31O4cfVRGmDpkVsQ2fZujoUdMAAYcP0NtqpC49Hs3SWJpBdsGB4VeqOt5TTm1vSZQzs1NkhA==",
-      "cpu": [
-        "x64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ]
-    },
-    "node_modules/@ffprobe-installer/ffprobe": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/ffprobe/-/ffprobe-2.1.2.tgz",
-      "integrity": "sha512-ZNvwk4f2magF42Zji2Ese16SMj9BS7Fui4kRjg6gTYTxY3gWZNpg85n4MIfQyI9nimHg4x/gT6FVkp/bBDuBwg==",
-      "engines": {
-        "node": ">=14.21.2"
-      },
-      "optionalDependencies": {
-        "@ffprobe-installer/darwin-arm64": "5.0.1",
-        "@ffprobe-installer/darwin-x64": "5.1.0",
-        "@ffprobe-installer/linux-arm": "5.2.0",
-        "@ffprobe-installer/linux-arm64": "5.2.0",
-        "@ffprobe-installer/linux-ia32": "5.2.0",
-        "@ffprobe-installer/linux-x64": "5.2.0",
-        "@ffprobe-installer/win32-ia32": "5.1.0",
-        "@ffprobe-installer/win32-x64": "5.1.0"
-      }
-    },
-    "node_modules/@ffprobe-installer/linux-arm": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/linux-arm/-/linux-arm-5.2.0.tgz",
-      "integrity": "sha512-PF5HqEhCY7WTWHtLDYbA/+rLS+rhslWvyBlAG1Fk8VzVlnRdl93o6hy7DE2kJgxWQbFaR3ZktPQGEzfkrmQHvQ==",
-      "cpu": [
-        "arm"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffprobe-installer/linux-arm64": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/linux-arm64/-/linux-arm64-5.2.0.tgz",
-      "integrity": "sha512-X1VvWtlLs6ScP73biVLuHD5ohKJKsMTa0vafCESOen4mOoNeLAYbxOVxDWAdFz9cpZgRiloFj5QD6nDj8E28yQ==",
-      "cpu": [
-        "arm64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffprobe-installer/linux-ia32": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/linux-ia32/-/linux-ia32-5.2.0.tgz",
-      "integrity": "sha512-TFVK5sasXyXhbIG7LtPRDmtkrkOsInwKcL43iEvEw+D9vCS2rc//mn9/0Q+BR0UoJEiMK4+ApYr/3LLVUBPOCQ==",
-      "cpu": [
-        "ia32"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffprobe-installer/linux-x64": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/linux-x64/-/linux-x64-5.2.0.tgz",
-      "integrity": "sha512-D3UeqTLYPNs7pBWPLUYGehPdRVqU8eACox4OZy3pZUZatxye2YKlvBwEfaLdL1v2Z4FOAlLUhms0kY8m8kqSRA==",
-      "cpu": [
-        "x64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffprobe-installer/win32-ia32": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/win32-ia32/-/win32-ia32-5.1.0.tgz",
-      "integrity": "sha512-5O3vOoNRxmut0/Nu9vSazTdSHasrr+zPT2B3Hm7kjmO3QVFcIfVImS6ReQnZeSy8JPJOqXts5kX5x/3KOX54XQ==",
-      "cpu": [
-        "ia32"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ]
-    },
-    "node_modules/@ffprobe-installer/win32-x64": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/win32-x64/-/win32-x64-5.1.0.tgz",
-      "integrity": "sha512-jMGYeAgkrdn4e2vvYt/qakgHRE3CPju4bn5TmdPfoAm1BlX1mY9cyMd8gf5vSzI8gH8Zq5WQAyAkmekX/8TSTg==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ]
-    },
-    "node_modules/@motion-canvas/2d": {
-      "version": "3.11.0",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/2d/-/2d-3.11.0.tgz",
-      "integrity": "sha512-T/RPXGRxddO/xxbC2RcOXfrtBTp8lfcmnuW1fa6++0qy0chK5NFxm3bHJczCbX0ynKB2VAoqLNobTF9eD6ZP3w==",
-      "dependencies": {
-        "@motion-canvas/core": "^3.11.0",
-        "code-fns": "^0.8.2",
-        "mathjax-full": "^3.2.2",
-        "parse-svg-path": "^0.1.2"
-      }
-    },
-    "node_modules/@motion-canvas/core": {
-      "version": "3.11.0",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/core/-/core-3.11.0.tgz",
-      "integrity": "sha512-/WjdoSTqTPwCgrB2pP8YXq2T3KviYHrywVxXJ5fEjQ1gajkPKYD7aVlRcY1+kaTbwqXhCARMCh+pSjT2nfhTsw==",
-      "dependencies": {
-        "@types/chroma-js": "^2.1.4",
-        "chroma-js": "^2.4.2"
-      },
-      "peerDependencies": {
-        "vite": "^4.1.4"
-      }
-    },
-    "node_modules/@motion-canvas/ffmpeg": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/ffmpeg/-/ffmpeg-1.1.1.tgz",
-      "integrity": "sha512-w2d7oFfR3hYHXeYtFGoHp6goY+vVL0LoZ2h1b/veTH5KvE7jrLp2Kl/XPHsYJ5ZDRHUT0Nhl05DBLdXYqdSqgg==",
-      "dependencies": {
-        "@ffmpeg-installer/ffmpeg": "^1.1.0",
-        "@ffprobe-installer/ffprobe": "^2.0.0",
-        "fluent-ffmpeg": "^2.1.2"
-      },
-      "peerDependencies": {
-        "@motion-canvas/core": "^3.7.0",
-        "@motion-canvas/vite-plugin": "^3.7.0",
-        "vite": "4.x"
-      }
-    },
-    "node_modules/@motion-canvas/ui": {
-      "version": "3.11.0",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/ui/-/ui-3.11.0.tgz",
-      "integrity": "sha512-sd0GxvCkejL2lzExsvgLsC1GgHzLP/0LlMw1QE2/3pMQo3rMOVA7L1Oq6br8HqdJhzMEgW3DWC0NjDJsUfkL2A==",
-      "dev": true,
-      "dependencies": {
-        "@motion-canvas/core": "^3.11.0"
-      }
-    },
-    "node_modules/@motion-canvas/vite-plugin": {
-      "version": "3.11.0",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/vite-plugin/-/vite-plugin-3.11.0.tgz",
-      "integrity": "sha512-26ixfy5NhvFePj1DBdh7MFsgevpRrzzEKjzSyCK3FOvPcnUWFjab4wWErpsIEnu6a0p7yj4w9VKpa8USx6N95A==",
-      "dependencies": {
-        "follow-redirects": "^1.15.2",
-        "mime-types": "^2.1.35"
-      },
-      "peerDependencies": {
-        "vite": "4.x"
-      }
-    },
-    "node_modules/@types/chroma-js": {
-      "version": "2.4.0",
-      "resolved": "https://registry.npmjs.org/@types/chroma-js/-/chroma-js-2.4.0.tgz",
-      "integrity": "sha512-JklMxityrwjBTjGY2anH8JaTx3yjRU3/sEHSblLH1ba5lqcSh1LnImXJZO5peJfXyqKYWjHTGy4s5Wz++hARrw=="
-    },
-    "node_modules/@types/hast": {
-      "version": "2.3.4",
-      "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.4.tgz",
-      "integrity": "sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==",
-      "dependencies": {
-        "@types/unist": "*"
-      }
-    },
-    "node_modules/@types/unist": {
-      "version": "2.0.6",
-      "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz",
-      "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ=="
-    },
-    "node_modules/@wooorm/starry-night": {
-      "version": "1.7.0",
-      "resolved": "https://registry.npmjs.org/@wooorm/starry-night/-/starry-night-1.7.0.tgz",
-      "integrity": "sha512-ktO0nkddrovIoNW2jAUT+Cdd9n1bWjy1Ir4CdcmgTaT6E94HLlQfu7Yv62falclBEwvsuVp3bSBw23wtta1fNw==",
-      "dependencies": {
-        "@types/hast": "^2.0.0",
-        "import-meta-resolve": "^2.0.0",
-        "vscode-oniguruma": "^1.0.0",
-        "vscode-textmate": "^9.0.0"
-      },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/wooorm"
-      }
-    },
-    "node_modules/async": {
-      "version": "3.2.4",
-      "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz",
-      "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ=="
-    },
-    "node_modules/chroma-js": {
-      "version": "2.4.2",
-      "resolved": "https://registry.npmjs.org/chroma-js/-/chroma-js-2.4.2.tgz",
-      "integrity": "sha512-U9eDw6+wt7V8z5NncY2jJfZa+hUH8XEj8FQHgFJTrUFnJfXYf4Ml4adI2vXZOjqRDpFWtYVWypDfZwnJ+HIR4A=="
-    },
-    "node_modules/code-fns": {
-      "version": "0.8.2",
-      "resolved": "https://registry.npmjs.org/code-fns/-/code-fns-0.8.2.tgz",
-      "integrity": "sha512-3VVeq3cnWxWiWKFLsVo+XWsOXBSW2gAx2uv0ViETLNmNuygEPHlCeDAv/Zy7xXqPgXtgLZyvIJZmx+ojTgOIGA==",
-      "dependencies": {
-        "@wooorm/starry-night": "^1.2.0"
-      }
-    },
-    "node_modules/commander": {
-      "version": "9.2.0",
-      "resolved": "https://registry.npmjs.org/commander/-/commander-9.2.0.tgz",
-      "integrity": "sha512-e2i4wANQiSXgnrBlIatyHtP1odfUp0BbV5Y5nEGbxtIrStkEOAAzCUirvLBNXHLr7kwLvJl6V+4V3XV9x7Wd9w==",
-      "engines": {
-        "node": "^12.20.0 || >=14"
-      }
-    },
-    "node_modules/esbuild": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz",
-      "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==",
-      "hasInstallScript": true,
-      "bin": {
-        "esbuild": "bin/esbuild"
-      },
-      "engines": {
-        "node": ">=12"
-      },
-      "optionalDependencies": {
-        "@esbuild/android-arm": "0.18.20",
-        "@esbuild/android-arm64": "0.18.20",
-        "@esbuild/android-x64": "0.18.20",
-        "@esbuild/darwin-arm64": "0.18.20",
-        "@esbuild/darwin-x64": "0.18.20",
-        "@esbuild/freebsd-arm64": "0.18.20",
-        "@esbuild/freebsd-x64": "0.18.20",
-        "@esbuild/linux-arm": "0.18.20",
-        "@esbuild/linux-arm64": "0.18.20",
-        "@esbuild/linux-ia32": "0.18.20",
-        "@esbuild/linux-loong64": "0.18.20",
-        "@esbuild/linux-mips64el": "0.18.20",
-        "@esbuild/linux-ppc64": "0.18.20",
-        "@esbuild/linux-riscv64": "0.18.20",
-        "@esbuild/linux-s390x": "0.18.20",
-        "@esbuild/linux-x64": "0.18.20",
-        "@esbuild/netbsd-x64": "0.18.20",
-        "@esbuild/openbsd-x64": "0.18.20",
-        "@esbuild/sunos-x64": "0.18.20",
-        "@esbuild/win32-arm64": "0.18.20",
-        "@esbuild/win32-ia32": "0.18.20",
-        "@esbuild/win32-x64": "0.18.20"
-      }
-    },
-    "node_modules/esm": {
-      "version": "3.2.25",
-      "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz",
-      "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==",
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/fluent-ffmpeg": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/fluent-ffmpeg/-/fluent-ffmpeg-2.1.2.tgz",
-      "integrity": "sha512-IZTB4kq5GK0DPp7sGQ0q/BWurGHffRtQQwVkiqDgeO6wYJLLV5ZhgNOQ65loZxxuPMKZKZcICCUnaGtlxBiR0Q==",
-      "dependencies": {
-        "async": ">=0.2.9",
-        "which": "^1.1.1"
-      },
-      "engines": {
-        "node": ">=0.8.0"
-      }
-    },
-    "node_modules/follow-redirects": {
-      "version": "1.15.2",
-      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
-      "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
-      "funding": [
-        {
-          "type": "individual",
-          "url": "https://github.com/sponsors/RubenVerborgh"
-        }
-      ],
-      "engines": {
-        "node": ">=4.0"
-      },
-      "peerDependenciesMeta": {
-        "debug": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/fsevents": {
-      "version": "2.3.3",
-      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
-      "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
-      }
-    },
-    "node_modules/import-meta-resolve": {
-      "version": "2.2.2",
-      "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-2.2.2.tgz",
-      "integrity": "sha512-f8KcQ1D80V7RnqVm+/lirO9zkOxjGxhaTC1IPrBGd3MEfNgmNG67tSUO9gTi2F3Blr2Az6g1vocaxzkVnWl9MA==",
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/wooorm"
-      }
-    },
-    "node_modules/isexe": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
-      "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
-    },
-    "node_modules/mathjax-full": {
-      "version": "3.2.2",
-      "resolved": "https://registry.npmjs.org/mathjax-full/-/mathjax-full-3.2.2.tgz",
-      "integrity": "sha512-+LfG9Fik+OuI8SLwsiR02IVdjcnRCy5MufYLi0C3TdMT56L/pjB0alMVGgoWJF8pN9Rc7FESycZB9BMNWIid5w==",
-      "dependencies": {
-        "esm": "^3.2.25",
-        "mhchemparser": "^4.1.0",
-        "mj-context-menu": "^0.6.1",
-        "speech-rule-engine": "^4.0.6"
-      }
-    },
-    "node_modules/mhchemparser": {
-      "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/mhchemparser/-/mhchemparser-4.1.1.tgz",
-      "integrity": "sha512-R75CUN6O6e1t8bgailrF1qPq+HhVeFTM3XQ0uzI+mXTybmphy3b6h4NbLOYhemViQ3lUs+6CKRkC3Ws1TlYREA=="
-    },
-    "node_modules/mime-db": {
-      "version": "1.52.0",
-      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
-      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/mime-types": {
-      "version": "2.1.35",
-      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
-      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
-      "dependencies": {
-        "mime-db": "1.52.0"
-      },
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/mj-context-menu": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/mj-context-menu/-/mj-context-menu-0.6.1.tgz",
-      "integrity": "sha512-7NO5s6n10TIV96d4g2uDpG7ZDpIhMh0QNfGdJw/W47JswFcosz457wqz/b5sAKvl12sxINGFCn80NZHKwxQEXA=="
-    },
-    "node_modules/nanoid": {
-      "version": "3.3.6",
-      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
-      "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/ai"
-        }
-      ],
-      "bin": {
-        "nanoid": "bin/nanoid.cjs"
-      },
-      "engines": {
-        "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
-      }
-    },
-    "node_modules/parse-svg-path": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/parse-svg-path/-/parse-svg-path-0.1.2.tgz",
-      "integrity": "sha512-JyPSBnkTJ0AI8GGJLfMXvKq42cj5c006fnLz6fXy6zfoVjJizi8BNTpu8on8ziI1cKy9d9DGNuY17Ce7wuejpQ=="
-    },
-    "node_modules/picocolors": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
-      "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
-    },
-    "node_modules/postcss": {
-      "version": "8.4.31",
-      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
-      "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
-      "funding": [
-        {
-          "type": "opencollective",
-          "url": "https://opencollective.com/postcss/"
-        },
-        {
-          "type": "tidelift",
-          "url": "https://tidelift.com/funding/github/npm/postcss"
-        },
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/ai"
-        }
-      ],
-      "dependencies": {
-        "nanoid": "^3.3.6",
-        "picocolors": "^1.0.0",
-        "source-map-js": "^1.0.2"
-      },
-      "engines": {
-        "node": "^10 || ^12 || >=14"
-      }
-    },
-    "node_modules/rollup": {
-      "version": "3.29.4",
-      "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz",
-      "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==",
-      "bin": {
-        "rollup": "dist/bin/rollup"
-      },
-      "engines": {
-        "node": ">=14.18.0",
-        "npm": ">=8.0.0"
-      },
-      "optionalDependencies": {
-        "fsevents": "~2.3.2"
-      }
-    },
-    "node_modules/source-map-js": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
-      "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/speech-rule-engine": {
-      "version": "4.0.7",
-      "resolved": "https://registry.npmjs.org/speech-rule-engine/-/speech-rule-engine-4.0.7.tgz",
-      "integrity": "sha512-sJrL3/wHzNwJRLBdf6CjJWIlxC04iYKkyXvYSVsWVOiC2DSkHmxsqOhEeMsBA9XK+CHuNcsdkbFDnoUfAsmp9g==",
-      "dependencies": {
-        "commander": "9.2.0",
-        "wicked-good-xpath": "1.3.0",
-        "xmldom-sre": "0.1.31"
-      },
-      "bin": {
-        "sre": "bin/sre"
-      }
-    },
-    "node_modules/typescript": {
-      "version": "4.9.5",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
-      "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
-      "dev": true,
-      "bin": {
-        "tsc": "bin/tsc",
-        "tsserver": "bin/tsserver"
-      },
-      "engines": {
-        "node": ">=4.2.0"
-      }
-    },
-    "node_modules/vite": {
-      "version": "4.5.0",
-      "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.0.tgz",
-      "integrity": "sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw==",
-      "dependencies": {
-        "esbuild": "^0.18.10",
-        "postcss": "^8.4.27",
-        "rollup": "^3.27.1"
-      },
-      "bin": {
-        "vite": "bin/vite.js"
-      },
-      "engines": {
-        "node": "^14.18.0 || >=16.0.0"
-      },
-      "funding": {
-        "url": "https://github.com/vitejs/vite?sponsor=1"
-      },
-      "optionalDependencies": {
-        "fsevents": "~2.3.2"
-      },
-      "peerDependencies": {
-        "@types/node": ">= 14",
-        "less": "*",
-        "lightningcss": "^1.21.0",
-        "sass": "*",
-        "stylus": "*",
-        "sugarss": "*",
-        "terser": "^5.4.0"
-      },
-      "peerDependenciesMeta": {
-        "@types/node": {
-          "optional": true
-        },
-        "less": {
-          "optional": true
-        },
-        "lightningcss": {
-          "optional": true
-        },
-        "sass": {
-          "optional": true
-        },
-        "stylus": {
-          "optional": true
-        },
-        "sugarss": {
-          "optional": true
-        },
-        "terser": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/vscode-oniguruma": {
-      "version": "1.7.0",
-      "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz",
-      "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA=="
-    },
-    "node_modules/vscode-textmate": {
-      "version": "9.0.0",
-      "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-9.0.0.tgz",
-      "integrity": "sha512-Cl65diFGxz7gpwbav10HqiY/eVYTO1sjQpmRmV991Bj7wAoOAjGQ97PpQcXorDE2Uc4hnGWLY17xme+5t6MlSg=="
-    },
-    "node_modules/which": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
-      "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
-      "dependencies": {
-        "isexe": "^2.0.0"
-      },
-      "bin": {
-        "which": "bin/which"
-      }
-    },
-    "node_modules/wicked-good-xpath": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/wicked-good-xpath/-/wicked-good-xpath-1.3.0.tgz",
-      "integrity": "sha512-Gd9+TUn5nXdwj/hFsPVx5cuHHiF5Bwuc30jZ4+ronF1qHK5O7HD0sgmXWSEgwKquT3ClLoKPVbO6qGwVwLzvAw=="
-    },
-    "node_modules/xmldom-sre": {
-      "version": "0.1.31",
-      "resolved": "https://registry.npmjs.org/xmldom-sre/-/xmldom-sre-0.1.31.tgz",
-      "integrity": "sha512-f9s+fUkX04BxQf+7mMWAp5zk61pciie+fFLC9hX9UVvCeJQfNHRHXpeo5MPcR0EUf57PYLdt+ZO4f3Ipk2oZUw==",
-      "engines": {
-        "node": ">=0.1"
-      }
-    }
-  }
-}
diff --git a/animation/static_no_classes/package.json b/animation/static_no_classes/package.json
deleted file mode 100644
index d608000..0000000
--- a/animation/static_no_classes/package.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
-  "name": "value_semantics",
-  "private": true,
-  "version": "0.0.0",
-  "scripts": {
-    "serve": "vite",
-    "build": "tsc && vite build"
-  },
-  "dependencies": {
-    "@motion-canvas/2d": "^3.11.0",
-    "@motion-canvas/core": "^3.11.0",
-    "@motion-canvas/ffmpeg": "^1.1.1"
-  },
-  "devDependencies": {
-    "@motion-canvas/ui": "^3.11.0",
-    "@motion-canvas/vite-plugin": "^3.11.0",
-    "typescript": "^4.9.5",
-    "vite": "^4.1.4"
-  }
-}
diff --git a/animation/static_no_classes/src/global.css b/animation/static_no_classes/src/global.css
deleted file mode 100644
index 84cea14..0000000
--- a/animation/static_no_classes/src/global.css
+++ /dev/null
@@ -1 +0,0 @@
-@import url('https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;700&display=swap');
diff --git a/animation/static_no_classes/src/motion-canvas.d.ts b/animation/static_no_classes/src/motion-canvas.d.ts
deleted file mode 100644
index 067c6a4..0000000
--- a/animation/static_no_classes/src/motion-canvas.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-/// <reference types="@motion-canvas/core/project" />
diff --git a/animation/static_no_classes/src/project.meta b/animation/static_no_classes/src/project.meta
deleted file mode 100644
index 7579bae..0000000
--- a/animation/static_no_classes/src/project.meta
+++ /dev/null
@@ -1,31 +0,0 @@
-{
-  "version": 0,
-  "shared": {
-    "background": "rgb(10,20,30)",
-    "range": [
-      0,
-      null
-    ],
-    "size": {
-      "x": 1920,
-      "y": 1080
-    },
-    "audioOffset": 0
-  },
-  "preview": {
-    "fps": 30,
-    "resolutionScale": 1
-  },
-  "rendering": {
-    "fps": 30,
-    "resolutionScale": 2,
-    "colorSpace": "srgb",
-    "exporter": {
-      "name": "@motion-canvas/ffmpeg",
-      "options": {
-        "fastStart": true,
-        "includeAudio": true
-      }
-    }
-  }
-}
\ No newline at end of file
diff --git a/animation/static_no_classes/src/project.ts b/animation/static_no_classes/src/project.ts
deleted file mode 100644
index 4d3565c..0000000
--- a/animation/static_no_classes/src/project.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import {makeProject} from '@motion-canvas/core';
-
-import static_vis from './scenes/static_vis?scene';
-
-import './global.css'; // <- import the css
-
-export default makeProject({
-  scenes: [static_vis],
-});
diff --git a/animation/static_no_classes/src/scenes/static_vis.meta b/animation/static_no_classes/src/scenes/static_vis.meta
deleted file mode 100644
index 5964ccf..0000000
--- a/animation/static_no_classes/src/scenes/static_vis.meta
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-  "version": 0,
-  "timeEvents": [],
-  "seed": 2078473243
-}
\ No newline at end of file
diff --git a/animation/static_no_classes/src/scenes/static_vis.tsx b/animation/static_no_classes/src/scenes/static_vis.tsx
deleted file mode 100644
index c7c6aba..0000000
--- a/animation/static_no_classes/src/scenes/static_vis.tsx
+++ /dev/null
@@ -1,345 +0,0 @@
-import { makeScene2D } from '@motion-canvas/2d/lib/scenes';
-import { Node, Txt, Rect, Grid, Line } from '@motion-canvas/2d/lib/components';
-import { all, waitFor } from '@motion-canvas/core/lib/flow';
-import { createRef } from '@motion-canvas/core/lib/utils';
-import { createSignal } from '@motion-canvas/core/lib/signals';
-import {
-  CodeBlock,
-  edit,
-  insert,
-  lines,
-  word,
-  remove,
-  CodeModification,
-} from '@motion-canvas/2d/lib/components/CodeBlock';
-import { DEFAULT } from '@motion-canvas/core/lib/signals';
-import { BBox, Vector2 } from '@motion-canvas/core/lib/types';
-
-const RED = '#ff6470';
-const GREEN = '#99A44A';
-const BLUE = '#68AADD';
-const WHITE = '#FFFFFF';
-
-export default makeScene2D(function* (view: { add: (arg0: Node) => void; }) {
-  const left_half = createRef<Node>();
-  const all_text_node = createRef<Node>();
-
-  const program_lifetime = createRef<Line>();
-  const program_text = createRef<Txt>();
-
-  const main_lifetime = createRef<Line>();
-  const main_text = createRef<Txt>();
-
-  const foo_lifetime = createRef<Line>();
-  const foo_text = createRef<Txt>();
-
-  const foo_lifetime_2 = createRef<Line>();
-  const foo_text_2 = createRef<Txt>();
-
-  const value_name = createRef<Txt>();
-  const value_lifetime = createRef<Rect>();
-
-  const const_name = createRef<Txt>();
-  const const_lifetime = createRef<Rect>();
-
-  const right_half = createRef<Node>();
-  const code_ref = createRef<CodeBlock>();
-
-  const text_offset = 12
-  const line_offset = 100
-  const x_offset = 80
-
-  view.add(
-    <>
-      <Node ref={left_half} position={[-900, 200]}>
-        <Line
-          ref={program_lifetime}
-          lineWidth={7}
-          stroke={GREEN}
-          points={[[0, 0], [700, 0]]}
-          opacity={0.0} />
-        <Txt
-          ref={program_text}
-          y={text_offset}
-          fontSize={50}
-          offset={[-1, -1]}
-          fill={GREEN}
-          opacity={0.0}
-          fontFamily={"Fira Code"}>program</Txt>
-
-        <Node ref={all_text_node}>
-          <Line
-            ref={main_lifetime}
-            lineWidth={7}
-            stroke={RED}
-            points={[[0, 0], [700 - 2 * x_offset, 0]]}
-            y={-line_offset}
-            x={x_offset}
-            opacity={0.0}
-          />
-          <Txt
-            ref={main_text}
-            fontSize={50}
-            offset={[-1, -1]}
-            y={-line_offset + text_offset}
-            x={main_lifetime().x}
-            fill={RED}
-            opacity={0.0}
-            fontFamily={"Fira Code"}>main()</Txt>
-
-          <Line
-            ref={foo_lifetime}
-            lineWidth={7}
-            y={-2 * line_offset}
-            x={2 * x_offset}
-            stroke={BLUE}
-            points={[[0, 0], [700 - 4 * x_offset, 0]]}
-            opacity={0.0} />
-          <Txt
-            ref={foo_text}
-            fontSize={50}
-            y={-2 * line_offset + text_offset}
-            x={foo_lifetime().x}
-            offset={[-1, -1]}
-            fill={BLUE}
-            opacity={0.0}
-            fontFamily={"Fira Code"}>Foo()</Txt>
-
-          <Line
-            ref={foo_lifetime_2}
-            lineWidth={7}
-            y={-2 * line_offset}
-            x={5 * x_offset}
-            stroke={BLUE}
-            points={[[0, 0], [700 - 5 * x_offset, 0]]}
-            end={0}
-            opacity={0.0} />
-          <Txt
-            ref={foo_text_2}
-            fontSize={50}
-            y={-2 * line_offset + text_offset}
-            x={foo_lifetime_2().x}
-            offset={[-1, -1]}
-            fill={BLUE}
-            opacity={0.0}
-            fontFamily={"Fira Code"}>Foo()</Txt>
-
-          <Rect
-            ref={value_lifetime}
-            lineWidth={3}
-            y={-2 * line_offset - 70}
-            x={2 * x_offset}
-            offset={[-1, 0]}
-            fill={BLUE}
-            width={700 - 4 * x_offset}
-            height={100}
-            opacity={0.0} >
-            <Txt
-              ref={value_name}
-              fontSize={50}
-              fill={WHITE}
-              fontFamily={"Fira Code"}>local_value</Txt>
-          </Rect>
-        </Node>
-
-        <Rect
-          ref={const_lifetime}
-          lineWidth={3}
-          y={-70}
-          offset={[-1, 0]}
-          fill={GREEN}
-          width={700}
-          height={100}
-          opacity={0.0} >
-          <Txt
-            ref={const_name}
-            fontSize={50}
-            fill={WHITE}
-            fontFamily={"Fira Code"}>kValue</Txt>
-        </Rect>
-
-      </Node >
-      <Node ref={right_half} position={[400, 0]}>
-        <CodeBlock
-          ref={code_ref}
-          language="cpp"
-          fontSize={50}
-        />
-      </Node>
-    </>,
-  );
-
-  const duration = 1.5
-
-  const store = (...args: [TemplateStringsArray, ...any]) => args;
-
-  function to_string([strings, ...values]: [TemplateStringsArray, ...any]): string {
-    return strings.reduce((acc, str, i) => {
-      const value = values[i] ?? '';
-      return acc + str + value;
-    }, ' ');
-  }
-
-  function append(
-    template_1: TemplateStringsArray, args_1: string[],
-    template_2: TemplateStringsArray, args_2: string[]): [TemplateStringsArray, ...string[]] {
-    let new_template = Array.from<string>(template_1);
-    let new_args: Array<string> = args_1;
-    new_template[template_1.length - 1] += template_2[0]
-    new_template = new_template.concat(template_2.slice(1))
-    new_args = new_args.concat(args_2)
-    return [new_template as unknown as TemplateStringsArray, ...new_args];
-  }
-
-  const isCodeModification = (code: any): code is CodeModification => (code as CodeModification).from !== undefined;
-
-  function simplify(
-    args_in: [TemplateStringsArray, ...any]): [TemplateStringsArray, ...string[]] {
-    const template = args_in[0]
-    const args = args_in.slice(1)
-    if (args.every((arg) => (typeof (arg) == "string") || isCodeModification(arg))) {
-      return args_in
-    }
-    let new_template: Array<any> = [];
-    let new_args: Array<any> = [];
-    let concatenate = false;
-    for (let i = 0; i <= args.length; i++) {
-      if (concatenate) {
-        concatenate = false;
-        new_template[new_template.length - 1] += template[i];
-      } else {
-        new_template.push(template[i]);
-      }
-      if (i == args.length) { break; }
-      if (typeof (args[i]) == "string" || isCodeModification(args[i])) {
-        new_args.push(args[i])
-        continue;
-      }
-      let simplified_arg = simplify(args[i]);
-      let simplified_template = simplified_arg[0]
-      let simplified_args = simplified_arg.slice(1)
-      const appended = append(
-        new_template as unknown as TemplateStringsArray,
-        new_args,
-        simplified_template,
-        simplified_args as string[]);
-      new_template = Array.from<string>(appended[0])
-      new_args = appended.slice(1)
-      concatenate = true;
-    }
-    return [new_template as unknown as TemplateStringsArray, ...new_args]
-  }
-
-  const const_value_code = `
-  namespace {
-  constexpr int kValue{42};
-  }  // namespace
-  `
-
-  const foo_func = (init_value: any = ``, static_keyword: any = ``) => store`
-  void Foo() {
-    ${static_keyword}int local_value{${init_value}};
-  }
-  `
-
-  const foo_call = `\n    Foo();`
-  const foo_call_double = `\n    Foo();\n    Foo();`
-
-  const code = (func_code: any = ``, func_call: any = ``, constant_def: any = ``) => store`
-${constant_def}${func_code}
-  int main() {${func_call}
-    return 0;
-  }
-  `
-
-  yield* code_ref().edit(duration, false)(...simplify(code(foo_func(), foo_call)));
-  yield* waitFor(duration / 2);
-  yield* all(
-    program_lifetime().opacity(1.0, 0),
-    program_lifetime().end(0.0, 0).to(1.0, duration / 2),
-    program_text().opacity(0.0, 0).to(1.0, duration / 2),
-  );
-  yield* all(
-    main_lifetime().opacity(1.0, 0),
-    main_lifetime().end(0.0, 0).to(1.0, duration / 2),
-    main_text().opacity(0.0, 0).to(1.0, duration / 2),
-  );
-  yield* all(
-    foo_lifetime().opacity(1.0, 0),
-    foo_lifetime().end(0.0, 0).to(1.0, duration / 2),
-    foo_text().opacity(0.0, 0).to(1.0, duration / 2),
-  );
-  yield* waitFor(duration);
-
-  yield* all(
-    code_ref().selection(lines(2), duration / 2),
-    value_lifetime().opacity(0.0, 0).to(1.0, duration / 2),
-    value_lifetime().scale.x(0.0, 0).to(1.0, duration / 2),
-  );
-  yield* waitFor(duration);
-
-  yield* code_ref().selection(DEFAULT, duration / 2);
-  yield* code_ref().edit(duration, false)(...simplify(code(foo_func(edit('', 'kValue')), foo_call, edit('', const_value_code))));
-  yield* all(
-    all_text_node().y(0.0, 0).to(-120, duration / 2),
-  );
-  yield* all(
-    const_lifetime().opacity(0.0, 0).to(1.0, duration / 2),
-    const_lifetime().scale.x(0.0, 0).to(1.0, duration / 2),
-  );
-  yield* waitFor(duration);
-  yield* all(
-    code_ref().edit(duration, true)(...simplify(code(foo_func('kValue', edit('', 'static ')), foo_call, const_value_code))),
-    value_lifetime().width(380, duration / 2).to(550, duration / 2),
-    value_lifetime().fill(GREEN, duration),
-  );
-
-  yield* waitFor(duration);
-  yield* code_ref().selection(DEFAULT, 0);
-  yield* waitFor(duration);
-
-  yield* all(
-    code_ref().edit(duration, false)(...simplify(code(foo_func('kValue', 'static '), edit(foo_call, foo_call_double), const_value_code))),
-    foo_lifetime().end(1.0, 0).to(0.5, duration),
-    foo_lifetime_2().end(0.0, 0).to(0.0, duration/2).to(0.6, duration / 2),
-    foo_lifetime_2().opacity(1.0),
-    foo_text_2().opacity(0.0, 0).to(1.0, duration / 2),
-  );
-  yield* waitFor(duration / 2);
-
-  yield* all(
-    code_ref().selection([...lines(6), ...lines(10, 11)], duration / 2),
-  );
-  yield* waitFor(duration);
-
-  // yield* waitFor(2.0);
-  // yield* a_ref().edit(1.0, false)`${insert(object_code)}`;
-  // yield* all(
-  //   grid_ref().height(0, 0.0).to(250, 0.5),
-  //   grid_ref().width(0, 0.0).to(1920, 0.5),
-  //   grid_ref().opacity(1.0, 0.1),
-  // );
-  // yield* all(
-  //   data_rect_ref().opacity(0.5, 1.0),
-  //   line_1().end(1, 1.0),
-  //   gray_line_ref().opacity(1.0, 0.5),
-  //   gray_code_ref().opacity(1.0, 0.5),
-  // );
-  // yield* b_ref().edit(1.0, false)`${insert(member_object_code)}`;
-  // yield* waitFor(1.0);
-  // yield* data_rect_ref().scale(1.2, 1.0);
-  // yield* data_rect_ref().position.x(-20, 0.2).to(20, 0.2).to(-20, 0.2).to(20, 0.2).to(0, 0.2);
-  // yield* data_rect_ref().scale(1.0, 0.5);
-  // yield* waitFor(1.0);
-  // yield* line_2().end(1, 1.5);
-  // yield* waitFor(1.0);
-  // yield* all(
-  //   data_rect_ref().opacity(0.5, 1.0),
-  //   line_1().arrowSize(0, 0.5),
-  //   line_1().end(0, 1.0),
-  //   a_ref().edit(1.5, false)`Data* a${insert(' = nullptr')};`,
-  // );
-
-  yield* waitFor(3.0);
-
-});
diff --git a/animation/static_no_classes/tsconfig.json b/animation/static_no_classes/tsconfig.json
deleted file mode 100644
index 789b7d1..0000000
--- a/animation/static_no_classes/tsconfig.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-  "extends": "@motion-canvas/2d/tsconfig.project.json",
-  "compilerOptions": {
-    "baseUrl": "src"
-  },
-  "include": ["src"]
-}
diff --git a/animation/static_no_classes/vite.config.ts b/animation/static_no_classes/vite.config.ts
deleted file mode 100644
index a463c29..0000000
--- a/animation/static_no_classes/vite.config.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import { defineConfig } from 'vite';
-import motionCanvas from '@motion-canvas/vite-plugin';
-import ffmpeg from '@motion-canvas/ffmpeg';
-
-export default defineConfig({
-  plugins: [
-    motionCanvas(),
-    ffmpeg()
-  ],
-});
diff --git a/animation/templates_how_functions/.gitignore b/animation/templates_how_functions/.gitignore
deleted file mode 100644
index 829b1c7..0000000
--- a/animation/templates_how_functions/.gitignore
+++ /dev/null
@@ -1,15 +0,0 @@
-# Generated files
-node_modules
-output
-dist
-
-# Editor directories and files
-.vscode/*
-!.vscode/extensions.json
-.idea
-.DS_Store
-*.suo
-*.ntvs*
-*.njsproj
-*.sln
-*.sw?
diff --git a/animation/templates_how_functions/package-lock.json b/animation/templates_how_functions/package-lock.json
deleted file mode 100644
index 31011a8..0000000
--- a/animation/templates_how_functions/package-lock.json
+++ /dev/null
@@ -1,1041 +0,0 @@
-{
-  "name": "value_semantics",
-  "version": "0.0.0",
-  "lockfileVersion": 3,
-  "requires": true,
-  "packages": {
-    "": {
-      "name": "value_semantics",
-      "version": "0.0.0",
-      "dependencies": {
-        "@motion-canvas/2d": "^3.11.0",
-        "@motion-canvas/core": "^3.11.0",
-        "@motion-canvas/ffmpeg": "^1.1.1"
-      },
-      "devDependencies": {
-        "@motion-canvas/ui": "^3.11.0",
-        "@motion-canvas/vite-plugin": "^3.11.0",
-        "typescript": "^4.9.5",
-        "vite": "^4.1.4"
-      }
-    },
-    "node_modules/@esbuild/android-arm": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
-      "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==",
-      "cpu": [
-        "arm"
-      ],
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/android-arm64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz",
-      "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/android-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz",
-      "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/darwin-arm64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz",
-      "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/darwin-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz",
-      "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/freebsd-arm64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz",
-      "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "freebsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/freebsd-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz",
-      "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "freebsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-arm": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz",
-      "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==",
-      "cpu": [
-        "arm"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-arm64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz",
-      "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-ia32": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz",
-      "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==",
-      "cpu": [
-        "ia32"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-loong64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz",
-      "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==",
-      "cpu": [
-        "loong64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-mips64el": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz",
-      "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==",
-      "cpu": [
-        "mips64el"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-ppc64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz",
-      "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==",
-      "cpu": [
-        "ppc64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-riscv64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz",
-      "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==",
-      "cpu": [
-        "riscv64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-s390x": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz",
-      "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==",
-      "cpu": [
-        "s390x"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz",
-      "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/netbsd-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz",
-      "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "netbsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/openbsd-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz",
-      "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "openbsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/sunos-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz",
-      "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "sunos"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/win32-arm64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz",
-      "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/win32-ia32": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz",
-      "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==",
-      "cpu": [
-        "ia32"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/win32-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz",
-      "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@ffmpeg-installer/darwin-arm64": {
-      "version": "4.1.5",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/darwin-arm64/-/darwin-arm64-4.1.5.tgz",
-      "integrity": "sha512-hYqTiP63mXz7wSQfuqfFwfLOfwwFChUedeCVKkBtl/cliaTM7/ePI9bVzfZ2c+dWu3TqCwLDRWNSJ5pqZl8otA==",
-      "cpu": [
-        "arm64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/darwin-x64": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/darwin-x64/-/darwin-x64-4.1.0.tgz",
-      "integrity": "sha512-Z4EyG3cIFjdhlY8wI9aLUXuH8nVt7E9SlMVZtWvSPnm2sm37/yC2CwjUzyCQbJbySnef1tQwGG2Sx+uWhd9IAw==",
-      "cpu": [
-        "x64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/ffmpeg": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/ffmpeg/-/ffmpeg-1.1.0.tgz",
-      "integrity": "sha512-Uq4rmwkdGxIa9A6Bd/VqqYbT7zqh1GrT5/rFwCwKM70b42W5gIjWeVETq6SdcL0zXqDtY081Ws/iJWhr1+xvQg==",
-      "optionalDependencies": {
-        "@ffmpeg-installer/darwin-arm64": "4.1.5",
-        "@ffmpeg-installer/darwin-x64": "4.1.0",
-        "@ffmpeg-installer/linux-arm": "4.1.3",
-        "@ffmpeg-installer/linux-arm64": "4.1.4",
-        "@ffmpeg-installer/linux-ia32": "4.1.0",
-        "@ffmpeg-installer/linux-x64": "4.1.0",
-        "@ffmpeg-installer/win32-ia32": "4.1.0",
-        "@ffmpeg-installer/win32-x64": "4.1.0"
-      }
-    },
-    "node_modules/@ffmpeg-installer/linux-arm": {
-      "version": "4.1.3",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/linux-arm/-/linux-arm-4.1.3.tgz",
-      "integrity": "sha512-NDf5V6l8AfzZ8WzUGZ5mV8O/xMzRag2ETR6+TlGIsMHp81agx51cqpPItXPib/nAZYmo55Bl2L6/WOMI3A5YRg==",
-      "cpu": [
-        "arm"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/linux-arm64": {
-      "version": "4.1.4",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/linux-arm64/-/linux-arm64-4.1.4.tgz",
-      "integrity": "sha512-dljEqAOD0oIM6O6DxBW9US/FkvqvQwgJ2lGHOwHDDwu/pX8+V0YsDL1xqHbj1DMX/+nP9rxw7G7gcUvGspSoKg==",
-      "cpu": [
-        "arm64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/linux-ia32": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/linux-ia32/-/linux-ia32-4.1.0.tgz",
-      "integrity": "sha512-0LWyFQnPf+Ij9GQGD034hS6A90URNu9HCtQ5cTqo5MxOEc7Rd8gLXrJvn++UmxhU0J5RyRE9KRYstdCVUjkNOQ==",
-      "cpu": [
-        "ia32"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/linux-x64": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/linux-x64/-/linux-x64-4.1.0.tgz",
-      "integrity": "sha512-Y5BWhGLU/WpQjOArNIgXD3z5mxxdV8c41C+U15nsE5yF8tVcdCGet5zPs5Zy3Ta6bU7haGpIzryutqCGQA/W8A==",
-      "cpu": [
-        "x64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/win32-ia32": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/win32-ia32/-/win32-ia32-4.1.0.tgz",
-      "integrity": "sha512-FV2D7RlaZv/lrtdhaQ4oETwoFUsUjlUiasiZLDxhEUPdNDWcH1OU9K1xTvqz+OXLdsmYelUDuBS/zkMOTtlUAw==",
-      "cpu": [
-        "ia32"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/win32-x64": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/win32-x64/-/win32-x64-4.1.0.tgz",
-      "integrity": "sha512-Drt5u2vzDnIONf4ZEkKtFlbvwj6rI3kxw1Ck9fpudmtgaZIHD4ucsWB2lCZBXRxJgXR+2IMSti+4rtM4C4rXgg==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ]
-    },
-    "node_modules/@ffprobe-installer/darwin-arm64": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/darwin-arm64/-/darwin-arm64-5.0.1.tgz",
-      "integrity": "sha512-vwNCNjokH8hfkbl6m95zICHwkSzhEvDC3GVBcUp5HX8+4wsX10SP3B+bGur7XUzTIZ4cQpgJmEIAx6TUwRepMg==",
-      "cpu": [
-        "arm64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ]
-    },
-    "node_modules/@ffprobe-installer/darwin-x64": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/darwin-x64/-/darwin-x64-5.1.0.tgz",
-      "integrity": "sha512-J+YGscZMpQclFg31O4cfVRGmDpkVsQ2fZujoUdMAAYcP0NtqpC49Hs3SWJpBdsGB4VeqOt5TTm1vSZQzs1NkhA==",
-      "cpu": [
-        "x64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ]
-    },
-    "node_modules/@ffprobe-installer/ffprobe": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/ffprobe/-/ffprobe-2.1.2.tgz",
-      "integrity": "sha512-ZNvwk4f2magF42Zji2Ese16SMj9BS7Fui4kRjg6gTYTxY3gWZNpg85n4MIfQyI9nimHg4x/gT6FVkp/bBDuBwg==",
-      "engines": {
-        "node": ">=14.21.2"
-      },
-      "optionalDependencies": {
-        "@ffprobe-installer/darwin-arm64": "5.0.1",
-        "@ffprobe-installer/darwin-x64": "5.1.0",
-        "@ffprobe-installer/linux-arm": "5.2.0",
-        "@ffprobe-installer/linux-arm64": "5.2.0",
-        "@ffprobe-installer/linux-ia32": "5.2.0",
-        "@ffprobe-installer/linux-x64": "5.2.0",
-        "@ffprobe-installer/win32-ia32": "5.1.0",
-        "@ffprobe-installer/win32-x64": "5.1.0"
-      }
-    },
-    "node_modules/@ffprobe-installer/linux-arm": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/linux-arm/-/linux-arm-5.2.0.tgz",
-      "integrity": "sha512-PF5HqEhCY7WTWHtLDYbA/+rLS+rhslWvyBlAG1Fk8VzVlnRdl93o6hy7DE2kJgxWQbFaR3ZktPQGEzfkrmQHvQ==",
-      "cpu": [
-        "arm"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffprobe-installer/linux-arm64": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/linux-arm64/-/linux-arm64-5.2.0.tgz",
-      "integrity": "sha512-X1VvWtlLs6ScP73biVLuHD5ohKJKsMTa0vafCESOen4mOoNeLAYbxOVxDWAdFz9cpZgRiloFj5QD6nDj8E28yQ==",
-      "cpu": [
-        "arm64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffprobe-installer/linux-ia32": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/linux-ia32/-/linux-ia32-5.2.0.tgz",
-      "integrity": "sha512-TFVK5sasXyXhbIG7LtPRDmtkrkOsInwKcL43iEvEw+D9vCS2rc//mn9/0Q+BR0UoJEiMK4+ApYr/3LLVUBPOCQ==",
-      "cpu": [
-        "ia32"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffprobe-installer/linux-x64": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/linux-x64/-/linux-x64-5.2.0.tgz",
-      "integrity": "sha512-D3UeqTLYPNs7pBWPLUYGehPdRVqU8eACox4OZy3pZUZatxye2YKlvBwEfaLdL1v2Z4FOAlLUhms0kY8m8kqSRA==",
-      "cpu": [
-        "x64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffprobe-installer/win32-ia32": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/win32-ia32/-/win32-ia32-5.1.0.tgz",
-      "integrity": "sha512-5O3vOoNRxmut0/Nu9vSazTdSHasrr+zPT2B3Hm7kjmO3QVFcIfVImS6ReQnZeSy8JPJOqXts5kX5x/3KOX54XQ==",
-      "cpu": [
-        "ia32"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ]
-    },
-    "node_modules/@ffprobe-installer/win32-x64": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/win32-x64/-/win32-x64-5.1.0.tgz",
-      "integrity": "sha512-jMGYeAgkrdn4e2vvYt/qakgHRE3CPju4bn5TmdPfoAm1BlX1mY9cyMd8gf5vSzI8gH8Zq5WQAyAkmekX/8TSTg==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ]
-    },
-    "node_modules/@motion-canvas/2d": {
-      "version": "3.11.0",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/2d/-/2d-3.11.0.tgz",
-      "integrity": "sha512-T/RPXGRxddO/xxbC2RcOXfrtBTp8lfcmnuW1fa6++0qy0chK5NFxm3bHJczCbX0ynKB2VAoqLNobTF9eD6ZP3w==",
-      "dependencies": {
-        "@motion-canvas/core": "^3.11.0",
-        "code-fns": "^0.8.2",
-        "mathjax-full": "^3.2.2",
-        "parse-svg-path": "^0.1.2"
-      }
-    },
-    "node_modules/@motion-canvas/core": {
-      "version": "3.11.0",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/core/-/core-3.11.0.tgz",
-      "integrity": "sha512-/WjdoSTqTPwCgrB2pP8YXq2T3KviYHrywVxXJ5fEjQ1gajkPKYD7aVlRcY1+kaTbwqXhCARMCh+pSjT2nfhTsw==",
-      "dependencies": {
-        "@types/chroma-js": "^2.1.4",
-        "chroma-js": "^2.4.2"
-      },
-      "peerDependencies": {
-        "vite": "^4.1.4"
-      }
-    },
-    "node_modules/@motion-canvas/ffmpeg": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/ffmpeg/-/ffmpeg-1.1.1.tgz",
-      "integrity": "sha512-w2d7oFfR3hYHXeYtFGoHp6goY+vVL0LoZ2h1b/veTH5KvE7jrLp2Kl/XPHsYJ5ZDRHUT0Nhl05DBLdXYqdSqgg==",
-      "dependencies": {
-        "@ffmpeg-installer/ffmpeg": "^1.1.0",
-        "@ffprobe-installer/ffprobe": "^2.0.0",
-        "fluent-ffmpeg": "^2.1.2"
-      },
-      "peerDependencies": {
-        "@motion-canvas/core": "^3.7.0",
-        "@motion-canvas/vite-plugin": "^3.7.0",
-        "vite": "4.x"
-      }
-    },
-    "node_modules/@motion-canvas/ui": {
-      "version": "3.11.0",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/ui/-/ui-3.11.0.tgz",
-      "integrity": "sha512-sd0GxvCkejL2lzExsvgLsC1GgHzLP/0LlMw1QE2/3pMQo3rMOVA7L1Oq6br8HqdJhzMEgW3DWC0NjDJsUfkL2A==",
-      "dev": true,
-      "dependencies": {
-        "@motion-canvas/core": "^3.11.0"
-      }
-    },
-    "node_modules/@motion-canvas/vite-plugin": {
-      "version": "3.11.0",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/vite-plugin/-/vite-plugin-3.11.0.tgz",
-      "integrity": "sha512-26ixfy5NhvFePj1DBdh7MFsgevpRrzzEKjzSyCK3FOvPcnUWFjab4wWErpsIEnu6a0p7yj4w9VKpa8USx6N95A==",
-      "dependencies": {
-        "follow-redirects": "^1.15.2",
-        "mime-types": "^2.1.35"
-      },
-      "peerDependencies": {
-        "vite": "4.x"
-      }
-    },
-    "node_modules/@types/chroma-js": {
-      "version": "2.4.0",
-      "resolved": "https://registry.npmjs.org/@types/chroma-js/-/chroma-js-2.4.0.tgz",
-      "integrity": "sha512-JklMxityrwjBTjGY2anH8JaTx3yjRU3/sEHSblLH1ba5lqcSh1LnImXJZO5peJfXyqKYWjHTGy4s5Wz++hARrw=="
-    },
-    "node_modules/@types/hast": {
-      "version": "2.3.4",
-      "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.4.tgz",
-      "integrity": "sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==",
-      "dependencies": {
-        "@types/unist": "*"
-      }
-    },
-    "node_modules/@types/unist": {
-      "version": "2.0.6",
-      "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz",
-      "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ=="
-    },
-    "node_modules/@wooorm/starry-night": {
-      "version": "1.7.0",
-      "resolved": "https://registry.npmjs.org/@wooorm/starry-night/-/starry-night-1.7.0.tgz",
-      "integrity": "sha512-ktO0nkddrovIoNW2jAUT+Cdd9n1bWjy1Ir4CdcmgTaT6E94HLlQfu7Yv62falclBEwvsuVp3bSBw23wtta1fNw==",
-      "dependencies": {
-        "@types/hast": "^2.0.0",
-        "import-meta-resolve": "^2.0.0",
-        "vscode-oniguruma": "^1.0.0",
-        "vscode-textmate": "^9.0.0"
-      },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/wooorm"
-      }
-    },
-    "node_modules/async": {
-      "version": "3.2.4",
-      "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz",
-      "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ=="
-    },
-    "node_modules/chroma-js": {
-      "version": "2.4.2",
-      "resolved": "https://registry.npmjs.org/chroma-js/-/chroma-js-2.4.2.tgz",
-      "integrity": "sha512-U9eDw6+wt7V8z5NncY2jJfZa+hUH8XEj8FQHgFJTrUFnJfXYf4Ml4adI2vXZOjqRDpFWtYVWypDfZwnJ+HIR4A=="
-    },
-    "node_modules/code-fns": {
-      "version": "0.8.2",
-      "resolved": "https://registry.npmjs.org/code-fns/-/code-fns-0.8.2.tgz",
-      "integrity": "sha512-3VVeq3cnWxWiWKFLsVo+XWsOXBSW2gAx2uv0ViETLNmNuygEPHlCeDAv/Zy7xXqPgXtgLZyvIJZmx+ojTgOIGA==",
-      "dependencies": {
-        "@wooorm/starry-night": "^1.2.0"
-      }
-    },
-    "node_modules/commander": {
-      "version": "9.2.0",
-      "resolved": "https://registry.npmjs.org/commander/-/commander-9.2.0.tgz",
-      "integrity": "sha512-e2i4wANQiSXgnrBlIatyHtP1odfUp0BbV5Y5nEGbxtIrStkEOAAzCUirvLBNXHLr7kwLvJl6V+4V3XV9x7Wd9w==",
-      "engines": {
-        "node": "^12.20.0 || >=14"
-      }
-    },
-    "node_modules/esbuild": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz",
-      "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==",
-      "hasInstallScript": true,
-      "bin": {
-        "esbuild": "bin/esbuild"
-      },
-      "engines": {
-        "node": ">=12"
-      },
-      "optionalDependencies": {
-        "@esbuild/android-arm": "0.18.20",
-        "@esbuild/android-arm64": "0.18.20",
-        "@esbuild/android-x64": "0.18.20",
-        "@esbuild/darwin-arm64": "0.18.20",
-        "@esbuild/darwin-x64": "0.18.20",
-        "@esbuild/freebsd-arm64": "0.18.20",
-        "@esbuild/freebsd-x64": "0.18.20",
-        "@esbuild/linux-arm": "0.18.20",
-        "@esbuild/linux-arm64": "0.18.20",
-        "@esbuild/linux-ia32": "0.18.20",
-        "@esbuild/linux-loong64": "0.18.20",
-        "@esbuild/linux-mips64el": "0.18.20",
-        "@esbuild/linux-ppc64": "0.18.20",
-        "@esbuild/linux-riscv64": "0.18.20",
-        "@esbuild/linux-s390x": "0.18.20",
-        "@esbuild/linux-x64": "0.18.20",
-        "@esbuild/netbsd-x64": "0.18.20",
-        "@esbuild/openbsd-x64": "0.18.20",
-        "@esbuild/sunos-x64": "0.18.20",
-        "@esbuild/win32-arm64": "0.18.20",
-        "@esbuild/win32-ia32": "0.18.20",
-        "@esbuild/win32-x64": "0.18.20"
-      }
-    },
-    "node_modules/esm": {
-      "version": "3.2.25",
-      "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz",
-      "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==",
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/fluent-ffmpeg": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/fluent-ffmpeg/-/fluent-ffmpeg-2.1.2.tgz",
-      "integrity": "sha512-IZTB4kq5GK0DPp7sGQ0q/BWurGHffRtQQwVkiqDgeO6wYJLLV5ZhgNOQ65loZxxuPMKZKZcICCUnaGtlxBiR0Q==",
-      "dependencies": {
-        "async": ">=0.2.9",
-        "which": "^1.1.1"
-      },
-      "engines": {
-        "node": ">=0.8.0"
-      }
-    },
-    "node_modules/follow-redirects": {
-      "version": "1.15.5",
-      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz",
-      "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==",
-      "funding": [
-        {
-          "type": "individual",
-          "url": "https://github.com/sponsors/RubenVerborgh"
-        }
-      ],
-      "engines": {
-        "node": ">=4.0"
-      },
-      "peerDependenciesMeta": {
-        "debug": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/fsevents": {
-      "version": "2.3.3",
-      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
-      "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
-      }
-    },
-    "node_modules/import-meta-resolve": {
-      "version": "2.2.2",
-      "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-2.2.2.tgz",
-      "integrity": "sha512-f8KcQ1D80V7RnqVm+/lirO9zkOxjGxhaTC1IPrBGd3MEfNgmNG67tSUO9gTi2F3Blr2Az6g1vocaxzkVnWl9MA==",
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/wooorm"
-      }
-    },
-    "node_modules/isexe": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
-      "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
-    },
-    "node_modules/mathjax-full": {
-      "version": "3.2.2",
-      "resolved": "https://registry.npmjs.org/mathjax-full/-/mathjax-full-3.2.2.tgz",
-      "integrity": "sha512-+LfG9Fik+OuI8SLwsiR02IVdjcnRCy5MufYLi0C3TdMT56L/pjB0alMVGgoWJF8pN9Rc7FESycZB9BMNWIid5w==",
-      "dependencies": {
-        "esm": "^3.2.25",
-        "mhchemparser": "^4.1.0",
-        "mj-context-menu": "^0.6.1",
-        "speech-rule-engine": "^4.0.6"
-      }
-    },
-    "node_modules/mhchemparser": {
-      "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/mhchemparser/-/mhchemparser-4.1.1.tgz",
-      "integrity": "sha512-R75CUN6O6e1t8bgailrF1qPq+HhVeFTM3XQ0uzI+mXTybmphy3b6h4NbLOYhemViQ3lUs+6CKRkC3Ws1TlYREA=="
-    },
-    "node_modules/mime-db": {
-      "version": "1.52.0",
-      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
-      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/mime-types": {
-      "version": "2.1.35",
-      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
-      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
-      "dependencies": {
-        "mime-db": "1.52.0"
-      },
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/mj-context-menu": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/mj-context-menu/-/mj-context-menu-0.6.1.tgz",
-      "integrity": "sha512-7NO5s6n10TIV96d4g2uDpG7ZDpIhMh0QNfGdJw/W47JswFcosz457wqz/b5sAKvl12sxINGFCn80NZHKwxQEXA=="
-    },
-    "node_modules/nanoid": {
-      "version": "3.3.6",
-      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
-      "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/ai"
-        }
-      ],
-      "bin": {
-        "nanoid": "bin/nanoid.cjs"
-      },
-      "engines": {
-        "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
-      }
-    },
-    "node_modules/parse-svg-path": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/parse-svg-path/-/parse-svg-path-0.1.2.tgz",
-      "integrity": "sha512-JyPSBnkTJ0AI8GGJLfMXvKq42cj5c006fnLz6fXy6zfoVjJizi8BNTpu8on8ziI1cKy9d9DGNuY17Ce7wuejpQ=="
-    },
-    "node_modules/picocolors": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
-      "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
-    },
-    "node_modules/postcss": {
-      "version": "8.4.31",
-      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
-      "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
-      "funding": [
-        {
-          "type": "opencollective",
-          "url": "https://opencollective.com/postcss/"
-        },
-        {
-          "type": "tidelift",
-          "url": "https://tidelift.com/funding/github/npm/postcss"
-        },
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/ai"
-        }
-      ],
-      "dependencies": {
-        "nanoid": "^3.3.6",
-        "picocolors": "^1.0.0",
-        "source-map-js": "^1.0.2"
-      },
-      "engines": {
-        "node": "^10 || ^12 || >=14"
-      }
-    },
-    "node_modules/rollup": {
-      "version": "3.29.4",
-      "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz",
-      "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==",
-      "bin": {
-        "rollup": "dist/bin/rollup"
-      },
-      "engines": {
-        "node": ">=14.18.0",
-        "npm": ">=8.0.0"
-      },
-      "optionalDependencies": {
-        "fsevents": "~2.3.2"
-      }
-    },
-    "node_modules/source-map-js": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
-      "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/speech-rule-engine": {
-      "version": "4.0.7",
-      "resolved": "https://registry.npmjs.org/speech-rule-engine/-/speech-rule-engine-4.0.7.tgz",
-      "integrity": "sha512-sJrL3/wHzNwJRLBdf6CjJWIlxC04iYKkyXvYSVsWVOiC2DSkHmxsqOhEeMsBA9XK+CHuNcsdkbFDnoUfAsmp9g==",
-      "dependencies": {
-        "commander": "9.2.0",
-        "wicked-good-xpath": "1.3.0",
-        "xmldom-sre": "0.1.31"
-      },
-      "bin": {
-        "sre": "bin/sre"
-      }
-    },
-    "node_modules/typescript": {
-      "version": "4.9.5",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
-      "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
-      "dev": true,
-      "bin": {
-        "tsc": "bin/tsc",
-        "tsserver": "bin/tsserver"
-      },
-      "engines": {
-        "node": ">=4.2.0"
-      }
-    },
-    "node_modules/vite": {
-      "version": "4.5.2",
-      "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.2.tgz",
-      "integrity": "sha512-tBCZBNSBbHQkaGyhGCDUGqeo2ph8Fstyp6FMSvTtsXeZSPpSMGlviAOav2hxVTqFcx8Hj/twtWKsMJXNY0xI8w==",
-      "dependencies": {
-        "esbuild": "^0.18.10",
-        "postcss": "^8.4.27",
-        "rollup": "^3.27.1"
-      },
-      "bin": {
-        "vite": "bin/vite.js"
-      },
-      "engines": {
-        "node": "^14.18.0 || >=16.0.0"
-      },
-      "funding": {
-        "url": "https://github.com/vitejs/vite?sponsor=1"
-      },
-      "optionalDependencies": {
-        "fsevents": "~2.3.2"
-      },
-      "peerDependencies": {
-        "@types/node": ">= 14",
-        "less": "*",
-        "lightningcss": "^1.21.0",
-        "sass": "*",
-        "stylus": "*",
-        "sugarss": "*",
-        "terser": "^5.4.0"
-      },
-      "peerDependenciesMeta": {
-        "@types/node": {
-          "optional": true
-        },
-        "less": {
-          "optional": true
-        },
-        "lightningcss": {
-          "optional": true
-        },
-        "sass": {
-          "optional": true
-        },
-        "stylus": {
-          "optional": true
-        },
-        "sugarss": {
-          "optional": true
-        },
-        "terser": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/vscode-oniguruma": {
-      "version": "1.7.0",
-      "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz",
-      "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA=="
-    },
-    "node_modules/vscode-textmate": {
-      "version": "9.0.0",
-      "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-9.0.0.tgz",
-      "integrity": "sha512-Cl65diFGxz7gpwbav10HqiY/eVYTO1sjQpmRmV991Bj7wAoOAjGQ97PpQcXorDE2Uc4hnGWLY17xme+5t6MlSg=="
-    },
-    "node_modules/which": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
-      "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
-      "dependencies": {
-        "isexe": "^2.0.0"
-      },
-      "bin": {
-        "which": "bin/which"
-      }
-    },
-    "node_modules/wicked-good-xpath": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/wicked-good-xpath/-/wicked-good-xpath-1.3.0.tgz",
-      "integrity": "sha512-Gd9+TUn5nXdwj/hFsPVx5cuHHiF5Bwuc30jZ4+ronF1qHK5O7HD0sgmXWSEgwKquT3ClLoKPVbO6qGwVwLzvAw=="
-    },
-    "node_modules/xmldom-sre": {
-      "version": "0.1.31",
-      "resolved": "https://registry.npmjs.org/xmldom-sre/-/xmldom-sre-0.1.31.tgz",
-      "integrity": "sha512-f9s+fUkX04BxQf+7mMWAp5zk61pciie+fFLC9hX9UVvCeJQfNHRHXpeo5MPcR0EUf57PYLdt+ZO4f3Ipk2oZUw==",
-      "engines": {
-        "node": ">=0.1"
-      }
-    }
-  }
-}
diff --git a/animation/templates_how_functions/package.json b/animation/templates_how_functions/package.json
deleted file mode 100644
index d608000..0000000
--- a/animation/templates_how_functions/package.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
-  "name": "value_semantics",
-  "private": true,
-  "version": "0.0.0",
-  "scripts": {
-    "serve": "vite",
-    "build": "tsc && vite build"
-  },
-  "dependencies": {
-    "@motion-canvas/2d": "^3.11.0",
-    "@motion-canvas/core": "^3.11.0",
-    "@motion-canvas/ffmpeg": "^1.1.1"
-  },
-  "devDependencies": {
-    "@motion-canvas/ui": "^3.11.0",
-    "@motion-canvas/vite-plugin": "^3.11.0",
-    "typescript": "^4.9.5",
-    "vite": "^4.1.4"
-  }
-}
diff --git a/animation/templates_how_functions/src/functions/functions.tsx b/animation/templates_how_functions/src/functions/functions.tsx
deleted file mode 100644
index 458fb31..0000000
--- a/animation/templates_how_functions/src/functions/functions.tsx
+++ /dev/null
@@ -1,64 +0,0 @@
-import {
-  CodeModification,
-} from '@motion-canvas/2d/lib/components/CodeBlock';
-
-const store = (...args: [TemplateStringsArray, ...any]) => args;
-
-function to_string([strings, ...values]: [TemplateStringsArray, ...any]): string {
-  return strings.reduce((acc, str, i) => {
-    const value = values[i] ?? '';
-    return acc + str + value;
-  }, '');
-}
-
-function append(
-  template_1: TemplateStringsArray, args_1: string[],
-  template_2: TemplateStringsArray, args_2: string[]): [TemplateStringsArray, ...string[]] {
-  let new_template = Array.from<string>(template_1);
-  let new_args: Array<string> = args_1;
-  new_template[template_1.length - 1] += template_2[0]
-  new_template = new_template.concat(template_2.slice(1))
-  new_args = new_args.concat(args_2)
-  return [new_template as unknown as TemplateStringsArray, ...new_args];
-}
-
-const isCodeModification = (code: any): code is CodeModification => (code as CodeModification).from !== undefined;
-
-function simplify(
-  args_in: [TemplateStringsArray, ...any]): [TemplateStringsArray, ...string[]] {
-  const template = args_in[0]
-  const args = args_in.slice(1)
-  if (args.every((arg) => (typeof (arg) == "string") || isCodeModification(arg))) {
-    return args_in
-  }
-  let new_template: Array<any> = [];
-  let new_args: Array<any> = [];
-  let concatenate = false;
-  for (let i = 0; i <= args.length; i++) {
-    if (concatenate) {
-      concatenate = false;
-      new_template[new_template.length - 1] += template[i];
-    } else {
-      new_template.push(template[i]);
-    }
-    if (i == args.length) { break; }
-    if (typeof (args[i]) == "string" || isCodeModification(args[i])) {
-      new_args.push(args[i])
-      continue;
-    }
-    let simplified_arg = simplify(args[i]);
-    let simplified_template = simplified_arg[0]
-    let simplified_args = simplified_arg.slice(1)
-    const appended = append(
-      new_template as unknown as TemplateStringsArray,
-      new_args,
-      simplified_template,
-      simplified_args as string[]);
-    new_template = Array.from<string>(appended[0])
-    new_args = appended.slice(1)
-    concatenate = true;
-  }
-  return [new_template as unknown as TemplateStringsArray, ...new_args]
-}
-
-export {store, simplify, to_string};
diff --git a/animation/templates_how_functions/src/global.css b/animation/templates_how_functions/src/global.css
deleted file mode 100644
index 84cea14..0000000
--- a/animation/templates_how_functions/src/global.css
+++ /dev/null
@@ -1 +0,0 @@
-@import url('https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;700&display=swap');
diff --git a/animation/templates_how_functions/src/motion-canvas.d.ts b/animation/templates_how_functions/src/motion-canvas.d.ts
deleted file mode 100644
index 067c6a4..0000000
--- a/animation/templates_how_functions/src/motion-canvas.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-/// <reference types="@motion-canvas/core/project" />
diff --git a/animation/templates_how_functions/src/project.meta b/animation/templates_how_functions/src/project.meta
deleted file mode 100644
index 7579bae..0000000
--- a/animation/templates_how_functions/src/project.meta
+++ /dev/null
@@ -1,31 +0,0 @@
-{
-  "version": 0,
-  "shared": {
-    "background": "rgb(10,20,30)",
-    "range": [
-      0,
-      null
-    ],
-    "size": {
-      "x": 1920,
-      "y": 1080
-    },
-    "audioOffset": 0
-  },
-  "preview": {
-    "fps": 30,
-    "resolutionScale": 1
-  },
-  "rendering": {
-    "fps": 30,
-    "resolutionScale": 2,
-    "colorSpace": "srgb",
-    "exporter": {
-      "name": "@motion-canvas/ffmpeg",
-      "options": {
-        "fastStart": true,
-        "includeAudio": true
-      }
-    }
-  }
-}
\ No newline at end of file
diff --git a/animation/templates_how_functions/src/project.ts b/animation/templates_how_functions/src/project.ts
deleted file mode 100644
index f3931af..0000000
--- a/animation/templates_how_functions/src/project.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import {makeProject} from '@motion-canvas/core';
-
-import template_print from './scenes/template_print?scene';
-import three_types from './scenes/three_types?scene';
-import mixing_params from './scenes/mixing_params?scene';
-
-import './global.css'; // <- import the css
-
-export default makeProject({
-  scenes: [template_print],
-});
diff --git a/animation/templates_how_functions/src/scenes/how_functions.meta b/animation/templates_how_functions/src/scenes/how_functions.meta
deleted file mode 100644
index 1f67c88..0000000
--- a/animation/templates_how_functions/src/scenes/how_functions.meta
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-  "version": 0,
-  "timeEvents": [],
-  "seed": 23128358
-}
\ No newline at end of file
diff --git a/animation/templates_how_functions/src/scenes/mixing_params.meta b/animation/templates_how_functions/src/scenes/mixing_params.meta
deleted file mode 100644
index 971e43c..0000000
--- a/animation/templates_how_functions/src/scenes/mixing_params.meta
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-  "version": 0,
-  "timeEvents": [],
-  "seed": 3747377392
-}
\ No newline at end of file
diff --git a/animation/templates_how_functions/src/scenes/mixing_params.tsx b/animation/templates_how_functions/src/scenes/mixing_params.tsx
deleted file mode 100644
index 7e25ccb..0000000
--- a/animation/templates_how_functions/src/scenes/mixing_params.tsx
+++ /dev/null
@@ -1,212 +0,0 @@
-import { makeScene2D, Ray } from '@motion-canvas/2d';
-import { createRef } from '@motion-canvas/core/lib/utils';
-import {
-  CodeBlock,
-  edit,
-  insert,
-  lines,
-  word,
-  remove,
-  CodeModification,
-} from '@motion-canvas/2d/lib/components/CodeBlock';
-import { all, sequence, waitFor, waitUntil } from '@motion-canvas/core/lib/flow';
-import { DEFAULT } from '@motion-canvas/core/lib/signals';
-import { BBox, Vector2 } from '@motion-canvas/core/lib/types';
-
-import { store, simplify } from '../functions/functions'
-
-export default makeScene2D(function* (view) {
-  const code_ref = createRef<CodeBlock>();
-  const type_1_ref = createRef<CodeBlock>();
-  const type_2_ref = createRef<CodeBlock>();
-  const type_3_ref = createRef<CodeBlock>();
-  const type_4_ref = createRef<CodeBlock>();
-  const type_5_ref = createRef<CodeBlock>();
-  const type_3_3_ref = createRef<CodeBlock>();
-  const line_explicit_arguments = createRef<Ray>();
-  const line_explicit_parameters = createRef<Ray>();
-  const line_implicit_arguments = createRef<Ray>();
-  const line_implicit_parameters = createRef<Ray>();
-
-  view.add(<Ray
-    ref={line_explicit_arguments}
-    from={[-400, 130]}
-    to={[-200, 130]}
-    stroke={'white'}
-    lineWidth={8}
-    endArrow
-    end={0}
-  />);
-
-  view.add(<Ray
-    ref={line_explicit_parameters}
-    from={[-530, -220]}
-    to={[-100, -220]}
-    stroke={'white'}
-    lineWidth={8}
-    endArrow
-    end={0}
-  />);
-
-  view.add(<Ray
-    ref={line_implicit_arguments}
-    from={[-180, 130]}
-    to={[350, 130]}
-    stroke={'white'}
-    lineWidth={8}
-    endArrow
-    end={0}
-  />);
-
-  view.add(<Ray
-    ref={line_implicit_parameters}
-    from={[-100, -220]}
-    to={[700, -220]}
-    stroke={'white'}
-    lineWidth={8}
-    endArrow
-    end={0}
-  />);
-
-  yield view.add(<CodeBlock
-    ref={code_ref}
-    language="cpp"
-    fontSize={35}
-  />);
-
-  yield view.add(<CodeBlock
-    ref={type_1_ref}
-    language="cpp"
-    fontSize={35}
-    shadowBlur={10}
-    shadowColor={0x00aaee}
-  />);
-
-  yield view.add(<CodeBlock
-    ref={type_2_ref}
-    language="cpp"
-    fontSize={35}
-    shadowBlur={10}
-    shadowColor={0x00aaee}
-  />);
-
-  yield view.add(<CodeBlock
-    ref={type_3_ref}
-    language="cpp"
-    fontSize={35}
-    shadowBlur={10}
-    shadowColor={0x00aaee}
-  />);
-
-  yield view.add(<CodeBlock
-    ref={type_4_ref}
-    language="cpp"
-    fontSize={35}
-    shadowBlur={10}
-    shadowColor={0x00aaee}
-  />);
-
-  yield view.add(<CodeBlock
-    ref={type_5_ref}
-    language="cpp"
-    fontSize={35}
-    shadowBlur={10}
-    shadowColor={0x00aaee}
-  />);
-
-  yield view.add(<CodeBlock
-    ref={type_3_3_ref}
-    language="cpp"
-    fontSize={35}
-    shadowBlur={10}
-    shadowColor={0x00aaee}
-  />);
-
-  const code_three_types = () => store`
-  template<class One, int kTwo, class Three, class Four, class Five>
-  void SomeFunction(Three three, Four four, Five five, Three one_more) {
-    // Some implementation;
-  }
-
-  int main() {
-    SomeFunction<float, 42>(42.42, 23, 23.23F, 23.42);
-  }
-`
-
-  const type_code = (some_type: any = ``) => store`${some_type}`
-
-  const zoom_fn = (in_zoom: number) => new Vector2(in_zoom, in_zoom);
-
-  const duration = 1.5
-
-  yield* code_ref().edit(0, false)(...code_three_types());
-  yield* waitFor(duration);
-
-  yield* type_1_ref().position([-350, 83], 0);
-  yield* type_2_ref().position([-230, 83], 0);
-  yield* type_3_ref().position([-120, 83], 0);
-  yield* type_4_ref().position([0, 83], 0);
-  yield* type_5_ref().position([130, 83], 0);
-  yield* type_3_3_ref().position([300, 83], 0);
-  yield* sequence(
-    duration / 2,
-    all(
-      line_explicit_arguments().end(1, duration),
-      line_explicit_parameters().end(1, duration),
-    ),
-    all(
-      type_1_ref().edit(duration / 2, false)(...type_code(insert("float"))),
-      type_1_ref().position([-350, 40], duration / 2).to([-370, -280], duration / 2),
-      type_1_ref().scale(1.5, duration / 2),
-    ),
-    all(
-      type_2_ref().edit(duration / 2, false)(...type_code(insert("42"))),
-      type_2_ref().position([-230, 40], duration / 2).to([-170, -280], duration / 2),
-      type_2_ref().scale(1.5, duration / 2),
-    ),
-    all(
-      line_explicit_arguments().start(1, duration),
-      line_explicit_parameters().start(1, duration),
-    )
-  );
-  yield* waitFor(duration);
-
-  yield* sequence(
-    duration / 2,
-    all(
-      line_implicit_arguments().end(1, duration),
-      line_implicit_parameters().end(1, duration),
-    ),
-    all(
-      type_3_ref().edit(duration / 2, false)(...type_code(insert("double"))),
-      type_3_ref().position([-120, 40], duration / 2).to([90, -280], duration / 2),
-      type_3_ref().scale(1.5, duration / 2),
-    ),
-    all(
-      type_4_ref().edit(duration / 2, false)(...type_code(insert("int"))),
-      type_4_ref().position([0, 40], duration / 2).to([340, -280], duration / 2),
-      type_4_ref().scale(1.5, duration / 2),
-    ),
-    all(
-      type_5_ref().edit(duration / 2, false)(...type_code(insert("float"))),
-      type_5_ref().position([130, 40], duration / 2).to([600, -280], duration / 2),
-      type_5_ref().scale(1.5, duration / 2),
-    ),
-    all(
-      type_3_3_ref().edit(duration / 2, false)(...type_code(insert("double"))),
-      type_3_3_ref().position([300, 40], duration / 2).to([90, -350], duration / 2),
-      type_3_3_ref().scale(1.5, duration / 2),
-    ),
-    all(
-      type_3_3_ref().position([90, -350], duration / 2).to([90, -280], duration / 2),
-
-    ),
-    type_3_3_ref().shadowBlur(10000, duration),
-    all(
-      line_implicit_arguments().start(1, duration),
-      line_implicit_parameters().start(1, duration),
-    )
-  );
-  yield* waitFor(duration);
-
-});
diff --git a/animation/templates_how_functions/src/scenes/template_print.meta b/animation/templates_how_functions/src/scenes/template_print.meta
deleted file mode 100644
index a10885f..0000000
--- a/animation/templates_how_functions/src/scenes/template_print.meta
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-  "version": 0,
-  "timeEvents": [],
-  "seed": 3669514604
-}
\ No newline at end of file
diff --git a/animation/templates_how_functions/src/scenes/template_print.tsx b/animation/templates_how_functions/src/scenes/template_print.tsx
deleted file mode 100644
index ab9e468..0000000
--- a/animation/templates_how_functions/src/scenes/template_print.tsx
+++ /dev/null
@@ -1,80 +0,0 @@
-import { makeScene2D } from '@motion-canvas/2d/lib/scenes';
-import { createRef } from '@motion-canvas/core/lib/utils';
-import {
-  CodeBlock,
-  edit,
-  insert,
-  lines,
-  word,
-  remove,
-  CodeModification,
-} from '@motion-canvas/2d/lib/components/CodeBlock';
-import { all, waitFor, waitUntil } from '@motion-canvas/core/lib/flow';
-import { DEFAULT } from '@motion-canvas/core/lib/signals';
-import { BBox, Vector2 } from '@motion-canvas/core/lib/types';
-
-import { store, simplify } from '../functions/functions'
-
-export default makeScene2D(function* (view) {
-  const codeRef = createRef<CodeBlock>();
-
-  yield view.add(<CodeBlock
-    ref={codeRef}
-    language="cpp"
-    fontSize={35}
-  />);
-
-
-  const code_template_print = (template: any = '',
-    template_type: any = 'int',
-    comment_int: any = '',
-    print_float: any = '',
-  ) => store`
-#include <iostream>
-
-${template}void Print(${template_type} p) {
-  std::cout << p << "\\n";
-}
-
-int main() {
-  Print(42);${comment_int}${print_float}
-  return 0;
-}
-`
-
-  const code_template = (template: any = '',
-    return_type: any = 'int',
-    type_1: any = 'int',
-    type_2: any = 'int',
-    template_params: any = ''
-  ) => store`
-${template}${return_type} SomeFunction(${type_1} value_1, ${type_2} value_2) {
-  ${return_type} result = DoSomething${template_params}(value_1, value_2);
-  return result;
-}
-`
-
-  const zoom_fn = (in_zoom: number) => new Vector2(in_zoom, in_zoom);
-
-  const duration = 1.5
-
-  // yield* codeRef().edit(0, false)(...code_template_print());
-  // yield* waitFor(duration);
-  // yield* codeRef().edit(duration, false)(...simplify(
-  //   code_template_print(insert("template <typename T>\n"),
-  //     edit("int", "T"),
-  //     insert("     // T=int"),
-  //     insert("\n  Print(42.42);  // T=double"))));
-  // yield* waitFor(duration);
-
-  yield* codeRef().fontSize(50, 0);
-  yield* codeRef().edit(0, false)(...code_template());
-  yield* waitFor(duration);
-  yield* codeRef().edit(duration, false)(...simplify(
-    code_template(insert("template <int kNumber, typename T1, typename T2>\n"),
-      edit("int", "T1"),
-      edit("int", "T1"),
-      edit("int", "T2"),
-      insert("<kNumber>"))));
-  yield* waitFor(duration);
-});
diff --git a/animation/templates_how_functions/src/scenes/three_types.meta b/animation/templates_how_functions/src/scenes/three_types.meta
deleted file mode 100644
index 62675f0..0000000
--- a/animation/templates_how_functions/src/scenes/three_types.meta
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-  "version": 0,
-  "timeEvents": [],
-  "seed": 1824033234
-}
\ No newline at end of file
diff --git a/animation/templates_how_functions/src/scenes/three_types.tsx b/animation/templates_how_functions/src/scenes/three_types.tsx
deleted file mode 100644
index 9f7466a..0000000
--- a/animation/templates_how_functions/src/scenes/three_types.tsx
+++ /dev/null
@@ -1,45 +0,0 @@
-import { makeScene2D } from '@motion-canvas/2d/lib/scenes';
-import { createRef } from '@motion-canvas/core/lib/utils';
-import {
-  CodeBlock,
-  edit,
-  insert,
-  lines,
-  word,
-  remove,
-  CodeModification,
-} from '@motion-canvas/2d/lib/components/CodeBlock';
-import { all, waitFor, waitUntil } from '@motion-canvas/core/lib/flow';
-import { DEFAULT } from '@motion-canvas/core/lib/signals';
-import { BBox, Vector2 } from '@motion-canvas/core/lib/types';
-
-import { store, simplify } from '../functions/functions'
-
-export default makeScene2D(function* (view) {
-  const codeRef = createRef<CodeBlock>();
-
-  yield view.add(<CodeBlock
-    ref={codeRef}
-    language="cpp"
-    fontSize={35}
-  />);
-
-  const code_three_types = (template: any = '',
-    template_type: any = 'int',
-  ) => store`
-${template}void SomeFunction(${template_type} one, ${template_type} two, ${template_type} three) {
-  // Do something important
-}
-`
-
-  const zoom_fn = (in_zoom: number) => new Vector2(in_zoom, in_zoom);
-
-  const duration = 1.5
-
-  yield* codeRef().edit(0, false)(...code_three_types());
-  yield* waitFor(duration);
-  yield* codeRef().edit(duration, false)(...simplify(
-    code_three_types(insert("template <typename T>\n"),
-      edit("int", "T"))));
-  yield* waitFor(duration);
-});
diff --git a/animation/templates_how_functions/tsconfig.json b/animation/templates_how_functions/tsconfig.json
deleted file mode 100644
index 789b7d1..0000000
--- a/animation/templates_how_functions/tsconfig.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-  "extends": "@motion-canvas/2d/tsconfig.project.json",
-  "compilerOptions": {
-    "baseUrl": "src"
-  },
-  "include": ["src"]
-}
diff --git a/animation/templates_how_functions/vite.config.ts b/animation/templates_how_functions/vite.config.ts
deleted file mode 100644
index a463c29..0000000
--- a/animation/templates_how_functions/vite.config.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import { defineConfig } from 'vite';
-import motionCanvas from '@motion-canvas/vite-plugin';
-import ffmpeg from '@motion-canvas/ffmpeg';
-
-export default defineConfig({
-  plugins: [
-    motionCanvas(),
-    ffmpeg()
-  ],
-});
diff --git a/animation/templates_why/.gitignore b/animation/templates_why/.gitignore
deleted file mode 100644
index 829b1c7..0000000
--- a/animation/templates_why/.gitignore
+++ /dev/null
@@ -1,15 +0,0 @@
-# Generated files
-node_modules
-output
-dist
-
-# Editor directories and files
-.vscode/*
-!.vscode/extensions.json
-.idea
-.DS_Store
-*.suo
-*.ntvs*
-*.njsproj
-*.sln
-*.sw?
diff --git a/animation/templates_why/package-lock.json b/animation/templates_why/package-lock.json
deleted file mode 100644
index 31011a8..0000000
--- a/animation/templates_why/package-lock.json
+++ /dev/null
@@ -1,1041 +0,0 @@
-{
-  "name": "value_semantics",
-  "version": "0.0.0",
-  "lockfileVersion": 3,
-  "requires": true,
-  "packages": {
-    "": {
-      "name": "value_semantics",
-      "version": "0.0.0",
-      "dependencies": {
-        "@motion-canvas/2d": "^3.11.0",
-        "@motion-canvas/core": "^3.11.0",
-        "@motion-canvas/ffmpeg": "^1.1.1"
-      },
-      "devDependencies": {
-        "@motion-canvas/ui": "^3.11.0",
-        "@motion-canvas/vite-plugin": "^3.11.0",
-        "typescript": "^4.9.5",
-        "vite": "^4.1.4"
-      }
-    },
-    "node_modules/@esbuild/android-arm": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
-      "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==",
-      "cpu": [
-        "arm"
-      ],
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/android-arm64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz",
-      "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/android-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz",
-      "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/darwin-arm64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz",
-      "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/darwin-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz",
-      "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/freebsd-arm64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz",
-      "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "freebsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/freebsd-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz",
-      "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "freebsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-arm": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz",
-      "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==",
-      "cpu": [
-        "arm"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-arm64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz",
-      "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-ia32": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz",
-      "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==",
-      "cpu": [
-        "ia32"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-loong64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz",
-      "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==",
-      "cpu": [
-        "loong64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-mips64el": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz",
-      "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==",
-      "cpu": [
-        "mips64el"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-ppc64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz",
-      "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==",
-      "cpu": [
-        "ppc64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-riscv64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz",
-      "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==",
-      "cpu": [
-        "riscv64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-s390x": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz",
-      "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==",
-      "cpu": [
-        "s390x"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz",
-      "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/netbsd-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz",
-      "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "netbsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/openbsd-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz",
-      "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "openbsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/sunos-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz",
-      "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "sunos"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/win32-arm64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz",
-      "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/win32-ia32": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz",
-      "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==",
-      "cpu": [
-        "ia32"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/win32-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz",
-      "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@ffmpeg-installer/darwin-arm64": {
-      "version": "4.1.5",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/darwin-arm64/-/darwin-arm64-4.1.5.tgz",
-      "integrity": "sha512-hYqTiP63mXz7wSQfuqfFwfLOfwwFChUedeCVKkBtl/cliaTM7/ePI9bVzfZ2c+dWu3TqCwLDRWNSJ5pqZl8otA==",
-      "cpu": [
-        "arm64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/darwin-x64": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/darwin-x64/-/darwin-x64-4.1.0.tgz",
-      "integrity": "sha512-Z4EyG3cIFjdhlY8wI9aLUXuH8nVt7E9SlMVZtWvSPnm2sm37/yC2CwjUzyCQbJbySnef1tQwGG2Sx+uWhd9IAw==",
-      "cpu": [
-        "x64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/ffmpeg": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/ffmpeg/-/ffmpeg-1.1.0.tgz",
-      "integrity": "sha512-Uq4rmwkdGxIa9A6Bd/VqqYbT7zqh1GrT5/rFwCwKM70b42W5gIjWeVETq6SdcL0zXqDtY081Ws/iJWhr1+xvQg==",
-      "optionalDependencies": {
-        "@ffmpeg-installer/darwin-arm64": "4.1.5",
-        "@ffmpeg-installer/darwin-x64": "4.1.0",
-        "@ffmpeg-installer/linux-arm": "4.1.3",
-        "@ffmpeg-installer/linux-arm64": "4.1.4",
-        "@ffmpeg-installer/linux-ia32": "4.1.0",
-        "@ffmpeg-installer/linux-x64": "4.1.0",
-        "@ffmpeg-installer/win32-ia32": "4.1.0",
-        "@ffmpeg-installer/win32-x64": "4.1.0"
-      }
-    },
-    "node_modules/@ffmpeg-installer/linux-arm": {
-      "version": "4.1.3",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/linux-arm/-/linux-arm-4.1.3.tgz",
-      "integrity": "sha512-NDf5V6l8AfzZ8WzUGZ5mV8O/xMzRag2ETR6+TlGIsMHp81agx51cqpPItXPib/nAZYmo55Bl2L6/WOMI3A5YRg==",
-      "cpu": [
-        "arm"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/linux-arm64": {
-      "version": "4.1.4",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/linux-arm64/-/linux-arm64-4.1.4.tgz",
-      "integrity": "sha512-dljEqAOD0oIM6O6DxBW9US/FkvqvQwgJ2lGHOwHDDwu/pX8+V0YsDL1xqHbj1DMX/+nP9rxw7G7gcUvGspSoKg==",
-      "cpu": [
-        "arm64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/linux-ia32": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/linux-ia32/-/linux-ia32-4.1.0.tgz",
-      "integrity": "sha512-0LWyFQnPf+Ij9GQGD034hS6A90URNu9HCtQ5cTqo5MxOEc7Rd8gLXrJvn++UmxhU0J5RyRE9KRYstdCVUjkNOQ==",
-      "cpu": [
-        "ia32"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/linux-x64": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/linux-x64/-/linux-x64-4.1.0.tgz",
-      "integrity": "sha512-Y5BWhGLU/WpQjOArNIgXD3z5mxxdV8c41C+U15nsE5yF8tVcdCGet5zPs5Zy3Ta6bU7haGpIzryutqCGQA/W8A==",
-      "cpu": [
-        "x64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/win32-ia32": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/win32-ia32/-/win32-ia32-4.1.0.tgz",
-      "integrity": "sha512-FV2D7RlaZv/lrtdhaQ4oETwoFUsUjlUiasiZLDxhEUPdNDWcH1OU9K1xTvqz+OXLdsmYelUDuBS/zkMOTtlUAw==",
-      "cpu": [
-        "ia32"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ]
-    },
-    "node_modules/@ffmpeg-installer/win32-x64": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/@ffmpeg-installer/win32-x64/-/win32-x64-4.1.0.tgz",
-      "integrity": "sha512-Drt5u2vzDnIONf4ZEkKtFlbvwj6rI3kxw1Ck9fpudmtgaZIHD4ucsWB2lCZBXRxJgXR+2IMSti+4rtM4C4rXgg==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ]
-    },
-    "node_modules/@ffprobe-installer/darwin-arm64": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/darwin-arm64/-/darwin-arm64-5.0.1.tgz",
-      "integrity": "sha512-vwNCNjokH8hfkbl6m95zICHwkSzhEvDC3GVBcUp5HX8+4wsX10SP3B+bGur7XUzTIZ4cQpgJmEIAx6TUwRepMg==",
-      "cpu": [
-        "arm64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ]
-    },
-    "node_modules/@ffprobe-installer/darwin-x64": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/darwin-x64/-/darwin-x64-5.1.0.tgz",
-      "integrity": "sha512-J+YGscZMpQclFg31O4cfVRGmDpkVsQ2fZujoUdMAAYcP0NtqpC49Hs3SWJpBdsGB4VeqOt5TTm1vSZQzs1NkhA==",
-      "cpu": [
-        "x64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ]
-    },
-    "node_modules/@ffprobe-installer/ffprobe": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/ffprobe/-/ffprobe-2.1.2.tgz",
-      "integrity": "sha512-ZNvwk4f2magF42Zji2Ese16SMj9BS7Fui4kRjg6gTYTxY3gWZNpg85n4MIfQyI9nimHg4x/gT6FVkp/bBDuBwg==",
-      "engines": {
-        "node": ">=14.21.2"
-      },
-      "optionalDependencies": {
-        "@ffprobe-installer/darwin-arm64": "5.0.1",
-        "@ffprobe-installer/darwin-x64": "5.1.0",
-        "@ffprobe-installer/linux-arm": "5.2.0",
-        "@ffprobe-installer/linux-arm64": "5.2.0",
-        "@ffprobe-installer/linux-ia32": "5.2.0",
-        "@ffprobe-installer/linux-x64": "5.2.0",
-        "@ffprobe-installer/win32-ia32": "5.1.0",
-        "@ffprobe-installer/win32-x64": "5.1.0"
-      }
-    },
-    "node_modules/@ffprobe-installer/linux-arm": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/linux-arm/-/linux-arm-5.2.0.tgz",
-      "integrity": "sha512-PF5HqEhCY7WTWHtLDYbA/+rLS+rhslWvyBlAG1Fk8VzVlnRdl93o6hy7DE2kJgxWQbFaR3ZktPQGEzfkrmQHvQ==",
-      "cpu": [
-        "arm"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffprobe-installer/linux-arm64": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/linux-arm64/-/linux-arm64-5.2.0.tgz",
-      "integrity": "sha512-X1VvWtlLs6ScP73biVLuHD5ohKJKsMTa0vafCESOen4mOoNeLAYbxOVxDWAdFz9cpZgRiloFj5QD6nDj8E28yQ==",
-      "cpu": [
-        "arm64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffprobe-installer/linux-ia32": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/linux-ia32/-/linux-ia32-5.2.0.tgz",
-      "integrity": "sha512-TFVK5sasXyXhbIG7LtPRDmtkrkOsInwKcL43iEvEw+D9vCS2rc//mn9/0Q+BR0UoJEiMK4+ApYr/3LLVUBPOCQ==",
-      "cpu": [
-        "ia32"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffprobe-installer/linux-x64": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/linux-x64/-/linux-x64-5.2.0.tgz",
-      "integrity": "sha512-D3UeqTLYPNs7pBWPLUYGehPdRVqU8eACox4OZy3pZUZatxye2YKlvBwEfaLdL1v2Z4FOAlLUhms0kY8m8kqSRA==",
-      "cpu": [
-        "x64"
-      ],
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "linux"
-      ]
-    },
-    "node_modules/@ffprobe-installer/win32-ia32": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/win32-ia32/-/win32-ia32-5.1.0.tgz",
-      "integrity": "sha512-5O3vOoNRxmut0/Nu9vSazTdSHasrr+zPT2B3Hm7kjmO3QVFcIfVImS6ReQnZeSy8JPJOqXts5kX5x/3KOX54XQ==",
-      "cpu": [
-        "ia32"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ]
-    },
-    "node_modules/@ffprobe-installer/win32-x64": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/@ffprobe-installer/win32-x64/-/win32-x64-5.1.0.tgz",
-      "integrity": "sha512-jMGYeAgkrdn4e2vvYt/qakgHRE3CPju4bn5TmdPfoAm1BlX1mY9cyMd8gf5vSzI8gH8Zq5WQAyAkmekX/8TSTg==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ]
-    },
-    "node_modules/@motion-canvas/2d": {
-      "version": "3.11.0",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/2d/-/2d-3.11.0.tgz",
-      "integrity": "sha512-T/RPXGRxddO/xxbC2RcOXfrtBTp8lfcmnuW1fa6++0qy0chK5NFxm3bHJczCbX0ynKB2VAoqLNobTF9eD6ZP3w==",
-      "dependencies": {
-        "@motion-canvas/core": "^3.11.0",
-        "code-fns": "^0.8.2",
-        "mathjax-full": "^3.2.2",
-        "parse-svg-path": "^0.1.2"
-      }
-    },
-    "node_modules/@motion-canvas/core": {
-      "version": "3.11.0",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/core/-/core-3.11.0.tgz",
-      "integrity": "sha512-/WjdoSTqTPwCgrB2pP8YXq2T3KviYHrywVxXJ5fEjQ1gajkPKYD7aVlRcY1+kaTbwqXhCARMCh+pSjT2nfhTsw==",
-      "dependencies": {
-        "@types/chroma-js": "^2.1.4",
-        "chroma-js": "^2.4.2"
-      },
-      "peerDependencies": {
-        "vite": "^4.1.4"
-      }
-    },
-    "node_modules/@motion-canvas/ffmpeg": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/ffmpeg/-/ffmpeg-1.1.1.tgz",
-      "integrity": "sha512-w2d7oFfR3hYHXeYtFGoHp6goY+vVL0LoZ2h1b/veTH5KvE7jrLp2Kl/XPHsYJ5ZDRHUT0Nhl05DBLdXYqdSqgg==",
-      "dependencies": {
-        "@ffmpeg-installer/ffmpeg": "^1.1.0",
-        "@ffprobe-installer/ffprobe": "^2.0.0",
-        "fluent-ffmpeg": "^2.1.2"
-      },
-      "peerDependencies": {
-        "@motion-canvas/core": "^3.7.0",
-        "@motion-canvas/vite-plugin": "^3.7.0",
-        "vite": "4.x"
-      }
-    },
-    "node_modules/@motion-canvas/ui": {
-      "version": "3.11.0",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/ui/-/ui-3.11.0.tgz",
-      "integrity": "sha512-sd0GxvCkejL2lzExsvgLsC1GgHzLP/0LlMw1QE2/3pMQo3rMOVA7L1Oq6br8HqdJhzMEgW3DWC0NjDJsUfkL2A==",
-      "dev": true,
-      "dependencies": {
-        "@motion-canvas/core": "^3.11.0"
-      }
-    },
-    "node_modules/@motion-canvas/vite-plugin": {
-      "version": "3.11.0",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/vite-plugin/-/vite-plugin-3.11.0.tgz",
-      "integrity": "sha512-26ixfy5NhvFePj1DBdh7MFsgevpRrzzEKjzSyCK3FOvPcnUWFjab4wWErpsIEnu6a0p7yj4w9VKpa8USx6N95A==",
-      "dependencies": {
-        "follow-redirects": "^1.15.2",
-        "mime-types": "^2.1.35"
-      },
-      "peerDependencies": {
-        "vite": "4.x"
-      }
-    },
-    "node_modules/@types/chroma-js": {
-      "version": "2.4.0",
-      "resolved": "https://registry.npmjs.org/@types/chroma-js/-/chroma-js-2.4.0.tgz",
-      "integrity": "sha512-JklMxityrwjBTjGY2anH8JaTx3yjRU3/sEHSblLH1ba5lqcSh1LnImXJZO5peJfXyqKYWjHTGy4s5Wz++hARrw=="
-    },
-    "node_modules/@types/hast": {
-      "version": "2.3.4",
-      "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.4.tgz",
-      "integrity": "sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==",
-      "dependencies": {
-        "@types/unist": "*"
-      }
-    },
-    "node_modules/@types/unist": {
-      "version": "2.0.6",
-      "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz",
-      "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ=="
-    },
-    "node_modules/@wooorm/starry-night": {
-      "version": "1.7.0",
-      "resolved": "https://registry.npmjs.org/@wooorm/starry-night/-/starry-night-1.7.0.tgz",
-      "integrity": "sha512-ktO0nkddrovIoNW2jAUT+Cdd9n1bWjy1Ir4CdcmgTaT6E94HLlQfu7Yv62falclBEwvsuVp3bSBw23wtta1fNw==",
-      "dependencies": {
-        "@types/hast": "^2.0.0",
-        "import-meta-resolve": "^2.0.0",
-        "vscode-oniguruma": "^1.0.0",
-        "vscode-textmate": "^9.0.0"
-      },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/wooorm"
-      }
-    },
-    "node_modules/async": {
-      "version": "3.2.4",
-      "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz",
-      "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ=="
-    },
-    "node_modules/chroma-js": {
-      "version": "2.4.2",
-      "resolved": "https://registry.npmjs.org/chroma-js/-/chroma-js-2.4.2.tgz",
-      "integrity": "sha512-U9eDw6+wt7V8z5NncY2jJfZa+hUH8XEj8FQHgFJTrUFnJfXYf4Ml4adI2vXZOjqRDpFWtYVWypDfZwnJ+HIR4A=="
-    },
-    "node_modules/code-fns": {
-      "version": "0.8.2",
-      "resolved": "https://registry.npmjs.org/code-fns/-/code-fns-0.8.2.tgz",
-      "integrity": "sha512-3VVeq3cnWxWiWKFLsVo+XWsOXBSW2gAx2uv0ViETLNmNuygEPHlCeDAv/Zy7xXqPgXtgLZyvIJZmx+ojTgOIGA==",
-      "dependencies": {
-        "@wooorm/starry-night": "^1.2.0"
-      }
-    },
-    "node_modules/commander": {
-      "version": "9.2.0",
-      "resolved": "https://registry.npmjs.org/commander/-/commander-9.2.0.tgz",
-      "integrity": "sha512-e2i4wANQiSXgnrBlIatyHtP1odfUp0BbV5Y5nEGbxtIrStkEOAAzCUirvLBNXHLr7kwLvJl6V+4V3XV9x7Wd9w==",
-      "engines": {
-        "node": "^12.20.0 || >=14"
-      }
-    },
-    "node_modules/esbuild": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz",
-      "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==",
-      "hasInstallScript": true,
-      "bin": {
-        "esbuild": "bin/esbuild"
-      },
-      "engines": {
-        "node": ">=12"
-      },
-      "optionalDependencies": {
-        "@esbuild/android-arm": "0.18.20",
-        "@esbuild/android-arm64": "0.18.20",
-        "@esbuild/android-x64": "0.18.20",
-        "@esbuild/darwin-arm64": "0.18.20",
-        "@esbuild/darwin-x64": "0.18.20",
-        "@esbuild/freebsd-arm64": "0.18.20",
-        "@esbuild/freebsd-x64": "0.18.20",
-        "@esbuild/linux-arm": "0.18.20",
-        "@esbuild/linux-arm64": "0.18.20",
-        "@esbuild/linux-ia32": "0.18.20",
-        "@esbuild/linux-loong64": "0.18.20",
-        "@esbuild/linux-mips64el": "0.18.20",
-        "@esbuild/linux-ppc64": "0.18.20",
-        "@esbuild/linux-riscv64": "0.18.20",
-        "@esbuild/linux-s390x": "0.18.20",
-        "@esbuild/linux-x64": "0.18.20",
-        "@esbuild/netbsd-x64": "0.18.20",
-        "@esbuild/openbsd-x64": "0.18.20",
-        "@esbuild/sunos-x64": "0.18.20",
-        "@esbuild/win32-arm64": "0.18.20",
-        "@esbuild/win32-ia32": "0.18.20",
-        "@esbuild/win32-x64": "0.18.20"
-      }
-    },
-    "node_modules/esm": {
-      "version": "3.2.25",
-      "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz",
-      "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==",
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/fluent-ffmpeg": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/fluent-ffmpeg/-/fluent-ffmpeg-2.1.2.tgz",
-      "integrity": "sha512-IZTB4kq5GK0DPp7sGQ0q/BWurGHffRtQQwVkiqDgeO6wYJLLV5ZhgNOQ65loZxxuPMKZKZcICCUnaGtlxBiR0Q==",
-      "dependencies": {
-        "async": ">=0.2.9",
-        "which": "^1.1.1"
-      },
-      "engines": {
-        "node": ">=0.8.0"
-      }
-    },
-    "node_modules/follow-redirects": {
-      "version": "1.15.5",
-      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz",
-      "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==",
-      "funding": [
-        {
-          "type": "individual",
-          "url": "https://github.com/sponsors/RubenVerborgh"
-        }
-      ],
-      "engines": {
-        "node": ">=4.0"
-      },
-      "peerDependenciesMeta": {
-        "debug": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/fsevents": {
-      "version": "2.3.3",
-      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
-      "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
-      }
-    },
-    "node_modules/import-meta-resolve": {
-      "version": "2.2.2",
-      "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-2.2.2.tgz",
-      "integrity": "sha512-f8KcQ1D80V7RnqVm+/lirO9zkOxjGxhaTC1IPrBGd3MEfNgmNG67tSUO9gTi2F3Blr2Az6g1vocaxzkVnWl9MA==",
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/wooorm"
-      }
-    },
-    "node_modules/isexe": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
-      "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
-    },
-    "node_modules/mathjax-full": {
-      "version": "3.2.2",
-      "resolved": "https://registry.npmjs.org/mathjax-full/-/mathjax-full-3.2.2.tgz",
-      "integrity": "sha512-+LfG9Fik+OuI8SLwsiR02IVdjcnRCy5MufYLi0C3TdMT56L/pjB0alMVGgoWJF8pN9Rc7FESycZB9BMNWIid5w==",
-      "dependencies": {
-        "esm": "^3.2.25",
-        "mhchemparser": "^4.1.0",
-        "mj-context-menu": "^0.6.1",
-        "speech-rule-engine": "^4.0.6"
-      }
-    },
-    "node_modules/mhchemparser": {
-      "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/mhchemparser/-/mhchemparser-4.1.1.tgz",
-      "integrity": "sha512-R75CUN6O6e1t8bgailrF1qPq+HhVeFTM3XQ0uzI+mXTybmphy3b6h4NbLOYhemViQ3lUs+6CKRkC3Ws1TlYREA=="
-    },
-    "node_modules/mime-db": {
-      "version": "1.52.0",
-      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
-      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/mime-types": {
-      "version": "2.1.35",
-      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
-      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
-      "dependencies": {
-        "mime-db": "1.52.0"
-      },
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/mj-context-menu": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/mj-context-menu/-/mj-context-menu-0.6.1.tgz",
-      "integrity": "sha512-7NO5s6n10TIV96d4g2uDpG7ZDpIhMh0QNfGdJw/W47JswFcosz457wqz/b5sAKvl12sxINGFCn80NZHKwxQEXA=="
-    },
-    "node_modules/nanoid": {
-      "version": "3.3.6",
-      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
-      "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/ai"
-        }
-      ],
-      "bin": {
-        "nanoid": "bin/nanoid.cjs"
-      },
-      "engines": {
-        "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
-      }
-    },
-    "node_modules/parse-svg-path": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/parse-svg-path/-/parse-svg-path-0.1.2.tgz",
-      "integrity": "sha512-JyPSBnkTJ0AI8GGJLfMXvKq42cj5c006fnLz6fXy6zfoVjJizi8BNTpu8on8ziI1cKy9d9DGNuY17Ce7wuejpQ=="
-    },
-    "node_modules/picocolors": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
-      "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
-    },
-    "node_modules/postcss": {
-      "version": "8.4.31",
-      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
-      "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
-      "funding": [
-        {
-          "type": "opencollective",
-          "url": "https://opencollective.com/postcss/"
-        },
-        {
-          "type": "tidelift",
-          "url": "https://tidelift.com/funding/github/npm/postcss"
-        },
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/ai"
-        }
-      ],
-      "dependencies": {
-        "nanoid": "^3.3.6",
-        "picocolors": "^1.0.0",
-        "source-map-js": "^1.0.2"
-      },
-      "engines": {
-        "node": "^10 || ^12 || >=14"
-      }
-    },
-    "node_modules/rollup": {
-      "version": "3.29.4",
-      "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz",
-      "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==",
-      "bin": {
-        "rollup": "dist/bin/rollup"
-      },
-      "engines": {
-        "node": ">=14.18.0",
-        "npm": ">=8.0.0"
-      },
-      "optionalDependencies": {
-        "fsevents": "~2.3.2"
-      }
-    },
-    "node_modules/source-map-js": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
-      "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/speech-rule-engine": {
-      "version": "4.0.7",
-      "resolved": "https://registry.npmjs.org/speech-rule-engine/-/speech-rule-engine-4.0.7.tgz",
-      "integrity": "sha512-sJrL3/wHzNwJRLBdf6CjJWIlxC04iYKkyXvYSVsWVOiC2DSkHmxsqOhEeMsBA9XK+CHuNcsdkbFDnoUfAsmp9g==",
-      "dependencies": {
-        "commander": "9.2.0",
-        "wicked-good-xpath": "1.3.0",
-        "xmldom-sre": "0.1.31"
-      },
-      "bin": {
-        "sre": "bin/sre"
-      }
-    },
-    "node_modules/typescript": {
-      "version": "4.9.5",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
-      "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
-      "dev": true,
-      "bin": {
-        "tsc": "bin/tsc",
-        "tsserver": "bin/tsserver"
-      },
-      "engines": {
-        "node": ">=4.2.0"
-      }
-    },
-    "node_modules/vite": {
-      "version": "4.5.2",
-      "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.2.tgz",
-      "integrity": "sha512-tBCZBNSBbHQkaGyhGCDUGqeo2ph8Fstyp6FMSvTtsXeZSPpSMGlviAOav2hxVTqFcx8Hj/twtWKsMJXNY0xI8w==",
-      "dependencies": {
-        "esbuild": "^0.18.10",
-        "postcss": "^8.4.27",
-        "rollup": "^3.27.1"
-      },
-      "bin": {
-        "vite": "bin/vite.js"
-      },
-      "engines": {
-        "node": "^14.18.0 || >=16.0.0"
-      },
-      "funding": {
-        "url": "https://github.com/vitejs/vite?sponsor=1"
-      },
-      "optionalDependencies": {
-        "fsevents": "~2.3.2"
-      },
-      "peerDependencies": {
-        "@types/node": ">= 14",
-        "less": "*",
-        "lightningcss": "^1.21.0",
-        "sass": "*",
-        "stylus": "*",
-        "sugarss": "*",
-        "terser": "^5.4.0"
-      },
-      "peerDependenciesMeta": {
-        "@types/node": {
-          "optional": true
-        },
-        "less": {
-          "optional": true
-        },
-        "lightningcss": {
-          "optional": true
-        },
-        "sass": {
-          "optional": true
-        },
-        "stylus": {
-          "optional": true
-        },
-        "sugarss": {
-          "optional": true
-        },
-        "terser": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/vscode-oniguruma": {
-      "version": "1.7.0",
-      "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz",
-      "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA=="
-    },
-    "node_modules/vscode-textmate": {
-      "version": "9.0.0",
-      "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-9.0.0.tgz",
-      "integrity": "sha512-Cl65diFGxz7gpwbav10HqiY/eVYTO1sjQpmRmV991Bj7wAoOAjGQ97PpQcXorDE2Uc4hnGWLY17xme+5t6MlSg=="
-    },
-    "node_modules/which": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
-      "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
-      "dependencies": {
-        "isexe": "^2.0.0"
-      },
-      "bin": {
-        "which": "bin/which"
-      }
-    },
-    "node_modules/wicked-good-xpath": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/wicked-good-xpath/-/wicked-good-xpath-1.3.0.tgz",
-      "integrity": "sha512-Gd9+TUn5nXdwj/hFsPVx5cuHHiF5Bwuc30jZ4+ronF1qHK5O7HD0sgmXWSEgwKquT3ClLoKPVbO6qGwVwLzvAw=="
-    },
-    "node_modules/xmldom-sre": {
-      "version": "0.1.31",
-      "resolved": "https://registry.npmjs.org/xmldom-sre/-/xmldom-sre-0.1.31.tgz",
-      "integrity": "sha512-f9s+fUkX04BxQf+7mMWAp5zk61pciie+fFLC9hX9UVvCeJQfNHRHXpeo5MPcR0EUf57PYLdt+ZO4f3Ipk2oZUw==",
-      "engines": {
-        "node": ">=0.1"
-      }
-    }
-  }
-}
diff --git a/animation/templates_why/package.json b/animation/templates_why/package.json
deleted file mode 100644
index d608000..0000000
--- a/animation/templates_why/package.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
-  "name": "value_semantics",
-  "private": true,
-  "version": "0.0.0",
-  "scripts": {
-    "serve": "vite",
-    "build": "tsc && vite build"
-  },
-  "dependencies": {
-    "@motion-canvas/2d": "^3.11.0",
-    "@motion-canvas/core": "^3.11.0",
-    "@motion-canvas/ffmpeg": "^1.1.1"
-  },
-  "devDependencies": {
-    "@motion-canvas/ui": "^3.11.0",
-    "@motion-canvas/vite-plugin": "^3.11.0",
-    "typescript": "^4.9.5",
-    "vite": "^4.1.4"
-  }
-}
diff --git a/animation/templates_why/src/global.css b/animation/templates_why/src/global.css
deleted file mode 100644
index 84cea14..0000000
--- a/animation/templates_why/src/global.css
+++ /dev/null
@@ -1 +0,0 @@
-@import url('https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;700&display=swap');
diff --git a/animation/templates_why/src/motion-canvas.d.ts b/animation/templates_why/src/motion-canvas.d.ts
deleted file mode 100644
index 067c6a4..0000000
--- a/animation/templates_why/src/motion-canvas.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-/// <reference types="@motion-canvas/core/project" />
diff --git a/animation/templates_why/src/project.meta b/animation/templates_why/src/project.meta
deleted file mode 100644
index 7579bae..0000000
--- a/animation/templates_why/src/project.meta
+++ /dev/null
@@ -1,31 +0,0 @@
-{
-  "version": 0,
-  "shared": {
-    "background": "rgb(10,20,30)",
-    "range": [
-      0,
-      null
-    ],
-    "size": {
-      "x": 1920,
-      "y": 1080
-    },
-    "audioOffset": 0
-  },
-  "preview": {
-    "fps": 30,
-    "resolutionScale": 1
-  },
-  "rendering": {
-    "fps": 30,
-    "resolutionScale": 2,
-    "colorSpace": "srgb",
-    "exporter": {
-      "name": "@motion-canvas/ffmpeg",
-      "options": {
-        "fastStart": true,
-        "includeAudio": true
-      }
-    }
-  }
-}
\ No newline at end of file
diff --git a/animation/templates_why/src/project.ts b/animation/templates_why/src/project.ts
deleted file mode 100644
index dee424e..0000000
--- a/animation/templates_why/src/project.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import {makeProject} from '@motion-canvas/core';
-
-import why from './scenes/why?scene';
-
-import './global.css'; // <- import the css
-
-export default makeProject({
-  scenes: [why],
-});
diff --git a/animation/templates_why/src/scenes/why.meta b/animation/templates_why/src/scenes/why.meta
deleted file mode 100644
index 67175ef..0000000
--- a/animation/templates_why/src/scenes/why.meta
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-  "version": 0,
-  "timeEvents": [],
-  "seed": 2417761898
-}
\ No newline at end of file
diff --git a/animation/templates_why/src/scenes/why.tsx b/animation/templates_why/src/scenes/why.tsx
deleted file mode 100644
index f7ba99a..0000000
--- a/animation/templates_why/src/scenes/why.tsx
+++ /dev/null
@@ -1,220 +0,0 @@
-import { makeScene2D } from '@motion-canvas/2d/lib/scenes';
-import { createRef } from '@motion-canvas/core/lib/utils';
-import {
-  CodeBlock,
-  edit,
-  insert,
-  lines,
-  word,
-  remove,
-  CodeModification,
-} from '@motion-canvas/2d/lib/components/CodeBlock';
-import { all, waitFor, waitUntil } from '@motion-canvas/core/lib/flow';
-import { DEFAULT } from '@motion-canvas/core/lib/signals';
-import { BBox, Vector2 } from '@motion-canvas/core/lib/types';
-
-export default makeScene2D(function* (view) {
-  const codeRef = createRef<CodeBlock>();
-
-  yield view.add(<CodeBlock
-    ref={codeRef}
-    language="cpp"
-    fontSize={35}
-  />);
-
-
-  const duration = 1.5
-
-  const store = (...args: [TemplateStringsArray, ...any]) => args;
-
-  function to_string([strings, ...values]: [TemplateStringsArray, ...any]): string {
-    return strings.reduce((acc, str, i) => {
-      const value = values[i] ?? '';
-      return acc + str + value;
-    }, '');
-  }
-
-  function append(
-    template_1: TemplateStringsArray, args_1: string[],
-    template_2: TemplateStringsArray, args_2: string[]): [TemplateStringsArray, ...string[]] {
-    let new_template = Array.from<string>(template_1);
-    let new_args: Array<string> = args_1;
-    new_template[template_1.length - 1] += template_2[0]
-    new_template = new_template.concat(template_2.slice(1))
-    new_args = new_args.concat(args_2)
-    return [new_template as unknown as TemplateStringsArray, ...new_args];
-  }
-
-  const isCodeModification = (code: any): code is CodeModification => (code as CodeModification).from !== undefined;
-
-  function simplify(
-    args_in: [TemplateStringsArray, ...any]): [TemplateStringsArray, ...string[]] {
-    const template = args_in[0]
-    const args = args_in.slice(1)
-    if (args.every((arg) => (typeof (arg) == "string") || isCodeModification(arg))) {
-      return args_in
-    }
-    let new_template: Array<any> = [];
-    let new_args: Array<any> = [];
-    let concatenate = false;
-    for (let i = 0; i <= args.length; i++) {
-      if (concatenate) {
-        concatenate = false;
-        new_template[new_template.length - 1] += template[i];
-      } else {
-        new_template.push(template[i]);
-      }
-      if (i == args.length) { break; }
-      if (typeof (args[i]) == "string" || isCodeModification(args[i])) {
-        new_args.push(args[i])
-        continue;
-      }
-      let simplified_arg = simplify(args[i]);
-      let simplified_template = simplified_arg[0]
-      let simplified_args = simplified_arg.slice(1)
-      const appended = append(
-        new_template as unknown as TemplateStringsArray,
-        new_args,
-        simplified_template,
-        simplified_args as string[]);
-      new_template = Array.from<string>(appended[0])
-      new_args = appended.slice(1)
-      concatenate = true;
-    }
-    return [new_template as unknown as TemplateStringsArray, ...new_args]
-  }
-
-  const comment_before = `// Not a great idea to repeat the code so many times! ❌\n// Imagine changing the implementation later!`
-  const comment_after = `// And so on for any other type we care about\n`
-
-  const template = (typename: any = `typename`) => store`// Works for any type as long as the implementation compiles ✅\ntemplate <${typename} NumberType>`
-  const int_func = (func_name: any = `Maximum`, used_type: any = `int`
-  ) => store`
-${used_type} ${func_name}(${used_type} first, ${used_type} second) {
-  if (first < second) { return second; }
-  return first;
-}`
-
-  const other_funcs = (func_name: any = `Maximum`,
-  ) => store`
-float ${func_name}(float first, float second) {
-  if (first < second) { return second; }
-  return first;
-}
-double ${func_name}(double first, double second) {
-  if (first < second) { return second; }
-  return first;
-}`
-
-
-  const code = (func_name: any = `Maximum`,
-    before: any = comment_before,
-    after: any = comment_after,
-    first_function: any = int_func(),
-    rest_functions: any = other_funcs(),
-  ) => store`
-${before}${first_function}${rest_functions}
-${after}
-int main() {
-  ${func_name}(42, 23);
-  ${func_name}(3.14F, 42.42F);
-  ${func_name}(3.14, 42.42);
-}
-`
-  const zoom_fn = (in_zoom: number) => new Vector2(in_zoom, in_zoom);
-
-  yield* codeRef().edit(duration, false)(...simplify(
-    code("Max",
-      comment_before,
-      comment_after,
-      int_func("Max"),
-      other_funcs("Max"))));
-  yield* waitFor(duration);
-
-  yield* codeRef().edit(duration, true)(...simplify(code(
-    edit("Max", "Maximum"),
-    comment_before,
-    comment_after,
-    int_func(edit("Max", "Maximum")),
-    other_funcs(edit("Max", "Maximum")))));
-  yield* waitFor(duration);
-
-  yield* all(
-    codeRef().selection(DEFAULT, duration),
-  );
-  yield* waitFor(duration);
-
-
-  yield* codeRef().edit(duration, false)(...simplify(
-    code(`Maximum`,
-      edit(comment_before, to_string(template())),
-      remove(comment_after),
-      int_func("Maximum", edit("int", "NumberType")),
-      remove(to_string(other_funcs())))));
-  yield* waitFor(duration);
-
-  yield* all(
-    codeRef().selection(DEFAULT, duration),
-  );
-  yield* waitFor(duration);
-
-  yield* codeRef().selection(lines(1), duration);
-  yield* waitFor(duration);
-
-  yield* codeRef().selection(word(1, 9, 21), duration);
-  yield* waitFor(duration);
-
-  yield* codeRef().edit(duration, false)(...simplify(
-    code(`Maximum`,
-      template(edit("typename", "class")),
-      "",
-      int_func("Maximum", "NumberType"),
-      "")));
-  yield* waitFor(duration);
-
-  yield* codeRef().edit(duration, false)(...simplify(
-    code(`Maximum`,
-      template(edit("class", "typename")),
-      "",
-      int_func("Maximum", "NumberType"),
-      "")));
-  yield* waitFor(duration);
-
-  yield* all(
-    codeRef().selection(lines(1, 2), duration),
-  );
-  yield* waitFor(duration);
-
-  yield* all(
-    codeRef().selection([...word(2, 19, 35)], duration),
-    codeRef().scale(zoom_fn(2), duration),
-    codeRef().position(new Vector2(-200, 400), duration),
-  );
-  yield* waitFor(duration);
-
-  yield* all(
-    codeRef().selection([...word(8, 10, 6), ...word(9, 10, 13), ...word(10, 10, 11)], duration),
-    codeRef().scale(zoom_fn(2), duration),
-    codeRef().position(new Vector2(700, -200), duration),
-  );
-  yield* waitFor(duration);
-
-  yield* all(
-    codeRef().selection([...lines(3, 4)], duration),
-    codeRef().scale(zoom_fn(1), duration),
-    codeRef().position(new Vector2(0, 0), duration),
-  );
-  yield* waitFor(duration);
-
-
-  yield* codeRef().selection([...lines(8)], 0.5 * duration);
-  yield* codeRef().selection([...lines(9)], 0.5 * duration);
-  yield* codeRef().selection([...lines(10)], 0.5 * duration);
-  yield* waitFor(duration);
-
-  yield* all(
-    codeRef().selection(DEFAULT, duration),
-  );
-  yield* waitFor(duration);
-
-});
diff --git a/animation/templates_why/tsconfig.json b/animation/templates_why/tsconfig.json
deleted file mode 100644
index 789b7d1..0000000
--- a/animation/templates_why/tsconfig.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-  "extends": "@motion-canvas/2d/tsconfig.project.json",
-  "compilerOptions": {
-    "baseUrl": "src"
-  },
-  "include": ["src"]
-}
diff --git a/animation/templates_why/vite.config.ts b/animation/templates_why/vite.config.ts
deleted file mode 100644
index a463c29..0000000
--- a/animation/templates_why/vite.config.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import { defineConfig } from 'vite';
-import motionCanvas from '@motion-canvas/vite-plugin';
-import ffmpeg from '@motion-canvas/ffmpeg';
-
-export default defineConfig({
-  plugins: [
-    motionCanvas(),
-    ffmpeg()
-  ],
-});
diff --git a/animation/value_semantics/.gitignore b/animation/value_semantics/.gitignore
deleted file mode 100644
index 829b1c7..0000000
--- a/animation/value_semantics/.gitignore
+++ /dev/null
@@ -1,15 +0,0 @@
-# Generated files
-node_modules
-output
-dist
-
-# Editor directories and files
-.vscode/*
-!.vscode/extensions.json
-.idea
-.DS_Store
-*.suo
-*.ntvs*
-*.njsproj
-*.sln
-*.sw?
diff --git a/animation/value_semantics/package-lock.json b/animation/value_semantics/package-lock.json
deleted file mode 100644
index cdefbbe..0000000
--- a/animation/value_semantics/package-lock.json
+++ /dev/null
@@ -1,759 +0,0 @@
-{
-  "name": "value_semantics",
-  "version": "0.0.0",
-  "lockfileVersion": 3,
-  "requires": true,
-  "packages": {
-    "": {
-      "name": "value_semantics",
-      "version": "0.0.0",
-      "dependencies": {
-        "@motion-canvas/2d": "^3.11.0",
-        "@motion-canvas/core": "^3.11.0"
-      },
-      "devDependencies": {
-        "@motion-canvas/ui": "^3.11.0",
-        "@motion-canvas/vite-plugin": "^3.11.0",
-        "typescript": "^4.9.5",
-        "vite": "^4.1.4"
-      }
-    },
-    "node_modules/@esbuild/android-arm": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
-      "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==",
-      "cpu": [
-        "arm"
-      ],
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/android-arm64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz",
-      "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/android-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz",
-      "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/darwin-arm64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz",
-      "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/darwin-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz",
-      "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/freebsd-arm64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz",
-      "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "freebsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/freebsd-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz",
-      "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "freebsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-arm": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz",
-      "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==",
-      "cpu": [
-        "arm"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-arm64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz",
-      "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-ia32": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz",
-      "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==",
-      "cpu": [
-        "ia32"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-loong64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz",
-      "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==",
-      "cpu": [
-        "loong64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-mips64el": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz",
-      "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==",
-      "cpu": [
-        "mips64el"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-ppc64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz",
-      "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==",
-      "cpu": [
-        "ppc64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-riscv64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz",
-      "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==",
-      "cpu": [
-        "riscv64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-s390x": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz",
-      "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==",
-      "cpu": [
-        "s390x"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/linux-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz",
-      "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/netbsd-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz",
-      "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "netbsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/openbsd-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz",
-      "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "openbsd"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/sunos-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz",
-      "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "sunos"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/win32-arm64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz",
-      "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==",
-      "cpu": [
-        "arm64"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/win32-ia32": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz",
-      "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==",
-      "cpu": [
-        "ia32"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@esbuild/win32-x64": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz",
-      "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==",
-      "cpu": [
-        "x64"
-      ],
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/@motion-canvas/2d": {
-      "version": "3.11.0",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/2d/-/2d-3.11.0.tgz",
-      "integrity": "sha512-T/RPXGRxddO/xxbC2RcOXfrtBTp8lfcmnuW1fa6++0qy0chK5NFxm3bHJczCbX0ynKB2VAoqLNobTF9eD6ZP3w==",
-      "dependencies": {
-        "@motion-canvas/core": "^3.11.0",
-        "code-fns": "^0.8.2",
-        "mathjax-full": "^3.2.2",
-        "parse-svg-path": "^0.1.2"
-      }
-    },
-    "node_modules/@motion-canvas/core": {
-      "version": "3.11.0",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/core/-/core-3.11.0.tgz",
-      "integrity": "sha512-/WjdoSTqTPwCgrB2pP8YXq2T3KviYHrywVxXJ5fEjQ1gajkPKYD7aVlRcY1+kaTbwqXhCARMCh+pSjT2nfhTsw==",
-      "dependencies": {
-        "@types/chroma-js": "^2.1.4",
-        "chroma-js": "^2.4.2"
-      },
-      "peerDependencies": {
-        "vite": "^4.1.4"
-      }
-    },
-    "node_modules/@motion-canvas/ui": {
-      "version": "3.11.0",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/ui/-/ui-3.11.0.tgz",
-      "integrity": "sha512-sd0GxvCkejL2lzExsvgLsC1GgHzLP/0LlMw1QE2/3pMQo3rMOVA7L1Oq6br8HqdJhzMEgW3DWC0NjDJsUfkL2A==",
-      "dev": true,
-      "dependencies": {
-        "@motion-canvas/core": "^3.11.0"
-      }
-    },
-    "node_modules/@motion-canvas/vite-plugin": {
-      "version": "3.11.0",
-      "resolved": "https://registry.npmjs.org/@motion-canvas/vite-plugin/-/vite-plugin-3.11.0.tgz",
-      "integrity": "sha512-26ixfy5NhvFePj1DBdh7MFsgevpRrzzEKjzSyCK3FOvPcnUWFjab4wWErpsIEnu6a0p7yj4w9VKpa8USx6N95A==",
-      "dev": true,
-      "dependencies": {
-        "follow-redirects": "^1.15.2",
-        "mime-types": "^2.1.35"
-      },
-      "peerDependencies": {
-        "vite": "4.x"
-      }
-    },
-    "node_modules/@types/chroma-js": {
-      "version": "2.4.0",
-      "resolved": "https://registry.npmjs.org/@types/chroma-js/-/chroma-js-2.4.0.tgz",
-      "integrity": "sha512-JklMxityrwjBTjGY2anH8JaTx3yjRU3/sEHSblLH1ba5lqcSh1LnImXJZO5peJfXyqKYWjHTGy4s5Wz++hARrw=="
-    },
-    "node_modules/@types/hast": {
-      "version": "2.3.4",
-      "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.4.tgz",
-      "integrity": "sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==",
-      "dependencies": {
-        "@types/unist": "*"
-      }
-    },
-    "node_modules/@types/unist": {
-      "version": "2.0.6",
-      "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz",
-      "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ=="
-    },
-    "node_modules/@wooorm/starry-night": {
-      "version": "1.7.0",
-      "resolved": "https://registry.npmjs.org/@wooorm/starry-night/-/starry-night-1.7.0.tgz",
-      "integrity": "sha512-ktO0nkddrovIoNW2jAUT+Cdd9n1bWjy1Ir4CdcmgTaT6E94HLlQfu7Yv62falclBEwvsuVp3bSBw23wtta1fNw==",
-      "dependencies": {
-        "@types/hast": "^2.0.0",
-        "import-meta-resolve": "^2.0.0",
-        "vscode-oniguruma": "^1.0.0",
-        "vscode-textmate": "^9.0.0"
-      },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/wooorm"
-      }
-    },
-    "node_modules/chroma-js": {
-      "version": "2.4.2",
-      "resolved": "https://registry.npmjs.org/chroma-js/-/chroma-js-2.4.2.tgz",
-      "integrity": "sha512-U9eDw6+wt7V8z5NncY2jJfZa+hUH8XEj8FQHgFJTrUFnJfXYf4Ml4adI2vXZOjqRDpFWtYVWypDfZwnJ+HIR4A=="
-    },
-    "node_modules/code-fns": {
-      "version": "0.8.2",
-      "resolved": "https://registry.npmjs.org/code-fns/-/code-fns-0.8.2.tgz",
-      "integrity": "sha512-3VVeq3cnWxWiWKFLsVo+XWsOXBSW2gAx2uv0ViETLNmNuygEPHlCeDAv/Zy7xXqPgXtgLZyvIJZmx+ojTgOIGA==",
-      "dependencies": {
-        "@wooorm/starry-night": "^1.2.0"
-      }
-    },
-    "node_modules/commander": {
-      "version": "9.2.0",
-      "resolved": "https://registry.npmjs.org/commander/-/commander-9.2.0.tgz",
-      "integrity": "sha512-e2i4wANQiSXgnrBlIatyHtP1odfUp0BbV5Y5nEGbxtIrStkEOAAzCUirvLBNXHLr7kwLvJl6V+4V3XV9x7Wd9w==",
-      "engines": {
-        "node": "^12.20.0 || >=14"
-      }
-    },
-    "node_modules/esbuild": {
-      "version": "0.18.20",
-      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz",
-      "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==",
-      "hasInstallScript": true,
-      "bin": {
-        "esbuild": "bin/esbuild"
-      },
-      "engines": {
-        "node": ">=12"
-      },
-      "optionalDependencies": {
-        "@esbuild/android-arm": "0.18.20",
-        "@esbuild/android-arm64": "0.18.20",
-        "@esbuild/android-x64": "0.18.20",
-        "@esbuild/darwin-arm64": "0.18.20",
-        "@esbuild/darwin-x64": "0.18.20",
-        "@esbuild/freebsd-arm64": "0.18.20",
-        "@esbuild/freebsd-x64": "0.18.20",
-        "@esbuild/linux-arm": "0.18.20",
-        "@esbuild/linux-arm64": "0.18.20",
-        "@esbuild/linux-ia32": "0.18.20",
-        "@esbuild/linux-loong64": "0.18.20",
-        "@esbuild/linux-mips64el": "0.18.20",
-        "@esbuild/linux-ppc64": "0.18.20",
-        "@esbuild/linux-riscv64": "0.18.20",
-        "@esbuild/linux-s390x": "0.18.20",
-        "@esbuild/linux-x64": "0.18.20",
-        "@esbuild/netbsd-x64": "0.18.20",
-        "@esbuild/openbsd-x64": "0.18.20",
-        "@esbuild/sunos-x64": "0.18.20",
-        "@esbuild/win32-arm64": "0.18.20",
-        "@esbuild/win32-ia32": "0.18.20",
-        "@esbuild/win32-x64": "0.18.20"
-      }
-    },
-    "node_modules/esm": {
-      "version": "3.2.25",
-      "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz",
-      "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==",
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/follow-redirects": {
-      "version": "1.15.2",
-      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
-      "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "individual",
-          "url": "https://github.com/sponsors/RubenVerborgh"
-        }
-      ],
-      "engines": {
-        "node": ">=4.0"
-      },
-      "peerDependenciesMeta": {
-        "debug": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/fsevents": {
-      "version": "2.3.3",
-      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
-      "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
-      "hasInstallScript": true,
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
-      }
-    },
-    "node_modules/import-meta-resolve": {
-      "version": "2.2.2",
-      "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-2.2.2.tgz",
-      "integrity": "sha512-f8KcQ1D80V7RnqVm+/lirO9zkOxjGxhaTC1IPrBGd3MEfNgmNG67tSUO9gTi2F3Blr2Az6g1vocaxzkVnWl9MA==",
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/wooorm"
-      }
-    },
-    "node_modules/mathjax-full": {
-      "version": "3.2.2",
-      "resolved": "https://registry.npmjs.org/mathjax-full/-/mathjax-full-3.2.2.tgz",
-      "integrity": "sha512-+LfG9Fik+OuI8SLwsiR02IVdjcnRCy5MufYLi0C3TdMT56L/pjB0alMVGgoWJF8pN9Rc7FESycZB9BMNWIid5w==",
-      "dependencies": {
-        "esm": "^3.2.25",
-        "mhchemparser": "^4.1.0",
-        "mj-context-menu": "^0.6.1",
-        "speech-rule-engine": "^4.0.6"
-      }
-    },
-    "node_modules/mhchemparser": {
-      "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/mhchemparser/-/mhchemparser-4.1.1.tgz",
-      "integrity": "sha512-R75CUN6O6e1t8bgailrF1qPq+HhVeFTM3XQ0uzI+mXTybmphy3b6h4NbLOYhemViQ3lUs+6CKRkC3Ws1TlYREA=="
-    },
-    "node_modules/mime-db": {
-      "version": "1.52.0",
-      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
-      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/mime-types": {
-      "version": "2.1.35",
-      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
-      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
-      "dev": true,
-      "dependencies": {
-        "mime-db": "1.52.0"
-      },
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/mj-context-menu": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/mj-context-menu/-/mj-context-menu-0.6.1.tgz",
-      "integrity": "sha512-7NO5s6n10TIV96d4g2uDpG7ZDpIhMh0QNfGdJw/W47JswFcosz457wqz/b5sAKvl12sxINGFCn80NZHKwxQEXA=="
-    },
-    "node_modules/nanoid": {
-      "version": "3.3.6",
-      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
-      "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/ai"
-        }
-      ],
-      "bin": {
-        "nanoid": "bin/nanoid.cjs"
-      },
-      "engines": {
-        "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
-      }
-    },
-    "node_modules/parse-svg-path": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/parse-svg-path/-/parse-svg-path-0.1.2.tgz",
-      "integrity": "sha512-JyPSBnkTJ0AI8GGJLfMXvKq42cj5c006fnLz6fXy6zfoVjJizi8BNTpu8on8ziI1cKy9d9DGNuY17Ce7wuejpQ=="
-    },
-    "node_modules/picocolors": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
-      "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
-    },
-    "node_modules/postcss": {
-      "version": "8.4.31",
-      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
-      "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
-      "funding": [
-        {
-          "type": "opencollective",
-          "url": "https://opencollective.com/postcss/"
-        },
-        {
-          "type": "tidelift",
-          "url": "https://tidelift.com/funding/github/npm/postcss"
-        },
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/ai"
-        }
-      ],
-      "dependencies": {
-        "nanoid": "^3.3.6",
-        "picocolors": "^1.0.0",
-        "source-map-js": "^1.0.2"
-      },
-      "engines": {
-        "node": "^10 || ^12 || >=14"
-      }
-    },
-    "node_modules/rollup": {
-      "version": "3.29.4",
-      "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz",
-      "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==",
-      "bin": {
-        "rollup": "dist/bin/rollup"
-      },
-      "engines": {
-        "node": ">=14.18.0",
-        "npm": ">=8.0.0"
-      },
-      "optionalDependencies": {
-        "fsevents": "~2.3.2"
-      }
-    },
-    "node_modules/source-map-js": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
-      "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/speech-rule-engine": {
-      "version": "4.0.7",
-      "resolved": "https://registry.npmjs.org/speech-rule-engine/-/speech-rule-engine-4.0.7.tgz",
-      "integrity": "sha512-sJrL3/wHzNwJRLBdf6CjJWIlxC04iYKkyXvYSVsWVOiC2DSkHmxsqOhEeMsBA9XK+CHuNcsdkbFDnoUfAsmp9g==",
-      "dependencies": {
-        "commander": "9.2.0",
-        "wicked-good-xpath": "1.3.0",
-        "xmldom-sre": "0.1.31"
-      },
-      "bin": {
-        "sre": "bin/sre"
-      }
-    },
-    "node_modules/typescript": {
-      "version": "4.9.5",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
-      "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
-      "dev": true,
-      "bin": {
-        "tsc": "bin/tsc",
-        "tsserver": "bin/tsserver"
-      },
-      "engines": {
-        "node": ">=4.2.0"
-      }
-    },
-    "node_modules/vite": {
-      "version": "4.5.0",
-      "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.0.tgz",
-      "integrity": "sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw==",
-      "dependencies": {
-        "esbuild": "^0.18.10",
-        "postcss": "^8.4.27",
-        "rollup": "^3.27.1"
-      },
-      "bin": {
-        "vite": "bin/vite.js"
-      },
-      "engines": {
-        "node": "^14.18.0 || >=16.0.0"
-      },
-      "funding": {
-        "url": "https://github.com/vitejs/vite?sponsor=1"
-      },
-      "optionalDependencies": {
-        "fsevents": "~2.3.2"
-      },
-      "peerDependencies": {
-        "@types/node": ">= 14",
-        "less": "*",
-        "lightningcss": "^1.21.0",
-        "sass": "*",
-        "stylus": "*",
-        "sugarss": "*",
-        "terser": "^5.4.0"
-      },
-      "peerDependenciesMeta": {
-        "@types/node": {
-          "optional": true
-        },
-        "less": {
-          "optional": true
-        },
-        "lightningcss": {
-          "optional": true
-        },
-        "sass": {
-          "optional": true
-        },
-        "stylus": {
-          "optional": true
-        },
-        "sugarss": {
-          "optional": true
-        },
-        "terser": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/vscode-oniguruma": {
-      "version": "1.7.0",
-      "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz",
-      "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA=="
-    },
-    "node_modules/vscode-textmate": {
-      "version": "9.0.0",
-      "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-9.0.0.tgz",
-      "integrity": "sha512-Cl65diFGxz7gpwbav10HqiY/eVYTO1sjQpmRmV991Bj7wAoOAjGQ97PpQcXorDE2Uc4hnGWLY17xme+5t6MlSg=="
-    },
-    "node_modules/wicked-good-xpath": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/wicked-good-xpath/-/wicked-good-xpath-1.3.0.tgz",
-      "integrity": "sha512-Gd9+TUn5nXdwj/hFsPVx5cuHHiF5Bwuc30jZ4+ronF1qHK5O7HD0sgmXWSEgwKquT3ClLoKPVbO6qGwVwLzvAw=="
-    },
-    "node_modules/xmldom-sre": {
-      "version": "0.1.31",
-      "resolved": "https://registry.npmjs.org/xmldom-sre/-/xmldom-sre-0.1.31.tgz",
-      "integrity": "sha512-f9s+fUkX04BxQf+7mMWAp5zk61pciie+fFLC9hX9UVvCeJQfNHRHXpeo5MPcR0EUf57PYLdt+ZO4f3Ipk2oZUw==",
-      "engines": {
-        "node": ">=0.1"
-      }
-    }
-  }
-}
diff --git a/animation/value_semantics/package.json b/animation/value_semantics/package.json
deleted file mode 100644
index 9c5588b..0000000
--- a/animation/value_semantics/package.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "name": "value_semantics",
-  "private": true,
-  "version": "0.0.0",
-  "scripts": {
-    "serve": "vite",
-    "build": "tsc && vite build"
-  },
-  "dependencies": {
-    "@motion-canvas/2d": "^3.11.0",
-    "@motion-canvas/core": "^3.11.0"
-  },
-  "devDependencies": {
-    "@motion-canvas/ui": "^3.11.0",
-    "@motion-canvas/vite-plugin": "^3.11.0",
-    "typescript": "^4.9.5",
-    "vite": "^4.1.4"
-  }
-}
diff --git a/animation/value_semantics/src/motion-canvas.d.ts b/animation/value_semantics/src/motion-canvas.d.ts
deleted file mode 100644
index 067c6a4..0000000
--- a/animation/value_semantics/src/motion-canvas.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-/// <reference types="@motion-canvas/core/project" />
diff --git a/animation/value_semantics/src/project.meta b/animation/value_semantics/src/project.meta
deleted file mode 100644
index 7b0759f..0000000
--- a/animation/value_semantics/src/project.meta
+++ /dev/null
@@ -1,32 +0,0 @@
-{
-  "version": 0,
-  "shared": {
-    "background": "rgb(10,20,30)",
-    "range": [
-      0,
-      null
-    ],
-    "size": {
-      "x": 1920,
-      "y": 1080
-    },
-    "audioOffset": 0
-  },
-  "preview": {
-    "fps": 30,
-    "resolutionScale": 1
-  },
-  "rendering": {
-    "fps": 30,
-    "resolutionScale": 2,
-    "colorSpace": "srgb",
-    "exporter": {
-      "name": "@motion-canvas/core/image-sequence",
-      "options": {
-        "fileType": "image/png",
-        "quality": 100,
-        "groupByScene": true
-      }
-    }
-  }
-}
\ No newline at end of file
diff --git a/animation/value_semantics/src/project.ts b/animation/value_semantics/src/project.ts
deleted file mode 100644
index d4428e6..0000000
--- a/animation/value_semantics/src/project.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import {makeProject} from '@motion-canvas/core';
-
-import example from './scenes/example?scene';
-import memory from './scenes/memory?scene';
-import stealing from './scenes/stealing?scene';
-
-export default makeProject({
-  scenes: [memory, stealing, example],
-});
diff --git a/animation/value_semantics/src/scenes/example.meta b/animation/value_semantics/src/scenes/example.meta
deleted file mode 100644
index 2d62bec..0000000
--- a/animation/value_semantics/src/scenes/example.meta
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-  "version": 0,
-  "timeEvents": [],
-  "seed": 1501821170
-}
\ No newline at end of file
diff --git a/animation/value_semantics/src/scenes/example.tsx b/animation/value_semantics/src/scenes/example.tsx
deleted file mode 100644
index 5ec127c..0000000
--- a/animation/value_semantics/src/scenes/example.tsx
+++ /dev/null
@@ -1,400 +0,0 @@
-import {makeScene2D} from '@motion-canvas/2d/lib/scenes';
-import {createRef} from '@motion-canvas/core/lib/utils';
-import {
-  CodeBlock,
-  edit,
-  insert,
-  lines,
-  word,
-  remove,
-  CodeModification,
-} from '@motion-canvas/2d/lib/components/CodeBlock';
-import {all, waitFor, waitUntil} from '@motion-canvas/core/lib/flow';
-import { DEFAULT } from '@motion-canvas/core/lib/signals';
-import { BBox, Vector2 } from '@motion-canvas/core/lib/types';
-
-export default makeScene2D(function* (view) {
-  const codeRef = createRef<CodeBlock>();
-
-  yield view.add(<CodeBlock
-    ref={codeRef}
-    language="cpp"
-    fontSize={50}
-  />);
-
-
-  const duration = 1.5
-
-  const store = (...args: [TemplateStringsArray, ...any]) => args;
-
-  function to_string([strings, ...values]: [TemplateStringsArray, ...any]): string {
-    return strings.reduce((acc, str, i) => {
-      const value = values[i] ?? '';
-      return acc + str + value;
-    }, ' ');
-  }
-
-  function append(
-    template_1: TemplateStringsArray, args_1: string[],
-    template_2: TemplateStringsArray, args_2: string[]) : [TemplateStringsArray, ...string[]] {
-      let new_template = Array.from<string>(template_1);
-      let new_args: Array<string> = args_1;
-      new_template[template_1.length - 1] += template_2[0]
-      new_template = new_template.concat(template_2.slice(1))
-      new_args = new_args.concat(args_2)
-      return [new_template as unknown as TemplateStringsArray, ...new_args];
-  }
-
-  const isCodeModification = (code: any): code is CodeModification => (code as CodeModification).from !== undefined;
-
-  function simplify(
-    args_in: [TemplateStringsArray, ...any]) : [TemplateStringsArray, ...string[]] {
-      const template = args_in[0]
-      const args = args_in.slice(1)
-      if (args.every((arg) => (typeof(arg) == "string") || isCodeModification(arg))) {
-          return args_in
-      }
-      let new_template: Array<any> = [];
-      let new_args: Array<any> = [];
-      let concatenate = false;
-      for (let i = 0; i <= args.length; i++) {
-          if (concatenate) {
-              concatenate = false;
-              new_template[new_template.length - 1] += template[i];
-          } else {
-              new_template.push(template[i]);
-          }
-          if (i == args.length) { break; }
-          if (typeof(args[i]) == "string" || isCodeModification(args[i])) {
-              new_args.push(args[i])
-              continue;
-          }
-          let simplified_arg = simplify(args[i]);
-          let simplified_template = simplified_arg[0]
-          let simplified_args = simplified_arg.slice(1)
-          const appended = append(
-              new_template as unknown as TemplateStringsArray,
-              new_args,
-              simplified_template,
-              simplified_args as string[]);
-          new_template = Array.from<string>(appended[0])
-          new_args = appended.slice(1)
-          concatenate = true;
-      }
-      return [new_template as unknown as TemplateStringsArray, ...new_args]
-  }
-
-
-  const code = (operator:any = ``, main:any = ``, operator_move:any=``) => store`
-  #include <cstddef>
-  #include <algorithm>
-
-  struct HugeObject {
-    HugeObject() = default;
-
-    explicit HugeObject(std::size_t data_length)
-        : length{data_length}, ptr{AllocateMemory(length)} {}
-    ${operator}${operator_move}
-    ~HugeObject() { FreeMemory(ptr); }
-
-    std::size_t length{};
-    std::byte *ptr{};
-  };
-  ${main}
-  `
-
-  const copy = `ptr = AllocateMemory(length);
-      std::copy(object.ptr, object.ptr + length, ptr);`
-  const steal = `ptr = object.ptr;
-      object.ptr = nullptr;`
-
-  const operator_copy = (
-      const_word:any = `const `,
-      copy_or_steal:any = copy,
-      ) => store`
-    HugeObject &operator=(${const_word}HugeObject& object) {
-      if (this == &object) { return *this; }
-      FreeMemory(ptr);
-      length = object.length;
-      ${copy_or_steal}
-      return *this;
-    }
-    `
-
-  const operator_move = `
-
-  HugeObject &operator=(HugeObject&& object) {
-    if (this == &object) { return *this; }
-    FreeMemory(ptr);
-    length = object.length;
-    ptr = object.ptr;
-    object.ptr = nullptr;
-    return *this;
-  }
-  `
-
-  const assign_fail = `
-    // ❌ Does not compile.
-    storage.member_object = HugeObject{200};`
-
-  const assign_int_fail = `
-    // ❌ Does not compile either.
-    int& answer = 42;`
-
-  const main_fn = (comment:any = ``, assign_temp:any = ``) => store`
-  struct HugeObjectStorage {
-    HugeObject member_object;
-  };
-
-  int main() {
-    HugeObject object{100};
-    HugeObjectStorage storage{};
-    storage.member_object = object;${assign_temp}
-    return 0;
-  } ${comment}`
-
-  const comment = ` // storage and object are destroyed`
-
-  const zoom_fn = (in_zoom: number) => new Vector2(in_zoom, in_zoom);
-
-  yield * codeRef().edit(duration, false)(...simplify(code()));
-  yield * codeRef().selection([...word(7, 30, 28)], duration);
-  yield * waitFor(duration);
-  yield * codeRef().selection([...word(9, 20, 15)], duration);
-  yield * waitFor(duration);
-  yield * codeRef().edit(duration, true)(...code(edit(``, to_string(operator_copy()))));
-  yield * waitFor(duration);
-  yield * codeRef().selection([...lines(9)], duration);
-  yield * waitFor(duration);
-  yield * all(
-    codeRef().selection([...word(9, 26, 24)], duration),
-    codeRef().scale(zoom_fn(1.5), duration),
-    codeRef().position(new Vector2(-500, 200), duration),
-  );
-  yield * waitFor(duration);
-  yield * all(
-    codeRef().selection([...lines(14)], duration),
-    codeRef().scale(zoom_fn(1.2), duration),
-    codeRef().position(new Vector2(50, -200), duration),
-  );
-  yield * waitFor(duration);
-  yield * all(
-    codeRef().selection(DEFAULT, duration),
-    codeRef().scale(zoom_fn(0.7), duration),
-    codeRef().position(new Vector2(0, 0), duration),
-  );
-  yield * waitFor(duration);
-  yield * all(
-    codeRef().position(new Vector2(0, -300), duration),
-    codeRef().edit(duration, true)(...simplify(code(operator_copy(), edit(``, to_string(main_fn()))))),
-  );
-  yield * all(
-    codeRef().scale(zoom_fn(1.2), duration),
-    codeRef().position(new Vector2(400, -800), duration),
-  );
-  yield * codeRef().selection([...lines(29)], duration);
-  yield * codeRef().selection([...lines(30)], duration);
-  yield * codeRef().selection([...lines(31)], duration);
-  yield * codeRef().edit(duration, true)(...simplify(code(operator_copy(), main_fn(insert(comment)))));
-  yield * waitFor(duration);
-
-  // Show destructor
-  yield * all(
-    codeRef().selection(DEFAULT, duration),
-    codeRef().scale(zoom_fn(0.5), duration),
-    codeRef().position(new Vector2(0, 0), duration),
-  );
-  yield * waitFor(duration);
-  yield * all(
-    codeRef().selection(DEFAULT, duration),
-    codeRef().scale(zoom_fn(1.2), duration),
-    codeRef().selection([...lines(18 )], duration),
-    codeRef().position(new Vector2(200, 0), duration),
-  );
-  yield * waitFor(duration);
-
-  // Show const
-  yield * all(
-    codeRef().selection(DEFAULT, duration),
-    codeRef().scale(zoom_fn(0.5), duration),
-    codeRef().position(new Vector2(0, 0), duration),
-  );
-  yield * waitFor(duration);
-  yield * all(
-    codeRef().scale(zoom_fn(1.2), duration),
-    codeRef().selection([...lines(9, 16)], duration),
-    codeRef().position(new Vector2(50, 400), duration),
-  );
-  yield * waitFor(duration);
-  yield * all(
-    codeRef().scale(zoom_fn(3.0), duration),
-    codeRef().selection([...word(9, 26, 5)], duration),
-    codeRef().position(new Vector2(100, 1400), duration),
-  );
-  yield * waitFor(duration);
-
-  // Remove const
-  yield * all(
-    codeRef().edit(duration, false)(...simplify(code(operator_copy(edit('const ', '')), main_fn(comment)))),
-    codeRef().selection([...word(9, 26, 12)], duration),
-  );
-  yield * all(
-    codeRef().scale(zoom_fn(1.2), duration),
-    codeRef().position(new Vector2(50, 400), duration),
-    codeRef().selection([...lines(9, 16)], duration),
-  );
-  yield *codeRef().selection([...lines(13, 14)], duration);
-  yield * codeRef().edit(duration, true)(...simplify(code(operator_copy('', edit(copy, steal)), main_fn(comment))));
-  yield * waitFor(duration);
-
-  // Look at the main again
-  yield * all(
-    codeRef().selection(DEFAULT, duration),
-    codeRef().scale(zoom_fn(0.5), duration),
-    codeRef().position(new Vector2(0, 0), duration),
-  );
-  yield * waitFor(duration);
-  yield * all(
-    codeRef().scale(zoom_fn(1.2), duration),
-    codeRef().position(new Vector2(400, -800), duration),
-  );
-  yield * codeRef().selection([...lines(29)], duration);
-  yield * codeRef().selection([...lines(30)], duration);
-  yield * codeRef().selection([...lines(31)], duration);
-  yield * codeRef().selection(DEFAULT, duration);
-
-  yield * waitFor(duration);
-  // Assign temp
-  yield * all(
-    codeRef().scale(zoom_fn(1.3), duration),
-    codeRef().edit(duration, true)(
-      ...simplify(
-        code(
-          operator_copy('', steal),
-          main_fn(comment, insert(assign_fail))))),
-    codeRef().position(new Vector2(200, -1100), duration),
-  );
-  yield * waitFor(duration);
-  yield * codeRef().edit(duration, true)(
-    ...simplify(
-      code(
-        operator_copy('', steal),
-        main_fn(comment, edit(assign_fail, assign_int_fail)))));
-  yield * waitFor(duration);
-
-  yield * all(
-    codeRef().selection(DEFAULT, duration),
-    codeRef().scale(zoom_fn(0.5), duration),
-    codeRef().position(new Vector2(0, 0), duration),
-    codeRef().edit(duration, false)(
-      ...simplify(
-        code(
-          operator_copy('', steal),
-          main_fn(comment, remove(assign_int_fail))))),
-  );
-
-  // Add move operator
-  yield * waitFor(duration);
-  yield * all(
-    codeRef().scale(zoom_fn(1.0), duration),
-    codeRef().position([0, 260], duration),
-    codeRef().edit(duration, true)(
-      ...simplify(
-        code(
-          operator_copy(insert('const '),
-          edit(steal, copy)),
-          main_fn(comment),
-          insert(operator_move)))),
-  );
-  yield * waitFor(duration);
-  yield * codeRef().selection([...word(9, 26, 24), ...lines(13, 14)], duration);
-  yield * waitFor(duration);
-  yield * codeRef().selection([...word(18, 26, 19), ...lines(22, 23)], duration);
-  yield * waitFor(duration);
-
-  const comment_temp_bind = `// Can be bound to a temporary`
-  const comment_pick_overload = ` // The compiler picks Blah(int&&)`
-
-  const blah_code = (
-    comment_temp:any = ``,
-    comment_pick:any = ``,
-    blah_answer:any = ``,
-    blah_answer_comment:any = ``,
-    blah_move_answer:any = ``,
-    blah_move_answer_comment:any = ``,
-  ) => store`
-  #include <iostream>
-
-  void Blah(int&) {
-    std::cout << "&" << std::endl;
-  }
-
-  void Blah(int&&) {
-    std::cout << "&&" << std::endl;
-  }
-
-  int main() {
-    int&& answer = 42;  ${comment_temp}
-    Blah(42);${comment_pick}${blah_answer}${blah_answer_comment}${blah_move_answer}${blah_move_answer_comment}
-  }`
-
-
-  yield * waitFor(duration);
-  yield * all(
-    codeRef().edit(duration, false)(...blah_code()),
-    codeRef().selection(DEFAULT, duration),
-    codeRef().scale(zoom_fn(1.0), 0),
-    codeRef().position(new Vector2(0, 0), 0),
-  );
-  yield * waitFor(duration);
-  yield * codeRef().selection([...lines(11)], duration);
-  yield * codeRef().edit(duration, false)(...simplify(blah_code(insert(comment_temp_bind))));
-  yield * waitFor(duration);
-  yield * codeRef().selection([...lines(12)], duration);
-  yield * codeRef().edit(duration, false)(...simplify(blah_code(comment_temp_bind, insert(comment_pick_overload))));
-  yield * waitFor(duration);
-  yield * waitFor(duration);
-
-
-  const final_main = `
-  int main() {
-    HugeObject object{100};
-    HugeObjectStorage storage{};
-    storage.member_object = object;
-    storage.member_object = HugeObject{200};
-    storage.member_object = std::move(object);
-    return 0;
-  }`
-
-  yield * codeRef().selection(DEFAULT, 0),
-  yield * codeRef().edit(duration, false)`${final_main}`;
-  yield * waitFor(duration);
-  yield * codeRef().selection([...lines(4)], duration);
-  yield * codeRef().selection([...lines(5)], duration);
-  yield * codeRef().selection([...lines(6)], duration);
-  yield * waitFor(duration);
-
-  const rref_comment = `  // Prints "&&"`
-  const lref_comment = `  // Prints "&"`
-  const blah_answer_ref = `
-    Blah(answer);`
-  const blah_answer_rref = `
-    Blah(std::move(answer));`
-
-  // Final rref example
-  yield * codeRef().selection(DEFAULT, 0),
-  yield * codeRef().edit(duration, false)(...blah_code());
-  yield * codeRef().edit(duration, false)(...blah_code('', insert(rref_comment)));
-  yield * codeRef().edit(duration, false)(...blah_code('', rref_comment, insert(blah_answer_ref)));
-  yield * codeRef().edit(duration, false)(...blah_code(
-    '', rref_comment, blah_answer_ref, insert(lref_comment)));
-  yield * codeRef().edit(duration, false)(...blah_code(
-    '', rref_comment, blah_answer_ref, lref_comment, insert(blah_answer_rref)));
-  yield * codeRef().edit(duration, false)(...blah_code(
-    '', rref_comment, blah_answer_ref, lref_comment, blah_answer_rref, insert(rref_comment)));
-
-  yield * waitFor(duration);
-
-  yield * waitFor(duration);
-
-});
diff --git a/animation/value_semantics/src/scenes/memory.meta b/animation/value_semantics/src/scenes/memory.meta
deleted file mode 100644
index bdef019..0000000
--- a/animation/value_semantics/src/scenes/memory.meta
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-  "version": 0,
-  "timeEvents": [],
-  "seed": 3499084582
-}
\ No newline at end of file
diff --git a/animation/value_semantics/src/scenes/memory.tsx b/animation/value_semantics/src/scenes/memory.tsx
deleted file mode 100644
index 0a35176..0000000
--- a/animation/value_semantics/src/scenes/memory.tsx
+++ /dev/null
@@ -1,96 +0,0 @@
-import {makeScene2D} from '@motion-canvas/2d/lib/scenes';
-import {Node, Circle, Rect, Grid, Line} from '@motion-canvas/2d/lib/components';
-import {all, waitFor} from '@motion-canvas/core/lib/flow';
-import {Vector2} from '@motion-canvas/core/lib/types';
-import {createRef} from '@motion-canvas/core/lib/utils';
-import {createSignal} from '@motion-canvas/core/lib/signals';
-import {CodeBlock} from '@motion-canvas/2d/lib/components/CodeBlock';
-
-const RED = '#ff6470';
-const GREEN = '#99C47A';
-const BLUE = '#68ABDF';
-
-export default makeScene2D(function* (view) {
-  const data_ref = createRef<CodeBlock>();
-  const line_1 = createRef<Line>();
-  const line_2 = createRef<Line>();
-
-  const data = `
-  1011011010110
-  1011000100100
-  0010011100000
-  1101000010001
-  0010100111111`
-
-  const object_code = `object`
-  const member_object_code = `storage.member_object`
-
-  view.add(
-    <Node>
-      {/* <Grid
-        y = {200}
-        width={1920}
-        height={300}
-        spacing={100}
-        stroke={'#444'}
-        lineWidth={2}
-        lineCap="square"
-        cache
-      /> */}
-      {/* <Rect
-        x = {0}
-        y = {250}
-        fill = {BLUE}
-        lineWidth={4}
-        width = {800}
-        height = {100}
-        opacity = {0.5}
-      /> */}
-      <CodeBlock
-        fontSize={60}
-        x = {0}
-        y = {200}
-        code={data}
-      />
-      <Node x = {-500} y = {-300}>
-        <CodeBlock
-          fontSize={60}
-          code={object_code}
-        />
-        <Line
-          ref={line_1}
-          stroke={RED}
-          lineWidth={10}
-          endArrow
-          arrowSize={20}
-          opacity = {0.0}
-          points={[[0, 50], [250, 300]]}
-        />
-      </Node>
-      <Node x = {500} y = {-300}>
-        <CodeBlock
-          fontSize={60}
-          code={member_object_code}
-        />
-        <Line
-          ref={line_2}
-          stroke={RED}
-          lineWidth={10}
-          endArrow
-          arrowSize={20}
-          opacity = {0.0}
-          points={[[0, 50], [-250, 300]]}
-        />
-      </Node>
-    </Node>,
-  );
-
-  yield* line_1().opacity(1.0, 1.0)
-  yield* line_1().points([[1000, 50], [750, 300]], 2.0)
-
-  yield * waitFor(2.0);
-  yield* line_1().points([[0, 50], [250, 300]], 0.0)
-  yield * waitFor(1.0);
-  yield* line_2().opacity(1.0, 1.0)
-  yield * waitFor(2.0);
-});
diff --git a/animation/value_semantics/src/scenes/stealing.meta b/animation/value_semantics/src/scenes/stealing.meta
deleted file mode 100644
index 1547019..0000000
--- a/animation/value_semantics/src/scenes/stealing.meta
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-  "version": 0,
-  "timeEvents": [],
-  "seed": 1249695661
-}
\ No newline at end of file
diff --git a/animation/value_semantics/src/scenes/stealing.tsx b/animation/value_semantics/src/scenes/stealing.tsx
deleted file mode 100644
index eb43caa..0000000
--- a/animation/value_semantics/src/scenes/stealing.tsx
+++ /dev/null
@@ -1,140 +0,0 @@
-import {makeScene2D} from '@motion-canvas/2d/lib/scenes';
-import {Node, Txt, Rect, Grid, Line} from '@motion-canvas/2d/lib/components';
-import {all, waitFor} from '@motion-canvas/core/lib/flow';
-import {Vector2} from '@motion-canvas/core/lib/types';
-import {createRef} from '@motion-canvas/core/lib/utils';
-import {createSignal} from '@motion-canvas/core/lib/signals';
-import {CodeBlock, edit, insert} from '@motion-canvas/2d/lib/components/CodeBlock';
-
-const RED = '#ff6470';
-const GREEN = '#99C47A';
-const BLUE = '#68ABDF';
-const WHITE = '#FFFFFF';
-
-export default makeScene2D(function* (view) {
-  const gray_line_ref = createRef<Line>();
-  const gray_code_ref = createRef<CodeBlock>();
-  const grid_ref = createRef<Grid>();
-  const data_rect_ref = createRef<Rect>();
-  const a_ref = createRef<CodeBlock>();
-  const b_ref = createRef<CodeBlock>();
-  const line_1 = createRef<Line>();
-  const line_2 = createRef<Line>();
-
-  const data = `
-  10010011`
-
-  const object_code = `Data* a;`
-  const member_object_code = `Data* b;`
-
-  view.add(
-    <Node>
-      <Grid
-        ref = {grid_ref}
-        y = {200}
-        spacing={100}
-        stroke={'#444'}
-        lineWidth={5}
-        opacity={0}
-        cache
-      />
-      <Rect
-        x = {0}
-        y = {250}
-        ref = {data_rect_ref}
-        fill = {BLUE}
-        lineWidth={4}
-        width = {800}
-        height = {100}
-        opacity = {0.0}
-      />
-      <CodeBlock
-          ref={gray_code_ref}
-          fontSize={40}
-          code = {"0x42424242"}
-          x = {-350}
-          y = {430}
-          opacity = {0.0}
-      />
-      <Line
-          ref={gray_line_ref}
-          stroke={'#777'}
-          lineWidth={5}
-          endArrow
-          arrowSize={15}
-          points={[[-350, 400], [-350, 310]]}
-          opacity = {0.0}
-      />
-
-      <Node x = {-400} y = {-300}>
-        <CodeBlock
-          ref = {a_ref}
-          fontSize={80}
-        />
-        <Line
-          ref = {line_1}
-          lineWidth={10}
-          stroke={BLUE}
-          arrowSize={20}
-          endArrow
-          points={[
-            [30, 50],
-            [30, 490],
-          ]}
-          end={0}
-        />,
-      </Node>
-      <Node x = {500} y = {-300}>
-        <CodeBlock
-          ref = {b_ref}
-          fontSize={80}
-        />
-        <Line
-          ref = {line_2}
-          lineWidth={10}
-          stroke={BLUE}
-          endArrow
-          arrowSize={20}
-          points={[
-            [0, 50],
-            [0, 200],
-            [-830, 200],
-            [-830, 490],
-          ]}
-          end={0}
-        />,
-      </Node>
-    </Node>,
-  );
-
-  yield * waitFor(2.0);
-  yield * a_ref().edit(1.0, false)`${insert(object_code)}`;
-  yield * all(
-    grid_ref().height(0, 0.0).to(250, 0.5),
-    grid_ref().width(0, 0.0).to(1920, 0.5),
-    grid_ref().opacity(1.0, 0.1),
-  );
-  yield * all(
-    data_rect_ref().opacity(0.5, 1.0),
-    line_1().end(1, 1.0),
-    gray_line_ref().opacity(1.0, 0.5),
-    gray_code_ref().opacity(1.0, 0.5),
-  );
-  yield * b_ref().edit(1.0, false)`${insert(member_object_code)}`;
-  yield * waitFor(1.0);
-  yield * data_rect_ref().scale(1.2, 1.0);
-  yield * data_rect_ref().position.x(-20, 0.2).to(20, 0.2).to(-20, 0.2).to(20, 0.2).to(0, 0.2);
-  yield * data_rect_ref().scale(1.0, 0.5);
-  yield * waitFor(1.0);
-  yield * line_2().end(1, 1.5);
-  yield * waitFor(1.0);
-  yield * all(
-    data_rect_ref().opacity(0.5, 1.0),
-    line_1().arrowSize(0, 0.5),
-    line_1().end(0, 1.0),
-    a_ref().edit(1.5, false)`Data* a${insert(' = nullptr')};`,
-  );
-
-  yield * waitFor(3.0);
-
-});
diff --git a/animation/value_semantics/tsconfig.json b/animation/value_semantics/tsconfig.json
deleted file mode 100644
index 789b7d1..0000000
--- a/animation/value_semantics/tsconfig.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-  "extends": "@motion-canvas/2d/tsconfig.project.json",
-  "compilerOptions": {
-    "baseUrl": "src"
-  },
-  "include": ["src"]
-}
diff --git a/animation/value_semantics/vite.config.ts b/animation/value_semantics/vite.config.ts
deleted file mode 100644
index bf32088..0000000
--- a/animation/value_semantics/vite.config.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-import {defineConfig} from 'vite';
-import motionCanvas from '@motion-canvas/vite-plugin';
-
-export default defineConfig({
-  plugins: [motionCanvas()],
-});
diff --git a/homeworks/homework_1/homework.md b/homeworks/homework_1/homework.md
index d81c099..bfe4d5d 100644
--- a/homeworks/homework_1/homework.md
+++ b/homeworks/homework_1/homework.md
@@ -1,6 +1,6 @@
 # Hello homework!
 
-Your task will be to implement a C++ program that prints "Hello World!" to the terminal when run. See the [lecture](../../lectures/hello_world_dissection.md) on this topic too!
+Your task will be to implement a C++ program that prints "Hello World!" to the terminal when run. See the [lecture](../../lectures/1.1_hello_world_dissection.md) on this topic too!
 
 If you get lost while submitting homework, just watch the [tutorial video](https://youtu.be/Nl0u04XgxGQ) again 😉
 
diff --git a/homeworks/homework_2/homework.md b/homeworks/homework_2/homework.md
index d9ba758..6e4a4e3 100644
--- a/homeworks/homework_2/homework.md
+++ b/homeworks/homework_2/homework.md
@@ -5,10 +5,10 @@ Your task here is to implement a fortune teller program. It will receive some in
 😅 If you get stuck, discuss it in [GitHub Discussions](https://github.com/orgs/cpp-for-yourself/discussions/categories/homeworks-q-a).
 
 ## Prerequisites
-- [Fundamental types and variables](../../lectures/cpp_basic_types_and_variables.md)
-- [I/O streams](../../lectures/io_streams.md)
-- [Sequence containers](../../lectures/more_useful_types.md)
-- [Associative containers](../../lectures/associative_containers.md)
+- [Fundamental types and variables](../../lectures/1.2_cpp_basic_types_and_variables.md)
+- [I/O streams](../../lectures/1.4_io_streams.md)
+- [Sequence containers](../../lectures/1.5_more_useful_types.md)
+- [Associative containers](../../lectures/1.6_associative_containers.md)
 
 If you get lost while submitting homework, just watch the [tutorial video](https://youtu.be/Nl0u04XgxGQ) again 😉
 
@@ -39,7 +39,7 @@ A C++ program that communicates with the user by using screams. It must:
     Please enter another adjective:
     ```
     And read it from the terminal as the user presses <kbd>Enter</kbd>
-7. Print a new line followed by the sentence "Here is your description:" and a fortune telling generated by our code based on the inputs that the user provided. For example:
+7. Print the fortune telling that is based on the inputs that the user provided. For example:
     ```
     Igor, the fearless STL guru that finds errors quicker than the compiler
     ```
diff --git a/homeworks/homework_3/homework.md b/homeworks/homework_3/homework.md
deleted file mode 100644
index a7bef95..0000000
--- a/homeworks/homework_3/homework.md
+++ /dev/null
@@ -1,93 +0,0 @@
-# The guessing game
-
-Your task here is to implement a program that will generate a random number and ask the user to guess it. It will then output the number of guesses the user required to guess the number.
-
-😅 If you get stuck, discuss it in [GitHub Discussions](https://github.com/orgs/cpp-for-yourself/discussions/categories/homeworks-q-a).
-
-## Prerequisites
-- Everything you needed for the [Homework 2](../homework_2/homework.md)
-- [Control structures lecture](../../lectures/control_structures.md)
-- [Random number generation](../../lectures/random_numbers.md)
-
-If you get lost while submitting homework, just watch the [tutorial video](https://youtu.be/Nl0u04XgxGQ) again 😉
-
-## Formal requirements
-
-You will write a C++ program that communicates with the user by using screams. It must:
-1. Print a welcome statement: 
-    ```
-    Welcome to the GUESSING GAME!
-    I will generate a number and you will guess it!
-    ```
-2. Ask the user (and read the answer) for the **smallest** number of the allowed range: 
-    ```
-    Please provide the smallest number: 
-    ```
-3. Ask the user (and read the answer) for the **largest** number of the allowed range:
-    ```
-    Please provide the largest number: 
-    ```
-4. Generate the random number that the user will have to guess and write the message about it to `stdout`:
-   ```
-   I've generated a number. Try to guess it!
-   ``` 
-5. Ask the user for the next guess and read it:
-    ```
-    Please provide the next guess:
-    ```
-6. If the user gave a number which is **smaller** than the generated one print:
-    ```
-    Your number is too small. Try again!
-    ```
-    Then repeat from `5.`
-7. If the user gave a number which is **larger** than the generated one print:
-    ```
-    Your number is too big. Try again!
-    ```
-    Then repeat from `5.`
-8. If the user guessed the number, print:
-    ```
-    You've done it! You guessed the number N in K guesses!
-    ```
-    Here, `N` is the generated number, `K` is the number of attempts that the user needed to guess it.
-
-Overall, the terminal will look something like this for the fully working program:
-```
-λ › ./guessing_game
-Welcome to the GUESSING GAME!
-I will generate a number and you will guess it!
-Please provide the smallest number: 
-1
-Please provide the largest number: 
-100
-I've generated a number. Try to guess it!
-Please provide the next guess: 50
-Your number is too big. Try again!
-Please provide the next guess: 25
-Your number is too big. Try again!
-Please provide the next guess: 10
-Your number is too small. Try again!
-Please provide the next guess: 11
-You've done it! You guessed the number 11 in 8 guesses!
-```
-
-🚨 Note the difference in whitespaces for different inputs. It is important to match them **exactly** in order to submit the homework and have a ✅ for all tasks!
-
-## What you need to implement this
-You might have already guessed that this program will use some loops and conditional statements. You will have to play this game until the user guesses the correct number and stop the loop when they do.
-
-You will also have to check if a certain situation occurs and stop the game then.
-
-Don't forget that to start the game you will need to generate a random number in a given range.
-
-
-## Where to put the solution
-- Work with **your fork** of the [homeworks](https://github.com/cpp-for-yourself/homeworks) repository
-- Here is the folder structure for this homework with respect to your `homeworks` repository root:
-  - `homeworks/`
-    - `homework_3/`
-      - `guessing_game/`
-        - `guessing_game.cpp` <-- **put your code here!**
-
----
-# Good luck! 🍀
diff --git a/homeworks/homework_4/homework.md b/homeworks/homework_4/homework.md
deleted file mode 100644
index 9253379..0000000
--- a/homeworks/homework_4/homework.md
+++ /dev/null
@@ -1,154 +0,0 @@
-# Writing a string processing library
-
-<p align="center">
-  <a href="https://youtu.be/f0x2qcFgu5o"><img src="https://img.youtube.com/vi/f0x2qcFgu5o/maxresdefault.jpg" alt="Video" align="right" width=50% style="margin: 0.5rem"></a>
-</p>
-
-<!-- Talking head -->
-It's time for the next homework. We now know a lot about writing functions, putting them into header and source files and organizing all of those into libraries, so it's about time we put it to the test.
-
-Today we will write a small library for string processing with an unassuming name `"no_strings_attached"` :wink:
-
-<!-- Screen record -->
-Speaking about "putting to the test", you will have to write tests for your library.
-
-<!-- Talking head -->
-We'll also implement a couple of examples to show how this library works.
-
-<!-- Screen record -->
-They all live in the examples folder and allow to:
-- Split strings by running: `examples/split_strings`
-- Trim strings by running: `examples/trim_strings`
-
-<!-- Talking head -->
-That's about it. Please see below for a formal definition of the homework. And good luck!
-
-## Formal homework definition
-The main task of this homework is to write a library that splits and trims strings. It is checked in two ways:
-1. Through tests using the `googletest` framework
-2. Through binaries in the `examples` folder
-
-Below we cover all the details that you might need for the implementation.
-
-### Prerequisites
-Please make sure you've done the previous homework and that you're comfortable with all lectures since that homework until this one. The [Readme](../../readme.md) is a convenient way to check this.
-
-### The expected project structure
-The project has to be implemented in the `homework_4` folder in your homework repository (that you can [create from this template](https://github.com/cpp-for-yourself/homeworks)). Otherwise automatic checking won't work.
-
-The project must follow the template described in the [CMake](../../lectures/cmake.md) and [GoogleTest](../../lectures/googletest.md) lectures.
-
-Here is how the structure of the project folder will look like:
-
-```bash
-homework_4/
-└── no_strings_attached/
-    ├── CMakeLists.txt
-    ├── external
-    │   ├── CMakeLists.txt
-    │   └── googletest/  # Googletest library as a submodule
-    ├── examples
-    │   ├── CMakeLists.txt
-    │   ├── split_strings.cpp
-    │   └── trim_strings.cpp
-    ├── no_strings_attached/
-    │   ├── CMakeLists.txt  # Defines all libraries
-    │   ├── string_split.cpp
-    │   ├── string_split.h
-    │   ├── string_split_test.cpp
-    │   └── ... # Same for all other libraries
-    ├── .clang-format
-    └── readme.md  # Description of your project. Go nuts!
-```
-
-### The libraries
-Here is a more formal definition about what the libraries must do and how they should be organized.
-
-#### Namespace
-Just as we discussed in the videos, make sure that the namespaces _follow the project structure_. Thus, all functions in this project must live in the `no_strings_attached` namespace.
-
-#### CMake targets
-There will be 2 libraries (more concretely, CMake targets), one per functionality:
-- `string_split`
-- `string_trim`
-
-These libraries must all be defined in the `no_strings_attached/CMakeLists.txt` so that the binaries in the `examples` folder and the tests could be linked to those.
-
-#### Header files
-They also should have header files so that they can be included with:
-- `#include <no_strings_attached/string_split.h>`
-- `#include <no_strings_attached/string_trim.h>`
-
-> :bulb: Such small libraries are a bit excessive for the real world use, but we are learning how to write libraries here, so it'll do :wink:
-
-#### Expected functionality
-- Splitting strings library `string_split` should have the following functions:
-  - A function to split a given string into a vector of strings from the right given a delimiter:
-    ```cpp
-    std::vector<std::string> Split(const std::string& str, const std::string& delimiter);
-    ```
-    > :bulb: Hint: You might want to use the [`find`](https://en.cppreference.com/w/cpp/string/basic_string/find) method from `std::string` when implementing this function.
-
-    Examples:
-      - `Split("hello world", " ")` ➡️ `std::vector{"hello", "world"}`
-      - `Split("aaabaaba", "aa")` ➡️ `std::vector{"", "ab", "ba"}`
-  - An overload of the above function that allows keeping only part of the output:
-    ```cpp
-    std::vector<std::string> Split(const std::string& str, const std::string& delimiter, int number_of_chunks_to_keep);
-    ```
-    Examples:
-      - `Split("hello world", " ", 1)` ➡️ `std::vector{"hello"}`
-      - `Split("hello world", " ", 2)` ➡️ `std::vector{"hello", "world"}`
-      - `Split("aaabaaba", "aa", 2)` ➡️ `std::vector{"", "ab"}`
-- Trimming strings library `string_trim` should have the following things:
-  - An `enum class` called `Side` that defines these options:
-    - `Side::kLeft`
-    - `Side::kRight`
-    - `Side::kBoth`
-    > :bulb: Think where you want to put this enumeration. Should it live in a separate header?
-  - A function that allows trimming strings from a given direction:
-    ```cpp
-    std::string Trim(const std::string& str, char char_to_trim, Side side);
-    ```
-    Examples:
-      - `Trim("  hello ", ' ', Side::kLeft)` ➡️ `std::string{"hello "}`
-      - `Trim("  hello ", ' ', Side::kRight)` ➡️ `std::string{"  hello"}`
-      - `Trim("  hello ", ' ', Side::kBoth)` ➡️ `std::string{"hello"}`
-      - `Trim("hello", 'h', Side::kLeft)` ➡️ `std::string{"ello"}`
-  - An overload of this function function that allows trimming spaces from both sides:
-    ```cpp
-    std::string Trim(const std::string& str);
-    ```
-    Examples:
-      - `Trim("  hello ")` ➡️ `std::string{"hello"}`
-
-#### Tests for libraries
-All of the libraries must have unit tests using the `googletest` framework available as a submodule in the project's `external` folder, just like it is presented in the [Googletest](../../lectures/googletest.md) lecture. All of the tests must live in the same folder as the file that contains the code that they test and must be registered through `ctest`.
-
-For validating the right functionality, the homework checking system will inject an additional folder `validation_test` into your project and run the custom-designed tests on your code. This will show up as a separate line in the output from the homework checker in your PR and wiki.
-
-#### Example binaries
-To show off the functionality we will also have binaries that use this functionality. These should be reachable after building the project under these paths and behave as follows:
-- The binary to split string: `build/examples/split_strings`
-  - It should ask the user for a string and print this string split on the `" "` character with every word surrounded in `'` characters
-  - Example:
-    ```
-    echo "hello world" | ./build/examples/split_strings
-    Example program that splits strings.
-    Please enter a string:
-    Your split string: 'hello' 'world'
-    ```
-- The binary to trim strings: `build/examples/trim_strings`
-  - It should ask the user for a string and trim the spaces around it. It should then print this string to the terminal surrounded in `'` characters
-  - Example:
-    ```
-    echo "  hello world  " | ./build/examples/trim_strings
-    Example program that trims strings.
-    Please enter a string:
-    Your trimmed string: 'hello world'
-    ```
-
-> :bulb: In your binaries, you might want to use the [`std::getline`](https://en.cppreference.com/w/cpp/string/basic_string/getline) function instead of using `std::cin` as the latter splits input on the <kbd>space</kbd> character, while the former does not.
-
-## That's it!
-Congratulations! You've implemented your own library in relatively modern C++! On to the next challenge! Do share your thoughts on the whole process in the [discussions page](https://github.com/orgs/cpp-for-yourself/discussions/categories/general) :pray:.
diff --git a/homeworks/homework_5/grumpy.png b/homeworks/homework_5/grumpy.png
deleted file mode 100644
index aa6eff5..0000000
--- a/homeworks/homework_5/grumpy.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:cecc8d151258fdd455184218f446072a34bff3c15e716ee7eac8cc84809fb381
-size 127165
diff --git a/homeworks/homework_5/grumpy_pixelated.png b/homeworks/homework_5/grumpy_pixelated.png
deleted file mode 100644
index b002e55..0000000
--- a/homeworks/homework_5/grumpy_pixelated.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:b3a9895a829397391ad64a429d0b50f83d41907031e24db9f8625d8cbbc3dd34
-size 25487
diff --git a/homeworks/homework_5/homework.md b/homeworks/homework_5/homework.md
deleted file mode 100644
index fdd52e0..0000000
--- a/homeworks/homework_5/homework.md
+++ /dev/null
@@ -1,438 +0,0 @@
-**Pixelating images in terminal**
-
-<p align="center">
-  <a href="https://youtu.be/Cj3x51iJdvM"><img src="https://img.youtube.com/vi/Cj3x51iJdvM/maxresdefault.jpg" alt="Video" align="right" width=40%></a>
-</p>
-
-- [What this homework is about](#what-this-homework-is-about)
-- [Prerequisites](#prerequisites)
-- [Here is what you will implement exactly](#here-is-what-you-will-implement-exactly)
-- [‼️‼️ Detailed requirements: read this whole section carefully\*\* ‼️‼️](#️️-detailed-requirements-read-this-whole-section-carefully-️️)
-  - [The expected project structure](#the-expected-project-structure)
-  - [Submodules and the `external` folder](#submodules-and-the-external-folder)
-    - [FTXUI library](#ftxui-library)
-      - [FTXUI library by example](#ftxui-library-by-example)
-      - [What the example does](#what-the-example-does)
-    - [The stb library](#the-stb-library)
-      - [The stb library by example](#the-stb-library-by-example)
-      - [What the example does](#what-the-example-does-1)
-  - [The libraries (and CMake targets) that you have to implement](#the-libraries-and-cmake-targets-that-you-have-to-implement)
-    - [`pixelator::StbImageDataView` class](#pixelatorstbimagedataview-class)
-    - [`pixelator::Image` class](#pixelatorimage-class)
-    - [The `pixelator::PixelateImage` function](#the-pixelatorpixelateimage-function)
-    - [`pixelator::Drawer` class](#pixelatordrawer-class)
-  - [The binary to test your data](#the-binary-to-test-your-data)
-  - [Namespace](#namespace)
-  - [Tests for libraries](#tests-for-libraries)
-- [How your code is checked](#how-your-code-is-checked)
-- [That's it!](#thats-it)
-
-## What this homework is about
-The aim of this homework is to further familiarize ourselves with creating full projects in C++ using CMake, making use of everything we've learned in the last couple of lectures.
-
-The way we are addressing this is by designing a program that is able to load an image from disk and show its pixelated version directly in the terminal.
-
-So, after you are done, you should be able to call your program with a path to an image and see its pixelated version in the terminal:
-```bash
-cd homework_5/pixelator
-./build/examples/pixelate ~/Pictures/grumpy_cat.png
-# The image will be printed after the previous call
-```
-
-| Original image  |      Pixelated image      |
-| :-------------: | :-----------------------: |
-| ![](grumpy.png) | ![](grumpy_pixelated.png) |
-
-## Prerequisites
-Please make sure you've done the previous homework and that you're comfortable with all lectures since that homework until this one. The [readme](../../readme.md) is a convenient way to check this.
-
-## Here is what you will implement exactly
-The functionality that you will implement in this homework can be summarized in the following diagram:
-
-```mermaid
-graph LR
-  Load --> Store --> PixelateImage --> Draw
-```
-While you _will_ implement parts of each of the above boxes, some of the functionality (`Load` and `Draw`) is partially handled by external libraries that you will have to use correctly.
-
-> :bulb: The description of this homework project is quite extensive and might be a bit confusing. It _is_ a larger project if you are a beginner and while I tried to provide as much clarity as possible, the implementation _will_ take a long time. You can count multiple hours (maybe even days) to implement everything described below. This is normal and figuring all of these things out is part of the fun. So give yourself time and enjoy implementing this project as much as you can.
-
-## ‼️‼️ Detailed requirements: read this whole section carefully** ‼️‼️
-In this part we will go over each of the block above as well as through the project structure.
-
-### The expected project structure
-The project has to be implemented in the `homework_5` folder in your homework repository (that you can [create from this template](https://github.com/cpp-for-yourself/homeworks) if you haven't done so before). If the structure of the project does not follow this guide the automatic checking won't work.
-
-The project must follow the template described in the [CMake](../../lectures/cmake.md) and [GoogleTest](../../lectures/googletest.md) lectures.
-
-Here is how the structure of the project folder will look like:
-```bash
-homework_5/
-└── pixelator/
-    ├── CMakeLists.txt
-    ├── external
-    │   ├── CMakeLists.txt
-    │   ├── stb/         # Stb library as a submodule
-    │   ├── ftxui/       # Ftxui library as a submodule
-    │   └── googletest/  # Googletest library as a submodule
-    ├── examples
-    │   ├── CMakeLists.txt
-    │   ├── pixelate.cpp
-    ├── pixelator/
-    │   ├── test_data/
-    │   │   └── test.png    # Test data, see below
-    │   ├── CMakeLists.txt  # Defines all libraries
-    │   ├── pixelate_image.hpp
-    │   ├── pixelate_image.cpp
-    │   ├── pixelate_image_test.cpp
-    │   └── # rest of your files
-    ├── .clang-format
-    └── readme.md  # Description of your project. Go nuts!
-```
-
-> :bulb: For your convenience, I am also providing an [empty project skeleton](pixelator) that you will have to fill in with your code.
-
-### Submodules and the `external` folder
-In this homework we make use of 3 external libraries:
-- [Googletest](https://github.com/google/googletest) to test our code
-- [ftxui](https://github.com/ArthurSonzogni/FTXUI) to print stuff to the terminal
-- [stb](https://github.com/nothings/stb) to load an image from disk using code in `stb_image.h` file
-
-To add all the submodules, navigate to the `homework_5/pixelator/` folder and execute the following:
-```bash
-git submodule add https://github.com/ArthurSonzogni/FTXUI.git external/ftxui
-git submodule add https://github.com/google/googletest.git external/googletest
-git submodule add https://github.com/nothings/stb.git external/stb
-```
-For your convenience, I am providing the rest of the [`external`](pixelator/external/) folder in the empty [project skeleton](pixelator/).
-
-Below you will find a description of each of the above (excluding Googletests, which you should already be familiar with)
-
-#### FTXUI library
-This is a library to print anything your heart desires to the terminal. It is a modern library that is easy to integrate with our code through CMake. We can use the target it generates upon build like this:
-```cmake
-target_link_libraries(your_target PUBLIC ftxui::screen)
-```
-
-> :bulb: It is a good exercise to read the readme of that project to figure out how to use it. You will need this skill _a lot_ in your C++ journey.
-
-##### FTXUI library by example
-We will mostly just be using the `ftxui::Screen` and `ftxui::Color` classes from the `ftxui` library. We can use them like this:
-```cpp
-#include "ftxui/screen/color.hpp"
-#include "ftxui/screen/screen.hpp"
-
-namespace {
-const ftxui::Color kYellowishColor = ftxui::Color::RGB(255, 200, 100);
-}
-
-int main() {
-  const ftxui::Dimensions dimensions{ftxui::Dimension::Full()};
-  ftxui::Screen screen{ftxui::Screen::Create(dimensions)};
-  auto &pixel_left = screen.PixelAt(10, 10);
-  pixel_left.background_color = kYellowishColor;
-  pixel_left.character = ' ';
-  auto &pixel_right = screen.PixelAt(11, 10);
-  pixel_right.background_color = kYellowishColor;
-  pixel_right.character = ' ';
-  screen.Print();
-  return 0;
-}
-```
-
-##### What the example does
-- We initialize the dimensions of the screen using the `ftxui` library
-- We create an `ftxui::Screen` from these dimensions, which takes up all the space that is available in our terminal
-- We take a reference to two "pixels" (actually characters in our terminal) and set them to the color we selected
-- We print the `ftxui::Screen` contents to the terminal, which we should see as the output of our program
-
-> :bulb: Note that you can also create dimensions of custom size using `ftxui::Dimension::Fixed(int_size)`, which is useful for tests.
-
-> :bulb: Note that we have to set color to 2 "pixels" in order to print a _square_. If we only set the color to one, we will only print a rectangle instead of a square.
-
-> :bulb: The above example is available in the project skeleton that I provide alongside this homework. You can find this file [here](pixelator/examples/use_ftxui.cpp).
-
-#### The stb library
-We use a single header from the `stb` library, namely `stb_image.h` to load our image from disk. For your convenience, this library is also set up as an external library and wrapped into a CMake target `stb::stb` that can be used as follows:
-```cmake
-target_link_libraries(your_target PUBLIC stb::stb)
-```
-
-##### The stb library by example
-The `stb` library provides a couple of utilities of interest to us:
-- `image_data = stbi_load(...)` that loads the data from the file and returns a raw pointer to `unsigned char` array representing colors of the image in the following order: `RGBARGBARGBA...` where, `RGB` stands for values for the red, green and blue from 0 to 255, and `A` represents transparency
-- `stbi_image_free(image_data)` that allows to free the memory allocated to store the image that we loaded from disk
-
-Let's see how we can use these functions in the actual code:
-```cpp
-// Make sure to have this in EXACTLY one cpp file
-// The best place for this is the cpp file of your library
-// that holds a class that wraps around the stb_image data
-// For more see here: https://github.com/nothings/stb#faq
-#define STB_IMAGE_IMPLEMENTATION
-#include "stb/stb_image.h"
-
-#include <filesystem>
-#include <iostream>
-
-namespace {
-static constexpr auto kLoadAllChannels{0};
-
-// A dummy color structure. Use ftxui::Color in actual code.
-struct Color {
-  int red;
-  int green;
-  int blue;
-};
-
-}  // namespace
-
-int main(int argc, char **argv) {
-  if (argc < 2) { std::cerr << "No image provided.\n"; }
-  const std::filesystem::path image_path{argv[1]};
-  if (!std::filesystem::exists(image_path)) {
-    std::cerr << "No image provided.\n";
-  }
-
-  // Load the data
-  int rows{};
-  int cols{};
-  int channels{};
-  // This call also populates rows, cols, channels.
-  auto image_data{
-      stbi_load(image_path.c_str(), &cols, &rows, &channels, kLoadAllChannels)};
-  std::cout << "Loaded image of size: [" << rows << ", " << cols << "] with "
-            << channels << " channels\n";
-  if (!image_data) {
-    std::cerr << "Failed to load image data from file: " << image_path
-              << std::endl;
-  }
-
-  // The data is stored sequentially, in this order per pixel: red, green, blue,
-  // alpha This patterns repeats for every pixel of the image, so the resulting
-  // data layout is: [rgbargbargba...]
-  int query_row = 3;
-  int query_col = 2;
-  const auto index{channels * (query_row * cols + query_col)};
-  const Color color{
-      image_data[index], image_data[index + 1], image_data[index + 2]};
-  std::cout << "Color at pixel: [" << query_row << ", " << query_col
-            << "] =  RGB: (" << color.red << ", " << color.green << ", "
-            << color.blue << ")\n";
-
-  // We must explicitly free the memory allocated for this image.
-  // The reason for this is that stb_image is a C library,
-  // which has no classes and no RAII in the form about which we talked before.
-  // Now you see why people want to write C++ and not C? ;)
-  stbi_image_free(image_data);
-  return 0;
-}
-
-```
-
-The above example can be built and called as follows:
-```bash
-./build/examples/use_stb_image pixelator/test_data/test.png
-```
-
-##### What the example does
-- We get the path provided by the user. This path is stored in `argv[1]`. We convert it to the `std::filesystem::path` and check if the file exists
-- We load the image using the `stbi_load` function. Note here that because the function is coming from the C interface, it operates on raw memory. We will have to wrap this raw memory into something that allows us to work with it safely. This function returns us the data stored in the image in the `RGBA` format where each value is an `unsigned char` of value in the range from 0 to 255. It also populates the variables `rows`, `cols` and `channels` the pointers to which we provide into the function call
-- We can now query the data that we just loaded. Because the colors are stored in a single array, we have to compute the index of the start of any particular pixel, which we do and store this value in the `index` variable. You will have to use this formula in your code too
-- We print the RGB value of the pixel at a given location by taking the appropriate values form the `image_data` array
-- We free the memory allocated for our image using the `stbi_image_free` function. Note that we will implement a memory safe wrapper around these data in this exercise
-
-If everything goes well the program will print:
-```
-Loaded image of size: [6, 4] with 4 channels
-Color at pixel: [3, 2] =  RGB: (255, 255, 255)
-```
-
-> :bulb: Note that this example is also provided as part of the skeleton for the project so that you can play around with it. You can find it [here](pixelator/examples/use_stb_image.cpp).
-
-### The libraries (and CMake targets) that you have to implement
-
-There will be 4 libraries (more concretely, library CMake targets):
-- `stb_image_data_view` - A library that encapsulates the work with the external STB image library and makes using the data loaded from disk nicer
-- `image` - A library that encapsulates an image that can be created for example by the `PixelateImage` function from the next point in this list
-- `pixelate_image` - A library that provides the function `PixelateImage` that pixelates a provided `StbImageDataView`
-- `drawer` - A library that implements a drawer - a class capable of drawing a pixelated image to the terminal
-
-
-These libraries must all be defined in the `pixelator/CMakeLists.txt` so that the binaries in the `examples` folder and the tests could be linked against those.
-
-Let's specify what these classes must do and, even more importantly, which interface they must follow.
-
-#### `pixelator::StbImageDataView` class
-This class must live in the `pixelator/stb_image_data_view.hpp` header file and must be wrapped into a CMake library with the name `stb_image_data_view` so that it can be linked against other targets.
-
-The `StbImageDataView` class wraps the usage of the `stb` external library. It must have the following interface:
-
-```cpp
-// There must be a size struct in some file, either this or some other header
-struct Size {
-  int row;
-  int col;
-};
-
-// Some path to an image on disk.
-const std::filesystem::path image_path{...};
-// We must be able to load the image from a path and store its data
-// internally in the image object.
-// We should also be able to create an empty image
-pixelator::StbImageDataView image{image_path};
-pixelator::StbImageDataView empty_image{};
-
-// We must have simple accessors
-const pixelator::Size size = image.size();
-const int rows = image.rows();
-const int cols = image.cols();
-// Returns true if and only if the image size is 0.
-const bool empty = image.empty();
-
-// We must be able to get a color by row and column.
-// Note that we return a copy of the color here.
-int row = 4;
-int col = 2;
-const ftxui::Color color = image.at(row, col);
-
-// We should be able to move the images
-pixelator::StbImageDataView other_image = std::move(image);
-empty_image = std::move(image);
-
-// ❌ The following code must NOT compile, copying the StbImageDataView should
-// NOT be allowed
-pixelator::StbImageDataView other_image = image;  // ❌ Must not compile
-empty_image = image;                              // ❌ Must not compile
-
-// At the end, the StbImageDataView objects should free the underlying memory
-// upon destruction.
-```
-
-> :bulb: It is your task to figure out which data this class must store. As long as the class correctly conforms to the required interface _what_ is stored within it is not important.
-
-#### `pixelator::Image` class
-
-This class must live in the `pixelator/image.hpp` header file and must be wrapped into a CMake library with the name `image` so that it can be linked against other targets.
-
-This class represents an image that we can modify in our program. Intuitively, it should store a vector of pixel colors and allow us to get and manipulate these colors provided their coordinate. In the following snippet we describe this interface in more detail:
-
-```cpp
-// Can be created empty
-pixelator::Image empty_image{};
-
-// Can be created with size provided.
-const auto rows{42};
-const auto cols{23};
-pixelator::Image image{rows, cols};
-
-// Has all the useful methods to get its size.
-empty_image.empty();  // Should be true.
-image.empty();  // Should be false.
-image.rows();  // Should be equal to rows.
-image.cols();  // Should be equal to cols.
-image.size();  // Should return pixelator::Size{rows, cols}.
-
-// Should provide read access to the colors.
-// All pixels must be initialized.
-image.at(0, 0) == ftxui::Color{};
-
-// Should provide write access to the colors.
-const ftxui::Color yellowish{ftxui::Color::RGB(255, 200, 100)};
-image.at(4, 2) = yellowish;
-image.at(4, 2) == yellowish;  // Should be true.
-
-// We should be able to copy an image
-const pixelator::Image image_copy{image};
-image_copy.at(4, 2) == yellowish;  // Should be true.
-
-// We should be able to move an image
-const pixelator::Image image_moved{std::move(image)};
-image_moved.at(4, 2) == yellowish;  // Should be true.
-```
-
-#### The `pixelator::PixelateImage` function
-This function must be declared in the `pixelator/pixelate_image.hpp` header file and must be wrapped into a CMake library with the name `pixelate_image` so that it can be linked against other targets.
-
-This is the meat of this homework. Intuitively, this function should take the original image (stored as `StbImageDataView`) and the requested new size. It should then return a new `pixelator::Image` object that holds the pixelated version of the original image. Here is this interface in code:
-
-```cpp
-// Use the test image provided in the project skeleton for tests.
-const auto kImagePath{"../../tui_pixelator/test_data/test.png"};
-const pixelator::StbImageDataView image{kImagePath};
-const auto pixelated_image = pixelator::PixelateImage(image, pixelator::Size{3, 2});
-
-// Note that if the size is larger than the original image the method returns the pixelator::Image object of the same size as the input image with all the pixels having the same values as the original image.
-```
-
-As you can see the interface is quite simple. But the devil is in the detail. You will have to think of a way to "sample" the color when changing to a smaller size.
-
-You will also have to handle the "aspect ratio". Meaning that the scaling factor for both rows and columns should be the same. You can choose it by picking the minimum one as follows:
-```cpp
-// static_cast<float>(number) converts (aka "casts") a number to float.
-const auto factor_cols = smaller_size.cols / static_cast<float>(image.cols());
-const auto factor_rows = smaller_size.rows / static_cast<float>(image.rows());
-const auto smallest_factor = std::min(factor_cols, factor_rows);
-```
-
-You might also make use of a function that can scale the coordinates downwards and upwards depending on the provided scale parameter:
-```cpp
-int Scale(int number, float factor) {
-  return static_cast<int>(number * factor);
-}
-```
-
-With this you should be well equipped to write this function.
-
-#### `pixelator::Drawer` class
-Finally, there should be the `pixelator::Drawer` class in the corresponding header `pixelator/drawer.hpp` that allows, well, to draw the `pixelator::Image` instance to the terminal using the `ftxui` library (more precisely of `ftxui::Screen` class) under the hood.
-
-Here is the interface that this class must conform to:
-```cpp
-// We should be able to create a drawer either of fixed size or of the maximum size that the terminal is capable of. Read the ftxui docs to understand these parameters better.
-pixelator::Drawer full_screen_drawer{ftxui::Dimension::Full()};
-pixelator::Drawer fixed_screen_drawer{ftxui::Dimension::Fixed(42)};
-
-// All the following must be true.
-// Note that the number of cols should be twice the number of rows, see explanation below the code block.
-fixed_screen_drawer.rows() == 42;
-fixed_screen_drawer.cols() == 84;
-fixed_screen_drawer.size() == Size{42, 84};
-
-// We should be able to set a pixelated image to our drawer.
-const auto kImagePath{"../../tui_pixelator/test_data/test.png"};
-const pixelator::StbImageDataView image{kImagePath};
-const auto pixelated_image = pixelator::PixelateImage(image, pixelator::Size{3, 2});
-full_screen_drawer.Set(pixelated_image);
-
-// We should be able to print to the terminal by calling ftxui::Screen functions under the hood.
-full_screen_drawer.Draw();  // Draws to the terminal.
-full_screen_drawer.ToString();  // Prints to string, used for testing.
-```
-
-> :bulb: There is one **important** aspect of the `Drawer` to note here. Remember the example [above](#ftxui-library-by-example) on the usage of `ftxui` and how we had to set 2 columns for 1 row in order to draw a square pixel? We have to do the same trick here. So remember to set the number of columns for the drawer as **double** of the provided rows.
-
-> :bulb: Note that `ftxui::Screen` uses X and Y to describe coordinates, while we use rows and columns. Generally, `rows` correspond to `Y`, while `cols` correspond to `X`. It _is_ confusing, so don't worry if you don't get it right straight away.
-
-### The binary to test your data
-The binary that loads an image from disk, pixelates it and outputs it to the terminal, is already provided to you in the project skeleton. You can find it here: [`pixelator/examples/pixelate.cpp`](pixelator/examples/pixelate.cpp).
-
-> :bulb: Note that you will have to add the needed CMake target on your own.
-
-### Namespace
-All functions and classes in this project must live in the `pixelator` namespace.
-
-### Tests for libraries
-All of the libraries must have unit tests using the `googletest` framework available as a submodule in the project's `external` folder, just like it is presented in the [Googletest](../../lectures/googletest.md) lecture. All of the tests must live in the same folder as the file that contains the code that they test and must be registered through `ctest`.
-
-## How your code is checked
-There is a number of levels of checks to satisfy the homework checker bot.
-- First, your code will be built as is
-- Then your tests will be called
-- After that your binary will be called with the test image as input
-- Finally, the bot will inject an additional test folder `validation_test` into the root of your project and run the custom-designed tests defined there
-
-Every step above will show up as a separate line in the output from the homework checker in your PR and wiki.
-
-## That's it!
-Congratulations! You've implemented this relatively complex project in relatively modern C++! On to the next challenge! Do share your thoughts on the whole process in the [discussions page](https://github.com/orgs/cpp-for-yourself/discussions/categories/general) :pray:
diff --git a/homeworks/homework_5/pixelator/.clang-format b/homeworks/homework_5/pixelator/.clang-format
deleted file mode 100644
index f00cfb4..0000000
--- a/homeworks/homework_5/pixelator/.clang-format
+++ /dev/null
@@ -1,13 +0,0 @@
----
-Language: Cpp
-BasedOnStyle: Google
-AllowShortBlocksOnASingleLine: true
-AllowShortCaseLabelsOnASingleLine: true
-AllowShortFunctionsOnASingleLine: All
-AllowShortLoopsOnASingleLine: true
-AllowShortIfStatementsOnASingleLine: true
-BinPackArguments: false
-BinPackParameters: false
-IncludeBlocks: Preserve
-SortIncludes: true
-...
diff --git a/homeworks/homework_5/pixelator/CMakeLists.txt b/homeworks/homework_5/pixelator/CMakeLists.txt
deleted file mode 100644
index f213f7a..0000000
--- a/homeworks/homework_5/pixelator/CMakeLists.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-cmake_minimum_required(VERSION 3.16..3.24)
-project(pixelator VERSION 1
-  DESCRIPTION "Pixelate images in terminal"
-  LANGUAGES CXX)
-
-if(NOT CMAKE_BUILD_TYPE)
-  set(CMAKE_BUILD_TYPE Release CACHE STRING "" FORCE)
-endif()
-
-message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}")
-
-# Create a pseudo-library to propagate the needed flags.
-add_library(cxx_setup INTERFACE)
-target_compile_options(cxx_setup INTERFACE -Wall -Wpedantic -Wextra)
-target_compile_features(cxx_setup INTERFACE cxx_std_17)
-target_include_directories(cxx_setup INTERFACE ${PROJECT_SOURCE_DIR})
-
-# Update the submodules here
-include(external/UpdateSubmodules.cmake)
-
-# Enable testing for this project
-include(CTest)
-
-# Add code in subdirectories
-add_subdirectory(external)
-add_subdirectory(${PROJECT_NAME})
-add_subdirectory(examples)
diff --git a/homeworks/homework_5/pixelator/examples/CMakeLists.txt b/homeworks/homework_5/pixelator/examples/CMakeLists.txt
deleted file mode 100644
index 7b52064..0000000
--- a/homeworks/homework_5/pixelator/examples/CMakeLists.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-add_executable(use_ftxui use_ftxui.cpp)
-target_link_libraries(use_ftxui PRIVATE cxx_setup ftxui::screen)
-
-add_executable(use_stb_image use_stb_image.cpp)
-target_link_libraries(use_stb_image PRIVATE cxx_setup stb::stb)
-
-# TODO: Add your binaries here
-# There must be a binary `pixelate` here
diff --git a/homeworks/homework_5/pixelator/examples/pixelate.cpp b/homeworks/homework_5/pixelator/examples/pixelate.cpp
deleted file mode 100644
index 06b1e3d..0000000
--- a/homeworks/homework_5/pixelator/examples/pixelate.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-#include "pixelator/drawer.hpp"
-#include "pixelator/pixelate_image.hpp"
-#include "pixelator/stb_image_data_view.hpp"
-
-#include <cstddef>
-#include <filesystem>
-#include <iostream>
-#include <utility>
-
-namespace {
-using pixelator::Drawer;
-using pixelator::PixelateImage;
-using pixelator::StbImageDataView;
-}  // namespace
-
-int main(int argc, char **argv) {
-  if (argc < 2) { std::cerr << "No image provided." << std::endl; }
-
-  const StbImageDataView image{argv[1]};
-  if (image.empty()) {
-    std::cerr << "Image could not be loaded" << std::endl;
-    exit(1);
-  }
-  Drawer drawer{ftxui::Dimension::Full()};
-
-  drawer.Set(PixelateImage(image, drawer.size()));
-  drawer.Draw();
-  return 0;
-}
diff --git a/homeworks/homework_5/pixelator/examples/use_ftxui.cpp b/homeworks/homework_5/pixelator/examples/use_ftxui.cpp
deleted file mode 100644
index 312f727..0000000
--- a/homeworks/homework_5/pixelator/examples/use_ftxui.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-#include "ftxui/screen/color.hpp"
-#include "ftxui/screen/screen.hpp"
-
-namespace {
-const ftxui::Color kYellowishColor = ftxui::Color::RGB(255, 200, 100);
-}
-
-int main() {
-  const ftxui::Dimensions dimensions{ftxui::Dimension::Full()};
-  ftxui::Screen screen{ftxui::Screen::Create(dimensions)};
-  auto &pixel_left = screen.PixelAt(10, 10);
-  pixel_left.background_color = kYellowishColor;
-  pixel_left.character = ' ';
-  auto &pixel_right = screen.PixelAt(11, 10);
-  pixel_right.background_color = kYellowishColor;
-  pixel_right.character = ' ';
-  screen.Print();
-  return 0;
-}
diff --git a/homeworks/homework_5/pixelator/examples/use_stb_image.cpp b/homeworks/homework_5/pixelator/examples/use_stb_image.cpp
deleted file mode 100644
index 9db38e7..0000000
--- a/homeworks/homework_5/pixelator/examples/use_stb_image.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-// Make sure to have this in EXACTLY one cpp file
-// The best place for this is the cpp file of your library
-// that holds a class that wraps around the stb_image data
-// For more see here: https://github.com/nothings/stb#faq
-#define STB_IMAGE_IMPLEMENTATION
-#include "stb/stb_image.h"
-
-#include <filesystem>
-#include <iostream>
-
-namespace {
-static constexpr auto kLoadAllChannels{0};
-
-// A dummy color structure. Use ftxui::Color in actual code.
-struct Color {
-  int red;
-  int green;
-  int blue;
-};
-
-}  // namespace
-
-int main(int argc, char **argv) {
-  if (argc < 2) { std::cerr << "No image provided.\n"; }
-  const std::filesystem::path image_path{argv[1]};
-  if (!std::filesystem::exists(image_path)) {
-    std::cerr << "No image file: " << image_path << std::endl;
-    std::exit(1);
-  }
-
-  // Load the data
-  int rows{};
-  int cols{};
-  int channels{};
-  // This call also populates rows, cols, channels.
-  auto image_data{
-      stbi_load(image_path.c_str(), &cols, &rows, &channels, kLoadAllChannels)};
-  std::cout << "Loaded image of size: [" << rows << ", " << cols << "] with "
-            << channels << " channels\n";
-  if (!image_data) {
-    std::cerr << "Failed to load image data from file: " << image_path
-              << std::endl;
-    std::exit(1);
-  }
-
-  // The data is stored sequentially, in this order per pixel: red, green, blue,
-  // alpha This patterns repeats for every pixel of the image, so the resulting
-  // data layout is: [rgbargbargba...]
-  int query_row = 3;
-  int query_col = 2;
-  const auto index{channels * (query_row * cols + query_col)};
-  const Color color{
-      image_data[index], image_data[index + 1], image_data[index + 2]};
-  std::cout << "Color at pixel: [" << query_row << ", " << query_col
-            << "] =  RGB: (" << color.red << ", " << color.green << ", "
-            << color.blue << ")\n";
-
-  // We must explicitly free the memory allocated for this image.
-  // The reason for this is that stb_image is a C library,
-  // which has no classes and no RAII in the form about which we talked before.
-  // Now you see why people want to write C++ and not C? ;)
-  stbi_image_free(image_data);
-  return 0;
-}
diff --git a/homeworks/homework_5/pixelator/external/CMakeLists.txt b/homeworks/homework_5/pixelator/external/CMakeLists.txt
deleted file mode 100644
index 76e97b4..0000000
--- a/homeworks/homework_5/pixelator/external/CMakeLists.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-include(gtest.cmake)
-include(ftxui.cmake)
-include(stb.cmake)
diff --git a/homeworks/homework_5/pixelator/external/UpdateSubmodules.cmake b/homeworks/homework_5/pixelator/external/UpdateSubmodules.cmake
deleted file mode 100644
index 53ecc98..0000000
--- a/homeworks/homework_5/pixelator/external/UpdateSubmodules.cmake
+++ /dev/null
@@ -1,27 +0,0 @@
-find_package(Git QUIET)
-
-if(GIT_FOUND)
-  option(UPDATE_SUBMODULES "Check submodules during build" ON)
-
-  if(NOT UPDATE_SUBMODULES)
-    return()
-  endif()
-
-  execute_process(COMMAND ${GIT_EXECUTABLE} submodule
-    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
-    OUTPUT_VARIABLE EXISTING_SUBMODULES
-    RESULT_VARIABLE RETURN_CODE)
-
-  message(STATUS "Updating git submodules:\n${EXISTING_SUBMODULES}")
-
-  execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive
-    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
-    RESULT_VARIABLE RETURN_CODE)
-
-  if(NOT RETURN_CODE EQUAL "0")
-    message(WARNING "Cannot update submodules. Git command failed with ${RETURN_CODE}.")
-    return()
-  endif()
-
-  message(STATUS "Git submodules updated successfully.")
-endif()
diff --git a/homeworks/homework_5/pixelator/external/ftxui.cmake b/homeworks/homework_5/pixelator/external/ftxui.cmake
deleted file mode 100644
index 66590db..0000000
--- a/homeworks/homework_5/pixelator/external/ftxui.cmake
+++ /dev/null
@@ -1,4 +0,0 @@
-set(CMAKE_CXX_STANDARD 17)
-set(CMAKE_CXX_STANDARD_REQUIRED ON)
-set(CMAKE_CXX_EXTENSIONS OFF)
-add_subdirectory(ftxui)
diff --git a/homeworks/homework_5/pixelator/external/gtest.cmake b/homeworks/homework_5/pixelator/external/gtest.cmake
deleted file mode 100644
index badab93..0000000
--- a/homeworks/homework_5/pixelator/external/gtest.cmake
+++ /dev/null
@@ -1,5 +0,0 @@
-set(CMAKE_CXX_STANDARD 17)
-set(CMAKE_CXX_STANDARD_REQUIRED ON)
-set(CMAKE_CXX_EXTENSIONS OFF)
-set(INSTALL_GTEST OFF)
-add_subdirectory(googletest)
diff --git a/homeworks/homework_5/pixelator/external/stb.cmake b/homeworks/homework_5/pixelator/external/stb.cmake
deleted file mode 100644
index 48b5676..0000000
--- a/homeworks/homework_5/pixelator/external/stb.cmake
+++ /dev/null
@@ -1,5 +0,0 @@
-add_library(stb INTERFACE)
-target_include_directories(stb INTERFACE ${PROJECT_SOURCE_DIR}/external/)
-if (NOT TARGET stb::stb)
-  add_library(stb::stb ALIAS stb)
-endif()
diff --git a/homeworks/homework_5/pixelator/pixelator/CMakeLists.txt b/homeworks/homework_5/pixelator/pixelator/CMakeLists.txt
deleted file mode 100644
index 4bafc29..0000000
--- a/homeworks/homework_5/pixelator/pixelator/CMakeLists.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-# TODO: Add your libraries here
-# You must have the following libraries:
-# - stb_image_data_view
-# - drawer
-# - image
-# - pixelate_image
-
-if(BUILD_TESTING)
-  include(GoogleTest)
-  # TODO: Add your tests executable with all your tests here
-  # Name it pixelator_tests.
-  # Also use gtest_discover_tests(pixelator_tests)
-  # to register them with CTest
-endif()
diff --git a/homeworks/homework_5/pixelator/pixelator/test_data/test.png b/homeworks/homework_5/pixelator/pixelator/test_data/test.png
deleted file mode 100644
index 16052d2..0000000
--- a/homeworks/homework_5/pixelator/pixelator/test_data/test.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:0e8b9e1511789c79f669a0144d85b8ca3a2be8ff1af0b0b408652b2fd9daf8a4
-size 145
diff --git a/homeworks/homework_5/script.md b/homeworks/homework_5/script.md
deleted file mode 100644
index 818f845..0000000
--- a/homeworks/homework_5/script.md
+++ /dev/null
@@ -1,31 +0,0 @@
-# Video script
-Hey everyone! In this video I want to introduce a project that we (and by "we" I mean "you") will implement to solidify everything that we've learned until this point.
-
-Here is what it'll do. It will turn a normal picture, like this one, into its pixelated form, like that one.
-
-And not only that, but it will also do all of this in the terminal!
-
-<!-- Intro -->
-
-
-Before we go into details, I hope that by now you know that you can find the full homework description below this video under a link to the course GitHub repository. I also provide an empty project skeleton with some boilerplate code for you to get started in an easier way.
-
-Now, let's talk details, shall we?
-
-In order to perform the pixelation we have to perform a number of actions.
-
-1. First we have to load the image from disk. We do this using an external library `stb`, or, more concretely a couple of functions from its header `stb_image.h`. In order to use this library, you will have to add it as a submodule. We already talked about submodules before, but I also provide the necessary command in the homework description file I mentioned before.
-2. Unfortunately, `stb` is a C library, so memory management is not its strongest side. That means we have to store the data that the `stb` library gave us in a safe way. How lucky for us that we learned about raw pointers and proper move semantics already! So we can implement a class, say `StbImageDataView` that will manage the memory allocated by the `stb` library for us! We should be able to move the objects of this class around and they should free the memory upon destruction. Again, I have an example to ease your way into this in the homework description.
-3. Eventually, we will also need a way to manipulate the colors in an image, so we will implement a class `Image` that will allow us to directly access and manipulate the RGB pixels in it. We can represent the colors as a vector of `ftxui::Color` which comes from an awesome library FTXUI, which we will also have to add as a submodule to our code. Once again, I provide an example of how this library can be used in the project skeleton.
-4. At this point we should be ready to implement the `PixelateImage` function that would take our `StbImageDataView`, pixelate it and return it as and `Image` instance. This is the most algorithmically intense part of the project but fear not, I'm sure you can manage!
-5. Finally, once we have the pixelated image at hand, we would like to show it in the terminal. We will again use the FTXUI library for that. The way we can do it is we wrap the `ftxui::Screen` instance into a class `Drawer`, that takes an `Image` instance and can `Draw()` it to the terminal. And, you guessed it, you'll find an example to guide you through this in the project skeleton.
-
-Oh, and of course we have to test all of this, so we add Googletest as a submodule to the project, write tests for all of the stuff I just talked about and test away!
-
-And that's it! That's all the functionality that you have to implement here. Now, I know it sounds like a lot and, if I'm honest, it might be. But it is still a good project to take on in order to get comfortable with coding in C++.
-
-Once again, all the needed details are in the repo linked in the description below.
-
-And at this, I wish you good luck, have lots of fun implementing it and _do_ take your time on this project. It sure took me a long time to prepare everything. It probably will take you multiple hours (or maybe even days) but there are no shortcuts in learning! If something is really confusing, do start a discussion in the GitHub organization linked under the video.
-
-Thanks again for watching and have fun implementing it all! And if you want a refresher on the move semantics or testing your code, do click on the thumbnails that have just appeared on your screen!
diff --git a/lectures/hello_world_dissection.md b/lectures/1.1_hello_world_dissection.md
similarity index 88%
rename from lectures/hello_world_dissection.md
rename to lectures/1.1_hello_world_dissection.md
index db0901a..dc74676 100644
--- a/lectures/hello_world_dissection.md
+++ b/lectures/1.1_hello_world_dissection.md
@@ -26,19 +26,19 @@ Hello World!
 ---
 # Here is what we can learn from it
 
-- [Some keywords](hello_world_dissection.md#some-words-and-symbols-are-more-special-than-other-🦄) like `return` or `int` _(and many more!)_
+- [Some keywords](1.1_hello_world_dissection.md#some-words-and-symbols-are-more-special-than-other-🦄) like `return` or `int` _(and many more!)_
 - Constants like `"Hello World!"` and `0`
-- [Lots of whitespaces!](hello_world_dissection.md#whitespaces-mostly-play-no-role)
-- [Different brackets:](hello_world_dissection.md#what-are-all-those-brackets-about)  `{}`, `()`, `<>`
-- [Signs with special meaning:](hello_world_dissection.md#the--is-not-just-for-social-networks) `#`, `;`, `//`
+- [Lots of whitespaces!](1.1_hello_world_dissection.md#whitespaces-mostly-play-no-role)
+- [Different brackets:](1.1_hello_world_dissection.md#what-are-all-those-brackets-about)  `{}`, `()`, `<>`
+- [Signs with special meaning:](1.1_hello_world_dissection.md#the--is-not-just-for-social-networks) `#`, `;`, `//`
 - Includes like `#include <stdio.h>`
-- [Functions](hello_world_dissection.md#functions-elevator-pitch) like `puts` and `main`
+- [Functions](1.1_hello_world_dissection.md#functions-elevator-pitch) like `puts` and `main`
 
 ## Let's dig into all of these!
-## 📺 Watch the related [YouTube video](https://youtu.be/t2h1geGSww4)!
+## 📺 Watch the related [YouTube video](https://youtu.be/t2h1geGSww4)! 
 
 ---
-# Some words and symbols are more special🦄 than other
+# Some words and symbols are more special than other 🦄
 - In the code above, some words and symbols are highlighted
 - This is done by **parsing** the language into meaningful parts
 - Whitespaces and symbols **separate** these parts
@@ -92,7 +92,7 @@ return 0;}
 
 ```C++
 #include <stdio.h>
-int main()
+int main() 
 {puts(
              "Hello 🌍!"
     );
@@ -114,13 +114,12 @@ return
 ;}
 ```
 </div>
-</div>
 
 ---
 
 # Use clang-format tool to deal with this madness!
 
-- 🤬 People tend to argue (a lot!) about how to style their code
+- 🤬 People tend to argue (a lot!) about how to style their code 
 - 💡 Avoid long discussions by using a tool `clang-format`!
 
 #### To style the `hello.cpp` do the following:
@@ -138,7 +137,7 @@ Just put a `.clang-format` file into a directory up the tree from your source fi
 
 # A "good" clang-format config
 
-- 🤔 Different people will have different opinions here
+- 🤔 Different people will have different opinions here 
 - ✅ This is the `.clang-format` file I use for my projects:
 ```yaml
 ---
@@ -154,7 +153,7 @@ BinPackParameters: false
 ...
 ```
 
-- 🤝 The most important thing is to have **a** format file in the project, regardless of which style it enforces
+- 🤝 The most important thing is to have **a** format file in the project, regardless of which style it enforces 
 
 ---
 
@@ -186,14 +185,14 @@ BinPackParameters: false
 - We'll talk about the other steps later
 
 
----
+--- 
 # An example is worth a 1000 words
 
 - An `#include` is just a _text_ substitution
 - Let's compile `hello.cpp` with a flag `--save-temps`:
     ```cmd
-    λ › c++ -std=c++17 -o hello --save-temps hello.cpp
-    ```
+    λ › c++ -std=c++17 -o hello --save-temps hello.cpp  
+    ``` 
 - This keeps a bunch of files, we care about `hello.ii`:
     ```cmd
     λ › tail -n 4 hello.ii
@@ -204,7 +203,7 @@ BinPackParameters: false
     ```
 - This file _ends_ with our program
 - Above our code there is the contents of the `stdio.h` file
----
+--- 
 
 # Let's get #inclusive
 
@@ -259,9 +258,9 @@ BinPackParameters: false
 - We can (and will!) write lots of our own functions
 - Let's write one right now!
 
----
+--- 
 # The `PrintSmth` function
-- This is **not** the most useful function in the world!
+- This is **not** the most useful function in the world! 
 - We also won't talk about a strict definition of what is a function here, we will cover it later
 - We aim at building intuition here!
 
diff --git a/lectures/cpp_basic_types_and_variables.md b/lectures/1.2_cpp_basic_types_and_variables.md
similarity index 83%
rename from lectures/cpp_basic_types_and_variables.md
rename to lectures/1.2_cpp_basic_types_and_variables.md
index fc42429..1b25909 100644
--- a/lectures/cpp_basic_types_and_variables.md
+++ b/lectures/1.2_cpp_basic_types_and_variables.md
@@ -3,7 +3,7 @@ marp: true
 math: katex
 theme: custom-theme
 footer: ![width:80px](images/C++ForYourselfIcon.png)
-paginate: true
+
 ---
 
 # Basics of C++
@@ -14,11 +14,11 @@ paginate: true
 - `const`, `constexpr`
 - References
 
-#### 📺 Watch the related [YouTube video](https://youtu.be/0z0gvv_Tb_U)!
+#### 📺 Watch the related [YouTube video](https://youtu.be/0z0gvv_Tb_U)! 
 
 ---
 # Prerequisites:
-- [Hello world dissection lecture](hello_world_dissection.md)
+- [Hello world dissection lecture](1.1_hello_world_dissection.md)
 
 ---
 # Special symbols used in slides
@@ -36,9 +36,6 @@ Style (🎨) and software design (🎓) recommendations mostly come from [Google
 
 # Declaring variables
 Variable declaration follows one of the following patterns:
-<!--
-`CPP_SKIP_SNIPPET`
--->
 ```cpp
 Type variable_name;  // 😱 Uninitialized! Contains random value!
 Type variable_name = value;
@@ -85,14 +82,6 @@ See [Google naming rules](https://google.github.io/styleguide/cppguide.html#Gene
 ---
 
 # Variables of fundamental types
-<!--
-`CPP_SETUP_START`
-int main() {
-  $PLACEHOLDER
-  return 0;
-}
-`CPP_SETUP_END`
--->
 ```cpp
 char caret_return = '\n';      // Single character
 int meaning_of_life = 42;      // Integer number
@@ -107,14 +96,6 @@ auto some_double = 13.0;       // Automatic type [double]
 bool this_is_fun = false;      // Boolean: true or false
 ```
 There are also `unsigned` equivalents for integer types
-<!--
-`CPP_SETUP_START`
-int main() {
-  $PLACEHOLDER
-  return 0;
-}
-`CPP_SETUP_END`
--->
 ```cpp
 unsigned int meaning_of_life = 42U;   // Unsigned integer number
 unsigned long bigger_int = 42UL;      // Unsigned long number
@@ -128,7 +109,7 @@ unsigned long explicit_copy = number; // This works too!
 # Difference between integer types
 - The difference is in the range of representable values
 - We will talk about this later in the course
-- We can get the range for any type `T`:
+- We can get the range for any type `T`: 
   - `std::numeric_limits<T>::min()` - minimum value
   - `std::numeric_limits<T>::max()` - maximum value
   - they live in the `<limits>` header
@@ -140,7 +121,7 @@ unsigned long explicit_copy = number; // This works too!
 int main() {
   std::printf("Min: %d, max: %d\n",
          std::numeric_limits<int>::min(),
-         std::numeric_limits<int>::max());
+         std::numeric_limits<int>::max());                   
   return 0;
 }
 ```
@@ -151,25 +132,10 @@ int main() {
 # Always initialize all variables! 🚨
 
 (unless measured slow, stay tuned to a later point in the course)
-<!--
-`CPP_SETUP_START`
-int main() {
-  $PLACEHOLDER
-  return 0;
-}
-`CPP_SETUP_END`
--->
+
 ```cpp
 int sad_uninitialized_variable;  // 😱 Really, don't do this!
 ```
-<!--
-`CPP_SETUP_START`
-int main() {
-  $PLACEHOLDER
-  return 0;
-}
-`CPP_SETUP_END`
--->
 ```cpp
 bool initializing_is_good = true;  // ✅ Always initialize!
 bool use_uniform_initialization{true};
@@ -177,9 +143,6 @@ auto also_works_with_auto{true};
 auto this_works_too = true;
 ```
 # Also use "value initialization"
-<!--
-`CPP_SKIP_SNIPPET`
--->
 ```cpp
 bool set_to_default_value{};  // Initialize to false
 int some_int_number{};        // Initialize to 0
@@ -216,15 +179,6 @@ Here is the typical output:
 
 # Initialization vs assignment
 We can also **initialize** the variables from other variables
-<!--
-`CPP_SETUP_START`
-int main() {
-  int other_int{};
-  $PLACEHOLDER
-  return 0;
-}
-`CPP_SETUP_END`
--->
 ```cpp
 int some_int{other_int};
 auto some_int_copy = some_int;
@@ -251,47 +205,36 @@ Here is a rule of thumb to tell them apart :+1:
 - Can be used for constants created at **run time**
 - Can be initialized with **any** provided value
 - _Sometimes_ will be available at compile time
-  <!--
-  `CPP_SETUP_START`
-  int main() {
-    $PLACEHOLDER
-    return 0;
-  }
-  `CPP_SETUP_END`
-  -->
-  ```cpp
-  int a = 42;
-  const int b = a;    // ✅
-  const int c = 23;   // ✅
-  const int d = c;    // ✅
-  const auto e = c;   // ✅
-  ```
+```cpp
+int a = 42;
+const int b = a;    // ✅
+const int c = 23;   // ✅
+const int d = c;    // ✅
+const auto e = c;   // ✅
+```
 
 </div>
 
 <div>
 
 ### `constexpr`
-- Can only be used for constants created at
+- Can only be used for constants created at 
   **compile time**
 - Can only be initialized from a `constexpr` value
-  <!--
-  `CPP_SKIP_SNIPPET`
-  -->
-  ```cpp
-  int a = 42;
-  const int a_const = 42;
-  constexpr int b = a;        // ❌
-  constexpr int c = a_const;  // ❌
-  constexpr int d = 23;       // ✅
-  constexpr int e = d;        // ✅
-  constexpr auto f = d;       // ✅
-  ```
+```cpp
+int a = 42;
+const int a_const = 42;
+constexpr int b = a;        // ❌
+constexpr int c = a_const;  // ❌
+constexpr int d = 23;       // ✅
+constexpr int e = d;        // ✅
+constexpr auto f = d;       // ✅
+```
 
 </div>
 </div>
 
-<!--
+<!-- 
 - Run time means whatever happens since we started the program
 - Compile time means whatever happens while the program is compiling
 - Computation happens at compile time and the result is stored to a variable
@@ -316,20 +259,12 @@ There are some exemptions from this rule, but it mostly works
 - Reference is part of the type:
   variable `ref` has type `<OriginalType> &`
 - Changing a reference changes the variable and vice versa
-  <!--
-  `CPP_SETUP_START`
-  int main() {
-    $PLACEHOLDER
-    return 0;
-  }
-  `CPP_SETUP_END`
-  -->
-  ```c++
-  int some_variable = 42;
-  int& some_variable_ref = some_variable;
-  some_variable_ref = 23;
-  // some_variable is now == 23
-  ```
+    ```c++
+    int some_variable = 42;
+    int& some_variable_ref = some_variable;
+    some_variable_ref = 23;
+    // some_variable is now == 23
+    ```
 - Yields performance gain as references **avoid copying data**
   Will be more important when we talk about functions later
 
@@ -346,7 +281,7 @@ There are some exemptions from this rule, but it mostly works
 #include <cstdio>
 
 int main() {
-  int number = 42;
+  int number = 42;  
   int& ref = number; // Name has to fit on the slides ¯\_(ツ)_/¯
   const int& const_ref = number;
   std::printf("ref: %d, const_ref: %d\n", ref, const_ref);
@@ -385,30 +320,14 @@ int main() {  // Start of main scope
 
 # Naming of constants
 - 🎨 Name constants in the **global scope** in `CamelCase` starting with a small letter `k`:
-  <!--
-  `CPP_SETUP_START`
-  int main() {
-    $PLACEHOLDER
-    return 0;
-  }
-  `CPP_SETUP_END`
-  -->
-  ```cpp
-  constexpr float kImportantFloat = 42.42f;
-  const int kHello{42};
-  ```
+```cpp
+constexpr float kImportantFloat = 42.42f;
+const int kHello{42};
+```
 - 🎨 Name constants in any **local scope** in `snake_case`
-  <!--
-  `CPP_SETUP_START`
-  int main() {
-    $PLACEHOLDER
-    return 0;
-  }
-  `CPP_SETUP_END`
-  -->
-  ```cpp
-  const auto local_scope_constant{42UL};
-  ```
+```cpp
+const auto local_scope_constant{42UL};
+```
 - Keyword `const` is part of the variable's type:
   variable `kHello` above has type `const int`
 
@@ -439,18 +358,9 @@ Prints `4294967277` due to an "underflow" (stay tuned)
 # More operations on variables
 - Logical operations defined over boolean variables:
   **or**: `||`, **and**: `&&`, **not**: `!`
-  <!--
-  `CPP_SETUP_START`
-  int main() {
-    bool is_hungry, is_rich, is_warm;
-    $PLACEHOLDER
-    return 0;
-  }
-  `CPP_SETUP_END`
-  -->
-  ```cpp
-  bool is_happy = (!is_hungry && is_warm) || is_rich;
-  ```
+    ```cpp
+    bool is_happy = (!is_hungry && is_warm) || is_rich;
+    ```
 - Additional operations on integer variables:
 - `/` is integer division: i.e. `7 / 3 == 2`
 - `%` is modulo division: i.e. `7 % 3 == 1`
diff --git a/lectures/namespaces_using.md b/lectures/1.3_namespaces_using.md
similarity index 88%
rename from lectures/namespaces_using.md
rename to lectures/1.3_namespaces_using.md
index 1085b99..5059e17 100644
--- a/lectures/namespaces_using.md
+++ b/lectures/1.3_namespaces_using.md
@@ -9,12 +9,12 @@ footer: ![width:80px](images/C++ForYourselfIcon.png)
 - Namespaces
 - Using `using`
 
-### 📺 Watch the related YouTube video!
+### 📺 Watch the related YouTube video! 
 
 ---
 # Prerequisites:
-- [Hello world dissection lecture](hello_world_dissection.md)
-- [Variables of fundamental types](cpp_basic_types_and_variables.md)
+- [Hello world dissection lecture](1.1_hello_world_dissection.md)
+- [Variables of fundamental types](1.2_cpp_basic_types_and_variables.md)
 
 ---
 # Special symbols used in slides
@@ -35,18 +35,12 @@ Style (🎨) and software design (🎓) recommendations mostly come from [Google
 
 - Variables (and other stuff) can live in namespaces
 - Namespaces are defined with the keyword `namespace`:
-  <!--
-  `CPP_SKIP_SNIPPET`
-  -->
   ```cpp
   namespace cpp_course {
   // Variables, functions etc.
   }  // namespace cpp_course
   ```
 - Namespaces can live within other namespaces:
-  <!--
-  `CPP_SKIP_SNIPPET`
-  -->
   ```cpp
   namespace foo {
   namespace bar {
@@ -54,7 +48,7 @@ Style (🎨) and software design (🎓) recommendations mostly come from [Google
   }  // namespace bar
   }  // namespace foo
   ```
-- 🎨 End with comment: `// namespace <name>`
+- 🎨 End with comment: `// namespace <name>` 
   (`clang_format` will take care of this)
 - 🎨 Name them like variables in `snake_case` ([source](https://google.github.io/styleguide/cppguide.html#Namespace_Names))
 - 🎨 Do not indent the code inside the namespace ([source](https://google.github.io/styleguide/cppguide.html#Namespace_Formatting))
@@ -101,7 +95,7 @@ int main() {
     return 0;
   }
   ```
----
+--- 
 # Use unnamed namespaces!
 - ✅ Use **"unnamed" namespaces** in source files
   ```cpp
@@ -116,7 +110,7 @@ int main() {
   ```
 - They are sometimes also called **"anonymous" namespaces**
 - This generates a namespace with a unique name available only in this "translation unit" (aka source file)
-- Also has "[linkage](static_outside_classes.md#linkage)" implications
+- Also has "linkage" implications 
   (stay tuned for when we talk about `static`)
 - Only use them in `.cpp`, `.cc` files, never in `.h`, `.hpp` etc.
   (stay tuned for when we talk about headers)
@@ -140,8 +134,8 @@ int main() {
 }
 ```
 - :x: **Don't** use from **global scope** (unless in a `cpp` file)
-- :x: **Never** use `using namespace foo;`
-  😱 It's too permissive and  pollutes the current namespace!
+- :x: **Never** use `using namespace foo;` 
+  😱 It's too permissive and  pollutes the current namespace! 
 
 ---
 
diff --git a/lectures/io_streams.md b/lectures/1.4_io_streams.md
similarity index 93%
rename from lectures/io_streams.md
rename to lectures/1.4_io_streams.md
index 8880954..4133f30 100644
--- a/lectures/io_streams.md
+++ b/lectures/1.4_io_streams.md
@@ -15,8 +15,8 @@ We're gonna talk about it a lot!
 ---
 # Prerequisites:
 - Working with terminal
-- [Hello world dissection](hello_world_dissection.md)
-- [Variables of fundamental types](cpp_basic_types_and_variables.md)
+- [Hello world dissection](1.1_hello_world_dissection.md)
+- [Variables of fundamental types](1.2_cpp_basic_types_and_variables.md)
 
 ---
 
diff --git a/lectures/more_useful_types.md b/lectures/1.5_more_useful_types.md
similarity index 80%
rename from lectures/more_useful_types.md
rename to lectures/1.5_more_useful_types.md
index e690b33..f190f85 100644
--- a/lectures/more_useful_types.md
+++ b/lectures/1.5_more_useful_types.md
@@ -2,7 +2,6 @@
 marp: true
 math: katex
 theme: custom-theme
-paginate: true
 footer: ![width:80px](images/C++ForYourselfIcon.png)
 ---
 
@@ -15,22 +14,22 @@ We're gonna talk about it a lot!
 #### Today:
 - `std::pair`
 - `std::array`
-- `std::vector`
+- `std::vector` 
 - `std::string`
 - Aggregate initialization
 
-### 📺 Watch the related [YouTube video](https://youtu.be/dwkSVkGsvFk)!
+### 📺 Watch the related [YouTube video](https://youtu.be/dwkSVkGsvFk)! 
 
 ---
 # Prerequisites:
-- [Variables of fundamental types](cpp_basic_types_and_variables.md)
-- [Namespaces and using](namespaces_using.md)
-- [Input output streams](io_streams.md)
+- [Variables of fundamental types](1.2_cpp_basic_types_and_variables.md)
+- [Namespaces and using](1.3_namespaces_using.md)
+- [Input output streams](1.4_io_streams.md)
 
 ---
 
 # Disclaimer
-- This lecture is beginner friendly
+- This lecture is beginner friendly 
 - There are some best practices that would use different types, but those require more in-depth understanding and will be covered later
 - What you see on this slide is the best practice **until this point** in the course 😉
 
@@ -52,29 +51,10 @@ Style (🎨) and software design (🎓) recommendations mostly come from [Google
 # Store value pairs in `std::pair`
 - `#include <utility>` to use [`std::pair`](https://en.cppreference.com/w/cpp/utility/pair)
 - Allows storing values of two types `std::pair<T1, T2>`
-  <!--
-  `CPP_SETUP_START`
-  #include <utility>
-  #include <string>
-  int main() {
-    $PLACEHOLDER
-    return 0;
-  }
-  `CPP_SETUP_END`
-  -->
   ```cpp
   std::pair<int, std::string> pair{42, "The answer"};
   ```
 - 🔼1️⃣7️⃣ The types will be guessed by the compiler:
-  <!--
-  `CPP_SETUP_START`
-  #include <utility>
-  int main() {
-    $PLACEHOLDER
-    return 0;
-  }
-  `CPP_SETUP_END`
-  -->
   ```cpp
   std::pair pair{42, "The answer"};
   ```
@@ -91,7 +71,7 @@ int main() {
 ```
 
 ---
-<!-- _paginate: false -->
+
 ![bg](https://fakeimg.pl/1280x1024/226699/fff/?text=STL%0ASequence%0Acontainers&font=bebas)
 
 ---
@@ -99,12 +79,12 @@ int main() {
 # Use `std::array` for fixed size collections of items of same type
 - 🔼1️⃣1️⃣ `#include <array>` to use [`std::array`](https://en.cppreference.com/w/cpp/container/array)
 - 🚨 The size must be known at compile time
-- Create from data:
-  🔼1️⃣7️⃣ `std::array arr = {1, 2, 3};`
-  🔼1️⃣7️⃣ `std::array arr{1, 2, 3};`
-  🔼1️⃣4️⃣ `std::array<int, 3UL> arr{1, 2, 3};`
-  🔼1️⃣1️⃣ `std::array<int, 3UL> arr = {1, 2, 3};`
-  1️⃣1️⃣ `std::array<int, 3UL> arr{{1, 2, 3}};`
+- Create from data: 
+  🔼1️⃣7️⃣ `std::array arr = {1, 2, 3};` 
+  🔼1️⃣7️⃣ `std::array arr{1, 2, 3};` 
+  🔼1️⃣4️⃣ `std::array<int, 3UL> arr{1, 2, 3};` 
+  🔼1️⃣1️⃣ `std::array<int, 3UL> arr = {1, 2, 3};` 
+  1️⃣1️⃣ `std::array<int, 3UL> arr{{1, 2, 3}};` 
   - In the newer standards, compiler guesses type and size
   - 🚨 Beware of double brackets in `C++11`!
 
@@ -135,10 +115,10 @@ int main() {
 - `#include <vector>` to use [`std::vector`](https://en.cppreference.com/w/cpp/container/vector)
 - Vector is implemented as a [**dynamic table**](https://en.wikipedia.org/wiki/Dynamic_array)
 - Create similarly to the `std::array`:
-  - 🔼1️⃣7️⃣ `std::vector vec{1, 2, 3};`
-  - 🔼1️⃣7️⃣ `std::vector vec = {1, 2, 3};`
-  - 🔼1️⃣1️⃣ `std::vector<int> vec{1, 2, 3};`
-  - 🔼1️⃣1️⃣ `std::vector<int> vec = {1, 2, 3};`
+  - 🔼1️⃣7️⃣ `std::vector vec{1, 2, 3};` 
+  - 🔼1️⃣7️⃣ `std::vector vec = {1, 2, 3};` 
+  - 🔼1️⃣1️⃣ `std::vector<int> vec{1, 2, 3};` 
+  - 🔼1️⃣1️⃣ `std::vector<int> vec = {1, 2, 3};` 
 - Access stored elements just like in `std::array`
   **But** we can also change the accessed values!
 - ✅ Use `std::vector` a lot! It is **fast and flexible**!
@@ -168,23 +148,13 @@ int main() {
 - `reserve(n)` allocates enough memory to store `n` items but **does not change** the `size()` of the vector
 - This is a very **important optimization**
 - Do it if you know (even just approximately) the number of elements you plan to add in advance
-  <!--
-  `CPP_SETUP_START`
-  #include <vector>
-  #include <string>
-  int main() {
-    $PLACEHOLDER
-    return 0;
-  }
-  `CPP_SETUP_END`
-  -->
   ```cpp
   // Somewhere in some function
   std::vector<std::string> vec;
   const int number_of_iterations = 100;
   // Always call reserve when you know the size.
   vec.reserve(number_of_iterations);
-  for (int i = 0; i < number_of_iterations; ++i) {
+  for (int i = 0; i < kIterNum; ++i) {
     vec.emplace_back("hello");
   }
   ```
@@ -244,27 +214,19 @@ int main() {
 
 - Use [`std::to_string`](https://en.cppreference.com/w/cpp/string/basic_string/to_string) to convert variables of fundamental types to `std::string`
 - Use `std::sto[i|d|f|ul]` etc. to convert from strings:
-  - [`std::stoi`](https://en.cppreference.com/w/cpp/string/basic_string/stol): `std::string` $\rightarrow$ `int`
-  - [`std::stof`](https://en.cppreference.com/w/cpp/string/basic_string/stof): `std::string` $\rightarrow$ `float`
-  - [`std::stod`](https://en.cppreference.com/w/cpp/string/basic_string/stof): `std::string` $\rightarrow$ `double`
-  - [`std::stoul`](https://en.cppreference.com/w/cpp/string/basic_string/stoul): `std::string` $\rightarrow$ `unsigned long`
+  - [`std::stoi`](https://en.cppreference.com/w/cpp/string/basic_string/stol) --- `std::string` $\rightarrow$ `int`
+  - [`std::stof`](https://en.cppreference.com/w/cpp/string/basic_string/stof) --- `std::string` $\rightarrow$ `float`
+  - [`std::stod`](https://en.cppreference.com/w/cpp/string/basic_string/stof) --- `std::string` $\rightarrow$ `double`
+  - [`std::stoul`](https://en.cppreference.com/w/cpp/string/basic_string/stoul) --- `std::string` $\rightarrow$ `unsigned long`
   - There are more flavors (click the links :wink:)
-<!--
-`CPP_SETUP_START`
-#include <string>
-int main() {
-  $PLACEHOLDER
-  return 0;
-}
-`CPP_SETUP_END`
--->
+
 ```cpp
 // Somewhere in some function
 const int starting_number{42};
 const std::string some_string{std::to_string(starting_number)};
 int recovered_number{std::stoi(some_string)};
-// It will even ignore the text after the number!
-int another_number{std::stoi("42 is the number")};
+// It will even ignore the text!
+int another_number{std::stoi("the number is 42")};
 // Try it with other types and negative numbers too!
 ```
 
@@ -276,15 +238,6 @@ int another_number{std::stoi("42 is the number")};
 - Be careful when creating containers with strings:
   **Reason:** compiler will use C-style `char` arrays instead of `std::string` as a storage type
 - 💡 `std::vector` has a special 2-element constructor:
-  <!--
-  `CPP_SETUP_START`
-  #include <vector>
-  int main() {
-    $PLACEHOLDER
-    return 0;
-  }
-  `CPP_SETUP_END`
-  -->
   ```cpp
   const std::size_t size{10};
   const int content{42};
@@ -294,43 +247,24 @@ int another_number{std::stoi("42 is the number")};
   const std::vector vec_full_of_42(size, content);
 
   // 🚨 Using curly brackets creates vector with elements {10, 42}
-  const std::vector vec_10_and_42{size, content};
+  const std::vector vec_10_and_42{size, content}; 
   ```
 - ❌ `std::vector<bool>` is **weird**!
   **Reason:** it does _not_ behave like a `vector`, which is confusing
   Use only if you know that you're doing (probably don't)
 
 ---
-# 🔼1️⃣7️⃣ Aggregate initialization
+# 🔼1️⃣7️⃣ Aggregate initialization 
 - Used to initialize multiple variables at the same time
 - 🚨 We **must** use `auto`
 - Also supports `const` and references (`&`)
 - Example with `std::array`:
-  <!--
-  `CPP_SETUP_START`
-  #include <array>
-  int main() {
-    $PLACEHOLDER
-    return 0;
-  }
-  `CPP_SETUP_END`
-  -->
   ```cpp
   const std::array arr{1, 2, 3};
   // Initialize a = 1, b = 2, c = 3
   const auto [a, b, c] = arr;
   ```
 - Example with `std::pair`:
-  <!--
-  `CPP_SETUP_START`
-  #include <utility>
-  #include <string>
-  int main() {
-    $PLACEHOLDER
-    return 0;
-  }
-  `CPP_SETUP_END`
-  -->
   ```cpp
   using std::string_literals::operator""s;
   const std::pair pair{"Hello"s, "World"s};
@@ -349,8 +283,4 @@ int another_number{std::stoi("42 is the number")};
 
 ---
 
-<!--
-_footer: ""
-_paginate: false
--->
-![bg](https://fakeimg.pl/1280x1024/226699/fff/?text=Good%20luck!&font=bebas)
+![bg](https://fakeimg.pl/1280x1024/226699/fff/?text=Good%20luck!&font=bebas)
\ No newline at end of file
diff --git a/lectures/associative_containers.md b/lectures/1.6_associative_containers.md
similarity index 84%
rename from lectures/associative_containers.md
rename to lectures/1.6_associative_containers.md
index acac7d3..29895e7 100644
--- a/lectures/associative_containers.md
+++ b/lectures/1.6_associative_containers.md
@@ -2,7 +2,7 @@
 marp: true
 math: katex
 theme: custom-theme
-paginate: true
+footer: ![width:80px](images/C++ForYourselfIcon.png)
 ---
 
 # Associative containers
@@ -13,7 +13,7 @@ paginate: true
 - `std::set`
 - `std::unordered_set`
 
-### 📺 Watch the related [YouTube video](https://youtu.be/TCu76SYmVCg)!
+### 📺 Watch the related [YouTube video](https://youtu.be/TCu76SYmVCg)! 
 
 ---
 # Special symbols used in slides
@@ -24,8 +24,8 @@ paginate: true
 - ❌ - Whatever is marked with this is wrong
 - 🚨 - Alert! Important information!
 - 💡 - Hint or a useful exercise
-- 🔼1️⃣7️⃣ - Holds for this version of C++ (here, `17`) and **above**
-- 🔽1️⃣1️⃣ - Holds for versions **until** this one C++ (here, `11`)
+- 🔼1️⃣7️⃣ - Holds for this version of C++(here, `17`) and **above**
+- 🔽1️⃣1️⃣ - Holds for versions **until** this one C++(here, `11`)
 
 Style (🎨) and software design (🎓) recommendations mostly come from [Google Style Sheet](https://google.github.io/styleguide/cppguide.html) and the [CppCoreGuidelines](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines)
 
@@ -36,58 +36,22 @@ Style (🎨) and software design (🎓) recommendations mostly come from [Google
 - Implemented _usually_ as a **Red-Black tree** (not guaranteed)
 - Key can be any type with operator `<` defined
 - By default takes two template parameters:
-  <!--
-  `CPP_SETUP_START`
-  #include <map>
-  int main() {
-    $PLACEHOLDER
-    return 0;
-  }
-  `CPP_SETUP_END`
-  -->
   ```cpp
   std::map<char, double> map_default{};
   ```
 - We can also use `>` operator by creating the map like this:
-  <!--
-  `CPP_SETUP_START`
-  #include <map>
-  int main() {
-    $PLACEHOLDER
-    return 0;
-  }
-  `CPP_SETUP_END`
-  -->
   ```cpp
   std::map<int, float, std::greater<int>> map_greater{};
   ```
 - Access, add, remove data in $\mathcal{O}(\log{}n)$
-
+  
 ---
 # Add data to `std::map`
 - We can create a map from data:
-  <!--
-  `CPP_SETUP_START`
-  #include <map>
-  int main() {
-    $PLACEHOLDER
-    return 0;
-  }
-  `CPP_SETUP_END`
-  -->
-  ```cpp
+- ```cpp
   const std::map<int, double> map_explicit = {{42, 42.42}};
   ```
 - 🔼1️⃣7️⃣
-  <!--
-  `CPP_SETUP_START`
-  #include <map>
-  int main() {
-    $PLACEHOLDER
-    return 0;
-  }
-  `CPP_SETUP_END`
-  -->
   ```cpp
   const std::map map_implicit = {std::pair{42, 42.42}};
   ```
@@ -102,8 +66,8 @@ Style (🎨) and software design (🎓) recommendations mostly come from [Google
 - Erase key: `my_map.erase(key);`
 
 ---
+
 # Example using `std::map`
-<!-- _class: center_code -->
 ```cpp
 #include <iostream>
 #include <map>
@@ -132,7 +96,7 @@ int main() {
 ```
 ---
 # Use `std::unordered_map` to store unordered data
-- 🔼1️⃣1️⃣ `#include <unordered_map>`
+- 🔼1️⃣1️⃣ `#include <unordered_map>` 
   to use [`std::unordered_map`](https://en.cppreference.com/w/cpp/container/unordered_map)
 - Serves same purpose as `std::map` but is implemented as a **hash table** and not a tree
 - Key type has to be **hashable** (all fundamental types are)
@@ -146,16 +110,6 @@ int main() {
   - Elements of `map2` not in `map1` are added to `map1`
   - Elements of `map2` with keys already in `map1` are ignored
 - Works for both: `std::map` and `std::unordered_map`:
-  <!--
-  `CPP_SETUP_START`
-  #include <string>
-  #include <map>
-  int main() {
-    $PLACEHOLDER
-    return 0;
-  }
-  `CPP_SETUP_END`
-  -->
   ```cpp
   std::map<std::string, int> map1{
       {"A", 1}, {"B", 2}, {"C", 3}};
@@ -163,16 +117,6 @@ int main() {
       {"A", 4}, {"B", 2}, {"D", 4}};
   map1.merge(map2);
   ```
-  <!--
-  `CPP_SETUP_START`
-  #include <string>
-  #include <unordered_map>
-  int main() {
-    $PLACEHOLDER
-    return 0;
-  }
-  `CPP_SETUP_END`
-  -->
   ```cpp
   std::unordered_map<std::string, int> map1{
       {"A", 1}, {"B", 2}, {"C", 3}};
@@ -212,4 +156,4 @@ We will cover the reason behind this in a later video!
 
 ---
 
-![bg](https://fakeimg.pl/1280x1024/226699/fff/?text=Good%20luck!&font=bebas)
+![bg](https://fakeimg.pl/1280x1024/226699/fff/?text=Good%20luck!&font=bebas)
\ No newline at end of file
diff --git a/lectures/all_or_nothing.md b/lectures/all_or_nothing.md
deleted file mode 100644
index c1f4453..0000000
--- a/lectures/all_or_nothing.md
+++ /dev/null
@@ -1,720 +0,0 @@
-
-The rule of "All Or Nothing" - safely copying and moving objects
----
-
-<p align="center">
-  <a href="https://youtu.be/una89pkP9ms"><img src="https://img.youtube.com/vi/una89pkP9ms/maxresdefault.jpg" alt="Video" align="right" width=50%></a>
-</p>
-
-- ["Good style" as our guide](#good-style-as-our-guide)
-- [What is "good style"](#what-is-good-style)
-- [Setting up the example](#setting-up-the-example)
-- [Rule 1: destructor](#rule-1-destructor)
-- [Rule 2: copy constructor](#rule-2-copy-constructor)
-- [Rule 3: copy assignment operator](#rule-3-copy-assignment-operator)
-- [Rule 4: move constructor](#rule-4-move-constructor)
-- [Rule 5: move assignment operator](#rule-5-move-assignment-operator)
-- [Now we (mostly) follow best practices](#now-we-mostly-follow-best-practices)
-- [Rule of 5](#rule-of-5)
-- [The rule of "all or nothing"](#the-rule-of-all-or-nothing)
-
-
-<!-- Talking head -->
-If you ever wanted to embrace a teenager within you, to deal with the world in absolute categories then this topic is for you. Because when it comes to destructors, custom copy and move constructors and operators of a class it is *really* about having "all or nothing"!
-
-<!-- Intro -->
-
-# "Good style" as our guide
-<!-- Talking head -->
-Jokes aside, in the previous video about [move semantics](move_semantics.md) we had an example `struct` that made use of copy and move assignment operators. Turns out there are rules to follow when implementing these operators and their "friends". As a result the struct in that video did not follow a good style.
-<!-- Maybe insert a throwback to previous video here -->
-
-# What is "good style"
-<!-- Talking head -->
-A logical question then seems to be "what *is* the good style?". Long story short:
-<!-- Overlay -->
-> Good style is a style that helps us avoid mistakes and makes things easier to implement.
-
-<!-- Talking head
-Pop-up google style sheet and core guidelines
--->
-There are many rules about good style when it comes to writing classes but I don't want to postulate any rules out of context. Rather, in the spirit of this course, let's build up to these good practices by formulating various "rules of good style" and summarize them as a single easy-to-remember rule afterwards.
-
-# Setting up the example
-<!-- Code voiceover
-- Show the whole struct 🆗
-- Change it to class 🆗
-- Highlight constructor 🆗
-- Highlight AllocateMemory function 🆗
-- Highlight destructor 🆗
-- Highlight FreeMemory function 🆗
-- Zoom out 🆗
--->
-So, in the [previous lecture](move_semantics.md) we had a struct `HugeObject` that owned some big chunk of memory. Today, we're going to make it a class to ensure encapsulation but other than that it does the same things as before. It allocates a chunk of memory in its constructor through some magic function `AllocateMemory` and frees this memory in its destructor through some other magic function `FreeMemory`.
-<!-- Just as before, their exact implementation is not important right now but you *can* find their implementation in the script to this video, link is as always in the description. -->
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-
-int main() {
-  HugeObject object_1;
-  HugeObject object_2{100};
-}
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` huge_object_initial/main.cpp
-`CPP_RUN_CMD` CWD:huge_object_initial c++ -std=c++17 -c main.cpp
--->
-```cpp
-#include <cstddef>
-
-std::byte *AllocateMemory(std::size_t length) { return new std::byte[length]; }
-void FreeMemory(std::byte *ptr) { delete[] ptr; }
-
-// 😱 Note that this class does not follow best style.
-class HugeObject {
- public:
-  HugeObject() = default;
-
-  explicit HugeObject(std::size_t data_length)
-      : length_{data_length}, ptr_{AllocateMemory(length_)} {}
-
-  ~HugeObject() { FreeMemory(ptr_); }
-
- private:
-  std::size_t length_{};
-  std::byte *ptr_{};
-};
-```
-<!-- Talking head -->
-To help us down the line we want to be able to get the address of the allocated memory, so let's add a function that will give it to us.
-<!-- Code voiceover
-- Add getter 🆗
-- highlight name 🆗
-- highlight return type 🆗
--->
-As covered in the lecture about [object lifecycle](object_lifecycle.md), we can provide a simple getter function that returns a pointer to our const data.
-<!--
-`CPP_SETUP_START`
-#include <cstddef>
-
-std::byte *AllocateMemory(std::size_t length) { return new std::byte[length]; }
-void FreeMemory(std::byte *ptr) { delete[] ptr; }
-
-// 😱 Note that this class does not follow best style.
-class HugeObject {
- public:
-  HugeObject() = default;
-
-  explicit HugeObject(std::size_t data_length)
-      : length_{data_length}, ptr_{AllocateMemory(length_)} {}
-
-  $PLACEHOLDER
-
-  ~HugeObject() { FreeMemory(ptr_); }
-
- private:
-  std::size_t length_{};
-  std::byte *ptr_{};
-};
-
-int main() {
-  const HugeObject object_1;
-  object_1.ptr();
-}
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` huge_object_getter/main.cpp
-`CPP_RUN_CMD` CWD:huge_object_getter c++ -std=c++17 -c main.cpp
--->
-```cpp
-std::byte const *ptr() const { return ptr_; }
-```
-> 🎨 Note that such a simple getter function usually has a name of the variable it returns without the trailing underscore [[Google style]](https://google.github.io/styleguide/cppguide.html#Variable_Names).
-
-> :bulb: Oh, and if you are confused about the return type of this function give a lecture about the [raw pointers](raw_pointers.md) a go.
-<!-- The link is in the description and somewhere on the screen. -->
-
-<!-- Talking head + code voiceover
-- Add main function 🆗
-- Highlight const in getter 🆗
--->
-One final preparatory touch, let's also introduce a simple `main` function that creates a `HugeObject` instance and prints the address of the memory allocated for it:
-<!--
-`CPP_SETUP_START`
-#include <cstddef>
-#include <iostream>
-
-std::byte *AllocateMemory(std::size_t length) { return new std::byte[length]; }
-void FreeMemory(std::byte *ptr) { delete[] ptr; }
-
-// 😱 Note that this class does not follow best style.
-class HugeObject {
- public:
-  HugeObject() = default;
-
-  explicit HugeObject(std::size_t data_length)
-      : length_{data_length}, ptr_{AllocateMemory(length_)} {}
-
-  std::byte const *ptr() const { return ptr_; }
-
-  ~HugeObject() { FreeMemory(ptr_); }
-
- private:
-  std::size_t length_{};
-  std::byte *ptr_{};
-};
-
-$PLACEHOLDER
-
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` huge_object_getter_cout/main.cpp
-`CPP_RUN_CMD` CWD:huge_object_getter_cout c++ -std=c++17 -c main.cpp
--->
-```cpp
-int main() {
-  const HugeObject object{42};
-  std::cout << "Data address: " << object.ptr() << std::endl;
-  return 0;
-}
-```
-> :bulb: Note that the `const` in the `ptr()` function allows us to call it on a constant `object` variable.
-
-<!-- Talking head -->
-If anything here confuses you, then do refresh your knowledge on [object lifecycle](object_lifecycle.md) in one of the previous lectures.
-
-# Rule 1: destructor
-<!-- Code voiceover
-- Highlight destructor 🆗
--->
-Now that we're done with the preparations, I would like to focus on the destructor here! What happens if it is missing?
-<!-- Animation on the side of the talking head
-- Create object, pointer, data 🆗
-- Remove data, pointer, object 🆗
-- Create object, pointer, data 🆗
-- Remove object and pointer 🆗
-- Wiggle data 🆗
--->
-Right now when an object is created it allocates memory and when it gets destroyed it frees this memory. If we miss the destructor, `FreeMemory` will not be called and the memory will stay behind, causing a memory leak.
-
-<!-- Talking head -->
-This already gives us a glimpse into our first "rule":
-<!-- Overlay -->
-> **Rule 1:** If we acquire resources manually in the constructor we must have a destructor that releases these resources.
-
-<!-- Highlight comment 🆗 -->
-Note that even with this destructor in place we still must explicitly state here that **this class does not follow the best practices**. We'll find out why pretty soon.
-
-<!-- Talking head -->
-Hopefully you did not learn anything _really_ new by now. We touched upon this topic in the [object lifecycle](object_lifecycle.md) lecture before. So now it is about time we focus on why does the comment above our class still hold?
-
-# Rule 2: copy constructor
-<!-- Code voiceover
-- Add new part of the main function 🆗
-- Highlight adding new object 🆗
-- Show the runtime error
--->
-Let's illustrate an issue with our class by changing our `main` function a little bit. If we introduce another object of the `HugeObject` type and initialize it as a copy of our existing object the code will compile but will crash when we run it!
-
-<!--
-`CPP_SETUP_START`
-#include <cstddef>
-#include <iostream>
-
-std::byte *AllocateMemory(std::size_t length) { return new std::byte[length]; }
-void FreeMemory(std::byte *ptr) { delete[] ptr; }
-
-// 😱 Note that this class does not follow best style.
-class HugeObject {
- public:
-  HugeObject() = default;
-
-  explicit HugeObject(std::size_t data_length)
-      : length_{data_length}, ptr_{AllocateMemory(length_)} {}
-
-  std::byte const *ptr() const { return ptr_; }
-
-  ~HugeObject() { FreeMemory(ptr_); }
-
- private:
-  std::size_t length_{};
-  std::byte *ptr_{};
-};
-
-$PLACEHOLDER
-
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` huge_object_copy_fail/main.cpp
-`CPP_RUN_CMD` CWD:huge_object_copy_fail c++ -std=c++17 -c main.cpp
--->
-```cpp
-int main() {
-  const HugeObject object{42};
-  std::cout << "object data address: " << object.ptr() << std::endl;
-  const HugeObject other_object{object};
-  std::cout << "other_object data address: " << other_object.ptr() << std::endl;
-  return 0;
-}
-```
-<!-- Talking head + code voiceover
-- Show the whole code 🆗
-- Highlight all constructors 🆗
-- Add ??? signs
--->
-Let's unpack this. First of all, why does it even compile in the first place? There is no constructor for `HugeObject` class that takes another instance of `HugeObject` class, and yet it still compiles! What is going on here?
-
-<!-- Talking head -->
-The reason is that the compiler is trying to be helpful. A constructor that takes a constant reference to the current type is called a **copy constructor** and the compiler generates a trivial copy constructor for our class **if none is provided by the user**. What do we mean by trivial? Means that it just copies all the variables from one object to another without giving it a second thought.
-
-<!-- Code voiceover
-- Add the constructor 🆗
-- Highlight the inputs 🆗
-- Highlight the copying 🆗
-- Highlight the use of private methods 🆗
--->
-We could even write one ourselves! Essentially, in our case a trivial copy constructor would take a constant `HugeObject` reference and will copy the length and the pointer to our new object:
-<!--
-`CPP_SETUP_START`
-#include <cstddef>
-#include <iostream>
-
-std::byte *AllocateMemory(std::size_t length) { return new std::byte[length]; }
-void FreeMemory(std::byte *ptr) { delete[] ptr; }
-
-// 😱 Note that this class does not follow best style.
-class HugeObject {
- public:
-  HugeObject() = default;
-
-  explicit HugeObject(std::size_t data_length)
-      : length_{data_length}, ptr_{AllocateMemory(length_)} {}
-
-  $PLACEHOLDER
-
-  std::byte const *ptr() const { return ptr_; }
-
-  ~HugeObject() { FreeMemory(ptr_); }
-
- private:
-  std::size_t length_{};
-  std::byte *ptr_{};
-};
-
-int main() {
-  HugeObject object{42};
-  HugeObject object_2{object};
-}
-
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` huge_object_copy_trivial/main.cpp
-`CPP_RUN_CMD` CWD:huge_object_copy_trivial c++ -std=c++17 -c main.cpp
--->
-```cpp
-// 😱 Not a good idea in our case, just showing what a trivial constructor is.
-HugeObject(const HugeObject &object)
-      : length_{object.length_}, ptr_{object.ptr_} {}
-```
-> Note how we can use private members of another object here as we are still within the same `HugeObject` class even though we're dealing with a different instance of this class.
-
-<!-- Talking head -->
-Those of you who watched the video on [move semantics](move_semantics.md) carefully might already notice the issue with such a trivial constructor. :wink:
-
-<!-- Talking head -->
-Really, try to figure this one out before watching further! Do re-watch the [move semantics](move_semantics.md) video if needed. I'll wait!
-<!-- Add video of reading a book, sleeping and doing other stuff -->
-
-<!-- Talking head -->
-Hope you got it by now! The issue is that the trivial constructor just copies over the pointer to a different object, **not the data**!
-<!-- Animation
-- One object that points to the data 🆗
-- Another object that points to the same data 🆗
-- Freeing memory twice 🆗
--->
-So now we have two objects pointing to the same data. And both of these have destructors that will try to remove these data! So in our case the destructor of the `other_object` will succeed at freeing the memory but the destructor of the `object` will try to free the memory that has already been freed, causing a runtime error that mentions something along the lines of freeing the memory twice:
-<!-- Code -->
-```
-a.out(78797,0x1e21a6500) malloc: Double free of object 0x155e06ac0
-a.out(78797,0x1e21a6500) malloc: *** set a breakpoint in malloc_error_break to debug
-```
-<!-- Talking head -->
-Let's dig a little into why this happened. The reason for this error is that there is a number of functions that we use to **actively** manage the resources that a certain object owns. In our case, we have a constructor that allocates memory and a destructor that frees this memory. What we missed here is that we also need to **actively manage memory** when copying our object. A trivial copy constructor does not do it - it just copies the pointer. So, here is our new rule:
-
-<!-- Overlay words -->
-> **Rule 2:** If we manage resources manually in our class, we need a custom copy constructor.
-
-<!-- Talking head -->
-For completeness, let's add the missing proper copy constructor to our class.
-<!-- Code voiceover
-- Add a copy constructor 🆗
-- Highlight every action 🆗
-- Highlight copying 🆗
- -->
-It needs to copy the length of the allocated memory, allocate the needed amount of memory and copy the content of the incoming object's data into its newly allocated memory:
-<!--
-`CPP_SETUP_START`
-#include <cstddef>
-#include <iostream>
-
-std::byte *AllocateMemory(std::size_t length) { return new std::byte[length]; }
-void FreeMemory(std::byte *ptr) { delete[] ptr; }
-
-// 😱 Note that this class does not follow best style.
-class HugeObject {
- public:
-  HugeObject() = default;
-
-  explicit HugeObject(std::size_t data_length)
-      : length_{data_length}, ptr_{AllocateMemory(length_)} {}
-
-  $PLACEHOLDER
-
-  std::byte const *ptr() const { return ptr_; }
-
-  ~HugeObject() { FreeMemory(ptr_); }
-
- private:
-  std::size_t length_{};
-  std::byte *ptr_{};
-};
-
-int main() {
-  const HugeObject object{42};
-  std::cout << "object data address: " << object.ptr() << std::endl;
-  const HugeObject other_object{object};
-  std::cout << "other_object data address: " << other_object.ptr() << std::endl;
-  return 0;
-}
-
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` copy_constructor/main.cpp
-`CPP_RUN_CMD` CWD:copy_constructor c++ -std=c++17 -c main.cpp
--->
-```cpp
-HugeObject(const HugeObject &object)
-      : length_{object.length_}, ptr_{AllocateMemory(length_)} {
-    std::copy(object.ptr_, object.ptr_ + length_, ptr_);
-  }
-```
-
-# Rule 3: copy assignment operator
-<!-- Talking head -->
-Can we remove the annoying comment now, I hear you ask? Unfortunately not yet :shrug:
-
-<!-- Code voiceover
-- Change copy constructor into copy assignment 🆗
--->
-Let me illustrate by changing our `main` function again. Instead of creating `another_object` by copying `object` directly, we will first create a new object as empty and only then assign `object` to it:
-<!--
-`CPP_SETUP_START`
-#include <cstddef>
-#include <iostream>
-
-std::byte *AllocateMemory(std::size_t length) { return new std::byte[length]; }
-void FreeMemory(std::byte *ptr) { delete[] ptr; }
-
-// 😱 Note that this class does not follow best style.
-class HugeObject {
- public:
-  HugeObject() = default;
-
-  explicit HugeObject(std::size_t data_length)
-      : length_{data_length}, ptr_{AllocateMemory(length_)} {}
-
-  HugeObject(const HugeObject &object)
-      : length_{object.length_}, ptr_{AllocateMemory(length_)} {
-    std::copy(object.ptr_, object.ptr_ + length_, ptr_);
-  }
-
-  std::byte const *ptr() const { return ptr_; }
-
-  ~HugeObject() { FreeMemory(ptr_); }
-
- private:
-  std::size_t length_{};
-  std::byte *ptr_{};
-};
-
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` copy_assignment/main.cpp
-`CPP_RUN_CMD` CWD:copy_assignment c++ -std=c++17 -c main.cpp
--->
-```cpp
-int main() {
-  const HugeObject object{42};
-  std::cout << "object data address: " << object.ptr() << std::endl;
-  HugeObject other_object{23};
-  other_object = object;
-  std::cout << "other_object data address: " << other_object.ptr() << std::endl;
-  return 0;
-}
-```
-<!-- Talking head + flipping table, rage quit -->
-If we now compile and run this code we will get exactly the same runtime error as before. I know that at this moment it is very tempting to just flip the table and never return to C++ again but actually, nothing too magical happens here. It's just that the helpful compiler generates more than just a trivial copy constructor. It also generates a trivial copy assignment operator which we actually have already seen in the previous video!
-
-<!-- Animation
-- Create two objects pointing to different data 🆗
-- Move the arrow of one of them to the first 🆗
--->
-> And, the situation here is even worse than with the copy constructor - not only we have a runtime error when our objects get destroyed but we also have a memory leak from the moment we perform the assignment! The memory allocated for the `other_object` is never freed as nothing points to it!
-
-<!-- Talking head -->
-Fixing this is as easy as it was for the copy constructor. We just need to write our own custom copy assignment operator.
-<!-- Code voiceover
-- Add a copy assignment operator 🆗
-- Highlight return type 🆗
-- Highlight self-assign 🆗
-- Highlight freeing memory 🆗
-- Highlight copying 🆗
- -->
-It is very similar to the copy constructor with just a couple of differences. It returns a reference to `HugeObject` and performs two additional steps: it needs to check if we are trying to perform a self-assignment, meaning that we're trying to assign the object to itself, and it needs to free the memory if we had any allocated from before, fixing the memory leak that we've just talked about. Other than that it copies the length, allocates new memory and copies the memory of the incoming object into this newly allocated memory.
-<!--
-`CPP_SETUP_START`
-#include <cstddef>
-#include <iostream>
-
-std::byte *AllocateMemory(std::size_t length) { return new std::byte[length]; }
-void FreeMemory(std::byte *ptr) { delete[] ptr; }
-
-// 😱 Note that this class does not follow best style.
-class HugeObject {
- public:
-  HugeObject() = default;
-
-  explicit HugeObject(std::size_t data_length)
-      : length_{data_length}, ptr_{AllocateMemory(length_)} {}
-
-  HugeObject(const HugeObject &object)
-      : length_{object.length_}, ptr_{AllocateMemory(length_)} {
-    std::copy(object.ptr_, object.ptr_ + length_, ptr_);
-  }
-
-  $PLACEHOLDER
-
-  std::byte const *ptr() const { return ptr_; }
-
-  ~HugeObject() { FreeMemory(ptr_); }
-
- private:
-  std::size_t length_{};
-  std::byte *ptr_{};
-};
-
-int main() {
-  const HugeObject object{42};
-  std::cout << "object data address: " << object.ptr() << std::endl;
-  HugeObject other_object{23};
-  other_object = object;
-  std::cout << "other_object data address: " << other_object.ptr() << std::endl;
-  return 0;
-}
-
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` copy_assignment_correct/main.cpp
-`CPP_RUN_CMD` CWD:copy_assignment_correct c++ -std=c++17 -c main.cpp
--->
-```cpp
-HugeObject &operator=(const HugeObject &object) {
-  if (this == &object) { return *this; }  // Do not self-assign.
-  FreeMemory(ptr_);  // In case we already owned some memory from before.
-  length_ = object.length_;
-  ptr_ = AllocateMemory(length_);
-  std::copy(object.ptr_, object.ptr_ + length_, ptr_);
-  return *this;
-}
-```
-<!-- Talking head -->
-This actually brings us to our third rule:
-
-> **Rule 3:** If we manage resources manually in our class, we need a custom copy assignment operator.
-
-# Rule 4: move constructor
-<!-- Talking head -->
-If you live in a world where you use only C++ versions before 11 then you could stop here but in a modern world we are missing a big chunk from this topic. You might have already guessed what it is - **the move semantics**!
-
-<!-- Talking head -->
-Just as compiler generates implicit copy constructor and assignment operator it also sometimes generates implicit move constructor and assignment operator although in slightly different circumstances - it only generates them if the user has defined no explicit destructor or copy constructor and assignment operator. But it still might cause problems to us so let's dig into this.
-
-<!-- Code voiceover
-- Add std::move to the old example 🆗
-- Add printing address of object 🆗
- -->
-Let's return back to our main function that used a copy constructor and modify it again by adding `std::move` to our `object` when passing it to the `other_object` to make sure that we are using a move constructor of our `HugeObject` class. And while we're at it let's also print the address of `object` after move:
-<!--
-`CPP_SETUP_START`
-#include <cstddef>
-#include <iostream>
-
-std::byte *AllocateMemory(std::size_t length) { return new std::byte[length]; }
-void FreeMemory(std::byte *ptr) { delete[] ptr; }
-
-// 😱 Note that this class does not follow best style.
-class HugeObject {
- public:
-  HugeObject() = default;
-
-  explicit HugeObject(std::size_t data_length)
-      : length_{data_length}, ptr_{AllocateMemory(length_)} {}
-
-  HugeObject(const HugeObject &object)
-      : length_{object.length_}, ptr_{AllocateMemory(length_)} {
-    std::copy(object.ptr_, object.ptr_ + length_, ptr_);
-  }
-
-  HugeObject(HugeObject &&object) : length_{object.length_}, ptr_{object.ptr_} {
-    object.ptr_ = nullptr;
-  }
-
-  std::byte const *ptr() const { return ptr_; }
-
-  ~HugeObject() { FreeMemory(ptr_); }
-
- private:
-  std::size_t length_{};
-  std::byte *ptr_{};
-};
-
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` missing_move_constructor/main.cpp
-`CPP_RUN_CMD` CWD:missing_move_constructor c++ -std=c++17 -c main.cpp
--->
-```cpp
-int main() {
-  HugeObject object{42};
-  std::cout << "object data address: " << object.ptr() << std::endl;
-  const HugeObject other_object{std::move(object)};
-  std::cout << "object data address: " << object.ptr() << std::endl;
-  std::cout << "other_object data address: " << other_object.ptr() << std::endl;
-  return 0;
-}
-```
-<!-- Talking head + output overlay + reuse animation from copying -->
-When we run it, we see that the `other_object.ptr()` points to an address different from where the `object.ptr()` points to, even after the move! If you remember the lecture about the move semantics this is not what we want! We want the `other_object` to steal the data from `object`. Right now it sure looks like the data is just copied over. And this is indeed the case which you can verify by adding a printout to our copy constructor and see that it is indeed called.
-
-<!-- Talking head -->
-The reason for this is that the compiler will only generate a move constructor if there is no custom destructor and no custom copy constructor and assignment operator. By now our class has all of these! So the compiler will _not_ generate a move constructor for us and the rvalue reference will just bind to the normal lvalue reference in our existing copy constructor, so we _will_ perform an unnecessary copy! So, how do we make our class moveable?
-
-<!-- Talking head -->
-By now we already know what to do! We know that we just need to write a custom move constructor and that is it!
-<!-- Code voiceover
-- Add new constructor 🆗
-- Highlight inputs 🆗
-- Highlight copying pointer 🆗
-- Highlight setting other to nullptr 🆗
--->
-We write it in a very similar way to the copy constructor with the slight difference that we take an rvalue reference to `HugeObject` as input, don't copy the data and set the other object's `ptr_` field to `nullptr` (again we cover this in-depth in the move semantics video):
-<!--
-`CPP_SETUP_START`
-#include <cstddef>
-#include <iostream>
-
-std::byte *AllocateMemory(std::size_t length) { return new std::byte[length]; }
-void FreeMemory(std::byte *ptr) { delete[] ptr; }
-
-// 😱 Note that this class does not follow best style.
-class HugeObject {
- public:
-  HugeObject() = default;
-
-  explicit HugeObject(std::size_t data_length)
-      : length_{data_length}, ptr_{AllocateMemory(length_)} {}
-
-  HugeObject(const HugeObject &object)
-      : length_{object.length_}, ptr_{AllocateMemory(length_)} {
-    std::copy(object.ptr_, object.ptr_ + length_, ptr_);
-  }
-
-  $PLACEHOLDER
-
-  HugeObject &operator=(const HugeObject &object) {
-    if (this == &object) { return *this; }  // Do not self-assign.
-    FreeMemory(ptr_);  // In case we already owned some memory from before.
-    length_ = object.length_;
-    ptr_ = AllocateMemory(length_);
-    std::copy(object.ptr_, object.ptr_ + length_, ptr_);
-    return *this;
-  }
-
-  std::byte const *ptr() const { return ptr_; }
-
-  ~HugeObject() { FreeMemory(ptr_); }
-
- private:
-  std::size_t length_{};
-  std::byte *ptr_{};
-};
-
-int main() {
-  HugeObject object{42};
-  std::cout << "object data address: " << object.ptr() << std::endl;
-  const HugeObject other_object{std::move(object)};
-  std::cout << "object data address: " << object.ptr() << std::endl;
-  std::cout << "other_object data address: " << other_object.ptr() << std::endl;
-  return 0;
-}
-
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` move_constructor/main.cpp
-`CPP_RUN_CMD` CWD:move_constructor c++ -std=c++17 -c main.cpp
--->
-```cpp
-HugeObject(HugeObject &&object) : length_{object.length_}, ptr_{object.ptr_} {
-  object.ptr_ = nullptr;
-}
-```
-<!-- Talking head -->
-It is clear that we must also have another rule which probably also connects to having a custom destructor just like it does for the copy constructor:
-
-<!-- Overlay -->
-> **Rule 4:** If we manage resources manually in our class, we need a custom move constructor.
-
-# Rule 5: move assignment operator
-<!-- Talking head -->
-Remember how once we had a copy constructor we also needed a copy assignment operator? Would you be surprized if I told you that the same story repeats here?
-
-<!-- Talking head + overlay video thumbnails -->
-I'd like to leave the implementation of a move assignment operator to you as a small homework. I'm sure you are going to be able to piece it together from this and the move semantics videos. If you get stuck the full code is in the script to this video, as always.
-
-<!-- Talking head -->
-Anyway, once you're done you will know that there is one last rule that we need:
-
-<!-- Overlay -->
-> **Rule 5:** If we manage resources manually in our class, we need a custom move assignment operator.
-
-# Now we (mostly) follow best practices
-<!-- Talking head + code voiceover
-- Remove the comment 🆗
--->
-Don't forget that after you're done implementing the move assignment operator, while there are still some things to improve about our class, we can remove the annoying comment at the top of it as the rest of the improvements are pretty minor!
-
-# Rule of 5
-<!-- Talking head -->
-It's time we summarize our findings somewhat. We might notice here that all of these custom functions rely on the fact that we have to manage some resource of an object manually. In summary we can reformulate all of the previous rules as a single one:
-
-<!-- Overlay -->
-**If the class manages resources manually, it must explicitly implement the following:**
-- **A custom destructor**
-- **A custom copy constructor**
-- **A custom copy assignment operator**
-- **A custom move constructor**
-- **A custom move assignment operator**
-
-<!-- Talking head + overlay -->
-The rule above is also known under the name of a **"rule of 5"** as there are 5 special functions here which was a **"rule of 3"** before move semantics was introduced.
-
-<!-- Talking head -->
-An alternative way to think about this rule is to think that if we find that we need to implement **just one** of the special functions that we just discussed then we most likely need to implement **all the rest** of them.
-
-<!-- Talking head -->
-That being said, I want to stress that we actually nearly never manage our resources manually! And if we don't manage them manually there is no reason to implement any of the special functions we've just discussed!
-
-# The rule of "all or nothing"
-<!-- Talking head -->
-So instead of the "rule of 5" I prefer talking about the rule of **"all or nothing"**:
-<!-- Overlay -->
-**Don't define custom destructor, copy or move constructor or copy or move assignment operators. If just one of them needs to be defined, explicitly define the rest of those operations.** [[ref]](https://arne-mertz.de/2015/02/the-rule-of-zero-revisited-the-rule-of-all-or-nothing/) [[ref]](http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#c20-if-you-can-avoid-defining-default-operations-do)
-
-<!-- Talking head -->
-This is a simple rule to follow and I hope that you now also understand *why* it is needed. We will touch more upon it when we start talking about polymorphism in the context of object oriented programming but for now thanks for following along!
-
-You can find the full code in this file: [all_or_nothing.cpp](code/all_or_nothing.cpp)
-<!-- See you in the next video, bye! -->
diff --git a/lectures/build_systems.md b/lectures/build_systems.md
deleted file mode 100644
index 6921dad..0000000
--- a/lectures/build_systems.md
+++ /dev/null
@@ -1,155 +0,0 @@
----
-marp: true
-math: katex
-theme: custom-theme
-paginate: true
-footer: ![width:80px](images/C++ForYourselfIcon.png)
----
-
-# Build systems
-
-#### Today:
-- Intro to build systems
-- Build commands in a script
-- Build commands in Makefile
-
-### 📺 Watch the related [YouTube video](https://youtu.be/kbk4DphsYPU)!
-
----
-# Special symbols used in slides
-- 🎨 - Style recommendation
-- 🎓 - Software design recommendation
-- 😱 - **Not** a good practice! Avoid in real life!
-- ✅ - Good practice!
-- ❌ - Whatever is marked with this is wrong
-- 🚨 - Alert! Important information!
-- 💡 - Hint or a useful exercise
-- 🔼1️⃣7️⃣ - Holds for this version of C++(here, `17`) and **above**
-- 🔽1️⃣1️⃣ - Holds for versions **until** this one C++(here, `11`)
-
-Style (🎨) and software design (🎓) recommendations mostly come from [Google Style Sheet](https://google.github.io/styleguide/cppguide.html) and the [CppCoreGuidelines](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines)
-
----
-# Let's set up our [C++ files](code/make/simple_build) (again)
-[`blah.h`](code/make/simple_build/blah.h)
-<!--
-`CPP_COPY_SNIPPET` make_simple/blah.h
--->
-```cpp
-#pragma once
-namespace tools {
-void PrintHello();
-} // namespace tools
-```
-
-[`blah.cpp`](code/make/simple_build/blah.cpp)
-<!--
-`CPP_COPY_SNIPPET` make_simple/blah.cpp
--->
-```cpp
-#include <blah.h>
-#include <iostream>
-namespace tools {
-void PrintHello() { std::cout << "Hello!" << std::endl; }
-} // namespace tools
-```
-
-[`main.cpp`](code/make/simple_build/main.cpp)
-<!--
-`CPP_COPY_SNIPPET` make_simple/main.cpp
-`CPP_RUN_CMD` CWD:make_simple c++ -std=c++17 -c blah.cpp -I . -o blah.o && ar rcs libblah.a blah.o && c++ -std=c++17 main.cpp -L . -I . -lblah -o main
--->
-```cpp
-#include <blah.h>
-int main() {
-  tools::PrintHello();
-  return 0;
-}
-```
-
----
-# It's annoying to compile libraries by hand, isn't it?
-- There are **many commands** we have to type **in the right order**
-- If we **mess up their order** --- the libraries **don't compile**!
-- **We can definitely do better!**
-- :thinking: **Naive solution:** we could write a **bash script**!
-  `build.sh`<br>
-  <!--
-  `CPP_COPY_SNIPPET` make_simple/build.sh
-  `CPP_RUN_CMD` CWD:make_simple bash build.sh
-  -->
-  ```bash
-  # Building an executable from main.cpp using library blah.cpp
-  c++ -std=c++17 -c blah.cpp -I . -o blah.o
-  ar rcs libblah.a blah.o
-  c++ -std=c++17 main.cpp -L . -I . -lblah -o main
-  ```
-- Now imagine building **many** libraries and executables
-  or **only** rebuilding **when the code changes**
-- We have to write **lots of bash code** to support this
-- To avoid that, people have written multiple **build systems**!
-
----
-# [Make](https://www.gnu.org/software/make/) - a basic build system
-- Stores the commands in a `Makefile` file
-- Commands are executed as a **chain of dependencies**
-- 🚨 Use **tabs** (<kbd>↹</kbd>) **not spaces** (<kbd>⎵</kbd>) to indent code in this file!
-- Has **block structure** and **simple syntax** (for simple cases :wink:)<br>
-  <!--
-  `CPP_SKIP_SNIPPET`
-  -->
-  ```make
-  target: dependencies
-    command
-    command
-    command
-  ```
-- Run `make target` from a folder with `Makefile`
-- Can have many targets with many dependencies
-- If `target` **file** exists and is **not older** than its `dependencies` --- **nothing happens**!
-- :bulb: This allows us to **avoid doing the work twice**!
-- :bulb: A very good `make` tutorial is [here](https://makefiletutorial.com/)
-
----
-# A [`Makefile`](code/make/simple_build/Makefile) to build C++ code
-<!--
-`CPP_COPY_SNIPPET` make_simple/Makefile
-`CPP_RUN_CMD` CWD:make_simple make
--->
-```make
-all: main
-
-main: main.cpp libblah.a
-	c++ -std=c++17 main.cpp -I . -L . -lblah -o main
-
-libblah.a: blah.o
-	ar rcs libblah.a blah.o
-
-blah.o: blah.cpp
-	c++ -std=c++17 -c blah.cpp -I . -o blah.o
-
-clean:
-	rm -f blah.o libblah.a main
-```
-- Run this with `make` from the same [folder](code/make/simple_build/)
-- :bulb: Follow the order of operations here! What happens when?
-- :bulb: Try to run `make` **again**! What happens now?
-- :bulb: Change a file and re-run `make` **again**! Did it re-build?
-- :bulb: Run `make clean` to remove the generated files
-
----
-# Problems with Makefiles :thinking:
-- `Makefile`s are **very powerful** but can get pretty **complex**
-- The syntax is **finicky** and a bit **too detailed**, not really abstract
-- Writing a `Makefile` for a big project can be hard
-- Supporting **different configurations** also gets complex
-
-# Alternatives?
-- Use a **different build system**, e.g. [ninja](https://ninja-build.org), [bazel](https://bazel.build) etc.
-- And/or use a **build generator**, like [CMake](https://cmake.org), [Meson](https://mesonbuild.com/Tutorial.html), etc.
-
-# Stay tuned!
-
----
-
-![bg](https://fakeimg.pl/1280x1024/226699/fff/?text=Good%20luck!&font=bebas)
diff --git a/lectures/classes_intro.md b/lectures/classes_intro.md
deleted file mode 100644
index 094be62..0000000
--- a/lectures/classes_intro.md
+++ /dev/null
@@ -1,432 +0,0 @@
-# Simple classes in C++
-
-<p align="center">
-  <a href="https://youtu.be/IijP--Xf5kQ"><img src="https://img.youtube.com/vi/IijP--Xf5kQ/maxresdefault.jpg" alt="Video" align="right" width=50%></a>
-</p>
-
-- [Simple classes in C++](#simple-classes-in-c)
-- [The cat's life example](#the-cats-life-example)
-  - [Let's model this using just the functions first](#lets-model-this-using-just-the-functions-first)
-    - [Extension to more cats](#extension-to-more-cats)
-  - [Model this nicer with custom types](#model-this-nicer-with-custom-types)
-- [Time for formalities](#time-for-formalities)
-  - [How to call things](#how-to-call-things)
-  - [What does custom type hold?](#what-does-custom-type-hold)
-    - [Let's define our own type `Cat`!](#lets-define-our-own-type-cat)
-    - [Access modifiers `public` and `private`](#access-modifiers-public-and-private)
-    - [Let's look at the class data](#lets-look-at-the-class-data)
-    - [What's with the `const` after the function?](#whats-with-the-const-after-the-function)
-  - [But what about `struct`?](#but-what-about-struct)
-- [That's about it for now](#thats-about-it-for-now)
-
-<!-- Talking head done -->
-By now we all should be quite comfortable using functions, but there are some things for which using just the functions alone doesn't really provide enough abstraction. The solution to this is to introduce the custom types, otherwise known as **classes**.
-
-<!-- Intro -->
-
-# The cat's life example
-<!-- Talking head done -->
-Let me illustrate what I'm talking about with an example. Imagine that we want to write a game about a cat roaming the world looking for fun adventures.
-
-<!-- B-roll cat doing mischief done -->
-The cat starts off as pretty grumpy and get's its happiness up by doing some fun mischief (like throwing a vase from a table). It's not all fun though and some actions are dangerous and sometimes (rarely) the cat will lose 1 of its 9 lives. We win the game once the cat's happiness reaches 100% or it has explored every corner of our world. If our cat reaches 0 lives, we lose the game.
-
-<!-- Talking head done -->
-Sounds good? So how can we model this in code taking into account everything we know until now?
-
-## Let's model this using just the functions first
-
-<!-- Talking head done -->
-Before we jump into coding this, we first would want to *model* our world and the cat using some variables.
-
-<!-- B-roll visualize done -->
-For simplicity, we will assume a line-like world, which we then can represent as a vector of fun and dangerous events randomly generated for each game. The cat then can be represented by its position in the world, number of lives, and happiness. The coordinate increases and the cat "finds" more events which update the cat's parameters.
-
-<!-- Talking head done -->
-> :bulb: I suggest you to pause here and to try to model this game on your own. How would *you* write it using functions? Give it a try - it's a good exercise!
-
-<!-- B-roll code done -->
-One way or another, we will probably come up with something like this:
-<!--
-`CPP_COPY_SNIPPET` cat_functions/main.cpp
-`CPP_RUN_CMD` CWD:cat_functions c++ -std=c++17 -c main.cpp
--->
-```cpp
-#include <iostream>
-#include <vector>
-
-namespace {
-constexpr auto kMaxHappiness = 100;
-constexpr auto kMaxLives = 9;
-} // namespace
-
-// Feel free to have more events here of course
-enum class Event {
-  kNone,
-  kFun,
-  kDanger,
-  kWorldExplored,
-};
-
-// Generate a random world to explore
-std::vector<Event> GenerateWorld();
-
-// Move the cat in some way
-std::size_t MoveCat(std::size_t cat_position);
-
-// Return a random event in the simplest case
-Event FindNextAdventure(const std::vector<Event>& world, std::size_t cat_position);
-
-// Update number of lives depending on what happened
-int UpdateLives(Event event, int current_lives);
-
-// Update happiness depending on what happened
-int UpdateHappiness(Event event, int current_happiness);
-
-int main() {
-  const auto world = GenerateWorld();
-  std::size_t cat_position{};
-  int cat_lives_counter{kMaxLives};
-  int cat_happiness{0};
-  while (true) {
-    cat_position = MoveCat(cat_position);
-    const auto event = FindNextAdventure(world, cat_position);
-    if (event == Event::kWorldExplored) {
-      std::cout << "The world is fully explored. We won!\n";
-      break;
-    }
-    cat_lives_counter = UpdateLives(event, cat_lives_counter);
-    if (cat_lives_counter < 1) {
-      std::cout << "Cat ran out of lives. We lost...\n";
-      break;
-    }
-    cat_happiness = UpdateHappiness(event, cat_happiness);
-    if (cat_happiness >= kMaxHappiness) {
-      std::cout << "Cat fully happy! We won!\n";
-      break;
-    }
-  }
-  return 0;
-}
-```
-<!-- Highlight the code -->
-> :bulb: Note how I did not implement the functions and just declared them - it is usually enough when designing something to get a feeling for the resulting system. We can fill the implementation once we're happy with the overall design.
-
-<!-- Talking head done -->
-Once we *actually implement* the functions, the code works and is fun to play with (you can add more events and print the ones your cat encounters during the exploration for example) but we quickly start seeing limitations of this approach once we try extending it, for example to multiple cats.
-
-### Extension to more cats
-<!-- Maybe B-roll code? Or animation? Or just number flying at the viewer -->
-We would need to store all the cat properties in vectors. So we'll have a vector for the `cat_lives_counter`, `cat_happiness`, and for `cat_position` so that there is one for each cat. Not only this is not neat, this opens us up to the famous ["off by one" bugs](more_useful_types.md#access-elements-in-an-array) as we now have to process multiple vectors in unison and given that the code will inevitably change later, this _will_ lead to errors.
-
-## Model this nicer with custom types
-<!-- Talking head done -->
-Wouldn't it be nice if we could capture our game setup in a more abstract way to keep the code readable and the logic clear?
-
-<!-- Talking head done -->
-And of course there is such a way (otherwise there would be no lecture about it :wink:), and this way involves **custom types**.
-
-Before we go into the mechanics of the custom types, let's first see how we could theoretically use them on an abstract level. The idea is that we bundle our data along with the methods to process them into the new `Cat` and `World` types:
-
-<!-- B-roll change the code from before done -->
-<!--
-`CPP_SETUP_START`
-using World = int;
-enum class Event {kWorldExplored};
-struct Cat {
-  Event FindNextAdventure(const World& world);
-  void UpdateLives(Event event);
-  void UpdateHappiness(Event event);
-  void Move();
-  bool IsTotallyHappy();
-  bool IsAlive();
-};
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` cat_classes_first/main.cpp
-`CPP_RUN_CMD` CWD:cat_classes_first c++ -std=c++17 -c main.cpp
--->
-```cpp
-#include <iostream>
-#include <vector>
-
-// Magically define the Cat and the World types here
-
-int main() {
-  World world{};
-  Cat cat{};
-  while(true) {
-    cat.Move();
-    const auto event = cat.FindNextAdventure(world);
-    if (event == Event::kWorldExplored) {
-      std::cout << "The world is fully explored. We won!\n";
-      break;
-    }
-    cat.UpdateLives(event);
-    if (!cat.IsAlive()) {
-      std::cout << "Cat ran out of lives. We lost...\n";
-      break;
-    }
-    cat.UpdateHappiness(event);
-    if (cat.IsTotallyHappy()) {
-      std::cout << "Cat fully happy! We won!\n";
-      break;
-    }
-  }
-  return 0;
-}
-```
-<!-- Talking head done -->
-Or, if we think more about it, when we interact with our `cat`, the `Move`, `UpdateLives` and the `UpdateHappiness` functions look more like an implementation detail so we could hide them into our existing `FindNextAdventure` function, further simplifying the `cat` interface!
-
-<!-- B-roll change the code from before done -->
-<!--
-`CPP_SETUP_START`
-using World = int;
-enum class Event {kWorldExplored};
-struct Cat {
-  Event FindNextAdventure(const World& world);
-  bool IsTotallyHappy();
-  bool IsAlive();
-};
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` cat_classes_simple/main.cpp
-`CPP_RUN_CMD` CWD:cat_classes_simple c++ -std=c++17 -c main.cpp
--->
-```cpp
-#include <iostream>
-#include <vector>
-
-// Magically define the Cat and the World types here
-
-int main() {
-  World world{};
-  Cat cat{};
-  while(true) {
-    const auto event = cat.FindNextAdventure(world);
-    if (event == Event::kWorldExplored) {
-      std::cout << "The world is fully explored. We won!\n";
-      break;
-    }
-    if (!cat.IsAlive()) {
-      std::cout << "Cat ran out of lives. We lost...\n";
-      break;
-    }
-    if (cat.IsTotallyHappy()) {
-      std::cout << "Cat fully happy! We won!\n";
-      break;
-    }
-  }
-  return 0;
-}
-```
-
-<!-- B-roll compare two tabs done -->
-Now *this* looks much better than before! The new code is more readable for humans and is going to be easier to maintain!
-
-<!-- Talking head with cats popping up done -->
-> :bulb: This is just one of the ways to design this game. If you have the time, I encourage you to think about the alternatives. Can you think of any? Write what you thought about in the description! Also, once you're at it, think how *this* can be extended to multiple cats :wink:
-
-# Time for formalities
-<!-- Talking head done -->
-<!-- Ok, time for a more formal definition -->
-Now that we know at least a little about what we need the custom types for, we can talk about how to write them!
-
-## How to call things
-<!-- B-roll write code in the middle of the screen done -->
-First of all, let's get the language out of the way:
-
-<!--
-`CPP_SETUP_START`
-using Cat = int;
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` object/main.cpp
-`CPP_RUN_CMD` CWD:object c++ -std=c++17 -c main.cpp
--->
-```cpp
-Cat grumpy_uninitialized_cat;
-Cat cute_initialized_cat{};  // ✅ Force the initialization of all Cat  data
-```
-🚨 Here, `Cat` (with the capital `C`) is called a **class** or a **user-defined type**. The `grumpy_uninitialized_cat` and the `cute_initialized_cat` are variables of type `Cat`. They are also often called **instances** or an **object** of type `Cat`.
-
-> :bulb: Note that in this example `grumpy_uninitialized_cat` _might_ remain uninitialized, which *might* lead to undefined behavior. Unless you have a good reason for it, always initialize variables, also of your custom types.
-
-<!-- Talking head done -->
-🎨 In this course we will name the [custom types in `CamelCase`](https://google.github.io/styleguide/cppguide.html#Type_Names) and the [variables in `snake_case`](https://google.github.io/styleguide/cppguide.html#Variable_Names) just as any other variable.
-
-<!-- Talking head with data and method on each hand done -->
-## What does custom type hold?
-A custom type consists of 2 things:
-- The data it holds
-- The methods to process these data
-
-<!-- Talking head smack them together for encapsulation done -->
-> :bulb: This is usually referred to as **encapsulation**, which is a fancy word that just means that we put data that belongs together in one place along with the methods to process them.
-
-<!-- B-roll: Overlay with class and struct words -->
-### Let's define our own type `Cat`!
-First of all, there are two C++ keywords that indicate to the compiler that we are defining our own custom type:
-- `class`
-- `struct`
-
-<!-- B-roll: Overlay, word class moves to the middle -->
-We're going to use `class` for now and talk about `struct` at the end of this lecture.
-
-<!-- Talking head done -->
-In the beginning of this lecture, we kinda *already* designed our `Cat` class methods without even thinking about the data it has to store.
-
-<!-- B-roll: Overlay with words Methods > Data -->
-In other words, **what** a class does is more important than **how** it does it. The class methods form its **public interface** answering the *what* question, while the data the class holds answers the *how* question and is just an **implementation detail**.
-
-<!-- Talking head done -->
-That's why the methods always come before the data! If we change the class data without changing its public interface nobody should notice!
-
-<!-- B-roll code -->
-<!--
-- Armed with this, let's fully implement our `Cat` class:
-- We define a class by typing the word class, its name and brackets with semicolon (that it ends with ;)
-- Classes have so-called access modifiers: public and private (+ Talking head TAG_5)
-  - Everything under public is a "public interface" and can be accessed from the outside, for example:
-  - The IsAlive() function. We want the user to be able to check if the cat is alive.
-  - Everything under `private` is an "implementation detail" and is only accessible from _within_ the class. For example:
-  - The function UpdateHappiness() should not be available to the user, as the cat decides if it wants to be happy on its own, without the user input
-  - Actually, let's write a small main function and compile this code to illustrate access modifiers in action
-  - int main() {Cat cat{}; cat.IsAlive(); cat.UpdateHappiness(Event::kFun); return 0; }
-  - Let's build it. We use the -c flag as we don't have the implementation for our functions and the code is not supposed to link, so we just want to compile it.
-  - The code builds if we just use the IsAlive function.
-  - But when using a private function we're getting an error!
-  - Insert Talking head TAG_1 and TAG_2 here
-- One more thing I want to draw your attention to is this "const" at the end of IsAlive(), we haven't seen smth like this before!
-  - Explain it with talking head TAG_4
-  - Let's illustrate how it works. First, let's add a dummy non-const function to our cat class and verify that we're able to compile the code as is.
-  - Now Let's make our cat object const and try to call const and non-const functions on it
-  - This results in an error that tells us what we did wrong here!
-- Now with this out of the way we can quickly finalize our public interface.
-- Awesome, the only thing left to do is to fill it with actual code!
-- The first two function are easy, they just return a boolean. But they touch upon the cat internal data, which we _always_ put into the private part of our class. Data is always an implementation detail of a class!
-- We name these variables in snake_case with a trailing underscore_
-- And just as with any other variables we don't want to leave them uninitialized (Talking head TAG_3)
-- Now we get to the most interesting function of our cat class: FindNextAdventure as it has most of the logic.
-- We first outline this logic with calls to some functions that we can then fill in with the actual implementation.
-- These functions will all live in the private area as they should only be used from within the class
-- Feel free to pause at any time to look into the implementation more precisely but once these functions have the actual code in them we have **fully** implemented our cat class!
--->
-<!--
-`CPP_SETUP_START`
-#include <iostream>
-#include <vector>
-
-enum class Event {
-  kNone,
-  kFun,
-  kDanger,
-  kWorldExplored,
-};
-
-namespace {
-constexpr auto kMaxHappiness = 100;
-constexpr auto kMaxLives = 9;
-constexpr auto kHappinessIncrement = 10;
-}  // namespace
-
-using World = std::vector<Event>;
-
-$PLACEHOLDER
-
-int main() {
-  World world{};
-  Cat cat{};
-  const auto& cat_ref{cat};
-  cat_ref.IsAlive();
-  cat_ref.IsTotallyHappy();
-  const auto adventure = cat.FindNextAdventure(world);
-
-  return 0;
-}
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` full_cat/main.cpp
-`CPP_RUN_CMD` CWD:full_cat c++ -std=c++17 -c main.cpp
--->
-```cpp
-class Cat {
-public:
-  bool IsAlive() const { return number_of_lives_ > 0; }
-  bool IsTotallyHappy() const { return happiness_ >= kMaxHappiness; }
-
-  Event FindNextAdventure(const World &world) {
-    Move();
-    if (position_ >= world.size()) {
-      return Event::kWorldExplored;
-    }
-    const auto event = world[position_];
-    UpdateNumberOfLives(event);
-    UpdateHappiness(event);
-    return event;
-  }
-
-private:
-  void Move() { position_++; }
-  void UpdateHappiness(Event event) {
-    if (event == Event::kDanger) {
-      number_of_lives_--;
-    }
-  }
-  void UpdateNumberOfLives(Event event) {
-    if (event == Event::kFun) {
-      happiness_ += kHappinessIncrement;
-    }
-  }
-
-  int number_of_lives_{kMaxLives};
-  int happiness_{};
-  std::size_t position_{};
-}; // <- Note a semicolon here!
-```
-<!-- Skip -->
-There is a whole lot of new stuff going on here! Let's unpack it all one by one.
-
-<!-- Skip -->
-### Access modifiers `public` and `private`
-These define how the data and methods of the class are accessed through an instance of this class.
-
-- Everything under `public:` can be accessed directly from the outside, i.e., `cat.IsAlive()` will compile.
-- Everything under `private:` can **only** be accessed from within the methods of the class itself, i.e., `cat.Move()` won't compile.
-
-<!-- Talking head TAG_5 done -->
-> :bulb: There is also the `protected` access modifier but we will talk about it later.
-
-<!-- Talking head TAG_1 done -->
-🚨 This is the fundamental principle behind **encapsulation**: the data of our class is only reachable from within the methods of our class, so every instance of such a class has full control over its data.
-
-<!-- Talking head TAG_2 done -->
-:art: Also note that we [always](https://google.github.io/styleguide/cppguide.html#Declaration_Order) start with `public` and `private` part follows later. Reason being that we read code from the top and care about what we actually can call more than about some obscure implementation details.
-
-<!-- Skip -->
-### Let's look at the class data
-All the data in a class [**must** live under `private:` part](https://google.github.io/styleguide/cppguide.html#Access_Control).
-
-<!-- Skip -->
-:art: Name `private` variables of a class in `snake_case_` [with the trailing underscore](https://google.github.io/styleguide/cppguide.html#Variable_Names) `_`. It helps differentiate which variable we work with in the class methods.
-
-<!-- Talking head TAG_3 done -->
-> :bulb: Note that we don't leave variables uninitialized as discussed in [the lecture on variable](cpp_basic_types_and_variables.md#always-initialize-all-variables). This helps us avoid the hard-to-debug undefined behavior.
-
-<!-- Talking head TAG_4 -->
-### What's with the `const` after the function?
-Essentially, this means that these functions guarantee that the object on which this function is called will not be changed. It works by the compiler basically assuming that this object is const while in the scope of such a function.
-
-🚨 If a method is not marked as `const` the compiler assumes that it _might need_ to change the object data, so if we call a non-`const` method on a `const` object, the code won't compile!
-
-<!-- Talking head done -->
-## But what about `struct`?
-Ok, I Nearly forgot to talk about `struct`. Structs are _exactly_ the same as classes with just one difference. If you leave a `class` without access modifiers, everything will be `private`. If you do the same with a `struct`, everything will be `public`. Other than that they are exactly the same. Go ahead and try to change our cat `class` into a `struct` to experiment with this!
-
-> :bulb: Having everything `public` though breaks encapsulation. When everybody has access to your internal data you don't really control it anymore. So a [rule of thumb](https://google.github.io/styleguide/cppguide.html#Structs_vs._Classes) is to use `struct` only for pure data storage, if you need any methods use a `class` instead.
-
-<!-- Talking head done -->
-# That's about it for now
-Now we know the basics of what custom types are, why we would care about them and how to write our own ones! This is an important topic to understand as a lot of what modern C++ is builds on top of a solid understanding of what custom types are. In the following lectures we are going to extend what we learned here with further details and learn how to use classes and structs to achieve great things!
-
-<!-- Thanks for watching as always! If you like what I do, tell your friends, subscribe here and maybe watch another video over there. Bye! -->
diff --git a/lectures/cmake.md b/lectures/cmake.md
deleted file mode 100644
index 39e3c22..0000000
--- a/lectures/cmake.md
+++ /dev/null
@@ -1,456 +0,0 @@
----
-marp: true
-math: katex
-theme: custom-theme
-paginate: true
-footer: ![width:80px](images/C++ForYourselfIcon.png)
----
-
-# CMake introduction
-
-#### Today:
-- Build process with CMake
-- CMake Variables
-- Targets and their properties
-- Example CMake project
-
-### 📺 Watch the related [YouTube video](https://youtu.be/UH6F6ypdYbw)!
-
----
-# Special symbols used in slides
-- 🎨 - Style recommendation
-- 🎓 - Software design recommendation
-- 😱 - **Not** a good practice! Avoid in real life!
-- ✅ - Good practice!
-- ❌ - Whatever is marked with this is wrong
-- 🚨 - Alert! Important information!
-- 💡 - Hint or a useful exercise
-- 🔼1️⃣7️⃣ - Holds for this version of C++(here, `17`) and **above**
-- 🔽1️⃣1️⃣ - Holds for versions **until** this one C++(here, `11`)
-
-Style (🎨) and software design (🎓) recommendations mostly come from [Google Style Sheet](https://google.github.io/styleguide/cppguide.html) and the [CppCoreGuidelines](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines)
-
----
-# Use [CMake](https://cmake.org) to simplify the build
-![center width:500](images/cmake.png)
-- A very popular **build configuration and generation tool**
-- [Designed to solve](https://cmake.org/cmake/help/book/mastering-cmake/chapter/Why%20CMake.html) most of the `make` shortcomings
-- Very **powerful**, while the build script is **readable**
-- **Does not build** the code, **generates files** for a build system
-- By default generates a `Makefile` with build commands
-- 🚨 We still need to call `make` to build the code!
-- :bulb: Have a look at the `Makefile` generated by CMake
-- The generated build file is complex but does many things
-- Can generate files for **other build systems** too (e.g. `ninja`)
-
----
-# Intuition to what CMake does
-- **Provides** access to your host system
-- **Configures** variables for your build
-- **Generates** the correct commands for the compiler:
-  - Defines **library targets** and **executable targets**
-  - Specifies their **dependency graph**
-  - Specifies correct **build and linking flags** for them
-  - **Stores these commands** in a single generated file
-
-# That's it!
-
-
----
-# CMake is just a scripting language
-- The build process is fully defined in `CMakeLists.txt` files
-- 🚨 CMake reads each `CMakeLists.txt` **sequentially**
-- Has all the features of a **scripting language**, i.e.,
-  functions, control structures, variables, etc.
-- Has some CMake-specific **quirks** 🤷‍♀️
-  - We will learn most by example
-  - Variables and CMake cache are especially confusing
-
----
-# Minimal CMake project
-Consists of a single file in some `project_folder`:
-`CMakeLists.txt`
-<!--
-`CPP_COPY_SNIPPET` simplest_cmake/CMakeLists.txt
-`CPP_RUN_CMD` CWD:simplest_cmake cmake -S . -B build && cmake --build build
--->
-```cmake
-cmake_minimum_required(VERSION 3.16..3.24)
-project(our_project VERSION 0.0.1
-                    DESCRIPTION "Our first project"
-                    LANGUAGES CXX)
-```
-### Set information about our project
-- Which version of CMake do we support (`3.16`---`3.24`)
-- Name of our project: `our_project`
-- Version of the project: `0.0.1`
-- Description of what this project is about
-- Languages used in this project
-  (Options: `C`, `CXX`, `CUDA`, `OBJC`, `OBJCXX`, `Fortran`, etc.)
-
----
-# Build generation with CMake
-✅ Configure and generate **using a command line**:
-```bash
-cd <project_folder>  # One that has CMakeLists.txt in it
-cmake -S . -B build  # Configure build and generate a Makefile
-cmake --build build -j 8  # Run make with 8 threads
-```
-✅ Configure and generate **using TUI** (text user interface)
-```bash
-cd <project_folder>  # One that has CMakeLists.txt in it
-ccmake -S . -B build  # Press "c" to configure and "g" to generate
-cmake --build build -j 8  # Run make with 8 threads
-```
-:scream: If you only have an older CMake version (🔽`3.13`)
-```bash
-cd <project_folder>
-mkdir build
-cd build
-cmake ..      # Configure build and generate a Makefile
-make -j8      # Run make with 8 threads
-```
-- 🚨 Always build using the `build` sub-folder!
-
-
-
----
-# Variables and cache 👇
-- CMake maintains a **cache of variables**
-  (look for `CMakeCache.txt` file after running CMake)
-- Two types of CMake variables: **cached** and **scope-local**
-  ```cmake
-  # Local variable hides any cached variable with the same name
-  set(VAR "value")  # Does not get copied to cache!
-  # Cached variable only set if not found already in cache
-  set(VAR "value" CACHE STRING "Description")
-  # Ignore the value in the cache and always set variable value
-  set(VAR "value" CACHE STRING "" FORCE)
-  set(VAR "value" CACHE INTERNAL "")
-  ```
-- Use `option` (`ON` or `OFF`) for a boolean cached variable
-  ```cmake
-  option(CUSTOM_OPTION "Description" OFF)
-  ```
-- **Use** the value of a variable as `${VAR}`
-- We can add a variable to cache from command line:<br>
-  ```bash
-  cmake -D FOO="foo" -D BAR="bar" -S . -B build
-  ```
----
-# Print a message in CMake
-- Show a **simple message**:<br>
-  ```cmake
-  message(STATUS "My awesome message")
-  ```
-- **Use variables** in messages:<br>
-  ```cmake
-  set(FOO 42)  # A local variable
-  message(STATUS "Value of FOO variable is: ${FOO}")
-  # The PROJECT_NAME variable is defined by project(...) command
-  message(STATUS "Project name is: ${PROJECT_NAME}")
-  ```
-- **Show warnings and errors** with `WARNING`, `FATAL_ERROR`
-  <!--
-  `CPP_SETUP_START`
-  set(FOO "foo")
-  set(CMAKE_BUILD_TYPE "Debug")
-  $PLACEHOLDER
-  `CPP_SETUP_END`
-  `CPP_COPY_SNIPPET` variables_cmake/CMakeLists.txt
-  `CPP_RUN_CMD` CWD:variables_cmake cmake -P CMakeLists.txt
-  -->
-  ```cmake
-  if(NOT CMAKE_BUILD_TYPE)
-    message(WARNING "CMAKE_BUILD_TYPE is not defined!")
-  endif()
-  if(NOT FOO)
-    message(FATAL_ERROR "FOO is not defined!")
-  endif()
-  ```
-- **Omit the message type** to always print the message:
-  ```cmake
-  message("Always print this")
-  ```
-
-
----
-# Create libraries: `add_library`
-- To add a **shared** library do:
-  <!--
-  `CPP_SETUP_START`
-  cmake_minimum_required(VERSION 3.16)
-  project(dummy)
-  $PLACEHOLDER
-  `CPP_SETUP_END`
-  `CPP_COPY_SNIPPET` shared_lib_project/CMakeLists.txt
-  `CPP_RUN_CMD` CWD:shared_lib_project mkdir -p folder && touch source_2.cpp && touch folder/source_1.cpp && cmake -S . -B build
-  -->
-  ```cmake
-  add_library(my_library SHARED
-  ${PROJECT_SOURCE_DIR}/folder/source_1.cpp source_2.cpp)
-  ```
-- To add a **static** library do:
-  <!--
-  `CPP_SETUP_START`
-  cmake_minimum_required(VERSION 3.16)
-  project(dummy)
-  $PLACEHOLDER
-  `CPP_SETUP_END`
-  `CPP_COPY_SNIPPET` static_lib_project/CMakeLists.txt
-  `CPP_RUN_CMD` CWD:static_lib_project mkdir -p folder && touch source_2.cpp && touch folder/source_1.cpp && cmake -S . -B build
-  -->
-  ```cmake
-  add_library(my_library STATIC
-  ${PROJECT_SOURCE_DIR}/folder/source_1.cpp source_2.cpp)
-  ```
-- Use `INTERFACE` for **header-only** libraries
-  <!--
-  `CPP_SETUP_START`
-  cmake_minimum_required(VERSION 3.16)
-  project(dummy)
-  $PLACEHOLDER
-  `CPP_SETUP_END`
-  `CPP_COPY_SNIPPET` header_only_project/CMakeLists.txt
-  `CPP_RUN_CMD` CWD:header_only_project cmake -S . -B build
-  -->
-  ```cmake
-  add_library(my_library INTERFACE) # 🚨 No source files needed!
-  ```
-- :bulb: Note that source file paths are **relative** to current folder
-- :bulb: For absolute paths use `${PROJECT_SOURCE_DIR}`
-- :bulb: If no `STATIC` or `SHARED` are provided the value of the `BUILD_SHARED_LIBS` variable defines the library type
-
----
-# Create executables with `add_executable` command
-- Very similar to the `add_library` command
-- To add an executable do:
-  <!--
-  `CPP_SETUP_START`
-  cmake_minimum_required(VERSION 3.16)
-  project(dummy)
-  $PLACEHOLDER
-  `CPP_SETUP_END`
-  `CPP_COPY_SNIPPET` single_binary_project/CMakeLists.txt
-  `CPP_RUN_CMD` CWD:single_binary_project echo "int main() {return 0;}" > source_with_main.cpp && cmake -S . -B build
-  -->
-  ```cmake
-  add_executable(my_executable source_with_main.cpp)
-  ```
-  <br>🚨 Note that there **must** be a `main` function in the source file
-
----
-# Setting various target properties
-- Modern CMake records properties **per-target**
-- Property **visibilities**: `PRIVATE`, `PUBLIC` or `INTERFACE`
-- Targets created as `INTERFACE` (e.g. header-only libraries)
-  can only have properties with `INTERFACE` visibility
-- 🚨 For a target `my_target` and a command that sets its properties
-  <!--
-  `CPP_SKIP_SNIPPET`
-  -->
-  ```cmake
-  command(my_target <VISIBILITY> properties)
-  ```
-
-| `<VISIBILITY>` | `properties` seen in `my_target` |  `properties` seen in targets depending on `my_target` |
-|-------|:------:|:-------:|
-|`PUBLIC`| ✅ | ✅ |
-|`PRIVATE`| ✅ | :x: |
-|`INTERFACE`| :x: | ✅ |
-
----
-# Dependencies between targets
-- Use `target_link_libraries` to **express dependencies** between library and binary targets:
-  <!--
-  `CPP_SKIP_SNIPPET`
-  -->
-  ```cmake
-  target_link_libraries(my_target PUBLIC|PRIVATE|INTERFACE lib)
-  ```
-- :bulb: `my_target` can be either a library or an executable
-- :rotating_light: **Confusion point:**
-  `target_link_libraries` doesn't just **"link"** libraries!
-  It **also** propagates all visible (`PUBLIC` and `INTERFACE`) properties of `lib` to `my_target`
-
----
-# What properties are there?
-- They map to what we care about when compiling
-- Set compilation flags for using `#include`: `-I`, etc.<br>✅ Use `target_include_directories` command
-- Set linker flags: `-L`, `-l`:<br>✅ Use `target_link_libraries` command
-- Set flags to choose the C++ standard: `-std=c++17`<br>✅ Use `target_compile_features`
-- Other compilation flags: `-Wall`, `-Wextra` etc. <br>✅ Use `target_compile_options`
-- All of these use the same interface and visibility
-
-
----
-# When to use which visibility 🎓
-- Use `PRIVATE` properties with `add_executable` targets
-- Mostly use `PUBLIC` properties on library targets
-- Use `INTERFACE` properties on header-only library targets
-- :rotating_light: **Always** specify visibility with commands:
-  - `target_include_directories`
-  - `target_compile_options`
-  - `target_compile_features`
-  - `target_link_libraries`
-  - (generally any command that starts with `target_`)
-
----
-<!-- _backgroundColor: #0000 -->
-![bg width:100%](images/follow_deer.jpg)
-
----
-# [Typical project](code/our_project/) structure
-```bash
-our_project/
-├── CMakeLists.txt
-├── executables   # Can also be "examples" or alike
-│   ├── CMakeLists.txt
-│   └── print_hello.cpp
-├── our_project/  # Name of this project (again)
-│   ├── CMakeLists.txt
-│   └── tools/    # A library (typically more than one)
-│       ├── CMakeLists.txt
-│       ├── tools.cpp
-│       ├── tools.h
-│       └── tools_test.cpp  # 💡 Can be in a separate folder too
-├── build/  # All generated build files. Don't modify manually!
-├── .git    # Generated by git. Don't modify manually!
-├── .clang-format
-├── .gitignore
-└── readme.md  # Description of your project. Very important!
-```
-
-**Let's fill in all** (well, most) **of these files!**
-
-Stay tuned for the `*_test.cpp` files in a later video :wink:
-
-🎨 It's a good style if namespaces follow the folder structure
-
----
-# Let's start with the C++ code
-- `our_project/our_project/tools/tools.h`<br>
-  <!--
-  `CPP_COPY_SNIPPET` our_project/our_project/tools/tools.h
-  -->
-  ```cpp
-  #pragma once
-  namespace our_project { namespace tools {
-  void PrintHello();
-  }} // Saving place on slides here, use clang-format!
-  ```
-- `our_project/our_project/tools/tools.cpp`<br>
-  <!--
-  `CPP_COPY_SNIPPET` our_project/our_project/tools/tools.cpp
-  -->
-  ```cpp
-  #include <our_project/tools/tools.h>
-  #include <iostream>
-  namespace our_project { namespace tools {
-  void PrintHello() { std::cout << "Hello!" << std::endl; }
-  }} // Saving place on slides here, use clang-format!
-  ```
-- `our_project/executables/print_hello.cpp`<br>
-  <!--
-  `CPP_COPY_SNIPPET` our_project/executables/print_hello.cpp
-  -->
-  ```cpp
-  #include <our_project/tools/tools.h>
-  int main() {
-    our_project::tools::PrintHello();
-    return 0;
-  }
-  ```
-
----
-# The main `CMakeLists.txt` file
-`our_project/CMakeLists.txt`
-<!--
-`CPP_COPY_SNIPPET` our_project/CMakeLists.txt
--->
-```cmake
-cmake_minimum_required(VERSION 3.16..3.24)
-project(our_project VERSION 0.0.1
-                    DESCRIPTION "Our first project"
-                    LANGUAGES CXX)
-if(NOT CMAKE_BUILD_TYPE)
-  set(CMAKE_BUILD_TYPE Release CACHE STRING "" FORCE)
-endif()
-message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}")
-
-add_library(cxx_setup INTERFACE)
-target_compile_options(cxx_setup
-  INTERFACE -Wall -Wpedantic -Wextra)
-target_compile_features(cxx_setup INTERFACE cxx_std_17)
-target_include_directories(cxx_setup
-  INTERFACE ${PROJECT_SOURCE_DIR})
-
-# 🚨 Make sure CMakeLists.txt file exists in the subdirectories!
-add_subdirectory(${PROJECT_NAME})
-add_subdirectory(executables)
-
-# 💡 Some things (e.g. tests or installation) are missing here.
-# 💡 Stay tuned for these in future lectures!
-```
----
-# CMake files in sub-folders
-- `our_project/our_project/CMakeLists.txt`<br>
-  <!--
-  `CPP_COPY_SNIPPET` our_project/our_project/CMakeLists.txt
-  -->
-  ```cmake
-  add_subdirectory(tools)
-  ```
-- `our_project/our_project/tools/CMakeLists.txt`<br>
-  <!--
-  `CPP_COPY_SNIPPET` our_project/our_project/tools/CMakeLists.txt
-  -->
-  ```cmake
-  add_library(tools tools.cpp)
-  target_link_libraries(tools PUBLIC cxx_setup)
-  ```
-- `our_project/executables/CMakeLists.txt`<br>
-  <!--
-  `CPP_COPY_SNIPPET` our_project/executables/CMakeLists.txt
-  `CPP_RUN_CMD` CWD:our_project cmake -S . -B build && cmake --build build
-  -->
-  ```cmake
-  add_executable(print_hello print_hello.cpp)
-  target_link_libraries(print_hello PRIVATE tools cxx_setup)
-  ```
-
----
-# That's it! Let's build it!
-We have to execute the following commands:
-(with approximately the same output)
-```cmd
-cd path/to/our/project/our_project
-λ › cmake -S . -B build
--- The CXX compiler identification is AppleClang 14.0.0.14000029
--- Detecting CXX compiler ABI info
--- Detecting CXX compiler ABI info - done
--- Check for working CXX compiler: .../usr/bin/c++ - skipped
--- Detecting CXX compile features
--- Detecting CXX compile features - done
--- Configuring done
--- Generating done
--- Build files have been written to: .../our_project/build
-λ › cmake --build build
-[ 25%] Building CXX object .../tools.cpp.o
-[ 50%] Linking CXX static library libtools.a
-[ 50%] Built target tools
-[ 75%] Building CXX object .../print_hello.cpp.o
-[100%] Linking CXX executable print_hello
-[100%] Built target print_hello
-```
-
----
-# How to clean the build
-- To "clean" means to remove all generated build artifacts
-- That includes all libraries and binaries as well as all the temporary files generated by the build system
-- It's very easy to do with CMake
-# Just remove the `build` folder!
-
----
-
-![bg](https://fakeimg.pl/1280x1024/226699/fff/?text=Good%20luck!&font=bebas)
diff --git a/lectures/cmake_install.md b/lectures/cmake_install.md
deleted file mode 100644
index 917afd4..0000000
--- a/lectures/cmake_install.md
+++ /dev/null
@@ -1,733 +0,0 @@
-**Reusing projects with CMake**
-
-<p align="center">
-  <a href="https://youtu.be/OMx3cZj_hoo"><img src="https://img.youtube.com/vi/OMx3cZj_hoo/maxresdefault.jpg" alt="Video" align="right" width=50% style="margin: 0.5rem"></a>
-</p>
-
-- [Disclaimer](#disclaimer)
-- [What does `find_package` do?](#what-does-find_package-do)
-  - [Search modes](#search-modes)
-    - [Module mode](#module-mode)
-    - [Config mode](#config-mode)
-  - [How do the config files look like?](#how-do-the-config-files-look-like)
-  - [What are the export files?](#what-are-the-export-files)
-  - [Summary of reusing targets](#summary-of-reusing-targets)
-- [How to make `core_project` available to `dependent_project`](#how-to-make-core_project-available-to-dependent_project)
-  - [Project skeleton for `core_project`](#project-skeleton-for-core_project)
-  - [Installing a package](#installing-a-package)
-    - [1. Copying headers](#1-copying-headers)
-    - [2. Copying binaries](#2-copying-binaries)
-    - [3. Creating export files](#3-creating-export-files)
-    - [4. Creating config files](#4-creating-config-files)
-- [How to use the installed package](#how-to-use-the-installed-package)
-- [Summary](#summary)
-
-We talked about [CMake](cmake.md) before, why we use it, what it is and how to configure it to build various libraries and binaries. However, until now we targeted the development of a single project. If we want to develop multiple interdependent projects or make our CMake project reusable by others what we know so far is not enough.
-
-One way of doing this within the CMake world is to `install` a project and find it using the `find_package` command from another CMake project.
-
-As an example, some `dependent_project` might have an executable `print_hello`, implemented in a `print_hello.cpp` file that uses a library from another `core_project` by including its header and calling a function `core_project::PrintHello()` from it:
-
-`dependent_project/print_hello.cpp`
-
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` dependent_project/print_hello.cpp
--->
-```cpp
-#include "core_project/some_library.hpp"
-
-int main() {
-  core_project::PrintHello();
-  return 0;
-}
-```
-
-To make this work we can use an already-installed `core_project` by calling `find_package(core_project REQUIRED)` from the `CMakeLists.txt` file of the `dependent_project`:
-
-`dependent_project/CMakeLists.txt`
-
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` dependent_project/CMakeLists.txt
--->
-```cmake
-cmake_minimum_required(VERSION 3.16..3.24)
-project(dependent_project
-    VERSION 0.0.1
-    DESCRIPTION "Sample project that uses the core project"
-    LANGUAGES CXX)
-
-# Set CMAKE_BUILD_TYPE if user did not provide it.
-if(NOT CMAKE_BUILD_TYPE)
-  set(CMAKE_BUILD_TYPE Release CACHE INTERNAL "Build type")
-endif()
-message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}")
-
-find_package(core_project REQUIRED)
-
-add_executable(print_hello print_hello.cpp)
-target_link_libraries(print_hello PRIVATE core_project::some_library)
-```
-
-After the `find_package` is called, the `print_hello` executable can use the functionality from `some_library` which is part of the `core_project`.
-
-<!-- org: use travolta animation -->
-Note how we do not explicitly create the `some_library` before linking it to our new executable `print_hello` as it gets exported from the previously-installed `core_project` when we call the `find_package` command. The `dependent_project` builds when we call the commands very similar to those [we already know](cmake.md#build-generation-with-cmake), with a tiny addition of providing CMake with a `CMAKE_PREFIX_PATH` variable that points to the `/tmp/install` folder where, in this example, we chose to install the `core_project`:
-
-```cmd
-# Note that -B flag requires at least CMake version 3.13
-cmake -DCMAKE_PREFIX_PATH="/tmp/install"  -S . -B build
-cmake --build build -j 12
-```
-
-And as a final proof, we can of course run our executable `print_hello` to get a "Hello World!" message printed to the terminal:
-
-```cmd
-./build/print_hello
-Hello World!
-```
-
-So let's dive in and see how all of this works!
-
-<!-- Intro -->
-
-## Disclaimer
-
-This is quite a nuanced topic and I'd like to start with a disclaimer that there are many ways to structure CMake projects and even more ways to make these projects talk to each other. My aim for today is to show the *concept* here and not to cover *all* the possible details.
-
-As a result, I show just one way that I grew to like. I'm sure there are other ways equally good if not better to achieve very similar behavior and I am always super interested to know what works for you!
-
-<!-- So please comment below this video with your questions and suggestions and let's have a chat! -->
-
-That being said, I believe that the concepts we're covering here are more of less universal and can be applied to any concrete CMake project design with minor adaptations.
-
-## What does `find_package` do?
-
-With that out of the way, we can start our deep dive by understanding what the `find_package` does under the hood. And, just as in all the other topics we've already covered, there is of course **no black magic** here.
-<!-- org: Show the no black magic animation from before -->
-
-<!-- org: Show the code again -->
-
-It is logical that in order to use the `core_project::some_library` target `find_package` must somehow provide us with it. What this really means is that the `find_package` command must somehow `include` all the CMake code that creates the needed `core_project::some_library` target as well as sets the required compiler and linker flags for it.
-
-For now let us assume that `core_project` has already been installed into `/tmp/install` folder and try to understand all of the steps that `find_package` takes to allow us to use the `core_project`'s targets. We'll get to *how* it was installed there in the second half of this tutorial.
-
-### Search modes
-
-<!-- org: show wiki excerpt -->
-If we read CMake docs, there are two modes in which [`find_package`](https://cmake.org/cmake/help/v3.16/command/find_package.html) operates: the **module mode** and **config mode**.
-
-#### Module mode
-
-By default when we call `find_package(core_project)` in our `CMakeLists.txt`, CMake first tries to use the **module mode** and looks for a file `Findcore_project.cmake` in the path stored under the `CMAKE_MODULE_PATH` CMake variable as well as among the default modules provided with the CMake installation. Once found, CMake `include`s that file, which, in CMake world, means that it executes all the code from that file.
-
-<!-- org: show code again with `CONFIG` or `NO_MODULE` -->
-If CMake is unable to find the required `Find*.cmake` file, or if we explicitly provide `CONFIG` or `NO_MODULE` as part of the `find_package` signature, it switches to the **config mode** instead.
-
-<!--
-`CPP_SKIP_SNIPPET`
--->
-```cmake
-find_package(core_project CONFIG REQUIRED)
-```
-
-<!-- org: show drake meme -->
-
-> 🚨 We must note that while **module mode** is the default one, in modern CMake we want to use **config mode** most of the time.
-
-#### Config mode
-
-So what makes **config mode** better? On the surface **config mode** works in a very similar manner to the **module mode**.
-
-For a call `find_package(core_project CONFIG)` or `find_package(core_project NO_MODULE)` CMake looks for a file `core_projectConfig.cmake` or for `core_project-config.cmake` using quite a comprehensive [search procedure](https://cmake.org/cmake/help/v3.16/command/find_package.html#search-procedure) starting with the path specified in the `CMAKE_PREFIX_PATH` CMake variable. Note that the names of these files are case sensitive and in the second option `core_project-config.cmake` the name of the project is translated into lowercase, which, in our case does not make any difference but does play a role should your project name have capital letters.
-
-However, the similarities end on this surface level. The [full command for config mode](https://cmake.org/cmake/help/v3.16/command/find_package.html#full-signature-and-config-mode) has many more settings than the module mode has, and, even more importantly, it is possible to generate the needed config files almost completely automatically. This was not the case in the module mode, where most of the `Find*.cmake` files historically had to be written by hand. As you might imagine, this makes the config mode setup much more maintainable and versatile. To the degree of my knowledge that's the main reason why we prefer it to the module mode.
-
-So in today's tutorial, I'm going to focus exclusively on the **config mode** as a more modern way, but please let me know if you'd like to hear about the module mode too as it might still be useful to understand when working with legacy code.
-
-### How do the config files look like?
-
-Now that we know which files `find_package` looks for and where it looks for them, we can take a peek inside these files.
-
-As we've mentioned before, because we call `find_package(core_project)`, we expect to find a file `core_projectConfig.cmake` in a subfolder of the folder stored in the `CMAKE_PREFIX_PATH` CMake variable. In our case, as our `core_project` was installed into `/tmp/install` folder, we can inspect that folder to find the file that matches our description in one of its subfolders: `/tmp/install/share/cmake/core_project/core_projectConfig.cmake`. This file is not very large, and its most important part is that it includes another `some_library_export.cmake` CMake file:
-
-<!--
-`CPP_SKIP_SNIPPET`
--->
-```cmake
-include ( "${CMAKE_CURRENT_LIST_DIR}/some_library_export.cmake" )
-```
-
-### What are the export files?
-
-Looking around the same folder, we can easily find this `some_library_export.cmake` file, which has a lot more auto-generated code in it. Today, we don't care about most of this code, and focus on the relevant parts only, starting with the creation of an `IMPORTED` library:
-
-<!--
-`CPP_SKIP_SNIPPET`
--->
-```cmake
-# Create imported target core_project::some_library
-add_library(core_project::some_library STATIC IMPORTED)
-```
-
-The keyword `IMPORTED` simply indicates that the actual binary file for this library will be provided at a later point.
-
-A bit lower within the same `some_library_export.cmake` file, there is another relevant part of auto-generated code:
-
-<!--
-`CPP_SKIP_SNIPPET`
--->
-```cmake
-# Load information for each installed configuration.
-get_filename_component(_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
-file(GLOB CONFIG_FILES "${_DIR}/some_library_export-*.cmake")
-foreach(f ${CONFIG_FILES})
-  include(${f})
-endforeach()
-```
-
-Here, CMake is instructed to look for additional CMake files to include and if we look around the folder that contains the `some_library_export.cmake` file we will find more files that match this pattern, for example `some_library_export-release.cmake`. This name depends on the configuration we used during build, having a `release` suffix in our case as we use the `Release` configuration by default.
-
-Looking into this new file, we can find the code that sets all the relevant properties of our `IMPORTED` library target, including its language, its binary file location, and the location of its headers:
-
-<!--
-`CPP_SKIP_SNIPPET`
--->
-```cmake
-# Import target "core_project::some_library" for configuration "Release"
-set_property(TARGET core_project::some_library APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
-set_target_properties(core_project::some_library PROPERTIES
-  IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "CXX"
-  IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/lib/libsome_library.a"
-  INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include/"
-)
-```
-
-> ❓ Actually, I have a couple of questions to you here: ❓
->
-> - Which [library kind](headers_and_libraries.md) is `core_project::some_library`?
-> - How do you think this code would change if the library would be a header-only one?
-
-<!-- Please write your answers below this video! And, while you're there, please do subscribe to my channel as only a third of you watching this are subscribed! -->
-
-The rest of the code in these files is not as relevant to us as it mostly performs some checks so that CMake is sure that all the necessary files are actually present on the system. But by all means, feel free to read into it when you have the time.
-
-So, you see, we've found the commands that create the targets as well as those that set their relevant properties.
-
-As a final piece of the puzzle, if we examine the `lib` and `include` folders in our `CMAKE_PREFIX_PATH`, we'll eventually find the needed binary and header files `/tmp/install/lib/libsome_library.a` and `/tmp/install/include/core_project/some_library.hpp`.
-
-### Summary of reusing targets
-
-We have now traced the full path that CMake takes in order for us to be able to use targets from another project. To recap, we start with a call to `find_package`, which looks for a `*Config.cmake` file, that includes the necessary `export` files that point towards the headers and relevant binary files:
-
-```mermaid
-graph TD
-  find[<code>find_package#40;core_project#41;</code>] --> configs[Config file:<br><code>.../core_project/core_projectConfig.cmake</code>] --> export[Export files:<br><code>.../core_project/some_library_export.cmake</code><br><code>.../core_project/some_library_export#8722;release.cmake</code>] --> headers[Binary and header files:<br><code>.../lib/libsome_library.a</code><br><code>.../include/core_project/some_library.hpp</code>]
-
-```
-
-## How to make `core_project` available to `dependent_project`
-
-So far so good. We now understand how a library within a `dependent_project` is able to use the library from the `core_project` after a `find_package` call. Now is a great time to figure out how these export files are actually created as well as how the header files and all the binary files land into the install folder in the first place.
-
-We'll actually follow the diagram that we've just introduced, but in reverse, starting at the bottom and making it all the way up to its top.
-
-### Project skeleton for `core_project`
-
-Before we learn how to to install the project we will have to define it so that this example does not get too abstract. We've already done very similar things before, so feel free to refer to the [CMake](cmake.md) tutorial if we rush too fast over some details here.
-
-Let's start with the C++ code. For the sake of our example, our `some_library` has a single function `PrintHello` that is declared in a header file `some_library.hpp`:
-
-`core_project/core_project/some_library.hpp`:
-
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` core_project/core_project/some_library.hpp
--->
-```cpp
-#pragma once
-
-namespace core_project {
-
-void PrintHello();
-
-} // namespace core_project
-```
-
-With the implementation of this function, that just prints "Hello, world!" to the terminal, living in the corresponding source file `some_library.cpp`:
-
-`core_project/core_project/some_library.cpp`
-
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` core_project/core_project/some_library.cpp
--->
-```cpp
-#include "core_project/some_library.hpp"
-
-#include <iostream>
-
-namespace core_project {
-
-void PrintHello() {
-  std::cout << "Hello, world!" << std::endl;
-}
-
-} // namespace core_project
-```
-
-And just to test that our library actually works, let's also add an example executable to `print_hello.cpp` file that includes `some_library.hpp` and calls it:
-
-`core_project/examples/print_hello.cpp`:
-
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` core_project/examples/print_hello.cpp
--->
-```cpp
-#include "core_project/some_library.hpp"
-
-int main() {
-  core_project::PrintHello();
-  return 0;
-}
-```
-
-The CMake part of the `core_project` is pretty standard too - it declares a new project, chooses build type to be `Release`, if the user did not provide one, and delegates the target creation to other `CMakeLists.txt` files within the `core_project` and `examples` folders:
-
-`core_project/CMakeLists.txt`:
-
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` core_project/CMakeLists.txt
--->
-```cmake
-cmake_minimum_required(VERSION 3.16..3.24)
-project(core_project
-    VERSION 0.0.1
-    DESCRIPTION "Project to illustrate installation"
-    LANGUAGES CXX)
-
-# Set CMAKE_BUILD_TYPE if user did not provide it.
-if(NOT CMAKE_BUILD_TYPE)
-  set(CMAKE_BUILD_TYPE Release CACHE STRING "" FORCE)
-endif()
-message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}")
-
-add_subdirectory(core_project)
-add_subdirectory(examples)
-```
-
-These other `CMakeLists.txt` files are, again, nothing special and we've seen their kind before.
-
-In the `core_project/CMakeLists.txt` we use a `LIBRARY_NAME` CMake variable for convenience, create our library target, set its C++ standard to C++17, indicate to it and its descendants where to look for the includes, and, finally, create an alias for this library that is prefixed by the `${PROJECT_NAME}`. Strictly speaking, this alias is not required but it *is* a good practice to use the library in the same way from within the project as well as in other projects. We will see why a bit later.
-
-`core_project/core_project/CMakeLists.txt`:
-
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` core_project/core_project/CMakeLists.txt
--->
-```cmake
-set(LIBRARY_NAME some_library)
-add_library(${LIBRARY_NAME} ${LIBRARY_NAME}.cpp)
-target_compile_features(${LIBRARY_NAME} PUBLIC cxx_std_17)
-target_include_directories(${LIBRARY_NAME} PUBLIC
-  $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}>
-  $<INSTALL_INTERFACE:include/>
-)
-add_library(${PROJECT_NAME}::${LIBRARY_NAME} ALIAS ${LIBRARY_NAME})
-```
-
-As for the `examples/CMakeLists.txt`, it creates an executable `print_hello` and links it to the `core_project::some_library` target:
-
-`core_project/examples/CMakeLists.txt`:
-
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` core_project/examples/CMakeLists.txt
-`CPP_RUN_CMD` CWD:core_project cmake -S . -B build && cmake --build build -j4 && ./build/examples/print_hello
--->
-```cmake
-add_executable(print_hello print_hello.cpp)
-target_link_libraries(print_hello PRIVATE core_project::some_library)
-```
-
-For now we have done nothing new, we've already done very similar things before in the [previous lectures on CMake](cmake.md). So we already know that we can easily configure and build our project with CMake as follows:
-
-```bash
-# Note that -B flag was introduced in CMake version 3.13
-cmake -S . -B build
-cmake --build build -j 12
-```
-
-Once it builds, we can run the example binaries without any issues:
-
-```cmd
-./build/examples/print_hello
-Hello world!
-```
-
-But we are still unable to use this library from our `dependent_project` aren't we? All of the special `export` and `Config` files are missing!
-
-> :bulb: We say that we **install** a CMake package when we make CMake create the config and export files as well as copy all the headers and binaries into the needed folders where they can be found by other projects.
-
-And for now our `core_project` does not know how to **install** itself!
-
-### Installing a package
-
-This installation process usually involves a couple of steps. It must:
-
-1. Copy all the needed headers into some `include` folder
-2. Copy all of the binary libraries into a `lib` folder and all executables into a `bin` folder (typically)
-3. Create the appropriate `*_export.cmake` files that create and configure the imported libraries
-4. Create the `*Config.cmake` file that includes all of the needed export files
-
-And there is a special CMake command that we can call to kick-off all of these steps: `cmake --install`, which also gets an optional `--prefix` flag that sets the folder into which this package will be installed. We call this command after configuring and building the project:
-
-```bash
-# Note that --install flag was introduced in CMake version 3.15
-cmake  -S . -B build                         # Configure.
-cmake --build build -j 12                    # Build.
-cmake --install build --prefix /tmp/install  # Install.
-```
-
-Here, we aim to install our package into some temporary install folder, but a more standard location, like `/usr/local` can be used if the `--prefix` flag is omitted. Note that in such a case we have to call this command with `sudo` rights.
-
-:bulb: However, if we call the install command for our package now, nothing happens!
-
-To actually perform all of the actions we've just talked about we need to write some more CMake code. But fear not, there is a number of different built-in CMake `install` commands that help us in most of these steps.
-
-Let's look at all of these steps in detail.
-
-#### 1. Copying headers
-
-Our first step is to copy the headers over. To this end, we add the following code to the end of `core_project/core_project/CMakeLists.txt` file:
-
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` core_project/core_project/install_headers.cmake
-`CPP_RUN_CMD` CWD:core_project cat core_project/install_headers.cmake >> core_project/CMakeLists.txt
--->
-```cmake
-install(
-    DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
-    DESTINATION include  # Must appear before FILES_MATCHING!
-    FILES_MATCHING PATTERN "*.hpp"
-)
-```
-
-This `install` command finds all the `*.hpp` files in the folder specified under `DIRECTORY`, in our case `core_project/core_project` and copies that directory and all the matching files into the `include` folder, as the `DESTINATION` option specifies. If you also need to copy other header files, like `*.h` for example, you can always adapt the `FILES_MATCHING PATTERN`.
-
-If we try installing our package after adding this CMake code to our project we'll be able to find the only header of our `core_project` installed into the expected location: `/tmp/install/include/core_project/some_library.hpp`:
-
-```bash
-cmake  -S . -B build                         # Configure.
-cmake --build build -j 12                    # Build.
-cmake --install build --prefix /tmp/install  # Install.
-```
-
-```cmd
-/tmp/install
-└── include
-    └── core_project
-        └── some_library.hpp
-```
-
-We only have one header for now but I hope it is easy to imagine that we can do this for any number of headers and in any number of folders. I prefer to add these install statements on a per-folder basis. This way we do not have to add too much code while keeping the folder structure intact. That being said, I've also seen people adding a single similar `install` statement to the top-most `CMakeLists.txt` file of the project instead with minor modifications.
-
-#### 2. Copying binaries
-
-Now that the headers are all installed, we need to do the same for all the binary files. We do this by adding another `install` command to `core_project/core_project/CMakeLists.txt`:
-
-<!--
-`CPP_SKIP_SNIPPET`
--->
-```cmake
-install(TARGETS ${LIBRARY_NAME})
-```
-
-As well as one more to `core_project/examples/CMakeLists.txt` for installing our example binaries:
-
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` core_project/examples/install_executables.cmake
-`CPP_RUN_CMD` CWD:core_project cat examples/install_executables.cmake >> examples/CMakeLists.txt
--->
-```cmake
-install(TARGETS print_hello)
-```
-
-This will automatically install all executables to a `bin` folder and all of the binary libraries to a `lib` folder.
-
-After running the install command again, we'll see that we now also have all of the binaries installed:
-
-```cmd
-λ › tree /tmp/install
-/tmp/install
-├── bin
-│   └── print_hello
-├── include
-│   └── core_project
-│       └── some_library.hpp
-└── lib
-    └── libsome_library.a
-```
-
-With this, all of our binary and header files are where we want them to be. But we still lack the `*_export.cmake` files to tell CMake where to find them!
-
-#### 3. Creating export files
-
-One classical way to do create these export files is to change the `install(TARGETS ...)` commands slightly for each of our library targets (one in our case) by adding an `EXPORT` entry to them:
-
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` core_project/core_project/install_libs.cmake
-`CPP_RUN_CMD` CWD:core_project cat core_project/install_libs.cmake >> core_project/CMakeLists.txt
--->
-```cmake
-install(
-    TARGETS ${LIBRARY_NAME}
-    EXPORT ${LIBRARY_NAME}_export  # <-- this one
-)
-```
-
-Now this command not only installs the binary library file into the `lib` folder but it also associates it with an `*_export.cmake` file.
-
-But this command alone is not enough for us as it does not actually copy the created `_export` file to the install folder, we can see it by running install again and not finding the `_export` file in the install folder. However, we *do* find it in the build folder!
-
-<!-- TODO: add build and install trees -->
-
-So what remains is to copy this already generated file to the install folder, which we can do by using yet another `install` command that copies our export file to the `/tmp/install/share/cmake/core_project` folder:
-
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` core_project/core_project/install_exports.cmake
-`CPP_RUN_CMD` CWD:core_project cat core_project/install_exports.cmake >> core_project/CMakeLists.txt
--->
-```cmake
-install(EXPORT ${LIBRARY_NAME}_export
-    FILE ${LIBRARY_NAME}_export.cmake
-    NAMESPACE ${PROJECT_NAME}::
-    DESTINATION share/cmake/${PROJECT_NAME}
-)
-```
-
-Running our install procedure again with all of this new code, we'll be able to see this file where we expect to find it within the install folder tree:
-
-```cmd
-λ › tree /tmp/install
-/tmp/install
-├── bin
-│   └── print_hello
-├── include
-│   └── core_project
-│       └── some_library.hpp
-├── share
-│   └── cmake
-│       └── core_project
-│           ├── some_library_export-release.cmake
-│           └── some_library_export.cmake
-└── lib
-    └── libsome_library.a
-```
-
-Note also the `NAMESPACE` option that adds the project prefix to all targets that we export *within the export files*. Super handy to disambiguate our targets from any other ones. Also, this matches our own `ALIAS` that we created before, keeping everything nice and consistent.
-
-#### 4. Creating config files
-
-Finally, with the export files in-place we only need to create the missing config files so that `find_package` can find all the export files we've just created. This process is a bit convoluted and involves a couple of steps.
-
-To create the `core_projectConfig.cmake` file we typically call `configure_package_config_file` from the `CMakePackageConfigHelpers` that we include into our main `CMakeLists.txt` file:
-
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` core_project/create_config.cmake
-`CPP_RUN_CMD` CWD:core_project cat create_config.cmake >> CMakeLists.txt
--->
-```cmake
-include(CMakePackageConfigHelpers)
-
-# Create a config file that CMake looks for when we call FindPackage(core_project)
-configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/Config.cmake.in
- "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
- INSTALL_DESTINATION "share/cmake/${PROJECT_NAME}"
-)
-```
-
-For this to work we need to create a "template file" that, in its simplest form includes all the export files we created before:
-
-`${CMAKE_CURRENT_SOURCE_DIR}/cmake/Config.cmake.in`
-
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` core_project/cmake/Config.cmake.in
--->
-```cmake
-@PACKAGE_INIT@
-
-include("${CMAKE_CURRENT_LIST_DIR}/some_library_export.cmake")
-
-check_required_components(core_project)
-```
-
-We can specify all of the export files by hand, like we just did, but we can also use a glob expression that matches *any* file that ends in `*_export.cmake`:
-
-`${CMAKE_CURRENT_SOURCE_DIR}/cmake/Config.cmake.in`
-
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` core_project/cmake/ConfigGlob.cmake.in
--->
-```cmake
-@PACKAGE_INIT@
-
-# Automatically include all exported library files
-file(GLOB EXPORT_FILES "${CMAKE_CURRENT_LIST_DIR}/*_export.cmake")
-foreach(EXPORT_FILE ${EXPORT_FILES})
-    include(${EXPORT_FILE})
-endforeach()
-
-check_required_components(core_project)
-```
-
-Passing this `cmake.in` file into `configure_package_config_file` we create a `${PROJECT_NAME}Config.cmake` in the current **build** folder. Note that this file is still not "installed", i.e., it is not present in the install folder just yet!
-
-Before we install it though, we'll also need to generate another very similar file `${PROJECT_NAME}ConfigVersion.cmake` by calling the `write_basic_package_version_file` command:
-
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` core_project/create_config_version.cmake
-`CPP_RUN_CMD` CWD:core_project cat create_config_version.cmake >> CMakeLists.txt
--->
-```cmake
-# Create a versioned config file that CMake uses to compare version of the package.
-write_basic_package_version_file(
- ${PROJECT_NAME}ConfigVersion.cmake
- VERSION ${PACKAGE_VERSION}
- COMPATIBILITY AnyNewerVersion
-)
-```
-
-This file is needed if we want to specify a version of our package. In our example we choose a version to match our project version as well as what the compatibility of this version is. This plays a role when we specify a version within the `find_package(core_project 1.0)` command. We will not go into more details here but I'm sure after this tutorial everyone should be able to look it up in the docs.
-
-Finally, our last step is to copy the just-generated config files into the install folder, which we can do with yet another `install(FILES ...)` command, providing all of our config files in the build folder into it and, as before, specifying their install destination:
-
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` core_project/install_configs.cmake
-`CPP_RUN_CMD` CWD:core_project cat install_configs.cmake >> CMakeLists.txt && cmake -S . -B build && cmake --build build -j 4 && cmake --install build --prefix /tmp/install && /tmp/install/bin/print_hello && cd ../dependent_project && cmake -DCMAKE_PREFIX_PATH="/tmp/install" -S . -B build && cmake --build build -j 4 && ./build/print_hello
--->
-```cmake
-# Copy these files into the install directory.
-install(
- FILES
- ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
- ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
- DESTINATION
- share/cmake/${PROJECT_NAME}
-)
-```
-
-And now we're done with installing! If we run `cmake --install` command again and look at how the `install` folder tree looks like, it will contain all of our headers, all our binary files as well as the export and config files needed to configure all of the targets, should someone look for them.
-
-## How to use the installed package
-
-One final thing to do now is to add a `find_package` call to our `dependent_project` of course. We've already seen this at the start of this tutorial:
-
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` dependent_project/CMakeLists.txt
-`CPP_RUN_CMD` CWD:dependent_project rm -r build && cmake -DCMAKE_PREFIX_PATH="/tmp/install" -S . -B build && cmake --build build -j 4 && ./build/print_hello
--->
-```cmake
-cmake_minimum_required(VERSION 3.16..3.24)
-project(dependent_project
-    VERSION 0.0.1
-    DESCRIPTION "Sample project that uses the core project"
-    LANGUAGES CXX)
-
-# Set CMAKE_BUILD_TYPE if user did not provide it.
-if(NOT CMAKE_BUILD_TYPE)
-  set(CMAKE_BUILD_TYPE Release CACHE INTERNAL "Build type")
-endif()
-message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}")
-
-find_package(core_project REQUIRED CONFIG)
-
-add_executable(print_hello print_hello.cpp)
-target_link_libraries(print_hello PRIVATE core_project::some_library)
-```
-
-And, just as before, we can configure and build this project. Because we've installed our `core_project` into a custom folder, `/tmp/install` in our case, we need to tell CMake where to look for packages by providing it with a `CMAKE_PREFIX_PATH`:
-
-```bash
-cd dependent_project
-cmake -DCMAKE_PREFIX_PATH="/tmp/install"  -S . -B build
-cmake --build build -j 12
-```
-
-Note that we don't need to provide an explicit `CMAKE_PREFIX_PATH` value if we installed our `core_project` in a standard system-wide location, like `/usr/local`.
-
-Running these commands builds our `dependent_project` without issues and we can run the binary that we've just built too:
-
-```cmd
-./build/print_hello
-Hello World!
-```
-
-## Summary
-
-Now we've fully closed the loop on this topic. We started by understanding how `find_package` works under the hood - what files it looks for in which folders. We then went bottom up and learned how to configure a project to install all of these files ending with a fully working minimal two-project example that we can return to whenever we need to setup a more complex installation procedure.
-
-As always, I believe that learning new things comes from doing, so I urge you to play around with these examples, which you can find on my GitHub as [complete projects](code/cmake_install/).
-
-There is a number of questions I urge you to think about. How would you install more libraries than one? What changes in the generated export files if we make the library header-only? How to install `dependent_project` too? If you are able to answer all of these questions, then, for my money, you understand this topic quite well!
-
-The CMake installation process is not a thing cast in stone. It changes over the years and, just as we move to a more target-based build, we are probably also going to be moving away from what is presented here and towards a more target-based install. But as it stands now, I believe that what we've covered today is still the most popular way to install packages and can be found in most CMake projects in the wild with slight differences here and there, which, after this tutorial, should be easier to spot and understand.
-
-<!-- Thanks a lot for your time and for watching to the end. Watching these videos fully seems to be very important for the YouTube algorithm to recommend these videos to more people, so if you want to help out, please just let the video play fully through, it helps me a lot!
-
-I intentionally keep all of this content, including all the code on GitHub, free and available to everybody as I believe that education should be accessible. If you agree with this and would like to support this work, there are ways in the description below this video.
-
-And if you need a refresher on what CMake does, you can watch this video over here, while if you'd like to see how one can configure GoogleTest with CMake, head over here instead.
-
-Thanks again for watching and see you next time! Bye!
--->
diff --git a/lectures/code/all_or_nothing.cpp b/lectures/code/all_or_nothing.cpp
deleted file mode 100644
index cb982b3..0000000
--- a/lectures/code/all_or_nothing.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-#include <cstddef>
-#include <iostream>
-
-std::byte *AllocateMemory(std::size_t length) { return new std::byte[length]; }
-void FreeMemory(std::byte *ptr) { delete[] ptr; }
-
-// 😱 Note that this class does not follow best style.
-class HugeObject {
- public:
-  HugeObject() = default;
-
-  explicit HugeObject(std::size_t data_length)
-      : length_{data_length}, ptr_{AllocateMemory(length_)} {}
-
-  HugeObject(const HugeObject &object)
-      : length_{object.length_}, ptr_{AllocateMemory(length_)} {
-    std::copy(object.ptr_, object.ptr_ + length_, ptr_);
-    std::cout << "copy" << std::endl;
-  }
-
-  // HugeObject(HugeObject &&object) : length_{object.length_}, ptr_{object.ptr_} {
-  //   object.ptr_ = nullptr;
-  // }
-
-  HugeObject &operator=(const HugeObject &object) {
-    if (this == &object) { return *this; }  // Do not self-assign.
-    FreeMemory(ptr_);  // In case we already owned some memory from before.
-    length_ = object.length_;
-    ptr_ = AllocateMemory(length_);
-    std::copy(object.ptr_, object.ptr_ + length_, ptr_);
-    return *this;
-  }
-
-  // HugeObject &operator=(HugeObject &&object) {
-  //   if (this == &object) { return *this; }  // Do not self-assign.
-  //   FreeMemory(ptr_);  // In case we already owned some memory from before.
-  //   length_ = object.length_;
-  //   ptr_ = object.ptr_;
-  //   object.ptr_ = nullptr;
-  //   return *this;
-  // }
-
-  std::byte const *ptr() const { return ptr_; }
-
-  // ~HugeObject() { FreeMemory(ptr_); }
-
- private:
-  std::size_t length_{};
-  std::byte *ptr_{};
-};
-
-// int main() {
-//   const HugeObject object{42};
-//   std::cout << "Data address: " << object.ptr() << std::endl;
-//   return 0;
-// }
-
-// int main() {
-//   const HugeObject object{42};
-//   std::cout << "object data address: " << object.ptr() << std::endl;
-//   const HugeObject other_object{object};
-//   std::cout << "other_object data address: " << other_object.ptr() << std::endl;
-//   return 0;
-// }
-
-// int main() {
-//   const HugeObject object{42};
-//   std::cout << "object data address: " << object.ptr() << std::endl;
-//   HugeObject other_object{23};
-//   other_object = object;
-//   std::cout << "other_object data address: " << other_object.ptr() << std::endl;
-//   return 0;
-// }
-
-int main() {
-  HugeObject object{42};
-  std::cout << "object data address: " << object.ptr() << std::endl;
-  const HugeObject other_object{std::move(object)};
-  std::cout << "object data address: " << object.ptr() << std::endl;
-  std::cout << "other_object data address: " << other_object.ptr() << std::endl;
-  return 0;
-}
diff --git a/lectures/code/class_headers/cmake_binary_lib/CMakeLists.txt b/lectures/code/class_headers/cmake_binary_lib/CMakeLists.txt
deleted file mode 100644
index 6e65dc7..0000000
--- a/lectures/code/class_headers/cmake_binary_lib/CMakeLists.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-cmake_minimum_required(VERSION 3.16..3.24)
-project(chatbot VERSION 0.0.1
-                    DESCRIPTION "Our first project"
-                    LANGUAGES CXX)
-if(NOT CMAKE_BUILD_TYPE)
-  set(CMAKE_BUILD_TYPE Release CACHE STRING "" FORCE)
-endif()
-message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}")
-
-add_library(cxx_setup INTERFACE)
-target_compile_options(cxx_setup INTERFACE -Wall -Wpedantic -Wextra)
-target_compile_features(cxx_setup INTERFACE cxx_std_17)
-target_include_directories(cxx_setup INTERFACE ${PROJECT_SOURCE_DIR})
-
-add_subdirectory(${PROJECT_NAME})
diff --git a/lectures/code/class_headers/cmake_binary_lib/chatbot/CMakeLists.txt b/lectures/code/class_headers/cmake_binary_lib/chatbot/CMakeLists.txt
deleted file mode 100644
index da524a8..0000000
--- a/lectures/code/class_headers/cmake_binary_lib/chatbot/CMakeLists.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-# Indicate that we have a library
-add_library(chatbot chatbot.cpp)
-target_link_libraries(chatbot PUBLIC cxx_setup)
-
-# A binary that uses the library
-add_executable(chatbot_main main.cpp)
-target_link_libraries(chatbot_main PRIVATE chatbot cxx_setup)
diff --git a/lectures/code/class_headers/cmake_binary_lib/chatbot/chatbot.cpp b/lectures/code/class_headers/cmake_binary_lib/chatbot/chatbot.cpp
deleted file mode 100644
index d60b611..0000000
--- a/lectures/code/class_headers/cmake_binary_lib/chatbot/chatbot.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
-#include <chatbot/chatbot.hpp>
-
-bool Chatbot::Data::IsValid() const {
-  return questions.size() == correct_answers.size();
-}
-
-void Chatbot::Train(const Data &data) {
-  if (!data.IsValid()) { return; }
-  IngestData(data);
-}
-
-Chatbot::Answer Chatbot::GetAnswer(const std::string &question) const {
-  if (smartness_ < 1) { return Answer{0.1, "I don't know"}; }
-  if (smartness_ < 5) { return Answer{0.8, "Yes."}; }
-  if (question.length() > 10) {
-    return Answer{1.0, "You will regret this question..."};
-  }
-  return Answer{1.0, "Can't you ask anything more important?"};
-}
-
-void Chatbot::IngestData(const Data &data) {
-  smartness_ += data.correct_answers.size();
-}
diff --git a/lectures/code/class_headers/cmake_binary_lib/chatbot/chatbot.hpp b/lectures/code/class_headers/cmake_binary_lib/chatbot/chatbot.hpp
deleted file mode 100644
index cae3455..0000000
--- a/lectures/code/class_headers/cmake_binary_lib/chatbot/chatbot.hpp
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef LECTURES_CODE_CLASS_HEADERS_CMAKE_PROJECT_CHATBOT_CHATBOT_HPP
-#define LECTURES_CODE_CLASS_HEADERS_CMAKE_PROJECT_CHATBOT_CHATBOT_HPP
-
-#include <string>
-#include <vector>
-
-class Chatbot {
- public:
-  struct Answer {
-    float probability{};
-    std::string text{};
-  };
-
-  struct Data {
-    bool IsValid() const;
-
-    std::vector<std::string> questions{};
-    std::vector<std::string> correct_answers{};
-  };
-
-  void Train(const Data &data);
-
-  Answer GetAnswer(const std::string &question) const;
-
- private:
-  void IngestData(const Data &data);
-
-  int smartness_{};
-};
-
-#endif /* LECTURES_CODE_CLASS_HEADERS_CMAKE_PROJECT_CHATBOT_CHATBOT_HPP */
diff --git a/lectures/code/class_headers/cmake_binary_lib/chatbot/main.cpp b/lectures/code/class_headers/cmake_binary_lib/chatbot/main.cpp
deleted file mode 100644
index f7a00f0..0000000
--- a/lectures/code/class_headers/cmake_binary_lib/chatbot/main.cpp
+++ /dev/null
@@ -1,15 +0,0 @@
-#include <chatbot/chatbot.hpp>
-#include <iostream>
-
-int main() {
-  Chatbot chatbot{};
-  chatbot.Train({{"How much is 2 + 2?",
-                  "What color is the sky?",
-                  "What is the answer to life and everything?"},
-                 {"4", "It depends", "42"}});
-  const auto question = "Are you self aware?";
-  std::cout << "Asking chatbot: " << question << std::endl;
-  std::cout << "Chatbot answered: " << chatbot.GetAnswer(question).text
-            << std::endl;
-  return 0;
-}
diff --git a/lectures/code/class_headers/cmake_header_only_lib/CMakeLists.txt b/lectures/code/class_headers/cmake_header_only_lib/CMakeLists.txt
deleted file mode 100644
index a59f6ac..0000000
--- a/lectures/code/class_headers/cmake_header_only_lib/CMakeLists.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-
-cmake_minimum_required(VERSION 3.16..3.24)
-project(chatbot VERSION 0.0.1
-                    DESCRIPTION "Our first project"
-                    LANGUAGES CXX)
-if(NOT CMAKE_BUILD_TYPE)
-  set(CMAKE_BUILD_TYPE Release CACHE STRING "" FORCE)
-endif()
-message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}")
-
-add_library(cxx_setup INTERFACE)
-target_compile_options(cxx_setup INTERFACE -Wall -Wpedantic -Wextra)
-target_compile_features(cxx_setup INTERFACE cxx_std_17)
-target_include_directories(cxx_setup INTERFACE ${PROJECT_SOURCE_DIR})
-
-add_subdirectory(${PROJECT_NAME})
diff --git a/lectures/code/class_headers/cmake_header_only_lib/chatbot/CMakeLists.txt b/lectures/code/class_headers/cmake_header_only_lib/chatbot/CMakeLists.txt
deleted file mode 100644
index 0ddf76f..0000000
--- a/lectures/code/class_headers/cmake_header_only_lib/chatbot/CMakeLists.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-# Indicate that we have a library
-add_library(chatbot INTERFACE)
-target_link_libraries(chatbot INTERFACE cxx_setup)
-
-# A binary that uses the library
-add_executable(chatbot_main main.cpp)
-target_link_libraries(chatbot_main PRIVATE chatbot cxx_setup)
diff --git a/lectures/code/class_headers/cmake_header_only_lib/chatbot/chatbot.hpp b/lectures/code/class_headers/cmake_header_only_lib/chatbot/chatbot.hpp
deleted file mode 100644
index 34d35e7..0000000
--- a/lectures/code/class_headers/cmake_header_only_lib/chatbot/chatbot.hpp
+++ /dev/null
@@ -1,40 +0,0 @@
-#pragma once
-
-#include <string>
-#include <vector>
-
-class Chatbot {
- public:
-  struct Answer {
-    float probability{};
-    std::string text{};
-  };
-
-  struct Data {
-    bool IsValid() const { return questions.size() == correct_answers.size(); }
-
-    std::vector<std::string> questions{};
-    std::vector<std::string> correct_answers{};
-  };
-
-  void Train(const Data &data) {
-    if (!data.IsValid()) { return; }
-    IngestData(data);
-  }
-
-  Answer GetAnswer(const std::string &question) const {
-    if (smartness_ < 1) { return Answer{0.1, "I don't know"}; }
-    if (smartness_ < 5) { return Answer{0.8, "Yes."}; }
-    if (question.length() > 10) {
-      return Answer{1.0, "You will regret this question..."};
-    }
-    return Answer{1.0, "Can't you ask anything more important?"};
-  }
-
- private:
-  void IngestData(const Data &data) {
-    smartness_ += data.correct_answers.size();
-  }
-
-  int smartness_{};
-};
diff --git a/lectures/code/class_headers/cmake_header_only_lib/chatbot/main.cpp b/lectures/code/class_headers/cmake_header_only_lib/chatbot/main.cpp
deleted file mode 100644
index f7a00f0..0000000
--- a/lectures/code/class_headers/cmake_header_only_lib/chatbot/main.cpp
+++ /dev/null
@@ -1,15 +0,0 @@
-#include <chatbot/chatbot.hpp>
-#include <iostream>
-
-int main() {
-  Chatbot chatbot{};
-  chatbot.Train({{"How much is 2 + 2?",
-                  "What color is the sky?",
-                  "What is the answer to life and everything?"},
-                 {"4", "It depends", "42"}});
-  const auto question = "Are you self aware?";
-  std::cout << "Asking chatbot: " << question << std::endl;
-  std::cout << "Chatbot answered: " << chatbot.GetAnswer(question).text
-            << std::endl;
-  return 0;
-}
diff --git a/lectures/code/class_headers/simple/chatbot.cpp b/lectures/code/class_headers/simple/chatbot.cpp
deleted file mode 100644
index f1e285d..0000000
--- a/lectures/code/class_headers/simple/chatbot.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-#include <iostream>
-#include <string>
-#include <vector>
-
-class Chatbot {
- public:
-  struct Answer {
-    float probability{};
-    std::string text{};
-  };
-
-  struct Data {
-    bool IsValid() const { return questions.size() == correct_answers.size(); }
-
-    std::vector<std::string> questions{};
-    std::vector<std::string> correct_answers{};
-  };
-
-  void Train(const Data &data) {
-    if (!data.IsValid()) { return; }
-    IngestData(data);
-  }
-
-  Answer GetAnswer(const std::string &question) const {
-    if (smartness_ < 1) { return Answer{0.1, "I don't know"}; }
-    if (smartness_ < 5) { return Answer{0.8, "Yes."}; }
-    if (question.length() > 10) {
-      return Answer{1.0, "You will regret this question..."};
-    }
-    return Answer{1.0, "Can't you ask anything more important?"};
-  }
-
- private:
-  void IngestData(const Data &data) {
-    smartness_ += data.correct_answers.size();
-  }
-
-  int smartness_{};
-};
-
-int main() {
-  Chatbot chatbot{};
-  chatbot.Train({{"How much is 2 + 2?",
-                  "What color is the sky?",
-                  "What is the answer to life and everything?"},
-                 {"4", "It depends", "42"}});
-  const auto question = "Are you self aware?";
-  std::cout << "Asking chatbot: " << question << std::endl;
-  std::cout << "Chatbot answered: " << chatbot.GetAnswer(question).text
-            << std::endl;
-  return 0;
-}
diff --git a/lectures/code/class_headers/simple_header/chatbot/chatbot.hpp b/lectures/code/class_headers/simple_header/chatbot/chatbot.hpp
deleted file mode 100644
index 34d35e7..0000000
--- a/lectures/code/class_headers/simple_header/chatbot/chatbot.hpp
+++ /dev/null
@@ -1,40 +0,0 @@
-#pragma once
-
-#include <string>
-#include <vector>
-
-class Chatbot {
- public:
-  struct Answer {
-    float probability{};
-    std::string text{};
-  };
-
-  struct Data {
-    bool IsValid() const { return questions.size() == correct_answers.size(); }
-
-    std::vector<std::string> questions{};
-    std::vector<std::string> correct_answers{};
-  };
-
-  void Train(const Data &data) {
-    if (!data.IsValid()) { return; }
-    IngestData(data);
-  }
-
-  Answer GetAnswer(const std::string &question) const {
-    if (smartness_ < 1) { return Answer{0.1, "I don't know"}; }
-    if (smartness_ < 5) { return Answer{0.8, "Yes."}; }
-    if (question.length() > 10) {
-      return Answer{1.0, "You will regret this question..."};
-    }
-    return Answer{1.0, "Can't you ask anything more important?"};
-  }
-
- private:
-  void IngestData(const Data &data) {
-    smartness_ += data.correct_answers.size();
-  }
-
-  int smartness_{};
-};
diff --git a/lectures/code/class_headers/simple_header/main.cpp b/lectures/code/class_headers/simple_header/main.cpp
deleted file mode 100644
index f7a00f0..0000000
--- a/lectures/code/class_headers/simple_header/main.cpp
+++ /dev/null
@@ -1,15 +0,0 @@
-#include <chatbot/chatbot.hpp>
-#include <iostream>
-
-int main() {
-  Chatbot chatbot{};
-  chatbot.Train({{"How much is 2 + 2?",
-                  "What color is the sky?",
-                  "What is the answer to life and everything?"},
-                 {"4", "It depends", "42"}});
-  const auto question = "Are you self aware?";
-  std::cout << "Asking chatbot: " << question << std::endl;
-  std::cout << "Chatbot answered: " << chatbot.GetAnswer(question).text
-            << std::endl;
-  return 0;
-}
diff --git a/lectures/code/cmake_install/core_project/CMakeLists.txt b/lectures/code/cmake_install/core_project/CMakeLists.txt
deleted file mode 100644
index 9442d24..0000000
--- a/lectures/code/cmake_install/core_project/CMakeLists.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-cmake_minimum_required(VERSION 3.16..3.24)
-project(core_project
- VERSION 0.0.1
- DESCRIPTION "Sample project with a library target"
- LANGUAGES CXX)
-
-if(NOT CMAKE_BUILD_TYPE)
- set(CMAKE_BUILD_TYPE Release CACHE INTERNAL "Build type")
-endif()
-
-message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}")
-
-add_subdirectory(core_project)
-add_subdirectory(examples)
-
-include(CMakePackageConfigHelpers)
-
-# Create a config file that CMake looks for when we call FindPackage(core_project)
-configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/Config.cmake.in
- "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
- INSTALL_DESTINATION "share/cmake/${PROJECT_NAME}"
-)
-
-# Create a versioned config file that CMake uses to compare version of the package.
-write_basic_package_version_file(
- ${PROJECT_NAME}ConfigVersion.cmake
- VERSION ${PACKAGE_VERSION}
- COMPATIBILITY AnyNewerVersion
-)
-
-# Copy these files into the install directory.
-install(
- FILES
- ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
- ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
- DESTINATION
- share/cmake/${PROJECT_NAME}
-)
diff --git a/lectures/code/cmake_install/core_project/cmake/Config.cmake.in b/lectures/code/cmake_install/core_project/cmake/Config.cmake.in
deleted file mode 100644
index 6a941ab..0000000
--- a/lectures/code/cmake_install/core_project/cmake/Config.cmake.in
+++ /dev/null
@@ -1,9 +0,0 @@
-@PACKAGE_INIT@
-
-# Automatically include all exported library files
-file(GLOB EXPORT_FILES "${CMAKE_CURRENT_LIST_DIR}/*_export.cmake")
-foreach(EXPORT_FILE ${EXPORT_FILES})
-    include(${EXPORT_FILE})
-endforeach()
-
-check_required_components(core_project)
diff --git a/lectures/code/cmake_install/core_project/core_project/CMakeLists.txt b/lectures/code/cmake_install/core_project/core_project/CMakeLists.txt
deleted file mode 100644
index 5fe32d3..0000000
--- a/lectures/code/cmake_install/core_project/core_project/CMakeLists.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-set(LIBRARY_NAME some_library)
-add_library(${LIBRARY_NAME} ${LIBRARY_NAME}.cpp)
-target_compile_features(${LIBRARY_NAME} PUBLIC cxx_std_17)
-target_include_directories(${LIBRARY_NAME}
-    PUBLIC
-    $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}>
-    $<INSTALL_INTERFACE:include/>
-)
-add_library(${PROJECT_NAME}::${LIBRARY_NAME} ALIAS ${LIBRARY_NAME})
-
-install(
-    DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
-    DESTINATION include
-    FILES_MATCHING PATTERN "*.hpp"
-)
-
-install(
-    TARGETS ${LIBRARY_NAME}
-    EXPORT ${LIBRARY_NAME}_export
-)
-
-install(EXPORT ${LIBRARY_NAME}_export
-    FILE ${LIBRARY_NAME}_export.cmake
-    NAMESPACE ${PROJECT_NAME}::
-    DESTINATION share/cmake/${PROJECT_NAME}
-)
diff --git a/lectures/code/cmake_install/core_project/core_project/some_library.cpp b/lectures/code/cmake_install/core_project/core_project/some_library.cpp
deleted file mode 100644
index 530535c..0000000
--- a/lectures/code/cmake_install/core_project/core_project/some_library.cpp
+++ /dev/null
@@ -1,11 +0,0 @@
-#include "core_project/some_library.hpp"
-
-#include <iostream>
-
-namespace core_project {
-
-void PrintHello() noexcept {
-    std::cout << "Hello world!" << std::endl;
- }
-
-} // namespace core_project
diff --git a/lectures/code/cmake_install/core_project/core_project/some_library.hpp b/lectures/code/cmake_install/core_project/core_project/some_library.hpp
deleted file mode 100644
index 814a7c6..0000000
--- a/lectures/code/cmake_install/core_project/core_project/some_library.hpp
+++ /dev/null
@@ -1,7 +0,0 @@
-#pragma once
-
-namespace core_project {
-
-void PrintHello() noexcept;
-
-} // namespace core_project
\ No newline at end of file
diff --git a/lectures/code/cmake_install/core_project/examples/CMakeLists.txt b/lectures/code/cmake_install/core_project/examples/CMakeLists.txt
deleted file mode 100644
index 8e633db..0000000
--- a/lectures/code/cmake_install/core_project/examples/CMakeLists.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-add_executable(print_hello print_hello.cpp)
-target_link_libraries(print_hello PRIVATE core_project::some_library)
-
-install(TARGETS print_hello)
diff --git a/lectures/code/cmake_install/core_project/examples/print_hello.cpp b/lectures/code/cmake_install/core_project/examples/print_hello.cpp
deleted file mode 100644
index 05ac599..0000000
--- a/lectures/code/cmake_install/core_project/examples/print_hello.cpp
+++ /dev/null
@@ -1,6 +0,0 @@
-#include "core_project/some_library.hpp"
-
-int main() {
-  core_project::PrintHello();
-  return 0;
-}
\ No newline at end of file
diff --git a/lectures/code/cmake_install/dependent_project/CMakeLists.txt b/lectures/code/cmake_install/dependent_project/CMakeLists.txt
deleted file mode 100644
index 0dddf33..0000000
--- a/lectures/code/cmake_install/dependent_project/CMakeLists.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-cmake_minimum_required(VERSION 3.16..3.24)
-project(dependent_project
-    VERSION 0.0.1
-    DESCRIPTION "Sample project that uses the core project"
-    LANGUAGES CXX)
-
-add_subdirectory(examples)
diff --git a/lectures/code/cmake_install/dependent_project/examples/CMakeLists.txt b/lectures/code/cmake_install/dependent_project/examples/CMakeLists.txt
deleted file mode 100644
index c75e88c..0000000
--- a/lectures/code/cmake_install/dependent_project/examples/CMakeLists.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-find_package(core_project REQUIRED CONFIG)
-
-add_executable(print_hello print_hello.cpp)
-target_link_libraries(print_hello PRIVATE core_project::some_library)
diff --git a/lectures/code/cmake_install/dependent_project/examples/print_hello.cpp b/lectures/code/cmake_install/dependent_project/examples/print_hello.cpp
deleted file mode 100644
index 05ac599..0000000
--- a/lectures/code/cmake_install/dependent_project/examples/print_hello.cpp
+++ /dev/null
@@ -1,6 +0,0 @@
-#include "core_project/some_library.hpp"
-
-int main() {
-  core_project::PrintHello();
-  return 0;
-}
\ No newline at end of file
diff --git a/lectures/code/error_handling/comparison_game/comparison_game.cpp b/lectures/code/error_handling/comparison_game/comparison_game.cpp
deleted file mode 100644
index 585b2d2..0000000
--- a/lectures/code/error_handling/comparison_game/comparison_game.cpp
+++ /dev/null
@@ -1,80 +0,0 @@
-#include <iostream>
-#include <vector>
-
-struct ChangeEntry {
-  int index{};
-  int value{};
-};
-
-// 😱 Warning! No error handling!
-class Game {
- public:
-  Game(std::vector<int>&& ref_numbers,
-       std::vector<int>&& player_numbers,
-       int budget)
-      : ref_numbers_{std::move(ref_numbers)},
-        player_numbers_{std::move(player_numbers)},
-        budget_{budget} {}
-
-  void Print() const {
-    std::cout << "Budget: " << budget_ << std::endl;
-    std::cout << "Reference numbers: ";
-    for (auto number : ref_numbers_) { std::cout << number << "\t"; }
-    std::cout << std::endl;
-    std::cout << "Player numbers:    ";
-    for (auto number : player_numbers_) { std::cout << number << "\t"; }
-    std::cout << std::endl;
-  }
-
-  bool CheckIfPlayerWon() const {
-    int win_loss_counter{};
-    for (auto i = 0UL; i < player_numbers_.size(); ++i) {
-      const auto difference = player_numbers_[i] - ref_numbers_[i];
-      if (difference > 0) win_loss_counter++;
-      if (difference < 0) win_loss_counter--;
-    }
-    return win_loss_counter > 0;
-  }
-
-  void ChangePlayerNumberIfPossible(const ChangeEntry& change_entry) {
-    auto& player_number = player_numbers_[change_entry.index];
-    const auto difference = std::abs(change_entry.value - player_number);
-    if (difference > budget_) { return; }
-    player_number = change_entry.value;
-    budget_ -= difference;
-  }
-
-  const std::vector<int>& ref_numbers() const { return ref_numbers_; }
-  const std::vector<int>& player_numbers() const { return player_numbers_; }
-  bool UserHasBudget() const { return budget_ > 0; }
-
- private:
-  std::vector<int> ref_numbers_{};
-  std::vector<int> player_numbers_{};
-  int budget_{};
-};
-
-// 😱 We should handle failure to get a proper value.
-ChangeEntry GetNextChangeEntryFromUser(const Game& game) {
-  game.Print();
-  ChangeEntry entry{};
-  std::cout << "Please enter number to change: ";
-  std::cin >> entry.index;
-  std::cout << "Please provide a new value: ";
-  std::cin >> entry.value;
-  return entry;
-}
-
-int main() {
-  Game game{{42, 49, 23}, {42, 40, 23}, 10};
-  while (game.UserHasBudget()) {
-    const auto change_entry = GetNextChangeEntryFromUser(game);
-    game.ChangePlayerNumberIfPossible(change_entry);
-  }
-  game.Print();
-  if (game.CheckIfPlayerWon()) {
-    std::cout << "You win!\n";
-  } else {
-    std::cout << "Not win today. Try again!\n";
-  }
-}
diff --git a/lectures/code/error_handling/comparison_game/comparison_game_expected.cpp b/lectures/code/error_handling/comparison_game/comparison_game_expected.cpp
deleted file mode 100644
index 1e004f9..0000000
--- a/lectures/code/error_handling/comparison_game/comparison_game_expected.cpp
+++ /dev/null
@@ -1,103 +0,0 @@
-// For simplicity, I don't use actual abseil here as it would require CMake
-// which would complicate this example.
-#define CHECK_GE(expr, value)
-#define CHECK_LT(expr, value)
-
-#include <algorithm>
-#include <expected>
-#include <format>
-#include <iostream>
-#include <utility>
-#include <vector>
-
-struct ChangeEntry {
-  int index{};
-  int value{};
-};
-
-class Game {
- public:
-  Game(std::vector<int>&& ref_numbers,
-       std::vector<int>&& player_numbers,
-       int budget)
-      : ref_numbers_{std::move(ref_numbers)},
-        player_numbers_{std::move(player_numbers)},
-        budget_{budget} {}
-
-  void Print() const {
-    std::cout << "Budget: " << budget_ << std::endl;
-    std::cout << "Reference numbers: ";
-    for (auto number : ref_numbers_) { std::cout << number << "\t"; }
-    std::cout << std::endl;
-    std::cout << "Player numbers:    ";
-    for (auto number : player_numbers_) { std::cout << number << "\t"; }
-    std::cout << std::endl;
-  }
-
-  bool CheckIfPlayerWon() const {
-    int win_loss_counter{};
-    for (auto i = 0UL; i < player_numbers_.size(); ++i) {
-      const auto difference = player_numbers_[i] - ref_numbers_[i];
-      if (difference > 0) win_loss_counter++;
-      if (difference < 0) win_loss_counter--;
-    }
-    return win_loss_counter > 0;
-  }
-
-  void ChangePlayerNumberIfPossible(const ChangeEntry& change_entry) {
-    // Checking:
-    //   (change_entry.index >= 0)
-    //   (change_entry.index < player_numbers_.size())
-    CHECK_GE(change_entry.index, 0);
-    CHECK_LT(change_entry.index, player_numbers_.size());
-    auto& player_number = player_numbers_[change_entry.index];
-    const auto difference = std::abs(change_entry.value - player_number);
-    if (difference > budget_) { return; }
-    player_number = change_entry.value;
-    budget_ -= difference;
-  }
-
-  const std::vector<int>& ref_numbers() const { return ref_numbers_; }
-  const std::vector<int>& player_numbers() const { return player_numbers_; }
-  bool UserHasBudget() const { return budget_ > 0; }
-
- private:
-  std::vector<int> ref_numbers_{};
-  std::vector<int> player_numbers_{};
-  int budget_{};
-};
-
-// Requires C++23
-std::expected<ChangeEntry, std::string> GetNextChangeEntryFromUser(
-    const Game& game) {
-  game.Print();
-  ChangeEntry entry{};
-  std::cout << "Please enter number to change: ";
-  std::cin >> entry.index;
-  if ((entry.index < 0) || (entry.index >= game.player_numbers().size())) {
-    return std::unexpected(std::format("Index {} must be in [0, {}) interval",
-                                       entry.index,
-                                       game.player_numbers().size()));
-  }
-  std::cout << "Please provide a new value: ";
-  std::cin >> entry.value;
-  return entry;
-}
-
-int main() {
-  Game game{{42, 49, 23}, {10, 40, 24}, 10};
-  while (game.UserHasBudget()) {
-    const auto change_entry = GetNextChangeEntryFromUser(game);
-    if (!change_entry) {  // Also possible: change_entry.has_value().
-      std::cerr << change_entry.error() << std::endl;
-      continue;
-    }
-    game.ChangePlayerNumberIfPossible(change_entry.value());
-  }
-  game.Print();
-  if (game.CheckIfPlayerWon()) {
-    std::cout << "You win!\n";
-  } else {
-    std::cout << "Not win today. Try again!\n";
-  }
-}
diff --git a/lectures/code/make/make_sample/Makefile b/lectures/code/make/make_sample/Makefile
deleted file mode 100644
index 39196fe..0000000
--- a/lectures/code/make/make_sample/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-print_hello:
-	echo "Hello, World"
diff --git a/lectures/code/make/make_sample/print_hello b/lectures/code/make/make_sample/print_hello
deleted file mode 100644
index e69de29..0000000
diff --git a/lectures/code/make/simple_build/Makefile b/lectures/code/make/simple_build/Makefile
deleted file mode 100644
index 2cb2e7d..0000000
--- a/lectures/code/make/simple_build/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-all: main
-
-clean:
-	rm -f blah.o libblah.a main
-
-main: main.cpp libblah.a
-	c++ -std=c++17 main.cpp -I . -L . -lblah -o main
-
-libblah.a: blah.o
-	ar rcs libblah.a blah.o
-
-blah.o: blah.cpp
-	c++ -std=c++17 -c blah.cpp -I . -o blah.o
diff --git a/lectures/code/make/simple_build/blah.cpp b/lectures/code/make/simple_build/blah.cpp
deleted file mode 100644
index e3e6a98..0000000
--- a/lectures/code/make/simple_build/blah.cpp
+++ /dev/null
@@ -1,9 +0,0 @@
-#include <blah.h>
-
-#include <iostream>
-
-namespace tools {
-
-void PrintHello() { std::cout << "Hello!" << std::endl; }
-
-} // namespace tools
diff --git a/lectures/code/make/simple_build/blah.h b/lectures/code/make/simple_build/blah.h
deleted file mode 100644
index c4b0cb7..0000000
--- a/lectures/code/make/simple_build/blah.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#pragma once
-
-namespace tools {
-
-void PrintHello();
-
-} // namespace tools
diff --git a/lectures/code/make/simple_build/main.cpp b/lectures/code/make/simple_build/main.cpp
deleted file mode 100644
index 0e1e414..0000000
--- a/lectures/code/make/simple_build/main.cpp
+++ /dev/null
@@ -1,6 +0,0 @@
-#include <blah.h>
-
-int main() {
-  tools::PrintHello();
-  return 0;
-}
diff --git a/lectures/code/our_project/CMakeLists.txt b/lectures/code/our_project/CMakeLists.txt
deleted file mode 100644
index c145972..0000000
--- a/lectures/code/our_project/CMakeLists.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-
-cmake_minimum_required(VERSION 3.16..3.24)
-project(our_project VERSION 0.0.1
-                    DESCRIPTION "Our first project"
-                    LANGUAGES CXX)
-if(NOT CMAKE_BUILD_TYPE)
-  set(CMAKE_BUILD_TYPE Release CACHE STRING "" FORCE)
-endif()
-message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}")
-
-add_library(cxx_setup INTERFACE)
-target_compile_options(cxx_setup INTERFACE -Wall -Wpedantic -Wextra)
-target_compile_features(cxx_setup INTERFACE cxx_std_17)
-target_include_directories(cxx_setup INTERFACE ${PROJECT_SOURCE_DIR})
-
-# 🚨 Make sure CMakeLists.txt file exists in the subdirectories!
-add_subdirectory(${PROJECT_NAME})
-add_subdirectory(executables)
-
-# 💡 Some things are missing in this example
-# 💡 For example tests, installation instructions, etc.
-# 💡 We'll add those later in the course
diff --git a/lectures/code/our_project/executables/CMakeLists.txt b/lectures/code/our_project/executables/CMakeLists.txt
deleted file mode 100644
index 809d195..0000000
--- a/lectures/code/our_project/executables/CMakeLists.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-
-  add_executable(print_hello print_hello.cpp)
-  target_link_libraries(print_hello PRIVATE tools cxx_setup)
diff --git a/lectures/code/our_project/executables/print_hello.cpp b/lectures/code/our_project/executables/print_hello.cpp
deleted file mode 100644
index 74a1903..0000000
--- a/lectures/code/our_project/executables/print_hello.cpp
+++ /dev/null
@@ -1,6 +0,0 @@
-
-  #include <our_project/tools/tools.h>
-  int main() {
-    our_project::tools::PrintHello();
-    return 0;
-  }
diff --git a/lectures/code/our_project/our_project/CMakeLists.txt b/lectures/code/our_project/our_project/CMakeLists.txt
deleted file mode 100644
index b02cbb7..0000000
--- a/lectures/code/our_project/our_project/CMakeLists.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-
-  add_subdirectory(tools)
diff --git a/lectures/code/our_project/our_project/tools/CMakeLists.txt b/lectures/code/our_project/our_project/tools/CMakeLists.txt
deleted file mode 100644
index 8fe444e..0000000
--- a/lectures/code/our_project/our_project/tools/CMakeLists.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-
-  add_library(tools tools.cpp)
-  target_link_libraries(tools PUBLIC cxx_setup)
diff --git a/lectures/code/our_project/our_project/tools/tools.cpp b/lectures/code/our_project/our_project/tools/tools.cpp
deleted file mode 100644
index cf09859..0000000
--- a/lectures/code/our_project/our_project/tools/tools.cpp
+++ /dev/null
@@ -1,8 +0,0 @@
-
-#include <iostream>
-#include <our_project/tools/tools.h>
-namespace our_project {
-namespace tools {
-void PrintHello() { std::cout << "Hello!" << std::endl; }
-} // namespace tools
-} // namespace our_project
diff --git a/lectures/code/our_project/our_project/tools/tools.h b/lectures/code/our_project/our_project/tools/tools.h
deleted file mode 100644
index 2d52423..0000000
--- a/lectures/code/our_project/our_project/tools/tools.h
+++ /dev/null
@@ -1,7 +0,0 @@
-
-#pragma once
-namespace our_project {
-namespace tools {
-void PrintHello();
-} // namespace tools
-} // namespace our_project
diff --git a/lectures/code/values.cpp b/lectures/code/values.cpp
deleted file mode 100644
index 73c9ecc..0000000
--- a/lectures/code/values.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-#include <iostream>
-
-std::byte *AllocateMemory(std::size_t length) { return new std::byte[length]; }
-void FreeMemory(std::byte *ptr) { delete[] ptr; }
-
-struct HugeObject {
-  HugeObject() { std::cout << "Default constructor" << std::endl; }
-
-  explicit HugeObject(std::size_t data_length)
-      : length{data_length}, ptr{AllocateMemory(length)} {
-    std::cout << "Allocated " << data_length << " bytes" << std::endl;
-  }
-
-  HugeObject &operator=(const HugeObject &object) {
-    if (this == &object) { return *this; }  // Do not self-assign.
-    FreeMemory(ptr);
-    length = object.length;
-    ptr = AllocateMemory(length);
-    std::copy(object.ptr, object.ptr + length, ptr);
-    std::cout << "Copied data from another object" << std::endl;
-    return *this;
-  }
-
-  HugeObject &operator=(HugeObject &&object) {
-    FreeMemory(ptr);
-    length = object.length;
-    ptr = object.ptr;
-    object.ptr = nullptr;
-    std::cout << "Stole data from another object" << std::endl;
-    return *this;
-  }
-
-  ~HugeObject() {
-    FreeMemory(ptr);
-    std::cout << "Destroyed" << std::endl;
-  }
-
-  std::size_t length{};
-  std::byte *ptr{};
-};
-
-struct HugeObjectStorage {
-  HugeObject member_object;
-};
-
-int main() {
-  HugeObject object{100};
-  HugeObjectStorage storage{};
-  storage.member_object = object;
-  storage.member_object = HugeObject{200};
-  storage.member_object = std::move(object);
-  return 0;
-}
diff --git a/lectures/compilation_debugging.md b/lectures/compilation_debugging.md
deleted file mode 100644
index 408488a..0000000
--- a/lectures/compilation_debugging.md
+++ /dev/null
@@ -1,166 +0,0 @@
----
-marp: true
-math: katex
-theme: custom-theme
-footer: ![width:80px](images/C++ForYourselfIcon.png)
----
-
-# Compilation flags and debugging
-
-#### Today:
-- What other compilation flags exist
-- What compilation flags to use
-- How to debug code
-
-### 📺 Watch the related [YouTube video](https://youtu.be/NTlcDv7W2-c)!
-
----
-# Special symbols used in slides
-- 🎨 - Style recommendation
-- 🎓 - Software design recommendation
-- 😱 - **Not** a good practice! Avoid in real life!
-- ✅ - Good practice!
-- ❌ - Whatever is marked with this is wrong
-- 🚨 - Alert! Important information!
-- 💡 - Hint or a useful exercise
-- 🔼1️⃣7️⃣ - Holds for this version of C++(here, `17`) and **above**
-- 🔽1️⃣1️⃣ - Holds for versions **until** this one C++(here, `11`)
-
-Style (🎨) and software design (🎓) recommendations mostly come from [Google Style Sheet](https://google.github.io/styleguide/cppguide.html) and the [CppCoreGuidelines](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines)
-
----
-# Compilation flags
-- Lots of flags can be passed while compiling the code
-- We have seen some already: `-std=c++17`, `-o`, etc.
-  ```cmd
-  c++ -std=c++17 -o test test.cpp
-  ```
-- ✅ Enable **most** [warnings](https://gcc.gnu.org/onlinedocs/gcc/gcc-command-options/options-to-request-or-suppress-warnings.html#cmdoption-Wall), treat them as errors:
-  `-Wall`, `-Wextra`, `-Wpedantic`, `-Werror`
-- Other warnings possible too:
-  `-Wimplicit-fallthrough`, `-Wsign-conversion`, etc.
-- Optimization options:
-  - `-O0` - no optimization `[default]`
-  - `-O3` - full optimization `[preferred]`
-- Keep debugging symbols: `-g` (usually used with `-O0`)
-
----
-# Debugging your code
-- Debugging **will** take more time than writing your code
-- :bulb: Read about [how to think about debugging](https://github.com/kmille/linux-debugging/blob/1e863038859420a50e2ebe3e7e18362aa70e8f57/mindset.md) (**really**, do it!)
-- When it comes to tools used for debugging,
-  there are largely two different philosophies:
-  - Using **print** statements `[my preference]`
-  - Using a **debugger**
-- Each has advantages and disadvantages
-- No debugging methods is complete without you thinking about the **probable cause of the problem**
-- You can read [a discussion](https://news.ycombinator.com/item?id=26925570) on Hacker News about it
-
----
-# Using print statements
-- Just add any printout statements to your code
-- I usually use a form of a print statement shown below:
-  <!--
-  `CPP_SETUP_START`
-  #include <iostream>
-  using std::cerr;
-  using std::endl;
-  int main() {
-    int value{};
-    $PLACEHOLDER
-    return 0;
-  }
-  `CPP_SETUP_END`
-  -->
-  ```cpp
-  cerr << __FILE__ << ":" << __LINE__ << ": " << value << endl;
-  ```
-- This will print the filename and a line where its called
-- We can also print a `value` of interest at any point
-- Usually requires to recompile only part of the program
-- **Typical workflow:**
-  - Observe the behavior
-  - Form a hypothesis of what is wrong
-  - Try a fix and repeat until problem is solved
-- This workflow forces us **to understand** the problem before rushing into trying a solution
----
-# Using a debugger
-- Allows stopping a program at a point and looking around
-- Requires **debug symbols** (`-g` flag), needs **full** recompilation
-- Might be confusing with optimizations enabled
-- Best program to use is probably `lldb` or `gdb`
-- Insanely popular and powerful (and already installed :wink:)
-- Allows to print the **backtrace**
-- No built-in gui :cry:
-- There are some tools built on top of GDB to fix this:
-  - [`gdbgui`](https://gdbgui.com/) is a Python tool that provides a web GUI for GDB
-  - VSCode C++ extension provides a GUI for the debugger
-- I rarely use a debugger and when I do I use `lldb`/`gdb`
----
-# Exercise: debug a simple program!
-:x: Beware it has an error!
-```cpp
-#include <iostream>
-#include <vector>
-int main() {
-  std::vector<int> numbers{1, 2, 3};
-  for (auto i = numbers.size() - 1UL; i >= 0; --i) {
-    std::cout << numbers[i] << std::endl;
-  }
-  return 0;
-}
-```
-Once we run the program it crashes at some point:
-```css
-[1]    74786 segmentation fault  ./program
-```
----
-# Using print statements
-```cpp
-#include <iostream>
-#include <vector>
-int main() {
-  std::vector<int> numbers{1, 2, 3};
-  int count{};  // <- Count used for debugging
-  for (auto i = numbers.size() - 1UL; i >= 0; --i) {
-    std::cerr << "i = " << i << std::endl;  // <- Debug print
-    std::cout << numbers[i] << std::endl;
-    if (count++ > 10) {break;}  // <- Early exit
-  }
-  return 0;
-}
-```
-- We can see smth like this on `stderr`:
-  ```
-  i = 2
-  i = 1
-  i = 0
-  i = 18446744073709551615
-  ```
-- Now we can guess what happens, here is a [hint](cpp_basic_types_and_variables.md#be-careful-with-unsigned-integers) :wink:
----
-# Using `lldb` (or `gdb`)
-- Recompile the code with `-g -O0` flags
-- Start the code in the debugger:
-  ```cmd
-  λ › lldb ./program
-  (lldb) target create "./program"
-  Current executable set to '/private/tmp/program' (arm64).
-  (lldb) r
-  ```
-- When it fails, `lldb` shows us **where** it fails
-- To find out **why** we will add a breakpoint
-  ```
-  (lldb) breakpoint set --file program.cpp --line 6
-  ```
-- Restart by typing `r`, the execution will stop at breakpoint
-- We now add a `watch` on the variable `i`
-  ```
-  (lldb) watch set var i
-  ```
-- Repeatedly enter `c` and press <kbd>⏎</kbd> until the [issue](cpp_basic_types_and_variables.md#be-careful-with-unsigned-integers) is found
-- Full [tutorial](https://lldb.llvm.org/use/tutorial.html) directly from `lldb`
----
-
-
-![bg](https://fakeimg.pl/1280x1024/226699/fff/?text=Good%20luck!&font=bebas)
diff --git a/lectures/const_correctness.md b/lectures/const_correctness.md
deleted file mode 100644
index 1c1a1e7..0000000
--- a/lectures/const_correctness.md
+++ /dev/null
@@ -1,383 +0,0 @@
-Const correctness
----
-
-<p align="center">
-  <a href="https://youtu.be/WsBdxq319OY"><img src="https://img.youtube.com/vi/WsBdxq319OY/maxresdefault.jpg" alt="Video" align="right" width=50%></a>
-</p>
-
-- [Modeling an example of passing the phone](#modeling-an-example-of-passing-the-phone)
-- [Rule 1: pass by const reference](#rule-1-pass-by-const-reference)
-- [Rule 2: create const objects](#rule-2-create-const-objects)
-- [Rules 3 and 4: return data by const reference, mark functions that don't change the object as const](#rules-3-and-4-return-data-by-const-reference-mark-functions-that-dont-change-the-object-as-const)
-  - [The `const` class methods can be confusing to beginners](#the-const-class-methods-can-be-confusing-to-beginners)
-- [Rule 5: don't mark class data as const unless you're implementing a view](#rule-5-dont-mark-class-data-as-const-unless-youre-implementing-a-view)
-- [Summary](#summary)
-
-
-Const correctness is a paradigm of how and when to use `const` with our objects and functions "correctly" to simplify the process of writing and reading of the code while using the compiler to protect us from changing data that should stay constant.
-
-<!-- Visual example
-We can even illustrate its usefulness in a somewhat dorky but still "real life" example. So... imagine a friend wants to borrow your phone...
-
-Dialog starts:
-- P1: Hey dude, how's it going?
-- P2: Good, good, I'm coding this cool project in C++ about...
-- P1: Yeah, yeah... That sounds great! Listen, can I borrow your phone for a sec?
-- P2: **taking out the phone** Sure... why?
-- P1: Nothing much, just need to check the weather tonight in Interlaken...
-- P2: **handing over the phone** Ah, ok, here you go.
-- P1: **taking the phone and clicking it** Thanks, man!
-**"a few moments later"**
-- P1: That's it! I'm done! Thanks a lot!
-- P2: **taking the phone** Sure! My pleasure... **looking at the phone, camera zooms in on a message to Bjarne that Java is cooler than C++** Wait... What the? WTF?
-
-Cut!!!! Stop! Whoah! That escalated quickly! What went wrong here? Well, we gave out too much access to an object that was important to us - a phone. What can we do to avoid this situation? Well, if we followed the "const correctness" paradigm we could have easily avoided this. In this particular situation, we could have provided a "view" over our phone instead of handing out the phone itself. Let's see how it would have played out:
-
-**Rewind**
-- P1: Listen, can I borrow your phone for a sec?
-- P2: **taking out the phone** Sure... why?
-- P1: Nothing much, just need to check the weather tonight in Interlaken...
-- P2: **showing the phone** Sure, here, have a look!
-
-See how by providing only a view of our phone we have eliminated a possibility of changing our phone object. And, you've guessed it, "providing a view" is just a fancy way of saying that we give out a const reference instead of the object itself. Now let's dig into how this and other similar situations would be represented in code and what exactly _is_ this "const correctness" when applied to C++, shall we?
-
- -->
-
-<!-- Intro -->
-
-# Modeling an example of passing the phone
-So let's say our friend wants to borrow our phone, how would we represent it in C++?
-
-I'd argue that both we and our friend would be objects of some classes, say `GoodPerson` and `MehPerson`. A `GoodPerson` would own a phone, i.e., the `Phone` object would be part of the data owned by the `GoodPerson`. And, being a `GoodPerson` open to the world, we will start by modelling a `GoodPerson` as a `struct` (see the [lecture on classes](classes_intro.md) for more on `struct` vs `class`). The `MehPerson` would have a function `DoStuff` that takes a reference to a phone:
-<!--
-`CPP_SETUP_START`
-using Phone = int;
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` persons/persons.h
--->
-```cpp
-struct GoodPerson {
-  Phone phone;
-};
-
-class MehPerson {
- public:
-  // Imagine the implementation is hidden in a library - no way for us to know
-  // what this function actually does with the phone it gets.
-  void DoStuff(Phone &phone);
-};
-```
-
-We can then model the situation of passing over the phone by creating an object of each of these classes and passing the phone object from one to another to do stuff with it:
-<!--
-`CPP_SETUP_START`
-#include "persons.h"
-void MehPerson::DoStuff(Phone &phone) {}
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` persons/main.cpp
-`CPP_RUN_CMD` CWD:persons c++ -std=c++17 main.cpp
--->
-```cpp
-int main() {
-  GoodPerson me{};
-  MehPerson my_friend{};
-  my_friend.DoStuff(me.phone);
-  return 0;
-}
-```
-
-# Rule 1: pass by const reference
-If you followed me talking about [functions](functions.md) before, then you will instantly see an issue with the `DoStuff` function: it takes a non-const `Phone` object. Which allows the `MehPerson` class to modify the `Phone` object in any way it wants. Even worse, the implementation of `MehPerson` can be hidden away into a [pre-compiled library](headers_and_libraries.md) from us so we can't know for sure what is happening there!
-
-Which leads us to **rule #1** of const correctness:
-
-> **Rule 1️⃣**: Always pass big objects you don't intend to change by a `const` reference to any function. Pass small objects by copy.
-
-This is nothing new to us as we have talked about it before when we talked about functions. However, it does not help us much here, does it? The function `DoStuff` does not belong to us. For all we know, it belongs to some other library. But _they_ are interested in _our_ `Phone` object, right? So we _do_ have some form of control.
-
-# Rule 2: create const objects
-One way to enforce const correctness here would be to not have a mutable `Phone` object in the first place. And a way to achieve this would be to become an extremely stable person and create the object that represents us in the previous example as a `const` object in the first place:
-<!--
-`CPP_SETUP_START`
-using Phone = int;
-struct GoodPerson {
-  Phone phone;
-};
-class MehPerson {
- public:
-  void DoStuff(const Phone &phone) {}
-};
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` persons/main.cpp
-`CPP_RUN_CMD` CWD:persons c++ -std=c++17 main.cpp
--->
-```cpp
-int main() {
-  const GoodPerson me{};
-  MehPerson my_friend{};
-  my_friend.DoStuff(me.phone);  // ❌ Won't compile unless DoStuff takes a const reference or a copy of the Phone
-}
-```
-
-Which leads us to our **rule #2** of const correctness:
-> **Rule 2️⃣**: Make every object `const` unless it explicitly needs to be changed. If you can design an object that does not need to change throughout its lifetime - do so.
-
-The bad news here is that it is hard to achieve at all times. Think about it, while I believe that I am a very stable person, in no way I could model myself as a `const` object. Not even talking about the physiological or moral things, what if I want to buy a new `Phone` and replace my instance with this new one? So the `GoodPerson` object cannot be `const` here and such cases are quite common.
-
-# Rules 3 and 4: return data by const reference, mark functions that don't change the object as const
-So how else can we make sure that the `DoStuff` function must take a constant `Phone` reference?
-
-We _do_ have another trick up our sleeves. It's time for the `GoodPerson` `struct` to close up a little and become a `class`. This allows us a lot more control over how the others get access to our data.
-
-In our case, we would make `GoodPerson` a class that takes a reference to a temporary `Phone` (an rref) object in its constructor. We would then move the underlying `Phone` object into its `private` data and hold it there.
-
-We also have to think of how to expose this internal `Phone` object to the world, so we implement a "getter" function. This function would return a `const` reference to our internal `Phone` object. Furthermore, this function is not supposed to change the underlying object in any way and we have a mechanism to indicate this to the compiler: we mark the whole function `const` too!
-
-<!--
-`CPP_SETUP_START`
-using Phone = int;
-class MehPerson {
- public:
-  void DoStuff(const Phone &phone) {}
-};
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` persons/main.cpp
-`CPP_RUN_CMD` CWD:persons c++ -std=c++17 main.cpp
--->
-```cpp
-#include <utility>  // For std::move
-
-class GoodPerson {
- public:
-  explicit GoodPerson(Phone &&phone) : phone_{std::move(phone)} {}
-  const Phone &phone() const { return phone_; }
-
- private:
-  Phone phone_;
-};
-
-int main() {
-  GoodPerson me{Phone{}};
-  MehPerson my_friend{};
-  my_friend.DoStuff(me.phone());
-}
-```
-
-Which allows us to formulate rules 3 and 4 of const correctness:
-> **Rule 3️⃣**: Prefer returning a `const` reference to the private data of complex types of any object if you need to expose them to the user of your class. Return a copy for simple types instead. Only return a non-`const` reference if your class implements a data-agnostic container, e.g., a `std::vector` or alike.
-
-> **Rule 4️⃣**: Mark every class method as `const` unless it is explicitly _supposed_ to change the underlying object. Prefer `const` methods when designing a class.
-
-
-## The `const` class methods can be confusing to beginners
-It is important to note here, that if a class method is not marked as `const` the compiler assumes that this method _can_ change the underlying object.
-
-<!-- RERECORD -->
-I want to note that in my experience, the `const` class functions are the reason most of the beginners struggle with `const` correctness in C++. Let's illustrate why.
-
-You have a class `Foo` with a function `bar` that is a "getter" and does not change the content of the `Foo` object:
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` foo/main.cpp
-`CPP_RUN_CMD` CWD:foo c++ -std=c++17 -c main.cpp
--->
-```cpp
-class Foo {
- public:
-  int bar() { return bar_; }
-
- private:
-  int bar_{};
-};
-```
-
-Now the `Foo` object is passed by a `const` reference to some function called `Whatever` that calls `bar()` on it:
-<!--
-`CPP_SETUP_START`
-class Foo {
- public:
-  int bar() const { return bar_; }
-
- private:
-  int bar_{};
-};
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` foo_new/main.cpp
-`CPP_RUN_CMD` CWD:foo_new c++ -std=c++17 -c main.cpp
--->
-```cpp
-void Whatever(const Foo& foo) {
-  foo.bar();
-}
-
-int main() {
-  Foo foo{};
-  Whatever(foo);
-  return 0;
-}
-```
-
-What will happen if we try to compile this code? The compiler will complain:
-```css
-main.cpp:4:3: error: 'this' argument to member function 'bar' has type 'const Foo', but function is not marked const
-   foo.bar();
-   ^~~
-```
-
-At this point a lot of beginners will become frustrated: they know that they don't change the `foo` object, they pass a `const` reference to the `Whatever` function and seem to be doing everything right. But the compiler sees that the `foo.bar()` method is not marked as `const` and assumes the worst. So it will complain that calling a non-`const` method on a `const` reference to an object might change the underlying object, which is forbidden. I've seen many frustrated students struggle with this concept but I, for one, like how it's implemented. Anyway, if you follow rules 3 and 4 that we just introduced, you should be fine :wink:
-
-<!-- Until here! -->
-
-# Rule 5: don't mark class data as const unless you're implementing a view
-Finally, there is just one more place where `const` can be used and that I have to mention here. We can actually have `const` _data_ within a class. So, coming back to our example, we _could_ make the `Phone` object constant within our `GoodPerson` structure:
-<!--
-`CPP_SETUP_START`
-using Phone = int;
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` const_person/main.cpp
-`CPP_RUN_CMD` CWD:const_person c++ -std=c++17 -c main.cpp
--->
-```cpp
-struct GoodPerson {
-  const Phone phone;  // 😱 not the best idea.
-};
-```
-
-However, this is nearly never a good idea.
-<!-- If you _do_ know of a good use-case, please write it in the comments. -->
-
-Essentially by having `const` data any object of such a class is doomed to live and die within a single scope with no way to be moved to any different scope.
-
-This is rarely useful with one significant outlier - the view paradigm. As one typical example consider this: say, a certain class has its interface but we would want it to have a different interface when we work with it. One way to achieve this is to introduce a thin wrapper around the class in question that holds a `const` reference to the object of interest and introduces new interface to working with this object. Feels a bit hand-wavy, right? Let's think of a concrete example then.
-
-Let's say, our friend and us from the previous example figure that the `MehPerson` class does not need the whole `Phone` object. They just need the weather! So they change the `DoStuff` function to take a const reference to the `Weather` object instead, which the `Phone` object readily provides:
-<!--
-`CPP_SETUP_START`
-#include <utility>
-using Weather = int;
-struct Phone {
-  Weather weather() const { return weather_; }
-  Weather weather_;
-};
-class GoodPerson {
- public:
-  explicit GoodPerson(Phone &&phone) : phone_{std::move(phone)} {}
-  const Phone &phone() const { return phone_; }
-
- private:
-  Phone phone_;
-};
-class MehPerson {
- public:
-  void DoStuff(const Weather &phone) {}
-};
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` weather/main.cpp
-`CPP_RUN_CMD` CWD:weather c++ -std=c++17 main.cpp
--->
-```cpp
-int main() {
-  GoodPerson me{Phone{}};
-  MehPerson my_friend{};
-  my_friend.DoStuff(me.phone().weather());
-  return 0;
-}
-```
-
-However, the `Weather` object only has a function to get a forecast by GNSS coordinate:
-<!--
-`CPP_SETUP_START`
-using Latitude = int;
-using Longitude = int;
-using Forecast = int;
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` weather_details/main.cpp
-`CPP_RUN_CMD` CWD:weather_details c++ -std=c++17 -c main.cpp
--->
-```cpp
-class Weather {
- public:
-  Forecast GetWeatherForLocation(const Latitude& latitude, const Longitude& longitude) const;
-  // Other stuff in the Weather object
-};
-```
-This is convenient for a very precise forecast but our friend wants to know the weather in Interlaken, remember? So they wrap the constant `Weather` reference into a view object, that uses some other functions and provides a better interface, calling the `weather.GetWeatherForLocation(lat, lon)` under the hood:
-<!--
-`CPP_SETUP_START`
-using Latitude = int;
-using Longitude = int;
-using Forecast = int;
-struct LatLon {
-  Latitude latitude;
-  Longitude longitude;
-};
-struct Weather {
-  Forecast GetWeatherForLocation(Latitude, Longitude) const {return {};}
-};
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` weather_view/view.h
--->
-```cpp
-#include <string>
-
-// Get latitude and longitude provided a city name
-LatLon GetGnssCoordinatesForCity(const std::string& city_name);
-
-class CityWeatherView {
- public:
-  explicit CityWeatherView(const Weather &weather) : weather_{weather} {}
-
-  Forecast GetWeatherForCity(const std::string &city_name) const {
-    const auto lat_lon = GetGnssCoordinatesForCity(city_name);
-    // ❓Question: should GetWeatherForLocation be a const method?
-    return weather_.GetWeatherForLocation(lat_lon.latitude, lat_lon.longitude);
-  }
-
- private:
-  const Weather &weather_;
-};
-```
-
-Such a `CityWeatherView` is not movable and exists for the sole purpose of simplifying the interface to the `Weather` object. This class is then typically used locally within some scope, say the `DoStuff` method of the `MehPerson` class:
-<!--
-`CPP_SETUP_START`
-#include "view.h"
-class MehPerson {
- public:
-  void DoStuff(const Weather &weather);
-};
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` weather_view/main.cpp
-`CPP_RUN_CMD` CWD:weather_view c++ -std=c++17 -c main.cpp
--->
-```cpp
-void MehPerson::DoStuff(const Weather &weather) {
-  const CityWeatherView weather_view{weather};
-  const auto forecast = weather_view.GetWeatherForCity("interlaken");
-  // Do smth with the forecast.
-}
-```
-
-While you might argue that in this example we don't need the view class as we could've just called the `GetGnssCoordinatesForCity` function directly from the `DoStuff` function, imagine what would happen if this would happen in many parts of the code base? And what if the view helper function was longer than a couple of lines? These lines of code would then get copied in all the places that they would be needed, requiring us to repeat ourselves all the time, making changes that will inevitably come next much harder.
-
-Anyway, this leads us to our last rule of const correctness:
-> **Rule 5️⃣**: Never make class data const unless it is a const reference to other object when you are implementing a view over that object.
-
-:bulb: There is a slight caveat to that: we can and should mark the class `static` data const, but we'll talk about it some other time.
-
-# Summary
-Ok, we're done now! If you follow these 5 rules you should have no problem with `const` in C++. Not only that, you will actually employ the compiler as your friend who is able to look over your shoulder and find the mistakes in your logic. In the end, if you're trying to call a function not marked as `const` on a `const` object - you probably didn't really mean it! If the compiler does not catch this, you will have to spend time searching for the logic bug, which, in my experience, is _much_ harder. With time, using these rules will become second nature and will help you writing high-quality code that ends up saving you and the others time and nerves.
-
-<!-- And with this, I wish you a great day and see you in the next videos! And if you by chance need a refresher on move semantics, just click on the video over here. Ok, that's it! Bye!  -->
diff --git a/lectures/control_structures.md b/lectures/control_structures.md
deleted file mode 100644
index 2ed9636..0000000
--- a/lectures/control_structures.md
+++ /dev/null
@@ -1,384 +0,0 @@
----
-marp: true
-math: katex
-theme: custom-theme
-paginate: true
-footer: ![width:80px](images/C++ForYourselfIcon.png)
----
-
-# Control structures
-
-#### Today:
-- `if` statements and ternary operator
-- Loops: `for` and `while`
-
-### 📺 Watch the related [YouTube video](https://youtu.be/jzgTxosgGIA)!
-
----
-# Special symbols used in slides
-- 🎨 - Style recommendation
-- 🎓 - Software design recommendation
-- 😱 - **Not** a good practice! Avoid in real life!
-- ✅ - Good practice!
-- ❌ - Whatever is marked with this is wrong
-- 🚨 - Alert! Important information!
-- 💡 - Hint or a useful exercise
-- 🔼1️⃣7️⃣ - Holds for this version of C++(here, `17`) and **above**
-- 🔽1️⃣1️⃣ - Holds for versions **until** this one C++(here, `11`)
-
-Style (🎨) and software design (🎓) recommendations mostly come from [Google Style Sheet](https://google.github.io/styleguide/cppguide.html) and the [CppCoreGuidelines](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines)
-
----
-# If statement
-<!--
-`CPP_SETUP_START`
-int main() {
-  bool STATEMENT{};
-  bool OTHER_STATEMENT{};
-  $PLACEHOLDER
-  return 0;
-}
-`CPP_SETUP_END`
--->
-```cpp
-if (STATEMENT) {
-  // This is executed if STATEMENT == true
-} else if (OTHER_STATEMENT) {
-  // This is executed if:
-  // (STATEMENT == false) && (OTHER_STATEMENT == true)
-} else {
-  // This is executed if neither is true
-}
-```
-- Used to conditionally execute code
-- All the `else` cases can be omitted if needed
-- `STATEMENT` can be **any boolean expression**
-- 💡 Curly brackets can be omitted for single-line statements
-  <!--
-  `CPP_SETUP_START`
-
-  inline void DoThis(){}
-
-  int main() {
-    bool STATEMENT{};
-    $PLACEHOLDER
-    return 0;
-  }
-  `CPP_SETUP_END`
-  -->
-  ```cpp
-  if (STATEMENT)
-    DoThis();
-  ```
-- 🎨 Always use curly brackets as it's harder to make a mistake
-- ✅ Use `clang-format` to indent your code for you!
-
----
-# Ternary operator
-
-- There is a short-hand version of writing an if statement
-- Let's look at an example
-  <!--
-  `CPP_SETUP_START`
-  inline bool GetRandomTrueOrFalse() {return false;}
-  inline void CallIfTrue() {}
-  inline void CallIfFalse() {}
-  int main() {
-    $PLACEHOLDER
-    return 0;
-  }
-  `CPP_SETUP_END`
-  -->
-  ```cpp
-  bool condition = GetRandomTrueOrFalse();
-  condition ? CallIfTrue() : CallIfFalse();
-  ```
-- This is **equivalent** to the following `if` statement:
-  <!--
-  `CPP_SETUP_START`
-  inline bool GetRandomTrueOrFalse() {return false;}
-  inline void CallIfTrue() {}
-  inline void CallIfFalse() {}
-  int main() {
-    $PLACEHOLDER
-    return 0;
-  }
-  `CPP_SETUP_END`
-  -->
-  ```cpp
-  bool condition = GetRandomTrueOrFalse();
-  if (condition) {
-    CallIfTrue();
-  } else {
-    CallIfFalse();
-  }
-  ```
-- ✅ You can use it for simple cases
-- :x: Don't use for complex scenarios
-
----
-# Switch statement
-<!--
-`CPP_SETUP_START`
-constexpr int kConst1{42};
-constexpr int kConst2{23};
-inline int GetNumber() {return 42;}
-int main() {
-  $PLACEHOLDER
-  return 0;
-}
-`CPP_SETUP_END`
--->
-```cpp
-const int statement = GetNumber();
-switch(statement) {
-  case kConst1:
-    // This runs if statement == kConst1
-    break;
-  case kConst2:
-    // This runs if statement == kConst2
-    break;
-  default:  // optional
-    // This runs if no other options worked
-    break;
-}
-```
-- Used to conditionally execute code
-- Can have many `case` statements
-- `break` exits the `switch` block
-- `statement` can be any integer-like type
-- If you covered all cases, you don't need `default`
-
----
-# Omitting the `break`
-- If the `break` is omitted from a `case` we call it a **fallthrough**
-- It means that the **next** case will be executed too
-- ✅ Always use `[[fallthrough]]` [C++ attribute](https://en.cppreference.com/w/cpp/language/attributes) to annotate situation where you want a fallthrough 🔼1️⃣7️⃣
-<!--
-`CPP_SETUP_START`
-constexpr int kConst1{42};
-constexpr int kConst2{23};
-int main() {
-  $PLACEHOLDER
-  return 0;
-}
-`CPP_SETUP_END`
--->
-```cpp
-// Somewhere in main
-const int statement = 1;
-switch (statement) {
-case kConst1:
-  // This runs if (statement == kConst1)
-  [[fallthrough]];  // Explicitly fall through
-case kConst2:
-  // This runs if:
-  // (statement == kConst2) or (statement == kConst1)
-  break;
-default:  // optional
-  break;
-}
-```
-
----
-
-# While loop
-<!--
-`CPP_SETUP_START`
-int main() {
-  bool STATEMENT{};
-  $PLACEHOLDER
-  return 0;
-}
-`CPP_SETUP_END`
--->
-```cpp
-while (STATEMENT) {
-  // Loop while STATEMENT == true.
-}
-```
-- Example `while` loop:
-<!--
-`CPP_SETUP_START`
-inline int GetRandomBool() {return false;}
-int main() {
-  bool STATEMENT{};
-  $PLACEHOLDER
-  return 0;
-}
-`CPP_SETUP_END`
--->
-```cpp
-bool condition = true;
-while (condition) {
-  condition = GetRandomBool();
-}
-```
-- Usually used when the exact number of iterations is unknown before-wise
-- Easy to form an endless loop by mistake
-
----
-# Do while loop
-- Sometimes you want the first iteration to always run
-- Use `do ... while();` construct for this!
-  ```cpp
-  #include <iostream>
-
-  int main() {
-    int number = 42;
-    do {
-      number--;
-      std::cout << number << std::endl;
-    } while (number != 0);
-    return 0;
-  }
-  ```
-- Notice that the check only happens _after_ the first iteration!
-- 💡 This is not used very often
-
-
----
-
-
-# For loop
-<!--
-`CPP_SETUP_START`
-#define INITIAL_CONDITION int i = 0
-#define END_CONDITION i < 42
-#define INCREMENT ++i
-int main() {
-  $PLACEHOLDER
-  return 0;
-}
-`CPP_SETUP_END`
--->
-```cpp
-for (INITIAL_CONDITION; END_CONDITION; INCREMENT) {
-  // This happens until END_CONDITION == false
-}
-```
-- Example `for` loop:
-<!--
-`CPP_SETUP_START`
-int main() {
-  const auto kIterationCount{100};
-  $PLACEHOLDER
-  return 0;
-}
-`CPP_SETUP_END`
--->
-```cpp
-for (int i = 0; i < kIterationCount; ++i) {
-  // This happens kIterationCount times.
-}
-```
-- In C++ `for` loops are _very_ fast. Use them!
-- Use `for` when the number of iterations is known and `while` otherwise
-
----
-# 🔼1️⃣1️⃣ Range for loop
-- ✅ Iterate over a standard containers with simpler syntax:
-  `std::array`, `std::vector`, or even `std::map`, *etc*.
-- Allows us to avoid mistakes with indices and shows intent
-  <!--
-  `CPP_SETUP_START`
-  #include<vector>
-  #include<iostream>
-  int main() {
-    $PLACEHOLDER
-    return 0;
-  }
-  `CPP_SETUP_END`
-  -->
-  ```cpp
-  const std::vector<int> numbers{42, 23};
-  for (const auto &number : numbers) {
-    std::cout << number << std::endl;
-  }
-  ```
-  <!--
-  `CPP_SETUP_START`
-  #include<map>
-  #include<iostream>
-  int main() {
-    $PLACEHOLDER
-    return 0;
-  }
-  `CPP_SETUP_END`
-  -->
-  ```cpp
-  const std::map<int, double> container{{42, 23.23}, {23, 42.42}};
-  for (const auto &[key, value] : container) {
-    std::cout << key << " " << value << std::endl;
-  }
-  ```
-- 🚨 Make sure to use `&` to get a reference when iterating over containers. Otherwise, the data is copied, which is slow!
-- :bulb: Modify data in the container by not using `const`
-  Try it out on your own!
-
----
-<!-- _footer: ![width:0px](images/C++ForYourselfIcon.png) -->
-
-
-# Endless loops
-![bg right contain](images/cats.gif)
-
-- We can create loops that never end with both `while` and `for`
-- ✅ `while` expresses the intent better
-  <!--
-  `CPP_SETUP_START`
-  int main() {
-    $PLACEHOLDER
-    return 0;
-  }
-  `CPP_SETUP_END`
-  -->
-  ```cpp
-  while(true) {
-    // Do this forever
-  }
-  ```
-- Syntax for `for` is less obvious:
-  <!--
-  `CPP_SETUP_START`
-  int main() {
-    $PLACEHOLDER
-    return 0;
-  }
-  `CPP_SETUP_END`
-  -->
-  ```cpp
-  for(;;) {
-    // Do this forever
-  }
-  ```
-
-
----
-# Exit loops and iterations
-- We have control over loop iterations
-- Use `continue` to skip to next iteration
-- Use `break` to exit the loop
-<!--
-`CPP_SETUP_START`
-int GetRandomInt() {return 42;}
-$PLACEHOLDER
-`CPP_SETUP_END`
--->
-```cpp
-#include <iostream>
-int main() {
-  while (true) {
-    int i = GetRandomInt();
-    if (i % 2 == 0) {
-      std::cout << i << std::endl;
-      continue;
-    }
-    break;
-  }
-}
-```
----
-
-
-![bg](https://fakeimg.pl/1280x1024/226699/fff/?text=Good%20luck!&font=bebas)
diff --git a/lectures/enums.md b/lectures/enums.md
deleted file mode 100644
index 28a4515..0000000
--- a/lectures/enums.md
+++ /dev/null
@@ -1,139 +0,0 @@
----
-marp: true
-math: katex
-theme: custom-theme
-# paginate: true
-footer: ![width:80px](images/C++ForYourselfIcon.png)
----
-
-# Enumeration types
-
-#### Today:
-- What are enumeration types
-- How to use them
-- How **not** to use them
-
-### 📺 Watch the related [YouTube video](https://youtu.be/4kZyQ-TwH00)!
-
----
-# Special symbols used in slides
-- 🎨 - Style recommendation
-- 🎓 - Software design recommendation
-- 😱 - **Not** a good practice! Avoid in real life!
-- ✅ - Good practice!
-- ❌ - Whatever is marked with this is wrong
-- 🚨 - Alert! Important information!
-- 💡 - Hint or a useful exercise
-- 🔼1️⃣7️⃣ - Holds for this version of C++(here, `17`) and **above**
-- 🔽1️⃣1️⃣ - Holds for versions **until** this one C++(here, `11`)
-
-Style (🎨) and software design (🎓) recommendations mostly come from [Google Style Sheet](https://google.github.io/styleguide/cppguide.html) and the [CppCoreGuidelines](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines)
-
----
-# 🔼1️⃣1️⃣ Enumeration classes
-- Store an **enumeration** of options
-  <!--
-  `CPP_SETUP_START`
-  using BaseType = int;
-  $PLACEHOLDER
-  int main() {
-    return 0;
-  }
-  `CPP_SETUP_END`
-  -->
-  ```cpp
-  enum class FoodOptions : BaseType { kPizza, kPasta, kSushi };
-  enum class ChoicesEnum { kYay, kNay };
-  ```
-- By default `BaseType` is `int`, can be any other integral type
-- Enums can have any number of options
-- The options are fixed upon `enum` definition
-- Options are assigned consequent numbers
-- Mostly used to pick a path in a `switch` statement
-- Use values as:
-  `FoodOptions::kPizza`, `ChoicesEnum::kYay`, ...
-- 🎨 Name enum types in `CamelCase`
-- 🎨 Name enum values as constants: `kSomeConstant`
-
----
-# Example
-```cpp
-#include <iostream>
-#include <string>
-
-enum class OutputChannel { kStdOut, kStdErr };
-
-// Note that output_channel is passed by value!
-void Print(OutputChannel output_channel, const std::string& msg) {
-  switch (output_channel) {
-    case OutputChannel::kStdOut:
-      std::cout << msg << std::endl;
-      break;
-    case OutputChannel::kStdErr:
-      std::cerr << msg << std::endl;
-      break;
-  }
-}
-int main() {
-  Print(OutputChannel::kStdOut, "hello");
-  Print(OutputChannel::kStdErr, "world");
-  return 0;
-}
-```
-
----
-# Explicit values
-- By default enum values start from `0`
-- We can specify **custom values** if needed
-  <!--
-  `CPP_SETUP_START`
-  $PLACEHOLDER
-  int main() {
-    return 0;
-  }
-  `CPP_SETUP_END`
-  -->
-  ```cpp
-  enum class EnumType {
-    kOption1 = 10,      // Decimal
-    kOption2 = 0x2,     // Hexadecimal
-    kOption3 = 0b101010 // Binary
-  };
-  ```
-- :bulb: Most of the times enums are used with default values
-
----
-# :scream: The olden days enum
-- Before C++11 you would define an enum without `class`:
-  <!--
-  `CPP_SKIP_SNIPPET`
-  -->
-  ```cpp
-  enum MyEnum{kValue1, kValue2};  // 😱 Don't do this in C++11
-  ```
-- Old enums can be implicitly converted to int:
-- These enums are **not** scoped like the `class` ones
-  ```cpp
-  enum OldEnum{kValue1, kValue2};  // Really, don't use it.
-  enum class NewEnum{kValue1, kValue2};
-  int main() {
-    const OldEnum old_value = kValue1; // Note no OldEnum:: prefix
-    const int some_value = kValue1;
-    const NewEnum new_value = NewEnum::kValue1;
-    return 0;
-  }
-  ```
-- ❓😱 Do you see an issue with this?
-  <!--
-  `CPP_SKIP_SNIPPET`
-  -->
-  ```cpp
-  enum EnumDecision{kRight, kWrong};
-  enum EnumSide{kLeft, kRight};
-  ```
-  <br>Try to compile this!
-
----
-
-
-![bg](https://fakeimg.pl/1280x1024/226699/fff/?text=Good%20luck!&font=bebas)
diff --git a/lectures/error_handling.md b/lectures/error_handling.md
deleted file mode 100644
index e53a23c..0000000
--- a/lectures/error_handling.md
+++ /dev/null
@@ -1,1172 +0,0 @@
-
-**Error Handling in C++**
-
-<p align="center">
-  <a href="https://youtu.be/6DqX8OJKM1g"><img src="https://img.youtube.com/vi/6DqX8OJKM1g/maxresdefault.jpg" alt="Video Thumbnail" align="right" width=50% style="margin: 0.5rem"></a>
-</p>
-
-- [Disclaimer](#disclaimer)
-- [What Do We Mean by “Error”?](#what-do-we-mean-by-error)
-- [Setting up the example: **a comparison game**](#setting-up-the-example-a-comparison-game)
-  - [Rules of the game](#rules-of-the-game)
-  - [Initial code of the game](#initial-code-of-the-game)
-- [Unrecoverable errors: **fail early**](#unrecoverable-errors-fail-early)
-  - [Our first unrecoverable error encounter](#our-first-unrecoverable-error-encounter)
-  - [How to deal with unrecoverable errors](#how-to-deal-with-unrecoverable-errors)
-    - [Catch them as early as possible](#catch-them-as-early-as-possible)
-    - [Use `CHECK` macro to fail early](#use-check-macro-to-fail-early)
-    - [Don't use `assert`](#dont-use-assert)
-    - [Complete the `Game` class yourself](#complete-the-game-class-yourself)
-  - [How to minimize number of unrecoverable errors](#how-to-minimize-number-of-unrecoverable-errors)
-- [Recoverable errors: **handle and proceed**](#recoverable-errors-handle-and-proceed)
-  - [Exceptions](#exceptions)
-    - [How to use exceptions](#how-to-use-exceptions)
-    - [A case for exceptions for both "recoverable" and "unrecoverable" errors](#a-case-for-exceptions-for-both-recoverable-and-unrecoverable-errors)
-    - [Why we might not want to use exceptions](#why-we-might-not-want-to-use-exceptions)
-      - [Exceptions are (sometimes) expensive](#exceptions-are-sometimes-expensive)
-      - [Exceptions hide the error path](#exceptions-hide-the-error-path)
-      - [Exceptions are banned in many code bases](#exceptions-are-banned-in-many-code-bases)
-  - [Returning errors explicitly can work better if done well](#returning-errors-explicitly-can-work-better-if-done-well)
-    - [Returning a value indicating error does not always work 😱](#returning-a-value-indicating-error-does-not-always-work-)
-    - [Returning an error code breaks "pure functions" 😱](#returning-an-error-code-breaks-pure-functions-)
-    - [Using `std::optional`: **a better way**](#using-stdoptional-a-better-way)
-    - [Using `std::expected`: **add context**](#using-stdexpected-add-context)
-  - [Performance Considerations for `std::optional` and `std::expected`](#performance-considerations-for-stdoptional-and-stdexpected)
-    - [Error type size matters](#error-type-size-matters)
-    - [Return value optimization with `std::optional` and `std::expected`](#return-value-optimization-with-stdoptional-and-stdexpected)
-  - [Summary](#summary)
-  - [Other use of `std::optional`](#other-use-of-stdoptional)
-
-When writing C++ code, much like in real life, we don’t always get what we want. The good news is that, unlike real life, C++ comes packed with the tools that help us prepare for not getting what we want.
-
-Today we’re talking about error handling. What options we have and which trade-offs they come with.
-
-So get a coffee and buckle up! There is a lot to cover and quite some nuance in this topic!
-
-Ah, and I can already smell the torches and hear the scraping of the pitchforks that people will inevitably bring to punish me for all the controversial statements I am about to make! What can go wrong, eh?
-
-# Disclaimer
-
-Jokes aside, this is definitely *not* a one-size-fits-all topic. C++ is huge, powerful, and used across every domain imaginable for a long-long time.
-
-*My* perspective comes from domains like robotics and automotive—where predictability and safety are of highest importance. What works for these domains may not work for everyone.
-
-However, I believe that what we talk about today fits many setups with minimal adaptation and is grounded in at least relatively sane reasoning. Where possible, I’ll try to mention multiple possible options and if I *do* miss an important one—please let me know!
-
-<!-- in the comments -->
-
-<!-- And, on this note, your comments and likes are the only ways I get any feedback from speaking into the void! So please do not shy away from sharing what you think, positive or negative! I value every nugget of feedback I can get!
-
-Now, back to error handling. -->
-
-# What Do We Mean by “Error”?
-
-Before we go into how to handle errors, however, let’s clarify what we mean when we think about an "error" in programming.
-
-At the highest level: **an error is what happens when a program doesn’t produce the result we expect.**
-
-I tend to think of errors belonging to one of two broad groups:
-
-- **Unrecoverable errors** — where the program reaches a state in which recovery is impossible or meaningless.
-- **Recoverable errors** — where the program can detect that something went wrong, and has ways to proceed following an alternative path.
-
-Some languages, like Rust, bake this distinction [directly into the language design](https://doc.rust-lang.org/book/ch09-00-error-handling.html). C++ doesn’t, making the topic of error handling slightly more nuanced.
-
-But, for my money, this classification, while not universal, is still useful. So let me present my case and talk a bit more in-depth about these kinds of errors and the intuition behind them.
-
-# Setting up the example: **a comparison game**
-
-## Rules of the game
-
-We have a lot to talk about and to not get lost, I would like to introduce a small example that will guide us and help illustrate all of the concepts we are talking about today.
-
-<img src="images/game_loss.png" alt="Game loss" align="right" width=50% style="margin: 0.5rem">
-
-To this end, let's model a simple puzzle game. In this game a player start with a vector of numbers generated for them. In the end of the game, this vector gets compared to some, also generated, reference vector. The vectors are compared element-by-element. The player gets nothing if the elements are equal, a `-1` if their number is smaller than the reference one, and a `+1` if their number is larger. If the resulting sum of these scores is positive - the player wins the game, and loses otherwise.
-
-<img src="images/game_win.png" alt="Game win" align="right" width=50% style="margin: 0.5rem">
-
-To make it an actual *game*, we need to give the player at least *some* control over their numbers. So we allow them to use a certain budget that can be used up to increase any numbers in their vector. The goal is to use the budget cleverly to win the game.
-
-## Initial code of the game
-
-Now let's spend a couple of minutes to set up the code for all what we've just discussed. We won't model all of the potential complexity of this game but I urge you to play around with these ideas after watching this lecture and see if you can build something that is actually interesting to play!
-
-To start off, we'll probably need a class `Game` that would hold the reference and player numbers as well as the remaining budget. It also needs a way:
-
-- to print the current state of the game;
-- to check if the player won by comparing the player's numbers with reference ones one-by-one and keeping the score;
-- to change the player number if there is still budget for this provided a `ChangeEntry` object, a tiny `struct` with `index` and `value` in our case.
-
-This `change_entry` must come from somewhere, so we need a way to ask the player to provide it. We can encapsulate our user interactions into a function like `GetNextChangeEntryFromUser` which will print the current state of the game, ask the user for their input and fill a `change_entry` object using this input.
-
-To keep this example simple, we implement all of this in one `cpp` file alongside a simple `main` function that creates a `Game` object, asks the user to provide a desired `change_entry` and changing the player's numbers accordingly in a loop until the user runs out of budget.
-
-Finally, we check if the player has won the game and show them the result.
-
-```cpp
-#include <iostream>
-#include <vector>
-
-struct ChangeEntry {
-  int index{};
-  int value{};
-};
-
-// 😱 Warning! No error handling!
-class Game {
- public:
-  Game(std::vector<int>&& ref_numbers,
-       std::vector<int>&& player_numbers,
-       int budget)
-      : ref_numbers_{std::move(ref_numbers)},
-        player_numbers_{std::move(player_numbers)},
-        budget_{budget} {}
-
-  void Print() const {
-    std::cout << "Budget: " << budget_ << std::endl;
-    std::cout << "Reference numbers: ";
-    for (auto number : ref_numbers_) { std::cout << number << "\t"; }
-    std::cout << std::endl;
-    std::cout << "Player numbers:    ";
-    for (auto number : player_numbers_) { std::cout << number << "\t"; }
-    std::cout << std::endl;
-  }
-
-  bool CheckIfPlayerWon() const {
-    int win_loss_counter{};
-    for (auto i = 0UL; i < player_numbers_.size(); ++i) {
-      const auto difference = player_numbers_[i] - ref_numbers_[i];
-      if (difference > 0) win_loss_counter++;
-      if (difference < 0) win_loss_counter--;
-    }
-    return win_loss_counter > 0;
-  }
-
-  void ChangePlayerNumberIfPossible(const ChangeEntry& change_entry) {
-    auto& player_number = player_numbers_[change_entry.index];
-    const auto difference = std::abs(change_entry.value - player_number);
-    if (difference > budget_) { return; }
-    player_number = change_entry.value;
-    budget_ -= difference;
-  }
-
-  const std::vector<int>& ref_numbers() const { return ref_numbers_; }
-  const std::vector<int>& player_numbers() const { return player_numbers_; }
-  bool UserHasBudget() const { return budget_ > 0; }
-
- private:
-  std::vector<int> ref_numbers_{};
-  std::vector<int> player_numbers_{};
-  int budget_{};
-};
-
-// 😱 We should handle failure to get a proper value.
-ChangeEntry GetNextChangeEntryFromUser(const Game& game) {
-  game.Print();
-  ChangeEntry entry{};
-  std::cout << "Please enter number to change: ";
-  std::cin >> entry.index;
-  std::cout << "Please provide a new value: ";
-  std::cin >> entry.value;
-  return entry;
-}
-
-int main() {
-  Game game{{42, 49, 23}, {10, 40, 24}, 10};
-  while (game.UserHasBudget()) {
-    const auto change_entry = GetNextChangeEntryFromUser(game);
-    game.ChangePlayerNumberIfPossible(change_entry);
-  }
-  game.Print();
-  if (game.CheckIfPlayerWon()) {
-    std::cout << "You win!\n";
-  } else {
-    std::cout << "Not win today. Try again!\n";
-  }
-}
-```
-
-This is not the most elegant code out there, but it is not too far from the style of code we might encounter in the wild.
-
-And by the way, all of this code is, as always, [available](code/error_handling/comparison_game/comparison_game.cpp) for you to play around with on the accompanying GitHub page.
-
-We can build this program as a single executable directly from the command line:
-
-```cmd
-c++ -std=c++17 -o comparison_game comparison_game.cpp
-```
-
-Ideally, we should at least unit-test all of our functions, but it will serve as a nice cautionary tale if we just give it a play-through instead!
-
-# Unrecoverable errors: **fail early**
-
-## Our first unrecoverable error encounter
-
-We run our executable and are greeted with expected numbers as well as a prompt to change one of *our* numbers:
-
-```output
-λ › ./comparison_game
-Budget: 10
-Reference numbers: 42    49      23
-Player numbers:    10    40      24
-Please enter number to change:
-```
-
-We see that we hopelessly lose on the first number but we win on the last number. The decisive number here is the second one, which we can increase by `10` from `40` to `50`, leading us to win this game! Considering that our budget is exactly `10` we provide these numbers to our program and observe what happens:
-
-```output
-λ › ./comparison_game
-Budget: 10
-Reference numbers: 42    49      23
-Player numbers:    10    40      24
-Please enter number to change: 40
-Please provide a new value: 50
-Budget: 2
-Reference numbers: 50    49      23
-Player numbers:    10    40      24
-Please enter number to change:
-```
-
-<img src="images/ub.jpg" alt="Docs are always out of date" align="right" width=40% style="margin: 0.5rem">
-
-🤯 But wait, what's going on here? Why did our number in the second column not change? Why is our budget not decreased by `10`? Even more strangely, why did the first reference number change to `50`?
-
-The answer to all of these questions is that we have just encountered an **unrecoverable error** that manifests itself in wrong values in our memory through the "virtues" of **Undefined Behavior**. But what gives?
-
-Well, there is a chain of events that caused our values to be changed in ways that we didn't expect. The most immediate cause is that the user has mistakenly provided the **number** they wanted to change, `40`, rather than an **index** of that number, `1`. We then did not check that the provided "index" is within the allowed bounds of the player numbers vector and wrote the provided new value under this wrong index.
-
-If we correct our mistake by rerunning our game again and providing `1` as the first input, we win, just as we expected to!
-
-```output
-λ › ./comparison_game
-Budget: 10
-Reference numbers: 42   49      23
-Player numbers:    10   40      24
-Please enter number to change: 1
-Please provide a new value: 50
-Budget: 0
-Reference numbers: 42   49      23
-Player numbers:    10   50      24
-You win!
-```
-
-When we provide `40` as we did the first time, our wrong index is far beyond the size of the `player_numbers_` vector and, when we write beyond its bounds we enter the Undefined Behavior land.
-
-What happens next is **unpredictable**. If we are *lucky* and the address into which we write does **not** belong to our program, the program will crash.
-
-If we are *not* lucky however, we will rewrite *some* memory that belongs to our program, potentially corrupting any objects that actually own that memory.
-
-<img src="images/memory_ub.png" alt="Memory layout" align="right" width=50% style="margin: 0.5rem">
-
-In this particular example, I picked the values in such a way, that the "fake index" just happens to be equal to a difference in pointers `player_numbers_.data()` and `ref_numbers_.data()`. Which then results in us writing directly into the first element of the `ref_numbers_` vector, resulting in an unexpected update to the reference numbers.
-
-But I want to stress again that if we run the same program on another machine - we will most likely get a *different behavior* altogether!
-
-Even the order of `ref_numbers_` and `player_numbers_` in memory is not guaranteed, note how during this run on my machine they do not even follow the order of declaration!
-
-What *doesn't* change is that once the `ChangePlayerNumberIfPossible` method is called with a wrong `change_entry` in our example, all bets are off - **we do not have any guarantees on the consistency of the state of our program anymore**
-
-Arbitrary objects might have already been corrupted and can behave in unpredictable ways from this point on without us knowing about it. Which can lead to random-looking sporadic failures in seemingly unrelated parts of our program across multiple runs. This obviously becomes even harder to track down when we write more complex programs than our toy example here.
-
-🚨 **This idea lies at the core of what makes this type of errors "unrecoverable". If the data we try to use for recovery is also corrupted, we have no guarantees that any recovery will succeed at all!**
-
-## How to deal with unrecoverable errors
-
-### Catch them as early as possible
-
-Therefore a typical advice is to catch any wrong values that propagate through our program as early as possible—and crash as early as possible—before any more damage is done.
-
-### Use `CHECK` macro to fail early
-
-My favorite tool for this is the [`CHECK`](https://abseil.io/docs/cpp/guides/logging#CHECK) macro that can be found in the [Abseil library](https://abseil.io/docs/). To use it, we must include the `absl/log/check.h` header file and change our `ChangePlayerNumberIfPossible` function so that is uses the `CHECK` macro to check if the index is within bounds:
-
-<!--
-`CPP_SETUP_START`
-#include <vector>
-#include <algorithm>
-
-#define CHECK_GE(expr, value)
-#define CHECK_LT(expr, value)
-
-struct ChangeEntry {
-  int index{};
-  int value{};
-};
-
-class Game {
-  void ChangePlayerNumberIfPossible(const ChangeEntry& change_entry);
-
- private:
-  std::vector<int> ref_numbers_{};
-  std::vector<int> player_numbers_{};
-  int budget_{};
-};
-
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` error_handling/main.cpp
-`CPP_RUN_CMD` CWD:error_handling mkdir -p absl/log && touch absl/log/check.h && c++ -std=c++17 -I . -c main.cpp
--->
-```cpp
-#include <absl/log/check.h>
-
-// Old code unchanged here.
-
-void Game::ChangePlayerNumberIfPossible(const ChangeEntry& change_entry) {
-  // Checking:
-  //   (change_entry.index >= 0)
-  //   (change_entry.index < player_numbers_.size())
-  CHECK_GE(change_entry.index, 0);
-  CHECK_LT(change_entry.index, player_numbers_.size());
-  auto& player_number = player_numbers_[change_entry.index];
-  const auto difference = std::abs(change_entry.value - player_number);
-  if (difference > budget_) { return; }
-  player_number = change_entry.value;
-  budget_ -= difference;
-}
-
-// Old code unchanged here.
-```
-
-If we run our example now, we will get a crash as soon as we call the `ChangePlayerNumberIfPossible` function that clearly states where this error originated from and which check failed letting us debug this as easily as possible:
-
-```output
-F0000 00:00:1750605447.566908       1 example.cpp:44] Check failed: change_entry.index < player_numbers_.size() (40 vs. 3)
-```
-
-To the degree of my knowledge, using `CHECK`-like macros to check pre-conditions of functions is [widely considered a good practice](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#i6-prefer-expects-for-expressing-preconditions). These `CHECK`s can be violated either due to a bug in our program or due to some undefined behavior just like in our example from earlier.
-
-One concern that people have when thinking of using the `CHECK` macros is performance as these checks stay in the production code we ship and do cost some little time when our program runs.
-
-For my money, in most cases, the benefits far outweigh the costs, and, unless we've measured that we cannot allow the tiny performance hit in a particular place of our code, we should be free to use `CHECK` for safety against entering the Undefined Behavior land and saving us days, weeks or even month of debugging issues that are really hard to debug.
-
-<!-- TODO: Add an animation of showing UB land and CHECK kicking its ass -->
-
-### Don't use `assert`
-
-You might wonder if using `CHECK` is our only way to help us detect when we are in an inconsistent state and so I have to talk about one very famous alternative that is often recommended on the Internet.
-
-This alternative is to use [`assert`](https://en.cppreference.com/w/cpp/error/assert.html) statement which can be found in the `<cassert>` include file. Full disclosure: I'm not a fan of using `assert`.
-
-If you came here with your torches and pitchforks, this is probably a good time to get them ready! 😉
-
-But let me explain myself before you do anything drastic. You see, `assert` has one super annoying flaw that makes it impossible for me to recommend it for production code. I've seen sooo many bugs go unnoticed because of this! Let me show what I'm talking about using our game example.
-
-First, we can use `assert` in a very similar way to `CHECK`:
-
-<!--
-`CPP_SETUP_START`
-#include <vector>
-#include <algorithm>
-
-struct ChangeEntry {
-  int index{};
-  int value{};
-};
-
-class Game {
-  void ChangePlayerNumberIfPossible(const ChangeEntry& change_entry);
-
- private:
-  std::vector<int> ref_numbers_{};
-  std::vector<int> player_numbers_{};
-  int budget_{};
-};
-
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` error_handling/main_assert.cpp
-`CPP_RUN_CMD` CWD:error_handling c++ -std=c++17 -c main_assert.cpp
--->
-```cpp
-#include <cassert>
-
-// Old code unchanged here.
-
-void Game::ChangePlayerNumberIfPossible(const ChangeEntry& change_entry) {
-  assert(change_entry.index >= 0);
-  assert(change_entry.index < player_numbers_.size());
-  auto& player_number = player_numbers_[change_entry.index];
-  const auto difference = std::abs(change_entry.value - player_number);
-  if (difference > budget_) { return; }
-  player_number = change_entry.value;
-  budget_ -= difference;
-}
-
-// Old code unchanged here.
-```
-
-We compile and run our game just as we did before:
-
-```cmd
-c++ -std=c++17 -o comparison_game comparison_game.cpp
-```
-
-And if we run our program the assertion triggers:
-
-```output
-output.s: /app/example.cpp:44: void Game::ChangePlayerNumberIfPossible(const ChangeEntry &): Assertion `change_entry.index < player_numbers_.size()' failed.
-Program terminated with signal: SIGSEGV
-```
-
-So far so good, right? Using `assert` also crashes our program when the wrong input is provided and shows us where the wrong value was detected.
-
-So what is that annoying flaw I've been talking about that makes me dislike `assert`? Well, you see, all `assert` statements get *disabled* when a macro `NDEBUG` is defined. This is a standard macro that controls if the debug symbols get compiled into the binary and gets passed to the compilation command for most release builds as we generally don't want debug symbols in the binary we release. So essentially, `assert` almost always **does not protect us from undefined behavior in the code we actually deploy**!
-
-We can easily demonstrate that the `assert`s indeed get *compiled out* by adding `-DNDEBUG` flag to our compilation command:
-
-```cmd
-c++ -std=c++17 -DNDEBUG -o comparison_game comparison_game.cpp
-```
-
-Running our game *now* and providing a wrong input index leads to the same undefined behavior we observed before as all of the assertions were compiled out. Not great, right? What makes it even less great is that many people just don't know that `asserts` get disabled like that and are sure that they are protected, while they really are not!
-
-And `CHECK` does not have these flaws.
-
-### Complete the `Game` class yourself
-
-By the way, we've only covered how we could improve our `ChangePlayerNumberIfPossible` method of the `Game` class. Do you think our `CheckIfPlayerWon` function would benefit from the same treatment?
-
-<!-- Write your answer and reasoning in the comments below! What checks would you add? -->
-
-## How to minimize number of unrecoverable errors
-
-Of course, hard failures in the programs we ship are not ideal!
-
-One way to reduce the risk of such failures is to keep the test coverage high for the code we write, ideally close to 100% line and branch coverage, i.e., every line and logical branch gets executed at least once in our test suite which is run regularly and automatically.
-
-This way we catch most of the unrecoverable errors during development. In some industries, like automotive, aviation, or medical this is actually a requirement to obtain the certifications necessary for the resulting software to be used.
-
-But unfortunately, despite our best efforts, we cannot *completely* avoid catastrophic failures in the programs we ship!
-
-Even if we do everything right on our side, hardware can still fail and corrupt our memory. One fun example of this is the famous error in the Belgian election on the 18th of May 2003, where [one political party got 4096 extra votes](https://en.wikipedia.org/wiki/Electronic_voting_in_Belgium) due to what is believed to have been a cosmic ray flipping "a bit at the position 13 in the memory of the computer", essentially leading to 4096 more votes.
-
-<!-- Use Veritasium visualization for a bit flip -->
-
-This visualization is actually taken from an [excellent Veritasium video](https://www.youtube.com/watch?v=AaZ_RSt0KP8) on this topic. Do watch it if you want to know more!
-
-With the knowledge that we cannot completely remove the risk of hitting an unrecoverable error in production, and that we also probably don't want our, say, flight software just randomly dying during operation, in safety-critical systems, we often isolate components into separate processes or even separate hardware units, with watchdogs that can trigger recovery actions if one of our components suddenly crashes.
-
-This way we can have our cake and eat it at the same time: using `CHECK` minimizes the time-to-failure when a bug is encountered, while our fallback options keep the system safe as a whole even when certain components fail.
-
-That being said, this is a system architecture question and this topic is far beyond what I want to talk about today. In most non-safety-critical systems we do not need to think about these failure cases as deeply and we can usually just restart our program in case of a one-off failure.
-
-# Recoverable errors: **handle and proceed**
-
-But not *every* error should instantly crash our program! Indeed, in our example, the original cause of the error is not a cosmic ray flipping bits of our memory - but a wrong user input!
-
-The good thing about user inputs is that we can ask the user to correct these without crashing! The type of errors we encounter here can be called **recoverable errors**.
-
-To talk about them, let us focus on the function `GetNextChangeEntryFromUser` from our example. Currently, there is no validation of what the user provides as input but we absolutely *can* and *should* perform such validation!
-
-As we design our program, we know that the index that the player provides must be within the bounds of the player numbers vector in the `game` object:
-
-<!--
-`CPP_SETUP_START`
-#include <iostream>
-
-struct ChangeEntry {
-  int index{};
-  int value{};
-};
-
-struct Game {
-  void Print() const;
-};
-
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` error_handling/main_get_change_before.cpp
-`CPP_RUN_CMD` CWD:error_handling c++ -std=c++17 -c main_get_change_before.cpp
--->
-```cpp
-// 😱 We should handle failure to get a proper value.
-ChangeEntry GetNextChangeEntryFromUser(const Game& game) {
-  game.Print();
-  ChangeEntry entry{};
-  std::cout << "Please enter number to change: ";
-  std::cin >> entry.index;  // <-- This value is NOT arbitrary!
-  std::cout << "Please provide a new value: ";
-  std::cin >> entry.value;
-  return entry;
-}
-```
-
-So, when the player, *does* provide a wrong value we'd like to somehow know that something went wrong within the `GetNextChangeEntryFromUser` function and recover from this.
-
-Broadly speaking, we have two strategies of communicating failures like these that have emerged in C++ over the years:
-
-1. **Return a special value from a function.**
-2. Throw an **exception**.
-
-We’ll spend most of our time on the first option—but let’s first talk about throwing exceptions, and yes, why I think it might not be the best thing we could do.
-
-This is, yet again, a good time to get your pitchforks and torches ready 😉.
-
-## Exceptions
-
-### How to use exceptions
-
-Since C++98 we have a powerful machinery of exceptions at our disposal. An exception is essentially just an object of some type, typically derived from [`std::exception`](https://en.cppreference.com/w/cpp/error/exception.html) class. Such an exception holds the information about the underlying failure and can be "thrown" and "caught" within a C++ program.
-
-In our example, we could throw an object of `std::out_of_range` when the user inputs a wrong number index:
-
-<!--
-`CPP_SETUP_START`
-#include <iostream>
-#include <vector>
-
-struct ChangeEntry {
-  int index{};
-  int value{};
-};
-
-struct Game {
-  void Print() const;
-  std::vector<int> player_numbers() const;
-};
-
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` error_handling/get_change_exceptions.cpp
-`CPP_RUN_CMD` CWD:error_handling c++ -std=c++17 -c get_change_exceptions.cpp
--->
-```cpp
-#include <stdexcept>
-
-// Old unchanged code.
-
-// 😱 I'm not a fan of using exceptions.
-ChangeEntry GetNextChangeEntryFromUser(const Game& game) {
-  game.Print();
-  ChangeEntry entry{};
-  std::cout << "Please enter number to change: ";
-  std::cin >> entry.index;
-  if ((entry.index < 0) || (entry.index >= game.player_numbers().size())) {
-    throw std::out_of_range("Wrong number index provided.");
-  }
-  std::cout << "Please provide a new value: ";
-  std::cin >> entry.value;
-  return entry;
-}
-```
-
-Throwing an exception interrupts the normal program flow. We leave the current scope, so all objects allocated in it are automatically destroyed and the program continues with the "exceptional flow" to find a place where the thrown exception can be handled.
-
-Speaking of handling exceptions, we can "catch" them anywhere upstream from the place they have been thrown from. As `std::exception` is just an object, it can be caught by value or by reference but it is considered a good practice to catch them by reference. In our case we can catch either a `std::out_of_range` exception directly or, as `std::out_of_range` derives from `std::exception`, catch `std::exception` instead. All of the exceptions that derive from `std::exception` can override the `what()` function that we can use to see the cause of the error:
-
-<!--
-`CPP_SETUP_START`
-#include <iostream>
-#include <vector>
-
-struct ChangeEntry {
-  int index{};
-  int value{};
-};
-
-struct Game {
-  Game(std::vector<int>&& ref_numbers,
-       std::vector<int>&& player_numbers,
-       int budget)
-      : ref_numbers_{std::move(ref_numbers)},
-        player_numbers_{std::move(player_numbers)},
-        budget_{budget} {}
-  void Print() const;
-  std::vector<int> player_numbers() const;
-  void ChangePlayerNumberIfPossible(const ChangeEntry&);
-  bool UserHasBudget() const;
-  bool CheckIfPlayerWon() const;
-
-  std::vector<int> ref_numbers_{};
-  std::vector<int> player_numbers_{};
-  int budget_{};
-};
-
-ChangeEntry GetNextChangeEntryFromUser(const Game& game);
-
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` error_handling/main_get_change_exceptions.cpp
-`CPP_RUN_CMD` CWD:error_handling c++ -std=c++17 -c main_get_change_exceptions.cpp
--->
-```cpp
-#include <stdexcept>
-
-// Old unchanged code.
-
-int main() {
-  Game game{{42, 49, 23}, {10, 40, 24}, 10};
-  while (game.UserHasBudget()) {
-    try {
-      const auto change_entry = GetNextChangeEntryFromUser(game);
-      game.ChangePlayerNumberIfPossible(change_entry);
-    } catch (const std::out_of_range& e) {
-      std::cerr << e.what() << std::endl;
-    }
-  }
-  game.Print();
-  if (game.CheckIfPlayerWon()) {
-    std::cout << "You win!\n";
-  } else {
-    std::cout << "Not win today. Try again!\n";
-  }
-}
-```
-
-### A case for exceptions for both "recoverable" and "unrecoverable" errors
-
-Should we forget to catch an exception it bubbles up to the very top and terminates our program. To verify this, we could change `catch (const std::out_of_range& e)` to `catch (const std::runtime_error& e)` and see what happens.
-
-On paper, all of this looks very neat. Essentially, with exceptions, we could forget about the distinction between recoverable and unrecoverable errors: if we catch an error, it is a "recoverable" one, if not - we treat it as "unrecoverable".
-
-This is one of the main arguments from people who like using exceptions and don't like the concept of "unrecoverable errors" - do not make a global decision about the error type inside of a local scope - let someone with more overview figure out what to do.
-
-And it *is* a very compelling argument!
-
-The other compelling argument is that exceptions *are* part of the language so it feels odd not to use them.
-
-But there are problems with exceptions that, at least in some industries, we just cannot ignore.
-
-### Why we might not want to use exceptions
-
-#### Exceptions are (sometimes) expensive
-
-Exceptions typically [allocate memory on the heap](memory_and_smart_pointers.md#the-heap) when thrown, and rely on **R**un-**T**ime **T**ype **I**nformation ([RTTI](https://en.wikipedia.org/wiki/Run-time_type_information)) to propagate through the call stack. See previous lectures on [memory](memory_and_smart_pointers.md) and [dynamic polymorphism](inheritance.md) if this does not ring a bell.
-
-There is a really in-depth C++Now talk, called ["Exceptions demystified", by Andreas Weiss](https://www.youtube.com/watch?v=kO0KVB-XIeE), my former colleague at BMW, that goes into a lot of detail about how exceptions behave.
-
-Long story short, both throwing and catching exceptions relies on mechanisms that work at runtime and therefore cost execution time.
-
-Unfortunately, there are no guarantees on timing or performance of at least some of these operations. While in most common scenarios these operations run "fast-enough", in real-time or safety-critical code, such unpredictability is usually unacceptable.
-
-#### Exceptions hide the error path
-
-Exceptions also arguably make control flow harder to read and reason about. To quote [Google C++ style sheet](https://google.github.io/styleguide/cppguide.html#Exceptions):
-
-> Exceptions make the control flow of programs difficult to evaluate by looking at code: functions may return in places you don't expect. This causes maintainability and debugging difficulties.
-
-<img src="images/docs.png" alt="Docs are always out of date" align="right" width=25% style="margin: 0.5rem">
-
-Indeed, an error can propagate across many layers of calls before being caught. It’s easy to miss what a function might throw—especially if documentation is incomplete or out of date (which it almost always is).
-
-Furthermore, the language permits the use of generic `catch (...)` blocks and these make things even more confusing. We end up catching *something*, but we no longer know what we caught or who threw it at us! 😱
-
-In our own example, if, the `ChangePlayerNumberIfPossible` function throws an undocumented `std::runtime_error` exception but we only expect `std::out_of_range`, we don't have a good way of detecting this! Our only options are to allow such exceptions to be left unhandled and eventually to terminate our program or to add a `catch(...)` clause where we miss important context for what caused the error, making catching it a lot less useful:
-
-<!--
-`CPP_SETUP_START`
-#include <iostream>
-#include <vector>
-
-struct ChangeEntry {
-  int index{};
-  int value{};
-};
-
-struct Game {
-  Game(std::vector<int>&& ref_numbers,
-       std::vector<int>&& player_numbers,
-       int budget);
-  void Print() const;
-  std::vector<int> player_numbers() const;
-  void ChangePlayerNumberIfPossible(const ChangeEntry&);
-  bool UserHasBudget() const;
-};
-
-ChangeEntry GetNextChangeEntryFromUser(const Game& game);
-
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` error_handling/main_get_change_exceptions_ellipsis.cpp
-`CPP_RUN_CMD` CWD:error_handling c++ -std=c++17 -c main_get_change_exceptions_ellipsis.cpp
--->
-```cpp
-// Old unchanged code.
-
-int main() {
-  Game game{{42, 49, 23}, {10, 40, 24}, 10};
-  while (game.UserHasBudget()) {
-    try {
-      const auto change_entry = GetNextChangeEntryFromUser(game);
-      game.ChangePlayerNumberIfPossible(change_entry);
-    } catch (const std::out_of_range& e) {
-      std::cerr << e.what() << std::endl;
-    } catch (...) {
-      // 😱 Not very useful, is it?
-      std::cerr << "Oops, something happened.\n";
-    }
-  }
-  // Rest of the code.
-}
-```
-
-<img src="images/error.png.webp" alt="Something happened error" align="right" width=30% style="margin: 0.5rem">
-
-I believe that `catch(...)` and equivalent constructs are singlehandedly responsible for the absolute majority of the very unspecific and unhelpful error messages that we see all over the internet and have probably encountered ourselves multiple times.
-
-#### Exceptions are banned in many code bases
-
-All of these issues led a lot of code bases to ban exceptions altogether. In 2019, isocpp.org did a [survey](https://isocpp.org/files/papers/CppDevSurvey-2018-02-summary.pdf) on this matter and found that about half the respondents could not use exceptions at least in part of their code bases.
-
-My own experience aligns with these results - every serious project I’ve worked on either banned exceptions completely, or avoided them in performance-critical paths. But then again, I did work in robotics and automotive for the majority of my career.
-
-The problem of ensuring that using exceptions has an acceptable overhead has quite vibrant discussions around it with even calls for re-designing exceptions altogether as can be seen in this [wonderful talk by Herb Sutter](https://www.youtube.com/watch?v=ARYP83yNAWk) from CppCon 2019 as well as his [corresponding paper](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0709r4.pdf) on this topic.
-
-<!-- All of these are of course linked in description to this video. -->
-
-But until the C++ community figures out what to do, we are stuck with many people being unable to use the default error handling mechanism in C++. 🤷‍♂️
-
-So what *do* we do?
-
-## Returning errors explicitly can work better if done well
-
-It's time to return to the other option of detecting errors in functions that we hinted at before: **dealing with errors by returning a special value from a function**.
-
-I would say that there are three distinct ways of thinking about it.
-
-For some function that might fail, we can:
-
-1. Keep the return type of the function if it has any, but return a special **value** of this type in case of failure;
-2. Return an **error code** from our function to indicate success or failure;
-3. Return a **different type** specifically designed to encode failure states alongside the actual return.
-
-I believe that the third option is the best out of these three, but it will be easier to explain why I think so after we talk about why the first two are not cutting it.
-
-### Returning a value indicating error does not always work 😱
-
-There is a number of issues with returning a special value from a function without using a special return type. As an illustration, in our `GetNextChangeEntryFromUser` function, a naïve choice would be to return a value-initialized `ChangeEntry{}` object if the user provided a wrong number index. This object would essentially hold zeros for its `index` and `value` entries. However, as you might imagine, a pair of zeros *is* a completely valid, if slightly useless, change entry! How do we disambiguate this value from a valid one?
-
-<!--
-`CPP_SETUP_START`
-#include <iostream>
-#include <vector>
-
-struct ChangeEntry {
-  int index{};
-  int value{};
-};
-
-struct Game {
-  Game(std::vector<int>&& ref_numbers,
-       std::vector<int>&& player_numbers,
-       int budget);
-  void Print() const;
-  std::vector<int> player_numbers() const;
-};
-
-ChangeEntry GetNextChangeEntryFromUser(const Game& game);
-
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` error_handling/get_change_default_value.cpp
-`CPP_RUN_CMD` CWD:error_handling c++ -std=c++17 -c get_change_default_value.cpp
--->
-```cpp
-// 😱 Not a great idea!
-ChangeEntry GetNextChangeEntryFromUser(const Game& game) {
-  game.Print();
-  ChangeEntry entry{};
-  std::cout << "Please enter number to change: ";
-  std::cin >> entry.index;
-  if ((entry.index < 0) || (entry.index >= game.player_numbers().size())) {
-    return {};  // 😱 How do we know this value indicates an error?
-  }
-  std::cout << "Please provide a new value: ";
-  std::cin >> entry.value;
-  return entry;
-}
-```
-
-Many other real-world functions will face the same issues which makes this method not particularly useful in practice.
-
-### Returning an error code breaks "pure functions" 😱
-
-Returning an error code instead solves at least a couple of these issues. It is fast and reliable and we can design our software with different error codes in mind so that the reason for the failure is also communicated to us. This is also still the prevalent way of handling errors in C and in some libraries that we can find in the wild, so there *is* some merit to this method.
-
-However, if our function actually must *return* a value, which most of the functions do, the only way to use error codes is to change its return type to the type that our error codes have, like `int`, which forces us to provide an additional output parameter to our function, like `ChangeEntry& result` which we subsequently fill inside of the body of our function:
-
-<!--
-`CPP_SETUP_START`
-#include <vector>
-#include <iostream>
-
-struct ChangeEntry {
-  int index{};
-  int value{};
-};
-
-struct Game {
-  Game(std::vector<int>&& ref_numbers,
-       std::vector<int>&& player_numbers,
-       int budget);
-  void Print() const;
-  std::vector<int> player_numbers() const;
-};
-
-constexpr inline int kError = 1;
-constexpr inline int kSuccess = 0;
-
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` error_handling/get_change_error_code_full.cpp
-`CPP_RUN_CMD` CWD:error_handling c++ -std=c++17 -c get_change_error_code_full.cpp
--->
-```cpp
-// 😱 Mostly not a great idea in C++.
-int GetNextChangeEntryFromUser(const Game& game, ChangeEntry& result) {
-  game.Print();
-  std::cout << "Please enter number to change: ";
-  int index{};
-  std::cin >> index;
-  if ((index < 0) || (index >= game.player_numbers().size())) {
-    return kError;  // Usually some constant defined elsewhere.
-  }
-  result.index = index;
-  std::cout << "Please provide a new value: ";
-  std::cin >> result.value;
-  return kSuccess;  // Typically a 0, but using a constant is better.
-}
-```
-
-The main issue with this from my point of view is that it is clunky, mixes input/output parameters in the signature, and limits functional composition.
-
-Consider how we would use this function:
-
-<!--
-`CPP_SETUP_START`
-#include <iostream>
-#include <vector>
-
-constexpr inline int kError = 1;
-constexpr inline int kSuccess = 0;
-
-struct ChangeEntry {
-  int index{};
-  int value{};
-};
-
-struct Game {
-  Game(std::vector<int>&& ref_numbers,
-       std::vector<int>&& player_numbers,
-       int budget);
-  void Print() const;
-  std::vector<int> player_numbers() const;
-  void ChangePlayerNumberIfPossible(const ChangeEntry&);
-  bool UserHasBudget() const;
-};
-
-int GetNextChangeEntryFromUser(const Game&, ChangeEntry&);
-
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` error_handling/main_get_change_error_code.cpp
-`CPP_RUN_CMD` CWD:error_handling c++ -std=c++17 -c main_get_change_error_code.cpp
--->
-```cpp
-// Old code above.
-
-std::string GetFailureReason(int constant) {
-  // Some logic to return a message.
-  if (constant == kError) { return "Provided index is out of range."; }
-  return "Unknown error encountered.";
-}
-
-int main() {
-  Game game{{42, 49, 23}, {10, 40, 24}, 10};
-  while (game.UserHasBudget()) {
-    // Cannot be const, cannot use auto, has to allocate.
-    ChangeEntry change_entry{};
-    const auto error_code = GetNextChangeEntryFromUser(game, change_entry);
-    if (error_code != kSuccess) {
-      std::cerr << GetFailureReason(error_code) << std::endl;
-      continue;
-    }
-    game.ChangePlayerNumberIfPossible(change_entry);
-  }
-  // Rest of the code.
-}
-```
-
-Here, we can detect that something went wrong and, if we have some function `GetReason` that converts an error code to string, we even know *what* went wrong.
-
-But! We have to create a `ChangeEntry` object before calling the `GetNextChangeEntryFromUser` function. Furthermore this object cannot be `const`, which goes against everything we've been talking about in this series of C++ lectures until now.
-
-On top of all this, nowadays, the compilers are able to perform **R**eturn **V**alue **O**ptimization (or [RVO](https://en.cppreference.com/w/cpp/language/copy_elision.html)) for values returned from a function, essentially skipping the function call altogether, and constructing the needed value in-place. This functionality is, however, limited when using input/output parameters.
-
-So clearly, there are some issues with this method too. I believe it has its merits sometimes, but there has to be a reason for using it and we must measure the performance well.
-
-### Using `std::optional`: **a better way**
-
-I believe that there *is* a better way though. With C++17, we gained [`std::optional`](https://en.cppreference.com/w/cpp/utility/optional.html) with which we can express that a function “might return a value” by returning an object of `std::optional<ChangeEntry>` type. We can create this object either empty, holding a so-called `std::nullopt`, or from a valid `ChangeEntry`:
-
-<!--
-`CPP_SETUP_START`
-#include <iostream>
-#include <vector>
-
-constexpr inline int kError = 1;
-constexpr inline int kSuccess = 0;
-
-struct ChangeEntry {
-  int index{};
-  int value{};
-};
-
-struct Game {
-  Game(std::vector<int>&& ref_numbers,
-       std::vector<int>&& player_numbers,
-       int budget);
-  void Print() const;
-  std::vector<int> player_numbers() const;
-  void ChangePlayerNumberIfPossible(const ChangeEntry&);
-  bool UserHasBudget() const;
-};
-
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` error_handling/get_change_optional.cpp
-`CPP_RUN_CMD` CWD:error_handling c++ -std=c++17 -c get_change_optional.cpp
--->
-```cpp
-#include <optional>
-
-// Other code above.
-std::optional<ChangeEntry> GetNextChangeEntryFromUser(const Game& game) {
-  game.Print();
-  ChangeEntry entry{};
-  std::cout << "Please enter number to change: ";
-  std::cin >> entry.index;
-  if ((entry.index < 0) || (entry.index >= game.player_numbers().size())) {
-    return {};   // <-- Create an empty optional, or std:nullopt.
-  }
-  std::cout << "Please provide a new value: ";
-  std::cin >> entry.value;
-  return entry;  // <-- Optional filled with a ChangeEntry object.
-}
-```
-
-We can use our newly-returned optional object in an `if` statement to find out if it actually holds a valid change entry. If the object does not hold a value, we show an error and continue asking the user to provide better input but if the object *does* hold a value, we can get to it by calling its `value()` method or using a dereferencing operators `*` and `->`, just like we did with pointers:
-
-<!--
-`CPP_SETUP_START`
-#include <iostream>
-#include <vector>
-#include <optional>
-
-struct ChangeEntry {
-  int index{};
-  int value{};
-};
-
-struct Game {
-  Game(std::vector<int>&& ref_numbers,
-       std::vector<int>&& player_numbers,
-       int budget);
-  void Print() const;
-  std::vector<int> player_numbers() const;
-  void ChangePlayerNumberIfPossible(const ChangeEntry&);
-  bool UserHasBudget() const;
-};
-
-std::optional<ChangeEntry> GetNextChangeEntryFromUser(const Game& game);
-
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` error_handling/get_change_optional_main.cpp
-`CPP_RUN_CMD` CWD:error_handling c++ -std=c++17 -c get_change_optional_main.cpp
--->
-```cpp
-// Other code above.
-int main() {
-  Game game{{42, 49, 23}, {10, 40, 24}, 10};
-  while (game.UserHasBudget()) {
-    const auto change_entry = GetNextChangeEntryFromUser(game);
-    if (!change_entry) {  // Also possible: change_entry.has_value().
-      std::cerr << "Error when getting a number index." << std::endl;
-      continue;
-    }
-    game.ChangePlayerNumberIfPossible(change_entry.value());
-  }
-  // Rest of the code.
-}
-```
-
-The presence or absence of a value is encoded into the type itself. No more guessing. No more relying on magic return values or input/output arguments. And the code is very short and neat! And, as always, we can always find more information about how to use `std::optional` at [cppreference.com](https://en.cppreference.com/w/cpp/utility/optional.html).
-
-But, we've again lost a capability of knowing *what* went wrong. We just know that *something* has not gone to plan. There is simply no place to store the reason!
-
-But we are still interested in a reason for our failures!
-
-### Using `std::expected`: **add context**
-
-Enter [`std::expected`](https://en.cppreference.com/w/cpp/utility/expected.html), coming in C++23. And if you'd like to hear somebody more entertaining than myself talk about why we have it, watch this [fantastic talk by Andrei Alexandrescu](https://www.youtube.com/watch?v=PH4WBuE1BHI)! It is one of my favorite talks ever! It is both informative and entertaining in an equal measure!
-
-Anyway, with `std::expected` we could do the same things we could do with `std::optional` and more by changing our function accordingly:
-
-<!--
-`CPP_SETUP_START`
-#include <iostream>
-#include <vector>
-
-struct ChangeEntry {
-  int index{};
-  int value{};
-};
-
-struct Game {
-  Game(std::vector<int>&& ref_numbers,
-       std::vector<int>&& player_numbers,
-       int budget);
-  void Print() const;
-  std::vector<int> player_numbers() const;
-  void ChangePlayerNumberIfPossible(const ChangeEntry&);
-  bool UserHasBudget() const;
-};
-
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` error_handling/get_change_expected.cpp
-`CPP_RUN_CMD` CWD:error_handling c++ -std=c++23 -c get_change_expected.cpp
--->
-```cpp
-#include <expected>
-#include <format>
-
-// Other code above.
-std::expected<ChangeEntry, std::string> GetNextChangeEntryFromUser(const Game& game) {
-  game.Print();
-  ChangeEntry entry{};
-  std::cout << "Please enter number to change: ";
-  std::cin >> entry.index;
-  if ((entry.index < 0) || (entry.index >= game.player_numbers().size())) {
-    return std::unexpected(
-      std::format("Index {} must be in [0, {}) interval",
-                  entry.index, game.player_numbers().size()));
-  }
-  std::cout << "Please provide a new value: ";
-  std::cin >> entry.value;
-  return entry;
-}
-```
-
-Essentially, `std::expected` holds one of two values that have two potentially different types - an expected (`ChangeEntry` in our case) or an unexpected one (`std::string` in our tiny example). Now we can return either a valid result, *or* an error message.
-
-Using it is also quite neat and is actually very similar to how we used the `std::optional`, the only difference is that we can now get the `error` from the object we return from `GetNextChangeEntryFromUser` if it holds one:
-
-<!--
-`CPP_SETUP_START`
-#include <iostream>
-#include <expected>
-#include <vector>
-
-struct ChangeEntry {
-  int index{};
-  int value{};
-};
-
-struct Game {
-  Game(std::vector<int>&& ref_numbers,
-       std::vector<int>&& player_numbers,
-       int budget);
-  void Print() const;
-  std::vector<int> player_numbers() const;
-  void ChangePlayerNumberIfPossible(const ChangeEntry&);
-  bool UserHasBudget() const;
-};
-
-std::expected<ChangeEntry, std::string> GetNextChangeEntryFromUser(const Game& game);
-
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` error_handling/get_change_expected_main.cpp
-`CPP_RUN_CMD` CWD:error_handling c++ -std=c++23 -c get_change_expected_main.cpp
--->
-```cpp
-// Other code above.
-int main() {
-  Game game{{42, 49, 23}, {10, 40, 24}, 10};
-  while (game.UserHasBudget()) {
-    const auto change_entry = GetNextChangeEntryFromUser(game);
-    if (!change_entry) {  // Also possible: change_entry.has_value().
-      std::cerr << change_entry.error() << std::endl;
-      continue;
-    }
-    game.ChangePlayerNumberIfPossible(change_entry.value());
-  }
-  // Rest of the code.
-}
-```
-
-This has all the benefits we mentioned before:
-
-- The signature of our function clearly states that it might fail
-- The error if it happens needs to be dealt with explicitly by the caller
-- Everything happens in deterministic time with no unpredictable runtime overhead
-- Works for functions returning `void` too
-
-There is just one tiny issue that spoils our fun. As you've probably noticed, most of the things we covered until now in this C++ course targeted C++17 as a recent-enough but also widely-enough-used standard. Unfortunately `std::expected` is only available from C++23 on. But there is a solution to this: we can use and open-source [`tl::expected`](https://github.com/TartanLlama/expected) as a drop-in replacement for code bases that don't yet adopt C++23.
-
-## Performance Considerations for `std::optional` and `std::expected`
-
-One final thing I want to talk about is performance considerations when using `std::optional` and `std::expected`.
-
-### Error type size matters
-
-Both `std::optional` and `std::expected` are implemented using [`union`](https://en.cppreference.com/w/cpp/language/union.html)-like storage internally—meaning the value and error **share** memory, with the bigger type defining the amount of memory allocated. Note that we should not use `union` directly in our code, but a number of standard classes, like `std::expected`, `std::optional`, or `std::variant` (that we'll talk about soon) use it under the hood.
-
-In the case of `std::optional` this does not play much of a difference, as the "error" type is a tiny `std::nullopt_t` type but for `std::expected`, the error type affects the size of the object—even when we’re returning a success.
-
-So this is something to avoid:
-
-<!--
-`CPP_SETUP_START`
-#include <expected>
-
-using HugeErrorObject = int;
-
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` error_handling/expected_bad.cpp
-`CPP_RUN_CMD` CWD:error_handling c++ -std=c++23 -c expected_bad.cpp
--->
-```cpp
-// Bad idea, wasting memory 😱
-std::expected<int, HugeErrorObject> SomeFunction();
-```
-
-If we do this, every return now has the size of the larger type. So let's not!
-
-Mostly I've seen people using `std::error_code`, `std::string` or custom enums as an error type in `std::expected`. All of these are relatively efficient and have a small stack memory footprint. If the code base you work in already has a rule for what types to use as error types in `std::expected` - follow it, otherwise, experiment with the options I just mentioned and find one that works best for your current circumstances.
-
-### Return value optimization with `std::optional` and `std::expected`
-
-There is also one quirk with how `std::optional` and `std::expected` types interact with the return value optimization (RVO) and named return value optimization (NRVO) which makes all the nice examples that we've just seen a little less nice.
-
-These topics are quite nuanced, and I don't want to go into many details here but in case we care about the performance of our code that uses `std::optional` or `std::expected` we'll have to uglify our code a little bit. For more details, see this [short video by Jason Turner](https://www.youtube.com/watch?v=0yJk5yfdih0) where he covers all of these situations in-depth.
-
-## Summary
-
-I believe that this concludes a more of less complete overview of how to deal (and how *not* to deal) with errors in modern C++.
-
-As a short summary, I hope that I could convince you that these are some sane suggestions (that can also be found in the [final example](code/error_handling/comparison_game/comparison_game_expected.cpp)):
-
-- Use `CHECK` and similar macros for dealing with unrecoverable errors like programming bugs or contract violations in order to fail as fast as possible when they are encountered;
-- Keep the test coverage of the code high to reduce chances of crashing in the released code;
-- Use `std::optional` as a return type when a value might be missing due to a recoverable error and the reason for the failure is not important;
-- Use `std::expected` for functions that return `void` but still can fail and when a reason for failure *is* needed to be able to recover from it;
-- Avoid exceptions in time-critical or safety-critical systems due to their non-deterministic runtime overhead;
-- Avoid old error handling mechanisms like returning error codes when possible.
-
-All in all, the overall direction that we seem to be following as a community is to make failure explicit and force the caller to handle it as close to the call site as possible or explicitly propagate it further. This leads to clearer, safer, and more maintainable code.
-
-## Other use of `std::optional`
-
-One final thing I wanted to add has nothing to do with error handling but as we talked about `std::optional` it seems relevant.
-
-Obviously, the `std::optional` class can be used also in other places, not just as a return type from a function. If some object of ours must have an optional value, using `std::optional` can be a good idea there too! But I'm sure you're going to be able to figure this out from the related [cppreference page](https://en.cppreference.com/w/cpp/utility/optional.html) on your own 😉.
-
-<!-- Now *this* is the end of our today's lecture! Thanks for watching everyone! If you find these videos useful, just let them play fully through to the end so that YouTube shows them to more people! And maybe watch one of these other videos of mine once you're at it? As we spoke about how important test coverage is, sounds like *this* video on how to set up GoogleTest framework with CMake might come in handy! Or, in case you'd like to refresh how dynamic polymorphism works and why it takes time at runtime then please click on *this* video instead!
-
-See you in the next one! Bye! -->
diff --git a/lectures/forwarding_references.md b/lectures/forwarding_references.md
deleted file mode 100644
index 0f26795..0000000
--- a/lectures/forwarding_references.md
+++ /dev/null
@@ -1,591 +0,0 @@
-**Forwarding references in modern C++**
-
-----
-
-<p align="center">
-  <a href="https://youtu.be/RW9KnqszYj4"><img src="https://img.youtube.com/vi/RW9KnqszYj4/maxresdefault.jpg" alt="Video" align="right" width=50% style="margin: 0.5rem"></a>
-</p>
-
-- [The forwarding reference](#the-forwarding-reference)
-- [Why use forwarding references](#why-use-forwarding-references)
-  - [Example setup](#example-setup)
-  - [How forwarding references simplify things](#how-forwarding-references-simplify-things)
-  - [When to prefer forwarding references](#when-to-prefer-forwarding-references)
-- [How forwarding references work](#how-forwarding-references-work)
-  - [Reference collapsing](#reference-collapsing)
-  - [Remove reference using `std::remove_reference_t`](#remove-reference-using-stdremove_reference_t)
-  - [How `std::forward` works](#how-stdforward-works)
-    - [Passing an lvalue](#passing-an-lvalue)
-    - [Passing by rvalue](#passing-by-rvalue)
-- [Summary](#summary)
-
-
-By now we already know what move semantics is. We have even essentially [reinvented](move_semantics.md) it from scratch in one of the previous lectures. So we should be quite comfortable seeing functions (be it part of a class or not) that look like this:
-<!--
-`CPP_SETUP_START`
-struct SomeType{};
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` forwarding_refs_do_smth/do_smth.cpp
-`CPP_RUN_CMD` CWD:forwarding_refs_do_smth c++ -std=c++17 -c do_smth.cpp
--->
-```cpp
-void DoSmth(SomeType&& value);
-```
-These function usually have something to do with the ownership of the parameters they receive by an rvalue reference.
-
-Well, now that we also talked about templates, there is one more thing we need to talk about. And it is a bit confusing at the first glance.
-
-🚨 You see if we add a template into the mix, `value` is **not really an rvalue reference** anymore:
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` forwarding_refs_do_smth/forward_do_smth_def.cpp
-`CPP_RUN_CMD` CWD:forwarding_refs_do_smth c++ -std=c++17 -c forward_do_smth_def.cpp
--->
-```cpp
-template <class SomeType>
-void DoSmth(SomeType&& value);
-```
-
-<!-- Intro -->
-
-## The forwarding reference
-Ok, to spend you the suspense, the `value` in this example of ours is called a **"forwarding reference"** and it is usually used in combination with `std::forward` (don't worry, we'll unpack what we see here a bit later):
-<!--
-`CPP_SETUP_START`
-struct SomeType{};
-void DoSmthElse(SomeType&&);
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` forwarding_refs_do_smth/forward_do_smth.cpp
-`CPP_RUN_CMD` CWD:forwarding_refs_do_smth c++ -std=c++17 -c forward_do_smth.cpp
--->
-```cpp
-#include <utility>
-
-template <class SomeType>
-void DoSmth(SomeType&& value) {
-  DoSmthElse(std::forward<SomeType>(value));
-}
-```
-
-More formally, to quote [cppreference.com](https://en.cppreference.com/w/cpp/language/reference#Forwarding_references):
-> Forwarding reference is a function parameter of a function template declared as rvalue reference to cv-unqualified type template parameter of that same function template.
-
-Sometimes you will also hear people calling it a "universal reference", a term [coined by Scott Meyers](https://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers), but I prefer the **"forwarding reference"** name as it is the one used in the standard today. If you want to learn more about it, please feel free to read [Arthur O'Dwyer's post](https://quuxplusone.github.io/blog/2022/02/02/look-what-they-need/) about this, he described it all much better than I ever could!
-
-## Why use forwarding references
-Anyway, in the spirit of this course, before we go into talking about **how** a forwarding reference works, I really want to talk a bit about **why** it exists and what we might want to use it for.
-
-Long story short, just like normal rvalue references, I see forwarding references exclusively in the sense of ownership transfer. However, where a standard rvalue reference is designed to **always** transfer the ownership, a forwarding reference is designed for very generic contexts where it can **decide** if the ownership can be transferred based on the types of the input parameters.
-
-I realize that this statement might feel too general, so let's illustrate what I mean using small concrete examples. As always, our examples are going to be very simple, but illustrative of the concept at hand.
-
-### Example setup
-For simplicity, let us say that we have a class `Container` that owns some `Data` and has a simple method `Put` that accepts a `const` reference to new `Data` to be put into it:
-
-`container.hpp`
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` forwarding_refs/container.hpp
--->
-```cpp
-#include "data.hpp"
-
-class Container {
-   public:
-    void Put(const Data& data) { data_ = data; }
-
-   private:
-    Data data_{};
-};
-```
-
-Our `Data` class is going to be a very simple `struct` that is able to print from its copy and move assignment operators:
-
-`data.hpp`
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` forwarding_refs/data.hpp
--->
-```cpp
-#include <iostream>
-
-// 😱 Missing other special class methods!
-struct Data {
-    Data& operator=(const Data& other) {
-        std::cout << "Copy assignment" << std::endl;
-        return *this;
-    }
-
-    Data& operator=(Data&& other) {
-        std::cout << "Move assignment" << std::endl;
-        return *this;
-    }
-};
-```
-Note that to keep the code to the minimum, I omit the rest of the special functions in this struct, specifically a copy and move constructors as well as the destructor, please see the [rule of "all or nothing"](all_or_nothing.md) lecture to make sure we're on the same page why it is important to have all of those special functions. This is not too important is this particular example as we don't work with any memory or resources, but it is good to keep this knowledge up to date for the cases when we do.
-
-Finally, in the `main` function, we create an instance of `Data` and pass it into our container:
-
-`main.cpp`
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` forwarding_refs/main.cpp
-`CPP_RUN_CMD` CWD:forwarding_refs c++ -std=c++17 main.cpp
--->
-```cpp
-#include "container.hpp"
-
-int main() {
-    Container container{};
-    Data data{};
-    container.Put(data);
-}
-```
-If we compile and run this code we will get the output `Copy assignment` which indicates that the data is copied into our container, just as we expect.
-
-Now let's say we don't want to create a `Data` instance in our `main` function and want to pass a temporary object to be owned by our `Container`. We can modify our `main` function every so slightly to achieve this:
-
-`main.cpp`
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` forwarding_refs/main_temp.cpp
-`CPP_RUN_CMD` CWD:forwarding_refs c++ -std=c++17 main_temp.cpp
--->
-```cpp
-#include "container.hpp"
-
-int main() {
-    Container container{};
-    container.Put(Data{});
-}
-```
-However, if we compile and run _this_ code we get the same output that indicates that copy assignment operator was called again. Not exactly what we want!
-
-The reason for this is, of course, the fact that the `Put` method of our `Container` class only accepts a `const` reference to `Data`. By design a `const` reference binds to anything, so a temporary `Data` object is created, it gets bound to a `const` reference when passed into the `Put` function and its lifetime is extended for the duration of the execution of this function. Then because `data` is a `const` reference, its copy assignment operator is called to copy itself into the private `data_` field of our `Container` object.
-
-Now, as copying might be expensive for large objects, we might want to avoid it, so we can force the temporary `Data` object to be moved into our container instead by overloading the `Put` method for an rvalue reference:
-
-`container.hpp`
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` forwarding_refs/container.hpp
--->
-```cpp
-#include "data.hpp"
-
-#include <utility>
-
-class Container {
-   public:
-    void Put(const Data& data) { data_ = data; }
-
-    void Put(Data&& data) { data_ = std::move(data); }
-
-   private:
-    Data data_{};
-};
-```
-If this, or the fact that we have to use `std::move` on `data` here is confusing, do give the lecture about [reinventing move semantics](move_semantics.md) another go, I go in pretty detailed explanations about everything relevant to this there.
-
-Anyway, this does the trick and now we can have both behaviors if we need them in our `main` function:
-
-`main.cpp`
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` forwarding_refs/main_both.cpp
-`CPP_RUN_CMD` CWD:forwarding_refs c++ -std=c++17 main_both.cpp
--->
-```cpp
-#include "container.hpp"
-
-int main() {
-    Container container{};
-    Data data{};
-    container.Put(data);
-    container.Put(Data{});
-}
-```
-Passing the `data` variable will actually copy the data into our container, while passing a temporary will move this temporary into the container without performing a copy.
-
-### How forwarding references simplify things
-So far we haven't really learnt anything new, have we? This is all just using the knowledge about move semantics and [function overloading](functions.md#function-overloading---writing-functions-with-the-same-names) from before. But it _is_ a necessary setup to understand **why** we might want to use forwarding references in the first place.
-
-In this simple case, we needed two function overloads to achieve the behavior that we wanted. Using forwarding references we only need one function instead. Let us modify our `Container` class to use forwarding references instead!
-
-For this, we remove the `Put` function that takes a `const` reference and make the remaining `Put` function, one that takes an rvalue reference, a function template. We then also use the template parameter `T` instead of the `Data` type in this function. Finally, we replace `std::move` with `std::forward<T>` and we have a fully functioning forwarding reference setup:
-
-`container.hpp`
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` forwarding_refs/container.hpp
-`CPP_RUN_CMD` CWD:forwarding_refs c++ -std=c++17 main_both.cpp
--->
-```cpp
-#include "data.hpp"
-
-#include <utility>
-
-class Container {
-   public:
-    template <typename T>
-    void Put(T&& data) { data_ = std::forward<T>(data); }
-
-   private:
-    Data data_{};
-};
-```
-If we compile and run this code we will still get exactly the behavior that we want: the `data` object gets copied into our container, while the temporary `Data` gets moved. So the forwarding references, and `std::forward` by extension allow us to auto-magically select if we want to copy or move an object based on the provided argument type. How neat is this?
-
-
-### When to prefer forwarding references
-So I hope it makes sense what forwarding references allow us to achieve. But it comes at a cost! We now have a `template` in the game, which means that we can now try to provide a wrong type, say `int` into our `Put` function:
-<!--
-`CPP_SKIP_SNIPPET`
--->
-```cpp
-#include "container.hpp"
-
-int main() {
-    Container container{};
-    container.Put(42);
-}
-```
-Which would lead to a nice compilation error of course that would tell us something about not being able to convert between `int` and an rvalue reference to `Data`:
-```css
-<source>: In instantiation of 'void Container::Put(DataT&&) [with DataT = int]':
-<source>:31:18:   required from here
-   31 |     container.Put(42);
-      |     ~~~~~~~~~~~~~^~~~
-<source>:19:15: error: no match for 'operator=' (operand types are 'Data' and 'int')
-   19 |         data_ = std::forward<DataT>(data);
-      |         ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
-<source>:4:11: note: candidate: 'Data& Data::operator=(const Data&)'
-    4 |     Data& operator=(const Data& other) {
-      |           ^~~~~~~~
-<source>:4:33: note:   no known conversion for argument 1 from 'int' to 'const Data&'
-    4 |     Data& operator=(const Data& other) {
-      |                     ~~~~~~~~~~~~^~~~~
-<source>:9:11: note: candidate: 'Data& Data::operator=(Data&&)'
-    9 |     Data& operator=(Data&& other) {
-      |           ^~~~~~~~
-<source>:9:28: note:   no known conversion for argument 1 from 'int' to 'Data&&'
-    9 |     Data& operator=(Data&& other) {
-      |                     ~~~~~~~^~~~~
-```
-And while we _can_ mitigate this and improve the error message by using traits or concepts, which we already talked about before when we talked about [how to use templates with classes](templates_how_classes.md), it still complicates the code quite a bit. So is it really worth it?
-
-I would argue that in the situations like the one in our example, I would _not_ use forwarding references and would just add the two overloads for the `const` reference and the rvalue reference instead. The reason being arguably better readability and the fact that in some cases the compiler will actually generate more code if we use a forwarding reference as opposed to explicit overloads in this case. This is, though, very close to being just a personal preference.
-
-The situation changes, however, should we have more function parameters to think about. To illustrate what I'm talking about, let us modify our `Container` class a bit by adding another `Data` entry to it:
-
-`container.hpp`
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` forwarding_refs/container.hpp
--->
-```cpp
-#include "data.hpp"
-
-#include <utility>
-
-class Container {
-   public:
-    template <typename T, typename S>
-    void Put(T&& data_1, S&& data_2) {
-      data_1_ = std::forward<T>(data_1);
-      data_2_ = std::forward<S>(data_2);
-    }
-
-   private:
-    Data data_1_{};
-    Data data_2_{};
-};
-```
-Note what changed here. We now have two objects to store. Here, both `data_1_` and `data_2_` have the same type, but they could of course be of different types. The `Put` function now accepts two template arguments `T` and `S` as well as two forwarding references as its function arguments: `data_1` and `data_2`.
-
-Now, what happens if we pass various combination of lvalue and rvalue references to `Data` into our `Put` function?
-
-`main.cpp`
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` forwarding_refs/main_two_params.cpp
-`CPP_RUN_CMD` CWD:forwarding_refs c++ -std=c++17 main_two_params.cpp
--->
-```cpp
-#include "container.hpp"
-
-int main() {
-    Container container{};
-    Data data{};
-    container.Put(data, Data{});
-    std::cout << "-----" << std::endl;
-    container.Put(Data{}, data);
-    std::cout << "-----" << std::endl;
-    container.Put(Data{}, std::move(data));
-}
-```
-I'll let you figure out the actual output from this code on your own.
-<!-- And please post in the comments what you think this code will print and why! -->
-
-But the main thing is that in all of these cases the `Put` function will do what we want. It will move the data it can move and copy the data it cannot. And by now, if we look at our new `Put` function long enough and think about how to write the same functionality without the forwarding references, we might start understanding where exactly the forwarding references are useful. Let's see how we would write our `Put` functions without using forwarding references, shall we?
-
-`container.hpp`
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` forwarding_refs/container.hpp
-`CPP_RUN_CMD` CWD:forwarding_refs c++ -std=c++17 main_two_params.cpp
--->
-```cpp
-#include "data.hpp"
-
-#include <utility>
-
-class Container {
-   public:
-    void Put(Data&& data_1, Data&& data_2) {
-      data_1_ = std::move(data_1);
-      data_2_ = std::move(data_2);
-    }
-    void Put(const Data& data_1, Data&& data_2) {
-      data_1_ = data_1;
-      data_2_ = std::move(data_2);
-    }
-    void Put(Data&& data_1, const Data& data_2) {
-      data_1_ = std::move(data_1);
-      data_2_ = data_2;
-    }
-    void Put(const Data& data_1, const Data& data_2) {
-      data_1_ = data_1;
-      data_2_ = data_2;
-    }
-
-   private:
-    Data data_1_{};
-    Data data_2_{};
-};
-```
-To achieve the same performance, we need to have an explicit overload for every combination of lvalue and rvalue references that is possible for our function parameters. Which means that we now need 4 different functions! And you can imagine now what would happen if we would have even more parameters. We didn't really talk about it just yet, but we can pass _any_ number of template parameters into a function, using variadic templates, where using forwarding references is really our only way to write the code that will behave efficiently for any input parameters.
-
-So, if you ask me, this is the reason why forwarding references really exist in the language. And this also warrants a rule of thumb of when they should be used.
-
-🚨 Slightly controversially, I would recommend to only use forwarding references when we **really know what we're doing** in very generic contexts. When we have many function parameters of different types to think of and when these said parameters might be copied or moved if their type allows for it.
-
-## How forwarding references work
-Now that we know why we might want to use forwarding references and what they allow us to achieve, I think it is important to also talk about **how** this is done. What is the magic behind a forwarding reference being able to figure out what to do given the argument type?
-
-And of course, this is not magic, but just clever engineering!
-Here, I'm planning to go quite deep into details, but we should be able to follow each step of the way with the knowledge we gained until this point in this course. 🤞
-
-### Reference collapsing
-In order to understand what happens there, we need to take a short detour through [reference collapsing](https://en.cppreference.com/w/cpp/language/reference#Reference_collapsing). This happens when we use type aliases to reference types and then use references with these type aliases. This basically leads us to effectively have many `&`s stacked together! So we need to map an arbitrary amount of `&`s onto the references that we know how to work with, the lvalue reference denoted by `&` and an rvalue reference denoted by `&&`. And the rule for reference collapsing is quite simple:
-
-🚨 **Rvalue reference to rvalue reference collapses to rvalue reference, all other combinations form lvalue references:**
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` ref_collapsing/main.cpp
-`CPP_RUN_CMD` CWD:ref_collapsing c++ -std=c++17 -c main.cpp
--->
-```cpp
-#include <type_traits>
-
-using lref = int&;
-using rref = int&&;
-
-static_assert(std::is_same_v<lref, int&>);
-static_assert(std::is_same_v<rref, int&&>);
-
-static_assert(std::is_same_v<lref&, int&>);
-static_assert(std::is_same_v<lref&&, int&>);
-
-static_assert(std::is_same_v<rref&, int&>);
-static_assert(std::is_same_v<rref&&, int&&>);
-```
-These `static_assert`s here check if the conditions in them are `true` at compile time. In our case, we use the trait alias [`std::is_same_v`](https://en.cppreference.com/w/cpp/types/is_same) to check if the provided types are the same. It doesn't really matter how `std::is_same_v` is implemented here as long as you trust me that it returns `true` if the types are the same :wink:
-
-That being said, after following the lecture on [how to write class templates](templates_how_classes.md) as well as the one on [how to use `static` with classes](static_in_classes.md) you should be able to implement such a trait on your own!
-<!-- Please comment below on how you would do it! And please like this video and subscribe to my channel if you got any value out of it for yourself -->
-
-### Remove reference using `std::remove_reference_t`
-Continuing with the topic of playing with references and type traits, we can design a type trait to remove reference from a provided type completely. Such a trait is implemented as [`std::remove_reference_t`](https://en.cppreference.com/w/cpp/types/remove_reference) in the C++ standard library.
-
-We can now see how it works using the `static_assert`s again:
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` remove_reference/main.cpp
-`CPP_RUN_CMD` CWD:remove_reference c++ -std=c++17 -c main.cpp
--->
-```cpp
-#include <type_traits>
-
-static_assert(std::is_same_v<std::remove_reference_t<int>, int>);
-static_assert(std::is_same_v<std::remove_reference_t<int&>, int>);
-static_assert(std::is_same_v<std::remove_reference_t<int&&>, int>);
-```
-Basically, passing any reference type through the `std::remove_reference_t` trait alias will produce the actual type behind the reference.
-
-
-### How `std::forward` works
-Armed with this knowledge let us have a precise look at `std::forward` and implement our own version of it to understand what happens under the hood better. For this, we need two overloads of our function template `forward`, one that takes an lvalue reference and one that takes an rvalue reference:
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` forward/forward.hpp
--->
-```cpp
-#include <type_traits>
-
-template <class T>
-T&& forward(std::remove_reference_t<T>& t) { return static_cast<T&&>(t); }
-
-template <class T>
-T&& forward(std::remove_reference_t<T>&& t) { return static_cast<T&&>(t); }
-```
-Both overloads don't use their template type parameter directly to specify the type of their input parameter, but pass it through the `std::remove_reference_t` trait that removes any kind of reference from its input template parameter. The function then always returns the input parameter cast to an rvalue of the template type parameter `T`, or `T&&` type. This difference of the input parameter type and the return type in combination with reference collapsing that we have just discussed is what makes the magic work!
-
-To see it in detail, let us illustrate what happens when we pass arguments of various types into our `forward` function using the forwarding reference:
-<!--
-`CPP_SETUP_START`
-#include "forward.hpp"
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` forward/do_smth.hpp
--->
-```cpp
-#include <iostream>
-#include <utility>
-
-void Print(int&) { std::cout << "lvalue" << std::endl; }
-void Print(int&&) { std::cout << "rvalue" << std::endl; }
-
-template <class SomeType>
-void DoSmth(SomeType&& value) {
-  // 💡 Using our custom forward here, but std::forward works the same.
-  Print(forward<SomeType>(value));
-}
-```
-Here, we will use a simple `Print` function overloaded for lvalue and rvalue references to `int` to show what happens. We then pass a number arguments into our `DoSmth` function from `main`.
-
-#### Passing an lvalue
-We can observe, that passing a variable `number` as an argument prints `lvalue`, which is what we expect. So let's dig in and understand exactly why it works.
-<!--
-`CPP_SETUP_START`
-#include "do_smth.hpp"
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` forward/main_lvalue.cpp
-`CPP_RUN_CMD` CWD:forward c++ -std=c++17 main_lvalue.cpp
--->
-```cpp
-int main() {
-  int number{};
-  DoSmth(number);
-}
-```
-
-1. When we pass `number` to `DoSmth`, the compiler needs to make sure that our forwarding reference type `SomeType&&` matches our de-facto input type, an lvalue reference to int: `int&`
-2. A way to make this happen is to deduce `SomeType` to be `int&` using the reference collapsing rules as then `SomeType&&` is `int& &&` which collapses to `int&`, which matches the de-factor input parameter.
-3. This leads `value` to have the type `int& &&`, or, as we've just discussed `int&`
-4. Given all of this, our call to `forward<SomeType>(value)` ends up being a call to `forward<int&>(int&)`, making the `T` type in the `forward` function be `int&` and choosing the first overload because `std::remove_reference_t<int&>` is just `int`, so the first overload takes `int&`.
-5. We then return `T&&` from the `forward` function, which means that we return `int& &&`, which again collapses to `int&`.
-6. Which means that we get an lvalue reference out of our `forward` function, and the compiler picks the first overload of our `Print` function and prints `lvalue`.
-
-
-#### Passing by rvalue
-Now let's do the same exercise for the situation when we pass an rvalue into the `DoSmth` function. We can see that the code prints `rvalue` for both situations when we pass a temporary and when we `std::move` from an lvalue. So let's dive into what happens here too.
-<!--
-`CPP_SETUP_START`
-#include "do_smth.hpp"
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` forward/main_rvalue.cpp
-`CPP_RUN_CMD` CWD:forward c++ -std=c++17 main_rvalue.cpp
--->
-```cpp
-int main() {
-  int number{};
-  DoSmth(42);
-  DoSmth(std::move(number));
-}
-```
-1. The compiler needs to make sure that `SomeType&&` matches the input type `int&&`
-2. So it trivially deduces `SomeType` to be `int`
-3. Which leaves `value` to have type `int&&`.
-4. Now, when we call `forward<int>(value)`, the `T` type in our `forward` function will be `int`, the `remove_reference_t<int>` in the `forward` function will collapse to a simple `int` type and, considering that `value` has type `int&&`, we might expect that a *second* overload would be called. But in reality, the **first overload will be picked!** We have to remember that `value` here **has a name and an address in memory** which makes it an **lvalue** that stores an rvalue reference! So it binds to the first `forward` overload. If this is confusing, which I admit it _is_ a little bit, please have another look at the [lecture where we reinvent move semantics](move_semantics.md) to learn why it was designed the way it was designed.
-5. Despite getting an lvalue reference as a parameter to our `forward` function we return this value as the `T&&` type, or `int&&` in our case. So in the end, we still convert our value to an rvalue reference and return it as such!
-6. This, in turn, leads us to picking the `Print(int&&)` overload and printing `rvalue` to the terminal.
-
-It might be a bit too quick to follow, so as usual, you can play with these examples yourself at your own pace by following the link to [cppinsights.io](https://cppinsights.io/s/e48f0dba)
-<!-- that you can find in the description to this video. -->
-
-But I'm afraid there is still one more thing to discuss, though. You might be still wondering: when is that second overload called? And really, the only case I can think of is when we directly call the `forward` function with a real rvalue - either providing a temporary object or an lvalue that we explicitly mark as an xvalue with `std::move`:
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` forward_overload/main.cpp
-`CPP_RUN_CMD` CWD:forward_overload c++ -std=c++17 main.cpp
--->
-```cpp
-#include <type_traits>
-#include <utility>
-
-template <class T>
-T&& forward(std::remove_reference_t<T>& t) {
-  return static_cast<T&&>(t);
-}
-
-template <class T>
-T&& forward(std::remove_reference_t<T>&& t) {
-  return static_cast<T&&>(t);
-}
-
-int main() {
-  // We can also use std::forward here of course.
-  forward<int>(42);
-  int number{};
-  forward<int>(std::move(number));
-}
-```
-I'll leave it up to you to figure out exactly why the second overload is called in both cases here but if something is not clear, please ask questions!
-
-And now I guess we've covered pretty much all there is to how forwarding references work in conjunction with `std::forward`! I know it was quite a lot, but if we are comfortable with this, it is a good indicator that we are comfortable with a lot of key mechanisms used in C++.
-
-## Summary
-With this we should be well equipped to detect when we see a forwarding reference used in the code.
-
-Not only that but we should also leave with an intuition that it makes sense to use forwarding references if we have many function parameters of many template type parameters that can be either copied or moved depending on the reference type used.
-
-Finally, we even dove deep into how it all works, how the compiler picks which types to deduce and which overloads to pick.
-
-Hope this makes your journey towards understanding how to work with templates in C++ easier and that you enjoyed this explanation of mine.
-
-<!-- Finally, if you feel that one or another concept don't fully make sense just yet, please give the appropriate videos on my channel a re-watch. So why not catch up on what move semantics is and maybe even reinvent it with me? For that please click on the video here. Otherwise, if you'd like to watch the series on why and how to use templates, then do give this video a click instead. Thanks a lot for watching and see you next time! Bye! -->
diff --git a/lectures/functions.md b/lectures/functions.md
deleted file mode 100644
index a4dbcd3..0000000
--- a/lectures/functions.md
+++ /dev/null
@@ -1,421 +0,0 @@
----
-marp: true
-math: katex
-theme: custom-theme
-paginate: true
-# footer: ![width:80px](images/C++ForYourselfIcon.png)
----
-
-# Functions introduction
-
-#### Today:
-- What is a function
-- Declaration and definition
-- Passing by reference
-- Overloading
-- Using default arguments
-
-### 📺 Watch the related [YouTube video](https://youtu.be/RaSw0g2aPig)!
-
----
-# Special symbols used in slides
-- 🎨 - Style recommendation
-- 🎓 - Software design recommendation
-- 😱 - **Not** a good practice! Avoid in real life!
-- ✅ - Good practice!
-- ❌ - Whatever is marked with this is wrong
-- 🚨 - Alert! Important information!
-- 💡 - Hint or a useful exercise
-- 🔼1️⃣7️⃣ - Holds for this version of C++(here, `17`) and **above**
-- 🔽1️⃣1️⃣ - Holds for versions **until** this one C++(here, `11`)
-
-Style (🎨) and software design (🎓) recommendations mostly come from [Google Style Sheet](https://google.github.io/styleguide/cppguide.html) and the [CppCoreGuidelines](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines)
-
----
-# Function help organize the code
-- Functions look smth like this:
-  <!--
-  `CPP_SETUP_START`
-  using ReturnType = int;
-  using ParamType1 = int;
-  using ParamType2 = int;
-  constexpr auto return_value{42};
-  $PLACEHOLDER
-  int main() {
-    return 0;
-  }
-  `CPP_SETUP_END`
-  -->
-  ```cpp
-  ReturnType DoSmth(ParamType1 in_1, ParamType2 in_2) {
-    // Some awesome code here.
-    return return_value;
-  }
-  ```
-- We can then call such a function as follows:
-  <!--
-  `CPP_SETUP_START`
-  constexpr auto param1{42};
-  constexpr auto param2{42};
-  int DoSmth(int a, int b) {return a+b;}
-  int main() {
-    $PLACEHOLDER
-    return 0;
-  }
-  `CPP_SETUP_END`
-  -->
-  ```cpp
-  const auto smth = DoSmth(param1, param2);
-  ```
-- Functions **split** execution into logical chunks
-- They **bundle common functionality** together
-- They also keep the overall project code **readable**
-- 🎓 You might have heard about the [**DRY**](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself) principle:
-  - Stands for **D**on't **R**epeate **Y**ourself
-  - Impossible without functions in C++
----
-# Some technical details
-- Functions **create a [scope](cpp_basic_types_and_variables.md#all-variables-live-in-scopes)**
-- A function is fully defined by:
-  - Its name
-  - Its return type
-  - Its parameter types
-  - Qualifiers (more on this later)
-- There is a **single return value** from a function
-- There can be multiple `return` statements in a function
-- The function stops when a `return` statement is reached
-- If the return type is `void` --- no explicit `return` required
-
----
-# How to write good functions
-- 🎓🚨 [**Write short functions**](https://google.github.io/styleguide/cppguide.html#Write_Short_Functions) --- they must do **one thing only**
-- :bulb: If your function has too many parameters, think if it does too much! You might want to split it into multiple functions!
-- 🎨 Function name should describe an action
-- 🎨 Name must clearly state **what the function does**
-- 🎨 Name functions in `CamelCase`
-- 🎨 Use `snake_case` for all function arguments
-
-
----
-# ✅ Use `[[nodiscard]]` attribute
-- 🔼1️⃣7️⃣ You can use it like this:
-  ```cpp
-  [[nodiscard]] double SquareNumber(double input) {
-    return input * input;
-  }
-  int main() { SquareNumber(42.0); }  // ❌ generates warning
-  ```
-- Forces the output of the function to actually be used
-- When we compile the above we get:
-  ```css
-  λ › c++ -std=c++17 -O3 -o test test.cpp
-  test.cpp:3:14: warning: ignoring return value of function
-  declared with 'nodiscard' attribute [-Wunused-result]
-  int main() { SquareNumber(2.0); }
-              ^~~~~~ ~~~
-  1 warning generated.
-  ```
-- No warning if result is actually used:
-  <!--
-  `CPP_SETUP_START`
-  [[nodiscard]] double SquareNumber(double input) {
-    return input * input;
-  }
-  int main() {
-    $PLACEHOLDER
-    return 0;
-  }
-  `CPP_SETUP_END`
-  -->
-  ```cpp
-  const auto smth = SquareNumber(42.0);
-  ```
-- Helps to avoid logical errors while programming
-
----
-# Good function example
-```cpp
-#include <vector>
-using std::vector;
-
-[[nodiscard]] vector<int>
-CreateFibonacciSequence(std::size_t length) {
-  // Vector of size `length`, filled with 1s.
-  vector<int> result(length, 1);
-  if (length < 3) { return result; }
-  for (auto i = 2UL; i < length; ++i) {
-    result[i] = result[i - 1UL] + result[i - 2UL];
-  }
-  return result;
-}
-int main() {
-  const auto fibonacci_sequence = CreateFibonacciSequence(10UL);
-  // Do something with fibonacci_sequence.
-  return 0;
-}
-```
-- ✅ Is small enough to see all the code at once
-- ✅ Name clearly states what the function does
-- ✅ Conceptually, does a single thing only
-
----
-# :scream: Bad function example
-```cpp
-#include <vector>
-using std::vector;
-
-vector<std::size_t> Func(std::size_t a, bool b) {
-  if (b) { return vector<std::size_t>(10, a); }
-  vector<std::size_t> vec(a);
-  for (auto i = 0UL; i < a; ++i) { vec[i] = a * i; }
-  if (vec.size() > a * 2) { vec[a] /= 2.0f; }
-  return vec;
-}
-
-int main() {
-  const auto smth = Func(10, true);
-  // Do smth with smth.
-  return 0;
-}
-```
-- :scream: It is **really** hard to understand what it does at a glance!
-- :scream: Name of the function means nothing
-- :scream: Names of the variables mean nothing
-- :scream: Function does not have a single purpose
-
----
-# Declaration vs definition
-- Function declaration can be separated from the implementation details
-- Function **declaration** sets up an interface
-- Function **definition** holds the implementation of the function that can even be hidden from the user (stay tuned)
-  <!--
-  `CPP_SETUP_START`
-  #include<iostream>
-  using namespace std;
-  $PLACEHOLDER
-  int main() {
-    return 0;
-  }
-  `CPP_SETUP_END`
-  -->
-  ```cpp
-  void FuncName();  // Ends with a ";"
-
-  // Somewhere further in the code.
-  void FuncName() {
-    // Implementation details.
-    cout << "This function is called FuncName! ";
-    cout << "Did you expect anything useful from it?";
-  }
-  ```
-- The name, the argument types (including `&`, `const` etc.)
-  and the return type have to be **exactly** the same
-
----
-# Passing big objects
-- Objects are copied by default when passed into functions
-  (the compiler can sometimes avoid the copy, stay tuned)
-- **Quick for small objects** (e.g., [fundamental](cpp_basic_types_and_variables.md#variables-of-fundamental-types) types)
-- **Slow for bigger objects** (usually any other type)
-- ✅ **Pass bigger objects by reference** to avoid copying!
-  <!--
-  `CPP_SETUP_START`
-  #include <string>
-  $PLACEHOLDER
-  int main() {
-    return 0;
-  }
-  `CPP_SETUP_END`
-  -->
-  ```cpp
-  void DoSmthSmall(float number);                // Ok ✅
-  void DoSmthBig(std::string huge_string);       // Slow 😱
-  void DoSmthWithRef(std::string& huge_string);  // Faster
-  ```
-
----
-# What is passing by reference?
-
-![center width:800](images/pass_by_ref.gif)
-
-<div class="grid-container">
-<div>
-
-### Pass by reference:
-- `void Fill(Cup &cup);`
-- The object that `cup` references is full afterwards
-
-</div>
-
-<div>
-
-### Pass by value:
-- `void Fill(Cup cup);`
-- A **copy** `cup` of the original object is full
-- The original is still empty
-
-</div>
-</div>
-
----
-# Do you see any problems?
-Is the string `hello` still the same after calling the function?
-<!--
-`CPP_SKIP_SNIPPET`
--->
-```cpp
-void DoSmthWithRef(std::string& huge_string);
-// Then somewhere in some function
-std::string hello = "some_important_long_string";
-DoSmthWithRef(hello);
-// 🤔 Is hello the same here?
-```
-
-<div class="grid-container">
-<div>
-
-### Could be the same:
-<!--
-`CPP_SKIP_SNIPPET`
--->
-```cpp
-void DoSmthWithRef(hello) {
-  print(hello);
-}
-```
-
-</div>
-
-<div>
-
-### Could be changed:
-<!--
-`CPP_SKIP_SNIPPET`
--->
-```cpp
-void DoSmthWithRef(hello) {
-  hello.clear();
-}
-```
-
-</div>
-</div>
-
-### 😱 Value of `hello` unknown without reading the function implementation!
-
----
-# Solution: use const references
-- Pass a `const` reference to the function!
-- Great speed as we pass a reference
-- Passed object stays intact, guaranteed because it's `const`!
-  <!--
-  `CPP_SETUP_START`
-  #include <string>
-  $PLACEHOLDER
-  int main() {
-    return 0;
-  }
-  `CPP_SETUP_END`
-  -->
-  ```cpp
-  void DoSmth(const std::string& huge_string);
-  ```
-- Non-`const` references are mostly used in older code written before C++11, often for performance reasons
-- Most of the times these reasons do not hold in modern C++
-- 🔼1️⃣1️⃣ Returning an object from function is **mostly** fast
-- 🔼1️⃣7️⃣ Returning an object from function is **always** fast
-- 🎓🎨 Avoid using non-`const` references, see [Google style](https://google.github.io/styleguide/cppguide.html#Inputs_and_Outputs)
-- 💡 Sometimes passing by non-const reference is still faster than returning an object from a function
-  **Measure before doing this!**
-
----
-# :scream: Never return a reference to a function-local object
-- Objects created in a function live within its scope
-- When function ends, all its variables die
-- Returning a reference to a local object leads to UB:
-  <!--
-  `CPP_SETUP_START`
-  $PLACEHOLDER
-  int main() {
-    return 0;
-  }
-  `CPP_SETUP_END`
-  -->
-  ```cpp
-  int& ReallyNastyFunction() {
-    int local_variable{};
-    return local_variable;  // 😱 Don't do this!
-  }
-  ```
-- Modern compilers will warn about it
-- **Always** make sure your program compiles without warnings!
-
-
----
-# Function overloading - writing functions with the same names
-- Compiler infers which function to call from input parameters
-- We cannot overload based on return type
-  ```cpp
-  #include <iostream>
-  #include <string>
-  using std::cout;
-  using std::endl;
-  using std::string;
-  string GetNames(int num) { return "int"; }
-  string GetNames(const string& str) { return "string"; }
-  string GetNames(int num, float other) { return "int_float"; }
-  int main() {
-    cout << GetNames(1) << endl;
-    cout << GetNames("hello") << endl;
-    cout << GetNames(42, 42.0F) << endl;
-    return 0;
-  }
-  ```
-- 🎓 [All overloads should do semantically the same thing](https://google.github.io/styleguide/cppguide.html#Function_Overloading)
-
----
-# 🤔 Use default arguments?
-- Default parameters have a default value:
-  <!--
-  `CPP_SETUP_START`
-  $PLACEHOLDER
-  int main() {
-    return 0;
-  }
-  `CPP_SETUP_END`
-  -->
-  ```cpp
-  void DoSmth(int number = 42);
-  ```
-- Only **set in declaration** not in definition
-- **Pros:** simplify _some_ function calls
-- **Cons:**
-  - Evaluated upon every call
-  - Values are hidden in declaration
-  - Can lead to unexpected behavior when overused
-  - Gets confusing when having overloaded functions
-- 🎓 [Only use them when readability gets much better](https://google.github.io/styleguide/cppguide.html#Default_Arguments)
-
-
----
-# Example: default arguments
-```cpp
-#include <iostream>
-using std::string;
-using std::cout;
-using std::endl;
-string SayHello(const string& to_whom = "world") {
-  return "Hello " + to_whom + "!";
-}
-int main() {
-  // 🤔 This is a good example how it can get confusing.
-  cout << SayHello() << endl;
-  cout << SayHello("students") << endl;
-  return 0;
-}
-```
-
----
-
-
-![bg](https://fakeimg.pl/1280x1024/226699/fff/?text=Good%20luck!&font=bebas)
diff --git a/lectures/googletest.md b/lectures/googletest.md
deleted file mode 100644
index 577ade1..0000000
--- a/lectures/googletest.md
+++ /dev/null
@@ -1,356 +0,0 @@
-**Introduction to testing with googletest**
-
-<p align="center">
-  <a href="https://youtu.be/pxJoVRfpRPE"><img src="https://img.youtube.com/vi/pxJoVRfpRPE/maxresdefault.jpg" alt="Video" align="right" width=50%></a>
-</p>
-
-- [What does "testing" even mean](#what-does-testing-even-mean)
-- [The usual automated testing frameworks](#the-usual-automated-testing-frameworks)
-  - [How to get the googletest code](#how-to-get-the-googletest-code)
-  - [How to include googletest in our CMake project](#how-to-include-googletest-in-our-cmake-project)
-  - [How to use the googletest framework](#how-to-use-the-googletest-framework)
-  - [How to write your first test](#how-to-write-your-first-test)
-  - [How to run a Google test?](#how-to-run-a-google-test)
-  - [Testing our own libraries](#testing-our-own-libraries)
-- [How to keep googletest in our project codebase correctly?](#how-to-keep-googletest-in-our-project-codebase-correctly)
-  - [Update the submodules automagically](#update-the-submodules-automagically)
-- [Conclusion](#conclusion)
-
-
-
-<!-- Talking head -->
-You already know how to write some C++ code. Furthermore, you also know that the code should be structured into bite-sized chunks and that you can write functions that you can put into libraries.
-
-<!-- B-roll person typing ✅ -->
-So, you write your next amazing project, you spend hours on writing out the code and thinking about how great everything's going to work.
-
-<!-- B-roll person closing laptop ✅ -->
-Finally, you're there, you run your code.
-
-<!-- Explosion ✅ -->
-And...
-
-<!-- Talking head -->
-Of course it crashes! At least my code would in such a scenario...
-
-Wouldn't it be nice if there was some automated framework we could use to reduce the likelihood of this outcome?
-
-<!-- B-roll Googletest running | ✅ -->
-Well, of course such a framework exists! There are actually various testing libraries out there that combined become our first line of defense against the bugs. They all allow writing "test code" to test that our code does what we expect it to.
-
-<!-- Talking head -->
-So today we're talking about how to set up such a system and make it work for our purposes. 😉
-
-## What does "testing" even mean
-<!-- Talking head -->
-Before we talk about a concrete framework, let's chat about what does it mean to "test" the code.
-
-Well, essentially, testing our code means that we want to verify that it does what we expect it to do.
-
-This testing can happen on many levels!
-
-<!-- B-roll show on screen | voice ✅ -->
-We won't go too deep into this, but largely speaking we usually have these layers:
-- **Unit testing** --- test if each module works on its own
-- **Integration testing** --- test how the modules work together
-- **Regression testing** --- test that we did not break critical systems with new changes
-- **Acceptance / system testing** --- test that the system as a whole works as expected
-
-<!-- Talking head -->
-In general, the first are done fully automatically, while the last one is a combination of automatic and manual validation.
-
-However, today we're going to be talking about a framework that *mostly* allows us to address the first two - the unit testing and the integration testing.
-
-## The usual automated testing frameworks
-<!-- Talking head -->
-Largely speaking there are 3 frameworks that I am aware of that are being used in the wild
-
-<!-- Show their logos on screen -->
-- [googletest](https://github.com/google/googletest)
-- [Catch2](https://github.com/catchorg/Catch2)
-- [Doctest](https://github.com/doctest/doctest)
-
-All of these can be integrated into your CMake or bazel project. Also, they all follow relatively similar concepts, so once you learn one you'll easily use the other ones too.
-
-<!-- B-roll scroll googletest website | voice ✅ -->
-In this course, we're going to be using the [googletest](https://github.com/google/googletest) framework as this is the one I've seen most often in the industries I've been working in.
-
-### How to get the googletest code
-<!-- Talking head -->
-There are multiple ways to include the googletest framework into your project.
-
-<!-- B-roll highlight google statement | voice ✅ -->
-Google recommends compiling their testing framework along with your project, so we won't install it as a dependency system-wide and will instead use the source code directly in our project
-
-<!-- B-roll downloading manually | voice ✅ -->
-For a start we'll just download it manually, unzip it and put it into the `external` subfolder of our project folder to be used by our build system. Let's put it to `my_project/external` folder.
-
-<!-- Talking head -->
-Even though we _do_ start with this manual way, but stick until the end of the video to find out why it's not what we want to do and what we should do instead.
-
-### How to include googletest in our CMake project
-<!-- B-roll write the cmake file | voice ✅ -->
-Anyway, now that the code is in the project folder, we can use it in our CMake project by adding the necessary `add_subdirectory` command to the `CMakeLists.txt` file.
-```cmd
-mkdir my_project
-cd my_project
-code CMakeLists.txt
-```
-`CMakeLists.txt`
-<!--
-`CPP_SKIP_SNIPPET`
--->
-```cmake
-cmake_minimum_required(VERSION 3.16..3.24)
-project(try_googletest VERSION 0.0.1
-                       DESCRIPTION "Try googletest"
-                       LANGUAGES CXX)
-# Add subdirectory with external projects' code
-add_subdirectory(external)
-```
-We then want to add a `CMakeLists.txt` to the `external` folder too:
-```cmd
-code external/CMakeLists.txt
-```
-`external/CMakeLists.txt`
-<!--
-`CPP_COPY_SNIPPET` my_project/external/CMakeLists.txt
--->
-```cmake
-# Setting this will only affect the folders down from the current one
-set(CMAKE_CXX_STANDARD 17)
-add_subdirectory(googletest)
-```
-
-<!-- B-roll build the code | voice ✅ -->
-That's it! If we now build our project it will build the googletest code.
-
-### How to use the googletest framework
-<!-- Talking head -->
-Building the code is a bit useless on its own. We want to use it!
-
-<!-- **B-roll add code to cmake** -->
-For that we have to add a couple of things to our CMake:
-- We want to call `include(CTest)` in the main `CMakeLists.txt` file of the project to enable tests:
-
-  `CMakeLists.txt`
-  <!--
-  `CPP_COPY_SNIPPET` my_project/CMakeLists.txt
-  -->
-  ```cmake
-  cmake_minimum_required(VERSION 3.16..3.24)
-  project(try_googletest VERSION 0.0.1
-                      DESCRIPTION "Try googletest"
-                      LANGUAGES CXX)
-  # Enable testing for this project
-  include(CTest)
-  # Add subdirectories with code
-  add_subdirectory(external)
-  add_subdirectory(my_project)
-  ```
-- In the folder with your test files create test binaries and register them with CTest using the [gtest_discover_tests](https://cmake.org/cmake/help/latest/module/GoogleTest.html) command:
-
-  `my_project/CMakeLists.txt`
-  <!--
-  `CPP_COPY_SNIPPET` my_project/my_project/CMakeLists.txt
-  -->
-  ```cmake
-  # BUILD_TESTING variable is created by include(CTest)
-  # It is set to ON by default
-  if (BUILD_TESTING)
-      add_executable(my_test my_test.cpp)
-      target_link_libraries(my_test PRIVATE GTest::gtest_main)
-
-      include(GoogleTest)
-      # Finds all the Google tests associated with the executable
-      gtest_discover_tests(my_test)
-  endif()
-  ```
-
-That's all we need to integrate our tests with CMake.
-
-### How to write your first test
-<!-- Talking head -->
-But wait! We don't have the actual test code there! Let's fix that right now!
-
-<!-- B-roll live editor -->
-We jump back into our editor, create a new file `my_project/my_test.cpp` and type away.
-
-<!--
-`CPP_COPY_SNIPPET` my_project/my_project/my_test.cpp
-`CPP_RUN_CMD` CWD:my_project rm -rf external/googletest/ && git clone https://github.com/google/googletest.git external/googletest && cmake -S . -B build && cmake --build build
--->
-```cpp
-// Must include the gtest header to use the testing library
-#include <gtest/gtest.h>
-
-namespace {
-  // We will test this dummy function but you can test
-  // any function from any library that you write too.
-  int GetMeaningOfLife() {  return 42; }
-}
-
-// All tests must live within TEST* blocks
-// Inside of the TEST block is a standard C++ scope
-// TestTopic defines a topic of our test, e.g. NameOfFunctionTest
-// TrivialEquality represents the name of this particular test
-// It should be descriptive and readable to the user
-// TEST is a macro, i.e., preprocessor replaces it with some code
-TEST(TestTopic, TrivialEquality) {
-  // We can test for equality, inequality etc.
-  // If the equality does not hold, the test fails.
-  // EXPECT_* are macros, i.e., also replaced by the preprocessor.
-  EXPECT_EQ(GetMeaningOfLife(), 42);
-}
-
-TEST(TestTopic, MoreEqualityTests) {
-  // ASSERT_* is similar to EXPECT_* but stops the execution
-  // of the test if fails.
-  // EXPECT_* continues execution on failure too.
-  ASSERT_EQ(GetMeaningOfLife(), 0) << "Oh no, a mistake!";
-  EXPECT_FLOAT_EQ(23.23F, 23.23F);
-}
-```
-
-### How to run a Google test?
-<!-- Talking head -->
-Now with these tests defined and our CMake configured to discover them, we can eventually actually run them!
-
-<!-- B-roll building and executing -->
-We now just need to build the project again and run `ctest`:
-```bash
-cmake -S . -B build
-cmake --build build -j 12
-GTEST_COLOR=1 ctest --test-dir build --output-on-failure -j12
-# Or if you have an older CMake version (<3.20)
-cd build && GTEST_COLOR=1 ctest --output-on-failure -j12
-```
-
-<!-- Talking head with error overlay -->
-Unfortunately, one of our tests is failing!
-It shows up in red and prints our custom error message too! Let's go back to the editor and fix it!
-
-<!-- B-roll code -->
-We can easily fix this error by changing the code in our test.
-```diff
--ASSERT_EQ(GetMeaningOfLife(), 0) << "Oh no, a mistake!";
-+ASSERT_EQ(GetMeaningOfLife(), 42) << "Oh no, a mistake!";
-```
-We now execute this again and see that all the tests have passed! Hooray!
-
-### Testing our own libraries
-<!-- Talking head -->
-For now we've only checked very trivial things in our tests. I mean, we've been testing a function that we wrote directly _in the test file_!
-If we want to use other libraries here we can easily do that by adding those libraries as dependencies to the test CMake target and including the appropriate header files in the C++ test file.
-
-If you don't know what I'm talking about then watch [this tutorial about libraries](headers_and_libraries.md) and then [this one about cmake](cmake.md).
-
-## How to keep googletest in our project codebase correctly?
-
-<!-- Talking head -->
-Ok, remember how I told you to stick around?
-<!-- show b/w part where I ask to stick around -->
-Copying the code from GitHub like we did before into your project is not enough. Let me illustrate!
-
-Imagine you're developing your project in a team (or, if you don't like people, imagine that you're developing your project on multiple machines). You've just copied the googletest code into your project and wrote some tests. You push your code changes into your git repository. You don't want to push the googletest code because it's not _your_ code, it is some _external_ code that you don't want to maintain.
-
-Now, what will happen to your colleagues when they pull the changes and try to build?
-
-<!-- B-roll failing to find the tests folder -->
-This. CMake fails to find the googletest folder so now they would also need to manually download it into the external folder.
-
-<!-- Talking head -->
-And now you also need to sync on the version of the googletest library that all of you download. You can probably guess that this is not the way.
-And you're right! There are multiple ways people deal with this:
-
-<!-- show options on screen -->
-- Installing googletest as a system dependency (deprecated, but still used)
-- Using the CMake's [`FetchContent`](https://cmake.org/cmake/help/latest/module/FetchContent.html) to download the code on every build (you can read all about it in Googletest's [Quickstart](https://google.github.io/googletest/quickstart-cmake.html) section)
-- Or adding Googletest as a submodule to your repository (this is my preference and I'll show you how to do it now) (adapted from [here](https://cliutils.gitlab.io/modern-cmake/chapters/projects/submodule.html))
-
-<!-- B-roll terminal -->
-We copy the link to the googletest library from GitHub and initialize a submodule with it:
-```cmd
-cd my_project
-git submodule add https://github.com/google/googletest.git external/googletest
-```
-
-That's it, now the code linked to your repository as a submodule and anybody who clones it can run a command to update it:
-```cmd
-git submodule update --init --recursive
-```
-And get the latest changes from the submodule.
-
-<!-- Talking head -->
-The only issue with this is that people _will_ forget to do this, which will lead to people complaining and running different versions of the underlying libraries, so there is one final trick I want to show you to avoid this.
-
-Remember how I told you that "CMake is just a scripting language"?
-
-**We can bake the submodule update procedure into CMake directly!**
-
-### Update the submodules automagically
-
-<!-- B-roll editor -->
-For that, create a new folder `cmake` in your project root and add the file `UpdateSubmodules.cmake` in it. Then copy the code linked in the description of this video into it. Here is what this code does roughly:
-- check if `git` exists on the system
-- check if we want to update the submodules
-- list available submodules
-- update them
-
-`my_project/cmake/UpdateSubmodules.cmake`:
-<!--
-`CPP_SKIP_SNIPPET`
--->
-```cmake
-# Adapted from https://cliutils.gitlab.io/modern-cmake/chapters/projects/submodule.html
-find_package(Git QUIET)
-if(GIT_FOUND)
-    option(UPDATE_SUBMODULES "Check submodules during build" ON)
-    if(NOT UPDATE_SUBMODULES)
-        return()
-    endif()
-    execute_process(COMMAND ${GIT_EXECUTABLE} submodule
-                    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
-                    OUTPUT_VARIABLE EXISTING_SUBMODULES
-                    RESULT_VARIABLE RETURN_CODE
-                    OUTPUT_STRIP_TRAILING_WHITESPACE)
-    message(STATUS "Updating git submodules:\n${EXISTING_SUBMODULES}")
-    execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive
-                    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
-                    RESULT_VARIABLE RETURN_CODE)
-    if(NOT RETURN_CODE EQUAL "0")
-        message(WARNING "Cannot update submodules. Git command failed with ${RETURN_CODE}")
-        return()
-    endif()
-    message(STATUS "Git submodules updated successfully")
-endif()
-```
-
-We can call this script by adding an additional line to our root `CMakeLists.txt` file:
-<!--
-`CPP_SKIP_SNIPPET`
--->
-```cmake
-cmake_minimum_required(VERSION 3.16..3.24)
-project(try_googletest VERSION 0.0.1
-                    DESCRIPTION "Try googletest"
-                    LANGUAGES CXX)
-# Update the submodules here
-include(cmake/UpdateSubmodules.cmake)
-# Enable testing for this project
-include(CTest)
-# Add subdirectories with code
-add_subdirectory(external)
-add_subdirectory(my_project)
-```
-
-<!-- B-roll terminal -->
-Now if we run the cmake commands again, our submodules will be updated automagically.
-
-
-## Conclusion
-
-<!-- Talking head -->
-Whoah, that was some amount of content. All in all, you now know that you should test your code and you know how to do that too using CMake and the googletest framework.
-
-If you like this stuff you can subscribe to my channel and also go explore other videos on my channel! Bye!
diff --git a/lectures/headers_and_libraries.md b/lectures/headers_and_libraries.md
deleted file mode 100644
index bcac3c4..0000000
--- a/lectures/headers_and_libraries.md
+++ /dev/null
@@ -1,631 +0,0 @@
----
-marp: true
-math: katex
-theme: custom-theme
-footer: ![width:80px](images/C++ForYourselfIcon.png)
----
-# Libraries
-
-#### Today:
-- Different types of libraries
-  - Header-only
-  - Static
-  - Dynamic
-- What is linking
-- When to use the keyword `inline`
-- Some common best practices
-
-### 📺 Watch the related [YouTube video](https://youtu.be/Lxo8ftglwXE)!
-
----
-# Special symbols used in slides
-- 🎨 - Style recommendation
-- 🎓 - Software design recommendation
-- 😱 - **Not** a good practice! Avoid in real life!
-- ✅ - Good practice!
-- ❌ - Whatever is marked with this is wrong
-- 🚨 - Alert! Important information!
-- 💡 - Hint or a useful exercise
-- 🔼1️⃣7️⃣ - Holds for this version of C++(here, `17`) and **above**
-- 🔽1️⃣1️⃣ - Holds for versions **until** this one C++(here, `11`)
-
-Style (🎨) and software design (🎓) recommendations mostly come from [Google Style Sheet](https://google.github.io/styleguide/cppguide.html) and the [CppCoreGuidelines](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines)
-
----
-
-# Let's start with an example
-
-Let's say we implement a new machine learning framework :wink:
-
-```cpp
-#include <vector>
-#include <iostream>
-
-[[nodiscard]] int
-PredictNumber(const std::vector<int>& numbers) {
-  // Arbitrarily complex code goes here.
-  if (numbers.empty()) { return 0; }
-  if (numbers.size() < 2) { return numbers.front(); }
-  const auto& one_before_last = numbers[numbers.size() - 2UL];
-  const auto difference = numbers.back() - one_before_last;
-  return numbers.back() + difference;
-}
-// Many more similar functions.
-
-int main() {
-  const auto number = PredictNumber({1, 2});
-  if (number != 3) {
-    std::cerr << "Our function does not work as expected 😥\n";
-    return 1;
-  }
-  return 0;
-}
-```
-
----
-# What if we want to use it in multiple places?
-- For now code lives **in a single binary**
-- Now assume that we have **two programs** we want to write:
-  - One to predict the **house pricing**
-  - One to predict the **bitcoin price**
-- These should use our "machine learning" functions
-- And other things special for those usecases
-- :scream: Should we just **copy the code over?**
-
----
-# :scream: Problems with copying?
-- Our code is **duplicated**
-- If we have more binaries, we have more copies
-- Any changes for the functionality needs to be synced
-- It requires **us** to keep this in mind - which is **error prone**
-- (violates the **DRY** principle)
-<br>
-
-<div data-marpit-fragment>
-
-![center w:700](images/im-not-sure.jpg)
-
-</div>
-
----
-# Better solution: header files!
-`ml.h`<br>
-<!--
-`CPP_SETUP_START`
-inline constexpr auto next_number{42};
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` ml/ml.h
--->
-```cpp
-#pragma once  // Stay tuned 😉
-#include <vector>
-[[nodiscard]] inline  // Stay tuned for "inline"
-int PredictNumber(const std::vector<int>& numbers) {
-  // Compute next number (skipped to fit on the slide)
-  return next_number;
-}
-```
-
-<div class="grid-container">
-<div>
-
-`predict_housing.cpp`
-<!--
-`CPP_SETUP_START`
-#include <vector>
-std::vector<int> MagicallyGetHousePrices() {
-  return {1, 2, 3};
-}
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` ml/main_houses.cpp
-`CPP_RUN_CMD` CWD:ml c++ -std=c++17 -I . main_houses.cpp
--->
-```cpp
-#include <ml.h>
-#include <iostream>
-int main() {
-  const auto prices =
-    MagicallyGetHousePrices();
-  std::cout
-    << "Upcoming price: "
-    << PredictNumber(prices);
-  return 0;
-}
-```
-</div>
-
-<div>
-
-`predict_bitcoin.cpp`
-<!--
-`CPP_SETUP_START`
-#include <vector>
-std::vector<int> MagicallyGetBitcoinPrices() {
-  return {1, 2, 3};
-}
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` ml/main_bitcoin.cpp
-`CPP_RUN_CMD` CWD:ml c++ -std=c++17 -I . main_bitcoin.cpp
--->
-```cpp
-#include <ml.h>
-#include <iostream>
-int main() {
-  const auto prices =
-    MagicallyGetBitcoinPrices();
-  std::cout
-    << "Upcoming price: "
-    << PredictNumber(prices);
-  return 0;
-}
-```
-
-</div>
-</div>
-
----
-# Yay! A header-only library! :tada:
-- All functions are implemented in header files (`.h`, `.hpp`)
-- We `#include` these header files in our binaries
-- :bulb: Put your includes first, then other libraries, then standard
-
-**Pros:**
-- **Compiler sees all code** so it can optimize it well
-- Compilation remains **simple** (just need the new `-I` flag)
-  ```cmd
-  c++ -std=c++17 -I folder_with_headers binary.cpp
-  ```
-**Cons:**
-- We **always** recompile the code in headers
-- Changes in headers **require recompilation** of depending code
-- If we ship the code it **remains readable to anyone**
-- We should make the functions `inline` (stay tuned)
-
----
-# What's `#pragma once`?
-- A **preprocessor directive** that ensures the header in which it is written is only included once
-- There are compilers that don't support it, but most do
-- Alternative --- **include guards**
-  For file `file.h` in `folder/` they can be:<br>
-  <!--
-  `CPP_SKIP_SNIPPET`
-  -->
-  ```cpp
-  #ifndef FOLDER_FILE_H_
-  #define FOLDER_FILE_H_
-
-  #endif /* FOLDER_FILE_H_ */
-  ```
-- They also ensure the header file will be included only once
-- ✅ Always use one of these in your header files!
----
-# Avoid long compilation times by using binary libraries!
-- Move only **declarations** to header files: `*.h` or `*.hpp`
-- Move **definitions** to source files: `*.cpp` or `*.cc`
-- Compile corresponding source files to **object files**
-- Bind the object files into **libraries**
-- **Link** the libraries to executables
-- The library is **built once**, and **linked** to multiple targets!
-- If we change the code in a library we only need to:
-  - Rebuild **only** the library
-  - `[maybe]` Relink this library to our executables
-
----
-**Declaration:** `ml.h`<br>
-<!--
-`CPP_COPY_SNIPPET` ml_lib/ml.h
--->
-```cpp
-#pragma once
-#include <vector>
-[[nodiscard]] int
-PredictNumber(const std::vector<int>& numbers);
-```
-
-**Definition:** `ml.cpp`
-<!--
-`CPP_SETUP_START`
-inline constexpr auto next_number{42};
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` ml_lib/ml.cpp
--->
-```cpp
-#include <ml.h>
-#include <vector>
-[[nodiscard]] int
-PredictNumber(const std::vector<int>& numbers) {
-  // Compute next number (skipped to fit on the slide)
-  return next_number;
-}
-```
-
-**Calling it:** `predict_prices.cpp`:<br>
-<!--
-`CPP_SETUP_START`
-#include <vector>
-std::vector<int> MagicallyGetBitcoinPrices() {
-  return {1, 2, 3};
-}
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` ml_lib/predict_prices.cpp
-`CPP_RUN_CMD` CWD:ml_lib c++ -std=c++17 -I . ml.cpp predict_prices.cpp
--->
-```cpp
-#include <ml.h>
-#include <iostream>
-int main() {
-  const auto prices = MagicallyGetBitcoinPrices();
-  std::cout << "Upcoming price: " << PredictNumber(prices);
-  return 0;
-}
-```
-
----
-
-# Just build it as before?
-```cmd
-c++ -std=c++17 predict_prices.cpp -I . -o predict_prices
-```
-<div data-marpit-fragment>
-
-### Error: compiler sees only the declaration
-```css
-Undefined symbols for architecture arm64:
-  "PredictNumber(
-    std::__1::vector<int, std::__1::allocator<int> > const&)",
-    referenced from: _main in predict_prices-066946.o
-ld: symbol(s) not found for architecture arm64
-clang: error: linker command failed with exit code 1
-(use -v to see invocation)
-```
-:bulb: Your error will look similar but slightly different
-
-
-### :thinking: Compile all together - solution?
-```cmd
-c++ -std=c++17 -I . ml.cpp predict_prices.cpp
-```
-<div data-marpit-fragment>
-
-:x: not really - does not solve our "recompilation" issue!
-
-</div>
-</div>
-
----
-
-# Compile objects and libraries
-- **Compile** source files into **object files** (use the `-c` flag) <br>
-  ```cmd
-  c++ -std=c++17 -c ml.cpp -I includes -o ml_static.o
-  ```
-  ```cmd
-  c++ -std=c++17 -c -fPIC ml.cpp -I includes -o ml_dynamic.o
-  ```
-  Assuming that all includes live in the `includes` folder,
-  results in `*.o` binary files that an OS can read and interpret
-- Pack objects into **libraries:**
-  - **Static** libraries (`*.a`) are just archives of object files
-    ```cmd
-    ar rcs libml.a ml_static.o <other_object_files>
-    ```
-  - **Dynamic** libraries (`*.so`) are a bit more complex
-    ```cmd
-    c++ -shared ml_dynamic.o <other_object_files> -o libml.so
-    ```
-- Finally, we **link** the libraries to our binary
-
----
-# Linking libraries to binaries
-- Linking tells the compiler in which binary library file to find the **definition** for a **declaration** it sees in a header file
-- **Link** our `main` executable to the libraries it uses
-  ```cmd
-  c++ -std=c++17 main.cpp -L folder -I includes -lml -o main
-  ```
-  - `-I includes` - Headers are in the `includes` folder
-  - `-L folder` - Add `folder` to the library search path
-  - `-lml` - Link to the library file `libml.a` or `libml.so`
-  - 🚨 Note that `-l` flags must be **after** all `.cpp` or `.o` files
-  - 🚨 Same usage for both static and dynamic libraries but a different resulting executable
-- **Static** libraries are **copied** inside the resulting `main` binary
-- **Dynamic** libraries are **linked** to the resulting `main` binary
-
----
-# What's the difference between static and dynamic libraries?
-- Binaries with **static linkage**:
-  - Contain **binary code** of other libraries, usually **bigger**
-  - Can be copied anywhere on any similar operating system
-- Binaries with **dynamic linkage**:
-  - Contain **references** to other libraries, usually **smaller**
-  - Dependencies (dynamic libraries) are looked up at runtime
-    - Relative to the current path
-    - In the paths stored in `LD_LIBRARY_PATH` variable
-  - If you move your binary or libraries you might break it
-  - See linked libs with `ldd` (Linux) or `otool -L` (MacOS)
-- In this course **we will use static libraries**
-
----
-# Mixing header-only and compiled libraries requires caution 🚨
-- Let's assume we have a header file `print.h`:
-  <!--
-  `CPP_COPY_SNIPPET` print/print.h
-  -->
-  ```cpp
-  #include <iostream>
-  // Notice no inline keyword here
-  void Print(const std::string& str) { std::cout << str << "\n"; }
-  ```
-- We use this file in two **compiled libraries**: `foo` and `bar`
-<div class="grid-container">
-<div>
-
-`foo.h`
-<!--
-`CPP_COPY_SNIPPET` print/foo.h
--->
-```cpp
-void Foo();
-```
-
-`foo.cpp`
-<!--
-`CPP_COPY_SNIPPET` print/foo.cpp
--->
-```cpp
-#include <print.h>
-void Foo() {
-  Print("Foo");
-}
-```
-
-</div>
-<div>
-
-`bar.h`
-<!--
-`CPP_COPY_SNIPPET` print/bar.h
--->
-```cpp
-void Bar();
-```
-
-`bar.cpp`
-<!--
-`CPP_COPY_SNIPPET` print/bar.cpp
--->
-```cpp
-#include <print.h>
-void Bar() {
-  Print("Bar");
-}
-```
-
-</div>
-</div>
-
----
-# Mixing header-only and compiled libraries requires caution 🚨
-- Finally, we write a program that uses them: `main.cpp`
-  <!--
-  `CPP_COPY_SNIPPET` print/main.cpp
-  `CPP_RUN_CMD` CWD:print c++ -std=c++17 -c -I . foo.cpp -o foo.o && c++ -std=c++17 -c -I . bar.cpp -o bar.o && ar rcs libfoo.a foo.o && ar rcs libbar.a bar.o
-  -->
-  ```cpp
-  #include <foo.h>
-  #include <bar.h>
-  int main() {
-    Foo();
-    Bar();
-    return 0;
-  }
-  ```
-- And compile it as an executable `main`:
-  ```cmd
-  c++ -std=c++17 -c -I . main.cpp -o main.o
-  c++ -std=c++17 -c -I . foo.cpp -o foo.o
-  ar rcs libfoo.a foo.o
-  c++ -std=c++17 -c -I . bar.cpp -o bar.o
-  ar rcs libbar.a bar.o
-  c++ main.o -L . -I . -lfoo -lbar -o main
-  ```
-
-<div data-marpit-fragment>
-
-:x: Oops, it does not link! (build it to see the error :wink:)
-
-</div>
-
----
-# But... why?
-- Linker failed because we violated **ODR** --- [**O**ne **D**efinition **R**ule](https://en.cppreference.com/w/cpp/language/definition)
-- It states that there must be **exactly one** definition of every symbol in the program, i.e., your **functions** and **variables**
-- We have two libraries `libfoo.a` and `libbar.a` with source files that both include the `print.h` and therefore have a **definition** of the `Print(...)` function
-- Our executable links to both `libfoo.a` and `libbar.a`, so it has two definitions for the `Print(...)` function, which causes an **error** :x:
----
-# `inline` to the rescue! 🦸‍♀️
-
-- ODR allows to have multiple definitions of `inline` functions (as long as all of them are in different translation units)
-- So adding `inline` to `Print(...)` will tell the compiler that we know there will be multiple definitions of it and we **guarantee that they are all the same**!
-  <!--
-  `CPP_COPY_SNIPPET` print/print.h
-  `CPP_RUN_CMD` CWD:print c++ -std=c++17 -c -I . foo.cpp -o foo.o && c++ -std=c++17 -c -I . bar.cpp -o bar.o && ar rcs libfoo.a foo.o && ar rcs libbar.a bar.o && c++ -std=c++17 main.cpp -L . -I . -lfoo -lbar -o main
-  -->
-  ```cpp
-  #include <iostream>
-  inline void
-  Print(const std::string& str) { std::cout << str << "\n"; }
-  ```
-- 🚨 `inline` can only be used in function **definition**
-- :bulb: `inline` also **hints** to the compiler that it should **inline** a function --- copy its binary code in-place
-
----
-# We have to be careful!
-Let's change our `foo.cpp` and `bar.cpp` a little
-<div class="grid-container">
-<div>
-
-`foo.cpp`
-<!--
-`CPP_COPY_SNIPPET` print/foo_inline.cpp
--->
-```cpp
-#include <iostream>
-inline void Print() {
-  std::cout << "Foo\n";
-}
-void Foo() { Print(); }
-```
-
-</div>
-<div>
-
-`bar.cpp`
-<!--
-`CPP_COPY_SNIPPET` print/bar_inline.cpp
-`CPP_RUN_CMD` CWD:print c++ -std=c++17 -c -I . main.cpp -o main.o && c++ -std=c++17 -c -I . foo_inline.cpp -o foo_inline.o && c++ -std=c++17 -c -I . bar_inline.cpp -o bar_inline.o && ar rcs libfoo_inline.a foo_inline.o && ar rcs libbar_inline.a bar_inline.o && c++ main.o -L . -I . -lfoo_inline -lbar_inline -o main_inline
--->
-```cpp
-#include <iostream>
-inline void Print() {
-  std::cout << "Bar\n";
-}
-void Bar() { Print(); }
-```
-
-</div>
-</div>
-
-<div class="grid-container">
-<div>
-
-`main.cpp`
-<!--
-`CPP_COPY_SNIPPET` print/main.cpp
-`CPP_RUN_CMD` CWD:print c++ -std=c++17 -c -I . foo.cpp -o foo.o && c++ -std=c++17 -c -I . bar.cpp -o bar.o && ar rcs libfoo.a foo.o && ar rcs libbar.a bar.o
--->
-```cpp
-#include <foo.h>
-#include <bar.h>
-int main() {
-  Foo(); Bar(); return 0;
-}
-```
-
-
-</div>
-
-<div>
-
-#### Output of `./main`?
-
-<div data-marpit-fragment>
-
-```
-Bar
-Bar
-```
-:scream:
-
-</div>
-</div>
-
-</div>
-
-```cmd
-c++ -std=c++17 -c -I . foo.cpp -o foo.o && ar rcs libfoo.a foo.o
-c++ -std=c++17 -c -I . bar.cpp -o bar.o && ar rcs libbar.a bar.o
-c++ -std=c++17 main.cpp -L . -I . -lfoo -lbar -o main
-```
-
----
-# Welcome back to the UB land!
-![bg center w:1100](images/this-is-fine.gif)
-
----
-
-# What happened?
-- We have two functions with the same signature:
-  <!--
-  `CPP_SKIP_SNIPPET`
-  -->
-  ```cpp
-  void Print();
-  ```
-- The definitions of this function are different and are in different translation units `foo.cpp` and `bar.cpp`
-- When we link them together into `main` the compiler sees multiple definitions and **assumes they are the same**
-- It **picks the first one** it sees and discard the other one
-
----
-
-# How to avoid errors?
-- Don't use `inline` in source files
-- ✅ Always use `inline` if you **define** functions in headers
-- ✅ Do the same for constants 🔼1️⃣7️⃣
-  ```c++
-  inline constexpr auto kConst = 42;
-  ```
-- ✅ Use **namespaces** rigorously
-- ✅ Use **unnamed namespaces** in your source files for functions and constants used only within that source file
-
-<div class="grid-container">
-<div>
-
-`foo.cpp`
-<!--
-`CPP_COPY_SNIPPET` print/foo_inline_unnamed.cpp
--->
-```cpp
-#include <iostream>
-namespace {
-void Print() {
-  std::cout << "Foo\n";
-}
-} // namespace
-void Foo() { Print(); }
-```
-
-</div>
-<div>
-
-`bar.cpp`
-<!--
-`CPP_COPY_SNIPPET` print/bar_inline_unnamed.cpp
-`CPP_RUN_CMD` CWD:print c++ -std=c++17 -c -I . foo_inline_unnamed.cpp -o foo_inline_unnamed.o && c++ -std=c++17 -c -I . bar_inline_unnamed.cpp -o bar_inline_unnamed.o && ar rcs libfoo_inline_unnamed.a foo_inline_unnamed.o && ar rcs libbar_inline_unnamed.a bar_inline_unnamed.o && c++ -std=c++17 main.cpp -L . -I . -lfoo_inline_unnamed -lbar_inline_unnamed -o main_inline_unnamed
--->
-```cpp
-#include <iostream>
-namespace {
-void Print() {
-  std::cout << "Bar\n";
-}
-} // namespace
-void Bar() { Print(); }
-```
-
-</div>
-</div>
-
----
-# Summary
-- Use libraries to reuse/share your code
-- You have **3 options** for libraries:
-  - **Header-only**
-  - **Static**
-  - **Dynamic**
-- Each has their own benefits and downsides
-- In this course we will mostly use a combination of
-  header-only and static libraries
-
----
-
-![bg](https://fakeimg.pl/1280x1024/226699/fff/?text=Good%20luck!&font=bebas)
-
-<!--
-Great article: https://jm4r.github.io/Inline/
-
-ELF: https://stackoverflow.com/questions/41879433/file-format-differences-between-a-static-library-a-and-a-shared-library-so -->
diff --git a/lectures/headers_with_classes.md b/lectures/headers_with_classes.md
deleted file mode 100644
index 86bc62d..0000000
--- a/lectures/headers_with_classes.md
+++ /dev/null
@@ -1,329 +0,0 @@
-Headers with classes
----
-
-<p align="center">
-  <a href="https://youtu.be/9MB1nHDIM64"><img src="https://img.youtube.com/vi/9MB1nHDIM64/maxresdefault.jpg" alt="Video" align="right" width=50%></a>
-</p>
-
-- [What stays the same](#what-stays-the-same)
-- [What is different](#what-is-different)
-- [The `Chatbot` illustrative example](#the-chatbot-illustrative-example)
-  - [Modeling the interface](#modeling-the-interface)
-  - [Thinking about the implementation](#thinking-about-the-implementation)
-  - [The code in a single cpp file](#the-code-in-a-single-cpp-file)
-  - [Making it a header-only library](#making-it-a-header-only-library)
-  - [Converting it all into a compiled library](#converting-it-all-into-a-compiled-library)
-  - [The final header-source code](#the-final-header-source-code)
-- [Conclusion](#conclusion)
-
-
-We now know a thing or two about classes. We know how to implement them and understand how valuable they are to write safe and efficient code as well as the great benefits that they bring for readability and abstraction.
-
-There is only one thing missing. We still can't properly use them in our CMake projects, largely because we don't know how to create a library that holds the code that lives in classes.
-
-What we _do_ know is how to create such a library from functions... Are classes any different?
-
-And here I have good news for you - no, no they are not! In fact, the situation is very much alike to how we create a library out of functions! The differences are pretty minor.
-
-# What stays the same
-Lots of things stay exactly as we had them before:
-- We still **declare** stuff in a header (`*.hpp`) file
-- We still **define** stuff in a source (`*.cpp`) file
-- We still **create static, shared or header-only libraries** from these files
-- We still use these libraries just like before. For a refresher, see [headers and libraries lecture](headers_and_libraries.md)
-
-# What is different
-That being said, some things _are_ different.
-- We now have data, not only methods, so we'll have to learn where they land
-- The definitions in the source file must show that they belong to a class
-- Our methods also have some attributes, like the trailing `const` modifier. We must somehow deal with those
-
-# The `Chatbot` illustrative example
-<!-- Illustrate with a screen cast of a chatbot question -->
-Let's see all of this in detail. As always, we will be looking at an example. As the various AI chat bots are so popular now, we'll write a very stupid one :wink: And by very stupid, I mean _very stupid_!
-
-## Modeling the interface
-<!-- Animation of an AI black box -->
-Largely speaking, any AI system is just a black box that "trains" by looking at lots of training data, stores them in some internal representation and then uses this representation to predict certain answers when new unseen test data arrives.
-
-Given that, our "chatbot" can be simply a class. To design such a class, let's talk about the public interface this class must have:
-- It should return an `Answer` through a method `GetAnswer` that gets a question as a `std::string` parameter <!-- Add GetAnswer to the code animation ✅ -->
-- In order to be able to answer the provided question, we would have to train our chat bot. Therefore, it must be able to ingest some training `Data` into a method `Train` and do some magic to become smarter (don't get your hopes high) <!-- Add Train to the code animation ✅ -->
-
-## Thinking about the implementation
-That's about all the interface we need here. Now we would have to fill in some details:
-- The `Answer` is going to be a very simple struct holding the actual answer and its probability (here is how you know our example is fictional, no chatbot is going to provide this to us anytime soon). Oh, and we can put this struct to be class-internal for our `Chatbot` class. <!-- Add Answer to the code animation ✅ -->
-- The `Data` is also going to be a class-internal struct with its own data in the form of questions and correct answers to them as well as some function to check its validity. I know it should be a class, but let's just stick with struct here for simplicity. <!-- Add Data to the code animation ✅ -->
-- The `Chatbot` class must have some internal parameters that we train with our `Train` function and that influence its answers. We will just call our internal parameter `smartness` and represent it as an `int` :shrug: What? I did promise a _very_ stupid chatbot. :wink: <!-- Add smartness_ to the code animation ✅ -->
-- We need some implementation for all of the methods we discussed above. The implementation is going to be really trivial, this is a lecture about C++, not machine learning after all. <!-- Add implementation ✅ -->
-<!-- See all the details in the script which is linked in the description of this video, as always. -->
-
-Finally, we need a `main` function to test that the chatbot does something.
-<!-- Add main function ✅ -->
-
-## The code in a single cpp file
-Putting it all together into a `chatbot.cpp` file, we get something like this:
-
-`chatbot.cpp`:
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` chatbot_basic/main.cpp
-`CPP_RUN_CMD` CWD:chatbot_basic c++ -std=c++17 -c main.cpp
--->
-```cpp
-#include <iostream>
-#include <string>
-#include <vector>
-
-class Chatbot {
- public:
-  struct Answer {
-    float probability{};
-    std::string text{};
-  };
-
-  struct Data {
-    bool IsValid() const { return questions.size() == correct_answers.size(); }
-
-    std::vector<std::string> questions{};
-    std::vector<std::string> correct_answers{};
-  };
-
-  void Train(const Data &data) {
-    if (!data.IsValid()) { return; }
-    IngestData(data);
-  }
-
-  Answer GetAnswer(const std::string &question) const {
-    if (smartness_ < 1) { return Answer{0.1, "I don't know"}; }
-    if (smartness_ < 5) { return Answer{0.8, "Yes."}; }
-    if (question.length() > 10) {
-      return Answer{1.0, "You will regret this question..."};
-    }
-    return Answer{1.0, "Can't you ask anything more important?"};
-  }
-
- private:
-  void IngestData(const Data &data) {
-    smartness_ += data.correct_answers.size();
-  }
-
-  int smartness_{};
-};
-
-int main() {
-  Chatbot chatbot{};
-  chatbot.Train({{"How much is 2 + 2?",
-                  "What color is the sky?",
-                  "What is the answer to life and everything?"},
-                 {"4", "It depends", "42"}});
-  const auto question = "Are you self aware?";
-  std::cout << "Asking chatbot: " << question << std::endl;
-  std::cout << "Chatbot answered: " << chatbot.GetAnswer(question).text
-            << std::endl;
-  return 0;
-}
-```
-
-This example is a bit simplistic (again, do run it on your own!), but covers quite a few things that can happen within a class. It has classes and structs declared inside of it, it has methods and data and some of the methods are even `const`.
-
-For now we have it all in one file that we can easily compile from a command line, see [how it's done in previous lectures](hello_world_dissection.md):
-```cmd
-c++ -std=c++17 chatbot.cpp -o chatbot_example
-```
-
-## Making it a header-only library
-<!-- Show name of the file, change it to hpp, move main to another file -->
-But what if we want to be serious about our development and make a library out of our `Chatbot` class that we can use from our CMake project? Let's start by moving the implementation into a header file by simply renaming our `chatbot.cpp` into `chatbot.hpp`, adding the `#pragma once` or include guards statements to the top of the new header file, and moving the `main` function to some other file, say `main.cpp` that includes `chatbot.hpp`. If we now try to compile `main.cpp` in exactly the same way, it still compiles!
-
-```cmd
-c++ -std=c++17 main.cpp -o chatbot_example
-```
-> :bulb: By the way, all class member functions defined in a header file are implicitly `inline`, so no need to worry about the One Definition Rule (ODR) violations.
-
-We can of course also put the appropriate commands into a `CMakeLists.txt` file:
-<!-- Show code + text that the full project is in the description -->
-<!--
-`CPP_SKIP_SNIPPET`
--->
-```cmake
-# Indicate that we have header-only library
-add_library(chatbot INTERFACE)
-target_link_libraries(chatbot INTERFACE cxx_setup)
-
-# A binary that uses our header-only library
-add_executable(chatbot_example main.cpp)
-target_link_libraries(chatbot_example PRIVATE chatbot cxx_setup)
-```
-> :bulb: If you are confused about the `cxx_setup` part, see the [lecture on CMake](cmake.md)
-
-## Converting it all into a compiled library
-If we only need a header-only library, we could stop there, but sometimes we want a compiled library. For that we would have to split our header file into a header and a source file.
-<!-- Show animation that moves declarations and definitions into separate files -->
-
-> :bulb: Oh, and if you are shaky on the differences between the two or why it is important that the class member functions are implicitly `inline`, do check out my [lecture on various kinds of libraries](headers_and_libraries.md).
-
-Generally speaking, all the data (apart from static data, stay tuned) belongs in the header file.
-
-<!--
-- Use split view between header and cpp ✅
-- Move all the code to the cpp file one by one with zoom ✅
-- Zoom in on prefixes ✅
-- Zoom on usage without prefixes ✅
-- Zoom in on const in both views ✅
--->
-As for the implementation of any methods (and static data, stay tuned) we can move them to the source file, a new `chatbot.cpp` file, leaving only their **declarations** in the header file. In the **definitions**, we must tell the compiler that we are defining not just a free standing function, but one from a class, thus the `Chatbot::` and the `Chatbot::Data::` prefixes. Note also, that we have the `Answer` as a return type of the `GetAnswer` function. For such return types we also have to tell the compiler if they are part of some class, the `Chatbot` class in this example. *Within* the definition of the function we can use these types without the prefix as the compiler already knows that it operates within the namespace of a certain class.
-
-Finally, note how the `const` postfix in functions that need it is present in **both** the header and the source file.
-
-## The final header-source code
-`chatbot.hpp`:
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` chatbot_cmake/chatbot/chatbot.hpp
--->
-```cpp
-#pragma once
-
-#include <string>
-#include <vector>
-
-class Chatbot {
- public:
-  struct Answer {
-    float probability{};
-    std::string text{};
-  };
-
-  struct Data {
-    bool IsValid() const;
-
-    std::vector<std::string> questions{};
-    std::vector<std::string> correct_answers{};
-  };
-
-  void Train(const Data &data);
-
-  Answer GetAnswer(const std::string &question) const;
-
- private:
-  void IngestData(const Data &data);
-
-  int smartness_{};
-};
-```
-
-`chatbot.cpp`:
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` chatbot_cmake/chatbot/chatbot.cpp
--->
-```cpp
-#include <chatbot/chatbot.hpp>
-
-void Chatbot::Train(const Data &data) {
-  if (!data.IsValid()) { return; }
-  IngestData(data);
-}
-
-bool Chatbot::Data::IsValid() const {
-  return questions.size() == correct_answers.size();
-}
-
-Chatbot::Answer Chatbot::GetAnswer(const std::string &question) const {
-  if (smartness_ < 1) { return Answer{0.1, "I don't know"}; }
-  if (smartness_ < 5) { return Answer{0.8, "Yes."}; }
-  if (question.length() > 10) {
-    return Answer{1.0, "You will regret this question..."};
-  }
-  return Answer{1.0, "Can't you ask anything more important?"};
-}
-
-void Chatbot::IngestData(const Data &data) {
-  smartness_ += data.correct_answers.size();
-}
-```
-
-`main.cpp`:
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` chatbot_cmake/chatbot/main.cpp
--->
-```cpp
-#include <chatbot/chatbot.hpp>
-
-#include <iostream>
-
-int main() {
-  Chatbot chatbot{};
-  chatbot.Train({{"How much is 2 + 2?",
-                  "What color is the sky?",
-                  "What is the answer to life and everything?"},
-                 {"4", "It depends", "42"}});
-  const auto question = "Are you self aware?";
-  std::cout << "Asking chatbot: " << question << std::endl;
-  std::cout << "Chatbot answered: " << chatbot.GetAnswer(question).text
-            << std::endl;
-  return 0;
-}
-```
-And that's it. Now we just need to update our `CMakeLists.txt` file, create a compiled library in it and link it to a binary that has the `main` function in it:
-
-Main `CMakeLists.txt` of the project:
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` chatbot_cmake/CMakeLists.txt
--->
-```cmake
-cmake_minimum_required(VERSION 3.16..3.24)
-project(chatbot VERSION 0.0.1
-                    DESCRIPTION "Our first project"
-                    LANGUAGES CXX)
-if(NOT CMAKE_BUILD_TYPE)
-  set(CMAKE_BUILD_TYPE Release CACHE STRING "" FORCE)
-endif()
-message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}")
-
-add_library(cxx_setup INTERFACE)
-target_compile_options(cxx_setup INTERFACE -Wall -Wpedantic -Wextra)
-target_compile_features(cxx_setup INTERFACE cxx_std_17)
-target_include_directories(cxx_setup INTERFACE ${PROJECT_SOURCE_DIR})
-
-add_subdirectory(${PROJECT_NAME})
-```
-
-<!-- Animate updating cmake file -->
-`chatbot/CMakeLists.txt`:
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` chatbot_cmake/chatbot/CMakeLists.txt
-`CPP_RUN_CMD` CWD:chatbot_cmake cmake -S . -B build && cmake --build build -j4
--->
-```cmake
-# Create a compiled library
-add_library(chatbot chatbot.cpp)
-target_link_libraries(chatbot PUBLIC cxx_setup)
-
-# A binary that uses our library
-add_executable(chatbot_example main.cpp)
-target_link_libraries(chatbot_example PRIVATE chatbot cxx_setup)
-```
-
-# Conclusion
-So, you see, there is only some marginal differences here and there but largely the pattern is exactly the same as we have already seen with the free-standing functions. It goes without saying that we can and should also test our classes with some unit testing library like GoogleTest too! I won't do it here but _do_ give it a try on you own. More on that in [one of my previous lectures](googletest.md).
-
-So now we know how to create libraries from the code that lives either in free-standing functions or in our own your classes. We also know how to compile and link all of this code together with CMake, which means that we can write pretty complex projects from scratch while still maintaining a certain level of abstraction and overview over the logic. How cool is that?
-
-I have to give you a short glimpse into what awaits us next! It is a homework where we will put all of this to the test and write a full program that reads an image and pixelates it. So stay tuned for the next video!
diff --git a/lectures/helper.cpp b/lectures/helper.cpp
deleted file mode 100644
index dc55ffa..0000000
--- a/lectures/helper.cpp
+++ /dev/null
@@ -1,21 +0,0 @@
-#include <iostream>
-
-struct Helper {
-  Helper(int number) {
-    std::cout << "Create helper with number: " << number << std::endl;
-  }
-  ~Helper() { std::cout << "Destroy helper" << std::endl; }
-  // 😱 Implement the rest for the rule of all or nothing!
-};
-
-Helper& GetHelper(int number) {
-  // Will only be initialized when encountered for the first time
-  static Helper helper{number};
-  return helper;
-}
-
-int main() {
-  auto& helper_1 = GetHelper(42);
-  auto& helper_2 = GetHelper(23);
-  std::cout << "Is same object: " << (&helper_1 == &helper_2) << std::endl;
-}
diff --git a/lectures/images/C++ForYourselfIcon.png b/lectures/images/C++ForYourselfIcon.png
index b185928..673f7cd 100644
Binary files a/lectures/images/C++ForYourselfIcon.png and b/lectures/images/C++ForYourselfIcon.png differ
diff --git a/lectures/images/CompilationMainWithFooFail.png b/lectures/images/CompilationMainWithFooFail.png
deleted file mode 100644
index 403b58c..0000000
--- a/lectures/images/CompilationMainWithFooFail.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:bf5a3ff978debd3e0b75c86dc98008e246ba1c5f1051370eba07c780fae088af
-size 611947
diff --git a/lectures/images/CompilationProcessEverything.png b/lectures/images/CompilationProcessEverything.png
deleted file mode 100644
index 41f0f56..0000000
--- a/lectures/images/CompilationProcessEverything.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:bb5e5126d35ee4be245135e739036f372e4ebc0d1d855762f5bdb6f1402e494f
-size 503488
diff --git a/lectures/images/CompilationSuccessWithHeaders.png b/lectures/images/CompilationSuccessWithHeaders.png
deleted file mode 100644
index 3ce1e46..0000000
--- a/lectures/images/CompilationSuccessWithHeaders.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:4969f1a60eaa45b74a218052210f0ba7d7b7de4431aa7e8984812480a2b8a922
-size 658726
diff --git a/lectures/images/Compilation_process.png b/lectures/images/Compilation_process.png
deleted file mode 100644
index 678cc6e..0000000
--- a/lectures/images/Compilation_process.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:e884d934a3013e83bbc08cb597ab40cdbc3ec3982704760314f48a336650fcb7
-size 1757797
diff --git a/lectures/images/Compiler.png b/lectures/images/Compiler.png
deleted file mode 100644
index 629ed63..0000000
--- a/lectures/images/Compiler.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:8866bf3b96bfc7b196f012355e07ed75bd8e631858086c76307bd3e5d9cf5100
-size 1597094
diff --git a/lectures/images/CompilerFooNotKnowing.png b/lectures/images/CompilerFooNotKnowing.png
deleted file mode 100644
index f4b8465..0000000
--- a/lectures/images/CompilerFooNotKnowing.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:f3067f5e8074214417243087f403d195e058956eb9b70b5801efdf18951d60c0
-size 454163
diff --git a/lectures/images/CompilerIndepth.png b/lectures/images/CompilerIndepth.png
deleted file mode 100644
index 82b23e1..0000000
--- a/lectures/images/CompilerIndepth.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:ccb10e98a823e0d9521cd53d0d78e5579ca18d5e68672350f8510a2f81c7ac64
-size 519786
diff --git a/lectures/images/cats.gif b/lectures/images/cats.gif
deleted file mode 100644
index 39558e3..0000000
--- a/lectures/images/cats.gif
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:3b13193e070b732fb91d3a8e5f0e097dc59e8c4d2c53983fca409bf71e9f07bf
-size 17252400
diff --git a/lectures/images/cmake.png b/lectures/images/cmake.png
deleted file mode 100644
index c85fc95..0000000
--- a/lectures/images/cmake.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:cf171d3ce86beae729833c9df905389ad89689c2a22bf8c10da12dd822d0e206
-size 14727
diff --git a/lectures/images/constexpr_diagram.png b/lectures/images/constexpr_diagram.png
index 731c355..f7154b2 100644
Binary files a/lectures/images/constexpr_diagram.png and b/lectures/images/constexpr_diagram.png differ
diff --git a/lectures/images/dangling_pointer.mp4 b/lectures/images/dangling_pointer.mp4
deleted file mode 100644
index 1f5aaeb..0000000
--- a/lectures/images/dangling_pointer.mp4
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:5a3a3569e1fb6729f83a5dd14d8746f12ca11d0a30bf9dea5a0372d49dd4caf1
-size 1272021
diff --git a/lectures/images/destructor.mp4 b/lectures/images/destructor.mp4
deleted file mode 100644
index 59b2345..0000000
--- a/lectures/images/destructor.mp4
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:25b4b3448439a679f90a119fabc3ec6594a5580fc3808257cdc94732c305ba16
-size 476385
diff --git a/lectures/images/docs.png b/lectures/images/docs.png
deleted file mode 100644
index 1640d62..0000000
--- a/lectures/images/docs.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:86d8bc75f4c9e9068cf034785c799b8fe6aee80e6e9c4d95c23f6b912d50a7db
-size 300075
diff --git a/lectures/images/error.png.webp b/lectures/images/error.png.webp
deleted file mode 100644
index 1c38906..0000000
Binary files a/lectures/images/error.png.webp and /dev/null differ
diff --git a/lectures/images/follow_deer.jpg b/lectures/images/follow_deer.jpg
deleted file mode 100644
index bc5d9eb..0000000
--- a/lectures/images/follow_deer.jpg
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:07dcb768fce612e7fd236ef227bea4a2438eafebf7ad5064e25b2103ae11d488
-size 49137
diff --git a/lectures/images/game_loss.png b/lectures/images/game_loss.png
deleted file mode 100644
index 8fd4a1f..0000000
--- a/lectures/images/game_loss.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:e051e6fdf633d3a9d9c72b165273a789e169152c2320c01e5d28abcd6865f898
-size 122750
diff --git a/lectures/images/game_win.png b/lectures/images/game_win.png
deleted file mode 100644
index 1ba4d99..0000000
--- a/lectures/images/game_win.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:ef1bc702765b98ff4e1711a6a0dacb2808285a38286f94b4446279ce673fcfb3
-size 132390
diff --git a/lectures/images/gc.png b/lectures/images/gc.png
deleted file mode 100644
index 7d540f6..0000000
--- a/lectures/images/gc.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:f72247545638ec3369f3370c090486d075059265054c237df20a3950b0c81f8c
-size 151141
diff --git a/lectures/images/heap-coins.png b/lectures/images/heap-coins.png
deleted file mode 100644
index 7859cb7..0000000
--- a/lectures/images/heap-coins.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:1799ef9fd500c880492ad6394e60f435dfc59e90de69d4cafab0f60580b3f6b2
-size 1964980
diff --git a/lectures/images/im-not-sure.jpg b/lectures/images/im-not-sure.jpg
deleted file mode 100644
index 59a916d..0000000
--- a/lectures/images/im-not-sure.jpg
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:32b49193e176e202c85f30a9ac53f78d00c893c87c83b3773d015e09b0ff529a
-size 32116
diff --git a/lectures/images/memory_ub.png b/lectures/images/memory_ub.png
deleted file mode 100644
index e7455df..0000000
--- a/lectures/images/memory_ub.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:f5a77980c57367fb4094e2814fd078fdb135ea150f7abfe64af5e27edc40d939
-size 48636
diff --git a/lectures/images/pass_by_ref.gif b/lectures/images/pass_by_ref.gif
deleted file mode 100644
index 6abc657..0000000
--- a/lectures/images/pass_by_ref.gif
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:2dae74d031158bd353e8cef303329ca86b4f70f6bd9f68f2d86e2c90844e678f
-size 119091
diff --git a/lectures/images/program_lifetime.png b/lectures/images/program_lifetime.png
deleted file mode 100644
index 4b806b0..0000000
--- a/lectures/images/program_lifetime.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:7bb709f8f1d5e25573d15180732138d488abb8608eded5cc09d4c863c80a646f
-size 67739
diff --git a/lectures/images/random_number.png b/lectures/images/random_number.png
deleted file mode 100644
index e5180c5..0000000
--- a/lectures/images/random_number.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:07668fc814bf21efb1b5451f1ae4e80d47959d97084cb654d41e825c5f36d2e7
-size 7457
diff --git a/lectures/images/shallow_assignment.mp4 b/lectures/images/shallow_assignment.mp4
deleted file mode 100644
index 8108423..0000000
--- a/lectures/images/shallow_assignment.mp4
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:e1097d1a82f30716c3ec57010c5ddc00cf22c04242b0c1c7ec8977b97460561a
-size 396710
diff --git a/lectures/images/stack-coins.png b/lectures/images/stack-coins.png
deleted file mode 100644
index 9fe1159..0000000
--- a/lectures/images/stack-coins.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:b8f874bfd3ba4550ba3df07848ae792e343629c21b088179d7ef93f1e96d9a9e
-size 2467986
diff --git a/lectures/images/static_foo_twice.png b/lectures/images/static_foo_twice.png
deleted file mode 100644
index 7db6037..0000000
--- a/lectures/images/static_foo_twice.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:270791ba665af666e0cda6b7b7ae6b0d0a570e7207193cb0d3f955dc4c654e3d
-size 88092
diff --git a/lectures/images/static_storage.png b/lectures/images/static_storage.png
deleted file mode 100644
index 88f23f3..0000000
--- a/lectures/images/static_storage.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:e4407aa60e93a49ade79e9594e6ce9844a5e1b0f2b1c470cc20b76b3fc242f9f
-size 80751
diff --git a/lectures/images/static_storage_function.png b/lectures/images/static_storage_function.png
deleted file mode 100644
index 579ee00..0000000
--- a/lectures/images/static_storage_function.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:9e523b9cd8cbac6118e2573940ccef9f1fc92ae076a2fc226799fa6eca5eb884
-size 80982
diff --git a/lectures/images/template_mistakes_meme.jpg b/lectures/images/template_mistakes_meme.jpg
deleted file mode 100644
index 0332584..0000000
--- a/lectures/images/template_mistakes_meme.jpg
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:4718e765db2fbd5cbb08018b4905c900363700e5c5117a189dd16964ea68387c
-size 83914
diff --git a/lectures/images/templates_meme.jpg b/lectures/images/templates_meme.jpg
deleted file mode 100644
index cb54d27..0000000
--- a/lectures/images/templates_meme.jpg
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:7fcbc8f44a48c1fba10fcb414e80e1889e52a4170bd65532b9931559cbb4f002
-size 50830
diff --git a/lectures/images/the-end.jpg b/lectures/images/the-end.jpg
new file mode 100644
index 0000000..a485c66
Binary files /dev/null and b/lectures/images/the-end.jpg differ
diff --git a/lectures/images/this-is-fine.gif b/lectures/images/this-is-fine.gif
deleted file mode 100644
index 21440fc..0000000
--- a/lectures/images/this-is-fine.gif
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:7a4900e296b46ad991943891a61cea50561e97d79175da8cf78ef1e2906c249c
-size 2561940
diff --git a/lectures/images/types_diagram.png b/lectures/images/types_diagram.png
index 8ab17f8..c9390d7 100644
Binary files a/lectures/images/types_diagram.png and b/lectures/images/types_diagram.png differ
diff --git a/lectures/images/ub.jpg b/lectures/images/ub.jpg
deleted file mode 100644
index 60597c4..0000000
--- a/lectures/images/ub.jpg
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:fe10a332383ccb2329c15ff3c3fc7b71d3c4bb6db23ec120edd87f588418e894
-size 45950
diff --git a/lectures/images/vtable.png b/lectures/images/vtable.png
deleted file mode 100644
index c250047..0000000
--- a/lectures/images/vtable.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:509d73c2ccb16cc841f04b596e25c98449021a83d10e03f38112342cd703ab48
-size 417384
diff --git a/lectures/images/while_true.gif b/lectures/images/while_true.gif
deleted file mode 100644
index 33d01e7..0000000
--- a/lectures/images/while_true.gif
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:d1eec0dd18749ba32ed96efe753ec7fc9e678f5258603918b051d8e95e84f918
-size 467215
diff --git a/lectures/images/whywhy.png b/lectures/images/whywhy.png
deleted file mode 100644
index bb8ddac..0000000
--- a/lectures/images/whywhy.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:3a2bdfb510fe6e0c40591367ac7278fe8ac9ac4bfd7de9cf4ade4c7aebb07052
-size 1114682
diff --git a/lectures/inheritance.md b/lectures/inheritance.md
deleted file mode 100644
index 65f087a..0000000
--- a/lectures/inheritance.md
+++ /dev/null
@@ -1,984 +0,0 @@
-Inheritance and the idea of OOP
---
-
-<p align="center">
-  <a href="https://youtu.be/oUALDqvCbWs"><img src="https://img.youtube.com/vi/oUALDqvCbWs/maxresdefault.jpg" alt="Video" align="right" width=50% style="margin: 0.5rem"></a>
-</p>
-
-- [Inheritance and the idea of OOP](#inheritance-and-the-idea-of-oop)
-- [Inheritance enables dependency inversion](#inheritance-enables-dependency-inversion)
-- [The idea behind dependency inversion](#the-idea-behind-dependency-inversion)
-- [Similarity to static polymorphism with templates](#similarity-to-static-polymorphism-with-templates)
-- [How inheritance looks in C++](#how-inheritance-looks-in-c)
-  - [Implementation inheritance](#implementation-inheritance)
-    - [Access control with inheritance](#access-control-with-inheritance)
-    - [Implicit upcasting](#implicit-upcasting)
-    - [Real-world example of implementation inheritance](#real-world-example-of-implementation-inheritance)
-  - [Using `virtual` for interface inheritance and proper polymorphism](#using-virtual-for-interface-inheritance-and-proper-polymorphism)
-  - [How interface inheritance works](#how-interface-inheritance-works)
-  - [Runtime and memory overhead of using virtual](#runtime-and-memory-overhead-of-using-virtual)
-  - [Things to know about classes with `virtual` methods](#things-to-know-about-classes-with-virtual-methods)
-    - [A `virtual` destructor](#a-virtual-destructor)
-    - [Delete other special methods for polymorphic classes](#delete-other-special-methods-for-polymorphic-classes)
-  - [Downcasting using the `dynamic_cast`](#downcasting-using-the-dynamic_cast)
-  - [Don't mix implementation and interface inheritance](#dont-mix-implementation-and-interface-inheritance)
-  - [Implement pure interfaces](#implement-pure-interfaces)
-  - [Keyword `final`](#keyword-final)
-- [Simple polymorphic class example following best practices](#simple-polymorphic-class-example-following-best-practices)
-- [Multiple inheritance](#multiple-inheritance)
-- [Detailed `Image` example following best practices](#detailed-image-example-following-best-practices)
-
-
-Inheritance is an important concept that enables a lot of techniques that we use in C++. It is also **the** mechanism for **dynamic polymorphism** which is one of the staples that allows us to think about design of our systems in very abstract and elegant ways within the C++ domain, enabling **Object Oriented Programming** or OOP.
-
-Largely speaking, we distinguish between two types of inheritance:
-- Implementation inheritance
-- Interface inheritance
-
-So let's talk about these: how interface inheritance enables abstract object oriented design and why we mostly don't use the implementation inheritance!
-
-<!-- Intro -->
-
-## Inheritance enables dependency inversion
-Essentially, we mostly care about inheritance because it, allows us to **invert dependencies** between our components. You might have heard people talking about this as, well, the **dependency inversion principle**. This term might sound a bit scary but the concept under the hood actually makes a lot of sense!
-
-Let's look at what it really means by following a small example.
-
-Imagine that we have a class `Image` that represents its pixel values as a [`std::vector`](more_useful_types.md) of colors represented by a class `Color`. For the sake of this example, it also has a constructor and a `Save` method that both make use of another class `JpegIo` that allows us to read and write image-like data in JPEG format. We skip a lot of details of the implementation because we only want to showcase the dependency inversion principle here.
-<!--
-`CPP_SETUP_START`
-#include <vector>
-#include <filesystem>
-using Color = int;
-
-struct JpegIo {
-  void Write(const std::filesystem::path&, const std::vector<Color>&) const {}
-  std::vector<Color> Read(const std::filesystem::path&) const {}
-};
-
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` inheritance/main.cpp
-`CPP_RUN_CMD` CWD:inheritance c++ -std=c++17 main.cpp
--->
-```cpp
-#include <filesystem>
-#include <vector>
-
-class Image {
- public:
-  Image(const std::filesystem::path& path, const JpegIo& io) {
-    pixels_ = io.Read(path);
-  }
-
-  void Save(const std::filesystem::path& path, const JpegIo& io) const {
-    io.Write(path, pixels_);
-  }
-
- private:
-  std::vector<Color> pixels_{};
-};
-
-int main() {
-  const Image image{"path.jpeg", JpegIo{}};
-  image.Save("other_path.jpeg", JpegIo{});
-  return 0;
-}
-```
-Now, we can say that the `Image` class **depends on** `JpegIo` class because `Image` uses the functionality of the `JpegIo` in its implementation. We can also think of this in terms of their public interfaces, i.e., their functions and how changes to these would propagate through our architecture. If a `Read` or `Write` function of the `JpegIo` class changes, we _will have to change_ the implementation of the `Image`, but if just the public interface of the `Image` changes, no changes are required on the `JpegIo` side.
-```mermaid
-graph LR
-  A[<code>Image</code>] --> B[<code>JpegIo</code>]
-```
-
-Such a dependency in itself might be completely OK if there are no changes expected from a system that we are designing.
-
-However, requiring that there would be no changes in the whole future lifetime of a system is a _very strong requirement_. And, as such, it is also the one that rarely holds. It happens often that systems actually _need_ to change and even for the most experienced folks these changes are hard to anticipate. We are just not that good at predicting the future. :shrug:
-
-As an example of one such change, it is absolutely conceivable that we might want to replace the `JpegIo` with another class, like `PngIo` that allows us to read and write images in a PNG format.
-```mermaid
-graph LR
-  A[<code>Image</code>] --> B[<code>PngIo</code>]
-```
-<!--
-`CPP_SETUP_START`
-#include <vector>
-#include <filesystem>
-using Color = int;
-
-struct PngIo {
-  void Write(const std::filesystem::path&, const std::vector<Color>&) const {}
-  std::vector<Color> Read(const std::filesystem::path&) const {}
-};
-
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` inheritance/main.cpp
-`CPP_RUN_CMD` CWD:inheritance c++ -std=c++17 main.cpp
--->
-```cpp
-#include <filesystem>
-#include <vector>
-
-class Image {
- public:
-  Image(const std::filesystem::path& path, const PngIo& io) {
-    pixels_ = io.Read(path);
-  }
-
-  void Save(const std::filesystem::path& path, const PngIo& io) const {
-    io.Write(path, pixels_);
-  }
-
- private:
-  std::vector<Color> pixels_{};
-};
-
-int main() {
-  const Image image{"path.png", PngIo{}};
-  image.Save("other_path.png", PngIo{});
-  return 0;
-}
-```
-Furthermore, we might need to be able to change the io strategy used in the `Image` class at runtime, allowing to pick the one that we want in any particular situation based, say, on user actions at runtime. Currently, to allow for this, we would have to rewrite the `Image` class and even change its public interface to depend on more io components, which would make our design quite rigid and brittle at the same time.
-```mermaid
-graph BT
-  A[<code>Image</code>] --> B[<code>PngIo</code>]
-  A[<code>Image</code>] --> C[<code>JpegIo</code>]
-  A[<code>Image</code>] --> D[<code>...</code>]
-```
-
-<!-- Use stock footage -->
-Add on top of this the fact that different components of complex systems are often developed by different people or even teams, which makes propagating changes even harder, and we start getting the feeling why we often want to avoid this type of strong inter-dependency between the components.
-
-## The idea behind dependency inversion
-Dependency inversion allows us to avoid all of these pitfalls. Instead of requiring the `Image` to rely on the `PngIo` or `JpegIo` directly, we can make all of these classes rely on an agreed upon **interface**, say `IoInterface`, thus inverting the dependencies - there is no path along the lines in our diagram from `Image` to `JpegIo` or to `PngIo` anymore!
-```mermaid
-graph BT
-  A[<code>Image</code>] -->|depends on| I[<code>IoInterface</code>]
-  B[<code>JpegIo</code>] -.->|implements| I[<code>IoInterface</code>]
-  C[<code>PngIo</code>] -.->|implements| I[<code>IoInterface</code>]
-```
-Here, the `Image` class **calls** the public methods of the `IoInterface`, while the `JpegIo` and `PngIo` classes **implement** this interface.
-
-Coming back to the code, our `Image` now receives a reference (or a pointer) to an `IoInterface` rather than on a concrete implementation:
-<!--
-`CPP_SETUP_START`
-
-#include <filesystem>
-#include <iostream>
-#include <vector>
-
-using Color = int;
-
-struct Noncopyable {
-    Noncopyable() = default;
-    Noncopyable(const Noncopyable&) = delete;
-    Noncopyable(Noncopyable&&) = delete;
-    Noncopyable& operator=(const Noncopyable&) = delete;
-    Noncopyable& operator=(Noncopyable&&) = delete;
-    ~Noncopyable() = default;
-};
-
-struct IoInterface : public Noncopyable {
-    virtual std::vector<Color> Read(
-        const std::filesystem::path& path) const = 0;
-    virtual void Write(const std::filesystem::path& path,
-                       const std::vector<Color>& data) const = 0;
-    virtual ~IoInterface() = default;
-};
-
-struct JpegIo final : public IoInterface {
-    std::vector<Color> Read(
-        const std::filesystem::path& path) const override {
-        std::cout << "Reading JPEG from path: " << path << std::endl;
-        return {};
-    }
-    virtual void Write(const std::filesystem::path& path,
-                       const std::vector<Color>& data) const override {
-        std::cout << "Writing JPEG to path: " << path << std::endl;
-    }
-};
-
-struct PngIo final : public IoInterface {
-    std::vector<Color> Read(
-        const std::filesystem::path& path) const override {
-        std::cout << "Reading PNG from path: " << path << std::endl;
-        return {};
-    }
-    virtual void Write(const std::filesystem::path& path,
-                       const std::vector<Color>& data) const override {
-        std::cout << "Writing PNG to path: " << path << std::endl;
-    }
-};
-
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` inheritance_polymorphic/main.cpp
-`CPP_RUN_CMD` CWD:inheritance_polymorphic c++ -std=c++17 main.cpp
--->
-```cpp
-class Image {
- public:
-  Image(const std::filesystem::path& path, const IoInterface& io) {
-    pixels_ = io.Read(path);
-  }
-
-  void Save(const std::filesystem::path& path, const IoInterface& io) const {
-    io.Write(path, pixels_);
-  }
-
- private:
-  std::vector<Color> pixels_{};
-};
-
-int main() {
-  const Image image{"path.jpeg", JpegIo{}};
-  image.Save("other_path.png", PngIo{});
-}
-```
-Once we design the `PngIo` and `JpegIo` classes to implement the `IoInterface` we are able to pass them interchangeably in place of the `IoInterface` reference! Look how easy it is now to change the behavior of our `Image` without changing its code! We just pass a new **strategy** (i.e., one of the classes that implement our `IoInterface`) into it and it magically works! And if we would want to work with some other image type we could just add another class that implements `IoInterface` and pass it instead! We could even condition the choice of the io strategy on a user action now! Neat, right?
-
-In addition to all of this, as long as we designed a good interface (which to me is arguably the hardest part of designing software), we can make changes to the `JpegIo`, `PngIo` and `Image` classes independently from each other as long as they communicate exclusively through the `IoInterface`.
-
-🚨 So we really care about inheritance because it is necessary for **this form of dynamic polymorphism**, which, along with encapsulation enables the **O**bject **O**riented **P**rogramming, or **OOP**! And just to make sure we're on the same page, polymorphism stands for "having multiple forms". In our case, the reference to an `IoInterface` can take many "forms": `JpegIo`, `PngIo` or any other implementation of this interface.
-
-As you have undoubtedly noticed, I have not provided any implementation for our io strategy classes just yet as we only cared about the "why" here, not the "how". We will of course fill all the details in towards the end of this lecture and for that we'll need to take a step back and see how inheritance works in modern C++, because to achieve the behavior we've just seen in C++, **we need inheritance!**
-
-## Similarity to static polymorphism with templates
-Now, those of you who were careful to follow the [lectures on templates in this course](templates_why.md) might get a feeling that, design-wise, something similar should be possible to achieve using templates too. After all, we did look at how we could replace an algorithm using a template strategy before. And you _are_ right! We _can_ do it with templates **at compile time** but **not at runtime**.
-<!--
-`CPP_SETUP_START`
-#include <vector>
-#include <filesystem>
-using Color = int;
-
-class JpegSavingStrategy {
-  public:
-    JpegSavingStrategy(const std::filesystem::path& path) : path_{path} {}
-
-    void Save(const std::vector<Color>& pixels) const {
-      // Logic to save pixels to path_ as jpeg data.
-    }
-
-  private:
-    std::filesystem::path path_{};
-};
-
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` inheritance_template/main.cpp
-`CPP_RUN_CMD` CWD:inheritance_template c++ -std=c++17 main.cpp
--->
-```cpp
-// Assuming the JpegSavingStrategy is implemented.
-
-class Image {
- public:
-  template <typename SavingStrategy>
-  void Save(const SavingStrategy& strategy) const {
-    strategy.Save(pixels_);
-  }
-
- private:
-  std::vector<Color> pixels_{};
-};
-
-int main() {
-  Image image{}; // Somehow create an image.
-  image.Save(JpegSavingStrategy{"image.jpg"});
-  return 0;
-}
-```
-Depending on our goals this might be more or less suitable for our needs. So, to cover the "runtime" path today we focus on dynamic polymorphism and how inheritance enables it.
-
-## How inheritance looks in C++
-### Implementation inheritance
-We'll start talking about inheritance by talking about its simplest form, the so-called **implementation inheritance**. It is designed to simply extend one class, say `Base` with another, say `Derived`. We say that a `Derived` class inherits from a `Base` class which implies that any object of the `Derived` class contains a full copy of the `Base` class, including all of its methods and appending the data of the `Derived` class to the data stored in the `Base` object.
-<!-- TODO: add image -->
-
-Let's show it on a simple example as we always do. Let's say we have two structs: `Base` and `Derived` that inherits from `Base`. We show the inheritance by a `:` symbol after the name of the derived class followed by the name of its parent class, along with some access modifiers, here `public`, more on that later.
-
-These classes have their corresponding methods `BaseMethod` and `DerivedMethod` and some data, which we keep `public` here for illustration purposes. They also each have a function `DoSmth` with the same signature. We then create an object of the `Derived` class and call both `Base`-specific and `Derived`-specific methods on it as well as print the address of the data it contains.
-```cpp
-#include <iostream>
-
-// Using struct here but the same holds for classes
-struct Base {
-  void DoSmth() const { std::cout << "Base DoSmth" << std::endl; }
-  void BaseMethod() const { std::cout << "BaseMethod" << std::endl; }
-  // Doesn't have to be int
-  int base_data{};
-};
-
-// Using struct here but the same holds for classes
-struct Derived : public Base {
-  void DoSmth() const { std::cout << "Derived DoSmth" << std::endl; }
-  void DerivedMethod() const { std::cout << "DerivedMethod" << std::endl; }
-  // Also can be any other type
-  float derived_data{};
-};
-
-int main() {
-  const Derived object{};
-  object.BaseMethod();
-  object.DerivedMethod();
-  object.DoSmth();
-  std::cout << "&object.base_data:    " << &object.base_data << std::endl;
-  std::cout << "&object.derived_data: " << &object.derived_data << std::endl;
-}
-```
-Looking at the output this code produces, we see that we can call both the `Base`-specific and the `Derived`-specific methods on an object of `Derived` type.
-```output
-BaseMethod
-DerivedMethod
-Derived DoSmth
-&object.base_data:    0x7ffe8fff82d8
-&object.derived_data: 0x7ffe8fff82dc
-```
-Furthermore, because we work with an object of the `Derived` type, the `DoSmth` function shadows its counterpart from the `Base` class. As for the data, looking at their address, we see that the `Derived`-defined data follow right after the `Base`-defined ones.
-
-#### Access control with inheritance
-Now is probably a good time for a relatively short interlude about access control in classes when inheritance is at play. First of all, there is another class access modifier that we did not talk about. Before, we talked about `private` and `public` access to class methods and data. There is one more access modifier to think of - `protected`. It works just like private for anybody trying to access data from the outside of class hierarchy, while within the class hierarchy the data is accessible.
-```cpp
-#include <iostream>
-
-// Using struct here but the same holds for classes
-class Base {
- public:
-  int public_base_data{};
- protected:
-  int protected_base_data{};
- private:
-  int private_base_data{};
-};
-
-// Using struct here but the same holds for classes
-struct Derived : public Base {
-  void PrintData() const {
-    std::cout << "public_base_data: " << public_base_data
-              << " protected_base_data: " << protected_base_data << std::endl;
-    // ❌ Cannot access private_base_data from here!
-  }
-};
-
-int main() {
-  const Derived object{};
-  std::cout << "object.public_base_data: " << object.public_base_data
-            << std::endl;
-  // ❌ Cannot access object.protected_base_data from here!
-  // ❌ Cannot access object.private_base_data from here!
-  return 0;
-}
-```
-That all being said, the Core Guidelines recommend to [avoid using `protected` data](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#c133-avoid-protected-data), so please be mindful of this.
-
-You might have also noticed that we used exclusively the word `public` after the `:` symbol when using inheritance. But we could also technically use `protected` or `private` there. The difference is the following:
-- ✅ `[most common]` Using `public` maintains the access levels of all data and methods of the base class, **mimics an "is a" relationship** between classes. Arguably this is the relationship we mostly want to achieve.
-- Using `protected` makes all the `public` attributes of the base class `protected` and leaves its `protected` and `private` members as is.
-- Using `private` makes all the accessible members of the base class `private`, i.e., invisible to anybody including its own descendants.
-
-All in all, we mostly use `public` inheritance and the reason is that composition usually is more readable and less error prone while achieves the same things as `private` and, to some degree, `protected` inheritance. It makes sense, if we think about it - storing an object of another class achieves nearly the same as inheriting privately from such an object. In both cases we can access that other class while not exposing any of its data or methods to the outside! The main difference is that with composition we only can access the stored object's public interface, while inheritance also gives us access the protected part of the class we inherit from.
-
-As a small example, if we wanted to implement a class that would store just integer numbers by reusing the `std::vector<int>` implementation we could go either by privately inheriting from `std::vector<int>` and exposing its base `push_back` method or by using composition and having a `data_` member of type `std::vector<int>`, which would require us to implement our own `push_back` function.
-```cpp
-#include <vector>
-
-class IntVectorInheritance : private std::vector<int> {
- public:
-  using std::vector<int>::push_back;
-};
-
-class IntVectorComposition {
- public:
-  void push_back(int number) { data_.push_back(number); }
-
- private:
-  std::vector<int> data_{};
-};
-
-int main() {
-  IntVectorInheritance vector_inheritance{};
-  vector_inheritance.push_back(42);
-
-  IntVectorComposition vector_composition{};
-  vector_composition.push_back(42);
-}
-```
-I believe that people are split on this issue. Some argue that `private` inheritance is superior here as it allows us to avoid boilerplate code of reimplementing existing functions that are already implemented better than most of us can implement them, while the other argue that composition is superior instead as it gives us more control and keeps things a bit more explicit. I, for one, lean closer to the second group.
-<!-- But please tell me what you think! Which way do you prefer? Why? -->
-
-Anyway, in the remainder of this lecture we will assume that whenever we mention "inheritance" we actually mean its `public` flavor.
-
-#### Implicit upcasting
-Now one of the defining features of how inheritance was designed in C++ is that a pointer or a reference to any derived class can be **implicitly converted** to a pointer or a reference of the base class. This is commonly called **upcasting**, "up" referring to the dependency diagrams usually shown in such a way that an arrow points from `Derived` below to `Base` above.
-
-```mermaid
-graph BT
-  Derived --> Base
-```
-
-Let's see how it works by changing our main function in our implementation inheritance example. We can add a `Base` reference that will point to a `Derived` object. And, of course, we can call only `Base`-specific methods on this reference:
-<!--
-`CPP_SETUP_START`
-#include <iostream>
-
-// Using struct here but the same holds for classes
-struct Base {
-  void DoSmth() const { std::cout << "Base DoSmth" << std::endl; }
-  void BaseMethod() const { std::cout << "BaseMethod" << std::endl; }
-  // Doesn't have to be int
-  int base_data{};
-};
-
-// Using struct here but the same holds for classes
-struct Derived : public Base {
-  void DoSmth() const { std::cout << "Derived DoSmth" << std::endl; }
-  void DerivedMethod() const { std::cout << "DerivedMethod" << std::endl; }
-  // Also can be any other type
-  float derived_data{};
-};
-
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` inheritance_using_base_ref/main.cpp
-`CPP_RUN_CMD` CWD:inheritance_using_base_ref c++ -std=c++17 main.cpp
--->
-```cpp
-int main() {
-  const Derived derived{};
-  const Base& base{derived};
-  base.BaseMethod();
-  base.DoSmth();
-}
-```
-While this is neat, it does not really bring us much closer to our goal of being able to abstract the implementation away behind a pointer. You see, the `Base` reference "forgets" that it was created from a `Derived` object and so the `DoSmth` method calls its `Base` implementation. So such simple inheritance _is quite limited_.
-
-:bulb: To actually be able to define and implement an interface like the one we talked about before, we will need to use **`virtual` functions**.
-
-#### Real-world example of implementation inheritance
-But before we do implement such an interface, I want to briefly mentions some legitimate uses of implementation inheritance that I've encountered. The only real-world examples that come to mind are the implementation of various [type traits](templates_how_classes.md#type-traits-and-how-to-implement-them-using-template-specialization) and maybe the [Curiously Recurring Template Pattern](https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern), or CRTP. I will not focus on CRTP here <!--, feel free to read up on it following the link in the description to this video, --> but the usage of implementation inheritance in type traits is quite common and I'd like to briefly look at it here. So I would like to return to a small piece of code we wrote when we talked about [type traits](templates_how_classes.md#type-traits-and-how-to-implement-them-using-template-specialization) before.
-
-This code shows our custom implementation of the [`std::is_integral`](https://en.cppreference.com/w/cpp/types/is_integral) type trait that checks if a type provided to it represents integer numbers.
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` inheritance_simple_trait/is_integral.cpp
-`CPP_RUN_CMD` CWD:inheritance_simple_trait c++ -std=c++17 -c is_integral.cpp
--->
-```cpp
-template <typename T>
-struct is_integral {
-  static constexpr inline bool value{};
-};
-```
-Such primary pattern implementation is perfectly fine but if we look at the standard library implementation it is actually implemented differently - through inheritance!
-
-You see, there is another trait [`std::integral_constant`](https://en.cppreference.com/w/cpp/types/integral_constant), which furthermore has `std::true_type` and `std::false_type` specializations. The `std::integral_constant` trait already has a `static` member `value` defined with all the current best practices in mind, so why not reuse it?
-
-And we _can_ reuse these already defined type traits by using implementation inheritance:
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` inheritance_traits/main.cpp
-`CPP_RUN_CMD` CWD:inheritance_traits c++ -std=c++17 -c main.cpp
--->
-```cpp
-template<class T, T v>
-struct integral_constant {
-    static constexpr inline T value = v;
-};
-
-using true_type = integral_constant<bool, true>;
-using false_type = integral_constant<bool, false>;
-
-template <typename T>
-struct is_integral : public false_type {};
-
-// Specializations for any types we deem integral.
-template <>
-struct is_integral<int> : public true_type {};
-
-static_assert(is_integral<int>::value);
-static_assert(is_integral<float>::value == false);
-```
-Here, we inherit our `struct` `is_integral` from the `false_type` **base** class. This has the effect that our `is_integral` struct gains the `value` that holds `false`. And, likewise, we can now specialize our struct for any type we want to be marked as integral type using another typedef `true_type`.
-
-This is really the only use case in which implementation inheritance is routinely used in modern C++.
-<!-- But if you know of other common examples, please tell me what they are in the comments! -->
-
-### Using `virtual` for interface inheritance and proper polymorphism
-Now that we know what implementation inheritance is useful for and what its limits, are we can focus on what we really want. Which is to enable dynamic polymorphism! To make sure that when we call a function through a base class reference or pointer a correct function from a derived class is called depending on which type in the class hierarchy was used to create the base object reference or pointer in the first place!
-
-For that we have to use the keyword `virtual` when declaring our `Base` function and `override` when declaring it in the `Derived` class. Note, that should we `override` a non-`virtual` function, we'll get an error!
-```cpp
-#include <iostream>
-
-// 😱 We do not follow best practices for simplicity here.
-// This struct misses lots of special functions.
-// Some of them must be virtual, some deleted. Stay tuned.
-struct Base {
-  virtual void DoSmth() const { std::cout << "Base DoSmth" << std::endl; }
-};
-
-// 😱 We do not follow best practices for simplicity here.
-// This struct misses lots of special functions.
-// Some of them must be virtual, some deleted. Stay tuned.
-struct Derived : public Base {
-  void DoSmth() const override { std::cout << "Derived DoSmth" << std::endl; }
-};
-
-int main() {
-  const Derived derived{};
-  const Base base{};
-  const Base& base_ref = derived;
-  base.DoSmth();      // Calls Base implementation.
-  derived.DoSmth();   // Calls Derived implementation.
-  base_ref.DoSmth();  // Calls Derived implementation.
-}
-```
-This works like magic! Now the `Base` reference "remembers" that it was created from a `Derived` object and when we call the `DoSmth` function it calls the `Derived` one! This is the core principle that enables **dynamic polymorphism** and **object oriented programming** in C++.
-
-### How interface inheritance works
-Now that we know that it works, let us dig a bit into **how** it is implemented under the hood. How does our reference "remember" that it was created from a derived object?
-
-And the answer is that it knows this "by looking up the correct function to call in a [**virtual method table**](https://en.wikipedia.org/wiki/Virtual_method_table), or a **vTable**".
-
-The vTable is not magic - it is just a table of pointers to functions that can be queried by a function name. Let's extend our example a little to see what happens under the hood when we declare and call `virtual` functions.
-
-
-![](images/vtable.png)
-
-Whenever a compiler compiles a class that has any `virtual` functions, it creates a vTable for that class and adds a hidden pointer member to the base of the corresponding class hierarchy, which makes sure that all the classes in the hierarchy have this vTable pointer.
-
-Now, if we create a `Derived` object, its vTable pointer points to the vTable that corresponds to the `Derived` class. The trick here is that even if we refer to this `Derived` object by a `Base` reference, this `Base` reference still has the access to the vTable pointer as it actually _is_ defined in the `Base` class! So if we call the `DoSmth` function through the `Base` reference (or a pointer for that matter), the compiler knows that because it is a `virtual` function, we have to follow the vTable pointer to find the correct `DoSmth` function in the vTable, in this case the `Derived::DoSmth`, and call it.
-
-As a tiny exercise, think what will happen if we set the `base_ref` to point to an object of `Base` class instead.
-<!-- Comment below this video with your answer! -->
-
-### Runtime and memory overhead of using virtual
-This implementation is very neat but there is no free lunch! We pay for this flexibility both with memory and a runtime overhead.
-
-As we've just discussed, every object of a class that has at least one `virtual` function must store a pointer to its vTable. That pointer occupies memory, usually 8 bytes.
-```cpp
-#include <iostream>
-
-struct WithoutVirtual {
-  void Foo() {}
-};
-
-struct WithVirtual {
-  virtual void Foo() {}
-};
-
-int main() {
-  std::cout << "Size of WithoutVirtual: " << sizeof(WithoutVirtual) << std::endl;
-  std::cout << "Size of WithVirtual: " << sizeof(WithVirtual) << std::endl;
-}
-```
-While it doesn't seem like much it might become an issue if we need a lot of such objects. So much so that it might become a serious limitation.
-
-And speaking of limitations, as we've just mentioned, the selection of which function to call happens at runtime, that means that the compiler generally doesn't know which `virtual` function will be called and so this limits its optimization capabilities.
-
-### Things to know about classes with `virtual` methods
-In addition to that, adding `virtual` functions to classes introduces some constraints on how we should use these classes and creates a couple of pitfalls that we should be aware of. In the previous examples we omitted quite some details and it is time we cover those details now.
-
-#### A `virtual` destructor
-Generally speaking, every class that has a `virtual` function **must have a [`virtual` destructor](https://en.cppreference.com/w/cpp/language/virtual#Virtual_destructor)**. Even though destructors are not inherited, if a base class declares its destructor `virtual`, the derived destructor always overrides it. The reason why this is important becomes easier to grasp once we move on from using references with our `Base` and `Derived` classes towards using pointers, especially owning ones.
-
-To properly understand why the destructor must be virtual we have to answer the question: if we create a derived object and store it by a base pointer, which destructor will be called once we delete our object through this base pointer? Take a moment to think about it.
-<!-- Pause a video here, look at the examples we just covered and, remembering that a destructor is just another kind of a function, really think about it! -->
-```cpp
-#include <iostream>
-
-struct Base {
-  // 😱 Careful! No virtual destructor! Other methods missing!
-  ~Base() { std::cout << "Base cleanup" << std::endl; }
-};
-
-struct Derived : public Base {
-  ~Derived() { std::cout << "Important cleanup" << std::endl; }
-};
-
-int main() {
-  // 😱 Code for illustrating a memory leak only! Avoid using new!
-  Base* ptr = new Derived;
-  delete ptr;  // "Important cleanup" is never printed!
-}
-```
-
-And I'm sure that you got it right! If the _base destructor_ is not `virtual` then _this base destructor will be called_. But this destructor knows nothing about the derived class! Which leads us, generally speaking, to an **undefined behavior** and if the derived class had additional data, their memory is not freed, which is a **memory leak**!
-
-Now if the destructor is `virtual`, a call to it will go through a vTable and so the correct derived destructor will be called.
-```cpp
-#include <iostream>
-
-struct Base {
-  // 😱 Still other method missing!
-  virtual ~Base() { std::cout << "Base cleanup" << std::endl; }
-};
-
-struct Derived : public Base {
-  ~Derived() override { std::cout << "Important cleanup" << std::endl; }
-};
-
-int main() {
-  // 😱 This will work but please don't use new!
-  Base* ptr = new Derived;
-  delete ptr;
-}
-```
-
-#### Delete other special methods for polymorphic classes
-So I hope that we see why we need a `virtual` destructor if we ever expect the object to be deleted by a pointer to its base class. But, if you remember, we already talked about the ["rule of all or nothing"](all_or_nothing.md) before, which states that if we need a single special function, like the destructor, that deals with the object's lifetime, we need all of them. This is true in this case too. Alongside a virtual destructor we need to deal with the copy and move constructors and assignment operators.
-
-This topic is slightly convoluted and I believe it is not talked about enough.
-
-I believe that all of these special methods must be `delete`d because classes with `virtual` methods are **designed to be used through a pointer**, i.e., they have pointer or reference semantics. They are not designed to be moved or copied, i.e., they do not have value semantics. If we try to copy or move a class that is designed with pointers and references in mind, we run a good risk of [**slicing**](https://www.learncpp.com/cpp-tutorial/object-slicing/) our object. Slicing happens when a copy or move constructor or an assignment operator is called on a base class when the actual allocated object was of a derived class that has more data stored in it. The base class only knows how to copy **its** data, **not the derived** data. This can only lead to confusion.
-
-Putting this all together a better way to implement our `Base` and `Derived` classes from before would be to add all the missing `deleted` special functions to the base class. We'll also add a default constructor too for a good measure.
-```cpp
-#include <iostream>
-
-struct Base {
-  virtual void DoSmth() { std::cout << "Base DoSmth" << std::endl; }
-
-  Base() = default;
-
-  Base(const Base&) = delete;
-  Base(Base&&) = delete;
-  Base& operator=(const Base&) = delete;
-  Base& operator=(Base&&) = delete;
-  virtual ~Base() = default;
-};
-
-struct Derived : public Base {
-  void DoSmth() override { std::cout << "Derived DoSmth" << std::endl; }
-};
-
-int main() {
-  Derived derived{};
-  Base base{};
-  Base& base_ref = derived;
-  base.DoSmth();      // Calls Base implementation.
-  derived.DoSmth();   // Calls Derived implementation.
-  base_ref.DoSmth();  // Calls Derived implementation.
-}
-```
-This allows us to get rid of the annoying disclaimer comment.
-
-There is also a quicker way to do this by inheriting from a simple `Noncopyable` class which can be reused for any class that is not supposed to be copyable or movable. Then we just need a `virtual` destructor because all the rest of the special functions are already taken care of.
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` inheritance_noncopyable/main.cpp
-`CPP_RUN_CMD` CWD:inheritance_noncopyable c++ -std=c++17 main.cpp
--->
-```cpp
-#include <iostream>
-
-struct Noncopyable {
-  Noncopyable() = default;
-  Noncopyable(const Noncopyable&) = delete;
-  Noncopyable(Noncopyable&&) = delete;
-  Noncopyable& operator=(const Noncopyable&) = delete;
-  Noncopyable& operator=(Noncopyable&&) = delete;
-  ~Noncopyable() = default;
-};
-
-struct Base : public Noncopyable {
-  virtual void DoSmth() const { std::cout << "Base DoSmth" << std::endl; }
-  virtual ~Base() = default;
-};
-
-struct Derived : public Base {
-  void DoSmth() const override { std::cout << "Derived DoSmth" << std::endl; }
-};
-
-int main() {
-  Derived derived{};
-  Base base{};
-  Base& base_ref = derived;
-  base.DoSmth();      // Calls Base implementation.
-  derived.DoSmth();   // Calls Derived implementation.
-  base_ref.DoSmth();  // Calls Derived implementation.
-}
-```
-
-### Downcasting using the `dynamic_cast`
-It is also important to mention that for [polymorphic classes](https://en.cppreference.com/w/cpp/language/object#Polymorphic_objects), i.e., those that have a vtable pointer, just like we can upcast our type along the hierarchy of classes we can downcast too. For that we use a `dynamic_cast`.
-
-This _is_ considered an anti-pattern though and breaks the so-called [Liskov Substitution Principle](https://en.wikipedia.org/wiki/Liskov_substitution_principle) that, applied to C++, states that when we work with a pointer or a reference to base type we should have no need to know which derived type is actually being used. If this principle is broken the programs usually become more brittle, meaning that making changes to them without breaking things requires more work. That being said, it is probably still important to understand how `dynamic_cast` works.
-
-`dynamic_cast` allows us to downcast a pointer or a reference of a polymorphic `Base` class into a pointer or reference of the `Derived` class, derived from `Base`. We won't go too much into detail, but it is important to note that this conversion might fail! If this conversion fails while converting a pointer, a `nullptr` will be returned, while if the failure occurs while converting a reference, a `std::bad_cast` exception will be thrown.
-<!--
-`CPP_SETUP_START`
-struct Noncopyable {
-  Noncopyable() = default;
-  Noncopyable(const Noncopyable&) = delete;
-  Noncopyable(Noncopyable&&) = delete;
-  Noncopyable& operator=(const Noncopyable&) = delete;
-  Noncopyable& operator=(Noncopyable&&) = delete;
-  ~Noncopyable() = default;
-};
-
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` inheritance_dynamic_cast/main.cpp
-`CPP_RUN_CMD` CWD:inheritance_dynamic_cast c++ -std=c++17 main.cpp
--->
-```cpp
-#include <iostream>
-
-struct Base : public Noncopyable {
-  virtual ~Base() {}
-};
-
-struct OtherBase : public Noncopyable {
-  virtual ~OtherBase() {}
-};
-
-struct Derived : public Base {};
-
-int main() {
-  const Derived object{};
-  const Base& base_ref{object};
-  const OtherBase other_base{};
-  const OtherBase& other_base_ref{other_base};
-  const Derived& derived_ref = dynamic_cast<const Derived&>(base_ref);
-  // other_derived_ptr will be nullptr because it is not derived from OtherBase.
-  const Derived* other_derived_ptr =
-      dynamic_cast<const Derived*>(&other_base_ref);
-  // ❌ The following will throw a std::bad_cast.
-  // const Derived& other_derived_ref =
-  //    dynamic_cast<const Derived&>(other_base_ref);
-}
-```
-
-### Don't mix implementation and interface inheritance
-We are almost ready to return to our original `Image` example and finish its implementation with all the best practices in mind. There is just one more thing to cover before that.
-
-In my experience, having virtual functions that have a base implementation and some overridden implementation in a derived class becomes confusing quite quickly. It becomes hard to find where in the class hierarchy the actual implementation lives and I've spent hours and hours on this in code bases that had deep polymorphic object hierarchies. And it seems that the experts who know much more about software design than I do agree with me on this.
-
-C++ Core Guidelines suggest to distinguish [between implementation inheritance and the interface inheritance](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#c129-when-designing-a-class-hierarchy-distinguish-between-implementation-inheritance-and-interface-inheritance) and the Google C++ Code Style suggest to [not overuse implementation inheritance](https://google.github.io/styleguide/cppguide.html#Inheritance) and prefer composition instead, while some go as far as to call [implementation inheritance evil](http://whats-in-a-game.com/implementation-inheritance-is-evil/) altogether.
-
-### Implement pure interfaces
-So what is the solution to this problem? The solution is to separate interface inheritance and implementation inheritance alltogether. You see, there is one more trick up our sleeves with `virtual` - the **pure `virtual` functions**.
-
-They allow us to define a `virtual` function that does not have any implementation by design and **must** be implemented by the descendants of the class it belongs to.
-<!--
-`CPP_SETUP_START`
-struct Noncopyable {
-  Noncopyable() = default;
-  Noncopyable(const Noncopyable&) = delete;
-  Noncopyable(Noncopyable&&) = delete;
-  Noncopyable& operator=(const Noncopyable&) = delete;
-  Noncopyable& operator=(Noncopyable&&) = delete;
-  ~Noncopyable() = default;
-};
-
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` pure_virtual/main.cpp
-`CPP_RUN_CMD` CWD:pure_virtual c++ -std=c++17 -c main.cpp
--->
-```cpp
-struct Base : public Noncopyable {
-  virtual void PureVirtualFunction() = 0;
-  virtual ~Base() = default;
-};
-
-struct Derived : public Base {
-  void PureVirtualFunction() override {
-    // Must be overridden!
-  }
-};
-```
-
-This is perfect for creating interfaces. We generally call a class that has at least one pure virtual function an **abstract class** and a class that has **all** of its function as pure virtual an **interface**.
-
-In my experience, I prefer to make sure that if my class is abstract - it is an interface. This allows to keep a shallow hierarchy of concrete implementations of such interfaces. In combination with using composition and function reusing in the actual implementation this allows us to have a hierarchy that is easy to read while avoiding code duplication.
-<!-- But do tell me your experience with all of this! What is your preference if you have any? -->
-
-### Keyword `final`
-Speaking of keeping a shallow hierarchy, let's also briefly talk about the word `final`. We can use it to forbid any future extensions of a particular class.
-<!--
-`CPP_SKIP_SNIPPET`
--->
-```cpp
-struct CannotBeDerivedFrom final {
-  // Some implementation here.
-};
-
-// ❌ Won't compile
-struct Oops : public CannotBeDerivedFrom {};
-```
-
-It _is_ helpful when implementing a shallow hierarchy of classes that all implement pure interfaces but I would suggest to be careful with the use of it as it is very hard to know the future and this is equivalent to a statement, "I'm 100% sure that nobody ever will need to extend this class". Which is a hard statement to make confidently.
-
-## Simple polymorphic class example following best practices
-For completeness, let's see how our polymorphic classes example changes if we follow all of the practices we've just talked about:
-```cpp
-#include <iostream>
-
-struct Noncopyable {
-  Noncopyable() = default;
-  Noncopyable(const Noncopyable&) = delete;
-  Noncopyable(Noncopyable&&) = delete;
-  Noncopyable& operator=(const Noncopyable&) = delete;
-  Noncopyable& operator=(Noncopyable&&) = delete;
-  ~Noncopyable() = default;
-};
-
-struct Base : public Noncopyable {
-  virtual void DoSmth() const = 0;
-  virtual ~Base() = default;
-};
-
-struct Derived final : public Base {
-  void DoSmth() const override { std::cout << "Derived DoSmth" << std::endl; }
-};
-
-struct AnotherDerived final : public Base {
-  void DoSmth() const override { std::cout << "AnotherDerived DoSmth" << std::endl; }
-};
-
-int main() {
-  const Derived derived{};
-  const AnotherDerived another_derived{};
-  const Base* base_ptr = &derived;
-  base_ptr->DoSmth();  // Calls Derived implementation.
-  base_ptr = &another_derived;
-  base_ptr->DoSmth();  // Calls AnotherDerived implementation.
-}
-```
-Here, we change `Base` to be an interface, add one more implementation class `AnotherDerived` and mark our derived implementations `final` to make sure nobody can build a deep hierarchy on top of them. We also convert the `main` to use pointers just to show that we can refer to two different implementations by the same pointer.
-
-## Multiple inheritance
-C++ also allows to use multiple inheritance. But do note that it is [heavily discouraged](https://google.github.io/styleguide/cppguide.html#Inheritance) in case of implementation inheritance. It is easy to show the reason. Imagine we have a class that inherits from a number of classes and we want to find the implementation of a certain functionality. How do we know where it is implemented? In bigger projects this becomes really cumbersome.
-
-That being said, it is ok sometimes to use multiple inheritance when a class needs to [implement multiple interfaces](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#c135-use-multiple-inheritance-to-represent-multiple-distinct-interfaces). It is easy to imagine that a game object can be both `Drawable` and, say `Moveable`.
-<!--
-`CPP_SETUP_START`
-
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` inheritance_multiple/main.cpp
-`CPP_RUN_CMD` CWD:inheritance_multiple c++ -std=c++17 -c main.cpp
--->
-```cpp
-struct Drawable {
-  virtual void Draw() = 0;
-};
-
-struct Moveable {
-  virtual void Move(float distance) = 0;
-};
-
-class Box: public Drawable, public Moveable {
- public:
-  void Draw() override {}
-  void Move(float distance) override {}
-  // Rest of the implementation.
-};
-
-void Move(Moveable* moveable, float distance) {
-  moveable->Move(distance);
-}
-
-void Draw(Drawable* drawable) {
-  drawable->Draw();
-}
-
-int main() {
-  Box box{};
-  Move(&box, 42.42F);
-  Draw(&box);
-  return 0;
-}
-```
-This allows us to separate the concerns in our design. The standalone functions `Move` and `Draw` need to know nothing about the objects being passed into them as long as those correspond to the required interface and our `Box` satisfies both.
-
-## Detailed `Image` example following best practices
-Now we really know everything there is to know about inheritance in modern C++. We know how simple (and a bit limited) implementation inheritance is, we know that the interface inheritance enables dynamic polymorphism, we understand how it works under the hood and we know the best practices related to creating and using interfaces. So it is time to put it all to a small test and get back to our original example with the `Image` class. We can now properly implement the missing parts.
-<!--
-`CPP_SETUP_START`
-using Color = int;
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` inheritance_final_example/main.cpp
-`CPP_RUN_CMD` CWD:inheritance_final_example c++ -std=c++17 main.cpp
--->
-```cpp
-#include <filesystem>
-#include <iostream>
-#include <vector>
-
-// Can be any custom type
-using Color = int;
-
-struct Noncopyable {
-  Noncopyable() = default;
-  Noncopyable(const Noncopyable&) = delete;
-  Noncopyable(Noncopyable&&) = delete;
-  Noncopyable& operator=(const Noncopyable&) = delete;
-  Noncopyable& operator=(Noncopyable&&) = delete;
-  ~Noncopyable() = default;
-};
-
-struct IoInterface : public Noncopyable {
-  virtual std::vector<Color> Read(const std::filesystem::path& path) const = 0;
-  virtual void Write(const std::filesystem::path& path,
-                     const std::vector<Color>& data) const = 0;
-  virtual ~IoInterface() = default;
-};
-
-struct JpegIo final : public IoInterface {
-  std::vector<Color> Read(const std::filesystem::path& path) const override {
-    std::cout << "Reading JPEG from path: " << path << std::endl;
-    return {};
-  }
-  void Write(const std::filesystem::path& path,
-             const std::vector<Color>& data) const override {
-    std::cout << "Writing JPEG to path: " << path << std::endl;
-  }
-};
-
-struct PngIo final : public IoInterface {
-  std::vector<Color> Read(const std::filesystem::path& path) const override {
-    std::cout << "Reading PNG from path: " << path << std::endl;
-    return {};
-  }
-  void Write(const std::filesystem::path& path,
-             const std::vector<Color>& data) const override {
-    std::cout << "Writing PNG to path: " << path << std::endl;
-  }
-};
-
-class Image {
- public:
-  Image(const std::filesystem::path& path, const IoInterface& io) {
-    pixels_ = io.Read(path);
-  }
-
-  void Save(const std::filesystem::path& path, const IoInterface& io) const {
-    io.Write(path, pixels_);
-  }
-
- private:
-  std::vector<Color> pixels_{};
-};
-
-int main() {
-  const Image image{"path.jpeg", JpegIo{}};
-  image.Save("other_path.png", PngIo{});
-}
-```
-We make use of the `Noncopyable` base class to declare the `IoInterface` with the `Write` and `Read` functions, along with a `virtual` destructor. Note that our functions are both `const`-qualified as well as pure `virtual`. Then, our `JpegIo` and `PngIo` implement the interface by overriding the `Write` and `Read` functions. The actual implementation is not important to understand inheritance so they just print something to the terminal here. Finally, just as before, we use the reference to our interface in our `Image` class to refer to any implementation that we pass into it in our `main` function.
-
-This, I believe, follows most of the current best practices when it comes to implementing an OOP-style system that relies on dynamic polymorphism. So I guess we can close this lecture with this example as the one that encapsulates everything that we covered today.
-
-<!-- And if you are interested in how to achieve very similar results with templates, please give a watch to the series of videos I recorded about templates, starting with why. Thanks a lot for your attention and bye! -->
diff --git a/lectures/lambdas.md b/lectures/lambdas.md
deleted file mode 100644
index 020a065..0000000
--- a/lectures/lambdas.md
+++ /dev/null
@@ -1,746 +0,0 @@
-Lambdas
---
-
-<p align="center">
-  <a href="https://youtu.be/l0BgadhkUL8"><img src="https://img.youtube.com/vi/l0BgadhkUL8/maxresdefault.jpg" alt="Video" align="right" width=50% style="margin: 0.5rem"></a>
-</p>
-
-- [Lambdas](#lambdas)
-- [Overview](#overview)
-- [What is a "callable"](#what-is-a-callable)
-- [A function pointer is sometimes enough](#a-function-pointer-is-sometimes-enough)
-- [Before lambdas we had function objects (or functors)](#before-lambdas-we-had-function-objects-or-functors)
-- [How to implement generic algorithms like `std::sort`](#how-to-implement-generic-algorithms-like-stdsort)
-- [Enter lambdas](#enter-lambdas)
-- [Lambda syntax](#lambda-syntax)
-- [When to use lambdas](#when-to-use-lambdas)
-- [Summary](#summary)
-
-
-We've already covered so many topics in this course but there is one more thing that firmly belongs to modern C++ that we did not really touch upon - [**lambdas**](https://en.cppreference.com/w/cpp/language/lambda).
-
-Here's one example for which they are useful. Imagine we have a list of people, represented as a struct `Person`, and we would like to sort them by age. We can try using the standard [`std::sort`](https://en.cppreference.com/w/cpp/algorithm/sort) function for that:
-<!--
-`CPP_SKIP_SNIPPET`
--->
-```cpp
-#include <algorithm>
-#include <string>
-#include <vector>
-
-struct Person {
-  std::string name;
-  int age;
-};
-
-int main() {
-  std::vector<Person> people{
-      {"Gandalf", 55'000}, {"Frodo", 33}, {"Legolas", 2'931}, {"Gimli", 139}};
-  // ❌ Won't compile, cannot compare Person objects.
-  std::sort(people.begin(), people.end());
-}
-```
-But the naïve call to `std::sort` will fail and the compiler will throw a loooong error at us:
-<details>
-<summary>Long compiler error</summary>
-
-```css
-In file included from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algobase.h:71,
-                 from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/algorithm:61,
-                 from <source>:1:
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/predefined_ops.h: In instantiation of 'constexpr bool __gnu_cxx::__ops::_Iter_less_iter::operator()(_Iterator1, _Iterator2) const [with _Iterator1 = __gnu_cxx::__normal_iterator<Person*, std::vector<Person> >; _Iterator2 = __gnu_cxx::__normal_iterator<Person*, std::vector<Person> >]':
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algo.h:82:17:   required from 'void std::__move_median_to_first(_Iterator, _Iterator, _Iterator, _Iterator, _Compare) [with _Iterator = __gnu_cxx::__normal_iterator<Person*, std::vector<Person> >; _Compare = __gnu_cxx::__ops::_Iter_less_iter]'
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algo.h:1924:34:   required from '_RandomAccessIterator std::__unguarded_partition_pivot(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Person*, std::vector<Person> >; _Compare = __gnu_cxx::__ops::_Iter_less_iter]'
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algo.h:1958:38:   required from 'void std::__introsort_loop(_RandomAccessIterator, _RandomAccessIterator, _Size, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Person*, std::vector<Person> >; _Size = long int; _Compare = __gnu_cxx::__ops::_Iter_less_iter]'
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algo.h:1974:25:   required from 'void std::__sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Person*, std::vector<Person> >; _Compare = __gnu_cxx::__ops::_Iter_less_iter]'
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algo.h:4859:18:   required from 'void std::sort(_RAIter, _RAIter) [with _RAIter = __gnu_cxx::__normal_iterator<Person*, std::vector<Person> >]'
-<source>:14:41:   required from here
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/predefined_ops.h:43:23: error: no match for 'operator<' (operand types are 'Person' and 'Person')
-   43 |       { return *__it1 < *__it2; }
-      |                ~~~~~~~^~~~~~~~
-In file included from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algobase.h:67,
-                 from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/algorithm:61,
-                 from <source>:1:
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_iterator.h:1096:5: note: candidate: 'template<class _IteratorL, class _IteratorR, class _Container> bool __gnu_cxx::operator<(const __gnu_cxx::__normal_iterator<_IteratorL, _Container>&, const __gnu_cxx::__normal_iterator<_IteratorR, _Container>&)'
- 1096 |     operator<(const __normal_iterator<_IteratorL, _Container>& __lhs,
-      |     ^~~~~~~~
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_iterator.h:1096:5: note:   template argument deduction/substitution failed:
-In file included from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algobase.h:71,
-                 from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/algorithm:61,
-                 from <source>:1:
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/predefined_ops.h:43:23: note:   'Person' is not derived from 'const __gnu_cxx::__normal_iterator<_IteratorL, _Container>'
-   43 |       { return *__it1 < *__it2; }
-      |                ~~~~~~~^~~~~~~~
-In file included from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algobase.h:67,
-                 from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/algorithm:61,
-                 from <source>:1:
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_iterator.h:1104:5: note: candidate: 'template<class _Iterator, class _Container> bool __gnu_cxx::operator<(const __gnu_cxx::__normal_iterator<_Iterator, _Container>&, const __gnu_cxx::__normal_iterator<_Iterator, _Container>&)'
- 1104 |     operator<(const __normal_iterator<_Iterator, _Container>& __lhs,
-      |     ^~~~~~~~
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_iterator.h:1104:5: note:   template argument deduction/substitution failed:
-In file included from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algobase.h:71,
-                 from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/algorithm:61,
-                 from <source>:1:
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/predefined_ops.h:43:23: note:   'Person' is not derived from 'const __gnu_cxx::__normal_iterator<_Iterator, _Container>'
-   43 |       { return *__it1 < *__it2; }
-      |                ~~~~~~~^~~~~~~~
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/predefined_ops.h: In instantiation of 'bool __gnu_cxx::__ops::_Val_less_iter::operator()(_Value&, _Iterator) const [with _Value = Person; _Iterator = __gnu_cxx::__normal_iterator<Person*, std::vector<Person> >]':
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algo.h:1826:20:   required from 'void std::__unguarded_linear_insert(_RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Person*, std::vector<Person> >; _Compare = __gnu_cxx::__ops::_Val_less_iter]'
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algo.h:1854:36:   required from 'void std::__insertion_sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Person*, std::vector<Person> >; _Compare = __gnu_cxx::__ops::_Iter_less_iter]'
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algo.h:1886:25:   required from 'void std::__final_insertion_sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Person*, std::vector<Person> >; _Compare = __gnu_cxx::__ops::_Iter_less_iter]'
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algo.h:1977:31:   required from 'void std::__sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Person*, std::vector<Person> >; _Compare = __gnu_cxx::__ops::_Iter_less_iter]'
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algo.h:4859:18:   required from 'void std::sort(_RAIter, _RAIter) [with _RAIter = __gnu_cxx::__normal_iterator<Person*, std::vector<Person> >]'
-<source>:14:41:   required from here
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/predefined_ops.h:96:22: error: no match for 'operator<' (operand types are 'Person' and 'Person')
-   96 |       { return __val < *__it; }
-      |                ~~~~~~^~~~~~~
-In file included from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algobase.h:67,
-                 from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/algorithm:61,
-                 from <source>:1:
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_iterator.h:1096:5: note: candidate: 'template<class _IteratorL, class _IteratorR, class _Container> bool __gnu_cxx::operator<(const __gnu_cxx::__normal_iterator<_IteratorL, _Container>&, const __gnu_cxx::__normal_iterator<_IteratorR, _Container>&)'
- 1096 |     operator<(const __normal_iterator<_IteratorL, _Container>& __lhs,
-      |     ^~~~~~~~
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_iterator.h:1096:5: note:   template argument deduction/substitution failed:
-In file included from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algobase.h:71,
-                 from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/algorithm:61,
-                 from <source>:1:
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/predefined_ops.h:96:22: note:   'Person' is not derived from 'const __gnu_cxx::__normal_iterator<_IteratorL, _Container>'
-   96 |       { return __val < *__it; }
-      |                ~~~~~~^~~~~~~
-In file included from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algobase.h:67,
-                 from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/algorithm:61,
-                 from <source>:1:
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_iterator.h:1104:5: note: candidate: 'template<class _Iterator, class _Container> bool __gnu_cxx::operator<(const __gnu_cxx::__normal_iterator<_Iterator, _Container>&, const __gnu_cxx::__normal_iterator<_Iterator, _Container>&)'
- 1104 |     operator<(const __normal_iterator<_Iterator, _Container>& __lhs,
-      |     ^~~~~~~~
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_iterator.h:1104:5: note:   template argument deduction/substitution failed:
-In file included from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algobase.h:71,
-                 from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/algorithm:61,
-                 from <source>:1:
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/predefined_ops.h:96:22: note:   'Person' is not derived from 'const __gnu_cxx::__normal_iterator<_Iterator, _Container>'
-   96 |       { return __val < *__it; }
-      |                ~~~~~~^~~~~~~
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/predefined_ops.h: In instantiation of 'bool __gnu_cxx::__ops::_Iter_less_val::operator()(_Iterator, _Value&) const [with _Iterator = __gnu_cxx::__normal_iterator<Person*, std::vector<Person> >; _Value = Person]':
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_heap.h:139:48:   required from 'void std::__push_heap(_RandomAccessIterator, _Distance, _Distance, _Tp, _Compare&) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Person*, std::vector<Person> >; _Distance = long int; _Tp = Person; _Compare = __gnu_cxx::__ops::_Iter_less_val]'
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_heap.h:246:23:   required from 'void std::__adjust_heap(_RandomAccessIterator, _Distance, _Distance, _Tp, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Person*, std::vector<Person> >; _Distance = long int; _Tp = Person; _Compare = __gnu_cxx::__ops::_Iter_less_iter]'
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_heap.h:355:22:   required from 'void std::__make_heap(_RandomAccessIterator, _RandomAccessIterator, _Compare&) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Person*, std::vector<Person> >; _Compare = __gnu_cxx::__ops::_Iter_less_iter]'
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algo.h:1666:23:   required from 'void std::__heap_select(_RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Person*, std::vector<Person> >; _Compare = __gnu_cxx::__ops::_Iter_less_iter]'
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algo.h:1937:25:   required from 'void std::__partial_sort(_RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Person*, std::vector<Person> >; _Compare = __gnu_cxx::__ops::_Iter_less_iter]'
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algo.h:1953:27:   required from 'void std::__introsort_loop(_RandomAccessIterator, _RandomAccessIterator, _Size, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Person*, std::vector<Person> >; _Size = long int; _Compare = __gnu_cxx::__ops::_Iter_less_iter]'
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algo.h:1974:25:   required from 'void std::__sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Person*, std::vector<Person> >; _Compare = __gnu_cxx::__ops::_Iter_less_iter]'
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algo.h:4859:18:   required from 'void std::sort(_RAIter, _RAIter) [with _RAIter = __gnu_cxx::__normal_iterator<Person*, std::vector<Person> >]'
-<source>:14:41:   required from here
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/predefined_ops.h:67:22: error: no match for 'operator<' (operand types are 'Person' and 'Person')
-   67 |       { return *__it < __val; }
-      |                ~~~~~~^~~~~~~
-In file included from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algobase.h:67,
-                 from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/algorithm:61,
-                 from <source>:1:
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_iterator.h:1096:5: note: candidate: 'template<class _IteratorL, class _IteratorR, class _Container> bool __gnu_cxx::operator<(const __gnu_cxx::__normal_iterator<_IteratorL, _Container>&, const __gnu_cxx::__normal_iterator<_IteratorR, _Container>&)'
- 1096 |     operator<(const __normal_iterator<_IteratorL, _Container>& __lhs,
-      |     ^~~~~~~~
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_iterator.h:1096:5: note:   template argument deduction/substitution failed:
-In file included from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algobase.h:71,
-                 from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/algorithm:61,
-                 from <source>:1:
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/predefined_ops.h:67:22: note:   'Person' is not derived from 'const __gnu_cxx::__normal_iterator<_IteratorL, _Container>'
-   67 |       { return *__it < __val; }
-      |                ~~~~~~^~~~~~~
-In file included from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algobase.h:67,
-                 from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/algorithm:61,
-                 from <source>:1:
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_iterator.h:1104:5: note: candidate: 'template<class _Iterator, class _Container> bool __gnu_cxx::operator<(const __gnu_cxx::__normal_iterator<_Iterator, _Container>&, const __gnu_cxx::__normal_iterator<_Iterator, _Container>&)'
- 1104 |     operator<(const __normal_iterator<_Iterator, _Container>& __lhs,
-      |     ^~~~~~~~
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_iterator.h:1104:5: note:   template argument deduction/substitution failed:
-In file included from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/stl_algobase.h:71,
-                 from /opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/algorithm:61,
-                 from <source>:1:
-/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/bits/predefined_ops.h:67:22: note:   'Person' is not derived from 'const __gnu_cxx::__normal_iterator<_Iterator, _Container>'
-   67 |       { return *__it < __val; }
-      |                ~~~~~~^~~~~~~
-Compiler returned: 1
-```
-
-</details>
-</br>
-
-This error message might be quite scary, but if we scroll all the way up, we will see that this error comes down to this line that states that there is no "less than" operator defined for the two `Person` objects:
-```css
-error: no match for 'operator<' (operand types are 'Person' and 'Person')
-```
-
-You see, by default `std::sort` will apply the operator `<` to the provided arguments and, unless we define such operator for our `Person` class, this operator does not exist.
-<!-- Add "or std::less from C++20 on, more on that later" on screen -->
-
-However, there is another overload of `std::sort` function that we can use! We can provide a **lambda expression** that compares two `Person` objects.
-```cpp
-#include <algorithm>
-#include <iostream>
-#include <string>
-#include <vector>
-
-struct Person {
-  std::string name;
-  int age;
-};
-
-void Print(const std::vector<Person>& persons, const std::string& tag) {
-  std::cout << tag << std::endl;
-  for (const auto& person : persons) {
-    std::cout << person.name << " " << person.age << "\n";
-  }
-}
-
-int main() {
-  std::vector<Person> people{
-      {"Gandalf", 55'000}, {"Frodo", 33}, {"Legolas", 2'931}, {"Gimli", 139}};
-  Print(people, "> Before sorting:");
-  std::sort(
-      people.begin(), people.end(),
-      [](const auto& left, const auto& right) { return left.age < right.age; });
-  Print(people, "> Sorted by age ascending:");
-}
-```
-And now `std::sort` sorts our Tolkien characters by age in ascending order.
-```
-> Before sorting:
-Gandalf 55000
-Frodo 33
-Legolas 2931
-Gimli 139
-> Sorted by age ascending:
-Frodo 33
-Gimli 139
-Legolas 2931
-Gandalf 55000
-```
-
-So let's talk about what lambdas are, how to write them in such a way that they operate safely and efficiently and, yes, how they make **this** a valid piece of C++ code :wink:
-```cpp
-// ✅ Yep, this compiles 🙃
-int main() {
-  [](){}();
-}
-```
-
-<!-- Intro -->
-
-## Overview
-My aim for today is to walk us through what lambdas are and the reasons they exist as well as roughly talk about how they work under the hood. As this topic comes relatively late in our modern C++ course, we have the advantage of being able to understand how lambdas operate using a bunch of things we already know about, like functions, classes, and a bit of templates.
-
-## What is a "callable"
-As a first step, though, I'd like to briefly talk about what `std::sort` does to whatever third argument we pass into it. It, well, calls it with two `Person` objects as the input arguments. But what do we really mean, when we say that something gets "called"?
-
-Clearly, we can "call" a function, more or less by definition. By extension, we can claim that anything that we can call through an `operator()` is also "callable". Which opens a whole new perspective on how to create these "callable" things.
-
-## A function pointer is sometimes enough
-In most cases, simple is good enough. As we've just mentioned, the simplest "callable" is a function. In our example from before, we don't _really_ need to use a lambda. If we write a function `less` that takes two `Person` objects and pass its pointer to `std::sort` it will do the trick and the objects will get sorted:
-```cpp
-#include <algorithm>
-#include <iostream>
-#include <string>
-#include <vector>
-
-struct Person {
-  std::string name;
-  int age;
-};
-
-void Print(const std::vector<Person>& persons, const std::string& tag) {
-  std::cout << tag << std::endl;
-  for (const auto& person : persons) {
-    std::cout << person.name << " " << person.age << "\n";
-  }
-}
-
-bool less(const Person& p1, const Person& p2) { return p1.age < p2.age; }
-
-int main() {
-  std::vector<Person> people{
-      {"Gandalf", 55'000}, {"Frodo", 33}, {"Legolas", 2'931}, {"Gimli", 139}};
-  Print(people, "> Before sorting:");
-  // 💡 We can also pass "less" without "&" here. Try it!
-  std::sort(people.begin(), people.end(), &less);
-  Print(people, "> Sorted by age ascending:");
-}
-```
-Note that we can also drop the `&` in the `std::sort` call and the code will do exactly the same thing:
-<!--
-`CPP_SETUP_START`
-#include <vector>
-#include <algorithm>
-bool less(int a, int b) { return a < b;}
-int main() {
-  std::vector<int> people{1, 2, 3};
-  $PLACEHOLDER
-}
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` lambda_use_simple_function/main.cpp
-`CPP_RUN_CMD` CWD:lambda_use_simple_function c++ -std=c++17 main.cpp
--->
-```cpp
-std::sort(people.begin(), people.end(), less);
-```
-The reason for this, if you are interested, is that [functions can be implicitly converted to function pointers](https://en.cppreference.com/w/cpp/language/implicit_conversion#Function-to-pointer_conversion), they are special in this way.
-<!-- You can always read more on this at cppreference.com following the link in the description to this video -->
-
-## Before lambdas we had function objects (or functors)
-But what if we need to have a certain *state* stored in our "callable"? For example, what if we wouldn't want to sort our `Person` objects by their absolute age, but by the difference of their age with respect to some number, say `4242`?
-
-Behold [**function objects**](https://en.cppreference.com/w/cpp/utility/functional), or sometimes also **functors**, although we should prefer the former name to avoid confusion. These are objects for which the function call operator is defined, or, in other words, that define an `operator()`. As they define this operator, they can be "called" and so they are also "callable".
-
-Which means that if we want to sort our array by an age difference to some number, we can create a class `ComparisonToQueryAge` that has a member `query_age_` and an `operator(const Person&, const Person&)` that compares the age differences of the two provided `Person` objects instead of comparing their ages between each other:
-```cpp
-#include <algorithm>
-#include <iostream>
-#include <string>
-#include <vector>
-
-struct Person {
-  std::string name;
-  int age;
-};
-
-void Print(const std::vector<Person>& persons, const std::string& tag) {
-  std::cout << tag << std::endl;
-  for (const auto& person : persons) {
-    std::cout << person.name << " " << person.age << "\n";
-  }
-}
-
-class ComparisonToQueryAge {
- public:
-  explicit ComparisonToQueryAge(int query_age) : query_age_{query_age} {}
-
-  bool operator()(const Person& p1, const Person& p2) const {
-    return std::abs(p1.age - query_age_) < std::abs(p2.age - query_age_);
-  }
-
- private:
-  int query_age_{};
-};
-
-int main() {
-  std::vector<Person> people{
-      {"Gandalf", 55'000}, {"Frodo", 33}, {"Legolas", 2'931}, {"Gimli", 139}};
-  Print(people, "> Before sorting:");
-  std::sort(people.begin(), people.end(), ComparisonToQueryAge{4242});
-  Print(people, "> Sorted by age difference to 4242, ascending:");
-}
-```
-Once we pass an object of this class as the callable into the `std::sort`, we can see that our Tolkien characters are now sorted by their age difference to the number `4242`.
-```
-> Before sorting:
-Gandalf 55000
-Frodo 33
-Legolas 2931
-Gimli 139
-> Sorted by age difference to 4242, ascending:
-Legolas 2931
-Gimli 139
-Frodo 33
-Gandalf 55000
-```
-
-## How to implement generic algorithms like `std::sort`
-So far so good. We already know a lot about classes so I hope that what we've just covered seems quite self-explanatory.
-
-Now I think it makes sense to look a bit deeper into how `std::sort` is implemented. How does it magically take anything that looks like a "callable" and just rolls with it?
-
-Please pause here for a moment and think how would **you** implement this! I promise you that if you followed the previous lectures, especially those on templates, you should have all the tools at your disposal by now.
-
-<!-- I'll go edit this video in the meantime :) -->
-
-The key is to think back to the lectures in which we covered [templates](templates_why.md)! We can hopefully all imagine that using templates would allow us to implement a function similar to `std::sort`, where the begin and end iterators as well as the comparator callable all have some template type that is guessed by the compiler at compile time:
-```cpp
-#include <iostream>
-#include <string>
-#include <vector>
-
-struct Person {
-  std::string name;
-  int age;
-};
-
-void Print(const std::vector<Person>& persons, const std::string& tag) {
-  std::cout << tag << std::endl;
-  for (const auto& person : persons) {
-    std::cout << person.name << " " << person.age << "\n";
-  }
-}
-
-class ComparisonToQueryAge {
- public:
-  explicit ComparisonToQueryAge(int query_age) : query_age_{query_age} {}
-
-  bool operator()(const Person& p1, const Person& p2) const {
-    return std::abs(p1.age - query_age_) < std::abs(p2.age - query_age_);
-  }
-
- private:
-  int query_age_{};
-};
-
-bool less(const Person& p1, const Person& p2) { return p1.age < p2.age; }
-
-template <class Iterator, class Comparator>
-void MySort(Iterator begin, Iterator end, Comparator comparator) {
-  // The actual algorithm is not important here.
-  for (Iterator i = begin + 1; i != end; ++i) {
-    Iterator j = i;
-    // We call comparator(*iter_1, *iter_2) somewhere in our algorithm.
-    while (j != begin && comparator(*j, *(j - 1))) {
-      std::iter_swap(j, j - 1);
-      --j;
-    }
-  }
-}
-
-int main() {
-  std::vector<Person> people{
-      {"Gandalf", 55'000}, {"Frodo", 33}, {"Legolas", 2'931}, {"Gimli", 139}};
-  Print(people, "> Before sorting:");
-  MySort(people.begin(), people.end(), less);
-  Print(people, "> Sorted by age ascending:");
-  MySort(people.begin(), people.end(), ComparisonToQueryAge{4242});
-  Print(people, "> Sorted by age difference to 4242, ascending:");
-  MySort(people.begin(), people.end(), &less);
-  Print(people, "> Sorted by age ascending:");
-}
-```
-Note though that our interest here is _not_ to implement a better sorting algorithm (so feel free to ignore the actual implementation) but to gain intuition about how we _could_ implement a generic algorithm that takes any comparator object that is "callable" with two `Person` objects, be it a function pointer or a function object. We don't have to write much code to achieve this too! And if we run this, we get the expected output.
-```
-> Before sorting:
-Gandalf 55000
-Frodo 33
-Legolas 2931
-Gimli 139
-> Sorted by age ascending:
-Frodo 33
-Gimli 139
-Legolas 2931
-Gandalf 55000
-> Sorted by age difference to 4242, ascending:
-Legolas 2931
-Gimli 139
-Frodo 33
-Gandalf 55000
-> Sorted by age ascending:
-Frodo 33
-Gimli 139
-Legolas 2931
-Gandalf 55000
-```
-
-Note also that from C++20 on this code would become more readable and safe as we could use concepts instead of raw templates.
-<!-- Please tell me in the comments if you would be interested in hearing more about that! -->
-
-Oh, one more thing, the story of course doesn't end with `std::sort`! There is a number of functions that take similar function objects. For some examples, see [`std::find_if`](https://en.cppreference.com/w/cpp/algorithm/find#Version_3), [`std::for_each`](https://en.cppreference.com/w/cpp/algorithm/for_each), [`std::transform`](https://en.cppreference.com/w/cpp/algorithm/transform), and many more.
-
-## Enter lambdas
-However, it might not be convenient to always define a new struct, class, or even a function for every single use case. Sometimes we want to use such a function object only locally, once, and don't want to expose it to the outside world, nor to deal with any additional boilerplate code.
-
-The strive to enable such convenience is what brought us the [**lambda expressions**](https://en.cppreference.com/w/cpp/language/lambda), or, colloquially, **lambdas**. They are really just syntactic sugar for defining our own function objects, just like the `ComparisonToQueryAge` class we talked about before.
-
-## Lambda syntax
-The syntax of defining a lambda expression is a little different from what we've seen until now. Let's modify our example to use lambdas instead of functions and function objects and look closer at how we can define and use lambdas in our programs.
-```cpp
-#include <algorithm>
-#include <iostream>
-#include <string>
-#include <vector>
-
-struct Person {
-  std::string name;
-  int age;
-};
-
-int main() {
-  const auto Print = [](const auto& persons, const auto& tag) {
-    std::cout << tag << std::endl;
-    for (const auto& person : persons) {
-      std::cout << person.name << " " << person.age << "\n";
-    }
-  };
-
-  std::vector<Person> people{
-      {"Gandalf", 55'000}, {"Frodo", 33}, {"Legolas", 2'931}, {"Gimli", 139}};
-  Print(people, "> Before sorting:");
-
-  std::sort(people.begin(), people.end(),
-            [](const auto& p1, const auto& p2) { return p1.age < p2.age; });
-  Print(people, "> Sorted by age ascending:");
-
-  const int query_age = 4242;
-  std::sort(people.begin(), people.end(),
-            [query_age](const auto& p1, const auto& p2) -> bool {
-              return std::abs(p1.age - query_age) <
-                     std::abs(p2.age - query_age);
-            });
-  Print(people, "> Sorted by age difference to 4242, ascending:");
-}
-```
-
-Here, we use 3 different lambdas. All of them follow the same general syntax that largely looks like this:
-<!--
-`CPP_SKIP_SNIPPET`
--->
-```cpp
-auto LambdaName = [CAPTURE_LIST](ARGUMENTS){BODY} -> ReturnType;
-```
-They all have some **arguments** (that can be omitted should they not be needed), a **body** that defines what the lambdas actually do, and a return type, that we can also provide explicitly but if we don't, it will be deduced from the `return` statement within the lambda function.
-
-If we assign our lambda to a variable, we can store our lambda object and reuse it multiple times as we do for the `Print` lambda. And if you were wondering, the type of this lambda will be some unique unnamed type that the compiler will make up on its own.
-
-Now it is time we talk about the stuff inside the square brackets in each lambda definition - the **capture list**. It is a new thing to us and is the syntax that we can easily recognize lambdas by.
-
-The first two lambdas we use have an empty capture list, but the third one captures the `query_age` variable in it:
-<!--
-`CPP_SETUP_START`
-#include <algorithm>
-struct P {
-  int age;
-};
-int main() {
-  int query_age{};
-  $PLACEHOLDER
-  Compare(P{0}, P{1});
-}
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` lambda_compare_1/main.cpp
-`CPP_RUN_CMD` CWD:lambda_compare_1 c++ -std=c++17 main.cpp
--->
-```cpp
-const auto Compare = [query_age](const auto& p1, const auto& p2) -> bool {
-  return std::abs(p1.age - query_age) < std::abs(p2.age - query_age);
-};
-```
-What this really means is that the `query_age` variable is copied such that it becomes available inside of the lambda body. If we look back at function objects we discussed before, this lambda behaves exactly the same as `ComparisonToQueryAge` class.
-
-In our case, `query_age` is a small variable - a single `int`. But if we want to capture a bigger variable, we would like to avoid unnecessary copies, so we'd like to capture it by reference. Any variable we would like to capture by reference we prefix by an ampersand `&` symbol. Just as an illustration, this code would capture `query_age` by reference instead of copying it:
-<!--
-`CPP_SETUP_START`
-#include <algorithm>
-struct P {
-  int age;
-};
-int main() {
-  int query_age{};
-  $PLACEHOLDER
-  Compare(P{0}, P{1});
-}
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` lambda_compare_2/main.cpp
-`CPP_RUN_CMD` CWD:lambda_compare_2 c++ -std=c++17 main.cpp
--->
-```cpp
-const auto Compare = [&query_age](const auto& p1, const auto& p2) -> bool {
-  return std::abs(p1.age - query_age) < std::abs(p2.age - query_age);
-};
-```
-
-We can also provide as many captured variables as we want, specifying for each if we want to capture them by copy or by reference.
-```cpp
-#include <iostream>
-int main() {
-  int one{};
-  float two{};
-  double three{};
-  const auto Lambda = [&one, two, &three] {
-    // Do something with one, two, three.
-    std::cout << one << " " << two << " " << three << std::endl;
-  };
-  Lambda();
-}
-```
-Here, `one` and `three` will be captured by reference, while `two` is captured by copy.
-
-Alternatively, we can capture all variables visible at the moment of lambda definition. There are three distinct cases that are worth talking about here.
-
-If we want to capture all variables by copy, we can use `=` as the first capture.
-```cpp
-#include <iostream>
-int main() {
-  int one{};
-  float two{};
-  double three{};
-  const auto Lambda = [=] {
-    // All variables are captured by copy.
-    std::cout << one << " " << two << " " << three << std::endl;
-  };
-  Lambda();
-}
-```
-And if we want some variables to be captured by reference we can specify such variables further in the capture list.
-```cpp
-#include <iostream>
-int main() {
-  int one{};
-  float two{};
-  double three{};
-  const auto Lambda = [=, &two] {
-    // two is captured by reference, all the others by copy.
-    std::cout << one << " " << two << " " << three << std::endl;
-  };
-  Lambda();
-}
-```
-
-Should we want to capture all variables by reference instead, we can pass a single ampersand `&` symbol instead.
-```cpp
-#include <iostream>
-int main() {
-  int one{};
-  float two{};
-  double three{};
-  const auto Lambda = [&] {
-    // All variables are captured by reference.
-    std::cout << one << " " << two << " " << three << std::endl;
-  };
-  Lambda();
-}
-```
-Almost opposite to the previous setup, if we want _some_ variables to still be captured by copy, we can simply append them to the capture list.
-```cpp
-#include <iostream>
-int main() {
-  int one{};
-  float two{};
-  double three{};
-  const auto Lambda = [&, two] {
-    // two is captured by copy, all the others by reference.
-    std::cout << one << " " << two << " " << three << std::endl;
-  };
-  Lambda();
-}
-```
-
-Finally, if a lambda appears within a class method, we might want it to have access to all the data within the current object. For that we can pass `this` into the lambda capture list and use the object data without issues:
-```cpp
-#include <iostream>
-
-struct Foo {
-  void Bar() {
-    [this] {
-      // The whole current object is captured by reference.
-      std::cout << one << " " << two << " " << three << std::endl;
-    }();  // We call this lambda in-place for illustration purposes.
-  }
-
-  int one{};
-  float two{};
-  double three{};
-};
-
-int main() {
-  Foo foo{};
-  foo.Bar();
-}
-```
-Note, that just to show that this is possible, we call the lambda in-place right after declaring it.
-
-And, on that note, now that we've discussed most of the syntax we use for lambdas, we can see that `[](){}()` from the start of this video is just a definition of a lambda that has an empty capture list, no arguments, empty body, which is called in-place right after creation (doing nothing of course). This lambda is totally useless, apart from the entertainment it provides :wink:
-
-## When to use lambdas
-All in all, lambdas are neat and efficient. If we need a callable object to pass to some function and we don't think we'll ever want to reuse it, like in our example with sorting, lambdas should be our go-to tool.
-
-Another typical use-case for lambdas is in situations when we find ourselves writing a long function and we end up outlining each logical step we take by a comment. I'm sure we've all seen code like this, but just to illustrate this, let's have a look at a small example code for, say, creating a sandwich. This process takes a bunch of steps, we need to prepare the bread, prepare the ingredients, and finally assemble the sandwich. Here we outline each step with a comment that corresponds to our actions.
-<!--
-`CPP_SETUP_START`
-#include <string>
-using Sandwich = std::string;
-$PLACEHOLDER
-int main() {
-  const auto sandwich = MakeGourmetSandwich();
-}
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` sandwich_no_lambdas/main.cpp
-`CPP_RUN_CMD` CWD:sandwich_no_lambdas c++ -std=c++17 main.cpp
--->
-```cpp
-#include <iostream>
-#include <string>
-
-// 😱 Comments tend to drift out of sync with code.
-Sandwich MakeGourmetSandwich() {
-    Sandwich sandwich{};
-
-    // Step 1: Prepare the bread
-    sandwich += "Choosing the finest sourdough...\n";
-    sandwich += "Lightly toasting it to perfection...\n";
-    sandwich += "Spreading a generous amount of garlic aioli...\n";
-
-    // Step 2: Prepare the ingredients
-    sandwich += "Grilling marinated chicken...\n";
-    sandwich += "Adding fresh arugula and juicy tomatoes...\n";
-    sandwich += "Topping it off with caramelized onions...\n";
-
-    // Step 3: Assemble the masterpiece
-    sandwich += "Assembling the sandwich with care...\n";
-    sandwich += "Adding a drizzle of truffle oil...\n";
-    sandwich += "Plating it elegantly...\n";
-
-    return sandwich;
-}
-```
-The main issue with comments is that if we change the implementation it is really easy to forget to update the corresponding comments! So comments tend to drift out of sync with the code. I much prefer putting each step into a separate lambda instead:
-<!--
-`CPP_SETUP_START`
-#include <string>
-using Sandwich = std::string;
-$PLACEHOLDER
-int main() {
-  const auto sandwich = MakeGourmetSandwich();
-}
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` sandwich_with_lambdas/main.cpp
-`CPP_RUN_CMD` CWD:sandwich_with_lambdas c++ -std=c++17 main.cpp
--->
-```cpp
-#include <iostream>
-#include <string>
-
-// ✅ Every step is encapsulated in a lambda.
-Sandwich MakeGourmetSandwich() {
-    Sandwich sandwich{};
-
-    const auto PrepareBread = [&sandwich]() {
-        sandwich += "Choosing the finest sourdough...\n";
-        sandwich += "Lightly toasting it to perfection...\n";
-        sandwich += "Spreading a generous amount of garlic aioli...\n";
-    };
-
-    const auto PrepareIngredients = [&sandwich]() {
-        sandwich += "Grilling marinated chicken...\n";
-        sandwich += "Adding fresh arugula and juicy tomatoes...\n";
-        sandwich += "Topping it off with caramelized onions...\n";
-    };
-
-    const auto PlateSandwich = [&sandwich]() {
-        sandwich += "Assembling the sandwich with care...\n";
-        sandwich += "Adding a drizzle of truffle oil...\n";
-        sandwich += "Plating it elegantly...\n";
-    };
-
-    PrepareBread();
-    PrepareIngredients();
-    PlateSandwich();
-
-    return sandwich;
-}
-```
-Now it is a bit harder to make a mistake and in my experience the situation in which the function name, lambda or not, does not correspond to what is happening inside of it is much more often caught during code review than a comment that went out of sync. This trick is sometimes useful for [header-only libraries](headers_and_libraries.md) as we cannot use functions in [unnamed namespaces](namespaces_using.md#use-unnamed-namespaces) there.
-
-One thing to be weary of though, is to try not to get used to capturing *all* variables by default. While it might be tempting to always capture all the observed variables by reference using the ampersand in the capture list `[&]`, in my experience it sometimes makes it harder to understand what the lambda really does when reading the code. So in most of *my* code, I prefer to capture only the variables I _really_ need, as opposed to blanket-capturing all the visible ones.
-<!-- But I'm interested in what you guys think about it, so please comment below the video with your experience with this. -->
-
-## Summary
-And this is pretty much most of the things we need to know about lambdas. But if you ever need more details on anything here, please refer to their [cppreference.com](https://en.cppreference.com/w/cpp/language/lambda) page, as always. And, as always, please play around with the examples I provided here or write your own. I firmly believe that the best way to learn is to make our own mistakes!
-
-All in all, lambdas are a useful tool in our toolbox and we'll find that we want to use them quite often when writing modern C++ code. I hope that I could build parallels with what we have already learnt until now so that you can get all the use out of lambdas while not being scared of what they do under the hood.
-
-<!--
-And if you'd like to refresh why we need templates, please click the video over here or maybe have another look at what kinds of libraries we can have here instead.
-
-Thanks a lot for watching and I'll catch you in the next video, bye! -->
diff --git a/lectures/memory_and_smart_pointers.md b/lectures/memory_and_smart_pointers.md
deleted file mode 100644
index a46b285..0000000
--- a/lectures/memory_and_smart_pointers.md
+++ /dev/null
@@ -1,532 +0,0 @@
-Memory management and smart pointers
---
-<p align="center">
-  <a href="https://youtu.be/eHcdTytDZrI"><img src="https://img.youtube.com/vi/eHcdTytDZrI/maxresdefault.jpg" alt="Video" align="right" width=50% style="margin: 0.5rem"></a>
-</p>
-
-- [Memory management and smart pointers](#memory-management-and-smart-pointers)
-- [Memory management in C++](#memory-management-in-c)
-  - [Automatic memory management in other programming languages](#automatic-memory-management-in-other-programming-languages)
-  - [The C++ way](#the-c-way)
-- [Memory allocation under the hood](#memory-allocation-under-the-hood)
-  - [The stack](#the-stack)
-  - [Why not keep persistent data on the stack](#why-not-keep-persistent-data-on-the-stack)
-  - [The heap](#the-heap)
-    - [Operators `new` and `delete`](#operators-new-and-delete)
-- [Typical pitfalls with data allocated on the heap](#typical-pitfalls-with-data-allocated-on-the-heap)
-    - [Forgetting to call `delete`](#forgetting-to-call-delete)
-    - [Performing shallow copy by mistake](#performing-shallow-copy-by-mistake)
-  - [Performing shallow assignment by mistake](#performing-shallow-assignment-by-mistake)
-  - [Calling a wrong `delete`](#calling-a-wrong-delete)
-  - [Returning owning pointers from functions](#returning-owning-pointers-from-functions)
-- [RAII for memory safety](#raii-for-memory-safety)
-  - [STL classes use RAII](#stl-classes-use-raii)
-  - [Smart pointers to the rescue!](#smart-pointers-to-the-rescue)
-    - [`std::unique_ptr`](#stdunique_ptr)
-    - [`std::shared_ptr`](#stdshared_ptr)
-      - [Prefer `std::unique_ptr`](#prefer-stdunique_ptr)
-  - [Smart pointers are polymorphic](#smart-pointers-are-polymorphic)
-- [Summary](#summary)
-
-
-Alongside with understanding move semantics that we've [already looked at](move_semantics.md), it is also important to understand how memory is allocated and freed when we create and destroy variables in various ways, why manually dealing with memory can quickly become a mess, and how smart pointers help us avoid this mess. So let's dive in!
-
-<!-- Intro -->
-
-## Memory management in C++
-When we declare variables they have to be allocated somewhere. Which essentially means that they need to find a big-enough free slot in memory to fit into. Once we stop using these variables, we want them to free the memory that they occupied so that it could be reused, otherwise we might run out of free memory and be unable to create any new variables, which we'd really like to avoid!
-
-This act of allocating and freeing memory is usually called **"memory management"**.
-
-### Automatic memory management in other programming languages
-Some languages like Python, Go, Java, or C#, just to name a few, deal with memory management in an automatic fashion, by using the so-called **"garbage collection"** system. This system runs at intervals in the background and searches for the variables that are not in use anymore and frees their memory. We can observe this by looking at the amount of memory used by programs written in such languages while they are running: the amount of allocated memory will grow for a while, followed by sharp drops once the garbage collection is triggered.
-
-<img src="images/gc.png" alt="Garbage collection" align="right" width=70% style="margin: 0.5rem">
-
-We won't focus too much on garbage collection here though, but if you'd like a more in-depth look into this, please feel free to follow a link to a post about various [options for garbage collection in Java](https://dzone.com/articles/choosing-the-right-gc).
-<!-- that is linked below this video. -->
-
-While such a garbage collection system is convenient in terms of not needing to think about memory on our side, using it takes away from the performance of our program. These systems must perform a scan for unused memory repeatedly at runtime which costs time. Furthermore it is hard to predict when these scans will happen and how long they will take, so garbage collected languages are not well-suited for safety-critical applications where we need to know exactly when each operation takes place and that they all fall within a certain time budget.
-
-### The C++ way
-What makes C++ suited for such safety-critical applications is that it stays away from garbage collection based memory management altogether. Instead it takes a two-tier approach.
-
-On one hand it makes a good use of scopes and makes sure that any simple small variable allocated withing a scope gets freed by the end of it in an extremely efficient manner.
-
-On the other hand, for some variables that need to allocate a large chunk of memory or that have to be still available after the end of the scope in which they were allocated, it allows us to allocate and release memory manually at our discretion. Which in turn allows us implement any behavior of arbitrary complexity.
-
-Here I have to mention that with great power comes great responsibility and, historically, most of the fear of C++ among the beginners came from this ability to manage memory manually. It was complicated to think about how this manually allocated memory should be managed, and especially when it should be freed. There was also a lack of good tools and guidance that would be universal for each and every situation, which made learning how to work with memory safely hard.
-
-But thankfully those days are in the past and that's where **modern C++** really comes into play. You see, today we *have* these tools within the Standard Template Library (STL) as well as the accompanying guidance on how to use them that work for nearly any situation that we might encounter! Using these tools and following the best practices allows us thinking more abstractly about what we do: not when to allocate and free memory but what **entities** we want to create, who owns them and how their ownership should be transferred while the program runs. This makes reasoning about our programs much easier while keeping our code efficient and memory-safe by default.
-
-## Memory allocation under the hood
-But before we talk about these tools we have at our disposal to manage memory in modern C++, let's briefly focus on the basics: on what happens under the hood when we want to create or destroy a variable. And, while common, this task is anything but trivial.
-
-Remember, we want to find a perfect place in memory for every variable we want to use. These variables can have vastly different sizes and lifetime durations which influences their optimal placement in memory. Furthermore, we usually want to avoid "fragmentation" of our memory, i.e., we don't want to have many small "holes" between allocated variables. If we have those, it might be that we have a lot of free memory in the absolute sense, but we are still unable to find a continuous chunk of memory to allocate some larger variable. This means that ideally we want to find for each variable being allocated the smallest free memory slot it fits into.
-
-Solving this problem in general is very hard! Think about it, we can't scan **all** the memory at our disposal exhaustively every time we want to allocate a variable, that would take too long! But we _can_ find effective algorithms for finding *not perfect*, but _good-enough_ spots, granted that we have some more information about our data.
-
-### The stack
-For example, we might notice that a lot of scope-local variables we use are really small variables like `int`s or `float`s. They are allocated and freed within their scopes very often which means that, ideally, they should be allocated and freed very quickly. Considering that these variables are mostly small in size and that our scopes are mostly quite short (at least they should be), it is a feasible assumption that we should be able to fit all of such small local variables into a relatively small continuous chunk of memory.
-
-So we designate a small part of our memory, typically around 8MB on Linux and MacOS, to managing such local variables. Furthermore, because these variables are always allocated sequentially and get de-allocated in the reverse order of their allocation at the end of the scope, we use a stack-like data structure for managing where to place them in memory.
-
-<img src="images/stack-coins.png" alt="Garbage collection" align="right" width=20% style="margin: 0.5rem">
-
-Just like a stack of coins allows putting and removing coins from the top of this stack, such data structure supports **putting** and **popping** variables at the **end** of the currently occupied stack space.
-
-🚨 This mechanism is used under the hood for all the local variables we create and destroy in our C++ programs. 🚨
-
-And just to get some more intuition let's look at it a bit more precisely. We'll use an example, as we always do. This example **does not follow any of the best practices** we followed throughout this course, furthermore it leads to an undefined behavior, so please don't copy this example to any real projects. But it does serve us well to build the intuition of how stack works.
-
-In this example, we allocate an `int` with a value of `2` on a stack, followed by a variable of type `int*` that points to nothing, or a `nullptr`. Then a new scope starts and we allocate two integers in a static C-style array without initializing them. Please don't use such C-style arrays in real life, but I do need them for illustration purposes here to make this example simpler. We set the values in that array in the next two lines. In C++, standard C-style arrays are equivalent to pointers and we can set `ptr` to point to the start of our `array` data. This is not a great idea in modern C++, but is a good indicator of where things are on a stack for us. If we now print these values we'll get the expected output of `42` followed by `23`. However, everything changes once we leave the inner scope. Once we leave that scope all of the variables allocated while in it get popped off the stack. Which means that now `ptr` points to some data that we do not control. This leads to **undefined behavior** and if we run this program it might print anything that it finds under that address.
-```cpp
-#include <iostream>
-
-int main() {
-  int size = 2;
-  int* ptr = nullptr;
-  {
-    int array[size];  // 😱 Don't use C-style arrays!
-    array[0] = 42;
-    array[1] = 23;
-    ptr = array;
-    std::cout << "Before stack cleanup.\n";
-    for (int i = 0; i < size; ++i) {
-      std::cout << ptr[i] << std::endl;
-    }
-  }
-  // 😱 Code below leads to undefined behavior!
-  std::cout << "After stack cleanup.\n";
-  for (int i = 0; i < size; ++i) {
-    std::cout << ptr[i] << std::endl;
-  }
-  return 0;
-}
-```
-This way of dealing with allocating and freeing variables is amazing for local data. As long as the data does not need to persist beyond the end of the scope, this data structure is very efficient! We always know exactly where to allocate new memory and which memory to free **at constant time**, no additional runtime operations needed!
-
-### Why not keep persistent data on the stack
-Many things change the moment we want to allocate bigger chunk of data at once or for our data to persist beyond the end of the scope. Pause for a moment and think if we can keep such data on the stack too! ⏱️
-
-In the case of bigger chunk of data the answer is obvious: once the data stops fitting into the stack, we can't allocate it. If we try to allocate progressively more data in a loop, the program will terminate with `SIGSEGV`, which means that we tried accessing memory that is not allowed for us to access when trying to allocate beyond 8MB of data:
-```cpp
-#include <iostream>
-
-int main() {
-  const int megabyte{1'000'000};
-  int i{};
-  while(true) {
-    // 😱 Don't use C-style arrays in real code!
-    std::byte numbers[i++ * megabyte];
-    std::cerr << "Allocating " << i << " * MB\n";
-  }
-  return 0;
-}
-```
-
-Now, what about persistent data?
-
-Let's for a moment assume that we could keep a variable in our stack for a longer time. And let's also assume that we allocated it in the middle of some scope, with some normal stack variables allocated before and after it. By the end of the scope we must free all memory of those variables. Which essentially means that we would need to pop all the variables above our persistent variable, then copy our variable somewhere, pop the rest of the normal variables and copy our persistent variable back. Not only this is not elegant but we also had to copy a potentially large chunk of memory around, which is slow.
-
-The situation is similarly bad if we would want to free the memory of our persistent variable at some manually chosen point. This would mean that we would need to copy everything that we put on top of it in the stack, remove the persistent data we want, then copy everything back on top of the stack. Also slow!
-
-And we don't like slow!
-
-As you can imagine, the situation would be even worse if there would be more of these persistent variables we wanted to keep track of, which is actually typically the case.
-
-So clearly we want to keep our stack quite small and used exclusively for local variables. Therefore, we must find another way to find a place to allocate potentially large persistent data.
-
-### The heap
-Such a place needs to be able to accommodate variables of any size, from small to very large. Also, allocations should depend as little as possible on the amount of data allocated before or after. Finally, such allocations should generally be made explicitly by the programmer as only they know if the particular data should persist and for how long.
-
-When we speak about allocating these data, we usually call these data being allocated **"on the heap"**. Those of you who know data structures might think that this is related to the "heap" data structure - a binary tree with the parent having a larger or smaller key value than its children. And indeed I could imagine how the free chunks of memory could be organized as such a heap data structure by size to optimize the search for a free chunk of a given size. But that seems to be **not the case**, although the evidence is murky on this one. If we trust Donald Knuth (one of the gods of algorithm design), this name is just coincidental. But I could not find any definitive proof for either side of the argument, so if you have it, please send it my way.
-
-<!-- And while you're at it, please subscribe to this channel, it really shows me if I'm moving in the right direction with these videos! -->
-
-Anyway, the easiest way to think about the heap is an intuitive one - imagine a heap of stuff, like coins. Every coin represents a place where we can store our variable that we want to allocate, and let's say that its denomination indicates the amount of free space available.
-
-<img src="images/heap-coins.png" alt="Garbage collection" align="right" width=30% style="margin: 0.5rem">
-
-So when we need to create a new variable on the heap, we look through our heap to find a coin that represents space big enough for our variable and store our variable in that found slot. In our analogy this effectively removes the found coin from the heap maybe adding a smaller coin in its place.
-
-This obviously takes some time at runtime but once such a place is found the variable can stay in that memory until we don't need it anymore. So, allocating on the heap is definitely less efficient than allocating on the stack but it has a benefit of being able to allocate or de-allocate these data at any time with less consideration on how packed the rest of the memory is.
-
-Please note that this is a **very inaccurate analogy** as there is much more stuff happening under the hood and the actual implementations of the heap allocators are well-optimized and, as a result, quite complex, but thinking about a heap of coins gives a decent enough intuition. And that is all I'm aiming for here.
-
-#### Operators `new` and `delete`
-We allocate memory on the heap manually in C++. For that we use `new` and `new[]` operators that take a type and derive the amount of space that we want to allocate from that type. The `new` operator allocates a single variable, while `new[]` allocates an array of those. In order to free the memory we need to call `delete` or `delete[]` respectively on the pointer that points to the memory allocated on the heap.
-```cpp
-int main() {
-  int* ptr_1 = new int{42};  // Allocate single variable.
-  int* ptr_2 = new int[3]{1, 2, 3};  // Allocate array.
-  delete ptr_1;
-  delete[] ptr_2;
-  return 0;
-}
-```
-
-<!-- Animate a change from the stack example -->
-To have a bit more hands-on experience, let us see how our previous example changes if we use `new[]` instead of allocating a C-style array directly on the stack.
-```cpp
-#include <iostream>
-
-int main() {
-  int size = 2;
-  int* ptr = nullptr;
-  {
-    // 😱 Don't use unprotected new and new[]!
-    int* array = new int[size];
-    array[0] = 42;
-    array[1] = 23;
-    ptr = array;
-    std::cout << "Before stack cleanup.\n";
-    for (int i = 0; i < size; ++i) {
-      std::cout << ptr[i] << std::endl;
-    }
-  }
-  std::cout << "After stack cleanup.\n";
-  for (int i = 0; i < size; ++i) {
-    std::cout << ptr[i] << std::endl;
-  }
-  delete[] ptr;  // 😱 What points to our data?
-  return 0;
-}
-```
-We start by pushing the `size` and the `ptr` to the stack and enter the inner scope just as before. What is not as before is that we now use the `new[]` operator to allocate our array on the heap. We only allocate memory for it, without initializing the stored values, so initially it stores garbage data. Note that the **pointer to these data**, that we here still call `array`, is **still stored on the stack**! Now we update the values stored in our array and set the `ptr` to point to the same address as the `array` which allows us to print the values using the `ptr` variable. Different from the example before, when we leave the scope, only the `array` variable is cleaned-up from the stack, but the `ptr` variable still points to our data, which still happily lives on the heap. So we can still print all the values we stored in our array using the `ptr` pointer without any undefined behavior. Finally, we can explicitly free the memory using the `delete[]` operator on our `ptr` variable and at the end of the program the stack empties itself.
-
-## Typical pitfalls with data allocated on the heap
-There is a number of common pitfalls when using heap-allocated data. And you could probably have already guessed this from the amount of screaming smileys in my code snippets. If you followed my lectures for a while, you know that I am not a fan of taking care of things manually, I don't really trust myself on that :wink:. If we use `new` and `delete` operators manually like in the example before, we have to be very careful with them!
-
-#### Forgetting to call `delete`
-If we forget to call `delete` on the data that we allocated with `new`, we get a memory leak as the memory we allocated is never be freed!
-<center>
-<video src="images/destructor.mp4" width=50% style="margin: 0.5rem" autoplay muted/>
-</center>
-
-#### Performing shallow copy by mistake
-Another common mistake when working with raw pointers is to try to copy the data by assigning one pointer to another.
-```cpp
-int main() {
-  int* ptr_1 = new int{42};
-  int* ptr_2 = ptr_1;
-  delete ptr_2;
-  ptr_2 = nullptr;
-  // 😱 ptr_1 points to garbage!
-  return 0;
-}
-```
-But this **does not copy the data**, this only copies the pointer! So instead we now have two pointers that point to the same data! If we `delete` the memory under both of these pointers we will free the memory twice, which is not allowed. Let's say we remove `ptr_2` first. Now `ptr_1` points to memory that was already released. If we try to `delete` it now we will get a runtime error that will tell us that we are trying to free the memory twice (thus, double free):
-```
-*** Error: double free or corruption (fasttop): 0x00000000010a3010 ***
-```
-<center>
-<video src="images/dangling_pointer.mp4" width=50% style="margin: 0.5rem" autoplay muted/>
-</center>
-
-
-### Performing shallow assignment by mistake
-If we initially allocate two objects the situation becomes even worse!
-```cpp
-int main() {
-  int* ptr_1 = new int{42};
-  int* ptr_2 = new int{23};
-  ptr_2 = ptr_1;
-  delete ptr_2;
-  ptr_2 = nullptr;
-  // 😱 Lost access to some data!
-  return 0;
-}
-```
-Not only we have the same error as before by freeing the memory twice but we also introduce a memory leak as we now do not have any pointer that points to the data originally stored under the second pointer!
-<center>
-<video src="images/shallow_assignment.mp4" width=50% style="margin: 0.5rem" autoplay muted/>
-</center>
-
-### Calling a wrong `delete`
-Even if we _do_ call a `delete` we can still mess things up. If we allocate an array using the `new[]` operator and free it with a normal `delete` we will only free the memory under the first element of our array, so, memory leak again!
-```cpp
-int main() {
-  int* array = new int[23];
-  delete array;
-  // 😱 Only freed a single int!
-  return 0;
-}
-```
-Although in this case, at least on a modern `clang` compiler, there is a compilation warning about this situation, so please make sure you have warnings enabled and there are no warnings left unhandled when you compile you code!
-
-### Returning owning pointers from functions
-But we're not always as lucky! It gets worse! Much worse! If we don't follow best practices, we might **have no way** of knowing if and how we should free the data under a given pointer! :scream:
-
-<!-- Animate this as code -->
-Imagine we have a bunch of functions that all return exactly the same type, `int*`. It is impossible to know if we need to free the memory that the returned value points to by just looking at that pointer alone! And yes, we might get lucky and these functions might all have descriptive names, of course. In this case, if we trust the names, we know which pointers we must free and which `delete` operator to use.
-```cpp
-// 😱 Manual allocation is bad, especially in functions!
-namespace {
-
-struct Pool {
-  static int* GetPtr() { return &data_; }
-  inline static int data_{};
-};
-
-int* AllocateVariable() {
-  return new int;
-}
-
-int* AllocateArray(int size) {
-  return new int[size];
-}
-
-int* BorrowDataFromPool() {
-  return Pool::GetPtr();
-}
-
-}  // namespace
-
-int main() {
-  auto* ptr_1 = AllocateVariable();
-  auto* ptr_2 = AllocateArray(20);
-  auto* ptr_3 = BorrowDataFromPool();
-  delete ptr_1;
-  delete[] ptr_2;
-  return 0;
-}
-```
-Our functions clearly state that they allocate memory and also what they allocate, so we know that we should use `delete` to free the memory of a single allocated variable under `ptr_1`, `delete[]` to free memory allocated to store an array pointer to by `ptr_2` and that we should not touch the memory under `ptr_3` as that memory will be freed by the `Pool` struct.
-
-However, let's be honest, life is rarely as accommodating in the real world. Functions might change their implementation with time without updating their names to adequately reflect these changes! Or they might not have readable names in the first place! This way we _must look into the implementation of these functions_ to make out what they do!
-```cpp
-// 😱 Manual allocation is bad, especially in functions!
-namespace {
-
-struct Pool {
-  static int* GetPtr() { return &data_; }
-  inline static int data_{};
-};
-
-int* Foo() {
-  return Pool::GetPtr();
-}
-
-int* Bar(int size) {
-  return new int[size];
-}
-
-int* Buzz() {
-  return new int;
-}
-
-}  // namespace
-
-int main() {
-  auto* ptr_1 = Foo();
-  auto* ptr_2 = Bar(20);
-  auto* ptr_3 = Buzz();
-  delete ptr_3;
-  delete[] ptr_2;
-  return 0;
-}
-```
-This is already quite annoying, but we still technically **can** find out if we should free the memory and with which operator in each of these cases. But note hard hard it is to track the correct `delete` operators even on such a small example. Imagine having a huge codebase riddles with code like this! :scream:
-
-But we're not done yet, oh no! There is more! If you remember the lectures about [libraries](headers_and_libraries.md) you know that the actual implementation can be hidden from us in a compiled library in such a way that the only thing we see is the declaration of the function. **Now there is no way for us to know what we should do with the pointers we get! :scream:**
-
-`lib.hpp`
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` memory_and_pointers/lib.hpp
--->
-```cpp
-int* Foo();
-int* Bar(int number);
-int* Buzz();
-```
-
-`main.cpp`
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` memory_and_pointers/main.cpp
-`CPP_RUN_CMD` CWD:memory_and_pointers c++ -std=c++17 -c main.cpp
--->
-```cpp
-#include "lib.hpp"
-
-int main() {
-  auto* ptr_1 = Foo();
-  auto* ptr_2 = Bar(20);
-  auto* ptr_3 = Buzz();
-  // 😱 What should we do with these pointers?
-  return 0;
-}
-```
-
-Let's quickly outline all the errors that are possible here:
-1. **We don't free the memory.** This causes a memory leak in data under `ptr_3` and `ptr_2` - they never release their memory!
-2. **We free memory with wrong `delete`.** Should we free memory under `ptr_2` with `delete` rather than with `delete[]` we will only release the memory directly under the pointer, not for the whole allocated array. So, a memory leak again.
-3. **We free memory twice.** If we use `delete` on `ptr_1` we will get various errors, either `double free or corruption` or `free(): invalid pointer` depending if the `Pool` allocates data on the heap or not. Regardless, we are getting a runtime error because of this.
-
-## RAII for memory safety
-I hope I scared you enough and you never want to allocate and free memory manually ever in your life! And this is a great attitude, trust me!
-
-There **is** a solution to all of these problems. In the lecture about [object lifecycle](object_lifecycle.md) we already touched upon the RAII principle that stands for **R**esource **A**llocation **I**s **I**nitialization. This principle is crucial for writing safe C++ code. Essentially, we need to make sure that all memory allocation happens at the time of object creation, ideally in a constructor, and that memory is released on object destruction, in the destructor. Combining this with properly implemented value semantics, such that these objects can be copied and [moved](move_semantics.md) safely, and we can pretty much guarantee the overall memory safety.
-
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` memory_smart_ptrs_object/main.cpp
-`CPP_RUN_CMD` CWD:memory_smart_ptrs_object c++ -std=c++17 -c main.cpp
--->
-```cpp
-class Object {
- public:
-  explicit Object(int number) : data_{new int{number}} {}
-
-  ~Object() { delete data_; }
-
-  Object(const Object& other)
-      : data_{other.data_ ? new int{*other.data_} : nullptr} {}
-
-  Object(Object&& other) : data_{other.data_} { other.data_ = nullptr; }
-
-  Object& operator=(const Object& other) {
-    if (other.data_) {
-      data_ = new int{*other.data_};
-    }
-    return *this;
-  }
-
-  Object& operator=(Object&& other) {
-    data_ = other.data_;
-    other.data_ = nullptr;
-    return *this;
-  }
-
- private:
-  int* data_{};
-};
-```
-### STL classes use RAII
-This is essentially what happens in the STL containers like `std::vector` or `std::string`. They wrap a raw pointer to some heap-allocated memory and dynamically manage it, including resizing it when required, moving the pointer to it during the ownership transfer and eventually cleaning things up when they get destroyed. So we can work with variables of these types as if we had simple local variables and let these classes handle all the memory-related stuff under the hood.
-
-### Smart pointers to the rescue!
-But what if we have our custom data that we want to allocate on the heap? Well, we could write a wrapper class that would allocate our data, handle all the move-semantics and eventually free its memory but there is a better way.
-
-And now is eventually a good time to talk about smart pointers! They are RAII containers with proper value semantics out of the box so that we don't have to implement such value semantics from scratch. Furthermore there are different flavors of smart pointers to model different types of ownership.
-
-Nowadays, we mostly use `std::unique_ptr` and `std::shared_ptr`, so let's talk about these a bit more in-depth.
-
-These are classes implemented in the **S**tandard **T**emplate **L**ibrary, or STL under the `#include <memory>` header. They are designed to be an almost drop-in replacement for raw owning pointers while providing guarantees for memory safety.
-
-#### `std::unique_ptr`
-The [`std::unique_ptr`](https://en.cppreference.com/w/cpp/memory/unique_ptr) is our main workhorse when we need to create data on the heap. The idea is extremely simple: the `std::unique_ptr` enforces unique ownership of a raw pointer given to it. That means that this unique pointer is the only entity responsible to free the memory under its pointer.
-
-The way this is achieved technically is by making sure that the copy constructor and assignment operators of the `std::unique_ptr` class are **deleted**. This way, a unique pointer **can only be moved, not copied**! This way, there are never two raw pointers that point to the same memory owned by this unique pointer.
-
-We work with an entity of such a unique pointer in a very similar way to how we usually work with a raw pointer.
-The `std::unique_ptr` is a class template which we can instantiate for any wanted type, here `int`. We can either directly call its constructor passing a raw pointer to the memory allocated with `new` or we can use a helper function `std::make_unique` that helps us hide the naked `new` away and has benefits in terms of memory safety should something go wrong during the allocation.
-```cpp
-#include <iostream>
-#include <memory>
-
-int main() {
-  auto ptr_1 = std::unique_ptr<int>(new int{23});
-  auto ptr_2 = std::make_unique<int>(42);  // Prefer this to the above.
-  std::cout << "*ptr_1: " << *ptr_1 << std::endl;
-  std::cout << "*ptr_2: " << *ptr_2 << std::endl;
-  ptr_1 = std::move(ptr_2);
-  std::cout << "*ptr_1: " << *ptr_1 << std::endl;
-  std::cout << "ptr_1: " << ptr_1.get() << std::endl;
-  ptr_1.reset(new int{2323});
-  std::cout << "*ptr_1: " << *ptr_1 << std::endl;
-  std::cout << "ptr_1: " << ptr_1.get() << std::endl;
-  return 0;
-}
-```
-Once created, we can access the values under our pointers by dereferencing them with the `*` operator or, in case of classes, we can call their members with `->` operator just like we did with [raw pointers](raw_pointers.md) before.
-
-We cannot assign `ptr_2` to `ptr_1` as the copy assignment operators is deleted for `std::unique_ptr`, which protects us from performing a shallow copy by mistake, but we _can_ move-assign one into another. This way, the memory initially held by `ptr_1` is freed and `ptr_1` takes ownership of the memory previously owned by `ptr_2`. When `ptr_1` dies it frees the memory it owns, so no need to call any `delete` on our side.
-
-In addition to this typical pointer-like interface, we also have access to functions like `.get()` which gets the underlying raw pointer and `.reset(T*)` that allows to reset the smart pointer to own a different raw pointer.
-
-All in all, `std::unique_ptr` is an extremely useful tool! Use it all the time when you need to allocate some persistent data on the heap! It mimics raw pointers very closely without any of their downsides and costing us ([nearly](https://youtu.be/rHIkrotSwcc?si=G1yWs9zJ59od6aMj)) nothing at runtime.
-<!-- If you are interested in why I said "nearly", watch this CppCon talk by Chandler Carruth, it is an amazing talk about what we call a "zero-cost abstraction" and why they probably don't really exist. Thanks me later! -->
-
-#### `std::shared_ptr`
-Another smart pointer that is extremely popular is the [`std::shared_ptr`](https://en.cppreference.com/w/cpp/memory/shared_ptr). As the name suggest, just as `std::unique_ptr` models unique ownership over some data, `std::shared_ptr` models, well, **shared ownership**.
-
-Under the hood, it is also a RAII container but, unlike the unique pointer, it does not delete its copy constructor and assignment operators. Rather, `std::shared_ptr` implements the so-called "reference counting" under the hood. Essentially, it keeps track of how many instances of this `shared_ptr` point to any particular underlying data. If a new copy is created, this counter is incremented and if some instance is destroyed it gets decremented. Only once all of them are destroyed, i.e., no one points to the data, the data is freed.
-
-I hope that you now see why the ownership is shared. Any of the `shared_ptr` instances can be the last surviving one and so can be the one that removes the data, and whoever removes the data owns it!
-
-We create a `std::shared_ptr` in a very similar way to `std::unique_ptr`, by either using its constructor that also takes a raw pointer or using the `std::make_shared` helper function that allocates the needed object under the hood.
-```cpp
-#include <iostream>
-#include <memory>
-// 😱 Missing other special functions to save space.
-struct A {
-  A(int a) { std::cout << "I'm alive!\n"; }
-  ~A() { std::cout << "I'm dead... :(\n"; }
-};
-
-int main() {
-  auto a_ptr = std::make_shared<A>(10);
-  std::cout << a_ptr.use_count() << std::endl;
-  {
-    auto b_ptr = a_ptr;
-    std::cout << a_ptr.use_count() << std::endl;
-  }
-  std::cout << "Back to main scope\n";
-  std::cout << a_ptr.use_count() << std::endl;
-  return 0;
-}
-```
-Note how, as opposed to the unique pointer, we can copy a shared pointer to another shared pointer.
-
-In addition to the interface that a unique pointer provides, we can also see the number of pointers that point to our particular place in memory by calling the `use_count()` function, which in this example will show us that it is incremented in the inner scope and goes back to the old value when we leave that scope.
-
-##### Prefer `std::unique_ptr`
-One final word of caution related to `std::shared_ptr`. Because they are so easy to use, I regularly see beginners overuse shared pointers where unique pointers would suffice. Mostly this happens due to issues that beginners have with move semantics, so if your understanding of that concept is not rock solid, please give a watch to a lecture where we reinvent move semantics in 13 minutes.
-
-In my experience, in most single-threaded application unique pointers are everything that we need for any situation and the overuse of shared pointers is usually a code smell. So please if you're unsure which one you need, always start with a unique pointer and only use a shared pointer if you really need to!
-
-### Smart pointers are polymorphic
-Finally, as a bonus, smart pointers, being, well, pointers are **polymorphic**, so we can create a `std::unique_ptr<Base>` from an instance of `std::unique_ptr<Derived>` just like what we discussed when talking about [inheritance](inheritance.md).
-```cpp
-#include <iostream>
-#include <memory>
-
-// 😱 Missing other special functions to save space.
-struct Base {
-  virtual void SayHello() const { std::cout << "Base hello\n"; }
-  virtual ~Base() = default;
-};
-struct Derived : public Base {
-  void SayHello() const override { std::cout << "Derived hello\n"; }
-};
-
-int main() {
-  auto ptr_1 = std::unique_ptr<Base>(new Base{});
-  auto ptr_2 = std::unique_ptr<Base>(new Derived{});
-  ptr_1->SayHello();
-  ptr_2->SayHello();
-  return 0;
-}
-```
-In this example, `ptr_1->SayHello()` will call the base implementation while the `ptr_2->SayHello()` will call the overriden `Derived` implementation just as we expect. I'll leave it up to you to check if this also works if we use a shared pointer instead.
-
-## Summary
-Now this is about everything one needs to know about memory allocation and smart pointers. At least this is about 99% of the knowledge, with the rest available at cppreference.com :wink: Was it too much? Tell me what you think!
-
-All in all, we should _almost never_ allocate memory manually. A good rule of thumb is to never write a manual `delete`, which leads us to also (almost) never writing a naked `new` (use `std::make_unique` and `std::make_shared` instead) and we should never have to deal with a memory leak or a dangling pointer in our life! :heart:
-
-<!-- On that, I'd like to, as always, thank you for your time! Please consider telling your C++ inclined friends if you found this useful and you think they might like it too, it would really mean a lot to me!
-
-And if you would like to look deeper in how you might use pointers in a polymorphic way in C++, then please give this video a watch, while if you'd rather dig deeper into how move semantics works, then give this video a go instead.
-
-Thanks again and bye!
--->
diff --git a/lectures/move_semantics.cpp b/lectures/move_semantics.cpp
deleted file mode 100644
index 0dfa7b8..0000000
--- a/lectures/move_semantics.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-#include <cstddef>
-#include <algorithm>
-
-std::byte *AllocateMemory(std::size_t length) { return new std::byte[length]; }
-void FreeMemory(std::byte *ptr) { delete[] ptr; }
-
-// 😱 Note that this struct does not follow best style.
-// We only use it to illustrate the concept here.
-struct HugeObject {
-  HugeObject() = default;
-
-  explicit HugeObject(std::size_t data_length)
-      : length{data_length}, ptr{AllocateMemory(length)} {}
-
-  HugeObject &operator=(const HugeObject &object) {
-    if (this == &object) { return *this; }  // Do not self-assign.
-    FreeMemory(ptr);  // In case we already owned some memory from before.
-    length = object.length;
-    ptr = AllocateMemory(length);
-    std::copy(object.ptr, object.ptr + length, ptr);
-    return *this;
-  }
-
-  HugeObject &operator=(HugeObject &&object) {
-    if (this == &object) { return *this; }  // Do not steal from ourselves.
-    FreeMemory(ptr);  // In case we already owned some memory from before.
-    length = object.length;
-    ptr = object.ptr;
-    object.ptr = nullptr;
-    return *this;
-  }
-
-  ~HugeObject() { FreeMemory(ptr); }
-
-  std::size_t length{};
-  std::byte *ptr{};
-};
-
-struct HugeObjectStorage {
-  HugeObject member_object;
-};
-
-// int main() {
-//   HugeObject object{100};
-//   HugeObjectStorage storage{};
-//   storage.member_object = object;
-//   return 0;
-// }
-
-int main() {
-  HugeObject object{100};
-  HugeObjectStorage storage{};
-  storage.member_object = object;
-  storage.member_object = HugeObject{200};
-  storage.member_object = std::move(object);
-  return 0;
-}
diff --git a/lectures/move_semantics.md b/lectures/move_semantics.md
deleted file mode 100644
index 3f0e21e..0000000
--- a/lectures/move_semantics.md
+++ /dev/null
@@ -1,535 +0,0 @@
-Move semantics
----
-
-<p align="center">
-  <a href="https://youtu.be/kqQ90R0_GFI"><img src="https://img.youtube.com/vi/kqQ90R0_GFI/maxresdefault.jpg" alt="Video" align="right" width=50%></a>
-</p>
-
-- [Why we care about move semantics](#why-we-care-about-move-semantics)
-  - [Setting up the example to illustrate why we need move semantics](#setting-up-the-example-to-illustrate-why-we-need-move-semantics)
-  - [Move semantics enables ownership transfer](#move-semantics-enables-ownership-transfer)
-- [Let's re-design move semantics from scratch](#lets-re-design-move-semantics-from-scratch)
-  - [Can we avoid having this "stealing" behavior?](#can-we-avoid-having-this-stealing-behavior)
-  - [What does it mean to "steal" the data from an object?](#what-does-it-mean-to-steal-the-data-from-an-object)
-  - [Naïve implementation of "stealing"](#naïve-implementation-of-stealing)
-  - [Problems with the naïve solution](#problems-with-the-naïve-solution)
-  - [Better solution - add a new "stealing reference" type to the language!](#better-solution---add-a-new-stealing-reference-type-to-the-language)
-  - [We also design how the "stealing references" are created from other objects](#we-also-design-how-the-stealing-references-are-created-from-other-objects)
-    - ["Stealing references" from temporary objects](#stealing-references-from-temporary-objects)
-    - ["Stealing references" from existing objects already stored as variables](#stealing-references-from-existing-objects-already-stored-as-variables)
-    - [Showcase of what we can do with our new "stealing references"](#showcase-of-what-we-can-do-with-our-new-stealing-references)
-  - [Yay! We've reinvented value semantics!](#yay-weve-reinvented-value-semantics)
-- [How is it actually designed and called in Modern C++?](#how-is-it-actually-designed-and-called-in-modern-c)
-  - [Classes of values](#classes-of-values)
-  - ["Stealing references" are rrefs and they are lvalues 🤯](#stealing-references-are-rrefs-and-they-are-lvalues-)
-- [That's all folks!](#thats-all-folks)
-
-<!-- Talking head + overlay words ✅ -->
-If you heard anything about modern C++, you've probably heard these words: value semantics, move semantics, rvalues, lvalues, rvalue references, rrefs etc.
-
-<!-- Talking head ✅  -->
-The concepts behind these words form the foundational principles behind Modern C++ as we know it.
-
-<!-- Talking head + b-rolls being scared, magic, confusion ✅ -->
-However, for various reasons these concepts are **very confusing to a lot of people**! I've seen people being scared of these things, treating them like magic, and having a lot of misunderstandings along the way. Navigating these waters effortlessly is a must for being able to design great software.
-
-<!-- Talking head ✅ -->
-So, today I'm here to tell you - **there is no black magic!**
-
-<!-- Talking head + scooby doo meme of unveiling rrefs ✅ -->
-Actually, to build a better understanding, we're about to design the value semantics mechanism from scratch using nothing more than the concepts that we already know from the previous videos, mostly references and function overloading!
-
-<!-- Intro -->
-
-# Why we care about move semantics
-<!-- Talking head ✅ -->
-So, in the spirit of "starting with why", I want us to start with an example that will illustrate why we need move semantics.
-
-## Setting up the example to illustrate why we need move semantics
-<!-- Talking head ✅ -->
-But first we need to set the stage. Please bear with me.
-
-<!-- Code -->
-Imagine that we have [a custom type](classes_intro.md) `HugeObject` that **owns** some **big** chunk of memory.
-<!--
-`CPP_SETUP_START`
-#include <cstddef>
-
-std::byte *AllocateMemory(std::size_t length) {
-  return new std::byte[length];
-}
-void FreeMemory(std::byte *ptr) { delete[] ptr; }
-
-$PLACEHOLDER
-
-int main() {
-  HugeObject object_1;
-  HugeObject object_2{100};
-}
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` huge_object_1/main.cpp
-`CPP_RUN_CMD` CWD:huge_object_1 c++ -std=c++17 -c main.cpp
--->
-```cpp
-#include <cstddef>
-
-// 😱 Note that this struct does not follow best style.
-// We only use it to illustrate the concept here.
-struct HugeObject {
-  HugeObject() = default;
-
-  explicit HugeObject(std::size_t data_length)
-      : length{data_length}, ptr{AllocateMemory(length)} {}
-
-  ~HugeObject() { FreeMemory(ptr); }
-
-  std::size_t length{};
-  std::byte *ptr{};
-};
-```
-<!-- ✅ -->
-It allocates this memory using some magic function `std::byte* AllocateMemory(std::size_t length)` on creation and frees this memory using another magic function `FreeMemory(std::byte* ptr)` when it dies. Please see the lecture on [object lifecycle](object_lifecycle.md) if this part sounds confusing.
-
-<!-- Talking head ✅ -->
-> At this point it is not important how exactly the memory allocation happens. We will talk about it in the future. We just have to remember that allocating, copying and freeing memory are all time-wise costly operations.
-> <!-- For the impatient, you can see example of such functions in the script, which is as always linked in the description below  -->
-> But for the impatient, here is one way to allocate the memory that we need in real code.
-> ```cpp
-> // 😱 Please don't do this in real code, for illustration purposes only!
-> // 💡 We will talk about how to properly allocate and free memory later!
-> std::byte *AllocateMemory(std::size_t length) { return new std::byte[length]; }
-> void FreeMemory(std::byte *ptr) { delete[] ptr; }
-> ```
-
-<!-- Code
-Anyway, back to our code... ✅
- -->
-We also want to be able to assign another `HugeObject` to our current object after creation for the sake of this example, so we also add an "assignment operator" to it. This "operator" is just a **function** with a certain signature that takes a reference to a `HugeObject` as an input and copies this incoming object's data into the current instance. You can think of such an operator as being just a function with a funky name.
-<!--
-`CPP_SETUP_START`
-#include <cstddef>
-
-std::byte *AllocateMemory(std::size_t length) {
-  return new std::byte[length];
-}
-void FreeMemory(std::byte *ptr) { delete[] ptr; }
-
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` huge_object_copy/object.hpp
--->
-```cpp
-#include <cstddef>
-#include <algorithm>
-
-// 😱 Note that this struct does not follow best style.
-// We only use it to illustrate the concept here.
-struct HugeObject {
-  HugeObject() = default;
-
-  explicit HugeObject(std::size_t data_length)
-      : length{data_length}, ptr{AllocateMemory(length)} {}
-
-  // Think of it as just a function with a funky name.
-  HugeObject &operator=(const HugeObject &object) {
-    if (this == &object) { return *this; }  // Do not self-assign.
-    FreeMemory(ptr);  // In case we already owned some memory from before.
-    length = object.length;
-    ptr = AllocateMemory(length);
-    std::copy(object.ptr, object.ptr + length, ptr);
-    return *this;
-  }
-
-  ~HugeObject() { FreeMemory(ptr); }
-
-  std::size_t length{};
-  std::byte *ptr{};
-};
-```
-
-<!-- Talking head in different location ✅ -->
-> :bulb: :scream: It's important to note here that this struct does not follow good style, but it is useful to us to illustrate the concept of value semantics. There are important parts missing here, like some constructors, operators or the fact that it should be a class in the first place, so don't copy this code blindly.
-
-<!-- Talking head ✅ -->
-Finally, as the last step of our setup, let's say we also want to store these `HugeObject`s somewhere, in some storage class. It could be an `std::vector` or any other container, but for now we will just have a struct `HugeObjectStorage` that holds a `HugeObject` instance as a `member_object`.
-
-<!-- Code changes ✅ -->
-This allows us to put an existing `HugeObject` into a `HugeObjectStorage` object in the `main` function:
-<!--
-`CPP_SETUP_START`
-#include "object.hpp"
-
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` huge_object_copy/main.cpp
-`CPP_RUN_CMD` CWD:huge_object_copy c++ -std=c++17 -c main.cpp
--->
-```cpp
-struct HugeObjectStorage {
-  HugeObject member_object;
-};
-
-int main() {
-  HugeObject object{100};
-  HugeObjectStorage storage{};
-  storage.member_object = object;
-  return 0;
-}
-```
-<!-- ✅ -->
-Let's quickly talk about what happens here:
-- We create an `object` in the `main` function scope (⚠️ costly)
-- We create an empty `storage.member_object` for the `storage` object (✅ cheap)
-- We copy the data from `object` to `storage.member_object` (⚠️ costly)
-- The `storage.member_object` is destroyed, freeing its data memory
-- The `object` is destroyed, freeing its data memory
-
-<!-- Talking head or code highlight ✅ -->
-At this point, we might observe that we actually **do not use `object` after it is copied into `storage.member_object`**! But both objects `object` and `storage.member_object` are **still maintained** and ready to use. Because of this the data is **copied**, costing us time.
-
-## Move semantics enables ownership transfer
-<!-- Talking head ✅  -->
-This situation is *exactly* why move semantics exists! It exists to enable **ownership transfer** in addition to copying and borrowing the data which we have seen before.
-
-# Let's re-design move semantics from scratch
-<!-- Illustrate data stealing ✅✅ -->
-Essentially we want a way to "steal" the data from `object` and give it to `storage.member_object` if we know that `object` will not use these data anymore. Let's design such a way!
-
-## Can we avoid having this "stealing" behavior?
-<!-- Talking head ✅ -->
-Before designing such a way to steal the data, let's think if there is really no other way. Do we _really_ need to steal the data?
-
-<!-- Illustrate ✅✅ -->
-We see why we can't copy them - it's slow - but why can't we just set the `member_object.ptr` to point to the same memory as `object.ptr` instead?
-
-<!-- Show code and illustrate ✅ -->
-To answer this, let's just look at the destructor of our `HugeObject` class. Essentially it frees the memory that the pointer points to.
-
-<!-- Talking head ✅ -->
-If we have pointers of two objects pointing to the same memory, this memory will be freed twice. This is not allowed and will cause a runtime error!
-
-## What does it mean to "steal" the data from an object?
-<!-- Illustrate with animation, maybe some heist reference ✅ -->
-So, we want to be able to steal the data. But what does it even mean to "steal" them? Well, essentially, it only really makes sense in the context of pointers. If we have a pointer `a` that points to some address `0x42424242` in memory and a pointer `b` "steals" its data it means that at the end of this operation the following is true:
-- Data stays where it was **with no modification**
-- Pointer `b` is set to point to `0x42424242` address
-- Pointer `a` is set to `nullptr`
-
-<!-- Talking head ✅ -->
-The emphasis here is on the **need to modify the pointer that we steal from**!
-
-<!-- Code ✅ -->
-If we want to implement this behavior in our existing assignment operator we can't! :shrug: Our assignment operator takes a **`const` reference** which makes it impossible to modify the underlying object!
-
-## Naïve implementation of "stealing"
-<!-- Talking head ✅ -->
-That is, however, easy enough to fix. Let's just forget everything that we talked about passing objects into functions for a second and just remove the `const` :wink:.
-
-<!-- Code ✅-->
-So let's now change the logic from "copying" to "stealing" by setting the data pointer of the incoming object to `nullptr`:
-<!--
-`CPP_SETUP_START`
-#include <cstddef>
-
-std::byte *AllocateMemory(std::size_t length) {
-  return new std::byte[length];
-}
-void FreeMemory(std::byte *ptr) { delete[] ptr; }
-
-// 😱 Note that this struct does not follow best style.
-// We only use it to illustrate the concept here.
-struct HugeObject {
-  HugeObject() = default;
-
-  explicit HugeObject(std::size_t data_length)
-      : length{data_length}, ptr{AllocateMemory(length)} {}
-
-  $PLACEHOLDER
-
-  ~HugeObject() { FreeMemory(ptr); }
-
-  std::size_t length{};
-  std::byte *ptr{};
-};
-
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` huge_object_move/object.hpp
--->
-```cpp
-// 😱 This is not a good practice and is only here for illustrating purposes
-HugeObject &operator=(HugeObject &object) {
-  if (this == &object) { return *this; }  // Do not self-assign.
-  FreeMemory(ptr);  // In case we already owned some memory from before.
-  length = object.length;
-  ptr = object.ptr;
-  object.ptr = nullptr;  // Essential for "stealing"!
-  return *this;
-}
-```
-
-<!-- Talking head ✅ -->
-Great! Now, here is what happens if we have a look at our old main function:
-<!--
-`CPP_SETUP_START`
-#include "object.hpp"
-
-struct HugeObjectStorage {
-  HugeObject member_object;
-};
-
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` huge_object_move/main.cpp
-`CPP_RUN_CMD` CWD:huge_object_move c++ -std=c++17 -c main.cpp
--->
-```cpp
-int main() {
-  HugeObject object{100};
-  HugeObjectStorage storage{};
-  storage.member_object = object;
-  return 0;
-}
-```
-- We create an `object` in the `main` function scope (⚠️ costly)
-- We create an empty `member_object` for the `storage` object (✅ cheap)
-- We **steal** the data from `object` and set it to `member_object` (✅ cheap)
-- The `storage.member_object` is destroyed, freeing its data memory
-- The `object` is destroyed without cleaning any data as its `ptr` points to `nullptr`
-
-<!-- Talking head ✅  -->
-Stop for a second to admire what we've done! This is essentially how we can steal resources without copying! If we have huge data stored under some pointer, stealing will be much quicker than copying while still not introducing any issues when destroying our objects! And if you ever heard phrases like "we move these data" this is what it is about! We've just "moved" one object into another.
-
-## Problems with the naïve solution
-<!-- Talking head from a different view ✅ -->
-However, the whole story is not as simple... While we *did* achieve what we wanted in this small example, we've made a pretty terrible decision. There is now no more way to do the following:
-
-<!-- Overlay text ✅ -->
-- We cannot copy the data anymore 😐. Sometimes we still might want to! We can only steal now.
-- We cannot pass a temporary object anymore! This won't work!
-  <!-- Code -->
-  <!--
-  `CPP_SKIP_SNIPPET`
-  -->
-  ```cpp
-  storage.member_object = HugeObject{200};  // ❌ Does not compile.
-  ```
-  <!-- More code ✅ -->
-  The reason for this is that we can't bind a non-const reference to a temporary object (try it yourselves to see the actual error)
-  <!--
-  `CPP_SKIP_SNIPPET`
-  -->
-  ```cpp
-  int& answer = 42;  // ❌ Does not compile.
-  ```
-
-<!-- Talking head + photos of cake mom made + image of growing C++ ✅ -->
-So the question is - how can we have our cake and eat it at the same time? We will have to extend our language for this (which is exactly what happened with C++11).
-
-## Better solution - add a new "stealing reference" type to the language!
-<!-- Talking head ✅ -->
-If we agree to add new things to the language, the answer to our problem is actually genius in its simplicity - we just invent a new type that means "reference that can be stolen from"!
-
-<!-- Overlay text or code ✅ -->
-Given any type, `HugeObject` in our case, we have a reference type for it: `HugeObject&`. By analogy, let's name our new type `HugeObject&&` and define it as such that it can bind to objects that we are allowed to steal from.
-
-<!-- Talking head moving to code ✅ -->
-This enables us to just write a different assignment operator overload for this new `&&` reference type. So writing something like this should be possible:
-
-<!--
-`CPP_SETUP_START`
-#include <cstddef>
-
-std::byte *AllocateMemory(std::size_t length) {
-  return new std::byte[length];
-}
-void FreeMemory(std::byte *ptr) { delete[] ptr; }
-
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` huge_object_copy_move/object.hpp
--->
-```cpp
-#include <algorithm>
-
-struct HugeObject {
-  HugeObject() = default;
-
-  explicit HugeObject(std::size_t data_length)
-      : length{data_length}, ptr{AllocateMemory(length)} {}
-
-  HugeObject &operator=(const HugeObject &object) {
-    if (this == &object) { return *this; }  // Do not self-assign.
-    FreeMemory(ptr);  // In case we already owned some memory from before.
-    length = object.length;
-    ptr = AllocateMemory(length);
-    std::copy(object.ptr, object.ptr + length, ptr);
-    return *this;
-  }
-
-  HugeObject &operator=(HugeObject &&object) {
-    if (this == &object) { return *this; }  // Do not steal from ourselves.
-    FreeMemory(ptr);  // In case we already owned some memory from before.
-    length = object.length;
-    ptr = object.ptr;
-    object.ptr = nullptr;
-    return *this;
-  }
-
-  ~HugeObject() { FreeMemory(ptr); }
-
-  std::size_t length{};
-  std::byte *ptr{};
-};
-```
-<!-- Voiceover code ✅
-- Highlight new operator
-- Highlight both operators
-- Highlight const and copying
-- Highlight && and stealing
- -->
-Here, the two operators are nearly the same with the sole significant difference of one taking a constant reference and copying the data, while the other is taking "reference that can be stolen from" and then, well, stealing the data.
-
-## We also design how the "stealing references" are created from other objects
-<!-- Talking head ✅ -->
-We now have different implementations and the compiler should be able to pick the appropriate one by using the same rules as it uses for any other [function overload resolution](functions.md#function-overloading---writing-functions-with-the-same-names)! There is just one thing missing... How are the `&&` references created?
-
-<!-- Talking head from a different view ✅  -->
-Ok, so we do need to design how our new `&&` reference type is created from various objects but then we are done! We mostly care about these two use cases:
-<!-- Overlay text ✅ -->
-- Passing temporary objects like `HugeObject{}`
-- Passing objects that we as programmers know will not be in use anymore and so can be stolen from
-
-### "Stealing references" from temporary objects
-<!-- Let's start with the temporaries ✅ -->
-<!-- Code -->
-For temporary objects we can postulate that they can be bound to our `&&` references, and that the compiler always picks the `&&` reference overload of a function if a temporary is provided as a parameter:
-```cpp
-void Blah(int&) {}
-
-void Blah(int&&) {}
-
-int main() {
-  int&& answer = 42;  // Can be bound to a temporary
-  Blah(42);  // The compiler picks Blah(int&&)
-}
-```
-> :bulb: Feel free to print something from these functions to make sure they work as intended.
-
-### "Stealing references" from existing objects already stored as variables
-<!-- Talking head ✅ -->
-For the objects stored as normal variables but ones that we know will not be used anymore, we can add a function that converts any object into its `&&` reference.
-
-<!-- Overlay text or code ✅ -->
-We could call this function `CanBeStolenFrom(object)` but in C++11 this function has a name `std::move(object)`.
-
-<!-- Talking head
-Maybe overlay providing different types and getting && ones out ✅
--->
-This naming might be slightly confusing as it does not actually *do* anything - it just makes a `&&` reference of any type we provide into it. This then serves as an indication that the resources of this object can be stolen.
-
-<!-- Talking head ✅ -->
-We will skip the actual implementation here for now as it is not important to understand the concept but feel free to look it up on [cppreference.com](https://en.cppreference.com/w/cpp/utility/move).
-
-### Showcase of what we can do with our new "stealing references"
-<!-- Code ✅ -->
-These new `&&` reference types enable us to write the code like this:
-<!--
-`CPP_SETUP_START`
-#include "object.hpp"
-
-struct HugeObjectStorage {
-  HugeObject member_object;
-};
-
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` huge_object_copy_move/main.cpp
-`CPP_RUN_CMD` CWD:huge_object_copy_move c++ -std=c++17 -c main.cpp
--->
-```cpp
-int main() {
-  HugeObject object{100};
-  HugeObjectStorage storage{};
-  storage.member_object = object;
-  storage.member_object = HugeObject{200};
-  storage.member_object = std::move(object);
-  return 0;
-}
-```
-<!-- Highlight ✅ -->
-All of the behaviors from before are present here!
-- We **copy** `object` into `storage.member_object`
-- We **move** a temporary `HugeObject{200}` into `storage.member_object`
-- We **move** the existing `object` into `storage.member_object`
-
-## Yay! We've reinvented value semantics!
-<!-- Talking head + celebrations ✅  -->
-That is it! Conceptually, we've just reinvented, at least conceptually, the whole thing that is called value semantics in modern C++! At this point, it should be pretty clear what happens in the previous examples and why we need all of this.
-
-<!-- Text overlay ✅  -->
-There is a couple of things that logically follow from what we've just done:
-- Moving objects only makes sense if they own some resource through a pointer. All the other data is simply copied over, yielding no benefit.
-- We should never use the object that has been "moved from" as its resources are left in some undefined but valid state.
-
-# How is it actually designed and called in Modern C++?
-<!-- Talking head ✅ -->
-Not to spoil all the fun, but there is one final thing before we can close this chapter. Let's return from our fairyland back to reality and make sure we are aligned with how things actually *are* in Modern C++. Our definition of this new type of reference was a bit hand-wavy, C++ standard of course defines things much more strictly.
-
-## Classes of values
-<!-- Text overlay ??? -->
-Largely speaking there are a couple of different **kinds** of values:
-- `lvalues` - with the name derived from "left value", historically anything that could be found on the left of the `=` operator. Nowadays, anything that has a name and an address in memory
-- `prvalue` - with its name derived from "pure right value", maps most precisely to what we called a "temporary" before. These values don't have a name and a permanent address in memory and usually cannot appear on the left of the `=` operation
-- `xvalues` - so-called e**X**piring values: mostly `lvalues` after `std::move`, i.e., those whose resources can be stolen
-- `rvalues` - historically everything that is not an `lvalue`, nowadays, either an `xvalue` or an `prvalue`.
-
-<!-- Talking head + overlay of cppreference ✅ -->
-The value categories are quite nuanced in C++, but you should now be prepared to be able to read all about them on the [related page of the cppreference.com](https://en.cppreference.com/w/cpp/language/value_category) :wink:
-
-## "Stealing references" are rrefs and they are lvalues 🤯
-<!-- Talking head ✅ -->
-The "stealing" `&&` references that we (and the authors of C++11 standard) have invented are usually referred to as `rrefs` because they are `refs` that binds to things that are `rvalues` and so the name is a shortcut for "rvalue references".
-
-<!-- Talking head ✅ -->
-There is also one important quirk of `rrefs` to be aware of. If we store an `rref` into a variable, **it is an `lvalue` and not an `rvalue`**! So, by default, such a value, when passed to a function, will choose the "lvalue reference" overload! This means that we have to use `std::move` on a named `rref` in order to choose a correct `rref` overload. It might sound a bit confusing, so let me illustrate:
-
-<!-- Code overlay -->
-```cpp
-#include <iostream>
-
-void Blah(int&) {
-  std::cout << "&" << std::endl;
-}
-
-void Blah(int&&) {
-  std::cout << "&&" << std::endl;
-}
-
-int main() {
-  int&& answer = 42;  // answer is an lvalue that stores an rvalue reference!
-  Blah(42);                 // Prints "&&"
-  Blah(answer);             // Prints "&"
-  Blah(std::move(answer));  // Prints "&&"
-  return 0;
-}
-```
-The function `Blah` is overloaded for taking lvalue references and rvalue references. In our main function we create an rvalue reference from an integer literal `42` and then pass it in various ways to the `Blah` function. If we compile and run this code we will observe that:
-- Passing `42` will bind to the rvalue reference overload
-- Passing `answer` will bind to the lvalue reference overload because `answer` is an lvalue that holds an rvalue reference
-- Passing `std::move(answer)` will allow binding to the rvalue reference overload again
-
-# That's all folks!
-<!-- Talking head ✅ -->
-Now we're done with this topic for good! We really do know close to everything there is to know about value semantics!
-
-<!-- Maybe again overlay illustrations ✅ -->
-We've learned that sometimes we want to transfer ownership of objects by moving the data as opposed to copying or borrowing them and, even more, we've designed the whole solution to achieve this, which, coincidentally is exactly the way it is implemented in the C++11 and later.
-
-<!-- Talking head -->
-So hopefully by this time we are all on the same page that the whole thing is definitely **not black magic** and is nothing else than a piece of clever and elegant engineering.
-
-<!--
-Thanks for watching! If you think this way of explaining this concept is worth your time, then do share this video with your friends, subscribe and leave any comment under this video so that I know how these land with you!
-
-There is always more to watch on my channel but apart from that, thanks again and see you in the next one! Bye!
- -->
diff --git a/lectures/object_lifecycle.md b/lectures/object_lifecycle.md
deleted file mode 100644
index 81b03c4..0000000
--- a/lectures/object_lifecycle.md
+++ /dev/null
@@ -1,342 +0,0 @@
-Object lifecycle
----
-
-<p align="center">
-  <a href="https://youtu.be/TFoav6vhgdg"><img src="https://img.youtube.com/vi/TFoav6vhgdg/maxresdefault.jpg" alt="Video" align="right" width=50%></a>
-</p>
-
-- [Creating a new object](#creating-a-new-object)
-  - [**Constructor** - the first function called for any object](#constructor---the-first-function-called-for-any-object)
-    - [A default constructor](#a-default-constructor)
-    - [User-defined custom constructors for expressive object creation](#user-defined-custom-constructors-for-expressive-object-creation)
-  - [Member initializer lists](#member-initializer-lists)
-    - [Member initializer lists **initialize** member variables](#member-initializer-lists-initialize-member-variables)
-    - [Be aware of the order of initialization](#be-aware-of-the-order-of-initialization)
-    - [What if a member initializer list skips a value?](#what-if-a-member-initializer-list-skips-a-value)
-    - [Try to leave the body of the constructor empty](#try-to-leave-the-body-of-the-constructor-empty)
-  - [Again on default constructor auto-generation](#again-on-default-constructor-auto-generation)
-  - [Use `= default` to re-enable a trivial default constructor](#use--default-to-re-enable-a-trivial-default-constructor)
-  - [Use `explicit` with single-argument constructors](#use-explicit-with-single-argument-constructors)
-  - [We've covered most of the things that happen when an object is created](#weve-covered-most-of-the-things-that-happen-when-an-object-is-created)
-- [What happens when an object dies](#what-happens-when-an-object-dies)
-  - [**Destructor** - the last function called for any object](#destructor---the-last-function-called-for-any-object)
-  - [We rarely need to write our own destructor](#we-rarely-need-to-write-our-own-destructor)
-- [Full class lifecycle explained](#full-class-lifecycle-explained)
-
-<!-- Talking head -->
-By now we kinda know how to create objects of [custom types](classes_intro.md) and that they get created and destroyed just like any other variable. But there is more to it!
-
-So today we look under the hood and tap into the machinery that allows Modern C++ to be what it is - a flexible, efficient, and memory safe language all without the use of any sort of garbage collector! We're talking about the machinery of **constructors** and **destructors**!
-
-Oh, and we'll also see how it enables us to create objects in a more expressive way, for example we can create a `Cat` class directly with its number of lives and happiness:
-<!--
-`CPP_SETUP_START`
-struct Cat {
-  Cat(int, int) {};
-};
-
-int main() {
-  int number_of_lives{};
-  int happiness{};
-  $PLACEHOLDER
-}
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` cat_simple/main.cpp
-`CPP_RUN_CMD` CWD:cat_simple c++ -std=c++17 -c main.cpp
--->
-```cpp
-Cat cat{number_of_lives, happiness};
-```
-<!-- Intro -->
-
-# Creating a new object
-## **Constructor** - the first function called for any object
-<!-- Talking head -->
-Under the hood, when a new object of any custom type is created a special member function called a **constructor** is called. New terminology might be scary, but there is nothing complicated about it - it looks and behaves just as a function with just two differences:
-
-<!-- B-roll show words on screen -->
-- Its name **must** match the name of the `class` (or `struct`) exactly
-- It does not return anything - it's job is to initialize a newly created object
-
-<!-- Talking head -->
-Other than that we are free to do whatever we want: there can be as many constructors as we want to have and each can take as many parameters as we like! Oh, and a constructor might also have no parameters at all!
-
-### A default constructor
-<!-- B-roll code -->
-Such a constructor without parameters is called a **default** constructor.
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-int main() { Foo{}; }
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` foo_default_constructor/main.cpp
-`CPP_RUN_CMD` CWD:foo_default_constructor c++ -std=c++17 -c main.cpp
--->
-```cpp
-class Foo {
-public:
-  Foo() {}  // Default constructor
-};
-```
-And, we can use the `= default` after the constructor to tell the compiler that it can generate it as it wants which is even better because the compiler is usually smarter than us:
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-int main() { Foo{}; }
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` better_default_constructor/main.cpp
-`CPP_RUN_CMD` CWD:better_default_constructor c++ -std=c++17 -c main.cpp
--->
-```cpp
-class Foo {
-public:
-  Foo() = default;  // Even better default constructor
-};
-```
-
-<!-- Talking head -->
-> :bulb: Note that when such default constructor is called it will leave the data uninitialized unless these data are initialized in-place:
-> <!-- B-roll add private part code  -->
-> ```cpp
-> class Foo {
-> public:
->   Foo() = default;
->
-> private:
->   int uninitialized;
->   int initialized{};
-> };
-> ```
-> Here, the `uninitialized` variable will remain uninitialized while the `initialized` one will be initialized to a default value.
->
-> <!-- Talking head  -->
-> To avoid mistakes, we should _always_ initialize data in-place unless there is a good performance-related reason for not doing so.
-
-<!-- B-roll code, remove the constructor from the above  -->
-> :bulb: Also note that if we provide no constructors at all the compiler will **generate** a default one automagically! 🦄
-
-### User-defined custom constructors for expressive object creation
-<!-- B-roll code -->
-Anyway, let's get our hands dirty and write a couple of constructors that take, say, `happiness` and `number_of_lives` values for some `Cat` class:
-<!-- 🚨
-We can see that now we are able to create a cat object providing either just its happiness or the number of lives and happiness. -->
-```cpp
-constexpr int kDefaultNumberOfLives = 9;
-
-class Cat {
-public:
-  // Please ignore explicit for now, we talk about it below
-  explicit Cat(int happiness)
-      : happiness_{happiness} {}
-
-  Cat(int number_of_lives, int happiness)
-      : number_of_lives_{number_of_lives}, happiness_{happiness} {}
-
-private:
-  int number_of_lives_{kDefaultNumberOfLives};
-  int happiness_{};
-};
-
-int main() {
-  const Cat cat_1{42};
-  const Cat cat_2{9, 100};
-  return 0;
-}
-```
-<!-- Talking head -->
-There is quite a bit of new syntax here! So let's have a more precise look at all of it.
-
-## Member initializer lists
-<!-- B-roll highlight code -->
-The parts `: happiness_{happiness}` and `: number_of_lives_{number_of_lives}, happiness_{happiness}` are called the **member initializer lists**. Everything that happens in the member initialized list is **guaranteed to happen before** we enter the constructor function scope.
-
-### Member initializer lists **initialize** member variables
-<!-- Talking head -->
-These are actually very aptly named - they really are just lists of values that initialize member variables. The emphasis here is on "initialize", meaning that the member initializer list brings the object member variables into existence and they don't exist before this operation. There is no copying involved.
-
-### Be aware of the order of initialization
-<!-- Talking head + show variables on screen -->
-It is important to understand here that the order of operations in the member initializer list will follow the order in which the data appears in the class declaration, **not** the order in which the variables show up in the member initializer list itself!
-
-<!-- B-roll highlight code -->
-So `number_of_lives_` will **always** be initialized before `happiness_`. Try to always have the variables appear in the right order in the member initializer list, otherwise it gets quite confusing.
-
-<!-- Talking head 🚨 -->
-If we are afraid to make such a mistake, we can use the `-Wall` flag when compiling your code to enable compiler checking this and warning us if we mistype!
-
-### What if a member initializer list skips a value?
-<!-- B-roll highlight code -->
-In the Cat example, we see a couple of places where the variables are initialized, so it is important to understand which initialization takes precedence when. The rule is quite simple: the initializer list takes precedence over the in-place initialization. If an initializer list misses a value for a certain class member variable, only then this class member gets initialized from its in-place initialization. And if that in-place initialization is missing it will remain uninitialized.
-
-### Try to leave the body of the constructor empty
-<!-- Talking head -->
-🎓 We can of course do more things inside the scope of the constructor but it is a good practice to initialize as much as we can in the member initializer lists and try to leave the rest empty. The reason for this is that in the body of the constructor all the member variables will have already been constructed, meaning that if we now set values to them, we will perform a copy, not an initialization.
-
-## Again on default constructor auto-generation
-<!-- B-roll code -->
-After creating our custom constructors, if we try creating the `Cat` object without parameters we get an error! The compiler sees no constructor which would be called in such a case.
-<!--
-`CPP_SETUP_START`
-using Cat = int;
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` no_default_constructor/main.cpp
-`CPP_RUN_CMD` CWD:no_default_constructor c++ -std=c++17 -c main.cpp
--->
-```cpp
-int main() {
-  Cat cat{};  // ❌ Won't compile when custom constructors present
-  return 0;
-}
-```
-```css
-error: no matching constructor for initialization of 'Cat'
-  Cat cat{};
-      ^  ~~
-```
-<!-- B-roll comment out, recompile -->
-Seems pretty logical, we did not provide a default constructor! However, the strange thing here is if we just comment out our custom constructors for the `Cat` class it suddenly starts working again! What's going on? :thinking:
-
-<!-- Talking head -->
-The reason behind this is that the compiler can generate some constructors automatically under certain conditions. In this particular case, it only generates the default constructor [if no constructors are provided by the user](https://en.cppreference.com/w/cpp/language/default_constructor).
-
-<!-- B-roll highlight -->
-So, as it follows, now we *did* provide custom constructors, so the compiler thinks that we know what we're doing and does not generate a default constructor anymore.
-
-## Use `= default` to re-enable a trivial default constructor
-<!-- B-roll code -->
-However, we can easily add this constructor back by adding just one line to our class:
-<!--
-`CPP_SETUP_START`
-struct Cat {
-  $PLACEHOLDER
-};
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` default_constructor/main.cpp
-`CPP_RUN_CMD` CWD:default_constructor c++ -std=c++17 -c main.cpp
--->
-```cpp
-// Somewhere in the public part of our Cat class
-Cat() = default;  // Tell the compiler to use the default implementation
-```
-
-<!-- Talking head -->
-It is important to note here, that we are just scratching the surface here and the compiler actually generates quite a number of special constructors and other useful functions for a class automatically under certain conditions. This is a bigger topic, so we will talk about later in the course, so stay tuned for that!
-
-## Use `explicit` with single-argument constructors
-<!-- B-roll highlight code -->
-Coming back to our example, there is one last new thing that we still did not cover - the word `explicit`.
-
-<!-- B-roll show google style website -->
-Google style suggests that if we write a single-argument constructor, we should [mark it as `explicit`](https://google.github.io/styleguide/cppguide.html#Implicit_Conversions). But why?
-
-<!-- Talking head 🚨 -->
-Well, without it, there are some implicit conversions that a compiler might perform that are a bit confusing and should be avoided. Let me illustrate this by *removing the `explicit`* from our previous `Cat` class implementation and trying to compile the following code replacing our previous `main` function:
-<!-- B-roll code -->
-<!--
-`CPP_SETUP_START`
-using Cat = int;
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` explicit_cat/main.cpp
-`CPP_RUN_CMD` CWD:explicit_cat c++ -std=c++17 -c main.cpp
--->
-```cpp
-void Foo(const Cat &cat) {}
-
-int main() { Foo(42); }
-```
-<!-- B-roll try to compile 🚨 -->
-This code doesn't look like it should compile, does it? We are passing an integer into a function where a `Cat` object is expected! And yet it does! What happens here?
-
-<!-- Talking head 🚨 -->
-Well, our `Cat` class has a constructor that takes a single integer as a parameter. The compiler is allowed to perform implicit creation and decides that the best way to compile this code is to generate a temporary `Cat` object from the provided integer `42` and pass it into the function `Foo`!
-
-<!-- B-roll try to compile after adding explicit 🚨 -->
-Now, if we add `explicit` back, the code *won't* compile anymore.
-So, `explicit` basically forbids creating the object implicitly.
-
-## We've covered most of the things that happen when an object is created
-<!-- Talking head -->
-At this point it should be pretty clear how the life of every object starts, it always starts with one or another constructor, which takes care of initializing the object's variables, acquiring any resources needed etc. Honestly, there is not that much more to it.
-
-# What happens when an object dies
-## **Destructor** - the last function called for any object
-<!-- Talking head -->
-So I guess it is about time we talked about what happens when an object is destroyed. Just as how the life of an object starts with a constructor, it ends with another special function - a **destructor**. The last thing that happens before the object is completely destroyed - its destructor is called.
-
-<!-- B-roll text on screen -->
-There are again some rules for how destructors are named and how they behave:
-- There can only be a single destructor for a class
-- The name of destructor for class `Foo` must be `~Foo()`
-- The destructor takes no input parameters and returns no value
-
-## We rarely need to write our own destructor
-<!-- Talking head -->
-A destructor is a good place to release any resources that were acquired during object construction and, just as with the default constructor a default destructor is generated by the compiler automagically.
-
-<!-- Code 🚨 Add destructor -->
-That is usually how we want it. Compilers know how to allocate and destroy any normal variable that we did not allocate manually (more on that later), so in most cases there is no need for us to write our own destructor. This is the reason why you don't see one in our `Cat` class from before.
-```cpp
-class Cat {
-public:
-  explicit Cat(int happiness)
-      : happiness_{happiness} {}
-
-  ~Cat() {
-    // Nothing to do here, so not really needed...
-  }
-private:
-  int happiness_{};
-};
-
-int main() { const Cat cat{9}; }
-```
-
-<!-- Talking head -->
-Nowadays in Modern C++ we need to write our own destructor only rarely, mostly when implementing really low-level stuff. But it is still important to know that destructors exist and what they are able to do. There will be more to them once we start talking about value semantics or polymorphism, so stay tuned for those topics but we'll leave it at that here.
-
-# Full class lifecycle explained
-<!-- B-roll code 🚨 -->
-So, to summarize todays' video, it is important to remember that essentially every object is created by calling one and only one of its constructors, used for a while and eventually its destructor will be called as the last thing before the object is destroyed.
-<!--
-`CPP_SETUP_START`
-struct Cat{
-  void RunAround();
-  void BeAwesome();
-  void ThrowThingsFromAbove();
-  int a;
-};
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` object_life/main.cpp
-`CPP_RUN_CMD` CWD:object_life c++ -std=c++17 -c main.cpp
--->
-```cpp
-int main() {
-  Cat cat{100}; // Cat(int happiness) is called.
-  cat.RunAround();
-  cat.BeAwesome();
-  cat.ThrowThingsFromAbove();
-  return 0;
-} // Destructor cat.~Cat(); is called.
-```
-
-<!-- B-roll show words on screen 🚨 -->
-> Exercise: to make sure this is clear, try adding some `std::cout` statements to the constructors and the destructor of our `Cat` class and see that they get printed!
-
-<!-- Talking head -->
-The reason for such a design is simple - to ensure control over the resources that each object owns.
-
-<!-- B-roll show words on screen -->
-The paradigm that this design enables is usually referred to as **RAII** - **R**esource **A**cquisition **I**s **I**nitialization and it is a very important paradigm in Modern C++.
-
-<!-- Talking head -->
-This means that all resources that a class owns should be acquired upon object creation and released upon object destruction. Well, technically they also can be transferred to some other object through the mechanism of move semantics but we're going to talk about this in the next video.
-
-<!-- Talking head -->
-For now, with the understanding of an object lifecycle, we've made our first steps on the path to understanding proper value semantics which is **the** cornerstone of the Modern C++ design.
-
-<!-- Talking head
-Thanks for watching as always and see you in the next video, bye!
--->
diff --git a/lectures/random_numbers.md b/lectures/random_numbers.md
deleted file mode 100644
index ab3ce94..0000000
--- a/lectures/random_numbers.md
+++ /dev/null
@@ -1,109 +0,0 @@
----
-marp: true
-math: katex
-theme: custom-theme
-footer: ![width:80px](images/C++ForYourselfIcon.png)
----
-
-# Random number generation
-
-#### Today:
-- How to generate random numbers in modern C++
-- What's wrong with `rand()`
-
-### 📺 Watch the related [YouTube video](https://youtu.be/IUoqMTGGo6k)! 
-
----
-# Special symbols used in slides
-- 🎨 - Style recommendation
-- 🎓 - Software design recommendation
-- 😱 - **Not** a good practice! Avoid in real life!
-- ✅ - Good practice!
-- ❌ - Whatever is marked with this is wrong
-- 🚨 - Alert! Important information!
-- 💡 - Hint or a useful exercise
-- 🔼1️⃣7️⃣ - Holds for this version of C++(here, `17`) and **above**
-- 🔽1️⃣1️⃣ - Holds for versions **until** this one C++(here, `11`)
-
-Style (🎨) and software design (🎓) recommendations mostly come from [Google Style Sheet](https://google.github.io/styleguide/cppguide.html) and the [CppCoreGuidelines](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines)
-
----
-# What are random numbers?
-[![bg 60%](images/random_number.png)](https://xkcd.com/221/)
-
----
-# What are random numbers?
-- Random numbers should be **hard to predict**
-  (under the definition of *"hard"*)
-- Mostly, we generate **pseudo-random** numbers instead
-- There are multiple algorithms for this:
-  - **[Linear congruential generator](https://en.wikipedia.org/wiki/Linear_congruential_generator)** - Fast and small storage
-  - **[Lagged Fibonacci generator](https://en.wikipedia.org/wiki/Lagged_Fibonacci_generator)** - Very fast, uses more storage
-  - **[Mersenne Twister](https://en.wikipedia.org/wiki/Mersenne_Twister)** - Slower, uses more storage but generates very high quality pseudo random numbers
-- We will **not** go into details here!
-- If you want to learn more, you can:
-  - Read a book [Random Numbers and Computers](https://link.springer.com/book/10.1007/978-3-319-77697-2) 
-  - Read this [technical report](https://www.pcg-random.org/pdf/hmc-cs-2014-0905.pdf) for a slightly advanced intro
-
----
-# But how do I use it?
-- 🔼1️⃣1️⃣ Include `<random>`
-- ✅ There is a great [summary of pseudo random number generation on cppreference.com](https://en.cppreference.com/w/cpp/numeric/random)
-- Implements **all** the algorithms listed on previous slide
-- Here is a summary of how it works:
-  1. We need a **"random device"** that is our source of non-deterministic uniform (maybe pseudo-) random numbers
-  2. We pass this device into a **"random number engine"** from the previous slide
-  3. We pass this engine into a **"random number distribution"** which generates the resulting numbers we want
-
----
-# Let's see it in practice
-```cpp
-#include <iostream>
-#include <random>
-
-int main() {
-  std::random_device random_device;
-  std::mt19937 random_engine{random_device()};
-  std::uniform_real_distribution distribution{23.0, 42.0};
-  for (auto i = 0; i < 5; ++i) {
-    std::cout << distribution(random_engine) << std::endl;
-  }
-  return 0;
-}
-```
-This gives an output that looks smth like this:
-```
-33.9856
-30.8976
-40.8357
-37.9964
-27.8459
-```
-
----
-# What's wrong with `rand()`?
-- It is available from the `<cstdlib>` header
-- [`rand()`](https://en.cppreference.com/w/cpp/numeric/random/rand) is a C function (**not** C++) 
-- The only option before `C++11`
-- :scream: Let's see how it's typically used:
-  <!--
-  `CPP_SETUP_START`
-  #include <cstdlib>
-  constexpr static int seed{};
-  int main() {
-    $PLACEHOLDER
-    return 0;
-  }
-  `CPP_SETUP_END`
-  -->
-  ```cpp
-  // Somewhere in main
-  std::srand(seed);  // Initialize random seed
-  int random_variable = std::rand();
-  ```
-- :scream: It uses global state (seed is set globally)
-- The **quality** of the generated random sequence is not guaranteed
-- ✅ Always use methods from `<random>` instead!
-
----
-![bg](https://fakeimg.pl/1280x1024/226699/fff/?text=Good%20luck!&font=bebas)
\ No newline at end of file
diff --git a/lectures/raw_pointers.md b/lectures/raw_pointers.md
deleted file mode 100644
index 845a1df..0000000
--- a/lectures/raw_pointers.md
+++ /dev/null
@@ -1,381 +0,0 @@
-# Raw pointers
-
-<p align="center">
-  <a href="https://youtu.be/pptRG345jnU"><img src="https://img.youtube.com/vi/pptRG345jnU/maxresdefault.jpg" alt="Video" align="right" width=40%></a>
-</p>
-
-- [Raw pointers](#raw-pointers)
-- [The pointer type](#the-pointer-type)
-- [Pointers = variables of pointer types](#pointers--variables-of-pointer-types)
-- [How to get the data?](#how-to-get-the-data)
-- [Initialization and assignment](#initialization-and-assignment)
-- [Using const with pointers](#using-const-with-pointers)
-  - [Non-const pointer to const data](#non-const-pointer-to-const-data)
-  - [Constant pointer to non-const data](#constant-pointer-to-non-const-data)
-  - [Constant pointer to constant data](#constant-pointer-to-constant-data)
-- [That's about it](#thats-about-it)
-
-
-<!-- Talking head DONE -->
-Today we talk about pointers. Largely speaking there are two kinds of pointers in modern C++:
-- Smart pointers
-- Raw pointers
-
-The difference between them is ownership. Smart pointers own their data, and the raw ones don't. While we will talk about ownership more soon, for now it's enough to think about it as follows:
-<!-- Spell out words on screen -->
-> **whoever owns data - cleans up its memory**.
-
-<!-- Talking head DONE -->
-Today we talk about the non-owning kind of pointers - the raw pointers. We already talked about something very similar: [references](cpp_basic_types_and_variables.md#references-to-variables). But with raw pointers you get more flexibility, i.e., ever tried putting references into an [`std::vector`](more_useful_types.md#use-stdvector-when-number-of-items-is-unknown-before-wise)?
-<!-- Code -->
-<!--
-`CPP_SKIP_SNIPPET`
--->
-```cpp
-std::vector<int&> vector_of_refs{};  // ❌ Doesn't compile
-```
-<!-- Talking head DONE -->
-You can do that (and more) with raw pointers but you do pay with some syntax overhead as well as with a potential infamous **"segfault"**. Let's dig into the details!
-
-<!-- Intro -->
-
-# The pointer type
-<!-- Talking head DONE -->
-<!-- Show int and int* on top -->
-First of all, when we talk about pointers, we talk about **variables** of a special **pointer type**. We form such "pointer types" from other types by appending the `*` symbol on the right. So, just as `int` is a type, `int*` is a "pointer to `int`" type. Of course it doesn't have to be `int`, it can be any other type, including other pointer types, for example `Cat**` type is a "pointer to a pointer of a `Cat` class".
-
-# Pointers = variables of pointer types
-<!-- Talking head DONE -->
-Anyway, as I said before, **pointers** are just **variables** of **pointer types**. So what do these variables hold?
-
-<!-- Draw memory and a pointer, also write the address as integer as in hex DONE -->
-They hold nothing else than an address in memory of another variable. Intuitively, we can think about this address as if it were simply a large integer number (usually represented in hexadecimal system). That's why all pointer variables occupy the same amount of memory that is also usually equal to a long integer.
-
-<!-- Talking head DONE -->
-However, C++ pointers are *much* better than just a number that represents an address. A pointer always *points to a variable of a certain type*. Which means that for every pointer the compiler knows:
-- The address of the start of a variable it points to
-- Type of the variable it points to
-
-This allows the compiler to check that we point to the correct type making our life easier.
-
-<!-- Code -->
-Which brings us to how such pointers can be created and initialized in code:
-<!--
-`CPP_SETUP_START`
-int main() {
-  $PLACEHOLDER
-}
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` simple_ptr/main.cpp
-`CPP_RUN_CMD` CWD:simple_ptr c++ -std=c++17 -c main.cpp
--->
-```cpp
-int var{};         // Some variable that we will point to
-int* ptr1{&var};   // The & operator returns a pointer to a variable
-int* ptr2 = &var;  // Same as above
-```
-<!-- Talking head DONE -->
-The use of `&` might confuse you as we've seen it also when declaring references. In references, it is **part of the type**, e.g. `int&` stands for a type "reference to int". But at the same time we can also use the same symbol `&` as an **"address operator"** to get a pointer to a variable.
-
-<!-- Code -->
-Once we're at it, let's quickly illustrate my point from before that compiler is our friend. If we try to create a pointer to a variable of a wrong type we get an error:
-<!--
-`CPP_SKIP_SNIPPET`
--->
-```cpp
-double var{};
-int* var_ptr{&var};  // ❌ Won't compile!
-```
-
-# How to get the data?
-<!-- Talking head DONE -->
-Being able to create pointers is all great, but we would like to get to the underlying data too! We use the `*` operator for that. It is called a **"dereferencing operator"**.
-
-<!-- Overlay illustration -->
-The compiler then is able to look at where the pointer points to in memory and, knowing the size of the underlying type, interpret the appropriate number of bytes as the underlying type giving us direct access to the underlying variable.
-
-<!-- Code -->
-<!--
-`CPP_SETUP_START`
-#include <iostream>
-int main() {
-  $PLACEHOLDER
-}
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` modify_ptr/main.cpp
-`CPP_RUN_CMD` CWD:modify_ptr c++ -std=c++17 -c main.cpp
--->
-```cpp
-int var{};
-int* var_ptr{&var};
-var = 42;
-std::cout << var << " " << *var_ptr << std::endl;
-*var_ptr = 23;
-std::cout << var << " " << *var_ptr << std::endl;
-```
-<!-- Skip -->
-> :bulb: What does the above print?
-
-<!-- Talking head DONE -->
-Oh, and one more thing. When pointing to more complex types, e.g. `std::string` or any type that has methods that we can call we technically have to:
-- Dereference the pointer to get to the object
-- Call the method on our object
-Which ends up looking something like this:
-<!-- Code -->
-<!--
-`CPP_SETUP_START`
-#include <iostream>
-#include <string>
-int main() {
-  $PLACEHOLDER
-}
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` ugly_string/main.cpp
-`CPP_RUN_CMD` CWD:ugly_string c++ -std=c++17 -c main.cpp
--->
-```cpp
-std::string blah{"blah"};
-std::string* str_ptr{&blah};
-// 😱 Ugh, this is ugly!
-std::cout << "String size: " << (*str_ptr).size() << std::endl;
-```
-<!-- Talking head DONE -->
-There is a shortcut for this! We can use the `->` operator which does exactly the two steps we actually perform here:
-<!-- Code -->
-<!--
-`CPP_SETUP_START`
-#include <iostream>
-#include <string>
-int main() {
-  $PLACEHOLDER
-}
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` nicer_string/main.cpp
-`CPP_RUN_CMD` CWD:nicer_string c++ -std=c++17 -c main.cpp
--->
-```cpp
-std::string blah{"blah"};
-std::string* str_ptr{&blah};
-// ✅ Now this is nice!
-std::cout << "String size: " << str_ptr->size() << std::endl;
-```
-
-# Initialization and assignment
-<!-- Talking head DONE -->
-It's time we talk about the main difference between references and pointers. Pointers **are re-assignable**, while a reference is initialized directly from a given variable and cannot be reassigned later.
-
-<!-- Code -->
-For example:
-<!--
-`CPP_SETUP_START`
-#include <iostream>
-#include <string>
-int main() {
-  $PLACEHOLDER
-}
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` diff_ptr_ref/main.cpp
-`CPP_RUN_CMD` CWD:diff_ptr_ref c++ -std=c++17 -c main.cpp
--->
-```cpp
-int var_1{42};
-int var_2{23};
-
-int* var_ptr{&var_1};
-// Re-assigns pointer: var_ptr now points to var_2 and not var_1
-var_ptr = &var_2;
-
-int& var_ref{var_1};
-// Copies the data into var_1, does not re-assign var_ref.
-var_ref = var_2;
-```
-<!-- Talking head DONE -->
-This is the feature that allows us to put pointers into containers!
-<!-- Code -->
-<!--
-`CPP_SETUP_START`
-#include <iostream>
-#include <vector>
-int main() {
-  $PLACEHOLDER
-}
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` vector_ptr/main.cpp
-`CPP_RUN_CMD` CWD:vector_ptr c++ -std=c++17 -c main.cpp
--->
-```cpp
-int foo{42};
-int bar{23};
-// Not very useful for now, but this is the staple
-// behind the Object Oriented Programming (stay tuned 😉)
-std::vector<int*> my_numbers{&foo, &bar};
-```
-
-<!-- Talking head DONE -->
-This flexibility for pointers also means that we *can* have an uninitialized pointer or a pointer pointing to nothing (also known as the `nullptr`).
-<!-- Code -->
-For example:
-<!--
-`CPP_SKIP_SNIPPET`
--->
-```cpp
-int& unassigned_ref;        // ❌ won't compile!
-int* unassigned_ptr;        // 😱 compiles but don't do this!
-int* empty_ptr_1{};         // ✅ do this instead!
-int* empty_ptr_2{nullptr};  // ✅ or this, same as above
-```
-
-<!-- Talking head DONE -->
-The `nullptr` is a special value with which to initialize the pointers that don't point to any existing variable. By definition is means "points to nothing".
-
-<!-- Code -->
-Oh, by the way, wanna see smth cool? Pointers get implicitly converted to `bool`, so we can check if a pointer is set to `nullptr` very neatly:
-<!--
-`CPP_SETUP_START`
-int main() {
-  int* some_ptr{};
-  int* empty_ptr{};
-  ${PLACEHOLDER}
-}
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` if/main.cpp
-`CPP_RUN_CMD` CWD:if c++ -std=c++17 -c main.cpp
--->
-```cpp
-if (some_ptr) { /* do smth with some_ptr */ }
-if (!empty_ptr) { /* do smth when empty_ptr is nullptr */ }
-```
-
-<!-- Code -->
-Trying to dereference a `nullptr` will lead to a **"segmentation fault"** runtime error, or, shorter, a **"segfault"**.
-<!--
-`CPP_SKIP_SNIPPET`
--->
-```cpp
-int* nothing{nullptr};
-*nothing;  // ❌ Will compile but fail at runtime with a segfault.
-```
-
-<!-- Talking head DONE -->
-It's unpleasant, yes, but this is not the worst that can happen! Dereferencing a `nullptr` is a well-defined runtime error. To fix it is just a matter of finding which pointer points to `nullptr`.
-
-<!-- Draw pointer pointing to a random memory -->
-🚨 But if you don't initialize your pointer at all, it will point to a random address and if you dereference it, it will interpret whatever it finds under that random address as the required type. It might segfault but might also just return some garbage data. Welcome back to the undefined behavior land :scream:
-
-# Using const with pointers
-<!-- Talking head with overlay DONE -->
-Switching gears, just as with references, we want to be able to forbid modification of data when using pointers. This is a topic that routinely leaves the best of us with a twitching eye... The issue here is that `int*`, `int *const`, `const int*`, and `const int* const` all represent their own types and all mean different things! So... what's the difference? And how to make sense of it?
-
-<!-- Talking head point right, point left DONE -->
-There is a trick to this: read the types that involve pointers from right to left. Let's see some examples:
-
-## Non-const pointer to const data
-<!-- Overlay with highlight -->
-<!--
-`CPP_SETUP_START`
-int main() {
-  ${PLACEHOLDER}
-}
-`CPP_SETUP_END`
--->
-```cpp
-  const int * blah{};
-//  |    |  |  | blah is a...
-//  |    |  | pointer to an...
-//  |    | integer...
-//  | constant!
-```
-<!-- Talking head DONE -->
-Which means that we cannot change the underlying data, but can reassign `blah` to point to other data!
-
-<!-- Code -->
-<!--
-`CPP_SKIP_SNIPPET`
--->
-```cpp
-const int * blah{&some_var};
-blah = &some_other_var;  // ✅
-*blah = 42;              // ❌
-```
-<!-- Talking head DONE -->
-:bulb: This is the most common use of `const` with pointers.
-
-But there are other ways too! Let's quickly look at those.
-
-## Constant pointer to non-const data
-<!-- Overlay with highlight -->
-<!--
-`CPP_SETUP_START`
-int main() {
-  ${PLACEHOLDER}
-}
-`CPP_SETUP_END`
--->
-```cpp
-   int * const blah{};
-//  |  |   |   | blah is a...
-//  |  |   | constant...
-//  |  | pointer to an...
-//  | integer!
-```
-<!-- Talking head DONE -->
-Which means that we **can** change the underlying data, but cannot reassign `blah` to point to other data!
-<!-- Code -->
-<!--
-`CPP_SKIP_SNIPPET`
--->
-```cpp
-int * const blah{&some_var};
-*blah = 42;              // ✅
-blah = &some_other_var;  // ❌
-```
-
-## Constant pointer to constant data
-<!-- Talking head DONE -->
-Finally, there is a way to forbid any changes as follows:
-
-<!-- Overlay with highlight -->
-<!--
-`CPP_SETUP_START`
-int main() {
-  ${PLACEHOLDER}
-}
-`CPP_SETUP_END`
--->
-```cpp
-  const int * const blah{};
-//  |    |  |   |   | blah is a...
-//  |    |  |   | constant...
-//  |    |  | pointer...
-//  |    | to an integer...
-//  | constant!
-```
-<!-- Talking head DONE -->
-which means that we cannot change the underlying data, **and** we cannot reassign `blah` to point to other data!
-<!-- Skip -->
-<!--
-`CPP_SKIP_SNIPPET`
--->
-```cpp
-const int * const blah{&some_var};
-blah = &some_other_var;  // ❌
-*blah = 42;              // ❌
-```
-
-<!-- Talking head DONE -->
-> :bulb: To make sure you understood how it works, try the same exercise yourself for the following:
-> <!--
-> `CPP_SKIP_SNIPPET`
-> -->
-> ```cpp
-> int const * const blah{};
-> ```
-> What does it translate to?
-
-# That's about it
-<!-- Talking head DONE -->
-This is about everything we have to know now about the raw pointers. They give us some flexibility but we pay the cost of possible segfaults and sometimes even with a potential for an undefined behavior in our code. The rule of thumb is to use references whenever you possibly can and resort to raw pointers if you cannot use a reference instead.
-
-That being said, understanding what raw pointers are is very important and they also will become more useful once we start talking more about the Object Oriented Programming and Polymorphism in that context.
-
-<!-- Thanks for watching and see you in the next one! -->
diff --git a/lectures/static_in_classes.md b/lectures/static_in_classes.md
deleted file mode 100644
index e297ab6..0000000
--- a/lectures/static_in_classes.md
+++ /dev/null
@@ -1,508 +0,0 @@
-Keyword `static` inside classes
----
-
-<p align="center">
-  <a href="https://youtu.be/ggNCjDPShrA"><img src="https://img.youtube.com/vi/ggNCjDPShrA/maxresdefault.jpg" alt="Video" align="right" width=50% style="margin: 0.5rem"></a>
-</p>
-
-- [Keyword `static` inside classes](#keyword-static-inside-classes)
-- [Using `static` class methods](#using-static-class-methods)
-- [Using `static` class data](#using-static-class-data)
-  - [Out-of-class definitions for `static` data](#out-of-class-definitions-for-static-data)
-- [What is `static` in classes useful for?](#what-is-static-in-classes-useful-for)
-  - [Using `static` member functions](#using-static-member-functions)
-  - [Using `static` member data](#using-static-member-data)
-- [Conclusion](#conclusion)
-
-
-The keyword [`static`](https://en.cppreference.com/w/cpp/keyword/static) is a very important keyword in C++ and is used a lot. Honestly, because of a very general name, it is probably a bit _overused_. Largely speaking, it can be used outside and inside of classes and these two cases are very different. Today we focus on the *latter* - using `static` inside of classes. If you are interested in how and when (khm-khm... *not*) to use `static` _outside_ of classes, I'm linking that [lecture right here](static_outside_classes.md).
-
-Now, as opposed to that, `static` _within_ classes is actually quite useful and is used quite often. If you just want to understand the gist of what `static` is used for within classes, here is a very concise summary [taken verbatim from cppreference.com](https://en.cppreference.com/w/cpp/language/static): static members of a class are **not associated with the objects of the class**: they are independent variables with static storage duration or regular functions. So much so that we can nearly think of them as being normal variables and functions in the namespace that represents the class with a small additional feature that they respect class access modifiers.
-
-If this sounds a bit confusing - don't worry. I, as always, have examples for you that hopefully will clear things up a bit :wink:
-
-<!-- Intro -->
-
-As you might have already understood, `static` can be applied to class methods or to class data. Both of these cases are actually quite useful.
-
-We'll start with the class methods and talk about the data later as there are some minor complications with how such data can be declared and defined.
-
-## Using `static` class methods
-To mark a class method `static` we just have to add the keyword `static` at the beginning of its declaration. The definition of such a method (should it be separate from the declaration) remains intact, without the `static` keyword.
-
-So, for a class `Foo` we can write two `static` functions:
-- `InlineBar()` which is defined in-place and
-- `Bar()` which has an out-of-class definition (that could also be in a separate `*.cpp` file of course)
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` static_methods/foo.hpp
--->
-```cpp
-#include <iostream>
-
-class Foo {
- public:
-  static void InlineBar() { std::cout << "InlineBar()" << std::endl; }
-  static void Bar();
-};
-
-void Foo::Bar() { std::cout << "Bar()" << std::endl; }
-```
-
-To call these functions in a canonical way, we have to prefix their names with the name of the class they belong to along with the double-colon symbol. Meaning that our functions can be called as `Foo::InlineBar()` and `Foo::Bar()` respectively:
-<!--
-`CPP_SETUP_START`
-#include "foo.hpp"
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` static_methods/main_simple.cpp
-`CPP_RUN_CMD` CWD:static_methods c++ -std=c++17 main_simple.cpp
--->
-```cpp
-int main() {
-  Foo::InlineBar();
-  Foo::Bar();
-  return 0;
-}
-```
-
-Essentially, the simplest way to think about `static` class methods is to think about them as just normal general functions and treat their surrounding class as a sort of a *namespace* for these functions. This way of thinking is of course stretching the concept a bit but is a useful mental model in my opinion. To show that these are mostly equivalent to general functions, we can show that we can store a pointer to such a `static` member function interchangeably with a pointer to a general function:
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` static_and_other_methods/main.cpp
-`CPP_RUN_CMD` CWD:static_and_other_methods c++ -std=c++17 -c main.cpp
--->
-```cpp
-#include <iostream>
-
-class Foo {
- public:
-  static void InlineBar() { std::cout << "InlineBar()" << std::endl; }
-};
-
-void FreeStandingFunction() {
-  std::cout << "FreeStandingFunction()" << std::endl;
-}
-
-int main() {
-  // Store the function address in a variable
-  auto* function_ptr = &Foo::InlineBar;
-  (*function_ptr)();
-  // Note that we do not change the type!
-  function_ptr = &FreeStandingFunction;
-  (*function_ptr)();
-  return 0;
-}
-```
-Here, we use the `&` to take the address of each of our functions and store them as a function pointer. It does not _really_ matter here what exactly that type is as long as it is the same in both cases. If we call these functions through our `function_ptr` variable by dereferencing the pointer (`*function_ptr`) and calling the underlying function with the round brackets, we should be able to call both of our functions resulting in the output that we expect.
-```
-InlineBar()
-FreeStandingFunction()
-```
-
-:bulb: Don't worry if this seems a bit complex, there is no need to fully understand everything here just now. At this point, I just wanted to illustrate that a pointer to a general function and one to a `static` class method can be stored in the same variable, which means that they are more or less equivalent.
-
-<!-- Please comment below what you think about it? Did it help? Did it confuse you more? Do let me know! -->
-
-There is one slight difference that makes the `static` class methods differ from the general functions - the `static` class methods obey class access modifiers! If we have a `static` class method in the `private` region of our class, we can only call it from within the class, i.e., from other `static` and non-`static` member functions.
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` weird_calling/foo.hpp
--->
-```cpp
-class Foo {
- public:
-  static void PublicStaticFunction() { PrivateStaticFunction(); }
-
-  void NormalFunction() { Foo::PrivateStaticFunction(); }
-
- private:
-  static void PrivateStaticFunction() {}
-};
-```
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` weird_calling/main.cpp
-`CPP_RUN_CMD` CWD:weird_calling c++ -std=c++17 main.cpp
--->
-```cpp
-#include "foo.hpp"
-
-int main() {
-  Foo::PublicStaticFunction();
-  Foo foo;
-  foo.NormalFunction();
-  // ❌ Cannot call private function!
-  // Foo::PrivateStaticFunction();
-}
-```
-Note how we don't need to (but still can) explicitly specify which class the `PrivateStaticFunction` is from if we call it from within the class it is declared in.
-
-However, if we try to call our `PrivateStaticFunction` from outside our class, we will get a compilation error that tells us why in a pretty much straightforward fashion:
-```css
-<source>: In function 'int main()':
-<source>:20:29: error: 'static void Foo::PrivateStaticFunction()' is private within this context
-   20 |   Foo::PrivateStaticFunction();
-      |   ~~~~~~~~~~~~~~~~~~~~~~~~~~^~
-<source>:13:16: note: declared private here
-   13 |    static void PrivateStaticFunction() {}
-      |                ^~~~~~~~~~~~~~~~~~~~~
-```
-
-That's _nearly_ it! There is one more thing, which is slightly confusing, nobody uses it (or at least nobody should) but I still need to tell you about it in case you see it in somebody else's code. Remember how we used the double-colon symbol `::` when calling the `static` member functions? Well, we can also use the dot `.` **on an object of the class** to do the same.
-```cpp
-struct Foo {
-  static void Bar() {}
-};
-
-int main() {
-  Foo foo;
-  // The next two lines do exactly the same thing
-  Foo::Bar();
-  foo.Bar();  // 😱 Don't use this syntax.
-}
-```
-
-Think about it, as we've just learnt, the `static` function has nothing to do with the class *object* data and yet it looks like it is called on an object with this syntax. Confusing, eh? I don't know of any situation where this would be useful, but if you do - please tell me!
-<!-- In the comments below this video! -->
-
-## Using `static` class data
-Now it's time we talked about `static` class data. The underlying idea is the same: the data is associated to the class type rather than to any particular object of such a class. Technically, on an idea level, this is everything anybody needs to know.
-
-What makes this a slightly complicated topic is that the way such data is declared and defined has been changing in the recent years, which adds quite a bit of confusion to the process.
-
-The good news is that we're now **in a good place**! There is an easy-to-use fool-proof best practice for declaring your class-`static` data:
-
-> 🚨 **Always define your class `static` data in-place by using `static inline` or `static constexpr` (`constexpr` in this case implies `inline`)**.
-
-So, all of these definitions are good-to-go:
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-int main() {
-  Foo::any_static_data;
-  Foo::kWord;
-  Foo::kNumber;
-}
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` static_inline_examples/main.cpp
-`CPP_RUN_CMD` CWD:static_inline_examples c++ -std=c++17 main.cpp
--->
-```cpp
-#include <string>
-
-struct AnyType {};
-
-class Foo {
- public:
-  static inline AnyType any_static_data{};
-  static inline const std::string kWord{"hello"};
-  static constexpr int kNumber{};  // implicitly inline
-};
-```
-We can use `static inline` for any complex types regardless of the variable being `const` or not and we can use `static constexpr` on any literal type such as an `int` in this case.
-
-**If you stick to this rule, your life is going to be much simpler.**
-<!-- You can thank me by subscribing to this channel and telling your friends when you're ready :wink: Really, my data shows me that only 20% of people watching these videos are subscribed. It would mean the world to me if you helped me out with this issue :wink: -->
-
-This rule is a lifesaver, but the ones of you, who already watched [the lecture about using `static` outside of classes](static_outside_classes.md) might be very confused now. Just one video ago, I was talking about using `inline` _instead of_ `static` but here, I suggest to use _both_ together? What is going on here? If you haven't watched that video yet - do so to be just as confused :wink:. As an answer, I need to explicitly state here that:
-> 🚨 **Words `static`, `inline` and `constexpr` mostly mean very different things inside and outside of classes, so do not confuse these cases. The best suggestion I can give is to not apply anything you know about one case to another. Think that these could have been different keywords altogether!**
-
-And while this train of thought is a bit extreme, I'd say it is quite helpful.
-
-To complicate things further, we only got the opportunity to use `inline` for `static` class data from C++17 on. Before that things were much more messy. And guess what? There is still a lot of code that is left from those times! So we'll have to dive head-first into the mess of (drumroll 🥁) `static` class data out-of-class definition requirements!
-
-### Out-of-class definitions for `static` data
-Remember, how usually, data declaration is also its definition? Well, not so for `static` class data. The declaration of such data is **not** a definition by default. So we can **declare** a `static` variable in the class and **define** it outside of class, which is called an **out-of-class** definition:
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-int main() {
-  Foo::number;
-}
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` foo_number/main.cpp
-`CPP_RUN_CMD` CWD:foo_number c++ -std=c++17 main.cpp
--->
-```cpp
-struct Foo {
-  // 😱 Use static inline instead!
-  // Declaration, not a definition!
-  static int number;
-};
-
-// Definition, does not use static
-int Foo::number = 42;
-```
-Note how we only use `static` in the declaration but not in definition.
-
-> :bulb: Until C++17 introduced `inline` for use with data, we **had** to have an out-of-class definition for **every** `static` class variable or constant. With its introduction we can define them directly during declaration as we just discussed before. In the remainder of this lecture we will talk about how things were **before** `inline` could be used in such a way, i.e., before C++17.
-
-Here is where it gets more confusing. If we declare a `const static` class data, we _could_ also provide its definition at the same time. And the confusing part is that we **still need an out-of-class definition in such a case**. Here is how it would look for a simple example of storing a number as a class `static` data member and printing a minimum of this number and, say 100:
-```cpp
-#include <algorithm>
-#include <iostream>
-
-struct Foo {
-  static const int number = 42;
-};
-
-// This is the out-of-class definition!
-const int Foo::number;
-
-int main() { std::cout << std::min(Foo::number, 100) << std::endl; }
-
-```
-
-If we fail to provide the out-of-class definition we will get a **linker** error!
-```css
-<source>:11: undefined reference to `Foo::number'
-collect2: error: ld returned 1 exit status
-```
-
-Very annoying and a lot of people (including myself more times than I'd like to admit) have forgotten this in their code and took some time to figure out why the linker error pops up. The situation is made worse by only happening _sometimes_, as it only occurs if `Foo::number` is, so-called, ODR-used. Now, this term ODR-used is quite convoluted, so we will skip the details here but you might have recognized the "ODR" part and that should indicate that it has something to do with [ODR, or One Definition Rule](https://en.cppreference.com/w/cpp/language/definition). I went into some details about it [in the previous lecture](static_outside_classes.md#dont-define-functions-and-data-as-static-in-header-files-use-inline-instead). Anyway, in many cases, for example with `std::cout`, we can use our `Foo::number` and the linker will *not* complain. Until we call our variable in such a way that it does. Long story short, always use `inline` in modern C++ and you will never have such issues.
-
-## What is `static` in classes useful for?
-Ok, I bored you enough with the details like these. Let's actually go back to how `static` can be used in classes - what does it allow us to do? I wouldn't say there is a clearly defined rule here. But let's have a look at a couple of use-cases that come to mind.
-
-### Using `static` member functions
-The `static` class member functions are mostly used for manipulating `static` class data, for creating objects in a special way, in logging or testing libraries as well as for meta-programming, which we will probably touch upon later in the course.
-
-Just to give a concrete example, we can look at our `Image` class from the ["Image Pixelator"](../homeworks/homework_5/homework.md#pixelatorimage-class) project that you've hopefully done before. If you haven't done that project, I do urge you to give it a go :wink:. Anyway, there we created an image empty, and set its pixels afterwards:
-<!--
-`CPP_SETUP_START`
-namespace ftxui {
-struct Color {
-  static Color RGB(int, int, int) { return Color{}; }
-};
-}
-
-struct Image {
-  int rows;
-  int cols;
-  ftxui::Color at(int r, int c) { return ftxui::Color{}; }
-};
-
-int main() {
-  $PLACEHOLDER
-}
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` image_1/main.cpp
-`CPP_RUN_CMD` CWD:image_1 c++ -std=c++17 main.cpp
--->
-```cpp
-const auto rows{42};
-const auto cols{23};
-Image image{rows, cols};
-image.at(4, 2) = ftxui::Color::RGB(255, 0, 0);
-```
-
-What if we wanted to set it to, say, a red color upon creation? Well, we _could_ have a specific constructor that would set the color to the whole matrix, but there is a couple of issues with such an approach.
-1. The constructor does not introduce a new name, so our intent of _how_ we want to create an object remains to be inferred from the parameters:
-   <!--
-   `CPP_SKIP_SNIPPET`
-   -->
-   ```cpp
-   Image image{rows, cols, color};
-   ```
-   Such an interface might or might not make sense to you, but in more complex situations it quickly gets out of hands
-2. Furthermore, if we want to do something different while still providing the same parameters we simply cannot. This severely limits our capabilities
-3. Finally, sometimes we would like to give such functions that create objects the ability to fail. We could use exceptions for this (stay tuned), but in certain code bases those are forbidden
-
-These reasons nudge us to follow a different path. We could use a `static` function to create our object instead! A naive implementation of such a function could be a `static` member function `FilledWithColor` that would take the image size and the color we want to set and would create an image inside of it, filling every pixel of it with color afterwards.
-<!--
-`CPP_SETUP_START`
-namespace ftxui {
-struct Color {
-  static Color RGB(int, int, int) { return Color{}; }
-};
-}
-
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` image_fill/image.hpp
--->
-```cpp
-#include <algorithm>
-#include <vector>
-
-// This is not a full useful implementation.
-// It just illustrates the things I want to talk about.
-class Image {
- public:
-  Image(int rows, int cols) : pixels_(rows * cols, ftxui::Color{}) {}
-
-  static Image FilledWithColor(int rows, int cols, const ftxui::Color& color) {
-    Image image{rows, cols};
-    std::fill(image.pixels_.begin(), image.pixels_.end(), color);
-    return image;
-  }
-
-  // Other important stuff lives here
-
- private:
-  std::vector<ftxui::Color> pixels_{};
-};
-```
-
-Note also how we can use the `private` data of our object directly because we are using it from within our class `Image`.
-
-> :bulb: Fun fact, there is a version of this function in some of the most used linear algebra and computer vision libraries I am aware of: [Eigen](https://gitlab.com/libeigen/eigen/-/blob/master/Eigen/src/Core/DenseBase.h#L326) has a function `Constant`, [OpenCV](https://docs.opencv.org/2.4/modules/core/doc/basic_structures.html#mat-ones) has a function `ones` etc. Using these functions usually provides us with convenience and allows to write more readable code that shows intent better. When we read how these functions are called we know what happens without the need to see the implementation details:
-<!--
-`CPP_SETUP_START`
-#include "image.hpp"
-
-int main() {
-  $PLACEHOLDER
-}
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` image_fill/main.cpp
-`CPP_RUN_CMD` CWD:image_fill c++ -std=c++17 main.cpp
--->
-```cpp
-// Somewhere in the code
-auto red_color = ftxui::Color::RGB(255, 0, 0);
-auto red_image = Image::FilledWithColor(42, 23, red_color);
-```
-There is a number of situations when such `static` member functions are useful. Keep your eyes peeled for such situations in the code you read. Oh, and by the way, did you notice something? The [`ftxui::Color::RGB(255, 0, 0)`](https://arthursonzogni.github.io/FTXUI/classftxui_1_1Color.html#aacec69e0aa1063fbec2cc305e7b076dd) from an awesome FTXUI library is nothing else than a call to a `static` member function of the `ftxui::Color` type!
-
-### Using `static` member data
-Now let's talk about `static` class data. We will stick with the `Image` class for our examples here too.
-
-First, let's look at how simple constant `static` class data can be used.
-Let's say when we create an image without additional parameters provided we would want it to be set to a certain color, the "default color". While there are many ways about it, we could set a `static const` member of the class `Image` along the lines of `kDefaultColor` and use it when filling our image:
-<!--
-`CPP_SETUP_START`
-namespace ftxui {
-struct Color {
-  static Color RGB(int, int, int) { return Color{}; }
-};
-}
-
-$PLACEHOLDER
-
-int main() {
-  Image image{42, 42};
-}
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` image_default_color/main.cpp
-`CPP_RUN_CMD` CWD:image_default_color c++ -std=c++17 main.cpp
--->
-```cpp
-#include <vector>
-
-class Image {
- public:
-  static inline const ftxui::Color kDefaultColor{ftxui::Color::RGB(10, 10, 10)};
-  // Treat this as an idea, not the full implementation
-  Image(int rows, int cols) : pixels_(rows * cols, kDefaultColor) {}
-  // other important stuff lives here
-
- private:
-  std::vector<ftxui::Color> pixels_{};
-};
-```
-
-Pretty straightforward, isn't it? This is not that much different from having such a constant at the namespace scope, but as it is only used within the `Image` class it kinda makes sense to have it stored there.
-
-Now, to `static` class non-const data. This is one of those rare cases when it's ok to use non-const data outside of a tight local scope. We can have `static` non-const class data that we use to compute anything that must have visibility or that must be used by all instances of this class. This can be a pool of memory or of some stuff, modified and reused by the objects of our class or some form of bookkeeping that involves all objects of the class.
-
-Just as an illustration, let's see how such data can be used within our `Image` class as an example. Let's say, we wanted to know how many `Image` instances are present at any time in our program. We would then extend our class with a `static` counter:
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-
-int main() {
-  Image::instance_counter;
-}
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` instance_counter_simple/main.cpp
-`CPP_RUN_CMD` CWD:instance_counter_simple c++ -std=c++17 main.cpp
--->
-```cpp
-class Image {
- public:
-  static inline int instance_counter{};
-  // Rest of the methods and data
-};
-```
-
-Having this `static` data is cool and all but it does not count the number of objects we have. The way to achieve what we want is, of course, to tap into the way our images get constructed, destructed, copied and moved. In a simplified way, we would increment our `instance_counter` in any constructor apart from the move one and decrement in the destructor:
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` instance_counter/image.hpp
--->
-```cpp
-class Image {
- public:
-  static inline int instance_counter{};
-
-  Image() { instance_counter++; }
-  Image(const Image&) { instance_counter++; }
-  Image(Image&&) = default;
-  Image& operator=(const Image&) = default;
-  Image& operator=(Image&&) = default;
-  ~Image() { instance_counter--; }
-};
-```
-Note, how we have to implement all of the special functions following the rule of "all or nothing" - we had to touch the copy constructor and the destructor, which means that we have to implement the rest of the copy and move constructors and operators. If you are confused about why, we had [a lecture about this before](all_or_nothing.md).
-<!-- Which you can watch by clicking over here -->
-
-Now, we can create an image, copy it within some scope, printing the number of instances of `Image` class along the way in various locations:
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` instance_counter/main.cpp
-`CPP_RUN_CMD` CWD:instance_counter c++ -std=c++17 main.cpp
--->
-```cpp
-#include "image.hpp"
-
-#include <iostream>
-
-int main() {
-  std::cout << "Current count: " << Image::instance_counter << std::endl;
-  Image image;
-  std::cout << "Current count: " << Image::instance_counter << std::endl;
-  {
-    Image image_copy{image};
-    std::cout << "Current count: " << Image::instance_counter << std::endl;
-  }
-  std::cout << "Current count: " << Image::instance_counter << std::endl;
-  return 0;
-}
-```
-Note how we also use the double-colon symbol just like we did with functions to refer to our class `static` data.
-
-With any luck we should get the following output:
-```
-Current count: 0
-Current count: 1
-Current count: 2
-Current count: 1
-```
-
-I would say that this pattern is not used very often but when it is, it is doing important work. We will talk about smart pointers a bit later and the `std::shared_ptr` that allows sharing the ownership over some data is implemented following conceptually the exact same ideas. You will also meet these ideas beyond standard C++ library. If you venture into robotics or computer vision it is only a matter of time till you find yourself using OpenCV. One of the main classes from OpenCV is their matrix class `cv::Mat` and, you guessed it, it also uses this pattern, being a bit similar to the `std::shared_ptr` I just mentioned in how it manages the data stored in it.
-
-Anyway, hope this example gives you an idea of how such `static` class data can be used. Please do not hesitate to experiment yourself, as you can see, you can find out a lot already using very simple examples.
-
-## Conclusion
-Overall, as opposed to using `static` outside of classes, using `static` _inside_ of classes allows to achieve certain things that are impossible to achieve in any other way. So use it when needed without hesitation. If you need a single guideline to remember in order to understand in which situation `static` might be useful for you, remember that it associates data and methods to the class itself, not to any of its instances. So, use `static` class data and functions when they need to work with **all** objects of your class rather than any single one. That being said, the line between `static` class data and methods and the free-standing data and functions is quite thin with the differences that mostly come down to encapsulation in most cases. Meaning that if your function or data is always going to be related to a single class - put it within that class.
-
-<!-- Anyway, that's about everything I wanted to say about using `static` in classes. These videos take a lot of my time and if you would like to support this work, please subscribe and comment below this video, I'd love to hear from you!
-
-Now, if you want to watch when **not** to use static outside of classes watch this video, and if you would like to refresh your knowledge on the rule of all or nothing, then click over here instead.
-
-Thanks again for watching! See you in the next one, bye!
--->
diff --git a/lectures/static_outside_classes.md b/lectures/static_outside_classes.md
deleted file mode 100644
index 6786425..0000000
--- a/lectures/static_outside_classes.md
+++ /dev/null
@@ -1,460 +0,0 @@
-Keyword `static` outside of classes
----
-
-<p align="center">
-  <a href="https://youtu.be/7cpPQunjv4s"><img src="https://img.youtube.com/vi/7cpPQunjv4s/maxresdefault.jpg" alt="Video" align="right" width=50% style="margin: 0.5rem"></a>
-</p>
-
-
-- [Keyword `static` outside of classes](#keyword-static-outside-of-classes)
-- [Storage duration](#storage-duration)
-  - [Automatic storage duration an local namespace scope](#automatic-storage-duration-an-local-namespace-scope)
-  - [Static storage duration at namespace scope](#static-storage-duration-at-namespace-scope)
-  - [Static storage duration at function scope](#static-storage-duration-at-function-scope)
-  - [Very rare use of `static` to create mutable variables with static storage duration from a function](#very-rare-use-of-static-to-create-mutable-variables-with-static-storage-duration-from-a-function)
-  - [Summary of controlling storage duration with `static`](#summary-of-controlling-storage-duration-with-static)
-- [Linkage](#linkage)
-  - [What is linkage](#what-is-linkage)
-  - [Levels of linkage](#levels-of-linkage)
-  - [How to understand what linkage a name has](#how-to-understand-what-linkage-a-name-has)
-  - [Back to `static`](#back-to-static)
-    - [Don't use `static` to declare functions in header files](#dont-use-static-to-declare-functions-in-header-files)
-    - [Don't define functions and data `static` in a source file, use unnamed namespace instead](#dont-define-functions-and-data-static-in-a-source-file-use-unnamed-namespace-instead)
-    - [Don't define functions and data as `static` in header files, use `inline` instead](#dont-define-functions-and-data-as-static-in-header-files-use-inline-instead)
-- [Conclusion and a rule of thumb](#conclusion-and-a-rule-of-thumb)
-- [Final words](#final-words)
-
-
-The keyword [`static`](https://en.cppreference.com/w/cpp/keyword/static) is a very important keyword in C++ and is used a lot. Honestly, because of a very general name, it is probably a bit _overused_. Largely speaking, it can be used outside of classes and inside classes and these two cases are slightly different. Today we focus on the former - using `static` outside of classes. If you are interested in how and when to use `static` _inside_ of classes, I'm linking that [lecture here](static_in_classes.md).
-
-Anyway, as for using `static` _outside_ of classes, I have good news for you. If you follow my advices about best practices from before then the rule-of-thumb for using `static` outside of classes in modern C++ (that is at least C++17) is very simple - don't! **Don't use `static` at all!**
-
-Technically, that's all you need to know. But if you want to learn _why_ you shouldn't use `static` outside of classes then keep watching this video and see how deep this rabbit hole goes :wink:
-
-<!-- Intro -->
-
-In order to explain why we mostly don't want to use `static` for anything outside of classes we will need to talk about why we _might_ want to use `static` in the first place. The keyword `static` really controls just two things:
-- The storage duration
-- The linkage
-
-These terms feel a bit technical and I can already feel the confused faces on the other side of the screen from me :wink: So... what do these words mean?
-
-## Storage duration
-We'll start with "storage duration". Every object declared in C++ has a certain lifetime, or, in other words, a _storage duration_. There is a number of storage durations that any variable can have. At this point, we care about these two:
-- Automatic storage duration
-- Static storage duration
-
-To explain the difference between the two we start with a simple `main` function that calls another function `Foo` that has a single local variable in it:
-
-<img src="images/program_lifetime.png" align="right" width=250 style="margin: 0.5rem">
-
-```cpp
-void Foo() {
-  int local_value{};
-  // Use local_value
-}
-
-int main() {
-  Foo();
-  return 0;
-}
-```
-We can then draw the execution time of the program, `main` and `Foo` functions as lines that indicate that most of the time that the program runs is spends in `main`, while most of the time in `main` is spent executing the `Foo` function.
-
-### Automatic storage duration an local namespace scope
-
-If we focus now on the lifetime of the `local_value` variable, shown as a blue box in the image, it lives as long as is needed for the execution of the `Foo` function. It's memory is allocated at the start of the function and is freed at the end of the scope.
-
-We say that a variable `local_value` and any other variable that lives in some local scope, has **automatic storage duration**.
-
-### Static storage duration at namespace scope
-Let's further extend our example by adding some value `kValue`, that is defined at **namespace scope**, and use it to initialize our `local_value`. We will introduce it in an unnamed namespace following the best practices, but it could live in any namespace including the global one.
-
-
-<img src="images/static_storage.png" align="right" width=250 style="margin: 0.5rem">
-
-
-```cpp
-namespace {
-constexpr int kValue{42};
-}  // namespace
-
-void Foo() {
-  int local_value{kValue};
-  // Use local_value
-}
-
-int main() {
-  Foo();
-  return 0;
-}
-```
-The `kValue` here has what is called the **static storage duration** and lives for the whole duration of the program. Its data gets allocated at the start of the program and freed at the end of the program.
-
-:bulb: While we _can_ use `static` for an object definition at namespace scope to indicate that it has the static storage duration **we don't have to**, as any such object has **static storage duration** by default. So all of these definitions are equivalent in terms of storage duration:
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-int main(){}
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` consts/main.cpp
-`CPP_RUN_CMD` CWD:consts c++ -std=c++17 -c main.cpp
--->
-```cpp
-constexpr auto answer_1 = 42;
-const auto answer_2 = 42;
-auto answer_3 = 42;  // 😱 please don't create non-const globals...
-
-// 😱 please don't use static like this ...
-static constexpr auto answer_4 = 42;
-static const auto answer_5 = 42;
-static auto answer_6 = 42;  // 😱 please don't create non-const globals...
-```
-
-### Static storage duration at function scope
-Finally, use of `static` can extend the storage duration of a local variable within some function scope to have the static storage duration.
-
-If we add `static` in front of our `local_value` definition, it will have **static storage duration** again even though it is defined in a local scope. Now `local_value` will get allocated when the function `Foo` is called for the first time and will get de-allocated at the end of the program.
-
-<img src="images/static_storage_function.png" align="right" width=250 style="margin: 0.5rem">
-
-```cpp
-namespace {
-constexpr int kValue{42};
-}  // namespace
-
-void Foo() {
-  static int local_value{kValue};
-  // Use local_value
-}
-
-int main() {
-  Foo();
-  return 0;
-}
-```
-
-Such a `static` variable will be initialized when first encountered during the program flow and destroyed when the program exits.
-
-One interesting peculiarity of using `static` to extend the storage duration of a local variable is that if the flow of our program encounters the line that defines the `static` variable multiple times, this line will **only be executed once**. The reason being is that the variable already exists when the program flow reaches the variable definition for the second time, so the definition is skipped and the existing `static` variable is simply used further.
-
-<img src="images/static_foo_twice.png" align="right" width=250 style="margin: 0.5rem">
-
-```cpp
-namespace {
-constexpr int kValue{42};
-}  // namespace
-
-void Foo() {
-  static int local_value{kValue};
-  // Use local_value
-}
-
-int main() {
-  Foo();
-  Foo();
-  return 0;
-}
-```
-
-You can easily see (*C++) this for yourself if you replace the creation of a `static` `int` object by the creation of a `static` object of your custom type that prints something on construction and destruction and calling the function `Foo` a couple of times from `main`, like we just discussed. Your object will only print once from its constructor and destructor. Really, give this a try, it should take you no more than a couple of minutes by now :wink:
-
-### Very rare use of `static` to create mutable variables with static storage duration from a function
-Now this is where I lied to you a bit about _never_ needing to use `static`. There _are_ situations when you might want to create a static object within a function. In our `Foo` function we could have returned a non-const reference and essentially model a global mutable variable that will live for the rest of the program lifetime.
-```cpp
-int& Foo() {
-  static int local_value{};
-  return local_value;
-}
-
-int main() {
-  // Reference to our static variable.
-  auto& ref_to_static = Foo();
-  return 0;
-}
-```
-
-This is also very similar to the **singleton** design pattern and we will talk about what it is and why you probably don't want to use it later in the course. Anyway, if you remember what we talked about before, you will know that using non-`const` global variables tends to wreak havoc and we probably don't want to do this.
-
-> For completeness, one use for such an improvised singleton is to deal with the **"static initialization order fiasco"**. It should not hit you as long as you only create variables that rely *exclusively* on values within the same translation unit and not across translation unit boundaries.
-> <!--
-> `CPP_SKIP_SNIPPET`
-> -->
-> ```cpp
-> constexpr int kAnswer = 42;  // ✅ this is ok.
-> constexpr int kValue = kValueFromOtherCppFile;  // ❌ not ok!
-> ```
->
-> I won't go into details here, but tell me in the comments if you are interested to learn more about it!
-
-### Summary of controlling storage duration with `static`
-It's time we sum up where `static` can be used and what it gives us in terms of changing the storage duration of variables. Generally speaking, when used outside of classes, `static` can be used in two places:
-- at namespace scope which adds nothing as any such variable already has the static storage duration
-- inside of functions to extend the local variable's automatic storage duration to static storage duration, which we mostly don't want to do
-
-:bulb: So, all in all, there is really **no good reason** to use `static` to change storage duration of our variables!
-
-## Linkage
-Now it's time to talk about the second thing that `static` controls - linkage.
-
-<!-- The topic of linkage is a bit nuanced and I tried to simplify it as much as I could here, but if I missed something or made a mistake in my strive for simplicity, please comment below this video. Oh, and maybe subscribe once you're at it? You did make it this far, right? Anyway, back to linkage. -->
-
-### What is linkage
-First, let me try to explain what linkage is by describing what it is used for. When we write programs we name things like our variables, classes, functions etc. We can think of linkage as of a property of any given name. This property basically controls if a name of any symbol can correspond (in other words - be linked) to its declaration in a different scope. We distinguish linkage of several levels that control which boundaries such links can cross:
-- No linkage
-- Internal linkage
-- External linkage
-
-Let's dive into these.
-
-### Levels of linkage
-Intuitively speaking, if we want some name to be available only in the current scope, it should have **no linkage**. As an example, any variable defined in any local scope usually has no linkage.
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-
-int main() {
-  Foo();
-}
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` no_linkage/main.cpp
-`CPP_RUN_CMD` CWD:no_linkage c++ -std=c++17 -c main.cpp
--->
-```cpp
-void Foo() {
-  int bar;  // bar has no linkage
-}
-```
-
-If a name should be available beyond local scopes but still **only** from within the same translation unit (think, within one `.cpp` file) - it should have **internal linkage**. The typical examples of these are constants defined at namespace scope, any data and functions put into an unnamed namespaces within a `.cpp` file. Oh, and also any `static` data and functions, but more on that in a minute.
-<!--
-`CPP_SETUP_START`
-#include <string>
-$PLACEHOLDER
-
-int main() {}
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` internal_linkage/main.cpp
-`CPP_RUN_CMD` CWD:internal_linkage c++ -std=c++17 -c main.cpp
--->
-```cpp
-// Constants have internal linkage by default
-constexpr int kGlobalConst{};  // 😱 should be inline
-const std::string kGlobalWord{};  // 😱 should be inline
-
-
-// In some cpp file
-namespace {
-// Everything within unnamed namespaces has internal linkage
-constexpr int kNumber{};
-const std::string kWord{};
-void Foo() {}
-}  // namespace
-
-// Any static variable or function has internal linkage
-static int kStaticVariable{};  // 😱 don't use static like this
-static void StaticFoo(){}  // 😱 don't use static like this
-```
-
-Finally, **external linkage** is needed for symbols that need to be available globally throughout the program. These are usually classes, enums, non-`static`  (usually `inline`) functions and `inline` constants declared at namespace scope in some header files.
-<!--
-`CPP_SETUP_START`
-#include <string>
-$PLACEHOLDER
-
-int main() {}
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` external_linkage/main.cpp
-`CPP_RUN_CMD` CWD:external_linkage c++ -std=c++17 -c main.cpp
--->
-```cpp
-// In some header file
-// All of the below have external linkage
-inline void GlobalFoo() {}
-inline constexpr int kGlobalNumber{};
-inline const std::string kGlobalString{};
-
-void OtherGlobalFoo() {}  // 😱 should be inline
-```
-
-### How to understand what linkage a name has
-In the end it is up to us which linkage our entities have. We can pick linkage of anything that we declare at declaration time by choosing **where** we put our declarations (local scope, namespace scope, unnamed namespace etc.) and by using keywords `const`, `constexpr`, `static` and `inline` all of which have their influence on linkage.
-
-As you might start to suspect, the complete rules of how linkage is selected are slightly convoluted. If you want to figure out these rules in all details you can always read the cppreference pages for [linkage](https://en.cppreference.com/w/cpp/language/storage_duration) and [inline](https://en.cppreference.com/w/cpp/language/inline). The good news is that when _we_ write the code the rules to follow the best practices are pretty simple and I will summarize them at the end of this lecture.
-
-However, in order to read the code written by others we have to dive a bit deeper into these convoluted rules. So, to save you the trouble of figuring out all of the intricate details, I came up with a flow chart. If we follow it, we can find out the linkage of any symbol we are looking at. This is helpful to debug code that we did not write and see issues in the code _before_ they happen as well as to know how to make sure the symbol we want to write has the linkage we want.
-
-```mermaid
-graph TB;
-  Local -->|yes| No[No linkage]
-  Local{{Is in local scope?}} -->|no| Unnamed
-  Unnamed{{Is in unnamed namespace?}} -->|yes| Internal
-  Unnamed -->|no| Static
-  Static{{<code>static</code>?}} -->|yes| Internal[Internal linkage]
-  Static -->|no| Inline{{<code>inline</code>?}}
-  Inline -->|no| Const{{<code>const? constexpr?</code>}}
-  Inline -->|yes| External[External linkage]
-  Const -->|yes| Func{{Is function?}}
-  Const -->|no| External
-  Func -->|no| Internal
-  Func -->|yes| External
-
-  style No fill:#226666,color:white;
-  style Internal fill:#763289,color:white;
-  style External fill:#3355AA,color:white;
-```
-
-Here is how to read it. This chart should work with any function or data declaration you might encounter. First, if you are looking at a function, ignore the return type along with any const qualifiers it might have. Then, follow the chart by answering the questions.
-
-Let's see a couple of examples that follow best practices:
-<!--
-`CPP_SETUP_START`
-#include <string>
-$PLACEHOLDER
-
-int main(){}
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` flow_char/main.cpp
-`CPP_RUN_CMD` CWD:flow_char c++ -std=c++17 -c main.cpp
--->
-```cpp
-// In some hpp file
-inline constexpr int kNumber{};  // external linkage
-inline const std::string kWord{};  // external linkage
-inline void Func();  // external linkage
-
-// Lives in some cpp file
-namespace {
-constexpr int kOtherNumber{};  // internal linkage
-
-void OtherFunc() {  // internal linkage
-  int local_variable{};  // no linkage
-}
-}  // namespace
-```
-<!-- So, looking at the kNumber here, we can follow the chart: Is in in local scope? No, it's not! Is it in unnamed namespace? Nope! Does it use the static keyword? No, it doesn't. Is it inline? Yeah it is, which brings us to it having external linkage. Feel free to do this for all other examples or any other ones that you see in any code you encounter. -->
-
-### Back to `static`
-Now that we understand more about linkage, let's return back to the topic we actually wanted to chat about: `static` and why we mostly don't want to use it for free standing functions and data. As you can see from the flow chart that we just looked at, `static` has something of a superpower to decide if some entity has internal or external linkage. Anything that we mark as `static` will definitely have internal linkage and will only be visible within the same translation unit it is defined in. Which has its consequences.
-
-#### Don't use `static` to declare functions in header files
-One of these consequences is that it makes very little sense to **declare** (and not define) a `static` function in a header file:
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-static void Foo() {}
-
-int main() {}
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` static_declaration/main.cpp
-`CPP_RUN_CMD` CWD:static_declaration c++ -std=c++17 -c main.cpp
--->
-```cpp
-// In some header file
-// 😱 Don't do this...
-static void Foo();
-```
-Any such function will have to be defined in _every source file_ this header will be included in. Not only that, but such a definition will only be seen from _within_ that same source file due to internal linkage that `static` enforces. Which means that we could have just defined this function in any such source file directly. So, don't declare functions in header files as `static`. Which brings us to my next point.
-
-#### Don't define functions and data `static` in a source file, use unnamed namespace instead
-When we _do_ define functions and data in a source file, we can still find some advice on the internet to use `static` in such definitions. I would argue that this advice is obsolete. If we go back to our chart, we can easily see that while `static` has a "superpower" to make anything have internal linkage, the unnamed namespaces have the same superpower. Without going too deep into details, it turns out that they are usually even more powerful in this regard. So, if we define some data or functions in some `.cpp` file, we should put them into an **unnamed namespace** instead of defining them as `static` (although technically, it won't be a bug):
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-
-int main() {}
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` ok_not_ok/main.cpp
-`CPP_RUN_CMD` CWD:ok_not_ok c++ -std=c++17 -c main.cpp
--->
-```cpp
-// In some source (cpp) file
-
-// ❌ Don't
-static constexpr int kStaticNumber{};
-static void StaticFoo() {}
-
-// ✅ Do
-namespace {
-  constexpr int kNumber{};
-  void StaticFoo() {}
-}
-```
-
-#### Don't define functions and data as `static` in header files, use `inline` instead
-One final place where I could imagine `static` being used is when **defining** functions or data **in a header file**. Now, you might wonder why would anybody want to do this and the answer is: to avoid [One Definition Rule (ODR)](https://en.cppreference.com/w/cpp/language/definition) violations. Let's dig a bit into this.
-
-ODR states roughly this: that any symbol must have **exactly one** definition in the entire program, i.e., across all of its translation units. Only `inline` symbols can have more than one definition which are then all assumed to be exactly the same.
-
-If we naively define a function in a header file `foo.hpp`:
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-
-int main() {}
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` raw_func/main.cpp
-`CPP_RUN_CMD` CWD:raw_func c++ -std=c++17 -c main.cpp
--->
-```cpp
-// 😱 Use inline instead
-void Foo() {}
-```
-And include this file into two source files `foo_1.cpp` and `foo_2.cpp` which are then compiled into two libraries, then we already violate ODR - we have two definitions of the function `Foo` in two different translation units. Granted, in this situation, these definitions are the same but there is a awful lot of things that can go wrong from this point on. Considering that ODR violations are not required to be checked by the linker, this can quickly lead to us finding ourselves in the undefined behavior land, which is typically a very painful experience. But that warrants a separate video. Please comment if you'd like to see a separate video on various ODR violations.
-
-One way that people sometimes, I would say wrongly, fix this is by marking their function `static`, so in our case we would make our `Foo` function `static` in the `foo.h` header:
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-
-int main() {}
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` static_raw_func/main.cpp
-`CPP_RUN_CMD` CWD:static_raw_func c++ -std=c++17 -c main.cpp
--->
-```cpp
-// 😱 Use inline instead
-static void Foo() {}
-```
-The reason people do this is that it _does_ help to avoid the ODR violation. Because `static` enforces internal linkage, the two translation units related to `foo_1.cpp` and `foo_2.cpp` that include our header will have their own **different** versions of the `Foo` definition not visible beyond their respective translation unit. Which means that ODR would not be violated.
-
-This approach has one major downside though. Now every translation unit that includes our header will have it's own implementation of `Foo` baked in. Which, depending on what functions or data we define, can have a significant impact on the binary size. This can be a problem if we develop for, say, constrained hardware.
-
-A proper way to fix this, would be to use `inline` instead of `static` here. Returning back to our flow chart, the "superpower" of `inline` is to enforce **external linkage** but one that is explicitly allowed by the ODR formulation. So, we can change the definition of our `Foo` function to `inline` inside of our `foo.hpp` file. And the same holds for any data. We should mark it as `inline constexpr` or `inline const`:
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-
-int main() {}
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` inline_func_data/main.cpp
-`CPP_RUN_CMD` CWD:inline_func_data c++ -std=c++17 -c main.cpp
--->
-```cpp
-// At namespace scope
-inline void Foo() {}
-inline constexpr int kNumber{};
-```
-
-<p align="center">
-  <a href="https://youtu.be/QVHwOOrSh3w"><img src="https://img.youtube.com/vi/QVHwOOrSh3w/maxresdefault.jpg" alt="Video" align="right" width=300 style="margin: 0.5rem"></a>
-</p>
-
-This will lead the binary code for such functions and data to only exist once and to be linked everywhere they are needed, while still not violating ODR.
-
-Note, though, that using `inline` is only safe **in header files**. Avoid using `inline` in source files as this can lead to its own ODR violations. But that is again probably a story for another video.
-
-For another intuitive explanations on this, I urge you to watch [this video](https://www.youtube.com/watch?v=QVHwOOrSh3w) by Jason Turner on his C++ Weekly chanel about the differences between `static` and `inline` in this context.
-
-## Conclusion and a rule of thumb
-And I guess this pretty much sums up everything I wanted to talk about with regard to using, or rather **NOT** using `static` outside of classes. This has led us down a couple of rabbit holes, linkage being a pretty deep one.
-
-But I hope that by now you see that **there is no need to use `static` outside of classes at all in modern C++**. Here is a guideline to follow along with this:
-
-- When defining variables at namespace scope always mark them as `inline const` or, even better `inline constexpr`. Do **not** mark them `static`!
-- When defining variables at local scope, do **not** mark them `static` unless you are explicitly implementing a singleton-like design pattern (which you probably shouldn't do anyway, stay tuned...)
-- When declaring functions at namespace scope, declare (and define) them as `inline`. Do **not** use `static` for this!
-- When declaring data or functions in an unnamed namespace, do not mark them as `static` or `inline`. Data should still be `const` or `constexpr`
-
-## Final words
-Understanding the key role that linkage and ODR play here is crucial to understanding what `inline` and, previously, `static` were designed to solve. Initially `static` was introduced into the C programming language and then was inherited by C++. It was in the times when C did not have `inline` and in C++ it meant something different and could not be used as it can be now. Thankfully, we live in better times now, which makes `static` close to obsolete when used outside of classes. Now if you want to know how to use `static` *in classes* you can see a video about that once it's ready and maybe also go back and refresh how `inline` plays a huge role in creating [libraries](headers_and_libraries.md) in C++.
diff --git a/lectures/templates_and_headers.md b/lectures/templates_and_headers.md
deleted file mode 100644
index 8742bd7..0000000
--- a/lectures/templates_and_headers.md
+++ /dev/null
@@ -1,329 +0,0 @@
-**Templates in header and source files**
-
-----
-
-<p align="center">
-  <a href="https://youtu.be/vjsr18XXMMQ"><img src="https://img.youtube.com/vi/vjsr18XXMMQ/maxresdefault.jpg" alt="Video" align="right" width=50% style="margin: 0.5rem"></a>
-</p>
-
-- [Why linker fails](#why-linker-fails)
-  - [Compilation process for single `main.cpp` file](#compilation-process-for-single-maincpp-file)
-  - [Compilation process for multiple files](#compilation-process-for-multiple-files)
-- [How to fix the linker error](#how-to-fix-the-linker-error)
-- [More complex explicit instantiations](#more-complex-explicit-instantiations)
-- [Summary](#summary)
-
-
-In the previous videos, we talked quite extensively about templates and we should already know what they are, what they do under the hood and how to use templates in our code.
-
-So, writing some simple templated code like this should come natural to us:
-```cpp
-// Function template.
-template <typename T>
-void Foo() {
-  // Do something.
-}
-
-int main() {
-  Foo<int>();
-  Foo<float>();
-  return 0;
-}
-```
-
-With all of this knowledge, we might want to write some slightly more complicated software. Which means that we will eventually want to compile our code into *libraries* and *link* these libraries to executable files.
-
-So we might try to split our files into header and source files just like we used to do with non-template code.
-
-<table>
-<tr>
-<td>
-
-`foo.hpp`
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` template_library_simple/foo.hpp
--->
-```cpp
-#pragma once
-
-// Function template declaration.
-template <typename T>
-void Foo();
-```
-
-`foo.cpp`
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-template void Foo<int>();
-template void Foo<float>();
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` template_library_simple/foo.cpp
-`CPP_RUN_CMD` CWD:template_library_simple c++ -std=c++17 -c foo.cpp -o foo.o
--->
-```cpp
-#include "foo.hpp"
-
-// Function template definition.
-template <typename T>
-void Foo() {
-  // Do something.
-}
-```
-</td>
-
-<td>
-
-`main.cpp`
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` template_library_simple/main.cpp
-`CPP_RUN_CMD` CWD:template_library_simple c++ -std=c++17 main.cpp foo.o -o main
--->
-```cpp
-#include "foo.hpp"
-
-int main() {
-  Foo<int>();
-  Foo<float>();
-  return 0;
-}
-```
-For simplicity of this example, we compile both our `foo.cpp` and `main.cpp` into binary object files `foo.o` and `main.o` and provide these to our compiler (which passes it internally to the linker) when building our executable:
-<!--
-`CPP_SKIP_SNIPPET`
--->
-```bash
-# Create object file foo.o.
-c++ -std=c++17 -c foo.cpp -o foo.o
-# Create object file main.o.
-c++ -std=c++17 -c main.cpp -o main.o
-# Link object files to produce an executable
-c++ -std=c++17 main.o foo.o -o main
-```
-
-</td>
-</tr>
-</table>
-
-
-It all looks quite logical, but there is a problem: when we run it we get our linker complaining about undefined symbols that we reference in our `main` function:
-```css
-Undefined symbols for architecture arm64:
-  "void Foo<float>()", referenced from:
-      _main in main-cebf24.o
-  "void Foo<int>()", referenced from:
-      _main in main-cebf24.o
-ld: symbol(s) not found for architecture arm64
-clang: error: linker command failed with exit code 1 (use -v to see invocation)
-```
-
-The same would have happened if we would have packed our object file into a library and linked this library explicitly to our executable. See the lecture about [libraries](headers_and_libraries.md) if you find this confusing.
-
-Anyway, today, we dive into why this linker error happens and what we can do about it. Because there **is** a way to compile templated code into libraries after all :wink:
-
-<!-- Intro -->
-
-## Why linker fails
-Before we start, we should make sure we understand the compilation process, especially when templates are involved, well enough as this is crucial to understand why the linker fails. We talk about this extensively in the lecture about [what templates do under the hood](templates_what.md) and I urge you to look at that lecture before we continue here. It will make this lecture much easier to digest.
-
-### Compilation process for single `main.cpp` file
-That being said, we will now go through the whole compilation process, starting with the simple case of compiling a single `main.cpp` file that contains all of our code and progressively making our example more complicated.
-
-Any compilation process consists really of 3 stages:
-1. Preprocessor creates translation units, `main.s` in our case
-2. Compiler compiles the code into binary object files, `main.o` in our case
-3. Linker links various symbols, potentially across multiple binaries to produce the `main` executable file
-
-<p align="center">
-<img src="images/CompilationProcessEverything.png" alt="Video" style="width:100%;max-width:800;">
-</p>
-
-At this point, it is important to look a bit closer at what the **compiler** does here. When it sees the templates, it looks at which type we instantiate these templates with in our code and, well, creates implicit instantiations of these templates with the needed types. In our case, we use the function template `Foo` with the types `int` and `float`. These are then compiled directly into the object file alongside all the rest of the code as can be seen if we look at the **Symbol Table** of the resulting object file, which can be done by using either the `objdump` command.
-
-These are the symbols we need in order to correctly compile our executable!
-
-<p align="center">
-<img src="images/CompilerIndepth.png" alt="Video" style="width:100%;max-width:800;">
-</p>
-
-
-### Compilation process for multiple files
-Armed with this knowledge, we can look at what happens if we naively try to separate our template implementation into `foo.hpp` and `foo.cpp` files, away from the `main.cpp` file that now holds only the `main` function.
-
-We start by compiling the `foo.cpp` file, which contains the definitions of our `Foo` function and includes the file `foo.hpp`, which contains the declaration of the function template `Foo`.
-
-<p align="center">
-<img src="images/CompilerFooNotKnowing.png" alt="Video" style="width:100%;max-width:800;">
-</p>
-
-As we already know, the preprocessor creates a **translation unit**, which essentially means that it just copies the contents of the `foo.hpp` into the `foo.cpp`, removes comments etc. As before, we will show this file as `foo.s` here. By default this file is not saved to disk but we _can_ save it using `--save-temps` flag that we can pass to the compiler.
-
-Anyway, this translation unit is then passed into the compiler, which generates the `foo.o` object file.
-
-The compiler sees our function template declaration and definition, however, this time around the compiler **does not see any code that asks it to instantiate our templates! And so it doesn't!** If we inspect the symbol table of the generated `foo.o` object file, we will see no `Foo` related symbols in it!
-
-Now, if we do the same compilation process for our new `main.cpp` that also includes `foo.hpp` and try to link the resulting `main.o` object file with the `foo.o` object file from the previous step, **we get the linker error!**
-
-<p align="center">
-<img src="images/CompilationMainWithFooFail.png" alt="Video" style="width:100%;max-width:800;">
-</p>
-
-And by now we should see that the reason is that the `foo.o` does not have the symbols that we need in our `main` function, namely the specializations of our `Foo` template for `int` and for `float`.
-
-## How to fix the linker error
-Linker errors like these prompt many people to just use header-only libraries when using templates. And this _might_ be the only available solution if the library we are writing *really has to be extremely generic* and we have no idea which types our templates might be used with.
-
-But this is not always the case. Actually, this is most often **not** the case! Most of us mortals don't write extremely generic libraries. We use templates to avoid code duplication and to introduce some nice-to-read abstractions into our system. In such situations, we usually know exactly what types we might be using with our templates!
-
-In this situations we have another tool in our toolbox, called the **explicit template instantiation**, which can be used to, well, explicitly instantiate templates.
-
-In our case, the explicit instantiation for our `Foo` function template looks like this:
-<!--
-`CPP_SKIP_SNIPPET`
--->
-```cpp
-template void Foo<int>();
-template void Foo<float>();
-```
-Essentially, syntax-wise it looks like something stuck between a function declaration (just with a `template` keyword before it) and a template specialization (just without the angular brackets after the word `template`). To avoid any confusion, I would suggest to refresh how [function template specialization](templates_how_functions.md#full-function-template-specialization-and-why-function-overloading-is-better) looks like. What it essentially does is it forces the compiler to generate the code for our template with the provided type without waiting for seeing the code that uses it within some function.
-
-And hopefully by now you can guess what we need to do to fix our linker error - we need to add **explicit template instantiations** to the end of our `foo.cpp` file:
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` template_library_simple/foo_new.cpp
-`CPP_RUN_CMD` CWD:template_library_simple c++ -std=c++17 -c foo_new.cpp -o foo_new.o && c++ -std=c++17 foo_new.o main.cpp
--->
-```cpp
-#include "foo.hpp"
-
-// Function template definition.
-template <typename T>
-void Foo() {
-  // Do something.
-}
-
-template void Foo<int>();
-template void Foo<float>();
-```
-It is common to add these instantiations to the end of the file as by that time the compiler has seen all of the definitions so it knows how to generate the required template instantiations, which are then available in the symbol table of the `foo.o` object file. These symbols are then available for linkage against those required from the `main.o` object file to produce the final executable without error! :tada:
-
-
-<p align="center">
-<img src="images/CompilationSuccessWithHeaders.png" alt="Video" style="width:100%;max-width:800;">
-</p>
-
-## More complex explicit instantiations
-This covers the basics of why we might want to use explicit template instantiation as well as hints on how this can be achieved.
-
-But I guess you might be wondering if this only works with functions and the answer is: of course not! We can explicitly instantiate function, classes and even class methods.
-
-Instead of talking about it too abstractly, let us look at a slightly more complex example which covers most of the interesting use-cases. The rest, I'm sure, you'll be able to figure out on your own.
-
-Here, in the new `foo.hpp` header, we have a struct template that has a method template. In addition to the struct we also have a function that returns an object of our struct template and accepts a parameter of some type.
-
-`foo.hpp`
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` complex_template_library/foo.hpp
--->
-```cpp
-#pragma once
-// Class template declaration.
-template <typename T>
-struct Foo {
-  template <typename S>
-  void Bar(const S& smth) const;
-
-  T data{};
-};
-
-// Function template declaration.
-template <typename T>
-Foo<T> MakeFoo(const T& smth);
-```
-Just as before, the definitions for all of these declarations live in the `foo.cpp` file. And, as we know by now, we have to also explicitly instantiate all of these. Here, we make sure that we instantiate the struct template `Foo` for the type `int`, its `Bar` method for the types `int` and `float` (note that for functions we can either provide the type explicitly or let it be figured out from the function parameters) and, finally, the `MakeFoo` function for the type `int`.
-
-`foo.cpp`
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` complex_template_library/foo.cpp
-`CPP_RUN_CMD` CWD:complex_template_library c++ -std=c++17 -c foo.cpp -o foo.o
--->
-```cpp
-#include "foo.hpp"
-
-// Class method template definition.
-template <typename T>
-template <typename S>
-void Foo<T>::Bar(const S& smth) const {}
-
-// Function template definition.
-template <typename T>
-Foo<T> MakeFoo(const T& smth) {
-  return Foo<T>{smth};
-}
-
-template class Foo<int>;
-template void Foo<int>::Bar<int>(const int&) const;
-template void Foo<int>::Bar(const float&) const;
-template Foo<int> MakeFoo<int>(const int&);
-```
-And of course we also have a `main` function that makes use of all of the instantiations from before.
-
-`main.cpp`
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` complex_template_library/main.cpp
-`CPP_RUN_CMD` CWD:complex_template_library c++ -std=c++17 main.cpp foo.o -o main
--->
-```cpp
-#include "foo.hpp"
-
-int main() {
-  const int data = 42;
-  const auto foo = MakeFoo(data);
-  foo.Bar(data);
-  foo.Bar(42.42F);
-  return 0;
-}
-```
-
-Now if we build the object files for the `foo.cpp` and `main.cpp` we can link them together to produce the resulting binary without issues as all of our symbols have been generated after our templates have been explicitly instantiated by us in the `foo.cpp` file.
-<!--
-`CPP_SKIP_SNIPPET`
--->
-```bash
-# Create object file foo.o.
-c++ -std=c++17 -c foo.cpp -o foo.o
-# Create object file main.o.
-c++ -std=c++17 -c main.cpp -o main.o
-# Link object files.
-c++ -std=c++17 main.o foo.o -o main
-```
-
-I'll leave it up to you to inspect the symbol tables of the generated binary files as well as to play around with this example by changing the template declarations and definitions as well as any arguments that we pass around. As always, it's all about getting a feeling for what works as well as how and why things break.
-
-## Summary
-This lecture should hopefully be enough to give us some intuition about explicit template instantiation and how it allows to split our template code declarations and definitions to header and source files.
-
-For more details, I'll refer you to cppreference.com, as always. There are two distinct pages there with all the information we might be interested in, one for [explicit instantiations of function templates](https://en.cppreference.com/w/cpp/language/function_template#Explicit_instantiation) and one for [explicit instantiations of class templates](https://en.cppreference.com/w/cpp/language/class_template#Explicit_instantiation).
-
-<!-- You'll also find the links to these below the video of course. And, as always, if you do run into any issues or come up with any questions, please write them in the comments, I value any feedback and will try my best to explain anything that was not clear enough.
-
-
-And with this, I'd like to thank you for your attention, hope you liked what you saw today and if you feel that some details still didn't fully clock, then why not refresh your understanding of how to use templates by re-watching one of these videos?
--->
diff --git a/lectures/templates_how_classes.md b/lectures/templates_how_classes.md
deleted file mode 100644
index a2ff107..0000000
--- a/lectures/templates_how_classes.md
+++ /dev/null
@@ -1,940 +0,0 @@
-How to use templates with classes in C++
---
-
-<p align="center">
-  <a href="https://youtu.be/IQ62tA51Vag"><img src="https://img.youtube.com/vi/IQ62tA51Vag/maxresdefault.jpg" alt="Video" align="right" width=50% style="margin: 0.5rem"></a>
-</p>
-
-- [How to use templates with classes in C++](#how-to-use-templates-with-classes-in-c)
-- [Class method templates](#class-method-templates)
-  - [Prefer overloading to specialization of class method templates](#prefer-overloading-to-specialization-of-class-method-templates)
-  - [Sometimes overloading is not possible --- specialize in this case](#sometimes-overloading-is-not-possible-----specialize-in-this-case)
-- [Class templates](#class-templates)
-- [Class template argument deduction (min. C++17)](#class-template-argument-deduction-min-c17)
-  - [Class template specialization: implicit and explicit](#class-template-specialization-implicit-and-explicit)
-  - [Full explicit template specialization](#full-explicit-template-specialization)
-    - [How to fully specialize class templates](#how-to-fully-specialize-class-templates)
-    - [Make sure a specialization follows the expected interface](#make-sure-a-specialization-follows-the-expected-interface)
-    - [Historical reference for `std::vector<bool>`](#historical-reference-for-stdvectorbool)
-    - [Specialize just one method of a class](#specialize-just-one-method-of-a-class)
-    - [Specialize method templates of class templates](#specialize-method-templates-of-class-templates)
-    - [Type traits and how to implement them using template specialization](#type-traits-and-how-to-implement-them-using-template-specialization)
-    - [More generic traits using partial specialization](#more-generic-traits-using-partial-specialization)
-  - [Difference between partial and full specializations](#difference-between-partial-and-full-specializations)
-    - [How to tell partial template specialization apart from a new template class definition?](#how-to-tell-partial-template-specialization-apart-from-a-new-template-class-definition)
-    - [How to tell a partial template specialization apart from a full class template specialization?](#how-to-tell-a-partial-template-specialization-apart-from-a-full-class-template-specialization)
-  - [Partial template specialization with more types](#partial-template-specialization-with-more-types)
-- [Summary](#summary)
-
-
-In the previous videos we talked about **why** we might want to use templates, **what** happens under the hood when we use them, and how to use function templates. Today, finally, we can talk about how to use **class templates**.
-
-On the surface they are kinda similar to function templates but, well, for classes, with one crucial difference that enables most of C++ meta-programming. That difference is that we can **partially specialize class templates** and I can't stress enough how important that is!
-
-<!-- Intro -->
-
-## Class method templates
-Before we start talking about actual class templates I want to briefly talk about **class method templates**.
-
-We can write them just like any freestanding function template. And we can treat `static` class method templates in the same way. All of these class method templates can appear in any class or struct and it doesn't matter if that class or struct is a class template itself or not.
-
-Such template methods behave in _exactly_ the same way as the normal function templates so we should already know how to use them after the [previous lectures](templates_how_functions.md):
-```cpp
-// Can also be a class, using struct for simplicity
-struct SomeClass {
-  template <typename ClassT>
-  void DoSmthWithObject(const ClassT& value) {}
-
-  template <typename ClassT>
-  static void DoSmthWithType(const ClassT& value) {}
-};
-
-int main() {
-  SomeClass object{};
-  // Compiler infers int
-  object.DoSmthWithObject(42);
-  // Same as above, but explicit
-  object.DoSmthWithObject<int>(42);
-
-  // Compiler infers double
-  SomeClass::DoSmthWithType(42.42);
-  // Same as above, but explicit
-  SomeClass::DoSmthWithType<double>(42.42);
-}
-```
-
-### Prefer overloading to specialization of class method templates
-Just like with function templates, we can overload or specialize these methods. And just like with function templates, we still should prefer overloading these methods while we are designing our class interface for the same reasons we discussed in the lecture about [free-standing function templates](templates_how_functions.md).
-```cpp
-// Can also be a class, using struct for simplicity
-struct Foo {
-  template <typename ClassT>
-  void Bar(ClassT value) {}  // 1️⃣
-  void Bar(int value) {}     // 2️⃣
-
-  template <typename ClassT>
-  static void StaticBar(ClassT value) {}   // 3️⃣
-  static void StaticBar(double value) {}   // 4️⃣
-};
-
-int main() {
-  Foo foo{};
-  // What gets called in every case?
-  foo.Bar(42);
-  foo.Bar(42.42);
-  Foo::StaticBar(42);
-  Foo::StaticBar(42.42);
-}
-```
-<!-- As a tiny exercise, tell me in the comments which methods get called in which order in this example! -->
-
-### Sometimes overloading is not possible --- specialize in this case
-There is one difference to the free-standing functions though: while it is always possible to introduce a new overload for any free-standing function at any place in the codebase after that function was defined, **it is impossible to create a new class method overloads outside of the class declaration**. So if we cannot change the code of our class, we are left with **full class function template specialization** as our only option:
-```cpp
-// Assume that we cannot change the code in this class
-struct Foo {
-  template <typename ClassT>
-  void Bar(ClassT value) {}  // 1️⃣
-  void Bar(int value) {}     // 2️⃣
-
-  template <typename ClassT>
-  static void StaticBar(ClassT value) {}   // 3️⃣
-  static void StaticBar(double value) {}   // 4️⃣
-};
-
-// Specialize our template out-of-class anywhere
-// in the code after the class declaration.
-template<>
-void Foo::Bar(double value) {}  // 5️⃣
-
-int main() {
-  Foo foo{};
-  // What gets called now?
-  foo.Bar(42);
-  foo.Bar(42.42);
-  Foo::StaticBar(42);
-  Foo::StaticBar(42.42);
-}
-```
-<!-- And, just like before, please tell me in the comments what you think gets called now? -->
-
-We can add these specializations anywhere in the codebase (after the class declaration that is) without ever touching the code in the class again.
-
-Anyway, with all of this out of the way, we're ready to talk about class templates!
-
-## Class templates
-The good news is that if we know how to use [function templates](templates_how_functions.md) and [what classes are](classes_intro.md), the syntax for class templates will look very logical and familiar. Another good news is that we've seen class templates before! A lot of [STL containers](more_useful_types.md) like `std::vector`, `std::array`, or `std::map` are actually class templates and that's why we can put values of nearly any (but same) type into them.
-
-So, for the sake of example, Let's say I want to write a simple class that will represent a coordinate of a pixel on the screen that has `int` row and column and does not much more than just pack them together as well as allow getting or printing their values:
-```cpp
-#include <iostream>
-
-class Coordinate {
-   public:
-    Coordinate(int row, int col) : row_{row}, col_{col} {}
-
-    int row() const { return row_; }
-    int col() const { return col_; }
-
-    void Print() const {
-      std::cout << "coordinate: [" << row_ << ", " << col_ << "]" << std::endl;
-    }
-
-   private:
-    int row_{};
-    int col_{};
-};
-
-int main() {
-    const Coordinate coordinate{42, 23};
-    coordinate.Print();
-    return 0;
-}
-```
-This is all good, but I come from robotics and image processing background where we regularly need the so-called sub-pixel resolution, meaning that our coordinates should be represented by floating point numbers. So we suddenly also need a `FloatCoordinate` class :thinking:
-```cpp
-#include <iostream>
-
-class Coordinate {
-   public:
-    Coordinate(int row, int col) : row_{row}, col_{col} {}
-
-    int row() const { return row_; }
-    int col() const { return col_; }
-
-    void Print() const {
-      std::cout << "int coordinate: [" << row_ << ", " << col_ << "]" << std::endl;
-    }
-
-   private:
-    int row_{};
-    int col_{};
-};
-
-class FloatCoordinate {
-   public:
-    FloatCoordinate(float row, float col) : row_{row}, col_{col} {}
-
-    float row() const { return row_; }
-    float col() const { return col_; }
-
-    void Print() const {
-      std::cout << "float coordinate: [" << row_ << ", " << col_ << "]" << std::endl;
-    }
-
-   private:
-    float row_{};
-    float col_{};
-};
-
-int main() {
-    const Coordinate coordinate{42, 23};
-    coordinate.Print();
-    const FloatCoordinate other_coordinate{42.42F, 23.23F};
-    other_coordinate.Print();
-    return 0;
-}
-```
-This is not very nice, is it? And of course you've already guessed that we can use class templates to get around this in an elegant way.
-
-We can replace our `Coordinate` and `FloatCoordinate` with a single **class template** `Coordinate`:
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` coordinate/coordinate.hpp
--->
-```cpp
-#include <iostream>
-
-template <typename ScalarT>
-class Coordinate {
-   public:
-    Coordinate(ScalarT row, ScalarT col) : row_{row}, col_{col} {}
-
-    ScalarT row() const { return row_; }
-    ScalarT col() const { return col_; }
-
-    void Print() const {
-      std::cout << "Generic coordinate: [" << row_ << ", " << col_ << "]" << std::endl;
-    }
-
-   private:
-    ScalarT row_{};
-    ScalarT col_{};
-};
-```
-<!--
-`CPP_SETUP_START`
-#include "coordinate.hpp"
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` coordinate/main.cpp
-`CPP_RUN_CMD` CWD:coordinate c++ -std=c++17 main.cpp
--->
-```cpp
-int main() {
-    const Coordinate<int> coordinate{42, 23};
-    coordinate.Print();
-    const Coordinate<float> other_coordinate{42.42F, 23.23F};
-    other_coordinate.Print();
-    return 0;
-}
-```
-
-A lot of things here are just like what we saw before for function templates:
-- We declare the class template by prefixing our class with the word `template`
-- We provide any number of templates parameters, here just one `ScalarT`, prefixing it with the key word `typename` or `class`. The compiler still doesn't care which names we give them but I would still advice to give these template parameters readable names
-- We can use our template parameter `ScalarT` anywhere in our class just like we would use any other normal type
-- When we instantiate an object of our class we provide the type that we want to use, which triggers **"implicit template instantiation"** (stay tuned for **explicit template instantiation** too). This means that the compiler creates a specialization of our class template for the concrete type that we are using it with. We can see this in detail using the awesome website [cppinsights.io](https://cppinsights.io/s/6729874b) where we see that in our example the compiler generates two concrete classes - one for `int` and one for `float` coordinates. For more see the lecture on [what templates do under the hood](templates_what.md).
-
-## Class template argument deduction (min. C++17)
-If our class has a constructor that uses all of our template types and we are using at least C++17 we can make use of the [**C**lass **T**emplate **A**rgument **D**eduction (CTAD)](https://en.cppreference.com/w/cpp/language/class_template_argument_deduction) and omit the template argument when creating our objects. This process uses implicit and explicit type deduction guides, which is a bit of a niche topic that I don't plan to actively cover in this course, but if we have a constructor for our class, we don't have to worry about it and the compiler will mostly be able to figure out the underlying types that we meant:
-<!--
-`CPP_SETUP_START`
-#include "coordinate.hpp"
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` coordinate/main_ctad.cpp
-`CPP_RUN_CMD` CWD:coordinate c++ -std=c++17 main_ctad.cpp
--->
-```cpp
-int main() {
-    // In C++17 the compiler is able to figure out the types
-    const Coordinate coordinate{42, 23};
-    coordinate.Print();
-    const Coordinate other_coordinate{42.42F, 23.23F};
-    other_coordinate.Print();
-    return 0;
-}
-```
-
-I use it all the time, but this is a bit of a controversial topic. If you look into the Google Code Style for C++ at least as of the date of preparing this lecture, they [suggest to steer away from using CTAD](https://google.github.io/styleguide/cppguide.html#CTAD) because the compiler might fail to deduce the type we expect it to deduce. We _can_ provide explicit type deduction guides but we won't cover it here. I believe that once you really need to use it, you'll know enough about C++ to read about it on your own. You can always read more on it [cppreference.com](https://en.cppreference.com/w/cpp/language/class_template_argument_deduction) under "User-defined deduction guides".
-
-### Class template specialization: implicit and explicit
-Ok, so from the lecture on [what templates do under the hood](templates_what.md) we already know that the code that actually gets compiled is just a copy of the code in our template with the chosen types substituted instead of the template parameters. These copies are called "specializations" and we touched upon this before too. So when we use a class template to instantiate an object in the code the compiler creates such a specialization and then uses that to create an object.
-<!--
-`CPP_SKIP_SNIPPET`
--->
-```cpp
-// Creates an implicit specialization Coordinate<int>
-// if it wasn't created before
-Coordinate<int> coordinate{42, 23};
-```
-
-But we don't *have* to wait for the compiler to create such a specialization at the first call site, we *can* (and sometimes *want*) to create one explicitly on our own! This is called **explicit template specialization** and it can be **full** and **partial**.
-
-### Full explicit template specialization
-We already talked about [full template specialization](templates_how_functions.md#full-function-template-specialization-and-why-function-overloading-is-better) when we talked about function templates because that's the only option we have with function templates (even though we should overload function instead of specializing them). Well, turns out we can use the same full template specialization with classes too. And in this case it _does_ have its valid use-cases that are quite popular.
-
-#### How to fully specialize class templates
-In order to fully specialize a class template we have to basically fully re-implement a class for a concrete type, prefixing it with `template<>`:
-```cpp
-#include <iostream>
-
-template <typename ScalarT>
-class Coordinate {
-   public:
-    Coordinate(ScalarT row, ScalarT col) : row_{row}, col_{col} {}
-
-    ScalarT row() const { return row_; }
-    ScalarT col() const { return col_; }
-
-    void Print() const {
-      std::cout << "Generic coordinate: [" << row_ << ", " << col_ << "]" << std::endl;
-    }
-
-   private:
-    ScalarT row_{};
-    ScalarT col_{};
-};
-
-// Full class template specialization for ScalarT = float.
-template<>
-class Coordinate<float> {
-   public:
-    Coordinate(float row, float col) : row_{row}, col_{col} {}
-
-    float row() const { return row_; }
-    float col() const { return col_; }
-
-    void Print() const {
-      std::cout << "float coordinate: [" << row_ << ", " << col_ << "]" << std::endl;
-    }
-
-   private:
-    float row_{};
-    float col_{};
-};
-
-int main() {
-    // Creates a new implicit instantiation of Coordinate<int>
-    const Coordinate coordinate{42, 23};
-    coordinate.Print();
-    // Uses the explicit instantiation of Coordinate<float>
-    const Coordinate other_coordinate{42.42F, 23.23F};
-    other_coordinate.Print();
-    return 0;
-}
-```
-Now, when we create a variable of this matching template instantiation, no implicit template instantiation is created by the compiler and it reuses the explicit template instantiation that we provide manually. I encourage you to play around with this simple example, printing things from these class template specializations to get a better intuition about what is happening.
-
-Notice how this is very similar to what we saw in the [cppinsights.io](https://cppinsights.io/s/6729874b) before! The only difference is that now _we_ force one of the specializations to be created **explicitly**.
-
-Note, that as _we_ implement the explicit specialization, it is **our responsibility** to implement the full class, along with all the data and methods that it provides. If we implement it differently from the original class template, it will behave differently when we try to use our specialization. Which might be confusing or error prone! Imagine if we for whatever reason dropped the `Print` function in our specialization:
-<!--
-`CPP_SKIP_SNIPPET`
--->
-```cpp
-#include <iostream>
-
-template <typename ScalarT>
-class Coordinate {
-   public:
-    Coordinate(ScalarT row, ScalarT col) : row_{row}, col_{col} {}
-
-    ScalarT row() const { return row_; }
-    ScalarT col() const { return col_; }
-
-    void Print() const {
-      std::cout << "Generic coordinate: [" << row_ << ", " << col_ << "]" << std::endl;
-    }
-
-   private:
-    ScalarT row_{};
-    ScalarT col_{};
-};
-
-template<>
-class Coordinate<float> {
-   public:
-    Coordinate(float row, float col) : row_{row}, col_{col} {}
-
-    float row() const { return row_; }
-    float col() const { return col_; }
-
-   private:
-    float row_{};
-    float col_{};
-};
-
-int main() {
-    // Creates a new implicit instantiation of Coordinate<int>
-    const Coordinate coordinate{42, 23};
-    coordinate.Print();
-    // Uses the explicit instantiation of Coordinate<float>
-    const Coordinate other_coordinate{42.42F, 23.23F};
-    // ❌ Won't compile! No Print() function in explicit specialization
-    other_coordinate.Print();
-    return 0;
-}
-```
-This example won't compile as there is no `Print` function found in the class template specialization for `float` :scream:.
-
-```css
-<source>: In function 'int main()':
-<source>:38:22: error: 'class Coordinate<float>' has no member named 'Print'
-   38 |     other_coordinate.Print();
-      |                      ^~~~~
-Compiler returned: 1
-```
-
-#### Make sure a specialization follows the expected interface
-🚨 So if we do decide to specialize a class, we have to make sure it conforms to the same logical interface as the original template, otherwise we're probably going to go through a whole lot of pain.
-<!-- Add the this is fine gif -->
-
-#### Historical reference for `std::vector<bool>`
-> **Story time:** one famous example of such a template specialization that **does not** fully conform to the interface that the original base template has is the specialization of `std::vector` for `bool` type. If you remember when we talked about `std::vector` in one of the [previous lectures](more_useful_types.md) I cautioned not to use `std::vector<bool>`. So here is the story behind that suggestion.
->
-> By default, if we store a `bool` it will still take a full byte of memory, even though we logically need just one bit to represent the stored value - `true` or `false`. So naïvely, if we store a number of `bool` variables in some array we will lose quite some memory, to be precise, we will use about 8 times the memory we could have.
->
-> At some point, the standardization committee decided that it would be a nice idea to have a specialization for the `std::vector` class template for type `bool` that addresses this issue. This specialization would allow to "pack" the boolean values together, 8 per byte and, as such, save space. It made sense too, a vector was designed to store a bunch of values in sequence, so it was conceivable that anybody who will want to store `bool` variables will want to pack them tightly.
->
-> The issue is that because we tightly pack these boolean values we can't really access them by a normal reference as we do with any other type. Type `bool` on its own still takes usually 1 byte. And so, `std::vector<bool>` returns a `std::__bit_reference` temporary wrapper instead that handles all the bit-fiddling. Which means that innocent-looking code like this won't compile:
-> <!--
-> `CPP_SKIP_SNIPPET`
-> -->
-> ```cpp
-> // ❌ Does not compile!
-> #include <vector>
-> int main() {
->   std::vector<bool> vector{/* some data */};
->   for (auto& value : vector) { /* do something */ };
-> }
-> ```
-> In addition to that, returning a temporary wrapper might actually be quite a bit slower, so there is a trade-off between storage and speed and forcing people to pack booleans together forces their hand.
-> As you might imagine, not everybody was a fan of this idea!
->
-> Anyway, long story short, while it is cool that `std::vector` is so flexible and interesting that we can reduce the usage of space occupied by a vector of booleans by a factor of 8, it has been widely considered a **"wrong move"** on the standard side and generally people are suggested to avoid using `std::vector<bool>` and use a different class specifically designed for this purpose if they need an array of bits.
->
-> I encourage you to read more about this from people who know much more about any of this: [Howard Hinnant](https://isocpp.org/blog/2012/11/on-vectorbool) and [Herb Sutter](http://www.gotw.ca/publications/mill09.htm). <!-- The links are below this video, of course. -->
-
-
-#### Specialize just one method of a class
-You might start noticing that sometimes it might be useful to specialize just one method of a class. And there _is_ a way to do it as we can specialize a single method of a class template too! For the sake of example, let us specialize the `Print` function for the specialization of our class template for type `float`:
-```cpp
-#include <iostream>
-
-template <typename ScalarT>
-class Coordinate {
-   public:
-    Coordinate(ScalarT row, ScalarT col) : row_{row}, col_{col} {}
-
-    ScalarT row() const { return row_; }
-    ScalarT col() const { return col_; }
-
-    void Print() const {
-      std::cout << "Generic coordinate: [" << row_ << ", " << col_ << "]" << std::endl;
-    }
-
-   private:
-    ScalarT row_{};
-    ScalarT col_{};
-};
-
-template<>
-void Coordinate<float>::Print() const {
-  std::cout << "float coordinate: [" << row_ << ", " << col_ << "]" << std::endl;
-}
-
-int main() {
-    // In C++17 the compiler is able to figure out the types
-    const Coordinate coordinate{42, 23};
-    coordinate.Print();
-    const Coordinate other_coordinate{42.42F, 23.23F};
-    other_coordinate.Print();
-    return 0;
-}
-```
-We just need to add a definition of a single function for our class specialization following the pattern that we should be used to by now, adding the `template <>` prefix. The main difference is that as we are implementing a class method, we have to indicate this by prefixing the name of the function with `Coordinate<float>::`. Note that we did not need to re-implement other methods of the generic coordinate class. This makes such a pattern quite useful: if a class still needs to conform to some generic interface, we usually don't need to specialize _all_ of its methods, just some. And we can also do this long after we're done designing our original class template.
-
-#### Specialize method templates of class templates
-Now if we would want to specialize a class method template that itself is found within a class template, we could still specialize it by just stacking multiple `template <>` prefixes together. So, if we would want a method `CastTo` that casts our `Coordinate` row and column to a different type we would be able to fully specialize such a method by specializing the class `Coordinate<int>::` with the first `template <>` and then the method `CastTo<int>` itself with the second `template <>`.
-```cpp
-#include <iostream>
-
-template <typename ScalarT>
-class Coordinate {
-   public:
-    Coordinate(ScalarT row, ScalarT col) : row_{row}, col_{col} {}
-
-    ScalarT row() const { return row_; }
-    ScalarT col() const { return col_; }
-
-    void Print() const {
-        std::cout << "Generic coordinate: [" << row_ << ", " << col_ << "]" << std::endl;
-    }
-
-    template <typename OtherScalarT>
-    Coordinate<OtherScalarT> CastTo() const {
-        std::cout << "Non-trivial cast" << std::endl;
-        return Coordinate<OtherScalarT>{
-          static_cast<OtherScalarT>(row_), static_cast<OtherScalarT>(col_)};
-    }
-
-   private:
-    ScalarT row_{};
-    ScalarT col_{};
-};
-
-template<>
-void Coordinate<float>::Print() const {
-  std::cout << "float coordinate: [" << row_ << ", " << col_ << "]" << std::endl;
-}
-
-template <>
-template <>
-Coordinate<int> Coordinate<int>::CastTo<int>() const {
-    std::cout << "Trivial cast" << std::endl;
-    return *this;
-}
-
-int main() {
-    // In C++17 the compiler is able to figure out the types
-    const Coordinate coordinate{42.42F, 23.23F};
-    coordinate.Print();
-    const auto int_coordinate = coordinate.CastTo<int>();
-    int_coordinate.Print();
-    const auto another_int_coordinate = int_coordinate.CastTo<int>();
-    another_int_coordinate.Print();
-    return 0;
-}
-```
-Running this shows that we are able to convert from a `float` coordinate to `int` coordinate and can perform a trivial cast after that.
-```output
-float coordinate: [42.42, 23.23]
-Non-trivial cast
-Generic coordinate: [42, 23]
-Trivial cast
-Generic coordinate: [42, 23]
-```
-
-#### Type traits and how to implement them using template specialization
-Going back to a class template specialization there is one canonical example where full class template specialization is widely used. I am talking about the implementation of the so-called "type traits". If you're not familiar with these, they are (usually) tiny structs that are designed to tell us certain things about various types. There is a bunch of these defined [in the standard](https://en.cppreference.com/w/cpp/header/type_traits), like for example [`std::is_integral`](https://en.cppreference.com/w/cpp/types/is_integral) that checks if the provided type is integer in an abstract sense. We can see how it works by using a `static_assert` that checks that any given boolean condition is `true` at compile time. So, if we combine all of the `std::is_integral` values for various input types we should get `true` in the end, which we can check by compiling this code:
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` is_integral/main.cpp
-`CPP_RUN_CMD` CWD:is_integral c++ -std=c++17 -c main.cpp
--->
-```cpp
-#include <type_traits>
-
-static_assert
-(
-    !std::is_integral<float>::value &&
-    !std::is_integral<int*>::value &&
-    std::is_integral<int>::value &&
-    std::is_integral<const int>::value &&
-    std::is_integral<bool>::value &&
-    std::is_integral<char>::value
-);
-```
-
-The way such a type trait can be implemented uses nothing but class template specialization and is genius in its simplicity.
-We start by defining the base trait that has its `static` `value` constant set to `false` for any given type:
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` custom_is_integral/is_integral.hpp
--->
-```cpp
-template <typename T>
-struct is_integral {
-  static constexpr inline bool value{};
-};
-```
-Now we can access the `value` for any of our class template instantiations as follows:
-<!--
-`CPP_SKIP_SNIPPET`
--->
-```cpp
-// ❌ Does not compile!
-static_assert(is_integral<int>::value);
-static_assert(!is_integral<double>::value);
-```
-And if we compile this assertion, it will _not_ compile with an error that a static assertion has failed. That's because we expect `is_integral<int>::value` to be `true` and in our case the `value` is `false` regardless of the type we pass into our trait.
-
-So let's fix this. And you might have already guessed that we can use class template specialization for this! Let us specialize our `is_integral` class template by prefixing it with `template <>` statement and specifying `int` as the type for which we specialize it:
-<!--
-`CPP_SETUP_START`
-#include "is_integral.hpp"
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` custom_is_integral/is_integral_specialization.hpp
--->
-```cpp
-template <>
-struct is_integral<int> {
-  static constexpr inline bool value{true};
-};
-```
-Now if we compile our asserts they will compile without issues!
-<!--
-`CPP_SETUP_START`
-#include "is_integral_specialization.hpp"
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` custom_is_integral/main.cpp
-`CPP_RUN_CMD` CWD:custom_is_integral c++ -std=c++17 -c main.cpp
--->
-```cpp
-// ✅ Compiles now!
-static_assert(is_integral<int>::value);
-static_assert(!is_integral<double>::value);
-```
-And, of course, we can repeat the same process for any other type that we consider to be integer-like (mostly variations on `bool` and `char`) and we've implemented `is_integral` type very similar to the one found in the STL.
-
-#### More generic traits using partial specialization
-And if you now think that it is a bit cumbersome to copy so much code to create an explicit specialization for any type we want, you're totally right! It feels a bit limiting. In the case of `is_integral` there is not too much we could do, but in most other cases, we can definitely do better!
-
-To illustrate this let's implement our own type trait `IsCoordinate` that we can use, for the sake of example, to show better errors to the users, should they try using our library in a wrong way.
-
-Imagine that we have a function to validate coordinates in some way:
-<!--
-`CPP_SETUP_START`
-template<class T>
-struct Coordinate {};
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` validate_simple/main.cpp
-`CPP_RUN_CMD` CWD:validate_simple c++ -std=c++17 -c main.cpp
--->
-```cpp
-#include <vector>
-
-template<typename ScalarT>
-[[nodiscard]] bool IsValid(const Coordinate<ScalarT>& coordinate) {
-  return true; // Actually do something useful here!
-}
-
-template<typename CoordinateT>
-[[nodiscard]] bool ValidateCoordinates(const std::vector<CoordinateT>& coordinates) {
-  for (const auto& coordinate : coordinates) {
-    if (!IsValid(coordinate)) return false;
-  }
-  return true;
-}
-```
-We have a function `IsValid` template that is able to validate a single coordinate and we pass a vector of these coordinates to some other function template `ValidateCoordinates`.
-
-If we pass a wrong type into this function, like `std::vector<int>` instead of a vector of actual coordinates, we will get an error which is not very nice to read:
-<!--
-`CPP_SKIP_SNIPPET`
--->
-```cpp
-#include <iostream>
-
-int main() {
-  const std::vector<int> wrong_input{1, 2, 3};
-  std::cout << ValidateCoordinates(wrong_input) << std::endl;
-}
-```
-
-```css
-<source>: In instantiation of 'bool ValidateCoordinates(const std::vector<CoordinateT>&) [with CoordinateT = int]':
-<source>:69:37:   required from here
-<source>:62:21: error: no matching function for call to 'IsValid(const int&)'
-   62 |         if (!IsValid(coordinate)) return false;
-      |              ~~~~~~~^~~~~~~~~~~~
-<source>:54:20: note: candidate: 'template<class ScalarT> bool IsValid(const Coordinate<U>&)'
-   54 | [[nodiscard]] bool IsValid(const Coordinate<ScalarT>& coordinate) {
-      |                    ^~~~~~~
-<source>:54:20: note:   template argument deduction/substitution failed:
-<source>:62:21: note:   mismatched types 'const Coordinate<U>' and 'const int'
-   62 |         if (!IsValid(coordinate)) return false;
-      |              ~~~~~~~^~~~~~~~~~~~
-```
-
-Now, what we _could_ do instead is check at compile time if we use the function correctly by, for the sake of example, putting a `static_assert` into it:
-<!--
-`CPP_SETUP_START`
-template<class T>
-struct IsCoordinate{
-  static constexpr inline bool value{};
-};
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` validate_static_assert/main.cpp
-`CPP_RUN_CMD` CWD:validate_static_assert c++ -std=c++17 -c main.cpp
--->
-```cpp
-#include <vector>
-
-template<typename CoordinateT>
-[[nodiscard]] bool ValidateCoordinates(const std::vector<CoordinateT>& coordinates) {
-  static_assert(IsCoordinate<CoordinateT>::value, "Contents of the container are not coordinates");
-  for (const auto& coordinate : coordinates) {
-    if (!IsValid(coordinate)) return false;
-  }
-  return true;
-}
-```
-
-Now if we try to write the same code it won't compile with a much more readable error generated by our `static_assert`.
-
-```css
-<source>: In instantiation of 'bool ValidateCoordinates(const std::vector<CoordinateT>&) [with CoordinateT = int]':
-<source>:71:37:   required from here
-<source>:61:52: error: static assertion failed: Contents of the container are not coordinates
-   61 |     static_assert(IsCoordinate<CoordinateT>::value == true,
-      |                                              ~~~~~~^~~~~~~
-<source>:61:52: note: the comparison reduces to '(0 == 1)'
-<source>:64:21: error: no matching function for call to 'IsValid(const int&)'
-   64 |         if (!IsValid(coordinate)) return false;
-      |              ~~~~~~~^~~~~~~~~~~~
-<source>:54:20: note: candidate: 'template<class ScalarT> bool IsValid(const Coordinate<U>&)'
-   54 | [[nodiscard]] bool IsValid(const Coordinate<ScalarT>& coordinate) {
-      |                    ^~~~~~~
-<source>:54:20: note:   template argument deduction/substitution failed:
-<source>:64:21: note:   mismatched types 'const Coordinate<U>' and 'const int'
-   64 |         if (!IsValid(coordinate)) return false;
-      |              ~~~~~~~^~~~~~~~~~~~
-```
-
-This is a powerful technique but it is now slowly getting outdated as in C++20 we have an even better tool to do the same things: **concepts**, which we'll briefly talk about soon. As a short introduction they will allow us to write code that looks something like this instead:
-<!--
-`CPP_SKIP_SNIPPET`
--->
-```cpp
-// Requires C++20!
-template <CoordinateLike CoordinateT>
-[[nodiscard]] bool ValidateCoordinates(const std::vector<CoordinateT>& coordinates) {
-  for (const auto& coordinate : coordinates) {
-    if (!IsValid(coordinate)) return false;
-  }
-  return true;
-}
-```
-Note the change from the `typename` keyword to a **concept** `CoordinateLike`, which defines a set of rules that a type must conform to in order to be accepted for this template. This function, if we pass a wrong type into it, will generate a similarly nice error message.
-
-But we're getting ahead of ourselves. For now we're interested in implementing such an `IsCoordinate` trait and see any limitations we encounter along the way. Just as in the case with `is_integral` trait, we start with the primary template that has a `false` `static` `value` constant:
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` is_coordinate_trait/is_coordinate_base.cpp
-`CPP_RUN_CMD` CWD:is_coordinate_trait c++ -std=c++17 -c is_coordinate_base.cpp
--->
-```cpp
-template <typename T>
-struct IsCoordinate {
-  static constexpr inline bool value{};
-};
-```
-And some of its explicit specializations for some of our `Coordinate` types:
-<!--
-`CPP_SETUP_START`
-template<class T>
-struct Coordinate {};
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` is_coordinate_trait/is_coordinate.cpp
-`CPP_RUN_CMD` CWD:is_coordinate_trait c++ -std=c++17 -c is_coordinate.cpp
--->
-```cpp
-template <typename T>
-struct IsCoordinate {
-  static constexpr inline bool value{};
-};
-
-template <>
-struct IsCoordinate<Coordinate<int>> {
-  static constexpr inline bool value{true};
-};
-
-template <>
-struct IsCoordinate<Coordinate<float>> {
-  static constexpr inline bool value{true};
-};
-
-// Not an exhaustive test, just an illustration.
-static_assert
-(
-    !IsCoordinate<void>::value &&
-    !IsCoordinate<int>::value &&
-    !IsCoordinate<float>::value &&
-    IsCoordinate<Coordinate<int>>::value &&
-    IsCoordinate<Coordinate<float>>::value
-);
-```
-We might notice that some things are not too optimal just yet. We are copying our `IsCoordinate` trait for each of the `Coordinate` template specializations just like we did in our `is_integral` trait implementation. And sure enough, if we want to cover _any_ type that the `Coordinate` template will accept, we are in for a lot of copying...
-
-Well, this is exactly what [**partial template specialization**](https://en.cppreference.com/w/cpp/language/partial_specialization) helps us to avoid!
-
-Partial template specialization is a very powerful technique. Let's see how it makes our `IsCoordinate` trait much nicer:
-<!--
-`CPP_SETUP_START`
-template<class T>
-struct Coordinate {};
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` is_coordinate_trait/is_coordinate_partial.cpp
-`CPP_RUN_CMD` CWD:is_coordinate_trait c++ -std=c++17 -c is_coordinate_partial.cpp
--->
-```cpp
-template <typename T>
-struct IsCoordinate {
-  static constexpr inline bool value{};
-};
-
-template <typename T>
-struct IsCoordinate<Coordinate<T>> {
-  static constexpr inline bool value{true};
-};
-
-static_assert
-(
-    !IsCoordinate<void>::value &&
-    !IsCoordinate<int>::value &&
-    !IsCoordinate<float>::value &&
-    IsCoordinate<Coordinate<int>>::value &&
-    IsCoordinate<Coordinate<float>>::value
-);
-```
-We definitely need to pause here and unpack this syntax a bit. We still have the same primary template trait that sets `value` to be `false` using value initialization. And we still have the same `static_assert` below. What changed is the way we define our template specialization.
-
-### Difference between partial and full specializations
-We replaced the `template <>` that we would have used for full template specialization with another `template <typename T>`.
-
-This syntax, in my experience, can be slightly confusing for beginners for two reasons.
-
-#### How to tell partial template specialization apart from a new template class definition?
-It is easy to confuse a new class template definition and a partial template specialization. The main indicator for the specialization is the `<Coordinate<T>>` part that follows the class template name `IsCoordinate`.
-<!--
-`CPP_SETUP_START`
-template<class T>
-struct Coordinate{};
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` is_coordinate_trait/is_coordinate_illustrate.cpp
-`CPP_RUN_CMD` CWD:is_coordinate_trait c++ -std=c++17 -c is_coordinate_illustrate.cpp
--->
-```cpp
-template <typename T>
-struct IsCoordinate {
-    static constexpr inline bool value{};
-};
-
-template <typename T>
-struct IsCoordinate  //
-    <Coordinate<T>>  // <-- This is an indicator of a specialization
-{
-    static constexpr inline bool value{true};
-};
-```
-
-#### How to tell a partial template specialization apart from a full class template specialization?
-Another confusing part is that it might take some time to learn the differences between partial and full class template specializations. So here is a simple rule of thumb:
-- **Full specialization** specializes a template **with a concrete type** and uses `template <>` prefix
-- **Partial specialization** specializes a template **with another template type** so needs template parameters in its definition
-
-In our case, we have a template type parameter `T`. It appears in the `Coordinate<T>` which is a specialization of the `Coordinate` template. We then specialize the `IsCoordinate` with `Coordinate<T>` type, making `IsCoordinate<Coordinate<T>>` a partial template specialization. We use the word "partial" because we don't *fully* constrain our specialization and the new input type `T` adds a degree of freedom to it.
-
-Now what the compiler does is it sees the call to `IsCoordinate<Coordinate<int>>` and looks for an appropriate implementation. It finds the primary template `IsCoordinate` and then looks for any explicit specializations available. Out of those it picks the ["most specialized"](https://en.cppreference.com/w/cpp/language/partial_specialization) one, which in our case is our only specialization. Here, a specialization is **"more specialized"** than the other if it only takes a subset of types that the other specialization takes.
-
-To fully understand the interplay of the full and partial class template specialization, let's have a look at this small artificial example where we have a custom dummy container for some data and some trait that has a couple of specializations:
-```cpp
-#include <iostream>
-
-template<typename T>
-struct Container {
-  T data{};
-};
-
-template<typename T>
-struct Trait {
-  static constexpr inline int kNumber{};
-};
-
-template<typename T>
-struct Trait<Container<T>> {
-  static constexpr inline int kNumber{1};
-};
-
-template<>
-struct Trait<int> {
-  static constexpr inline int kNumber{2};
-};
-
-int main() {
-  std::cout << Trait<float>::kNumber << " ";
-  std::cout << Trait<int>::kNumber << " ";
-  std::cout << Trait<Container<int>>::kNumber << " ";
-  std::cout << Trait<Container<float>>::kNumber << std::endl;
-}
-```
-Please spend some time playing with this example! By now you should be able to understand what each definition does and what gets printed to the terminal.
-<!-- Please pause the video, think about this example and type what will be printer to the terminal and why in the comments!
-
-Also, while you're at it, hit that like button and subscribe if you haven't already!
--->
-
-### Partial template specialization with more types
-Partial template specialization works in exactly the same way if there are more types! Like if we have a class `Foo` that accepts 3 template parameters, we can write its partial specialization that takes, for example, just two types and reuses them to specialize the primary template:
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` multiple_types/foo.hpp
--->
-```cpp
-// Primary template
-template<class T1, class T2, int I>
-class Foo {};
-
-// Partial specialization of Foo where T2 is a pointer to T1
-template<class T, int I>
-class Foo<T, T*, I> {};
-```
-
-The compiler then still picks the most specialized out of all the template specializations it finds for a given class or struct when they are used.
-<!--
-`CPP_SETUP_START`
-#include "foo.hpp"
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` multiple_types/main.cpp
-`CPP_RUN_CMD` CWD:multiple_types c++ -std=c++17 main.cpp
--->
-```cpp
-int main() {
-  Foo<int, double, 23> foo_generic;
-  Foo<int, int*, 42> foo_partial_specialization;
-}
-```
-
-Play around with this a bit on tiny examples and see if everything that happens makes sense. If it doesn't (even after you slept on it) please do not hesitate to ask questions! This is an important topic to understand!
-
-That being said, because of the sheer power that templates and their specialization provide, there _will_ be situations when what the compiler does will seem confusing. But if we firmly understand the concepts behind what is happening, we should be able to eventually figure out what is going on.
-
-## Summary
-All in all, using templates with classes is one of the super powers of C++. In combination with full and partial template specialization and function overloading, this enables most of the things that C++ is so well known for --- extreme flexibility that we only pay for with compile time (well, at least almost).
-
-Class templates also enable most of what we know as template meta-programming, i.e., writing code with complex logic that makes its results available at compile time. Furthermore, it was a stepping stone and the basis for arguably the most modern way to write C++ code by using concepts. So understanding how to use templates as well as various template specialization techniques is key to a happy and healthy C++ life.
-
-But don't worry if some concepts don't "click" from the first time, play around with examples, try to use templates in real code and see what causes you trouble. Then ask questions and I hope that in no time you will feel very comfortable using templates.
-
-<!-- And if you'd like to start watching all of the template-related videos in the order that I intended them to be watched please feel free to watch this video where I "start with why" we might be interested in using templates in the first place. If you'd rather dive deeper and refresh what templates do under the hood, then do click on this video instead! Other than that, thanks again for watching, tell your friends if you want to further support my efforts at recording these videos, and see you next time! -->
diff --git a/lectures/templates_how_functions.md b/lectures/templates_how_functions.md
deleted file mode 100644
index bbea935..0000000
--- a/lectures/templates_how_functions.md
+++ /dev/null
@@ -1,800 +0,0 @@
-**How to write template functions in C++**
-
-----
-
-<p align="center">
-  <a href="https://youtu.be/BZ626ZWPspc"><img src="https://img.youtube.com/vi/BZ626ZWPspc/maxresdefault.jpg" alt="Video" align="right" width=50% style="margin: 0.5rem"></a>
-</p>
-
-By now we talked about **why** we might want to use templates, **what** happens under the hood when we use them and today we can finally start talking about **how** to use them.
-
-While there is a lot of intricacies related to templates that often turn the C++ beginners away, I'm going to try to present all (well, ok, most) of the relevant information in the following couple of lectures.
-
-For this one in particular, my ambition is to make it your one-stop shop for all the basics you need to know about writing and using **function templates**. The class templates I'll leave for the next lecture. So we are starting very gently and will dive deeper as we go.
-
-That being said, I strongly urge you to go and look at the [**why**](templates_why.md) and the [**what**](templates_what.md) lectures before if you haven't already. I believe it will make this lecture much easier to digest.
-
-After you're done with those, you should be ready to hear about all the stuff we will cover today:
-- [The basics of writing a function template](#the-basics-of-writing-a-function-template)
-- [Explicit template parameters](#explicit-template-parameters)
-  - [Type template parameters](#type-template-parameters)
-  - [Non-type template parameters](#non-type-template-parameters)
-  - [Multiple different template parameters](#multiple-different-template-parameters)
-- [Implicit template parameters](#implicit-template-parameters)
-  - [We can use const references, pointers etc.](#we-can-use-const-references-pointers-etc)
-  - [Forwarding references](#forwarding-references)
-  - [Multiple template parameters](#multiple-template-parameters)
-  - [Multiple arguments of the same template type](#multiple-arguments-of-the-same-template-type)
-- [Using both explicit and implicit template parameters at the same time](#using-both-explicit-and-implicit-template-parameters-at-the-same-time)
-  - [Typical compiler error messages](#typical-compiler-error-messages)
-- [Function overloading and templates](#function-overloading-and-templates)
-  - [Function overloading with concrete types](#function-overloading-with-concrete-types)
-  - [Function template overloading](#function-template-overloading)
-  - [Be careful overloading on reference types](#be-careful-overloading-on-reference-types)
-- [Full function template specialization and why function overloading is better](#full-function-template-specialization-and-why-function-overloading-is-better)
-  - [First example of why function specialization is confusing](#first-example-of-why-function-specialization-is-confusing)
-  - [Second example of why function specialization is confusing](#second-example-of-why-function-specialization-is-confusing)
-- [Everything happens at compile-time!](#everything-happens-at-compile-time)
-- [Summary](#summary)
-
-<!-- Intro -->
-
-## The basics of writing a function template
-Let's start with a very simple function `PrintDefaultInteger` that just prints a default value of `int` for now ([demo](https://godbolt.org/z/rzofGhzM4)):
-```cpp
-#include <iostream>
-
-void PrintDefaultInteger() { std::cout << int{} << std::endl; }
-
-int main() {
-  PrintDefaultInteger();
-  return 0;
-}
-```
-Running this tiny program will print a `0` just as we expect. But this feels extremely limiting. If we would want to print a default value of more types we would have to write a lot more of these functions!
-
-Function templates provide us with a better way. To declare a function template we prefix a normal function declaration with the keyword `template` followed by a list of [**template parameters**](https://en.cppreference.com/w/cpp/language/template_parameters).
-```C++
-template <{TemplateParameters...}>
-{ReturnType} FunctionName({Arguments...}) {}
-```
-
-## Explicit template parameters
-These template parameters can be used at any place within our function, including its return type, input arguments, or the body of the function. Let us begin with just one of such parameters and rewrite our function `PrintDefaultInteger` into `PrintDefaultValue` function template ([demo](https://godbolt.org/z/j8MKcTz54)):
-```cpp
-#include <iostream>
-
-template <typename T>
-void PrintDefaultValue() { std::cout << T{} << std::endl; }
-
-int main() {
-  PrintDefaultValue<int>();    // T=int
-  PrintDefaultValue<float>();  // T=float
-  return 0;
-}
-```
-Straightaway we notice a couple of changes. Now we have a template parameter `T` that represents any type and we print *its* default value by calling `T{}` <!-- T with curly brackets --> within a `std::cout` statement. We could've done many more things with it and can generally treat it as any other type we used before.
-
-We call our function template from `main` explicitly providing the types `int` and `float` for our template parameter at the call site, so the call looks a bit different from how we normally call functions. This is not always the case with function templates but more on that in a couple of minutes.
-
-When the compiler sees our calls it instantiates the specialization of our function template for the requested types and calls the appropriate specialized functions afterwards. If this is confusing, do look into the previous lecture about [what templates do under the hood](templates_what.md) again.
-
-### Type template parameters
-In our simple example here we specify our template parameter with the word `typename`. Such template parameters are called **type template parameters** because they represent, well, a type. We could've also used the keyword `class` instead but I prefer the `typename` because it indicates that it can stand for any **type**, while `class` seems to suggest that it must be, well, a `class`, or a user-defined type. For whatever reason though this is one of those topics in which there are people with very strong opinions on the matter in either way :wink: <!-- Please tell me in the comments if you have such strong opinions on tha matter :wink: -->
-
-The name of the template parameter `T`, can be chosen arbitrarily but a good rule of thumb is to use a name that is representative of what one wants to do with these types, like `Number` or `Algorithm` or whatever this type should represent. Consequently, we will name them just as any other type in `PascalCase`. That being said you will see `T` used very often, especially in simpler examples, like the ones in this lecture. Speaking of what these type template parameters represent, they represent, well, types and can be used within our function just like any other type. We could create variables of these types or pass them into further function templates etc.
-
-### Non-type template parameters
-Now, apart from type template parameters there are more things we can see after the `template` keyword:
-- non-type template parameters
-- template template parameters (yes, template word is repeated twice)
-- variadic templates
-- concepts (from C++20 on)
-
-For now we focus only on the **non-type template parameters** and we will talk about the rest in the future lectures. Let's illustrate the use of non-type template parameters on a another small example function template `PrintValue` that receives an `int` template parameter and prints its value ([demo](https://godbolt.org/z/84G17e64E)):
-```cpp
-#include <iostream>
-
-template <int kNumber>
-void PrintValue() { std::cout << kNumber << std::endl; }
-
-int main() {
-    PrintValue<42>();
-    PrintValue<23>();
-    return 0;
-}
-```
-In this example, `kNumber` is a non-type template parameter. Such template parameters are just compile-time constants of their respective types and when we run the code it will print the values we pass to our template parameters. Before C++20 they could only be integer-like numbers but from C++20 on they can also be floating point numbers or even strings. Oh, and they can also be `auto` but I wouldn't use `auto` like this here.
-
-Please note, that the value we provide as our template arguments should be available **at compile time**, meaning that it either has to be a compile-time constant or a result of a constant expression, so we cannot use a normal non-const variable when instantiating such a function template:
-<!--
-`CPP_SKIP_SNIPPET`
--->
-```cpp
-// Somewhere in some function
-PrintValue<42>();  // Ok
-constexpr int kLocalNumber{42};
-PrintValue<kLocalNumber>();  // Ok, value of kLocalNumber is available at compile time
-int number{42};
-PrintValue<number>();  // ❌ Not ok, won't compile, number is not a constant expression
-```
-
-### Multiple different template parameters
-For now we've looked at using a single template parameter of each kind. But we can have any number of those in any order. We just have to make sure to provide the explicit template arguments in the same order. Furthermore, the template parameters can have default values. We can specify these default values from the end of the template parameter list although I would recommend not to use default values like these as they can cause quite some confusion once you forget that you set them somewhere deep in your software architecture.
-
-Anyway, as an illustration, for some function template `DoSomething` we can have a number of template parameters in any arbitrary order and provide the template arguments at the call site in the same order ([demo](https://godbolt.org/z/xPh8nG5MP)):
-```cpp
-template <typename T1,          //
-          int kNumber,          //
-          typename T2,          //
-          bool kCondition,      //
-          typename T3,          //
-          typename T4 = float>  // 😱 don't use defaults
-void DoSomething() {}
-
-int main() {
-  // T1=int, kNumber=42, T2=float, kCondition=true, T3=int, T4=int
-  DoSomething<int, 42, float, true, int, int>();
-  DoSomething<double, 23, int, false, float, bool>();
-  // Last template parameter takes default value
-  DoSomething<float, 42, int, true, double>();
-  return 0;
-}
-```
-The first call assigns `T1=int, kNumber=42, T2=float, kCondition=true, T3=int, T4=int` and the last call makes use of the default value of the last template parameter and sets `T4=float`.
-
-## Implicit template parameters
-This is more or less everything we have to know about function templates if they don't have any function parameters. If they _do_ have such parameters, that use the template parameters for their types, then the compiler is able to reason about the template parameters based on the types of these provided function arguments. Which is really handy but complicates the things a little. So let's see what it gives us as well as what pitfalls we should be aware of.
-
-We'll start again with a tiny example. With a normal function `Print` that has a single `int` parameter:
-<!--
-`CPP_SETUP_START`
-#include <iostream>
-$PLACEHOLDER
-int main() {
-  Print(42);
-}
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` tiny/main.cpp
-`CPP_RUN_CMD` CWD:tiny c++ -std=c++17 main.cpp
--->
-```cpp
-void Print(int p) { std::cout << p << "\n"; }
-```
-Nothing magical about this function. We've seen tons of these by now. However, just as before, we want it to be a function template instead because we might want it to work for more than just `int` arguments.
-
-We can achieve this in exactly the same way as what we've just discussed, by introducing the `template` keyword before the function as well as specifying all the necessary template parameters using `typename` or `class` keywords (of which we will just as before use just `typename`). We will also again just print the argument of our function ([demo](https://godbolt.org/z/18hEGTM51)):
-<!--
-`CPP_SETUP_START`
-#include <iostream>
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` tiny_template/print.hpp
--->
-```cpp
-template <typename T>
-void Print(T p) { std::cout << p << std::endl; }
-```
-We can call this function with any type we want:
-<!--
-`CPP_SETUP_START`
-#include "print.hpp"
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` tiny_template/main.cpp
-`CPP_RUN_CMD` CWD:tiny_template c++ -std=c++17 main.cpp
--->
-```cpp
-int main() {
-  Print(42);     // T = int
-  Print(42.42);  // T = double
-  return 0;
-}
-```
-And it will work just as we expect and print the output with the correct types `int` and `double`:
-```
-42
-42.42
-```
-What is important to note here is that the compiler is able to figure out the template parameter to be `int` or `double` purely depending on the function arguments that we provide, without us providing the types explicitly as opposed to what we did before. That being said, we _can_ explicitly provide the type we want. Which makes the following calls equivalent:
-<!--
-`CPP_SETUP_START`
-#include "print.hpp"
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` tiny_template/main_explicit.cpp
-`CPP_RUN_CMD` CWD:tiny_template c++ -std=c++17 main_explicit.cpp
--->
-```cpp
-int main() {
-    Print(42);             // T = int
-    Print<int>(42);        // T = int
-    Print(42.42);          // T = double
-    Print<double>(42.42);  // T = double
-    return 0;
-}
-```
-Now, one small remark here, think about what happens if you change `Print<double>(42.42)` to `Print<int>(42.42)`?
-<!-- I encourage you to write what will happen and why in the comments below this video -->
-
-### We can use const references, pointers etc.
-Now that we are talking about passing arguments to the function, we are still able to do what we learned before and use a constant reference for the input arguments:
-```cpp
-#include <iostream>
-
-template <typename T>
-void Print(const T& p) { std::cout << p << std::endl; }
-
-int main() {
-  Print(42);     // T = int
-  Print(42.42);  // T = double
-  return 0;
-}
-```
-Which prints exactly the same things as before.
-
-### Forwarding references
-After we used a const reference with no issue for our template parameter we might become brave and remember stuff that we discussed when we talked about move semantics. So we might want to use a rref `&&` and an input parameter to our function template.
-
-However, the naïve logic fails us here as when we use a type template parameter with `&&` we are **not** getting an rref, we are getting a **forwarding reference** (also sometimes called a **universal reference**):
-<!--
-`CPP_SKIP_SNIPPET`
--->
-```cpp
-// 🚨 This is a FORWARDING reference, not an rref!
-template <typename T>
-void Print(T&& p);
-```
-
-These behave slightly differently from normal rrefs and allow to use a single function to handle both normal references and rrefs making use of the [`std::forward`](https://en.cppreference.com/w/cpp/utility/forward) function. We will not go deeper into this here and will talk about it separately.
-
-### Multiple template parameters
-We can, however, further extend our printing example in a different way, by adding more template parameters into the mix. Just as before, we just extend the template parameter list to more types ([demo](https://godbolt.org/z/M68qohaPh)):
-<!--
-`CPP_SETUP_START`
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` print_two_params/print.hpp
--->
-```cpp
-#include <iostream>
-
-template <typename T1, typename T2>
-void Print(const T1& p1, T2 p2, T1 p3) {
-    std::cout << p1 << ", "  //
-              << p2 << ", "  //
-              << p3 << std::endl;
-}
-```
-So here, we have two template parameters `T1` and `T2` that we use to specify the types of our function parameters. And, of course, we can run it by either letting the compiler figure out the template parameters on its own or providing them explicitly:
-<!--
-`CPP_SETUP_START`
-#include "print.hpp"
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` print_two_params/main.cpp
-`CPP_RUN_CMD` CWD:print_two_params c++ -std=c++17 main.cpp
--->
-```cpp
-int main() {
-    Print(42, 42.42, 23);               // T1=int, T2=double
-    Print<int, double>(42, 42.42, 23);  // Equivalent to above
-    return 0;
-}
-```
-Which results in printing the expected argument values:
-```
-42, 42.42, 23
-42, 42.42, 23
-```
-
-### Multiple arguments of the same template type
-Actually there is one more thing in this example that we haven't seen before. We have 3 function parameters but only two template parameters. This is to show that there is no need for a 1-to-1 correspondence between their number. This totally makes sense too. Just as we can have a function that accepts 3 integers, we can have a function that accepts 3 different arguments on any **same** type. In our case, we want the first and the last argument of our function to have the same type (albeit first being a `const` reference) and only the second argument to be of the different type.
-
-Now, if we fail to match the types of the first and the last argument by, say, providing a `double` as the last argument as opposed to the expected `int`:
-<!--
-`CPP_SKIP_SNIPPET`
--->
-```cpp
-Print(42, 42.42, 23.23);  // ❌ Won't compile
-```
-We will cause a compilation issue that says something about "template argument deduction/substitution" failing:
-```css
-<source>: In function 'int main()':
-<source>:12:8: error: no matching function for call to 'Print(int, double, double)'
-   12 |     Print(42, 42.42, 23.23);
-      |     ~~~^~~~~~~~~~~~~~~~~~
-<source>:5:6: note: candidate: 'template<class T1, class T2> void Print(const T1&, T2, T1)'
-    5 | void Print(const T1& p1, T2 p2, T1 p3) {
-      |      ^~~
-<source>:5:6: note:   template argument deduction/substitution failed:
-<source>:12:8: note:   deduced conflicting types for parameter 'T1' ('int' and 'double')
-   12 |     Print(42, 42.42, 23.23);
-      |     ~~~^~~~~~~~~~~~~~~~~~
-Compiler returned: 1
-```
-
-## Using both explicit and implicit template parameters at the same time
-You might have already started to wonder - if we have multiple function parameters and multiple template parameters that represent the types, can we provide _some_ types explicitly and let the compiler guess the rest?
-
-And the answer to your question is yes - yes we can! This all gets again slightly more complex but we'll comb through it, no worries! The complications arise because the compiler's ability to guess the types depends partially on the order of the function parameters as well as on the order of the template parameters.
-
-One easy way to think about it is this:
-> 🚨 When we specify the template arguments explicitly, we are specifying them **from left to right**. Then, when the compiler doesn't see any more explicit template parameters, it looks at the provided function arguments and tries to match them to the function parameters hopefully figuring out the rest of the template parameters in the process:
-
-An example of such a situation could be some function called `SomeFunction` (yeah, I have no fantasy) that has a number of template parameters as well as function parameters that make use of some of those template parameters ([demo](https://godbolt.org/z/cK1Evxqfz)):
-```cpp
-template<class One, int kTwo, class Three, class Four, class Five>
-void SomeFunction(Three three, Four four, Five five, Three one_more) {
-  // Some implementation;
-}
-
-int main() {
-  // The types guessed in this call:
-  // One = float
-  // kTwo = 42
-  // Three = double
-  // Four = int
-  // Five = float
-  SomeFunction<float, 42>(42.42, 23, 23.23F, 23.42);
-}
-```
-
-### Typical compiler error messages
-If the compiler fails to figure out the template parameters it will throw an error at us. Just for the sake of example, let's look at a couple of errors that might happen.
-
-If we try to call our function without the last argument:
-<!--
-`CPP_SKIP_SNIPPET`
--->
-```cpp
-// ❌ Won't compile.
-SomeFunction<float, 42>(42.42, 23, 23.23F);
-```
-We will get an error along the lines of "candidate expects 4 arguments, 3 provided":
-```css
-<source>: In function 'int main()':
-<source>:13:26: error: no matching function for call to 'SomeFunction<float, 42>(double, int, float)'
-   13 |   SomeFunction<float, 42>(42.42, 23, 23.23F);
-      |   ~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~
-<source>:2:6: note: candidate: 'template<class One, int kTwo, class Three, class Four, class Five> void SomeFunction(Three, Four, Five, Three)'
-    2 | void SomeFunction(Three three, Four four, Five five, Three one_more) {
-      |      ^~~~~~~~~~~~
-<source>:2:6: note:   candidate expects 4 arguments, 3 provided
-Compiler returned: 1
-```
-
-If we provide a wrong type in the last argument:
-<!--
-`CPP_SKIP_SNIPPET`
--->
-```cpp
-// ❌ Won't compile.
-SomeFunction<float, 42>(42.42, 23, 23.23F, 42);
-```
-We will instead get an error about a "conflicting type for a parameter" as the compiler will see that our type `Three` must be both `double` **and** `int` at the same time to match our template:
-```css
-<source>: In function 'int main()':
-<source>:13:22: error: no matching function for call to 'SomeFunction<float, 42>(double, int, float, int)'
-   13 |   SomeFunction<float, 42>(42.42, 23, 23.23F, 42);
-      |   ~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~
-<source>:2:6: note: candidate: 'template<class One, int kTwo, class Three, class Four, class Five> void SomeFunction(Three, Four, Five, Three)'
-    2 | void SomeFunction(Three three, Four four, Five five, Three one_more) {
-      |      ^~~~~~~~~~~~
-<source>:2:6: note:   template argument deduction/substitution failed:
-<source>:13:22: note:   deduced conflicting types for parameter 'Three' ('double' and 'int')
-   13 |   SomeFunction<float, 42>(42.42, 23, 23.23F, 42);
-      |   ~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~
-Compiler returned: 1
-```
-
-Feel free to experiment with various error messages here to get a feeling for them.
-
-## Function overloading and templates
-Now I want to switch gears and talk about a very important topic - function overloading. We [touched](functions.md#function-overloading---writing-functions-with-the-same-names) upon it before but now that we have templates in the mix, we have to look at the whole thing again.
-
-Long story short, function overloading allows us to have functions with the same name that differ by their parameters and to look up the correct one to call based on the arguments provided at the call site. This way, should we have two different `Print` functions, one that takes a `double` and one that takes an `int` the compiler will still know what to do:
-```cpp
-#include <iostream>
-
-void Print(double number) {
-    std::cout << "double: " << number << std::endl;
-}
-
-void Print(int number) {
-    std::cout << "int: " << number << std::endl;
-}
-
-int main() {
-    Print(42);      // Chooses int
-    Print(42.42);   // Chooses double
-    return 0;
-}
-```
-It sees the types with which we call our `Print` functions and picks the correct one - one that takes `int` when passing `42` and one that takes a `double` when passing `42.42`. So far so good.
-
-### Function overloading with concrete types
-The good news is that if we add a function template into the mix, function overloading still works! To show this, let's replace the first of our functions with a function template ([demo](https://godbolt.org/z/8MKjKx596)):
-```cpp
-#include <iostream>
-
-template <typename T>
-void Print(T number) {
-  std::cout << "T: " << number << "\n";
-}
-
-void Print(int number) {
-  std::cout << "int: " << number << "\n";
-}
-
-int main() {
-  Print(42);     // Still chooses int
-  Print(42.42);  // Chooses template with T=double
-  return 0;
-}
-```
-If we run this code we will see that the call with `42` as input still chooses the normal `Print` function that accepts an `int`, while the call with `42.42` as input now uses our function template. And the main question that you might be having right about now is: "how does a compiler know not to use our function template for `42` too?"
-
-Great question! The reason it prefers a concrete function implementation rather than a template is that the rules of function overloading will **always** prefer a non-template function to template ones, that is if there is an exact match. Please spend some time experimenting with this. Write various functions, see how the compiler always uses a matching concrete implementation rather than a template.
-
-### Function template overloading
-But the overloading story does not end there! We can do so much more with overloading! Just like with any normal type, we can treat our template parameter as just such normal types and largely speaking, if we forget about the `template` prefix along with its template parameters, then the template functions can be overloaded just as any other function can.
-
-Let's see a concrete example, where we will overload our function template `Print` for a case when it accepts pointers and for a case when it accepts a vector of elements ([demo](https://godbolt.org/z/9M1EsGPbz)):
-```cpp
-#include <iostream>
-#include <vector>
-
-template <typename T>
-void Print(T number) {
-    std::cout << number << std::endl;
-}
-
-template <typename T>
-void Print(T* ptr) {
-    std::cout << "pointer: " << *ptr << std::endl;
-}
-
-template <typename T>
-void Print(const std::vector<T>& vec) {
-    std::cout << "vector: ";
-    for (const auto& element : vec) {
-        std::cout << element << " ";
-    }
-    std::cout << std::endl;
-}
-
-int main() {
-    Print(42);
-    int number{23};
-    Print(&number);
-    Print(std::vector{1, 2, 3});
-    return 0;
-}
-```
-And if we run it we will get the output that shows that the compiler is able to pick the correct overload when we pass a pointer or a vector into our `Print` function:
-```
-42
-pointer: 23
-vector: 1 2 3
-```
-
-The intuition behind it (which can actually go quite a long way) is that the compiler will pick that overload which is more specific to the input. So when we pass a vector it actually fits to two of our `Print` functions, as it also fits into the basic implementation. However, the vector overload is much more specific - it only accepts vectors, while the basic function accepts vectors and all other sorts of types. So the compiler considers the vector overload to be more specific and picks it. The same story holds for the pointer.
-
-Now, try to answer yourself, what if we add our `Print(int)` function back into the mix? What will change?
-
-### Be careful overloading on reference types
-Just as we could overload on a pointer type just now, we technically can overload on reference types. The problem is that while a pointer has its own semantics and the compiler is happy to distinguish it from a normal variable, this is not the case for the references.
-
-This results in us not being able to have both the version that accepts `T` and the version that accepts a reference type, say `const T&` ([demo](https://godbolt.org/z/57adWKzYz)):
-<!--
-`CPP_SKIP_SNIPPET`
--->
-```cpp
-template <typename T>
-void Function(T parameter);
-
-template <typename T>
-void Function(const T& parameter);
-
-int main() {
-  Function(42);  // ❌ Won't compile
-}
-```
-If we try to compile the above we're going to get a compilation error along the lines of the call being ambiguous:
-```css
-<source>: In function 'int main()':
-<source>:8:11: error: call of overloaded 'Function(int)' is ambiguous
-    8 |   Function(42);  // ❌ Won't compile
-      |   ~~~~~~~~^~~~
-<source>:2:6: note: candidate: 'void Function(T) [with T = int]'
-    2 | void Function(T parameter);
-      |      ^~~~~~~~
-<source>:5:6: note: candidate: 'void Function(const T&) [with T = int]'
-    5 | void Function(const T& parameter);
-      |      ^~~~~~~~
-Compiler returned: 1
-```
-The reason for this is that there is no way for the compiler to figure out at the call site which version we mean. So we can't use both overloads at the same time. However, in most cases we should be good with using constant references by default. If we need to squeeze more performance by copying small types we will have to go towards partial specialization with classes instead. And for those cases when we need to forward ownership of an object through a function we have the _forwarding reference_ that I mentioned before.
-
-## Full function template specialization and why function overloading is better
-Now one last thing to talk about today is template specialization. Generally speaking it can be of two kinds: **full** and **partial**. However, function templates can only be **fully** specialized so we will only talk about that kind today.
-
-The funny thing is that this kind of specialization basically serves _exactly_ the same purpose as function overloading. And considering that we have this very powerful overloading mechanism for functions that works mostly as we expect it to, the experts in C++ like [Herb Sutter](http://www.gotw.ca/publications/mill17.htm) and by extension [CppCoreGuidelines](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#t144-dont-specialize-function-templates) suggest that we **should not specialize function templates at all** 🚨.
-
-That being said, it is not uncommon to find code that _does_ specialize a function template. To deal with this code we must still know how specialization looks like and more or less how it is _supposed_ to work. So that's what we'll focus on in the remainder of this lecture.
-
-Let us for this go back to the example from before where we had a function `Print` that was accepting any argument:
-```cpp
-#include <iostream>
-
-template <typename T>
-void Print(T number) {
-    std::cout << number << std::endl;
-}
-
-int main() {
-    Print(42);     // T=int
-    Print(42.42);  // T=double
-    return 0;
-}
-```
-Now let's say that we want this function to do something different for some random type, for simplicity let's pick `int`. We already know that we could overload this function and just write a normal function that accepts an `int` but we could also specialize our function instead. In order to specialize a function template, we write `template <>` <!-- template and empty angle brackets --> before the chosen template specialization and then use the types we wanted to in the first place when writing the rest of our function ([demo](https://godbolt.org/z/j46x6Gnao)):
-```cpp
-#include <iostream>
-
-template <typename T>
-void Print(T number) {
-    std::cout << number << std::endl;
-}
-
-// 😱 Not a great idea, overloading is better!
-template <>
-void Print(int number) {
-    std::cout << "int: " << number << std::endl;
-}
-
-int main() {
-    Print(42);     // Picks specialization
-    Print(42.42);  // Picks base function template
-    return 0;
-}
-```
-Here, we provide such a specialization for our `Print` function and this will do the trick. If we pass `42` as an argument into the `Print` function the compiler will pick the specialization, while for any other type of argument it will use the base function template.
-
-### First example of why function specialization is confusing
-So if all seems to be working then what't the issue? Why is it that it is suggested to not specialize function templates?
-
-This topic is quite confusing because of the complicated rules of [template argument deduction](https://en.cppreference.com/w/cpp/language/template_argument_deduction). The best thing I can do is give a couple of examples that look a little counterintuitive to me (and to [many other people](http://stackoverflow.com/questions/25353976) for that matter).
-
-Let us start with an example related to passing objects by `const` references. Assuming we have some relatively large object `Object` we would have the code that does something with it using a function template `Process`. Now we want some special processing for our `Object` so we have a bright idea to specialize the function template `Process` and we use a `const Object&` as an input type because we don't want to copy our object ([demo](https://godbolt.org/z/ejdY7ezzz)):
-```cpp
-#include <iostream>
-
-struct Object {
-    Object() = default;
-    Object(const Object& other) { std::cout << "copy\n"; }
-    // 😱 Omitting the rule of all or nothing for shortness.
-};
-
-template <typename T>
-void Process(T object) {
-    std::cout << "base\n";
-}
-
-// 😱 Not a great idea, overloading is better!
-template <>
-void Process(const Object& object) {
-    std::cout << "specialization\n";
-}
-
-int main() {
-    const Object object;
-    Process(object);
-    return 0;
-}
-```
-Intuitively, looking at the code one could expect that a specialization that fits perfectly to accept our `const Object&` would be called, but unfortunately if we run this code, we get the following output:
-```
-copy
-base
-```
-This indicates to us that the specialization **was not** called and the object was copied because the `Process` base function template was called instead.
-
-The reasons for this are [slightly involved](https://en.cppreference.com/w/cpp/language/template_argument_deduction) but the idea is this: template argument deduction never deduces a reference type, so `T` cannot be a reference type. In our case it deduces `T=Object`, which means that there is a function instantiated from our template `void Process<Object>(Object)` which is the **exact** match to the object that is being passed. This instantiation is better than our hand-written specialization that takes a reference type instead. So the compiler never picks our specialization. At least that's my understanding for now.
-
-We _can_ fix it in a hacky way, by explicitly forcing the compiler to pick the right specialization by changing the call to our function:
-```diff
--Process(object);
-+Process<const Object&>(object);
-```
-With this modification, the correct specialization is called and the object is not copied. But it _is_ quite hacky and still the actual better solution would be to overload the function instead of specializing it:
-```cpp
-#include <iostream>
-
-struct Object {
-    Object() = default;
-    Object(const Object& other) { std::cout << "copy\n"; }
-    // 😱 Omitting the rule of all or nothing for shortness.
-};
-
-template <typename T>
-void Process(T number) {
-    std::cout << "base\n";
-}
-
-void Process(const Object& number) {
-    std::cout << "overload\n";
-}
-
-int main() {
-    const Object object;
-    Process(object);
-    return 0;
-}
-```
-If we run _this_ example we get the expected output:
-```
-overload
-```
-So the object is not copied and our overload is preferred to the general function template.
-
-### Second example of why function specialization is confusing
-Another classical example is the so-called Dimov/Abrahams example. It involves both a function template overload and a function template specialization and has confused a lot of people in its time. Here is how it goes. We have a function template `Process` and its specialization for `int*` parameter. We then create an `int*` variable and pass it as a parameter to a function `Process`:
-```cpp
-#include <iostream>
-
-template <class T>
-void Process(T) { std::cout << "base\n"; }
-
-template <>
-void Process<>(int*) { std::cout << "specialization\n"; }
-
-int main() {
-    int* pointer{};
-    Process(pointer);  // Calls the specialization.
-}
-```
-The compiler sees that there is a template, sees a specialization too and correctly picks it. So we're all good for now.
-
-The confusing parts begin if we now add an overload for any pointer type **after** the specialization (and it is important that it happens after):
-```cpp
-#include <iostream>
-
-template <class T>
-void Process(T) { std::cout << "base\n"; }
-
-template <>
-void Process<>(int*) { std::cout << "specialization\n"; }
-
-template <class T>
-void Process(T*) { std::cout << "base overload\n"; }
-
-int main() {
-    int* pointer{};
-    Process(pointer);  // Now the overload is called instead! 🤯
-}
-```
-If we run _this_ code the **overload** is going to be called, not the specialization!
-
-This is confusing because our specialization is **still the exact match to the type we pass**! So if it happens that we have an overload _after_ we defined a _perfect_ specialization that fits to our passed argument _exactly_, suddenly this overload will be picked?
-
-Now, the key to understanding this behavior is really well described by Herb Sutter in his post [Why Not Specialize Function Templates](http://www.gotw.ca/publications/mill17.htm) and goes as follows. The specializations **do not participate in overload resolution!** Which means that **first** an overload is picked, and only **then** a specialization of **that selected overload** is picked, if any. So, in our case, the `Process(T*)` is a better overload so it is selected. The `Process(int*)` specialization is not selected as it is a specialization of `Process(T)` and not the `Process(T*)`. Anyway, just making it an overload fixes the issue for good:
-```cpp
-#include <iostream>
-
-template <class T>
-void Process(T) { std::cout << "base\n"; }
-
-void Process(int*) { std::cout << "overload\n"; }
-
-template <class T>
-void Process(T*) { std::cout << "base overload\n"; }
-
-int main() {
-    int* pointer{};
-    Process(pointer);  // Selects the correct overload.
-}
-```
-
-By the way, if you made it this far, I have a question for you. What will happen if we move the specialization **below** the overload in the original example?
-```cpp
-#include <iostream>
-
-template <class T>
-void Process(T) { std::cout << "base\n"; }
-
-template <class T>
-void Process(T*) { std::cout << "base overload\n"; }
-
-template <>
-void Process<>(int*) { std::cout << "specialization\n"; }
-
-int main() {
-    int* pointer{};
-    Process(pointer);  // What's called here?
-}
-```
-Write your answers in the comments to the video including the reasoning for what is happening and let's chat about it there!
-
-## Everything happens at compile-time!
-One final thing for today is that everything related to templates happens at compile time. Which has its consequences. One of the errors that I see beginners do (and did it myself some many years ago) is to assume that the compiler cares about the logic inside of the function when it compiles it. The reasoning goes along the way that if we logically guarantee that a code path will never be taken then it's ok for this path to not compile and the compiler should still be fine with this. Unfortunately, this is not the case.
-
-Let us illustrate this with an example. Let's say we have a function `GetLength` that should return lengths of various objects. And it has a couple of template parameters, the non-type enum value representing which type we expect and then the type template parameter that actually represents the type of the function parameter. We then try to write the code that logically seems quite sane:
-<!--
-`CPP_SKIP_SNIPPET`
--->
-```cpp
-#include <string>
-
-enum class Type {
-    kString, kNumber
-};
-
-template <Type kType, class T>
-std::size_t GetLength(const T& param) {
-    if (kType == Type::kString) {
-        return param.size();
-    }
-    return 1;
- }
-
-int main() {
-    std::string s{};
-    GetLength<Type::kString>(s);
-    GetLength<Type::kNumber>(42);
-}
-```
-We have an `if` statement in our function and we pass the `Type::kString` enum value whenever we use our `GetLength` function with string and the `Type::kNumber` value when we use it with a number. It _might_ be reasonable to assume that this code should compile but it does not with an error that complains on our number not having the `size()` method:
-```css
-<source>: In instantiation of 'std::size_t GetLength(const T&) [with Type kType = Type::kNumber; T = int; std::size_t = long unsigned int]':
-<source>:18:29:   required from here
-<source>:10:22: error: request for member 'size' in 'param', which is of non-class type 'const int'
-   10 |         return param.size();
-      |                ~~~~~~^~~~
-Compiler returned: 1
-```
-
-The reason for this is actually quite simple. The compiler does not care about the logic in our function as that logic is **runtime** logic. It cannot assume that just because we did not happen to call all the possible paths through our function nobody else would. In the end, if this function gets compiled into a library and distributed, somebody _might_ call it in a different way, so it has to compile as a whole. And of course it doesn't, because many types don't have the `size()` method.
-
-I've seen this mistake being made countless times so I wanted to explicitly mention it here.
-
-I also have a piece of good news related to this. We now live in the world of modern C++, that is at least C++17, and we have more tools at our disposal to achieve what we want in this situation. What we _could_ do now is to use the `if constexpr` - a compile-time cousin of the normal runtime `if`, which will allow the compiler to actually conditionally compile parts of our function based on the provided parameters ([demo](https://godbolt.org/z/bjeodGf4W)):
-```cpp
-#include <string>
-
-enum class Type {
-    kString, kNumber
-};
-
-template <Type kType, class T>
-std::size_t GetLength(const T& param) {
-    if constexpr(kType == Type::kString) {
-        return param.size();
-    }
-    return 1;
- }
-
-int main() {
-    std::string s{};
-    GetLength<Type::kString>(s);
-    GetLength<Type::kNumber>(42);
-}
-```
-With this change the code compiles and runs as expected. If we're feeling adventurous we could even say that with this example we dipped our feet into compile-time meta programming. 🤘 In reality we don't really need an explicit `enum` for purposes similar to the one in the example and we have more tools for conditional compilation as well as tools for estimating traits about our types but more on that in the future.
-
-## Summary
-If you've made it this far, you are a hero! You're clearly interested in templates and determined enough to listen to me ramble about them for a long time.
-<!-- So why not subscribe to this channel to not miss what's coming? -->
-
-I know this seems like it is a lot of information at once, but trust me it becomes easier with time. Also, we covered not only the basics of using function templates but also what _not_ to do as well as _why_ we shouldn't do it. Which doesn't help making this lecture easy to digest but _will_ make your life easier going forward.
-
-Anyway, as a very short summary, today we covered most of the important parts of function templates. We know how to define them, what template parameters they can accept and how to call these function templates. Furthermore we now know that we can and should overload function templates but we probably should steer away from specializing them.
-
-And honestly, with this information at our disposal, we can go a pretty long way in the world of generic programming.
-
-The next lecture is going to still focus on how to use templates, but now for classes, where there are slightly more details and where specialization actually _does_ play a much more important role than with functions. But if this lecture is firmly placed within our heads we should have little issues figuring out class templates too.
-
-<!-- And if you feel that you still need a refresher on what is it that templates do under the hood, then click on a video over here.
-
-And at this, as always, thanks a lot for your attention, please do not hesitate to write any comment and chat with me in the comments under this video and I'll see you in the next one. Bye! -->
diff --git a/lectures/templates_what.md b/lectures/templates_what.md
deleted file mode 100644
index d1f2e0c..0000000
--- a/lectures/templates_what.md
+++ /dev/null
@@ -1,127 +0,0 @@
-What templates do under the hood
----
-<p align="center">
-  <a href="https://youtu.be/NKvEbPVllRE"><img src="https://img.youtube.com/vi/NKvEbPVllRE/maxresdefault.jpg" alt="Video" align="right" width=50% style="margin: 0.5rem"></a>
-</p>
-
-- [What templates do under the hood](#what-templates-do-under-the-hood)
-- [Compilation process recap](#compilation-process-recap)
-- [Compiler uses templates to generate code](#compiler-uses-templates-to-generate-code)
-- [Hands-on example](#hands-on-example)
-- [Try it out!](#try-it-out)
-- [Compiler is lazy](#compiler-is-lazy)
-- [Summary](#summary)
-
-
-We've talked a little bit about **why** we need templates [in the previous lecture](templates_why.md) but to properly use them we are still missing two important parts of the equation: the **what**, as in what is it that they **actually** do and the **how**, as in how to use them without shooting our leg off.
-
-Today, we focus on the **what**. We will try to build an intuition about what the compiler does when we write templated code so that we all are on the same page that templates are not black magic and the intuition behind what they do is actually easier to understand than many fear it to be.
-
-<!-- Intro -->
-
-## Compilation process recap
-First, let's do a small recap of how our executables are generated. We already talked about the full compilation process [before](headers_and_libraries.md) but the gist is that all of our input source files pass through three stages to become executable files:
-
-<p align="center">
-<img src="images/Compilation_process.png" alt="Video" style="width:100%;max-width:600;">
-</p>
-
-They start by going through the **preprocessor** that unwraps any macros and includes and creates translation units from our source files. These files are then transformed into object files by the **compiler**. Finally, the object files get linked together by the **linker** to form the actual executables.
-
-## Compiler uses templates to generate code
-Everything that we discuss today happens in the **compiler**. So, let's discuss what it does when we use a function or class template.
-
-<!-- The intuition is that -->
-> 🚨 **Intuition:** compiler uses templates to generate code. Which also explains their name. A function, struct or a class template is just that - a template for a normal function, struct or a class.
-
-```mermaid
-graph LR
-  F[Function template] ---> F1[Function 1]
-  F ---> F2[Function 2]
-  F ---> F3[Function 3]
-  F ---> FF[...]
-```
-
-While this **is** a simplified rule of thumb, it serves as a good intuition for what happens to our templates during compilation.
-
-<!-- Use animation -->
-To be slightly more precise, let us illustrate what happens to a simple function template `Foo` during the compilation.
-
-<p align="center">
-<img src="images/Compiler.png" alt="Video" style="width:100%;max-width:600;">
-</p>
-
-Any time the compiler encounters a call that it associates to a template, it **instantiates** a concrete **specialization** of that function, substituting all of its template arguments for the actually used types. Such specializations are then compiled into their binary form and for all means and purposes behave just like normal functions. If we inspect the resulting object file, we will see all of our concrete functions in it!
-
-This, however, means that if we have, say, a function template and use it with many types we will have many specializations of that function compiled into our binary - one for each combination of types it is used with.
-
-## Hands-on example
-For completeness, let's now see how we can check these things by compiling some real code by hand. Well, ok, not by hand but by using a compiler directly from the command line :smile:. For that we will go back to our `maximum.cpp` file from the previous lecture:
-```cpp
-template <typename NumberType>
-NumberType Maximum(NumberType first, NumberType second) {
-  if (first < second) { return second; }
-  return first;
-}
-
-int main() {
-  Maximum(42, 23);
-  Maximum(3.14F, 42.42F);
-  Maximum(3.14, 42.42);
-}
-```
-It defines the `Maximum` function template and uses it with 3 different types. Not the most useful code but a good illustration.
-We can compile it from the terminal in the same way we compiled code into object files before (note the `-c` flag, we are only interested in compilation into an object file):
-```bash
-# Generates maximum.o object file
-c++ -std=c++17 -c maximum.cpp
-```
-This produces an object file `maximum.o`. This object file is just a binary file in [`ELF`](https://en.wikipedia.org/wiki/Executable_and_Linkable_Format) format on Linux, or [`Mach-O`](https://en.wikipedia.org/wiki/Mach-O) format on MacOS, at least by default. But for our purposes, both will equally do. We can inspect these files with the `objdump` command. At this point, we are interested in looking at the part of this file that lists all the available symbols - **a symbols table**. We can read it by providing the appropriate flags to the `objdump` executable (`-t` to get a symbols table and `-C` to get better looking symbol names) and we expect to see all the compiled function names briefly mentioned there:
-<!--
-`CPP_SKIP_SNIPPET`
--->
-```cpp
-λ › objdump -tC maximum.o
-
-maximum.o:      file format mach-o arm64
-
-SYMBOL TABLE:
-...
-00000000000000e0  w    F __TEXT,__text double Maximum<double>(double, double)
-0000000000000098  w    F __TEXT,__text float Maximum<float>(float, float)
-0000000000000050  w    F __TEXT,__text int Maximum<int>(int, int)
-0000000000000000 g     F __TEXT,__text _main
-```
-Now if we look carefully at this output (which I trimmed a little), we see that there is the `_main` symbol for our `main` function as well as three different `Maximum` functions with the types that match those that we used in the `main` function: `int`, `double`, and `float`.
-
-Furthermore, if we run this code in the excellent [compiler explorer](https://godbolt.org/z/9zjoTh7Kq) (link <!--below--> brings you to this same example) we can also see the actual calls to the compiler-generated concrete function specializations. We just have to look for `call` statements in the instructions generated by the compiler. The other details in the output are not too important for us for now.
-
-## Try it out!
-Please do try it all out yourself, so that you're sure that I'm not lying to you :wink: Really, you see that these examples take minutes to write and you can learn so much from them! Don't be afraid to fail, try other functions, try more types, try class and struct templates and call their methods that might have templates of their own! You don't even need to read the documentation at this point, just try what feels like it should work!
-<!-- And if anything doesn't work that you think should work, please feel free to ask any clarifying questions under this video! -->
-
-## Compiler is lazy
-After we've experimented with all of this for a while, we might start noticing something...
-
-> 🚨 Note, and this is very important, that the compiler is **lazy**! Only those specializations are generated that are **actually used**!
-
-If we didn't use the `Maximum` function it would not have been compiled at all! Now if we think about it for a minute it becomes clear why this is so --- looking at the `Maximum` function template itself, in isolation, the compiler doesn't know which types it will be used with!
-<!-- Add a travolta meme -->
-
-Technically, it could be any type we want! So the compiler cannot (and should not) compile the code for **all** the types it knows about. There are multiple reasons for this:
-1. It would take ages --- it would need to compile **a lot** of code!
-2. The binary size would be huge --- it would need to contain all that binary code!
-3. It might still not be enough as maybe we will give out our template function as part of a header-only library and we simply don't know which types it might be used with!
-
-This is actually something that plays a lead role in making splitting templated code between header and source files confusing for beginners. We'll talk about this very soon, but if you understand everything that we talked about here, you should face no issues there too, when the time comes.
-
-## Summary
-Ok, time for a short recap and after it we can be sure that we know the most important bits about what is it that the compiler does to our templated code.
-
-Long story short, the compiler generates concrete functions, classes or structs for any template instantiation whenever it encounters such instantiations in the code. It then treats these as any other ordinary functions, classes or structs and proceeds by compiling them into binary object files. From this point on these symbols in the object files behave just like any normal class or function and those we already know about :wink:
-
-And that's it, conceptually, this is everything that happens under the hood when we use templates. Now, there are a lot of intricate details on which exact concrete binary code gets generated depending on how we declare and define our templates and we will cover this in the next video!
-
-<!-- Until then, please feel free to watch the video about why we might want to use templates in the first place if you haven't already!
-
-And at this, time to end this video, so, as always, thanks for watching and see you in the next one! Bye! -->
diff --git a/lectures/templates_why.md b/lectures/templates_why.md
deleted file mode 100644
index 53dd01e..0000000
--- a/lectures/templates_why.md
+++ /dev/null
@@ -1,205 +0,0 @@
-Why use templates?
----
-
-<p align="center">
-  <a href="https://youtu.be/1Mrt1NM3KnI"><img src="https://img.youtube.com/vi/1Mrt1NM3KnI/maxresdefault.jpg" alt="Video" align="right" width=50% style="margin: 0.5rem"></a>
-</p>
-
-- [Why use templates?](#why-use-templates)
-- [Templates provide abstraction and separation of concerns](#templates-provide-abstraction-and-separation-of-concerns)
-- [Function templates](#function-templates)
-- [Class and struct templates](#class-and-struct-templates)
-- [Generic algorithms and design patterns](#generic-algorithms-and-design-patterns)
-- [Zero runtime cost (almost)](#zero-runtime-cost-almost)
-- [Compile-time meta-programming](#compile-time-meta-programming)
-- [Summary](#summary)
-
-
-[Templates](https://en.cppreference.com/w/cpp/language/templates) are definitely one of the features that make C++ so popular and powerful. They provide an extremely versatile mechanism to write truly generic code and allow building meaningful abstractions only paying for these benefits with some compilation time and little to no run time!
-
-However, with great power come long error messages so historically, templates were met with fear and anxiety by the beginners in C++. Which is a pity because I believe that templates are **the** way to write modern C++ code, especially with concepts available in C++20 and beyond.
-
-And while we will talk about concepts at some point, I would like to start with templates as an important building block in our C++ understanding. Because this is quite a big topic, I decided to split it into the **why**, **what** and **how** parts:
-- In this lecture we talk about **why** we might want to use templates in the first place
-- Next we'll talk about [**what** happens under the hood](templates_what.md) when we use them
-- And finally we'll talk about all the details in a lecture about **how** to write templated code and stay sane.
-
-<!-- Intro -->
-
-## Templates provide abstraction and separation of concerns
-Ok, so, to start I'll try to squeeze the answer to the question **why use templates** into an overly generic statement that should provide a very short overview:
-> 🚨 Templates are used to abstract algorithms (or logic) away from a concrete implementation, which improves both code readability and reusability, allowing to repeat ourselves less and separate the concerns better. Templates allow to do all of this at compile time having little to no runtime impact[*](https://www.youtube.com/watch?v=rHIkrotSwcc).
-
-Such abstractions can take various forms of different complexity, varying on **what** we abstract away and **how** we create our abstractions. These range from simply abstracting away the type for some simple algorithms or containers to a full fledged abstraction of a whole algorithm conditioned on some compile-time computed logic.
-
-And you've already seen (and used) templates in this very course! Remember `std::array`, `std::vector`, `std::map`, and other STL containers? Or maybe a function like `std::max`? Well, they are all implemented as class and function templates which allows them to store and process almost any type you throw at them. Oh, and they all are part of STL, which stands for **S**tandard **T**emplate **L**ibrary :wink:
-
-Anyway, one thing is to know that _somebody_ can write function and class templates and another thing is to know that _we_ can do it ourselves, so let's have a look at a couple of simple examples. Again, today, I just want to illustrate the purpose of templates, not talk about all the possible details. That lecture comes shortly after.
-
-## Function templates
-The first, somewhat classical use-case, allows us to abstract our function logic away from the actual argument types. For example, think about a `Max` function that must compute a maximum of two numbers. These numbers can of course be of various types, like `int`, `float`, `double` or any other type for which `Max` makes sense. Naïvely, without using templates, we would need to explicitly implement this function for any type we want to use with it:
-```cpp
-// Not a great idea to repeat the code so many times! 😱
-// Imagine changing the implementation later!
-int Max(int first, int second) {
-  if (first < second) { return second; }
-  return first;
-}
-float Max(float first, float second) {
-  if (first < second) { return second; }
-  return first;
-}
-double Max(double first, double second) {
-  if (first < second) { return second; }
-  return first;
-}
-// And so on for any other type we care about 😱
-
-int main() {
-  Max(42, 23);
-  Max(3.14F, 42.42F);
-  Max(3.14, 42.42);
-}
-```
-<img src="images/templates_meme.jpg" alt="Meme about writing code" align="right" width=20% style="margin: 0.5rem">
-
-<!-- Animate rename to Maximum one by one -->
-So if we want to use it with `int`, `float`, and `double`, we would need to copy our code three times. This number, of course, grows with the number of types we want to use. Due to [function overloading](functions.md#function-overloading---writing-functions-with-the-same-names) that we touched upon before, the compiler will be able to pick the correct function for each of our function calls. But think what happens if we ever need to change the name of this function, say to `Maximum`. We would have to make sure that we change it everywhere and don't miss a single implementation. And while in this case it looks easy, believe me that these type of actions are one of the major sources of errors in the real-world big projects. I, for one, don't trust myself on this. Whenever there are manual actions to be taken, I can guarantee you that I will make a mistake, so it would be cool to reduce such manual repetitions and let something else do our work for us.
-<!-- Show the meme -->
-
-<!-- Animate by removing code from before -->
-It turns out that this is one of those typical situations when templates come to the rescue! Look how neatly we can rewrite it all using the keyword `template`:
-```cpp
-// Works for any type as long as the implementation compiles ✅
-template <typename NumberType>
-NumberType Maximum(NumberType first, NumberType second) {
-  if (first < second) { return second; }
-  return first;
-}
-
-int main() {
-  Maximum(42, 23);          // int
-  Maximum(3.14F, 42.42F);   // float
-  Maximum(3.14, 42.42);     // double
-}
-```
-Let's unpack what we see. The body of the function looks just as before. The only difference is the part **before** the function:
-<!--
-`CPP_SKIP_SNIPPET`
--->
-```cpp
-template <typename NumberType>
-```
-This is what makes this a **function template**. The `typename NumberType` is a [template parameter](https://en.cppreference.com/w/cpp/language/template_parameters) that represents a type to be used in our function, thus the keyword `typename`, although we could also have used an older `class` word here. We called this type `NumberType` but this name is just for our convenience, the compiler does not care about it. It just knows that this is a definition of a function template `Maximum` with two function parameters of the same type `NumberType` which in this case is guessed by the compiler based on the types of the provided arguments. And as long as the code inside of this function compiles for any given type `NumberType` it will do what it is supposed to do. So now, when we call our `Maximum` function with parameters of `int`, `float`, or `double` it just magically works! Neat, right? And by the way, because `NumberType` represents a type, we will name it as we name our types, using `PascalCase` following the [Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html#General_Naming_Rules).
-
-At this point, I just want to make sure that we are on the same page about templates allowing us to write the code once that will work for many different types as long as the logic inside of the function compiles. We will talk about all of the details later.
-
-## Class and struct templates
-The same story holds for class and struct templates too. As an example, think about the `std::array` class that we touched upon before. For such a class, we want to be able to store **any** type of data in it and we don't want to have a separate implementation for all of those situations:
-<!--
-`CPP_SETUP_START`
-#include <cstddef>
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` array/main.cpp
-`CPP_RUN_CMD` CWD:array c++ -std=c++17 main.cpp
--->
-```cpp
-template <typename UnderlyingType, std::size_t kSize>
-struct Array {
-  // Some implementation
-};
-
-int main() {
-  Array<int, 42> int_array;
-  Array<double, 23> double_array;
-}
-```
-<!-- Talk about naming -->
-I'll skip the implementation here as it has no influence on the concept we're talking about here. Note how we have two template parameters here instead of one. The first one, `UnderlyingType` is a type and the second one, `kSize`, is a `std::size_t` number. There can be any number of such parameters, but more on that later. Oh, and we name the number-like template parameters just like constants: in `CamelCase` with the prefix `k`, following the [Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html#General_Naming_Rules).
-
-## Generic algorithms and design patterns
-Anyway, apart from these "simple" abstractions, templates can be used for so much more, like implementing abstract design ideas in a composable and separable fashion. Ideally, our functions and classes should operate on a "need to know" basis - as long as the inputs conform to their expectations, they shouldn't care what these inputs do in the rest of their lives. Just to give you one concrete example, we could think about an `Image` class, just like the one that we implemented in this course before, and implement a method `Save` for this class that takes in the templated `SavingStrategy` instance which will take care of the actual saving logic. As long as such a `SavingStrategy` has the appropriate `Save` method, we don't care about anything else it does:
-<!--
-`CPP_SETUP_START`
-#include <vector>
-using Color = int;
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` image/image.hpp
--->
-```cpp
-class Image {
- public:
-  // Note how a member function can also be a template function
-  template <typename SavingStrategy>
-  void Save(const SavingStrategy& strategy) const {
-    strategy.Save(pixels_);
-  }
-  // Skipping any other class details for the sake of example.
-
- private:
-  std::vector<Color> pixels_{};
-};
-```
-This way we could have two (or more) different classes, say `JpegSavingStrategy` and `PngSavingStrategy` that would implement their own logic to save an array of pixels to disk and the reason we want this is that as long as they have their own `Save` method, the `Image` class would need to have no knowledge about how such saving actually is done. Which means that we would not need to touch our `Image` class should we want to change how the images are stored to disk at some point in the future.
-
-For completeness, let's have a look at an example implementation of one of these strategies and see how it ties into our new `Image` class. I will omit the actual saving to disk as this is not important to understand the topic that we have at hand right now. The main thing to note here is that our strategy will have the `Save` method that is required for it to be eligible for use with our `Image` class. It also has a constructor to allow creating such a strategy:
-<!--
-`CPP_SETUP_START`
-#include "image.hpp"
-#include <filesystem>
-#include <vector>
-$PLACEHOLDER
-`CPP_SETUP_END`
-`CPP_COPY_SNIPPET` image/main.cpp
-`CPP_RUN_CMD` CWD:image c++ -std=c++17 main.cpp
--->
-```cpp
-class JpegSavingStrategy {
-  public:
-    JpegSavingStrategy(const std::filesystem::path& path) : path_{path} {}
-
-    void Save(const std::vector<Color>& pixels) const {
-      // Logic to save pixels to path_ as jpeg data.
-    }
-
-  private:
-    std::filesystem::path path_{};
-};
-
-int main() {
-  Image image{}; // Somehow create an image.
-  image.Save(JpegSavingStrategy{"image.jpg"});
-  return 0;
-}
-```
-While maybe not the most elegant design it still separates the concerns of these classes while maintaining code readability and having little to no runtime overhead. Here, we create a `JpegSavingStrategy` object and pass it into our `Image` class, so the image does not need to know anything about such a strategy, including how it was created, apart from the fact that it has a method `Save`. And this check happens at compile time which allows us to catch the inevitable bugs early!
-
-As a side note, I use the word "strategy" here not by chance. Such a design loosely follows a "Strategy" software design pattern if we opt to use templates. As always with C++, there are many other ways to implement similar behaviors with or without templates. One example of introducing similar abstractions without using patterns would by embracing **O**bject **O**riented **P**rogramming (OOP) and we will talk about this extensively later, but there are other trade-offs to be made there and I believe that in modern C++ we embrace templates more and more over time, especially when we move towards using concepts in C++20.
-
-
-## Zero runtime cost (almost)
-There is one huge benefit for designing these abstractions using template-like mechanism - **runtime**. All of the work that templates do happens at compile time. So, if we **can** fix our abstract code design at compile time, by using templates it is very likely that we reduce the runtime of our code in comparison to other design paradigms. Or at least we don't introduce a huge runtime overhead.
-
-<img src="images/template_mistakes_meme.jpg" alt="Meme about template mistakes" align="right" width=20% style="margin: 0.5rem">
-
-Speaking of stuff that happens at compilation time, using templates rigorously makes sure that we catch most of our design and logic bugs also at compile time, even before our code gets to run, let alone shipped to any users! If you ask me, I'd say that compile-time errors are the best errors to be had.
-
-In the next lecture we're going to see **why** templates work at compile time and dig into what it is that enables this near-zero runtime overhead by looking at **what** happens under the hood when we use them.
-
-One final thing to mention is that it's not all perfect as we do pay for all of the above benefits with some design rigidity and with the compilation times which might become problematic for bigger projects. There are ways to mitigate this to a degree that we will discuss in one of the follow-up lectures too.
-
-## Compile-time meta-programming
-Finally, digging even deeper into the compile-time design that templates enable, we can also do really advanced things, like compile-time meta-programming, but I won't talk about it much at the moment because this is a bit of an advanced and maybe even somewhat esoteric topic.
-
-But, just to not leave you hanging, it allows us to create complex logic that happens **during compilation**, allowing to further reduce the runtime of our programs. Think about computing lots of values at compile time and storing them into a table that is then available at runtime. Or allowing to dramatically reduce code duplication while designing a very generic smart container all while introducing hard type safety without paying a runtime cost for it. There are many examples where this comes handy.
-
-Likewise, there are many dedicated keywords in this topic like SFINAE (a C++ paradigm that allows conditional compilation), type traits (that allow to tell certain things about types, like `std::is_same` that allows to compare types between each other etc.) and many more but these do add complexity to our code and the resulting code is generally less readable, so I'll leave it for some future time as it probably warrants a separate lecture in the future and I will have to think about good examples really hard. That being said, I believe that these advanced features have paved a way to the C++20 concepts which are much more pleasant to use and we will definitely talk about those too.
-
-## Summary
-Anyway, even without going into the details, I hope that it was easy to grasp why we would want to have a mechanism like this. I also hope, that looking at those functions and classes the syntax was more or less self explanatory. If you understand the gist of what we've just talked about, then you understand why templates are so important.
-
-So stay tuned for what comes next, as we're about to also talk about **what** the templates do under the hood, which is very important to understand to avoid any confusion when using them as well as **how** we can use templates, including most of the details on their usage that we might need in our day to day C++ life.
-
-<!-- Thanks for watching as always and see you in the next one! Bye! -->
diff --git a/readme.md b/readme.md
index b947299..fc12331 100644
--- a/readme.md
+++ b/readme.md
@@ -1,768 +1,106 @@
-# Lectures and projects for the [C++ for yourself](https://youtube.com/playlist?list=PLwhKb0RIaIS1sJkejUmWj-0lk7v_xgCuT) course
+# Lectures and homeworks
+
+
+This is a list of lectures from the [C++ for yourself](https://www.youtube.com/Codeforyourself) channel.
+
+## Basic C++ syntax
+
+- <details>
+  <summary>
+  <code>1.1</code>
+  Hello world program dissection: 
+  </summary>
+
+  [`[video]`](https://youtu.be/t2h1geGSww4)
+  [`[slides]`](lectures/1.1_hello_world_dissection.md)
+
+  - First keywords
+  - What brackets mean
+  - What do different signs mean
+  - Intro to "scopes"
+  - Intro to functions
+  - Intro to includes
+  </details>
+- <details>
+  <summary><code>Homework 1</code>: hello world program</summary>
+
+  [`[homework]`](homeworks/homework_1/homework.md)
+
+  - Write a simple program that prints `Hello World!`
+  - Learn to compile and run simple programs
+  </details>
+- <details>
+  <summary>
+  <code>1.2</code>
+  Variables of fundamental types: 
+  </summary>
+
+  [`[video]`](https://youtu.be/0z0gvv_Tb_U)
+  [`[slides]`](lectures/1.2_cpp_basic_types_and_variables.md)
+
+  - How to create variables of fundamental types
+  - Naming variables
+  - Using `const`, `constexpr` with variables
+  - References to variables
+  </details>
+- <details>
+  <summary>
+  <code>1.3</code>
+  Namespaces for variables: 
+  </summary>
+
+  [`[video]`](https://youtu.be/cP2IDg4_BRk)
+  [`[slides]`](lectures/1.3_namespaces_using.md)
+
+  - Namespaces with variables
+  - The word `using` with variables
+  </details>
+- <details>
+  <summary>
+  <code>1.4</code>
+  Input/output streams: 
+  </summary>
+
+  [`[video]`](https://youtu.be/hy3eOpZmxbY)
+  [`[slides]`](lectures/1.4_io_streams.md)
+
+  - `std::cout`, `std::cerr`, `std::cin`
+  </details>
+- <details>
+  <summary>
+  <code>1.5</code>
+  Sequence and utility containers: 
+  </summary>
+
+  [`[video]`](https://youtu.be/dwkSVkGsvFk)
+  [`[slides]`](lectures/1.5_more_useful_types.md)
+
+  - Sequence containers: `std::array`, `std::vector`, their usage and some caveats
+  - Pair container: `std::pair`
+  - Strings from STL: `std::string`
+  - Convertion to/from strings: `to_string`, `stoi`, `stod`, `stof`, etc.
+  - Aggregate initialization
+  </details>
+- <details>
+  <summary>
+  <code>1.6</code>
+  Associative containers: 
+  </summary>
+
+  [`[video]`](https://youtu.be/TCu76SYmVCg)
+  [`[slides]`](lectures/1.6_associative_containers.md)
+
+  - `std::map` and `std::unordered_map`
+  - Touch up on `std::set` and `std::unordered_set`
+  </details>
+- <details>
+  <summary><code>Homework 2</code>: fortune teller program</summary>
+
+  [`[homework]`](homeworks/homework_2/homework.md)
+
+  - Write a program that tells your C++ fortune
+  - It reads and writes data from and to terminal
+  - Stores and accesses these data in containers
+  </details>
 
-<img alt="Icon" align="right" width=150 src="https://github.com/user-attachments/assets/2f72be25-d8b5-4bc8-ade5-c7167ac41324">
 
-![Build status](https://img.shields.io/github/actions/workflow/status/cpp-for-yourself/supplementary-materials/action.yml?branch=main&label=Link%20and%20code%20validation&style=for-the-badge)
-[![YouTube Channel Views](https://img.shields.io/youtube/channel/views/UCRm39hwBxsX-8yj2xs3OJjQ?style=for-the-badge&label=YouTube%20views)](https://www.youtube.com/code-for-yourself)
-![Visitors](https://api.visitorbadge.io/api/visitors?path=code-for-yourself%2Fcode-for-yourself&labelColor=%23697689&countColor=%23263759)
-
-This repository is a collection of Markdown scripts used for all the videos in the [C++ for yourself](https://youtube.com/playlist?list=PLwhKb0RIaIS1sJkejUmWj-0lk7v_xgCuT) course.
-
-These can be used to follow-along the video or as a standalone learning material.
-
-## 🙏 Support this work
-
-[![GitHub Sponsors](https://img.shields.io/github/sponsors/niosus?style=for-the-badge&logo=github&label=Sponsor%20on%20github)](https://github.com/sponsors/niosus)
-[![Audible trial](https://img.shields.io/badge/Audible_free_trial-orange?style=for-the-badge&logo=audible&logoColor=white&logoSize=auto&link=https%3A%2F%2Fwww.audibletrial.com%2FCodeForYourself)](https://www.audibletrial.com/CodeForYourself)
-[![Amazon affiliate links](https://img.shields.io/badge/amazon_affiliate_links-orange?style=for-the-badge&logo=amazon&logoColor=white&logoSize=auto&color=black)](https://github.com/cpp-for-yourself/sponsor/blob/main/amazon.md)
-
-
-Please remember that there is a human behind all of this work. I write scripts, create animations, record and edit videos at night after a full-time work day. It is at times hard.
-But _you_ can make it easier. Here is what you can do:
-
-- 💶 Become a [**sponsor on GitHub**](https://github.com/sponsors/niosus)!
-- 💸 Can't support monetarily?
-  + 👍 **Like** the videos and **watch them to the end**!
-  + 💬 **Leave comments** on YouTube!
-  + 📢 **Spread the word** among your friends!
-- 🤬 Don't like something? 🗣️ **Talk to me about it!** I am always eager to improve.
-
-## :bulb: How to follow this course
-
-The course is designed to be consumed from top to bottom, so start at the beginning and you will always have enough knowledge for the next video.
-
-That being said, I aim to leave links in the videos so that one could watch them out of order without much hassle.
-
-Enjoy! 😎
-
-## 📕 C++ for yourself lectures
-
-<details>
-<summary>
-Hello world program dissection
-</summary>
-
-----------------------------------------------------------
-[![Video thumbnail](https://img.youtube.com/vi/t2h1geGSww4/maxresdefault.jpg)](https://youtu.be/t2h1geGSww4)
-
-[Lecture script](lectures/hello_world_dissection.md)
-- First keywords
-- What brackets mean
-- What do different signs mean
-- Intro to "scopes"
-- Intro to functions
-- Intro to includes
-----------------------------------------------------------
-</details>
-
-<details>
-<summary><code>Project</code>: hello world program</summary>
-
-----------------------------------------------------------
-[Homework script](homeworks/homework_1/homework.md)
-- Write a simple program that prints `Hello World!`
-- Learn to compile and run simple programs
-----------------------------------------------------------
-</details>
-
-<details>
-<summary>
-Variables of fundamental types
-</summary>
-
-----------------------------------------------------------
-[![Video thumbnail](https://img.youtube.com/vi/0z0gvv_Tb_U/maxresdefault.jpg)](https://youtu.be/0z0gvv_Tb_U)
-
-[Lecture script](lectures/cpp_basic_types_and_variables.md)
-- How to create variables of fundamental types
-- Naming variables
-- Using `const`, `constexpr` with variables
-- References to variables
-----------------------------------------------------------
-</details>
-
-<details>
-<summary>
-Namespaces for variables
-</summary>
-
------------------------------------------------------------
-[![Video thumbnail](https://img.youtube.com/vi/cP2IDg4_BRk/maxresdefault.jpg)](https://youtu.be/cP2IDg4_BRk)
-
-[Lecture script](lectures/namespaces_using.md)
-- Namespaces with variables
-- The word `using` with variables
-----------------------------------------------------------
-</details>
-
-<details>
-<summary>
-Input/output streams
-</summary>
-
-----------------------------------------------------------
-[![Video thumbnail](https://img.youtube.com/vi/hy3eOpZmxbY/maxresdefault.jpg)](https://youtu.be/hy3eOpZmxbY)
-
-[Lecture script](lectures/more_useful_types.md)
-- `std::cout`, `std::cerr`, `std::cin`
-----------------------------------------------------------
-</details>
-
-<details>
-<summary>
-Sequence and utility containers
-</summary>
-
-----------------------------------------------------------
-[![Video thumbnail](https://img.youtube.com/vi/dwkSVkGsvFk/maxresdefault.jpg)](https://youtu.be/dwkSVkGsvFk)
-
-[Lecture script](lectures/more_useful_types.md)
-- Sequence containers: `std::array`, `std::vector`, their usage and some caveats
-- Pair container: `std::pair`
-- Strings from STL: `std::string`
-- Conversion to/from strings: `to_string`, `stoi`, `stod`, `stof`, etc.
-- Aggregate initialization
-----------------------------------------------------------
-</details>
-
-<details>
-<summary>
-Associative containers
-</summary>
-
-----------------------------------------------------------
-[![Video thumbnail](https://img.youtube.com/vi/TCu76SYmVCg/maxresdefault.jpg)](https://youtu.be/TCu76SYmVCg)
-
-[Lecture script](lectures/associative_containers.md)
-- `std::map` and `std::unordered_map`
-- Touch up on `std::set` and `std::unordered_set`
-----------------------------------------------------------
-</details>
-
-<details>
-<summary><code>Project</code>: fortune teller program</summary>
-
-----------------------------------------------------------
-[Homework script](homeworks/homework_2/homework.md)
-- Write a program that tells your C++ fortune
-- It reads and writes data from and to terminal
-- Stores and accesses these data in containers
-----------------------------------------------------------
-</details>
-
-<details>
-<summary>
-Control structures
-</summary>
-
-----------------------------------------------------------
-[![Video thumbnail](https://img.youtube.com/vi/jzgTxosgGIA/maxresdefault.jpg)](https://youtu.be/jzgTxosgGIA)
-
-[Lecture script](lectures/control_structures.md)
-- `if`, `switch` and ternary operator
-- `for`, `while` and `do ... while`
-----------------------------------------------------------
-</details>
-
-<details>
-<summary>
-Random number generation
-</summary>
-
-----------------------------------------------------------
-[![Video thumbnail](https://img.youtube.com/vi/IUoqMTGGo6k/maxresdefault.jpg)](https://youtu.be/IUoqMTGGo6k)
-
-[Lecture script](lectures/random_numbers.md)
-- What are random numbers
-- How to generate them in modern C++
-- Why not to use `rand()`
-----------------------------------------------------------
-</details>
-
-<details>
-<summary><code>Project</code>: the guessing game</summary>
-
-----------------------------------------------------------
-[![Video thumbnail](https://img.youtube.com/vi/TYs_xwihCNc/maxresdefault.jpg)](https://youtu.be/TYs_xwihCNc)
-
-[Homework script](homeworks/homework_3/homework.md)
-- A program that generates a number
-- The user guesses this number
-- The program tells the user if they are above or below with their guess (or if they've won)
-----------------------------------------------------------
-</details>
-
-<details>
-<summary>
-Compilation flags and debugging
-</summary>
-
-----------------------------------------------------------
-[![Video thumbnail](https://img.youtube.com/vi/NTlcDv7W2-c/maxresdefault.jpg)](https://youtu.be/NTlcDv7W2-c)
-
-[Lecture script](lectures/compilation_debugging.md)
-- Useful compilation flags
-- Debugging a program with:
-  - Print statements
-  - `lldb` debugger
-----------------------------------------------------------
-</details>
-
-<details>
-<summary>
-Functions
-</summary>
-
-----------------------------------------------------------
-[![Video thumbnail](https://img.youtube.com/vi/RaSw0g2aPig/maxresdefault.jpg)](https://youtu.be/RaSw0g2aPig)
-
-[Lecture script](lectures/functions.md)
-- What is a function
-- Declaration and definition
-- Passing by reference
-- Overloading
-- Using default arguments
-----------------------------------------------------------
-</details>
-
-<details>
-<summary>
-Enumerations
-</summary>
-
-----------------------------------------------------------
-[![Video thumbnail](https://img.youtube.com/vi/4kZyQ-TwH00/maxresdefault.jpg)](https://youtu.be/4kZyQ-TwH00)
-
-[Lecture script](lectures/enums.md)
-- What are `enums`
-- How to use them?
-- Why not to use old style `enums`
-----------------------------------------------------------
-</details>
-
-<details>
-<summary>
-Libraries and header files
-</summary>
-
-----------------------------------------------------------
-[![Video thumbnail](https://img.youtube.com/vi/Lxo8ftglwXE/maxresdefault.jpg)](https://youtu.be/Lxo8ftglwXE)
-
-[Lecture script](lectures/headers_and_libraries.md)
-- Different types of libraries
-  - Header-only
-  - Static
-  - Dynamic
-- What is linking
-- When to use the keyword `inline`
-- Some common best practices
-----------------------------------------------------------
-</details>
-
-<details>
-<summary>
-Build systems introduction
-</summary>
-
-----------------------------------------------------------
-[![Video thumbnail](https://img.youtube.com/vi/kbk4DphsYPU/maxresdefault.jpg)](https://youtu.be/kbk4DphsYPU)
-
-[Lecture script](lectures/build_systems.md)
-- Intro to build systems
-- Build commands as a script
-- Build commands in a `Makefile`
-----------------------------------------------------------
-</details>
-
-<details>
-<summary>
-CMake introduction
-</summary>
-
-----------------------------------------------------------
-[![Video thumbnail](https://img.youtube.com/vi/UH6F6ypdYbw/maxresdefault.jpg)](https://youtu.be/UH6F6ypdYbw)
-
-[Lecture script](lectures/cmake.md)
-- Build process with CMake
-- CMake Variables
-- Targets and their properties
-- Example CMake project
-----------------------------------------------------------
-</details>
-
-<details>
-<summary>
-Using GoogleTest framework for testing code
-</summary>
-
-----------------------------------------------------------
-[![Video thumbnail](https://img.youtube.com/vi/pxJoVRfpRPE/maxresdefault.jpg)](https://youtu.be/pxJoVRfpRPE)
-
-[Lecture script](lectures/googletest.md)
-- Explain what testing is for
-- Explain what testing is
-- Show how to download and setup googletest
-- Show how to write a simple test
-----------------------------------------------------------
-</details>
-
-<details>
-<summary>Installing projects and using <code>find_project</code> with CMake</summary>
-
-----------------------------------------------------------
-[![Video thumbnail](https://img.youtube.com/vi/OMx3cZj_hoo/maxresdefault.jpg)](https://youtu.be/OMx3cZj_hoo)
-
-- [Disclaimer](lectures/cmake_install.md#disclaimer)
-- [What does `find_package` do?](lectures/cmake_install.md#what-does-find_package-do)
-  - [Search modes](lectures/cmake_install.md#search-modes)
-    - [Module mode](lectures/cmake_install.md#module-mode)
-    - [Config mode](lectures/cmake_install.md#config-mode)
-  - [How do the config files look like?](lectures/cmake_install.md#how-do-the-config-files-look-like)
-  - [What are the export files?](lectures/cmake_install.md#what-are-the-export-files)
-  - [Summary of reusing targets](lectures/cmake_install.md#summary-of-reusing-targets)
-- [How to make `core_project` available to `dependent_project`](lectures/cmake_install.md#how-to-make-core_project-available-to-dependent_project)
-  - [Project skeleton for `core_project`](lectures/cmake_install.md#project-skeleton-for-core_project)
-  - [Installing a package](lectures/cmake_install.md#installing-a-package)
-    - [1. Copying headers](lectures/cmake_install.md#1-copying-headers)
-    - [2. Copying binaries](lectures/cmake_install.md#2-copying-binaries)
-    - [3. Creating export files](lectures/cmake_install.md#3-creating-export-files)
-    - [4. Creating config files](lectures/cmake_install.md#4-creating-config-files)
-- [How to use the installed package](lectures/cmake_install.md#how-to-use-the-installed-package)
-- [Summary](lectures/cmake_install.md#summary)
-
-----------------------------------------------------------
-</details>
-
-<details>
-<summary><code>Project</code>: string processing library</summary>
-
-----------------------------------------------------------
-[![Video thumbnail](https://img.youtube.com/vi/f0x2qcFgu5o/maxresdefault.jpg)](https://youtu.be/f0x2qcFgu5o)
-
-[Homework script](homeworks/homework_4/homework.md)
-- You will write library that allows to split and trim strings
-- You will learn how to:
-  - Write a CMake project from scratch
-  - Write your own libraries
-  - Test them with googletest
-  - Link them to binaries
-----------------------------------------------------------
-</details>
-
-<details>
-<summary>
-Simple custom types with classes and structs
-</summary>
-
-----------------------------------------------------------
-[![Video thumbnail](https://img.youtube.com/vi/IijP--Xf5kQ/maxresdefault.jpg)](https://youtu.be/IijP--Xf5kQ)
-
-[Lecture script](lectures/classes_intro.md)
-- Explain why the classes are needed
-- Implement an example game about a car
-- Define classes and structs more formally
-----------------------------------------------------------
-</details>
-
-<details>
-<summary>
-Raw pointers
-</summary>
-
-----------------------------------------------------------
-[![Video thumbnail](https://img.youtube.com/vi/pptRG345jnU/maxresdefault.jpg)](https://youtu.be/pptRG345jnU)
-
-[Lecture script](lectures/raw_pointers.md)
-- The pointer type
-- Pointers = variables of pointer types
-- How to get the data?
-- Initialization and assignment
-- Using const with pointers
-- Non-const pointer to const data
-- Constant pointer to non-const data
-- Constant pointer to constant data
-----------------------------------------------------------
-</details>
-
-<details>
-<summary>
-Object lifecycle
-</summary>
-
-----------------------------------------------------------
-[![Video thumbnail](https://img.youtube.com/vi/TFoav6vhgdg/maxresdefault.jpg)](https://youtu.be/TFoav6vhgdg)
-
-[Lecture script](lectures/object_lifecycle.md)
-- Creating a new object
-- What happens when an object dies
-- Full class lifecycle explained
-----------------------------------------------------------
-</details>
-
-<details>
-<summary>
-Move semantics
-</summary>
-
-----------------------------------------------------------
-[![Video thumbnail](https://img.youtube.com/vi/kqQ90R0_GFI/maxresdefault.jpg)](https://youtu.be/kqQ90R0_GFI)
-
-[Lecture script](lectures/move_semantics.md)
-- Why we care about move semantics
-- Let’s re-design move semantics from scratch
-- How is it actually designed and called in Modern C++?
-
-----------------------------------------------------------
-</details>
-
-<details>
-<summary>
-Constructors, operators, destructor - rule of all or nothing
-</summary>
-
-----------------------------------------------------------
-[![Video thumbnail](https://img.youtube.com/vi/una89pkP9ms/maxresdefault.jpg)](https://youtu.be/una89pkP9ms)
-
-[Lecture script](lectures/all_or_nothing.md)
-- “Good style” as our guide
-- What is “good style”
-- Setting up the example
-- Rule 1: destructor
-- Rule 2: copy constructor
-- Rule 3: copy assignment operator
-- Rule 4: move constructor
-- Rule 5: move assignment operator
-- Now we (mostly) follow best practices
-- Rule of 5 (and 3)
-- The rule of “all or nothing”
-
-----------------------------------------------------------
-</details>
-
-<details>
-<summary>
-Headers with classes
-</summary>
-
-----------------------------------------------------------
-[![Video thumbnail](https://img.youtube.com/vi/9MB1nHDIM64/maxresdefault.jpg)](https://youtu.be/9MB1nHDIM64)
-
-[Lecture script](lectures/headers_with_classes.md)
-- What stays the same
-- What is different
-- Example to show it all
-
-----------------------------------------------------------
-</details>
-
-<details>
-<summary>Const correctness</summary>
-
-----------------------------------------------------------
-[![Video thumbnail](https://img.youtube.com/vi/WsBdxq319OY/maxresdefault.jpg)](https://youtu.be/WsBdxq319OY)
-
-[Lecture script](lectures/const_correctness.md)
-- What is const correctness
-- Some rules and examples to follow in order to work with `const` correctly
-----------------------------------------------------------
-</details>
-
-<details>
-<summary><code>Project</code>: pixelate images in terminal</summary>
-
-----------------------------------------------------------
-[![Video thumbnail](https://img.youtube.com/vi/Cj3x51iJdvM/maxresdefault.jpg)](https://youtu.be/Cj3x51iJdvM)
-
-[Homework script](homeworks/homework_5/homework.md)
-- You will write a library that allows to pixelate an image
-- You will learn how to:
-  - Work with classes
-  - Use external libraries
-    - Read images from disk using `stb_image.h`
-    - Draw stuff in the terminal using `FTXUI` library
-  - Manage memory allocated elsewhere correctly
-  - Writing multiple libraries and binaries and linking them together
-  - Manage a larger CMake project
-----------------------------------------------------------
-</details>
-
-<details>
-<summary>Keyword <code>static</code> <b>outside</b> of classes</summary>
-
-----------------------------------------------------------
-[![Video thumbnail](https://img.youtube.com/vi/7cpPQunjv4s/maxresdefault.jpg)](https://youtu.be/7cpPQunjv4s)
-
-[Lecture script](lectures/static_outside_classes.md)
-- Why we should not use `static` outside of classes
-- Relation to storage duration
-- Relation to linkage
-- Why we should use `inline` instead
-
-----------------------------------------------------------
-</details>
-
-<details>
-<summary>Keyword <code>static</code> <b>inside</b> classes</summary>
-
-----------------------------------------------------------
-[![Video thumbnail](https://img.youtube.com/vi/ggNCjDPShrA/maxresdefault.jpg)](https://youtu.be/ggNCjDPShrA)
-
-[Lecture script](lectures/static_in_classes.md)
-- Using `static` class methods
-- Using `static` class data
-- What is `static` in classes useful for?
-
-----------------------------------------------------------
-</details>
-
-<details>
-<summary>Templates: <b>why</b> would we want to use them?</summary>
-
-----------------------------------------------------------
-[![Video thumbnail](https://img.youtube.com/vi/1Mrt1NM3KnI/maxresdefault.jpg)](https://youtu.be/1Mrt1NM3KnI)
-
-[Lecture script](lectures/templates_why.md)
-- Templates provide abstraction and separation of concerns
-- Function templates
-- Class and struct templates
-- Generic algorithms and design patterns
-- Zero runtime cost (almost)
-- Compile-time meta-programming
-- Summary
-
-----------------------------------------------------------
-</details>
-
-<details>
-<summary>Templates: <b>what</b> do they do under the hood?</summary>
-
-----------------------------------------------------------
-[![Video thumbnail](https://img.youtube.com/vi/NKvEbPVllRE/maxresdefault.jpg)](https://youtu.be/NKvEbPVllRE)
-
-[Lecture script](lectures/templates_what.md)
-- Compilation process recap
-- Compiler uses templates to generate code
-- Hands-on example
-- Compiler is lazy
-
-----------------------------------------------------------
-</details>
-
-<details>
-<summary>How to write function templates</summary>
-
-----------------------------------------------------------
-[![Video thumbnail](https://img.youtube.com/vi/BZ626ZWPspc/maxresdefault.jpg)](https://youtu.be/BZ626ZWPspc)
-
-[Lecture script](lectures/templates_how_functions.md)
-- The basics of writing a function template
-- Explicit template parameters
-- Implicit template parameters
-- Using both explicit and implicit template parameters at the same time
-- Function overloading and templates
-- Full function template specialization and why function overloading is better
-
-----------------------------------------------------------
-</details>
-
-<details>
-<summary>How to write class templates</summary>
-
-----------------------------------------------------------
-[![Video thumbnail](https://img.youtube.com/vi/IQ62tA51Vag/maxresdefault.jpg)](https://youtu.be/IQ62tA51Vag)
-
-- [How to use templates with classes in C++](lectures/templates_how_classes.md#how-to-use-templates-with-classes-in-c)
-- [Class method templates](lectures/templates_how_classes.md#class-method-templates)
-  - [Prefer overloading to specialization of class method templates](lectures/templates_how_classes.md#prefer-overloading-to-specialization-of-class-method-templates)
-  - [Sometimes overloading is not possible --- specialize in this case](lectures/templates_how_classes.md#sometimes-overloading-is-not-possible-----specialize-in-this-case)
-- [Class templates](lectures/templates_how_classes.md#class-templates)
-- [Class template argument deduction (min. C++17)](lectures/templates_how_classes.md#class-template-argument-deduction-min-c17)
-  - [Class template specialization: implicit and explicit](lectures/templates_how_classes.md#class-template-specialization-implicit-and-explicit)
-  - [Full explicit template specialization](lectures/templates_how_classes.md#full-explicit-template-specialization)
-    - [How to fully specialize class templates](lectures/templates_how_classes.md#how-to-fully-specialize-class-templates)
-    - [Make sure a specialization follows the expected interface](lectures/templates_how_classes.md#make-sure-a-specialization-follows-the-expected-interface)
-    - [Historical reference for `std::vector<bool>`](lectures/templates_how_classes.md#historical-reference-for-stdvectorbool)
-    - [Specialize just one method of a class](lectures/templates_how_classes.md#specialize-just-one-method-of-a-class)
-    - [Specialize method templates of class templates](lectures/templates_how_classes.md#specialize-method-templates-of-class-templates)
-    - [Type traits and how to implement them using template specialization](lectures/templates_how_classes.md#type-traits-and-how-to-implement-them-using-template-specialization)
-    - [More generic traits using partial specialization](lectures/templates_how_classes.md#more-generic-traits-using-partial-specialization)
-  - [Difference between partial and full specializations](lectures/templates_how_classes.md#difference-between-partial-and-full-specializations)
-    - [How to tell partial template specialization apart from a new template class definition?](lectures/templates_how_classes.md#how-to-tell-partial-template-specialization-apart-from-a-new-template-class-definition)
-    - [How to tell a partial template specialization apart from a full class template specialization?](lectures/templates_how_classes.md#how-to-tell-a-partial-template-specialization-apart-from-a-full-class-template-specialization)
-  - [Partial template specialization with more types](lectures/templates_how_classes.md#partial-template-specialization-with-more-types)
-- [Summary](lectures/templates_how_classes.md#summary)
-
-----------------------------------------------------------
-</details>
-
-</details>
-
-<details>
-<summary>Forwarding references</summary>
-
-----------------------------------------------------------
-[![Video thumbnail](https://img.youtube.com/vi/RW9KnqszYj4/maxresdefault.jpg)](https://youtu.be/RW9KnqszYj4)
-
-- [The forwarding reference](lectures/forwarding_references.md#the-forwarding-reference)
-- [Why use forwarding references](lectures/forwarding_references.md#why-use-forwarding-references)
-  - [Example setup](lectures/forwarding_references.md#example-setup)
-  - [How forwarding references simplify things](lectures/forwarding_references.md#how-forwarding-references-simplify-things)
-  - [When to prefer forwarding references](lectures/forwarding_references.md#when-to-prefer-forwarding-references)
-- [How forwarding references work](lectures/forwarding_references.md#how-forwarding-references-work)
-  - [Reference collapsing](lectures/forwarding_references.md#reference-collapsing)
-  - [Remove reference using `std::remove_reference_t`](lectures/forwarding_references.md#remove-reference-using-stdremove_reference_t)
-  - [How `std::forward` works](lectures/forwarding_references.md#how-stdforward-works)
-    - [Passing an lvalue](lectures/forwarding_references.md#passing-an-lvalue)
-    - [Passing by rvalue](lectures/forwarding_references.md#passing-by-rvalue)
-- [Summary](lectures/forwarding_references.md#summary)
-
-----------------------------------------------------------
-</details>
-
-<details>
-<summary>Header and source files for templated code</summary>
-
-----------------------------------------------------------
-[![Video thumbnail](https://img.youtube.com/vi/vjsr18XXMMQ/maxresdefault.jpg)](https://youtu.be/vjsr18XXMMQ)
-
-- [Why linker fails](lectures/templates_and_headers.md#why-linker-fails)
-  - [Compilation process for single `main.cpp` file](lectures/templates_and_headers.md#compilation-process-for-single-maincpp-file)
-  - [Compilation process for multiple files](lectures/templates_and_headers.md#compilation-process-for-multiple-files)
-- [How to fix the linker error](lectures/templates_and_headers.md#how-to-fix-the-linker-error)
-- [More complex explicit instantiations](lectures/templates_and_headers.md#more-complex-explicit-instantiations)
-- [Summary](lectures/templates_and_headers.md#summary)
-
-----------------------------------------------------------
-</details>
-
-<details>
-<summary>Almost everything about inheritance</summary>
-
-----------------------------------------------------------
-[![Video thumbnail](https://img.youtube.com/vi/oUALDqvCbWs/maxresdefault.jpg)](https://youtu.be/oUALDqvCbWs)
-
-- [Inheritance enables dependency inversion](lectures/inheritance.md#inheritance-enables-dependency-inversion)
-- [The idea behind dependency inversion](lectures/inheritance.md#the-idea-behind-dependency-inversion)
-- [Similarity to static polymorphism with templates](lectures/inheritance.md#similarity-to-static-polymorphism-with-templates)
-- [How inheritance looks in C++](lectures/inheritance.md#how-inheritance-looks-in-c)
-  - [Implementation inheritance](lectures/inheritance.md#implementation-inheritance)
-    - [Access control with inheritance](lectures/inheritance.md#access-control-with-inheritance)
-    - [Implicit upcasting](lectures/inheritance.md#implicit-upcasting)
-    - [Real-world example of implementation inheritance](lectures/inheritance.md#real-world-example-of-implementation-inheritance)
-  - [Using `virtual` for interface inheritance and proper polymorphism](lectures/inheritance.md#using-virtual-for-interface-inheritance-and-proper-polymorphism)
-  - [How interface inheritance works](lectures/inheritance.md#how-interface-inheritance-works)
-  - [Runtime and memory overhead of using virtual](lectures/inheritance.md#runtime-and-memory-overhead-of-using-virtual)
-  - [Things to know about classes with `virtual` methods](lectures/inheritance.md#things-to-know-about-classes-with-virtual-methods)
-    - [A `virtual` destructor](lectures/inheritance.md#a-virtual-destructor)
-    - [Delete other special methods for polymorphic classes](lectures/inheritance.md#delete-other-special-methods-for-polymorphic-classes)
-  - [Downcasting using the `dynamic_cast`](lectures/inheritance.md#downcasting-using-the-dynamic_cast)
-  - [Don't mix implementation and interface inheritance](lectures/inheritance.md#dont-mix-implementation-and-interface-inheritance)
-  - [Implement pure interfaces](lectures/inheritance.md#implement-pure-interfaces)
-  - [Keyword `final`](lectures/inheritance.md#keyword-final)
-- [Simple polymorphic class example following best practices](lectures/inheritance.md#simple-polymorphic-class-example-following-best-practices)
-- [Multiple inheritance](lectures/inheritance.md#multiple-inheritance)
-- [Detailed `Image` example following best practices](lectures/inheritance.md#detailed-image-example-following-best-practices)
-
-
-----------------------------------------------------------
-</details>
-
-<details>
-<summary>Memory management and smart pointers</summary>
-
-----------------------------------------------------------
-[![Video thumbnail](https://img.youtube.com/vi/eHcdTytDZrI/maxresdefault.jpg)](https://youtu.be/eHcdTytDZrI)
-
-- [Memory management and smart pointers](lectures/memory_and_smart_pointers.md#memory-management-and-smart-pointers)
-- [Memory management in C++](lectures/memory_and_smart_pointers.md#memory-management-in-c)
-  - [Automatic memory management in other programming languages](lectures/memory_and_smart_pointers.md#automatic-memory-management-in-other-programming-languages)
-  - [The C++ way](lectures/memory_and_smart_pointers.md#the-c-way)
-- [Memory allocation under the hood](lectures/memory_and_smart_pointers.md#memory-allocation-under-the-hood)
-  - [The stack](lectures/memory_and_smart_pointers.md#the-stack)
-  - [Why not keep persistent data on the stack](lectures/memory_and_smart_pointers.md#why-not-keep-persistent-data-on-the-stack)
-  - [The heap](lectures/memory_and_smart_pointers.md#the-heap)
-    - [Operators `new` and `delete`](lectures/memory_and_smart_pointers.md#operators-new-and-delete)
-- [Typical pitfalls with data allocated on the heap](lectures/memory_and_smart_pointers.md#typical-pitfalls-with-data-allocated-on-the-heap)
-    - [Forgetting to call `delete`](lectures/memory_and_smart_pointers.md#forgetting-to-call-delete)
-    - [Performing shallow copy by mistake](lectures/memory_and_smart_pointers.md#performing-shallow-copy-by-mistake)
-  - [Performing shallow assignment by mistake](lectures/memory_and_smart_pointers.md#performing-shallow-assignment-by-mistake)
-  - [Calling a wrong `delete`](lectures/memory_and_smart_pointers.md#calling-a-wrong-delete)
-  - [Returning owning pointers from functions](lectures/memory_and_smart_pointers.md#returning-owning-pointers-from-functions)
-- [RAII for memory safety](lectures/memory_and_smart_pointers.md#raii-for-memory-safety)
-  - [STL classes use RAII](lectures/memory_and_smart_pointers.md#stl-classes-use-raii)
-  - [Smart pointers to the rescue!](lectures/memory_and_smart_pointers.md#smart-pointers-to-the-rescue)
-    - [`std::unique_ptr`](lectures/memory_and_smart_pointers.md#stdunique_ptr)
-    - [`std::shared_ptr`](lectures/memory_and_smart_pointers.md#stdshared_ptr)
-      - [Prefer `std::unique_ptr`](lectures/memory_and_smart_pointers.md#prefer-stdunique_ptr)
-  - [Smart pointers are polymorphic](lectures/memory_and_smart_pointers.md#smart-pointers-are-polymorphic)
-- [Summary](lectures/memory_and_smart_pointers.md#summary)
-
-
-----------------------------------------------------------
-</details>
-
-<details>
-<summary>Lambdas in modern C++</summary>
-
-----------------------------------------------------------
-[![Video thumbnail](https://img.youtube.com/vi/l0BgadhkUL8/maxresdefault.jpg)](https://youtu.be/l0BgadhkUL8)
-
-- [Lambdas](lectures/lambdas.md#lambdas)
-- [Overview](lectures/lambdas.md#overview)
-- [What is a "callable"](lectures/lambdas.md#what-is-a-callable)
-- [A function pointer is sometimes enough](lectures/lambdas.md#a-function-pointer-is-sometimes-enough)
-- [Before lambdas we had function objects (or functors)](lectures/lambdas.md#before-lambdas-we-had-function-objects-or-functors)
-- [How to implement generic algorithms like `std::sort`](lectures/lambdas.md#how-to-implement-generic-algorithms-like-stdsort)
-- [Enter lambdas](lectures/lambdas.md#enter-lambdas)
-- [Lambda syntax](lectures/lambdas.md#lambda-syntax)
-- [When to use lambdas](lectures/lambdas.md#when-to-use-lambdas)
-- [Summary](lectures/lambdas.md#summary)
-
-----------------------------------------------------------
-</details>
-
-<details>
-<summary>Error handling in C++</summary>
-
-----------------------------------------------------------
-[![Video thumbnail](https://img.youtube.com/vi/6DqX8OJKM1g/maxresdefault.jpg)](https://youtu.be/6DqX8OJKM1g)
-
-- [Disclaimer](#disclaimer)
-- [What Do We Mean by “Error”?](lectures/error_handling.md#what-do-we-mean-by-error)
-- [Setting up the example: **a comparison game**](lectures/error_handling.md#setting-up-the-example-a-comparison-game)
-  - [Rules of the game](lectures/error_handling.md#rules-of-the-game)
-  - [Initial code of the game](lectures/error_handling.md#initial-code-of-the-game)
-- [Unrecoverable errors: **fail early**](lectures/error_handling.md#unrecoverable-errors-fail-early)
-  - [Our first unrecoverable error encounter](lectures/error_handling.md#our-first-unrecoverable-error-encounter)
-  - [How to deal with unrecoverable errors](lectures/error_handling.md#how-to-deal-with-unrecoverable-errors)
-    - [Catch them as early as possible](lectures/error_handling.md#catch-them-as-early-as-possible)
-    - [Use `CHECK` macro to fail early](lectures/error_handling.md#use-check-macro-to-fail-early)
-    - [Don't use `assert`](lectures/error_handling.md#dont-use-assert)
-    - [Complete the `Game` class yourself](lectures/error_handling.md#complete-the-game-class-yourself)
-  - [How to minimize number of unrecoverable errors](lectures/error_handling.md#how-to-minimize-number-of-unrecoverable-errors)
-- [Recoverable errors: **handle and proceed**](lectures/error_handling.md#recoverable-errors-handle-and-proceed)
-  - [Exceptions](lectures/error_handling.md#exceptions)
-    - [How to use exceptions](lectures/error_handling.md#how-to-use-exceptions)
-    - [A case for exceptions for both "recoverable" and "unrecoverable" errors](lectures/error_handling.md#a-case-for-exceptions-for-both-recoverable-and-unrecoverable-errors)
-    - [Why we might not want to use exceptions](lectures/error_handling.md#why-we-might-not-want-to-use-exceptions)
-      - [Exceptions are (sometimes) expensive](lectures/error_handling.md#exceptions-are-sometimes-expensive)
-      - [Exceptions hide the error path](lectures/error_handling.md#exceptions-hide-the-error-path)
-      - [Exceptions are banned in many code bases](lectures/error_handling.md#exceptions-are-banned-in-many-code-bases)
-  - [Returning errors explicitly can work better if done well](lectures/error_handling.md#returning-errors-explicitly-can-work-better-if-done-well)
-    - [Returning a value indicating error does not always work 😱](lectures/error_handling.md#returning-a-value-indicating-error-does-not-always-work-)
-    - [Returning an error code breaks "pure functions" 😱](lectures/error_handling.md#returning-an-error-code-breaks-pure-functions-)
-    - [Using `std::optional`: **a better way**](lectures/error_handling.md#using-stdoptional-a-better-way)
-    - [Using `std::expected`: **add context**](lectures/error_handling.md#using-stdexpected-add-context)
-  - [Performance Considerations for `std::optional` and `std::expected`](lectures/error_handling.md#performance-considerations-for-stdoptional-and-stdexpected)
-    - [Error type size matters](lectures/error_handling.md#error-type-size-matters)
-    - [Return value optimization with `std::optional` and `std::expected`](lectures/error_handling.md#return-value-optimization-with-stdoptional-and-stdexpected)
-  - [Summary](lectures/error_handling.md#summary)
-  - [Other use of `std::optional`](lectures/error_handling.md#other-use-of-stdoptional)
-
-----------------------------------------------------------
-</details>
-
-## PS
-
-### Most of the code snippets are validated automatically
-If you **do** find an error in some of those, please open an issue in this repo!
diff --git a/scripts/Pipfile b/scripts/Pipfile
deleted file mode 100644
index 01bf348..0000000
--- a/scripts/Pipfile
+++ /dev/null
@@ -1,9 +0,0 @@
-[[source]]
-url = "https://pypi.org/simple"
-verify_ssl = true
-name = "pypi"
-
-[packages]
-rich = "*"
-typer = "*"
-black = "*"
diff --git a/scripts/Pipfile.lock b/scripts/Pipfile.lock
deleted file mode 100644
index 1d73dae..0000000
--- a/scripts/Pipfile.lock
+++ /dev/null
@@ -1,116 +0,0 @@
-{
-    "_meta": {
-        "hash": {
-            "sha256": "385c4740b6d3848c4d858d92aab44f75062bdea16a77865a31b8d413193a57c9"
-        },
-        "pipfile-spec": 6,
-        "requires": {},
-        "sources": [
-            {
-                "name": "pypi",
-                "url": "https://pypi.org/simple",
-                "verify_ssl": true
-            }
-        ]
-    },
-    "default": {
-        "black": {
-            "hashes": [
-                "sha256:14ff67aec0a47c424bc99b71005202045dc09270da44a27848d534600ac64fc7",
-                "sha256:197df8509263b0b8614e1df1756b1dd41be6738eed2ba9e9769f3880c2b9d7b6",
-                "sha256:1e464456d24e23d11fced2bc8c47ef66d471f845c7b7a42f3bd77bf3d1789650",
-                "sha256:2039230db3c6c639bd84efe3292ec7b06e9214a2992cd9beb293d639c6402edb",
-                "sha256:21199526696b8f09c3997e2b4db8d0b108d801a348414264d2eb8eb2532e540d",
-                "sha256:2644b5d63633702bc2c5f3754b1b475378fbbfb481f62319388235d0cd104c2d",
-                "sha256:432247333090c8c5366e69627ccb363bc58514ae3e63f7fc75c54b1ea80fa7de",
-                "sha256:444ebfb4e441254e87bad00c661fe32df9969b2bf224373a448d8aca2132b395",
-                "sha256:5b9b29da4f564ba8787c119f37d174f2b69cdfdf9015b7d8c5c16121ddc054ae",
-                "sha256:5cc42ca67989e9c3cf859e84c2bf014f6633db63d1cbdf8fdb666dcd9e77e3fa",
-                "sha256:5d8f74030e67087b219b032aa33a919fae8806d49c867846bfacde57f43972ef",
-                "sha256:72ef3925f30e12a184889aac03d77d031056860ccae8a1e519f6cbb742736383",
-                "sha256:819dc789f4498ecc91438a7de64427c73b45035e2e3680c92e18795a839ebb66",
-                "sha256:915ace4ff03fdfff953962fa672d44be269deb2eaf88499a0f8805221bc68c87",
-                "sha256:9311e99228ae10023300ecac05be5a296f60d2fd10fff31cf5c1fa4ca4b1988d",
-                "sha256:974308c58d057a651d182208a484ce80a26dac0caef2895836a92dd6ebd725e0",
-                "sha256:b8b49776299fece66bffaafe357d929ca9451450f5466e997a7285ab0fe28e3b",
-                "sha256:c957b2b4ea88587b46cf49d1dc17681c1e672864fd7af32fc1e9664d572b3458",
-                "sha256:e41a86c6c650bcecc6633ee3180d80a025db041a8e2398dcc059b3afa8382cd4",
-                "sha256:f513588da599943e0cde4e32cc9879e825d58720d6557062d1098c5ad80080e1",
-                "sha256:fba8a281e570adafb79f7755ac8721b6cf1bbf691186a287e990c7929c7692ff"
-            ],
-            "index": "pypi",
-            "version": "==22.10.0"
-        },
-        "click": {
-            "hashes": [
-                "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e",
-                "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"
-            ],
-            "markers": "python_version >= '3.7'",
-            "version": "==8.1.3"
-        },
-        "commonmark": {
-            "hashes": [
-                "sha256:452f9dc859be7f06631ddcb328b6919c67984aca654e5fefb3914d54691aed60",
-                "sha256:da2f38c92590f83de410ba1a3cbceafbc74fee9def35f9251ba9a971d6d66fd9"
-            ],
-            "version": "==0.9.1"
-        },
-        "mypy-extensions": {
-            "hashes": [
-                "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d",
-                "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"
-            ],
-            "version": "==0.4.3"
-        },
-        "pathspec": {
-            "hashes": [
-                "sha256:46846318467efc4556ccfd27816e004270a9eeeeb4d062ce5e6fc7a87c573f93",
-                "sha256:7ace6161b621d31e7902eb6b5ae148d12cfd23f4a249b9ffb6b9fee12084323d"
-            ],
-            "markers": "python_version >= '3.7'",
-            "version": "==0.10.1"
-        },
-        "platformdirs": {
-            "hashes": [
-                "sha256:027d8e83a2d7de06bbac4e5ef7e023c02b863d7ea5d079477e722bb41ab25788",
-                "sha256:58c8abb07dcb441e6ee4b11d8df0ac856038f944ab98b7be6b27b2a3c7feef19"
-            ],
-            "markers": "python_version >= '3.7'",
-            "version": "==2.5.2"
-        },
-        "pygments": {
-            "hashes": [
-                "sha256:56a8508ae95f98e2b9bdf93a6be5ae3f7d8af858b43e02c5a2ff083726be40c1",
-                "sha256:f643f331ab57ba3c9d89212ee4a2dabc6e94f117cf4eefde99a0574720d14c42"
-            ],
-            "markers": "python_version >= '3.6'",
-            "version": "==2.13.0"
-        },
-        "rich": {
-            "hashes": [
-                "sha256:a4eb26484f2c82589bd9a17c73d32a010b1e29d89f1604cd9bf3a2097b81bb5e",
-                "sha256:ba3a3775974105c221d31141f2c116f4fd65c5ceb0698657a11e9f295ec93fd0"
-            ],
-            "index": "pypi",
-            "version": "==12.6.0"
-        },
-        "tomli": {
-            "hashes": [
-                "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc",
-                "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"
-            ],
-            "markers": "python_full_version < '3.11.0a7'",
-            "version": "==2.0.1"
-        },
-        "typer": {
-            "hashes": [
-                "sha256:2d5720a5e63f73eaf31edaa15f6ab87f35f0690f8ca233017d7d23d743a91d73",
-                "sha256:54b19e5df18654070a82f8c2aa1da456a4ac16a2a83e6dcd9f170e291c56338e"
-            ],
-            "index": "pypi",
-            "version": "==0.6.1"
-        }
-    },
-    "develop": {}
-}
diff --git a/scripts/validate_code_snippets.py b/scripts/validate_code_snippets.py
deleted file mode 100644
index 7805ed7..0000000
--- a/scripts/validate_code_snippets.py
+++ /dev/null
@@ -1,322 +0,0 @@
-import re
-import sys
-import logging
-import tempfile
-import typer
-from os import environ, killpg, terminal_size
-from pathlib import Path
-from string import Template
-from signal import SIGINT
-from rich import print
-from rich.text import Text
-from rich.panel import Panel
-from rich.padding import Padding
-from rich.syntax import Syntax
-from rich.console import Group
-from rich.pretty import Pretty
-from typing import List, Optional, Mapping, Any
-from subprocess import PIPE, Popen, TimeoutExpired, CalledProcessError, CompletedProcess
-
-FORMAT = "%(message)s"
-logging.basicConfig(format=FORMAT)
-log = logging.getLogger("code_validation")
-log.setLevel(logging.INFO)
-
-
-# See a playground here: https://regex101.com/r/Tfwjsq/1
-REGEX_TEMPLATE = r"""
-(?:\s*<!--
-(:?\s*`CPP_SETUP_START`\n(?P<setup>(?:[^`]+)\n)\s*`CPP_SETUP_END`\s*)*\s*
-(?P<skip>`CPP_SKIP_SNIPPET`)*\s*
-(?:`CPP_COPY_SNIPPET`\s*(?P<copy>.*$))*\s*
-(?:`CPP_RUN_CMD`\s*(?:CWD:(?P<cwd>[\w/]+))*\s*(?P<cmd>.*$))*\s*
--->\s*)*
-```(?P<language>\w+)
-(?P<code>(?:[^`]+)\n)+\s*
-```\s*
-"""
-
-DEFAULT_CMD_PER_LANGUAGE = {
-    "cpp": "c++ -std=c++17 $FILENAME",
-    "c++": "c++ -std=c++17 $FILENAME",
-    "cmake": "cmake -P $FILENAME",
-    "bash": "",
-    "make": "make",
-}
-
-
-class CmdResult:
-    def __init__(self, status, stdout, stderr) -> None:
-        self.status = status
-        self.stdout = stdout
-        self.stderr = stderr
-
-
-def run_command(
-    command: List[str],
-    timeout: float,
-    cwd: Path = Path.cwd(),
-    env: Optional[Mapping[str, Any]] = None,
-) -> CmdResult:
-    """Run a generic command in a subprocess.
-    Args:
-        command (str): command to run
-    Returns:
-        CmdResult: Result of the command execution
-    """
-    try:
-        startupinfo = None
-        if env is None:
-            env = environ
-        process = __run_subprocess(
-            command,
-            stdout=PIPE,
-            stderr=PIPE,
-            stdin=PIPE,
-            shell=True,
-            cwd=str(cwd),
-            env=env,
-            startupinfo=startupinfo,
-            timeout=timeout,
-        )
-        return CmdResult(
-            status=process.returncode,
-            stdout=process.stdout.decode("utf-8"),
-            stderr=process.stderr.decode("utf-8"),
-        )
-    except CalledProcessError as error:
-        output_text = error.output.decode("utf-8")
-        log.error("command '%s' finished with code: %s", error.cmd, error.status)
-        log.debug("command output: \n%s", output_text)
-        return CmdResult(status=error.status, stderr=output_text)
-    except TimeoutExpired as error:
-        output_text = "Timeout: command '{}' ran longer than {} seconds".format(
-            error.cmd.strip(), error.timeout
-        )
-        log.error(output_text)
-        return CmdResult(status=CmdResult.TIMEOUT, stderr=output_text)
-
-
-def __run_subprocess(
-    command: List[str],
-    str_input: str = None,
-    timeout: float = None,
-    check: bool = False,
-    **kwargs,
-) -> CompletedProcess:
-    """Run a command as a subprocess.
-    Using the guide from StackOverflow:
-    https://stackoverflow.com/a/36955420/1763680
-    This command has been adapted from:
-    https://github.com/python/cpython/blob/3.5/Lib/subprocess.py#L352-L399
-    This code does essentially the same as subprocess.run(...) but makes sure to
-    kill the whole process tree which allows to use the timeout even when using
-    shell=True. The reason I don't want to stop using shell=True here is the
-    convenience of piping arguments from one function to another.
-    """
-    if str_input is not None:
-        if "stdin" in kwargs:
-            raise ValueError("stdin and str_input arguments may not both be used.")
-        kwargs["stdin"] = PIPE
-
-    if timeout is None:
-        timeout = 20
-    with Popen(command, start_new_session=True, **kwargs) as process:
-        try:
-            stdout, stderr = process.communicate(str_input, timeout=timeout)
-        except TimeoutExpired as timeout_error:
-            # Kill the whole group of processes.
-            killpg(process.pid, SIGINT)
-            stdout, stderr = process.communicate()
-            raise TimeoutExpired(
-                process.args, timeout, output=stdout, stderr=stderr
-            ) from timeout_error
-        return_code = process.poll()
-        if return_code is None:
-            return_code = 1
-        if check and return_code:
-            raise CalledProcessError(
-                return_code, process.args, output=stdout, stderr=stderr
-            )
-    return CompletedProcess(process.args, return_code, stdout, stderr)
-
-
-def compile_all_snippets(regex_pattern: str, file: Path):
-    def get_file_object(language, file_name=None):
-        if not file_name:
-            return tempfile.NamedTemporaryFile(suffix="." + language, delete=False)
-        return open(file_name, "wb")
-
-    def get_start_line_of_span(text, span):
-      line_count = 0
-      for i in range(span[0]):
-        if text[i] == "\n":
-          line_count += 1
-      return line_count + 2
-
-    def get_code_start_line(text, span):
-      line_count = 0
-      for i in range(span[0], span[1]):
-        if text[i] == "\n":
-          line_count += 1
-        if text[i] == "`" and text[i + 1] == "`":
-          break
-      return line_count
-
-    error_count = 0
-    temp_folder = Path(tempfile.gettempdir())
-    file_text = file.read_text()
-    for match in re.finditer(pattern=regex_pattern, string=file_text):
-        span = match.span()
-        span_start_line = get_start_line_of_span(file_text, span)
-        code_start_line = span_start_line + get_code_start_line(file_text, span)
-        found_group_dict = match.groupdict()
-        skip = found_group_dict["skip"]
-        setup = found_group_dict["setup"]
-        code = found_group_dict["code"]
-        copy_destination = found_group_dict["copy"]
-        cmd = found_group_dict["cmd"]
-        cwd = found_group_dict["cwd"]
-        language = found_group_dict["language"]
-        if language not in DEFAULT_CMD_PER_LANGUAGE:
-            continue
-        if skip is not None:
-            continue
-        if setup is not None:
-            code = Template(setup).substitute(PLACEHOLDER=code)
-        if copy_destination is not None:
-            copy_destination = temp_folder / copy_destination
-            copy_destination.parent.mkdir(parents=True, exist_ok=True)
-            log.info("🗒️  Creating file copy: %s", copy_destination)
-            if cwd is not None:
-                cwd = temp_folder / cwd
-        code_file_name = None
-        with get_file_object(
-            file_name=copy_destination, language=language
-        ) as code_file:
-            code_file.write(bytes(code, encoding="utf-8"))
-            code_file_name = code_file.name
-            if not cwd:
-                cwd = Path(code_file.name).parent
-        if not cmd:
-            if copy_destination is not None:
-                # We just want to copy the file, not run the command here
-                continue
-            cmd = DEFAULT_CMD_PER_LANGUAGE[language]
-        cmd = Template(cmd).substitute(FILENAME=code_file_name)
-        log.info("🤞  Validating with command: %s", cmd)
-        result = run_command(
-            command=cmd,
-            timeout=20,
-            cwd=cwd,
-        )
-        if result.status != 0:
-            highlighted_code = Syntax(code, "c++", line_numbers=True)
-            file_info = Padding(
-                Text(
-                    "❌ Failed to compile file {} ❌".format(code_file_name),
-                    style="bold red",
-                    justify="center",
-                ),
-                1,
-            )
-            print("code_start_line:", code_start_line)
-            code_info = Padding(
-                Text(
-                    "ℹ️ The code is situated in {}:{}".format(file, code_start_line),
-                    justify="center",
-                ),
-                1,
-            )
-            code_panel = Panel(highlighted_code, title="Snippet code")
-            error_panel = Panel.fit(
-                Syntax(result.stderr, "gdscript", line_numbers=False),
-                title="Error",
-                style="red",
-            )
-            print(Padding(Panel.fit(Group(file_info, code_info, code_panel, error_panel)), 1))
-            error_count += 1
-    return error_count
-
-
-def get_all_files(path: Path, suffix: str):
-    return [file for file in path.iterdir() if file.suffix == suffix]
-
-
-def get_all_changed_files(path: Path, suffix: str):
-    git_command = """
-    {
-        git diff HEAD origin/main --name-only;
-        git diff HEAD origin/main --name-only --staged;
-        git diff --name-only;
-        git diff --name-only --staged;
-    } | sort | uniq"""
-    result = run_command(command=git_command, timeout=20, cwd=path)
-    files = [
-        path / file_name for file_name in result.stdout.split("\n") if file_name.strip()
-    ]
-    print(
-        Padding(
-            Panel.fit(
-                Pretty(files),
-                title="Files changed compared to origin/main",
-                subtitle="Only selecting markdown files from these",
-            ),
-            1,
-        )
-    )
-    return [file for file in files if file.suffix == suffix]
-
-
-def main(
-    changes_only: bool = typer.Option(
-        False,
-        help="Only run on changed files.",
-        rich_help_panel="Customization and Utils",
-    ),
-    project_folder: str = typer.Option(
-        ..., help="Project folder.", rich_help_panel="Customization and Utils"
-    ),
-):
-    regex_pattern = re.compile(REGEX_TEMPLATE, flags=re.VERBOSE | re.MULTILINE)
-    lectures_dir = Path(project_folder) / "lectures"
-    error_count = 0
-    if changes_only:
-        files = get_all_changed_files(Path(project_folder), ".md")
-    else:
-        files = get_all_files(lectures_dir, ".md")
-
-    for file in files:
-        log.info("ℹ️ Processing file: %s", file)
-        error_count += compile_all_snippets(regex_pattern=regex_pattern, file=file)
-    if error_count == 0:
-        print(
-            Padding(
-                Panel(
-                    Padding(
-                        Text(
-                            "All snippets compiled successfully!",
-                            justify="center",
-                        ),
-                        1,
-                    ),
-                    style="green bold",
-                ),
-                1,
-            )
-        )
-    else:
-        text = Text(
-            "{} snippets did not compile! 😢".format(error_count),
-            style="bold",
-            justify="center",
-        )
-        error = Padding(
-            Panel(Padding(text, 1), title="Errors encountered", style="red"), 1
-        )
-        print(error)
-        sys.exit(1)
-
-
-if __name__ == "__main__":
-    typer.run(main)
diff --git a/theme.css b/theme.css
index a706654..e51602e 100644
--- a/theme.css
+++ b/theme.css
@@ -1,6 +1,4 @@
-/* @theme custom-theme
- * @auto-scaling false
- */
+/* @theme custom-theme */
 
 @import 'uncover';
 @import url('https://fonts.googleapis.com/css?family=Roboto:400,700&display=swap');
@@ -8,182 +6,152 @@
 
 
 :root {
-  font-family: 'Roboto';
-  text-align: left;
-  justify-content: flex-start;
-  line-height: 1.4em;
-  letter-spacing: normal;
-  width: 1280px;
-  height: 1024px;
+    font-family: 'Roboto';
+    text-align: left;
+    justify-content: flex-start;
+    line-height:1.5em;
+    letter-spacing: normal;
+    width: 1280px;
+    height: 1024px;
 }
 
 rect.label-container {
-  fill: #eeeeee;
-  stroke: #519EF0;
-  stroke-width: 2px;
-  filter: drop-shadow(2px 2px lightgray);
+    fill: #eeeeee;
+    stroke:#519EF0;
+    stroke-width:2px;
 }
 
 polygon.label-container {
-  fill: #eeeeee;
-  stroke: #519EF0;
-  stroke-width: 2px;
-  box-shadow: 10px 10px lightgray;
+    fill: #eeeeee;
+    stroke:#519EF0;
+    stroke-width:2px;
 }
 
 .label foreignObject {
-  overflow: visible;
-  display: flex;
-  padding: 2px;
+    overflow: visible;
+    display: flex;
+    padding: 2px;
 }
 
 span.nodeLabel {
-  color: black;
+    color: black;
 }
 
 .flowchart-link {
-  stroke: darkgray;
-  fill: darkgray;
-  stroke-width: 2px;
+    stroke: darkgray;
+    fill: darkgray;
+    stroke-width: 2px;
 }
 
 path {
-  stroke: darkgray;
-  fill: darkgray;
-  stroke-width: 2px;
+    stroke: darkgray;
+    fill: darkgray;
+    stroke-width: 2px;
 }
 
 span.edgeLabel {
-  background-color: white;
-  color: black;
+    background-color: white;
+    color: black;    
 }
 
 svg {
-  zoom: 1.8;
-  line-height: 100%;
+    zoom: 1.8;
 }
 
 code {
-  font-family: 'Fira Mono', monospace !important;
-  box-shadow: 2px 2px lightgray;
-  font-size: 70%;
-  font-weight: 500;
-  line-height: 1.3em;
-  padding-top: 3px;
-  padding-left: 5px;
-  padding-right: 5px;
-  padding-bottom: 3px;
-  margin-top: 0.2em;
-  margin-left: 0.1em;
-  margin-bottom: 0.5em;
+    font-family: 'Fira Mono', monospace !important;
+    font-weight: 500;
+    padding-top: 3px;
+    padding-left: 5px;
+    padding-right: 5px;
+    padding-bottom: 3px;
+    margin-left: 2px;
+    margin-right: 2px;
 }
 
 pre {
-  --preserve-aspect-ratio: xLeftYTop meet;
-
-  filter: none;
-  padding-left: 5px;
-  margin-top: 0.2em;
-  margin-left: 0.1em;
-  margin-bottom: 0.5em;
-  width: auto;
-  font-size: 80%;
+    display: inline-block;
+    margin-left: 0.5em;
+    margin-bottom: 0.5em;
+    box-shadow: none;
+    outline: auto;
+    outline-color: #519EF0;
 }
 
 footer {
-  text-align: left;
-  position: absolute;
-  bottom: 920px;
-  left: 1190px;
+    text-align: right;
+    position: absolute;
+    bottom: 0em;
+    right: 1.5em;
 }
 
 .grid-container {
-  display: grid;
-  grid-template-columns: 50% auto;
+    display: grid;
+    grid-template-columns: 50% auto;
 }
 
 blockquote p {
-  color: darkslategray;
-  text-align: right;
-  font-family: "Fira Mono Medium";
+    color: darkslategray;
+    text-align: right;
+    font-family: "Fira Code Medium";
 }
 
 header {
-  text-align: right;
+    text-align: right;
+}
+
+svg {
+    line-height: 100%;
 }
 
 h1 {
-  color: #519EF0;
-  padding-top: 0.4em;
-  margin-bottom: 0.2em;
-  font-size: 55pt;
-  line-height: 1.2em;
-}
-
-h2,
-h3,
-h4,
-h5,
-h6 {
-  color: #226699;
-  margin-bottom: 0.2em;
-  margin-top: 0.5em;
-  letter-spacing: normal;
-}
-
-ul,
-ol {
-  margin-top: 0.2em;
-  margin-bottom: 0.2em;
-  margin-left: 0.2em;
-}
-
-kbd {
-  font-family: 'Fira Mono', monospace !important;
-  font-weight: 500;
-  background-color: rgba(0, 0, 0, 0.05);
-  color: black;
-  padding-left: 0.3em;
-  padding-right: 0.3em;
-  margin-left: 0.1em;
-  margin-right: 0.2em;
-  box-shadow: 0.1em 0.1em 0em rgba(0, 0, 0, 0.2);
+    color: #519EF0;
+    padding-top: 0.4em;
+    margin-bottom: 0.2em;
+    font-size: 55pt;
+    line-height:1.2em;
 }
 
-img[alt~="center"] {
-  display: block;
-  margin: 0 auto;
+h2, h3, h4, h5, h6 {
+    color: #226699;
+    margin-bottom: 0.2em;
+    margin-top: 0.5em;
+    letter-spacing: normal;
 }
 
-section.white h1 {
-  color: white;
-  padding-left: 0.2em;
-  padding-right: 0.2em;
-  background-color: #519EF0;
+ul, ol {
+    margin-top: 0.2em;
+    margin-bottom: 0.2em;
+    margin-left: 0.2em;
 }
 
-section::after {
-  box-sizing: border-box;
-  text-align: center;
-  width: 120px;
-  height: 120px;
-  line-height: 0px;
-  color: gray;
-  background: linear-gradient(-45deg, rgba(0, 0, 0, 0.05) 50%, transparent 50%);
-  background-size: cover;
+img[alt~="center"] {
+    display: block;
+    margin: 0 auto;
+}
+
+section.white h1 {
+    color: white;
+    padding-left: 0.2em;
+    padding-right: 0.2em;
+    background-color: #519EF0;
 }
 
 section.center_code pre {
-  --preserve-aspect-ratio: xMidYMid meet;
-  margin: 0.5em;
+    align-items: center;
+    align-self: center;
+    margin-left: auto;
+    position: absolute;
+    top: 50%;
+    -ms-transform: translateY(-50%);
+    transform: translateY(-50%);
 }
 
 section.code_without_margins pre {
-  --preserve-aspect-ratio: xMidYMid meet;
-  margin: 0.5em;
+    margin: 0.5em;
 }
 
 a {
-  color: #519EF0;
-  text-decoration: underline dotted;
+    color: #519EF0;
+    text-decoration: underline dotted;
 }
