diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 000000000..490051876
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1 @@
+github: iliakan
diff --git a/.gitignore b/.gitignore
index b4a7ec854..f55b4ff9d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,4 +21,8 @@ sftp-config.json
 Thumbs.db
 
 
+<<<<<<< HEAD
 .vscode
+=======
+/svgs
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
diff --git a/1-js/01-getting-started/1-intro/article.md b/1-js/01-getting-started/1-intro/article.md
index 0e9461c61..6a88903de 100644
--- a/1-js/01-getting-started/1-intro/article.md
+++ b/1-js/01-getting-started/1-intro/article.md
@@ -1,10 +1,18 @@
 # Wprowadzenie do JavaScriptu
 
+<<<<<<< HEAD
 Sprawdźmy, czym jest JavaScript, co możemy osiągnąć z jego pomocą i z jakimi innymi technologiami dobrze współpracuje.
+=======
+Let's see what's so special about JavaScript, what we can achieve with it, and what other technologies play well with it.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ## Czym jest JavaScript?
 
+<<<<<<< HEAD
 *JavaScript* pierwotnie został stworzony z myślą o *"ożywieniu stron internetowych"*.
+=======
+*JavaScript* was initially created to "make web pages alive".
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 Programy napisane w tym języku nazywamy *skryptami*. Możemy je pisać bezpośrednio w kodzie HTML strony i uruchamiać podczas wczytywania strony.
 
@@ -24,26 +32,44 @@ Przeglądarka posiada wbudowany silnik, potocznie nazywany "wirtualną maszyną
 
 Poszczególne silniki różnią się "nazwami kodowymi", na przykład:
 
+<<<<<<< HEAD
 - [V8](https://pl.wikipedia.org/wiki/V8_(silnik_JavaScript)) -- w Chromie i Operze.
 - [SpiderMonkey](https://pl.wikipedia.org/wiki/SpiderMonkey) -- w Firefoksie.
 - ... istnieją inne nazwy, jak "Trident" lub "Chakra" dla różnych wersji IE, "ChakraCore" dla Microsoft Edge, "Nitro" i "SquirrelFish" dla Safari itd.
 
 Warto zapamiętać powyższe nazwy, ponieważ często przewijają się w artykułach programistycznych w Internecie. W tym także będą się pojawiać. Będziemy pisać, na przykład, że "funkcjonalność X jest wspierana przez silnik V8", co oznacza, że najprawdopodobniej zadziała w Chromie i Operze.
+=======
+- [V8](https://en.wikipedia.org/wiki/V8_(JavaScript_engine)) -- in Chrome, Opera and Edge.
+- [SpiderMonkey](https://en.wikipedia.org/wiki/SpiderMonkey) -- in Firefox.
+- ...There are other codenames like "Chakra" for IE, "JavaScriptCore", "Nitro" and "SquirrelFish" for Safari, etc.
+
+The terms above are good to remember because they are used in developer articles on the internet. We'll use them too. For instance, if "a feature X is supported by V8", then it probably works in Chrome, Opera and Edge.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ```smart header="Jak działają silniki?"
 
 Silniki są skomplikowane. Ale ich podstawy są proste.
 
+<<<<<<< HEAD
 1. Silnik (wbudowany, jeśli mowa o przeglądarce) odczytuje ("parsuje") kod skryptu.
 2. Następnie konwertuje ("kompiluje") skrypt do kodu maszynowego.
 3. Na koniec kod maszynowy jest uruchamiany i działa dość szybko.
+=======
+1. The engine (embedded if it's a browser) reads ("parses") the script.
+2. Then it converts ("compiles") the script to machine code.
+3. And then the machine code runs, pretty fast.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 Silnik stosuje różne optymalizacje na każdym z kroków tego procesu. Co więcej, obserwuje on skompilowany kod podczas działania, analizuje przepływ danych i optymalizuje kod maszynowy, bazując na tej wiedzy.
 ```
 
 ## Co potrafi JavaScript w przeglądarce?
 
+<<<<<<< HEAD
 Współczesny JavaScript jest "bezpiecznym" językiem programowania. Nie umożliwia on, na przykład, niskopoziomowego dostępu do pamięci czy procesora, ponieważ został pierwotnie stworzony dla przeglądarek, które tego nie potrzebują.
+=======
+Modern JavaScript is a "safe" programming language. It does not provide low-level access to memory or the CPU, because it was initially created for browsers which do not require it.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 Możliwości JavaScriptu w dużej mierze zależą od środowiska, w którym jest uruchamiany. Przykładowo, [Node.js](https://pl.wikipedia.org/wiki/Node.js) dostarcza mechanizmy umożliwiające odczyt/zapis plików, wykonywanie zapytań sieciowych itp.
 
@@ -59,14 +85,23 @@ Przeglądarkowy JavaScript może więc:
 
 ## Czego NIE potrafi Javascript w przeglądarce?
 
+<<<<<<< HEAD
 Możliwości przeglądarkowego JavaScriptu są ograniczone ze względu na bezpieczeństwo użytkownika. Celem jest zapobieganie dostępu do prywatnych danych użytkownika przez złośliwe strony.
+=======
+JavaScript's abilities in the browser are limited to protect the user's safety. The aim is to prevent an evil webpage from accessing private information or harming the user's data.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 Przykładami takich restrykcji są:
 
+<<<<<<< HEAD
 - JavaScript zawarty na stronie nie może odczytywać/zapisywać plików na dysku twardym, kopiować ich ani uruchamiać programów. Nie ma bezpośredniego dostępu do funkcji systemu operacyjnego.
+=======
+- JavaScript on a webpage may not read/write arbitrary files on the hard disk, copy them or execute programs. It has no direct access to OS functions.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
     Współczesne przeglądarki pozwalają na przetwarzanie plików, jednak dostęp jest ograniczony do sytuacji, w których użytkownik wykona odpowiednie akcje, np. "przeciągnie" plik do okna przeglądarki lub wybierze go poprzez element `<input>`.
 
+<<<<<<< HEAD
     Istnieją również sposoby na interakcję z kamerą/mikrofonem lub podobnymi urządzeniami, jednak wymagają one wyraźnego pozwolenia ze strony użytkownika. Tak więc strona z włączonym JavaScriptem nie włączy cichaczem kamerki internetowej, nie zeskanuje otoczenia i nie wyśle nagrania do [CBŚ](https://pl.wikipedia.org/wiki/Centralne_Biuro_%C5%9Aledcze_Policji).
 - Poszczególne zakładki/okna przeglądarki zazwyczaj niczego nie wiedzą o sobie nawzajem. Czasem jednak mają do siebie dostęp, np. jeśli jedno okno otworzy drugie przy pomocy skryptu. Jednak nawet wtedy skrypt z jednej strony nie będzie miał dostępu do innego, jeśli pochodzi on z innej strony (ma inną domenę, protokół czy port).
 
@@ -78,21 +113,44 @@ Przykładami takich restrykcji są:
 ![](limitations.svg)
 
 Powyższe ograniczenia nie istnieją dla kodu JavaScript uruchamianego poza przeglądarką, na przykład na serwerze. Ponadto, współczesne przeglądarki umożliwiają wtyczkom uzyskiwanie rozszerzonych uprawnień.
+=======
+    There are ways to interact with the camera/microphone and other devices, but they require a user's explicit permission. So a JavaScript-enabled page may not sneakily enable a web-camera, observe the surroundings and send the information to the [NSA](https://en.wikipedia.org/wiki/National_Security_Agency).
+- Different tabs/windows generally do not know about each other. Sometimes they do, for example when one window uses JavaScript to open the other one. But even in this case, JavaScript from one page may not access the other page if they come from different sites (from a different domain, protocol or port).
+
+    This is called the "Same Origin Policy". To work around that, *both pages* must agree for data exchange and must contain special JavaScript code that handles it. We'll cover that in the tutorial.
+
+    This limitation is, again, for the user's safety. A page from `http://anysite.com` which a user has opened must not be able to access another browser tab with the URL `http://gmail.com`, for example, and steal information from there.
+- JavaScript can easily communicate over the net to the server where the current page came from. But its ability to receive data from other sites/domains is crippled. Though possible, it requires explicit agreement (expressed in HTTP headers) from the remote side. Once again, that's a safety limitation.
+
+![](limitations.svg)
+
+Such limitations do not exist if JavaScript is used outside of the browser, for example on a server. Modern browsers also allow plugins/extensions which may ask for extended permissions.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ## Dlaczego JavaScript jest wyjątkowy?
 
 Istnieją co najmniej *trzy* powody świetności JavaScriptu:
 
 ```compare
+<<<<<<< HEAD
 + Pełna integracja z HTML-em i CSS-em.
 + Proste rzeczy można zrobić w prosty sposób.
 + Jest wspierany przez większość przeglądarek oraz domyślnie w nich włączony.
+=======
++ Full integration with HTML/CSS.
++ Simple things are done simply.
++ Supported by all major browsers and enabled by default.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 ```
 JavaScript jest jedyną technologią przeglądarkową, która posiada te trzy cechy.
 
 To właśnie sprawia, że jest taki unikatowy. To dzięki temu jest najczęstszym narzędziem używanym do tworzenia interfejsów przeglądarkowych.
 
+<<<<<<< HEAD
 Nie można jednak zapominać, że JavaScript doskonale nadaje się do tworzenia serwerów czy aplikacji mobilnych.
+=======
+That said, JavaScript can be used to create servers, mobile applications, etc.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ## Języki oparte o JavaScript
 
@@ -100,21 +158,42 @@ Składnia JavaScriptu nie spełnia wymagań wszystkich osób. Różni ludzie pot
 
 Nie ma w tym nic dziwnego, w końcu projekty i ich wymagania bywają bardzo różne.
 
+<<<<<<< HEAD
 Z tego powodu w ostatnim czasie powstały niezliczone ilości nowych języków, które są *transpilowane* (konwertowane) do JavaScriptu przed uruchomieniem.
+=======
+So, recently a plethora of new languages appeared, which are *transpiled* (converted) to JavaScript before they run in the browser.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 Współczesne narzędzia pozwalają na szybką i przejrzystą transpilację, umożliwiając deweloperom na pisanie kodu w innym języku i automatycznie go konwertując do JavaScriptu.
 
 Przykłady takich języków:
 
+<<<<<<< HEAD
 - [CoffeeScript](http://coffeescript.org/) jest "lukrem składniowym" (ang. *syntactic sugar*) dla JavaScriptu. Wprowadza krótszą składnie, pozwalając na pisanie precyzyjnego i bardziej przejrzystego kodu. Ma zwolenników wśród programistów języka Ruby.
 - [TypeScript](http://www.typescriptlang.org/) skupia się na dodaniu "rygorystycznego typowania danych" w celu ułatwienia dewelopmentu i lepszego wsparcia dla skomplikowanych systemów. Jest rozwijany przez Microsoft.
 - [Flow](http://flow.org/) również dodaje typy, ale w nieco inny sposób. Rozwijany przez Facebooka.
 - [Dart](https://www.dartlang.org/) jest odrębnym językiem, posiadającym własny silnik, który działa poza przeglądarką (np. w aplikacjach mobilnych), ale może być także transpilowany do JavaScriptu. Rozwijany przez Google.
 
 Jest ich więcej. Rzecz jasna, nawet jeśli używamy któregoś z języków transpilowanych, powinniśmy znać JavaScript, aby lepiej rozumieć, co się dzieje w kodzie.
+=======
+- [CoffeeScript](https://coffeescript.org/) is "syntactic sugar" for JavaScript. It introduces shorter syntax, allowing us to write clearer and more precise code. Usually, Ruby devs like it.
+- [TypeScript](https://www.typescriptlang.org/) is concentrated on adding "strict data typing" to simplify the development and support of complex systems. It is developed by Microsoft.
+- [Flow](https://flow.org/) also adds data typing, but in a different way. Developed by Facebook.
+- [Dart](https://www.dartlang.org/) is a standalone language that has its own engine that runs in non-browser environments (like mobile apps), but also can be transpiled to JavaScript. Developed by Google.
+- [Brython](https://brython.info/) is a Python transpiler to JavaScript that enables the writing of applications in pure Python without JavaScript.
+- [Kotlin](https://kotlinlang.org/docs/reference/js-overview.html) is a modern, concise and safe programming language that can target the browser or Node.
+
+There are more. Of course, even if we use one of these transpiled languages, we should also know JavaScript to really understand what we're doing.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ## Podsumowanie
 
+<<<<<<< HEAD
 - JavaScript został stworzony jako język tylko dla przeglądarek, jednak obecnie używa się go także w wielu innych środowiskach.
 - Uplasował się na dogodnej pozycji jako najszerzej stosowany język przeglądarkowy o pełnej integrowalności z HTML-em i CSS-em.
 - Istnieje wiele języków "transpilowanych" do JavaScriptu, które dodają konkretne funkcjonalności. Dobrze jest się z nimi zapoznać po nauce JavaScriptu, choćby pobieżnie.
+=======
+- JavaScript was initially created as a browser-only language, but it is now used in many other environments as well.
+- Today, JavaScript has a unique position as the most widely-adopted browser language, fully integrated with HTML/CSS.
+- There are many languages that get "transpiled" to JavaScript and provide certain features. It is recommended to take a look at them, at least briefly, after mastering JavaScript.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
diff --git a/1-js/01-getting-started/2-manuals-specifications/article.md b/1-js/01-getting-started/2-manuals-specifications/article.md
index 49094dde6..682b5c308 100644
--- a/1-js/01-getting-started/2-manuals-specifications/article.md
+++ b/1-js/01-getting-started/2-manuals-specifications/article.md
@@ -1,7 +1,11 @@
 
 # Podręczniki i specyfikacje
 
+<<<<<<< HEAD
 Ta książka służy jako *samouczek*. Pozwala stopniowo wdrażać się w język. Jednak gdy tylko zapoznasz się z podstawami, nadejdzie czas na zgłębienie wiedzy z innych źródeł.
+=======
+This book is a *tutorial*. It aims to help you gradually learn the language. But once you're familiar with the basics, you'll need other resources.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ## Specyfikacja
 
@@ -9,14 +13,23 @@ Ta książka służy jako *samouczek*. Pozwala stopniowo wdrażać się w język
 
 Przez tę całą formalność trudniej jest jednak ją zrozumieć. Dlatego jeśli potrzebujesz najbardziej wiarygodnego źródła informacji o szczegółach dotyczących języka, zajrzenie do specyfikacji jest najlepszym wyjściem. Nie służy ona jednak do codziennego użytku.
 
+<<<<<<< HEAD
 Co roku wypuszczana jest nowa wersja specyfikacji. W międzyczasie wszelkie aktualne "szkice" można zobaczyć na <https://tc39.es/ecma262/>.
+=======
+A new specification version is released every year. Between these releases, the latest specification draft is at <https://tc39.es/ecma262/>.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 Aby dowiedzieć się czegoś o najświeższych funkcjonalnościach, wliczając w to te, które "są już prawie częścią standardu" (są na tzw. "etapie 3"), przejrzyj listę wniosków na <https://github.com/tc39/proposals>.
 
+<<<<<<< HEAD
 Jeśli piszesz kod dla przeglądarek, w [drugiej części](info:browser-environment) samouczka znajdziesz więcej materiałów.
+=======
+Also, if you're developing for the browser, then there are other specifications covered in the [second part](info:browser-environment) of the tutorial.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ## Podręczniki
 
+<<<<<<< HEAD
 - **Dokumentacja referencyjna JavaScript na MDN (Mozilla)** służy za poradnik z przykładami i innymi informacjami. Świetnie nadaje się do zgłębiania wiedzy na temat poszczególnych funkcjonalności języka, interfejsów itd.
 
     Dostępna jest pod adresem <https://developer.mozilla.org/pl/docs/Web/JavaScript/Referencje>.
@@ -27,6 +40,13 @@ Jeśli piszesz kod dla przeglądarek, w [drugiej części](info:browser-environm
 - **MSDN** – podręcznik od Microsoftu zawierający sporo informacji, m.in. o JavaScripcie (często nazywany JScriptem). Jeśli szukasz czegoś konkretnego z tematyki Internet Explorera, lepiej zajrzyj na <http://msdn.microsoft.com/>.
 
     Można też przeszukać internet przy użyciu fraz "[pojęcie] MSDN" lub "[pojęcie] MSDN jscript", np. "RegExp MSDN".
+=======
+- **MDN (Mozilla) JavaScript Reference** is the main manual with examples and other information. It's great to get in-depth information about individual language functions, methods etc.
+
+    You can find it at <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference>.
+
+Although, it's often best to use an internet search instead. Just use "MDN [term]" in the query, e.g. <https://google.com/search?q=MDN+parseInt> to search for the `parseInt` function.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ## Tabele kompatybilności
 
@@ -34,9 +54,16 @@ JavaScript jest językiem intensywnie rozwijanym, dlatego dość często pojawia
 
 Jeśli chcesz dowiedzieć się, jak wygląda wsparcie dla nich w poszczególnych silnikach (przeglądarkowych i innych), odwiedź:
 
+<<<<<<< HEAD
 - <http://caniuse.com> - tabela kompatybilności dla każdej z funkcji z osobna. Na przykład, jeśli chcesz sprawdzić, które silniki wspierają funkcje kryptograficzne: <http://caniuse.com/#feat=cryptography>.
 - <https://kangax.github.io/compat-table> - tabela z wypisanymi funkcjonalnościami języka oraz informacjami, które silniki je wspierają, a które nie.
 
 Wszystkie z powyższych źródeł są przydatne podczas codziennego dewelopmentu, jako że zawierają cenne informacje o szczegółach języka, wsparcia dla nich itp.
+=======
+- <https://caniuse.com> - per-feature tables of support, e.g. to see which engines support modern cryptography functions: <https://caniuse.com/#feat=cryptography>.
+- <https://kangax.github.io/compat-table> - a table with language features and engines that support those or don't support.
+
+All these resources are useful in real-life development, as they contain valuable information about language details, their support, etc.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 Pamiętaj o nich (lub o tej stronie) na wypadek potrzeby zasięgnięcia informacji o konkretnej funkcjonalności.
diff --git a/1-js/01-getting-started/3-code-editors/article.md b/1-js/01-getting-started/3-code-editors/article.md
index eb9282b94..0c3c1db1e 100644
--- a/1-js/01-getting-started/3-code-editors/article.md
+++ b/1-js/01-getting-started/3-code-editors/article.md
@@ -12,8 +12,13 @@ IDE ładuje projekt (który może mieć mnóstwo plików), pozwala nawigować mi
 
 Jeśli nie masz jeszcze wybranego żadnego IDE, rozważ następujące opcje:
 
+<<<<<<< HEAD
 - [Visual Studio Code](https://code.visualstudio.com/) (cross-platform, darmowy).
 - [WebStorm](http://www.jetbrains.com/webstorm/) (cross-platform, płatny).
+=======
+- [Visual Studio Code](https://code.visualstudio.com/) (cross-platform, free).
+- [WebStorm](https://www.jetbrains.com/webstorm/) (cross-platform, paid).
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 Dla systemu Windows istnieje jeszcze "Visual Studio", którego nie należy mylić z "Visual Studio Code". "Visual Studio" jest rozbudowanym i płatnym edytorem tylko dla systemu Windows, świetnie dopasowanym do platformy .NET. Jest również dobry dla JavaScriptu. Dostępna jest również darmowa wersja [Visual Studio Community](https://www.visualstudio.com/vs/community/).
 
@@ -29,6 +34,7 @@ Główna różnica pomiędzy lekkim edytorem a środowiskiem programistycznym po
 
 W praktyce jednak lekkie edytory mają wiele wtyczek, które wspomagają pracę, analizują i dostarcząją autouzupełnianie na poziomie projektu, więc granica pomiędzy lekkimi edytorami a IDE powoli się zaciera.
 
+<<<<<<< HEAD
 Poniższe przykłady zasługują na twoją uwagę: 
 
 - [Atom](https://atom.io/) (wieloplatformowy, darmowy).
@@ -36,6 +42,13 @@ Poniższe przykłady zasługują na twoją uwagę:
 - [Sublime Text](http://www.sublimetext.com) (wieloplatformowy, shareware).
 - [Notepad++](https://notepad-plus-plus.org/) (Windows, darmowy).
 - [Vim](http://www.vim.org/) i [Emacs](https://www.gnu.org/software/emacs/) są świetne, pod warunkiem że wiesz, jak na nich pracować.
+=======
+There are many options, for instance:
+
+- [Sublime Text](https://www.sublimetext.com/) (cross-platform, shareware).
+- [Notepad++](https://notepad-plus-plus.org/) (Windows, free).
+- [Vim](https://www.vim.org/) and [Emacs](https://www.gnu.org/software/emacs/) are also cool if you know how to use them.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ## Nie sprzeczajmy się
 
@@ -43,4 +56,13 @@ Edytory na powyższej liście to narzędzia, z których sam korzystam lub korzys
 
 Jest mnóstwo takich programów w naszym dużym świecie. Używaj tego, który lubisz najbardziej. 
 
+<<<<<<< HEAD
 Wybór edytora, jak i dowolnego innego narzędzia deweloperskiego, jest naszą indywidualną sprawą, zależną od potrzeb w projekcie, przyzwyczajeń czy osobistych preferencji.
+=======
+The choice of an editor, like any other tool, is individual and depends on your projects, habits, and personal preferences.
+
+The author's personal opinion:
+
+- I'd use [Visual Studio Code](https://code.visualstudio.com/) if I develop mostly frontend.
+- Otherwise, if it's mostly another language/platform and partially frontend, then consider other editors, such as XCode (Mac), Visual Studio (Windows) or Jetbrains family (Webstorm, PHPStorm, RubyMine etc, depending on the language).
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
diff --git a/1-js/02-first-steps/01-hello-world/1-hello-alert/index.html b/1-js/02-first-steps/01-hello-world/1-hello-alert/index.html
new file mode 100644
index 000000000..ff1d871b0
--- /dev/null
+++ b/1-js/02-first-steps/01-hello-world/1-hello-alert/index.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+
+<body>
+
+  <script>
+    alert( "I'm JavaScript!" );
+  </script>
+
+</body>
+
+</html>
diff --git a/1-js/02-first-steps/01-hello-world/1-hello-alert/solution.md b/1-js/02-first-steps/01-hello-world/1-hello-alert/solution.md
index e69de29bb..81552913b 100644
--- a/1-js/02-first-steps/01-hello-world/1-hello-alert/solution.md
+++ b/1-js/02-first-steps/01-hello-world/1-hello-alert/solution.md
@@ -0,0 +1,2 @@
+
+[html src="index.html"]
diff --git a/1-js/02-first-steps/01-hello-world/article.md b/1-js/02-first-steps/01-hello-world/article.md
index 85beeccc3..e26a9a8ce 100644
--- a/1-js/02-first-steps/01-hello-world/article.md
+++ b/1-js/02-first-steps/01-hello-world/article.md
@@ -9,7 +9,11 @@ Na początek zobaczmy, jak podpiąć skrypt do naszej strony. W środowiskach se
 
 ## Znacznik "script"
 
+<<<<<<< HEAD
 Programy napisane w JavaScripcie można wrzucić do dowolnej części dokumentu HTML za pomocą znacznika `<script>`.
+=======
+JavaScript programs can be inserted almost anywhere into an HTML document using the `<script>` tag.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 Na przykład:
 
@@ -45,8 +49,13 @@ Znacznik `<script>` zawiera kod javascriptowy, który jest automatycznie wywoły
 
 Znacznik `<script>` posiada kilka atrybutów, których współcześnie się nie używa, a na które można się natknąć w starym kodzie:
 
+<<<<<<< HEAD
 Atrybut `type`: <code>&lt;script <u>type</u>=...&gt;</code>
 : Stary standard HTML, czyli HTML4, wymagał, aby skrypty miały określony typ (`type`). Zwykle było to `type="text/javascript"`. Obecnie nie jest on już wymagany. Ponadto, w aktualnym standardzie HTML całkowicie zmieniło się jego znaczenie - teraz stosuje się go przy modułach javascriptowych. Ale to zaawansowany temat. O modułach będziemy mówić w innej części samouczka.
+=======
+The `type` attribute: <code>&lt;script <u>type</u>=...&gt;</code>
+: The old HTML standard, HTML4, required a script to have a `type`. Usually it was `type="text/javascript"`. It's not required anymore. Also, the modern HTML standard totally changed the meaning of this attribute. Now, it can be used for JavaScript modules. But that's an advanced topic, we'll talk about modules in another part of the tutorial.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 Atrybut `language`: <code>&lt;script <u>language</u>=...&gt;</code>
 : Ten atrybut służył do określenia języka skryptu. Obecnie nie ma on większego sensu, ponieważ JavaScript jest domyślnym językiem. Nie trzeba go używać.
@@ -73,12 +82,16 @@ Pliki skryptowe dołącza się do HTML-a za pomocą atrybutu `src`:
 <script src="/ścieżka/do/skryptu.js"></script>
 ```
 
+<<<<<<< HEAD
 W tym przykładzie `/ścieżka/do/skryptu.js` to ścieżka bezwzględna do pliku, licząc od katalogu głównego strony. Można jednak podać ścieżkę względną, liczoną od położenia aktualnej strony. Na przykład, `src="skrypt.js"` odnosi się do pliku `"skrypt.js"` w tym samym folderze.
+=======
+Here, `/path/to/script.js` is an absolute path to the script from the site root. One can also provide a relative path from the current page. For instance, `src="script.js"`, just like `src="./script.js"`, would mean a file `"script.js"` in the current folder.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 Oprócz tego mamy możliwość podania pełnego adresu URL, na przykład:
 
 ```html
-<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.2.0/lodash.js"></script>
+<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
 ```
 
 Jeśli chcesz dodać kilka skryptów, wstaw więcej znaczników:
diff --git a/1-js/02-first-steps/02-structure/article.md b/1-js/02-first-steps/02-structure/article.md
index 8fb05366f..39429f96e 100644
--- a/1-js/02-first-steps/02-structure/article.md
+++ b/1-js/02-first-steps/02-structure/article.md
@@ -45,7 +45,11 @@ Istnieje kilka sytuacji, w których nowa linia nie oznacza, że powinien tam zna
 alert(3 + 1 + 2);
 ```
 
+<<<<<<< HEAD
 Kod zwróci `6`, ponieważ JavaScript nie wstawi średnika na końcu linii. Wydaje się oczywistym, że jeśli linia kończy się wyrażeniem, na przykład plusem `"+"`, to mamy do czynienia z "niepełnym wyrażeniem" i średnik nie jest wymagany. I w tym przypadku działa to zgodnie z oczekiwaniami.
+=======
+The code outputs `6` because JavaScript does not insert semicolons here. It is intuitively obvious that if the line ends with a plus `"+"`, then it is an "incomplete expression", so a semicolon there would be incorrect. And in this case, that works as intended.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 **Są jednak sytuacje, w których JavaScript błędnie zakłada, gdzie średnik jest rzeczywiście potrzebny.**
 
@@ -55,19 +59,31 @@ Błąd, który się pojawi w takim przypadku, jest trudny do wykrycia i naprawie
 Jeśli ciekawi cię konkretny przykład takiego błędu, uruchom poniższy kod:
 
 ```js run
-[1, 2].forEach(alert)
+alert("Hello");
+
+[1, 2].forEach(alert);
 ```
 
+<<<<<<< HEAD
 Nie musisz się zastanawiać, co oznaczają te nawiasy kwadratowe `[]` ani czym jest `forEach`. Będzie o tym później. Na tę chwilę musisz wiedzieć, że rezultatem będzie wyświetlenie najpierw `1`, a później `2`.
 
 Teraz dodaj `alert` przed kodem i *nie* dodawaj średnika na końcu linii:
 
 ```js run no-beautify
 alert("Tutaj będzie błąd")
+=======
+No need to think about the meaning of the brackets `[]` and `forEach` yet. We'll study them later. For now, just remember the result of running the code: it shows `Hello`, then `1`, then `2`.
 
-[1, 2].forEach(alert)
+Now let's remove the semicolon after the `alert`:
+
+```js run no-beautify
+alert("Hello")
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
+
+[1, 2].forEach(alert);
 ```
 
+<<<<<<< HEAD
 Jeśli uruchomimy powyższy kod, zobaczymy tylko pierwszy `alert`, a następnie otrzymamy komunikat błędu w konsoli!
 
 Wszystko jednak zacznie działać, gdy tylko umieścimy średnik po pierwszej instrukcji:
@@ -89,11 +105,32 @@ alert("Tutaj będzie błąd")[1, 2].forEach(alert)
 ```
 
 To powinny być dwie oddzielne instrukcje, ale nie są. Takie łączenie jest po prostu błędne i może pojawić się również w wielu innych sytuacjach.
+=======
+The difference compared to the code above is only one character: the semicolon at the end of the first line is gone.
+
+If we run this code, only the first `Hello` shows (and there's an error, you may need to open the console to see it). There are no numbers any more.
+
+That's because JavaScript does not assume a semicolon before square brackets `[...]`. So, the code in the last example is treated as a single statement.
+
+Here's how the engine sees it:
+
+```js run no-beautify
+alert("Hello")[1, 2].forEach(alert);
+```
+
+Looks weird, right? Such merging in this case is just wrong. We need to put a semicolon after `alert` for the code to work correctly.
+
+This can happen in other situations also.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 ````
 
 Zalecamy używanie średników nawet wtedy, gdy instrukcje są oddzielone nową linią. Społeczność programistów przyjęła taką właśnie zasadę. Zanotujmy to jeszcze raz -- _istnieje możliwość_ nie wpisywania średników w większości przypadków. Ale bezpieczniej jest -- szczególnie dla początkujących -- używać ich zawsze.
 
+<<<<<<< HEAD
 ## Komentarze
+=======
+## Comments [#code-comments]
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 Z czasem programy stają się coraz bardziej złożone. Przychodzi wtedy konieczność dodania _komentarzy_, które opisują, co robi kod i dlaczego.
 
@@ -135,8 +172,13 @@ alert('Witaj');
 alert("świecie");
 ```
 
+<<<<<<< HEAD
 ```smart header="Używaj skrótów klawiaturowych!"
 W większości edytorów można zamienić jedną linię w komentarz za pomocą klawiszy `key:Ctrl+/` lub kilka linii za pomocą `key:Ctrl+Shift+/` (zaznacz fragment kodu i po prostu wciśnij te klawisze). Jeśli korzystasz z Maca, zamiast `key:Ctrl` użyj `key:Cmd`.
+=======
+```smart header="Use hotkeys!"
+In most editors, a line of code can be commented out by pressing the `key:Ctrl+/` hotkey for a single-line comment and something like `key:Ctrl+Shift+/` -- for multiline comments (select a piece of code and press the hotkey). For Mac, try `key:Cmd` instead of `key:Ctrl` and `key:Option` instead of `key:Shift`.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 ```
 
 ````warn header="Nie można zagnieżdżać komentarzy!"
diff --git a/1-js/02-first-steps/03-strict-mode/article.md b/1-js/02-first-steps/03-strict-mode/article.md
index 7b11975a6..49365ddc1 100644
--- a/1-js/02-first-steps/03-strict-mode/article.md
+++ b/1-js/02-first-steps/03-strict-mode/article.md
@@ -19,8 +19,12 @@ Dla przykładu:
 ...
 ```
 
+<<<<<<< HEAD
 W niedługim czasie nauczysz się funkcji (sposobu łączenia instrukcji w grupy). Zauważ, że trybu ścisłego `"use strict"` można użyć na początku funkcji zamiast umieszczać na początku całego skryptu. Jeśli tak zrobisz, tryb ścisły będzie obowiązywał tylko w wybranej funkcji. Zazwyczaj jednak stosuje się go dla całego skryptu.
 
+=======
+Quite soon we're going to learn functions (a way to group commands), so let's note in advance that `"use strict"` can be put at the beginning of a function. Doing that enables strict mode in that function only. But usually people use it for the whole script.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ````warn header="Upewnij się, że \"use strict\" jest na samej górze"
 Upewnij się, że dyrektywa `"use strict"` znajduje się na samej górze skryptu. W przeciwnym wypadku tryb ten nie zostanie włączony.
@@ -47,11 +51,21 @@ Jeśli włączysz tryb ścisły, nie ma już odwrotu.
 
 ## Konsola przeglądarki
 
+<<<<<<< HEAD
 Tak na przyszłość, jeśli chcesz używać konsoli przeglądarki do testowania swoich funkcjonalności, pamiętaj, że tryb ścisły `use strict` nie jest domyślnie włączony.
+=======
+When you use a [developer console](info:devtools) to run code, please note that it doesn't `use strict` by default.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 W niektórych sytuacjach użycie tego trybu skutkuje otrzymywaniem niewłaściwych rezultatów.
 
+<<<<<<< HEAD
 Naciśnij `key:Shift+Enter`, żeby wpisać kod w wielu liniach i wpisz `use strict` na samej górze, jak tutaj:
+=======
+So, how to actually `use strict` in the console?
+
+First, you can try to press `key:Shift+Enter` to input multiple lines, and put `use strict` on top, like this:
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ```js
 'use strict'; <Shift+Enter dla nowej linii>
@@ -61,12 +75,17 @@ Naciśnij `key:Shift+Enter`, żeby wpisać kod w wielu liniach i wpisz `use stri
 
 Działa na większości przeglądarek, a z pewnością na Firefoksie i Chromie.
 
+<<<<<<< HEAD
 Jeśli jednak z jakiegoś powodu nie zadziała, wystarczy że użyjesz poniższego kodu:
+=======
+If it doesn't, e.g. in an old browser, there's an ugly, but reliable way to ensure `use strict`. Put it inside this kind of wrapper:
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ```js
 (function() {
   'use strict';
 
+<<<<<<< HEAD
   // ...twój kod...
 })()
 ```
@@ -82,4 +101,25 @@ Póki co, wystarczy, jeśli wiesz, że:
 1. Dyrektywa `"use strict"` przełącza silnik JavaScript w tryb "nowoczesny" (ścisły). Zmienia to zachowanie wbudowanych funkcjonalności. O szczegółach dowiesz się z kolejnych rozdziałów.
 2. Tryb ścisły jest włączany, gdy umieścisz dyrektywę `"use strict"` na początku skryptu lub funkcji. Niektóre z funkcjonalności języka, takie jak "klasy" czy "moduły", włączają tryb ścisły wewnątrz siebie automatycznie.
 3. Tryb ścisły jest wspierany przez wszystkie nowoczesne przeglądarki internetowe.
-4. Zalecamy zaczynanie wszystkich skryptów od dyrektywy `"use strict"`. Wszystkie przykłady w tym samouczku zakładają, że tryb jest włączony, chyba że (bardzo rzadko) określono inaczej.
\ No newline at end of file
+4. Zalecamy zaczynanie wszystkich skryptów od dyrektywy `"use strict"`. Wszystkie przykłady w tym samouczku zakładają, że tryb jest włączony, chyba że (bardzo rzadko) określono inaczej.
+=======
+  // ...your code here...
+})()
+```
+
+## Should we "use strict"?
+
+The question may sound obvious, but it's not so.
+
+One could recommend to start scripts with `"use strict"`... But you know what's cool?
+
+Modern JavaScript supports "classes" and "modules" - advanced language structures (we'll surely get to them), that enable `use strict` automatically. So we don't need to add the `"use strict"` directive, if we use them.
+
+**So, for now `"use strict";` is a welcome guest at the top of your scripts. Later, when your code is all in classes and modules, you may omit it.**
+
+As of now, we've got to know about `use strict` in general.
+
+In the next chapters, as we learn language features, we'll see the differences between the strict and old modes. Luckily, there aren't many and they actually make our lives better.
+
+All examples in this tutorial assume strict mode unless (very rarely) specified otherwise.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
diff --git a/1-js/02-first-steps/04-variables/2-declare-variables/solution.md b/1-js/02-first-steps/04-variables/2-declare-variables/solution.md
index 81ab1a538..44901f4bc 100644
--- a/1-js/02-first-steps/04-variables/2-declare-variables/solution.md
+++ b/1-js/02-first-steps/04-variables/2-declare-variables/solution.md
@@ -6,7 +6,11 @@ To proste:
 let ourPlanetName = "Ziemia";
 ```
 
+<<<<<<< HEAD
 Zauważ, że mogliśmy użyć krótszej nazwy `planet`, ale nie jest oczywiste, do jakiej planety się odnosimy. Dobrze jest być konkretnym. Przynajmniej dopóki nazwa nie jest za długa.
+=======
+Note, we could use a shorter name `planet`, but it might not be obvious what planet it refers to. It's nice to be more verbose. At least until the variable isNotTooLong.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ## Nazwa obecnego użytkownika
 
diff --git a/1-js/02-first-steps/04-variables/3-uppercast-constant/task.md b/1-js/02-first-steps/04-variables/3-uppercast-constant/task.md
index 9a874d4fc..96fba0fd4 100644
--- a/1-js/02-first-steps/04-variables/3-uppercast-constant/task.md
+++ b/1-js/02-first-steps/04-variables/3-uppercast-constant/task.md
@@ -12,13 +12,24 @@ const birthday = '18.04.1982';
 const age = someCode(birthday);
 ```
 
+<<<<<<< HEAD
 Mamy tutaj stałą datę urodzenia `birthday` oraz wiek `age`, który jest obliczany na podstawie `birthday` za pomocą jakiegoś kodu (który nie jest podany dla uproszczenia, ponieważ szczegóły nie są tutaj istotne).
+=======
+Here we have a constant `birthday` for the date, and also the `age` constant.
+
+The `age` is calculated from `birthday` using `someCode()`, which means a function call that we didn't explain yet (we will soon!), but the details don't matter here, the point is that `age` is calculated somehow based on the `birthday`.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 Czy byłoby poprawne użycie wielkich liter dla `birthday`? Albo dla `age`? A może nawet dla obydwóch zmiennych?
 
 ```js
+<<<<<<< HEAD
 const BIRTHDAY = '18.04.1982'; // wielkimi literami?
 
 const AGE = someCode(BIRTHDAY); // wielkimi literami?
-```
+=======
+const BIRTHDAY = '18.04.1982'; // make birthday uppercase?
 
+const AGE = someCode(BIRTHDAY); // make age uppercase?
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
+```
diff --git a/1-js/02-first-steps/04-variables/article.md b/1-js/02-first-steps/04-variables/article.md
index 235dbd905..4fa455c71 100644
--- a/1-js/02-first-steps/04-variables/article.md
+++ b/1-js/02-first-steps/04-variables/article.md
@@ -24,7 +24,11 @@ Teraz możemy przypisać do niej jakieś dane używając operatora przypisania `
 let message;
 
 *!*
+<<<<<<< HEAD
 message = 'Witaj'; // przechowaj ciąg znaków
+=======
+message = 'Hello'; // store the string 'Hello' in the variable named message
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 */!*
 ```
 
@@ -63,7 +67,12 @@ let age = 25;
 let message = 'Witaj';
 ```
 
+<<<<<<< HEAD
 Niektórzy ludzie definiują wiele zmiennych w tym stylu:
+=======
+Some people also define multiple variables in this multiline style:
+
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 ```js no-beautify
 let user = 'Jan',
   age = 25,
@@ -80,30 +89,50 @@ let user = 'Jan'
 
 Wszystkie powyższe przykłady działają tak samo. Wybór zależy od osobistego gustu i poczucia estetyki.
 
+<<<<<<< HEAD
 
 ````smart header="`var` zamiast `let`"
 W starszych skryptach możesz napotkać słowo kluczowe `var` zamiast `let`:
+=======
+````smart header="`var` instead of `let`"
+In older scripts, you may also find another keyword: `var` instead of `let`:
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ```js
 *!*var*/!* message = 'Witaj';
 ```
 
+<<<<<<< HEAD
 Słowo kluczowe `var` jest *prawie* tożsame z `let`. Również deklaruje zmienną, lecz w nieco inny, starodawny sposób.
 
 Istnieją subtelne różnice pomiędzy `let` i `var`, ale nie mają one dla nas jeszcze znaczenia na tym etapie nauki. Omówimy je szczegółowo w rozdziale pt. "<info:var>".
+=======
+The `var` keyword is *almost* the same as `let`. It also declares a variable but in a slightly different, "old-school" way.
+
+There are subtle differences between `let` and `var`, but they do not matter to us yet. We'll cover them in detail in the chapter <info:var>.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 ````
 
 ## Analogia do życia
 
 Możemy łatwo pojąć pojęcie "zmiennej", jeśli wyobrazimy sobie ją jako "pudełko" na dane, z naklejką o unikalnej nazwie.
 
+<<<<<<< HEAD
 Na przykład, zmienną `message` możemy wyobrazić sobie jako pudełko z etykietą `"message"` z wartością `"Witaj!"` wewnątrz:
+=======
+For instance, the variable `message` can be imagined as a box labelled `"message"` with the value `"Hello!"` in it:
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ![](variable.svg)
 
 W pudełku możemy umieścić jakąkolwiek wartość.
 
+<<<<<<< HEAD
 Możemy też zmienić tę wartość tyle razy, ile chcemy:
+=======
+We can also change it as many times as we want:
+
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 ```js run
 let message;
 
@@ -135,11 +164,34 @@ alert(hello); // Witaj, świecie!
 alert(message); // Witaj, świecie!
 ```
 
+<<<<<<< HEAD
 ```smart header="Języki funkcyjne"
 Warto zauważyć, że istnieją języki programowania [funkcyjnego](https://pl.wikipedia.org/wiki/Programowanie_funkcyjne), jak [Scala](http://www.scala-lang.org/) czy [Erlang](http://www.erlang.org/), które zabraniają zmiany wartości zmiennych.
 W takich językach, gdy wartość  trafi do "pudełka", pozostaje tam na zawsze. Jeśli chcemy przechować coś innego, język zmusza nas do utworzenia nowego pudełka (zadeklarowania nowej zmiennej). Nie możemy ponownie użyć starego.
 
 Choć na pierwszy rzut oka może się to wydawać trochę dziwne, te języki całkiem dobrze nadają się do pisania poważnych programów. Co więcej, istnieją obszary, takie jak obliczenia równoległe, w których takie ograniczenie daje pewne korzyści. Warto przestudiować tego typu języki (nawet jeśli nie planujesz go używać w najbliższym czasie), aby poszerzyć horyzonty.
+=======
+````warn header="Declaring twice triggers an error"
+A variable should be declared only once.
+
+A repeated declaration of the same variable is an error:
+
+```js run
+let message = "This";
+
+// repeated 'let' leads to an error
+let message = "That"; // SyntaxError: 'message' has already been declared
+```
+So, we should declare a variable once and then refer to it without `let`.
+````
+
+```smart header="Functional languages"
+It's interesting to note that there exist so-called [pure functional](https://en.wikipedia.org/wiki/Purely_functional_programming) programming languages, such as [Haskell](https://en.wikipedia.org/wiki/Haskell), that forbid changing variable values.
+
+In such languages, once the value is stored "in the box", it's there forever. If we need to store something else, the language forces us to create a new box (declare a new variable). We can't reuse the old one.
+
+Though it may seem a little odd at first sight, these languages are quite capable of serious development. More than that, there are areas like parallel computations where this limitation confers certain benefits.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 ```
 
 ## Nazywanie zmiennych [#variable-naming]
@@ -177,20 +229,33 @@ let 1a; // nie może zaczynać się od cyfry
 let my-name; // myślniki '-' nie są dozwolone
 ```
 
+<<<<<<< HEAD
 ```smart header="Wielkość liter ma znaczenie"
 Zmienne nazwane `apple` i `AppLE` są dwiema różnymi zmiennymi.
 ```
 
 ````smart header="Litery inne niż łacińskie są dozwolone, ale nie zalecane"
 Możliwe jest użycie dowolnego języka, w tym cyrylicy lub nawet hieroglifów:
+=======
+```smart header="Case matters"
+Variables named `apple` and `APPLE` are two different variables.
+```
+
+````smart header="Non-Latin letters are allowed, but not recommended"
+It is possible to use any language, including Cyrillic letters, Chinese logograms and so on, like this:
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ```js
 let имя = '...';
 let 我 = '...';
 ```
 
+<<<<<<< HEAD
 Technicznie rzecz biorąc, nie ma tu błędu (takie nazwy są dozwolone), ale istnieje międzynarodowa tradycja używania języka angielskiego do nazywania zmiennych.
 Nawet jeśli piszemy niewielki skrypt, może mieć on przed sobą długie życie. Mogą go kiedyś chcieć przeczytać ludzie z innych krajów.
+=======
+Technically, there is no error here. Such names are allowed, but there is an international convention to use English in variable names. Even if we're writing a small script, it may have a long life ahead. People from other countries may need to read it sometime.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 ````
 
 ````warn header="Nazwy zarezerwowane"
@@ -245,12 +310,20 @@ const myBirthday = '18.04.1982';
 myBirthday = '01.01.2001'; // błąd, nie można ponownie przypisać wartości do stałej!
 ```
 
+<<<<<<< HEAD
 Gdy programista jest pewien, że zmienna nigdy się nie zmieni, może zadeklarować ją za pomocą `const`, aby to zagwarantować i wyraźnie przekazać ten fakt wszystkim.
 
+=======
+When a programmer is sure that a variable will never change, they can declare it with `const` to guarantee and communicate that fact to everyone.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ### Stałe pisane wielkimi literami
 
+<<<<<<< HEAD
 Istnieje powszechna praktyka używania stałych jako aliasów dla trudnych do zapamiętania wartości, znanych przed wykonaniem programu.
+=======
+There is a widespread practice to use constants as aliases for difficult-to-remember values that are known before execution.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 Takie stałe są zapisywane za pomocą wielkich liter i podkreślników.
 
@@ -275,16 +348,29 @@ Zalety:
 
 Kiedy powinniśmy używać wielkich liter dla stałej i kiedy powinniśmy nazywać ją normalnie? Wyjaśnijmy to.
 
+<<<<<<< HEAD
 Bycie "stałą" oznacza po prostu, że jej wartość nigdy się nie zmienia. Istnieją jednak stałe znane przed wykonaniem (jak wartość szesnastkowa dla koloru czerwonego) i istnieją stałe, które *są obliczane* na bieżąco w czasie wykonywania, ale nie zmieniają się po ich początkowym przypisaniu.
 
 Na przykład:
+=======
+Being a "constant" just means that a variable's value never changes. But some constants are known before execution (like a hexadecimal value for red) and some constants are *calculated* in run-time, during the execution, but do not change after their initial assignment.
+
+For instance:
+
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 ```js
 const pageLoadTime = /* czas, jaki zajął stronie na wczytanie się */;
 ```
 
+<<<<<<< HEAD
 Wartość `pageLoadTime` nie jest znana przed załadowaniem strony, więc jest nazwana normalnie. Ale wciąż jest stała, ponieważ nie zmienia się po przypisaniu.
 
 Innymi słowy, stałe pisane wielkimi literami są używane tylko jako aliasy dla wartości ustawionych na sztywno.
+=======
+The value of `pageLoadTime` is not known before the page load, so it's named normally. But it's still a constant because it doesn't change after the assignment.
+
+In other words, capital-named constants are only used as aliases for "hard-coded" values.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ## Nazywaj rzeczy poprawnie
 
@@ -292,18 +378,31 @@ W temacie zmiennych jest jeszcze jedna, bardzo istotna kwestia.
 
 Nazwa zmiennej powinna mieć oczywiste znaczenie i opisywać dane, które przechowuje.
 
+<<<<<<< HEAD
 Nazewnictwo zmiennych jest jedną z najważniejszych i najbardziej złożonych umiejętności programowania. Szybkie spojrzenie na nazwy zmiennych może ujawnić, który kod został napisany przez początkującego, a który przez doświadczonego programistę.
 
 W prawdziwym projekcie większość czasu spędza się na modyfikowaniu i rozszerzaniu istniejącego kodu, zamiast pisać coś całkowicie od zera. Kiedy wracamy do jakiegoś kodu po robieniu czegoś innego przez jakiś czas, znacznie łatwiej jest znaleźć informacje, które są dobrze oznaczone. Lub, innymi słowy, gdy zmienne mają dobre nazwy.
+=======
+Variable naming is one of the most important and complex skills in programming. A glance at variable names can reveal which code was written by a beginner versus an experienced developer.
+
+In a real project, most of the time is spent modifying and extending an existing code base rather than writing something completely separate from scratch. When we return to some code after doing something else for a while, it's much easier to find information that is well-labelled. Or, in other words, when the variables have good names.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 Poświęć trochę czasu na zastanowienie się nad właściwą nazwę zmiennej przed jej zadeklarowaniem. Takie podejście odpłaci się z nawiązką.
 
 Niektóre z zasad wartych naśladowania to:
 
+<<<<<<< HEAD
 - Używaj czytelnych dla człowieka nazw, jak `userName` lub `shoppingCart`.
 - Trzymaj się z dala od skrótów lub krótkich nazw jak `a`, `b`, `c`, chyba że naprawdę wiesz, co robisz.
 - Twórz nazwy maksymalnie opisowe i zwięzłe. Przykłady złych nazw to `data` i `value`. Takie nazwy nic nie mówią. Można z nich korzystać tylko wtedy, gdy kontekst kodu czyni wyjątkowo oczywistym, co kryje się w tej zmiennej.
 - Ustal nazewnictwo ze swoim zespołem. Jeśli odwiedzający stronę jest nazywany "user", to kolejne, powiązane z nim zmienne powinny nazywać się `currentUser` lub `newUser`, a nie `currentVisitor` lub `newManInTown`.
+=======
+- Use human-readable names like `userName` or `shoppingCart`.
+- Stay away from abbreviations or short names like `a`, `b`, and `c`, unless you know what you're doing.
+- Make names maximally descriptive and concise. Examples of bad names are `data` and `value`. Such names say nothing. It's only okay to use them if the context of the code makes it exceptionally obvious which data or value the variable is referencing.
+- Agree on terms within your team and in your mind. If a site visitor is called a "user" then we should name related variables `currentUser` or `newUser` instead of `currentVisitor` or `newManInTown`.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 Brzmi prosto? Z pewnością. Ale tworzenie opisowych i zwięzłych nazw w praktyce nie jest proste. Śmiało, spróbuj!
 
diff --git a/1-js/02-first-steps/05-types/article.md b/1-js/02-first-steps/05-types/article.md
index a88c806fc..f92408ade 100644
--- a/1-js/02-first-steps/05-types/article.md
+++ b/1-js/02-first-steps/05-types/article.md
@@ -1,6 +1,14 @@
 # Typy danych
 
+<<<<<<< HEAD
 Zmienna w JavaScripcie może zawierać różne dane. Zmienna może być w jednej chwili łańcuchem znaków (ang. *string*), a w innym liczbą:
+=======
+A value in JavaScript is always of a certain type. For example, a string or a number.
+
+There are eight basic data types in JavaScript. Here, we'll cover them in general and in the next chapters we'll talk about each of them in detail.
+
+We can put any type in a variable. For example, a variable can at one moment be a string and then store a number:
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ```js
 // nie ma tu błędów
@@ -8,9 +16,13 @@ let message = "hello";
 message = 123456;
 ```
 
+<<<<<<< HEAD
 Część języków programowania stosuje tak zwane "dynamiczne typowanie", które oznacza, że typy danych zmiennych mogą zmienić się w trakcie działania programu.
 
 Wyróżniamy 8 podstawowych typów danych w JavaScripcie. Przedstawimy je teraz ogólnie, w następnych rozdziałach omówimy bardziej szczegółowo.
+=======
+Programming languages that allow such things, such as JavaScript, are called "dynamically typed", meaning that there exist data types, but variables are not bound to any of them.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ## Typ liczbowy
 
@@ -44,6 +56,7 @@ Poza zwykłymi liczbami, wyróżniamy "specjalne wartości liczbowe", które tak
     alert( "wartość nieliczbowa" / 2 ); // NaN, takie działanie prowadzi do błędu
     ```
 
+<<<<<<< HEAD
     Każda operacja z użyciem `NaN` zawsze zwraca `NaN` jako wynik:
 
     ```js run
@@ -51,6 +64,17 @@ Poza zwykłymi liczbami, wyróżniamy "specjalne wartości liczbowe", które tak
     ```
 
     Zatem, jeżeli `NaN` znajduje się w wyrażeniu matematycznym, staje się też jego wynikiem końcowym.
+=======
+    `NaN` is sticky. Any further mathematical operation on `NaN` returns `NaN`:
+
+    ```js run
+    alert( NaN + 1 ); // NaN
+    alert( 3 * NaN ); // NaN
+    alert( "not a number" / 2 - 1 ); // NaN
+    ```
+
+    So, if there's a `NaN` somewhere in a mathematical expression, it propagates to the whole result (there's only one exception to that: `NaN ** 0` is `1`).
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ```smart header="Operacje matematyczne są bezpieczne"
 Przeprowadzanie obliczeń matematycznych w JavaScripcie jest "bezpieczne". Możemy dzielić przez zero, traktować ciągi znaków jako liczby itd.
@@ -62,24 +86,49 @@ Specjalne wartości liczbowe formalnie należą do typu "liczbowego". Oczywiści
 
 Więcej informacji o pracy z liczbami zawarte jest w rozdziale pt. "<info:number>".
 
-## BigInt
+## BigInt [#bigint-type]
 
+<<<<<<< HEAD
 W JavaScripcie typ liczbowy nie może reprezentować liczb całkowitych większych od <code>2<sup>53</sup></code> (ani ujemnych mniejszych od <code>-2<sup>53</sup></code>) ze względu na ograniczenia techniczne narzucone przez jego reprezentację wewnętrzną. Daje to liczby o długości około 16 cyfr, co w większości przypadków wystarcza. Jednak czasami potrzebujemy skorzystać z naprawdę dużych liczb, np. w krytografii czy znaczników czasowych z dokładnością do mikrosekund.
+=======
+In JavaScript, the "number" type cannot safely represent integer values larger than <code>(2<sup>53</sup>-1)</code> (that's `9007199254740991`), or less than <code>-(2<sup>53</sup>-1)</code> for negatives.
+
+To be really precise, the "number" type can store larger integers (up to <code>1.7976931348623157 * 10<sup>308</sup></code>), but outside of the safe integer range <code>±(2<sup>53</sup>-1)</code> there'll be a precision error, because not all digits fit into the fixed 64-bit storage. So an "approximate" value may be stored.
+
+For example, these two numbers (right above the safe range) are the same:
+
+```js
+console.log(9007199254740991 + 1); // 9007199254740992
+console.log(9007199254740991 + 2); // 9007199254740992
+```
+
+So to say, all odd integers greater than <code>(2<sup>53</sup>-1)</code> can't be stored at all in the "number" type.
+
+For most purposes <code>±(2<sup>53</sup>-1)</code> range is quite enough, but sometimes we need the entire range of really big integers, e.g. for cryptography or microsecond-precision timestamps.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 Typ `BigInt` został niedawno dodany do języka i reprezentuje liczby całkowite o dowolnej długości.
 
+<<<<<<< HEAD
 `BigInt` tworzy się poprzez dodanie `n` na końcu liczby:
+=======
+A `BigInt` value is created by appending `n` to the end of an integer:
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ```js
 // "n" na końcu oznacza, że to liczba typu BigInt
 const bigInt = 1234567890123456789012345678901234567890n;
 ```
 
+<<<<<<< HEAD
 Z racji tego, że liczby typu `BigInt` są rzadko stosowane, poświęciliśmy im osobny rozdział pt. "<info:bigint>".
 
 ```smart header="Problemy z kompatybilnością"
 Aktualnie dla typu `BigInt` wsparcie posiadają przeglądarki Firefox i Chrome. Brakuje go w Safari/IE/Edge.
 ```
+=======
+As `BigInt` numbers are rarely needed, we don't cover them here, but devoted them a separate chapter <info:bigint>. Read it when you need such big numbers.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ## Typ tekstowy
 
@@ -123,7 +172,11 @@ Więcej o ciągach znaków można przeczytać w rozdziale pt. "<info:string>".
 ```smart header="JavaScript nie posiada typu *znakowego*."
 W niektórych językach istnieje specjalny typ "znakowy", używany do przechowywania pojedynczych znaków. Przykładowo, w językach C i Java możemy użyć typu o nazwie "char".
 
+<<<<<<< HEAD
 W JavaScripcie nie ma takiego typu. Mamy do dyspozycji jedynie `string`. Ciąg znaków może być pusty albo zawierać jeden i więcej znaków.
+=======
+In JavaScript, there is no such type. There's only one type: `string`. A string may consist of zero characters (be empty), one character or many of them.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 ```
 
 ## Typ logiczny (boolean)
@@ -163,7 +216,11 @@ W JavaScripcie `null` nie odnosi się do "nieistniejącego obiektu" lub "wskaźn
 
 Jest specjalną wartością, która reprezentuje "nic", "brak wartości" lub "nieznaną wartość".
 
+<<<<<<< HEAD
 Kod powyżej zakłada, że wartość zmiennej `age` jest pusta bądź nieznana z jakiegoś powodu.
+=======
+The code above states that `age` is unknown.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ## Wartość "undefined"
 
@@ -174,33 +231,54 @@ Wartość `undefined` oznacza, że "wartość zmiennej nie jest przypisana"
 W przypadku zadeklarowania zmiennej bez przypisania do niej konkretnej wartości, domyślna wartość to `undefined`:
 
 ```js run
-let x;
+let age;
 
+<<<<<<< HEAD
 alert(x); // wyświetla "undefined"
 ```
 
 W zasadzie możliwe jest przypisanie `undefined` do zmiennej:
+=======
+alert(age); // shows "undefined"
+```
+
+Technically, it is possible to explicitly assign `undefined` to a variable:
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ```js run
-let x = 123;
+let age = 100;
 
-x = undefined;
+// change the value to undefined
+age = undefined;
 
-alert(x); // "undefined"
+alert(age); // "undefined"
 ```
 
+<<<<<<< HEAD
 ... Jednak nie zalecamy tworzenia zmiennych o wartości `undefined`. Zazwyczaj używamy `null` dla zmiennych bez wartości, `undefined` przydaje się przy sprawdzaniu czy zmienna została przypisana do jakiejś wartości.
+=======
+...But we don't recommend doing that. Normally, one uses `null` to assign an "empty" or "unknown" value to a variable, while `undefined` is reserved as a default initial value for unassigned things.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ## Obiekty i symbole
 
 Typ `object` jest jedyny w swoim rodzaju.
 
+<<<<<<< HEAD
 Wszystkie inne typy zwane są "prostymi" (ang. *primitive*), ponieważ ich wartości mogą przechowywać tylko jedną rzecz (może to być ciąg znaków, liczba, typ logiczny itd.). W przeciwieństwie do typów prostych, obiekty używane są do przechowywania większych kolekcji danych. Więcej o obiektach omówimy poźniej w rozdziale pt. "<info:object>", po wcześniejszym omówieniu typów prostych.
 
 Typ `symbol` jest używany do tworzenia unikalnych identyfikatorów dla obiektów. Wspominamy o nim tylko dla kompletności tego rozdziału, niemniej zdecydowanie lepiej jest poznać ten typ po zrozumieniu samych obiektów.
+=======
+All other types are called "primitive" because their values can contain only a single thing (be it a string or a number or whatever). In contrast, objects are used to store collections of data and more complex entities.
+
+Being that important, objects deserve a special treatment. We'll deal with them later in the chapter <info:object>, after we learn more about primitives.
+
+The `symbol` type is used to create unique identifiers for objects. We have to mention it here for the sake of completeness, but also postpone the details till we know objects.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ## Operator "typeof" [#type-typeof]
 
+<<<<<<< HEAD
 Operator `typeof` zwraca typ danego argumentu. Jest użyteczny, gdy chcemy przetworzyć wartości różnych typów lub sprawdzić sam typ.
 
 Występują dwa sposoby na użycie tego operatora:
@@ -211,6 +289,11 @@ Występują dwa sposoby na użycie tego operatora:
 Innymi słowy, bez względu na to, czy użyjemy nawiasów czy nie - wynik jest ten sam.
 
 Wywołanie `typeof x` zwraca ciąg znaków z nazwą typu sprawdzanej zmiennej:
+=======
+The `typeof` operator returns the type of the operand. It's useful when we want to process values of different types differently or just want to do a quick check.
+
+A call to `typeof x` returns a string with the type name:
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ```js
 typeof undefined // "undefined"
@@ -240,14 +323,43 @@ typeof alert // "function"  (3)
 
 Ostatnie trzy linijki wymagają dodatkowego wyjaśnienia.
 
+<<<<<<< HEAD
 1. `Math` jest wbudowanym obiektem, który daje dostęp do operacji matematycznych. Dowiemy się o nim więcej w rozdziale pt. "<info:number>". W tym przypadku posłużył jako przykład obiektu.
 2. Wynikiem wywołania `typeof null` jest `object`. Jest to znany błąd związany z `typeof`, nie został on jednak poprawiony ze względu na wsteczną kompatybilność. Oczywiście `null` nie jest obiektem - posiada własny typ.
 3. Wynikiem wywołania `typeof alert` jest `"function"` ze względu na to, że `alert` jest po prostu funkcją. O funkcjach napisaliśmy więcej w następnych rozdziałach, gdzie zauważamy, że tak naprawdę nie ma typu "function" w JavaScripcie. Funkcje należą do typu "object". Jednak `typeof` traktuje funkcje inaczej, zwracając `"function"`, co nie jest do końca poprawne, lecz bardzo wygodne w praktyce.
+=======
+1. `Math` is a built-in object that provides mathematical operations. We will learn it in the chapter <info:number>. Here, it serves just as an example of an object.
+2. The result of `typeof null` is `"object"`. That's an officially recognized error in `typeof`, coming from very early days of JavaScript and kept for compatibility. Definitely, `null` is not an object. It is a special value with a separate type of its own. The behavior of `typeof` is wrong here.
+3. The result of `typeof alert` is `"function"`, because `alert` is a function. We'll study functions in the next chapters where we'll also see that there's no special "function" type in JavaScript. Functions belong to the object type. But `typeof` treats them differently, returning `"function"`. That also comes from the early days of JavaScript. Technically, such behavior isn't correct, but can be convenient in practice.
+
+```smart header="The `typeof(x)` syntax"
+You may also come across another syntax: `typeof(x)`. It's the same as `typeof x`.
+
+To put it clear: `typeof` is an operator, not a function. The parentheses here aren't a part of `typeof`. It's the kind of parentheses used for mathematical grouping.
+
+Usually, such parentheses contain a mathematical expression, such as `(2 + 2)`, but here they contain only one argument `(x)`. Syntactically, they allow to avoid a space between the `typeof` operator and its argument, and some people like it.
+
+Some people prefer `typeof(x)`, although the `typeof x` syntax is much more common.
+```
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 
 ## Podsumowanie
 
+<<<<<<< HEAD
 W JavaScripcie wyróżniamy 8 podstawowych typów danych.
+=======
+- Seven primitive data types:
+    - `number` for numbers of any kind: integer or floating-point, integers are limited by <code>±(2<sup>53</sup>-1)</code>.
+    - `bigint` for integer numbers of arbitrary length.
+    - `string` for strings. A string may have zero or more characters, there's no separate single-character type.
+    - `boolean` for `true`/`false`.
+    - `null` for unknown values -- a standalone type that has a single value `null`.
+    - `undefined` for unassigned values -- a standalone type that has a single value `undefined`.
+    - `symbol` for unique identifiers.
+- And one non-primitive data type:
+    - `object` for more complex data structures.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 - `number` dla wszystkich liczb: całkowitych lub zmiennoprzecinkowych.
 - `bigint` dla liczb całkowitych o dowolnej długości.
@@ -258,7 +370,13 @@ W JavaScripcie wyróżniamy 8 podstawowych typów danych.
 - `object` dla bardziej złożonych struktur danych.
 - `symbol` dla unikalnych identyfikatorów.
 
+<<<<<<< HEAD
 Operator `typeof` pozwala na sprawdzenie typu zmiennej.
+=======
+- Usually used as `typeof x`, but `typeof(x)` is also possible.
+- Returns a string with the name of the type, like `"string"`.
+- For `null` returns `"object"` -- this is an error in the language, it's not actually an object.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 - Istnieją dwie formy: `typeof x` lub `typeof(x)`.
 - Zwraca ciąg znaków z nazwą danego typu, na przykład `"string"`.
diff --git a/1-js/02-first-steps/09-alert-prompt-confirm/1-simple-page/solution.md b/1-js/02-first-steps/06-alert-prompt-confirm/1-simple-page/solution.md
similarity index 100%
rename from 1-js/02-first-steps/09-alert-prompt-confirm/1-simple-page/solution.md
rename to 1-js/02-first-steps/06-alert-prompt-confirm/1-simple-page/solution.md
diff --git a/1-js/02-first-steps/09-alert-prompt-confirm/1-simple-page/task.md b/1-js/02-first-steps/06-alert-prompt-confirm/1-simple-page/task.md
similarity index 100%
rename from 1-js/02-first-steps/09-alert-prompt-confirm/1-simple-page/task.md
rename to 1-js/02-first-steps/06-alert-prompt-confirm/1-simple-page/task.md
diff --git a/1-js/02-first-steps/09-alert-prompt-confirm/article.md b/1-js/02-first-steps/06-alert-prompt-confirm/article.md
similarity index 73%
rename from 1-js/02-first-steps/09-alert-prompt-confirm/article.md
rename to 1-js/02-first-steps/06-alert-prompt-confirm/article.md
index 0ca6f28cd..05187addb 100644
--- a/1-js/02-first-steps/09-alert-prompt-confirm/article.md
+++ b/1-js/02-first-steps/06-alert-prompt-confirm/article.md
@@ -1,5 +1,6 @@
 # Interakcje: alert, prompt, confirm
 
+<<<<<<< HEAD:1-js/02-first-steps/09-alert-prompt-confirm/article.md
 W tej części poradnika przedstawimy język JavaScript w podstawowej formie, bez żadnych ulepszeń dla danego środowiska.
 
 Nadal będziemy używać przeglądarki jako domyślnego środowiska, więc powinniśmy znać przynajmniej kilka funkcji interfejsu przeglądarki. W tym rozdziale, zaznajomimy się z funkcjami dostępnymi w przeglądarce: `alert`, `prompt` and `confirm`.
@@ -13,6 +14,13 @@ alert(message);
 ```
 
 Funkcja `alert` wyświetla zawartość zmiennej `message` i wstrzymuje wykonywanie skryptu do czasu, kiedy użytkownik kliknie "OK".
+=======
+As we'll be using the browser as our demo environment, let's see a couple of functions to interact with the user: `alert`, `prompt` and `confirm`.
+
+## alert
+
+This one we've seen already. It shows a message and waits for the user to press "OK".
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3:1-js/02-first-steps/06-alert-prompt-confirm/article.md
 
 Na przykład:
 
@@ -20,7 +28,11 @@ Na przykład:
 alert("Witaj");
 ```
 
+<<<<<<< HEAD:1-js/02-first-steps/09-alert-prompt-confirm/article.md
 Pojawi się niewielkie okno z wiadomością, które nazywamy *oknem modalnym*. Słowo "modalny" oznacza, że użytkownik nie może wejść w interakcję z pozostałą treścią strony czy też z innymi przyciskami i tak dalej, dopóki nie zakończy interakcji z oknem. W tym przypadku -- do czasu kliknięcia *OK*.
+=======
+The mini-window with the message is called a *modal window*. The word "modal" means that the visitor can't interact with the rest of the page, press other buttons, etc, until they have dealt with the window. In this case -- until they press "OK".
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3:1-js/02-first-steps/06-alert-prompt-confirm/article.md
 
 ## prompt
 
@@ -38,7 +50,15 @@ Funkcja `prompt` wyświetla okno z wiadomością, pole tekstowe do uzupełnienia
 `default`
 : Opcjonalny drugi parametr, wartość początkowa dla pola tekstowego.
 
+<<<<<<< HEAD:1-js/02-first-steps/09-alert-prompt-confirm/article.md
 Użytkownik może wpisać tekst do pola tekstowego i zatwierdzić przyciskiem *OK*. Może także anulować operację, klikając przycisk *Anuluj* lub wciskając klawisz `key:Esc`.
+=======
+```smart header="The square brackets in syntax `[...]`"
+The square brackets around `default` in the syntax above denote that the parameter is optional, not required.
+```
+
+The visitor can type something in the prompt input field and press OK. Then we get that text in the `result`. Or they can cancel the input by pressing Cancel or hitting the `key:Esc` key, then we get `null` as the `result`.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3:1-js/02-first-steps/06-alert-prompt-confirm/article.md
 
 Wywołanie funkcji `prompt` zwraca tekst wpisany do pola tekstowego lub wartość `null`, w przypadku gdy użytkownik anulował akcję.
 
diff --git a/1-js/02-first-steps/06-type-conversions/article.md b/1-js/02-first-steps/07-type-conversions/article.md
similarity index 78%
rename from 1-js/02-first-steps/06-type-conversions/article.md
rename to 1-js/02-first-steps/07-type-conversions/article.md
index 663d4c776..8b3c72e9b 100644
--- a/1-js/02-first-steps/06-type-conversions/article.md
+++ b/1-js/02-first-steps/07-type-conversions/article.md
@@ -6,8 +6,16 @@ Na przykład `alert` automatycznie zmieni typ dowolnej wartości do typu tekstow
 
 Istnieją jednak przypadki, w których musimy jawnie zmienić typ wartości na inny. 
 
+<<<<<<< HEAD:1-js/02-first-steps/06-type-conversions/article.md
 ```smart header="Nie mówimy jeszcze o obiektach"
 W tym rozdziale nie zajmujemy się obiektami. Zamiast tego nauczymy się najpierw typów prostych. Później nauczymy się co nieco o obiektach i w rozdziale pt. "<info:object-toprimitive>" zobaczymy, jak działa rzutowanie obiektów.
+=======
+```smart header="Not talking about objects yet"
+In this chapter, we won't cover objects. For now, we'll just be talking about primitives.
+
+Later, after we learn about objects, in the chapter <info:object-toprimitive> we'll see how objects fit in.
+```
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3:1-js/02-first-steps/07-type-conversions/article.md
 
 ## Rzutowanie do typu tekstowego
 
@@ -31,7 +39,11 @@ Rzutowanie wartości do tekstu jest bardzo przewidywalne. `false` zostaje `"fals
 
 ## Rzutowanie do typu liczbowego
 
+<<<<<<< HEAD:1-js/02-first-steps/06-type-conversions/article.md
 Rzutowanie do typu liczbowego następuje automatycznie w wyniku matematycznych wyrażeń i funkcji.
+=======
+Numeric conversion in mathematical functions and expressions happens automatically.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3:1-js/02-first-steps/07-type-conversions/article.md
 
 Na przykład przy dzieleniu (`/`) z udziałem wartości nie będących liczbami:
 
@@ -66,8 +78,13 @@ Zasady rzutowania do typu liczbowego:
 |---------|-------------|
 |`undefined`|`NaN`|
 |`null`|`0`|
+<<<<<<< HEAD:1-js/02-first-steps/06-type-conversions/article.md
 |<code>true&nbsp;i&nbsp;false</code> | `1` i `0` |
 | `string` | Białe znaki z początku i końca są usuwane. Jeśli pozostała wartość napisu jest pusta, wynikiem będzie `0`. W przeciwnym wypadku liczba jest odczytywana z tekstu. Wszystkie nieprawidłowe rzutowania dają `NaN`. |
+=======
+|<code>true&nbsp;and&nbsp;false</code> | `1` and `0` |
+| `string` | Whitespaces (includes spaces, tabs `\t`, newlines `\n` etc.) from the start and end are removed. If the remaining string is empty, the result is `0`. Otherwise, the number is "read" from the string. An error gives `NaN`. |
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3:1-js/02-first-steps/07-type-conversions/article.md
 
 Przykłady:
 
@@ -127,7 +144,11 @@ Rzutowanie to jest zgodne z zasadami:
 |`undefined`|`NaN`|
 |`null`|`0`|
 |<code>true&nbsp;/&nbsp;false</code> | `1 / 0` |
+<<<<<<< HEAD:1-js/02-first-steps/06-type-conversions/article.md
 | `string` | Tekst jest odczytywany "jak leci", białe znaki na obydwóch końcach są ignorowane. Pusty ciąg znaków staje się `0`. Błąd konwersji zwraca `NaN`.|
+=======
+| `string` | The string is read "as is", whitespaces (includes spaces, tabs `\t`, newlines `\n` etc.) from both sides are ignored. An empty string becomes `0`. An error gives `NaN`. |
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3:1-js/02-first-steps/07-type-conversions/article.md
 
 **`Rzutowanie do typu logicznego`** -- Zachodzi w operacjach logicznych. Może zajść również przy użyciu funkcji `Boolean(value)`.
 
diff --git a/1-js/02-first-steps/07-operators/1-increment-order/solution.md b/1-js/02-first-steps/08-operators/1-increment-order/solution.md
similarity index 100%
rename from 1-js/02-first-steps/07-operators/1-increment-order/solution.md
rename to 1-js/02-first-steps/08-operators/1-increment-order/solution.md
diff --git a/1-js/02-first-steps/07-operators/1-increment-order/task.md b/1-js/02-first-steps/08-operators/1-increment-order/task.md
similarity index 100%
rename from 1-js/02-first-steps/07-operators/1-increment-order/task.md
rename to 1-js/02-first-steps/08-operators/1-increment-order/task.md
diff --git a/1-js/02-first-steps/07-operators/2-assignment-result/solution.md b/1-js/02-first-steps/08-operators/2-assignment-result/solution.md
similarity index 100%
rename from 1-js/02-first-steps/07-operators/2-assignment-result/solution.md
rename to 1-js/02-first-steps/08-operators/2-assignment-result/solution.md
diff --git a/1-js/02-first-steps/07-operators/2-assignment-result/task.md b/1-js/02-first-steps/08-operators/2-assignment-result/task.md
similarity index 100%
rename from 1-js/02-first-steps/07-operators/2-assignment-result/task.md
rename to 1-js/02-first-steps/08-operators/2-assignment-result/task.md
diff --git a/1-js/02-first-steps/07-operators/3-primitive-conversions-questions/solution.md b/1-js/02-first-steps/08-operators/3-primitive-conversions-questions/solution.md
similarity index 50%
rename from 1-js/02-first-steps/07-operators/3-primitive-conversions-questions/solution.md
rename to 1-js/02-first-steps/08-operators/3-primitive-conversions-questions/solution.md
index cc3445b63..3a0406a18 100644
--- a/1-js/02-first-steps/07-operators/3-primitive-conversions-questions/solution.md
+++ b/1-js/02-first-steps/08-operators/3-primitive-conversions-questions/solution.md
@@ -9,14 +9,14 @@ true + false = 1
 "$" + 4 + 5 = "$45"
 "4" - 2 = 2
 "4px" - 2 = NaN
-7 / 0 = Infinity
-" -9  " + 5 = " -9  5" // (3)
-" -9  " - 5 = -14 // (4)
+"  -9  " + 5 = "  -9  5" // (3)
+"  -9  " - 5 = -14 // (4)
 null + 1 = 1 // (5)
 undefined + 1 = NaN // (6)
 " \t \n" - 2 = -2 // (7)
 ```
 
+<<<<<<< HEAD:1-js/02-first-steps/07-operators/3-primitive-conversions-questions/solution.md
 1. Dodawanie ciągu znaków `"" + 1` rzutuje `1` do typu tekstowego: `"" + 1 = "1"`, a później analogicznie `"1" + 0`.
 2. Odejmowanie `-` (jak większość operacji matematycznych) działa wyłącznie z typami liczbowymi i konwertuje pusty napis `""` do `0`.
 3. Dodawanie ciągu znaków dołącza (konkatenuje) liczbę `5` do zmiennej.
@@ -24,3 +24,12 @@ undefined + 1 = NaN // (6)
 5. `null` rzutowany na liczbę stanie się `0`.
 6. `undefined` rzutowany na liczbę stanie się `NaN`.
 7. Podczas rzutowania typu tekstowego na liczbowy ignorowane są białe znaki po obydwóch stronach tekstu. W tym przypadku cały tekst składa się z białych znaków: `\t`, `\n` i "zwykłych" spacji pomiędzy nimi. W rezultacie powstały pusty ciąg znaków po rzutowaniu na liczbę da wartość `0`.
+=======
+1. The addition with a string `"" + 1` converts `1` to a string: `"" + 1 = "1"`, and then we have `"1" + 0`, the same rule is applied.
+2. The subtraction `-` (like most math operations) only works with numbers, it converts an empty string `""` to `0`.
+3. The addition with a string appends the number `5` to the string.
+4. The subtraction always converts to numbers, so it makes `"  -9  "` a number `-9` (ignoring spaces around it).
+5. `null` becomes `0` after the numeric conversion.
+6. `undefined` becomes `NaN` after the numeric conversion.
+7. Space characters are trimmed off string start and end when a string is converted to a number. Here the whole string consists of space characters, such as `\t`, `\n` and a "regular" space between them. So, similarly to an empty string, it becomes `0`.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3:1-js/02-first-steps/08-operators/3-primitive-conversions-questions/solution.md
diff --git a/1-js/02-first-steps/07-operators/3-primitive-conversions-questions/task.md b/1-js/02-first-steps/08-operators/3-primitive-conversions-questions/task.md
similarity index 98%
rename from 1-js/02-first-steps/07-operators/3-primitive-conversions-questions/task.md
rename to 1-js/02-first-steps/08-operators/3-primitive-conversions-questions/task.md
index f0d686f7e..0528cfe7d 100644
--- a/1-js/02-first-steps/07-operators/3-primitive-conversions-questions/task.md
+++ b/1-js/02-first-steps/08-operators/3-primitive-conversions-questions/task.md
@@ -16,7 +16,6 @@ true + false
 "$" + 4 + 5
 "4" - 2
 "4px" - 2
-7 / 0
 "  -9  " + 5
 "  -9  " - 5
 null + 1
diff --git a/1-js/02-first-steps/08-operators/4-fix-prompt/solution.md b/1-js/02-first-steps/08-operators/4-fix-prompt/solution.md
new file mode 100644
index 000000000..209a0702c
--- /dev/null
+++ b/1-js/02-first-steps/08-operators/4-fix-prompt/solution.md
@@ -0,0 +1,32 @@
+The reason is that prompt returns user input as a string.
+
+So variables have values `"1"` and `"2"` respectively.
+
+```js run
+let a = "1"; // prompt("First number?", 1);
+let b = "2"; // prompt("Second number?", 2);
+
+alert(a + b); // 12
+```
+
+What we should do is to convert strings to numbers before `+`. For example, using `Number()` or prepending them with `+`.
+
+For example, right before `prompt`:
+
+```js run
+let a = +prompt("First number?", 1);
+let b = +prompt("Second number?", 2);
+
+alert(a + b); // 3
+```
+
+Or in the `alert`:
+
+```js run
+let a = prompt("First number?", 1);
+let b = prompt("Second number?", 2);
+
+alert(+a + +b); // 3
+```
+
+Using both unary and binary `+` in the latest code. Looks funny, doesn't it?
diff --git a/1-js/02-first-steps/08-operators/4-fix-prompt/task.md b/1-js/02-first-steps/08-operators/4-fix-prompt/task.md
new file mode 100644
index 000000000..b3ea4a3a3
--- /dev/null
+++ b/1-js/02-first-steps/08-operators/4-fix-prompt/task.md
@@ -0,0 +1,18 @@
+importance: 5
+
+---
+
+# Fix the addition
+
+Here's a code that asks the user for two numbers and shows their sum.
+
+It works incorrectly. The output in the example below is `12` (for default prompt values).
+
+Why? Fix it. The result should be `3`.
+
+```js run
+let a = prompt("First number?", 1);
+let b = prompt("Second number?", 2);
+
+alert(a + b); // 12
+```
diff --git a/1-js/02-first-steps/07-operators/article.md b/1-js/02-first-steps/08-operators/article.md
similarity index 68%
rename from 1-js/02-first-steps/07-operators/article.md
rename to 1-js/02-first-steps/08-operators/article.md
index 74cbdf315..912b126f6 100644
--- a/1-js/02-first-steps/07-operators/article.md
+++ b/1-js/02-first-steps/08-operators/article.md
@@ -1,8 +1,16 @@
+<<<<<<< HEAD:1-js/02-first-steps/07-operators/article.md
 # Operatory
+=======
+# Basic operators, maths
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3:1-js/02-first-steps/08-operators/article.md
 
 Z czasów szkolnych znamy wiele operatorów: dodawania `+`, mnożenia `*`, odejmowania `-` itd.
 
+<<<<<<< HEAD:1-js/02-first-steps/07-operators/article.md
 W tym rozdziale skupimy się na operatorach, o których nie uczono na matematyce.
+=======
+In this chapter, we’ll start with simple operators, then concentrate on JavaScript-specific aspects, not covered by school arithmetic.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3:1-js/02-first-steps/08-operators/article.md
 
 ## Pojęcia: "jednoargumentowy", "dwuargumentowy", "operandy"
 
@@ -28,9 +36,66 @@ Zanim przejdziemy dalej, zapoznajmy się z podstawową terminologią.
 
     Z formalnego punktu widzenia, powyższe przykłady używają dwóch różnych operatorów, które mają ten sam symbol: operator negacji (jednoargumentowy operator zmieniający znak na przeciwny) oraz operator odejmowania (dwuargumentowy operator odejmujący jedną liczbę od drugiej).
 
+<<<<<<< HEAD:1-js/02-first-steps/07-operators/article.md
 ## Konkatenacja ciągów znaków, dwuargumentowy +
 
 Teraz zajmijmy się specjalnymi właściwościami operatorów javascriptowych, o których nie dowiemy się na matematyce.
+=======
+## Maths
+
+The following math operations are supported:
+
+- Addition `+`,
+- Subtraction `-`,
+- Multiplication `*`,
+- Division `/`,
+- Remainder `%`,
+- Exponentiation `**`.
+
+The first four are straightforward, while `%` and `**` need a few words about them.
+
+### Remainder %
+
+The remainder operator `%`, despite its appearance, is not related to percents.
+
+The result of `a % b` is the [remainder](https://en.wikipedia.org/wiki/Remainder) of the integer division of `a` by `b`.
+
+For instance:
+
+```js run
+alert( 5 % 2 ); // 1, the remainder of 5 divided by 2
+alert( 8 % 3 ); // 2, the remainder of 8 divided by 3
+alert( 8 % 4 ); // 0, the remainder of 8 divided by 4
+```
+
+### Exponentiation **
+
+The exponentiation operator `a ** b` raises `a` to the power of `b`.
+
+In school maths, we write that as a<sup>b</sup>.
+
+For instance:
+
+```js run
+alert( 2 ** 2 ); // 2² = 4
+alert( 2 ** 3 ); // 2³ = 8
+alert( 2 ** 4 ); // 2⁴ = 16
+```
+
+Just like in maths, the exponentiation operator is defined for non-integer numbers as well.
+
+For example, a square root is an exponentiation by ½:
+
+```js run
+alert( 4 ** (1/2) ); // 2 (power of 1/2 is the same as a square root)
+alert( 8 ** (1/3) ); // 2 (power of 1/3 is the same as a cubic root)
+```
+
+
+## String concatenation with binary +
+
+Let's meet the features of JavaScript operators that are beyond school arithmetics.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3:1-js/02-first-steps/08-operators/article.md
 
 Zwykle operator plusa `+` dodaje do siebie liczby.
 
@@ -41,7 +106,11 @@ let s = "mój" + "napis";
 alert(s); // mójnapis
 ```
 
+<<<<<<< HEAD:1-js/02-first-steps/07-operators/article.md
 Zauważ, że jeśli jeden z operandów jest typu tekstowego, drugi też jest konwertowany do tekstu.
+=======
+Note that if any of the operands is a string, then the other one is converted to a string too.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3:1-js/02-first-steps/08-operators/article.md
 
 Na przykład:
 
@@ -50,22 +119,40 @@ alert( '1' + 2 ); // "12"
 alert( 2 + '1' ); // "21"
 ```
 
+<<<<<<< HEAD:1-js/02-first-steps/07-operators/article.md
 Nie ma znaczenia, czy to pierwszy argument będzie tekstem, czy drugi. Zasada jest prosta: jeśli którykolwiek z operandów jest ciągiem znaków, drugi też się nim staje.
 
 Warto jednak zwrócić uwagę na fakt, iż operacje wykonywane są w kolejności od lewej do prawej. Jeśli dodamy do siebie dwie liczby, a następnie ciąg znaków, najpierw zostaną zsumowane liczby, a następnie wynik zostanie przekonwertowany do tekstu:
+=======
+See, it doesn't matter whether the first operand is a string or the second one.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3:1-js/02-first-steps/08-operators/article.md
 
+Here's a more complex example:
 
 ```js run
 alert(2 + 2 + '1' ); // "41", a nie "221"
 ```
 
+<<<<<<< HEAD:1-js/02-first-steps/07-operators/article.md
 Konkatenacja i konwersja ciągów znaków to specjalne własności dwuargumentowego plusa `+`. Pozostałe operatory arytmetyczne działają tylko na liczbach i zawsze konwertują swoje argumenty do typu liczbowego.
 
 Przykład z odejmowaniem i dzieleniem:
+=======
+Here, operators work one after another. The first `+` sums two numbers, so it returns `4`, then the next `+` adds the string `1` to it, so it's like `4 + '1' = '41'`.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3:1-js/02-first-steps/08-operators/article.md
 
 ```js run
-alert( 2 - '1' ); // 1
-alert( '6' / '2' ); // 3
+alert('1' + 2 + 2); // "122" and not "14"
+```
+Here, the first operand is a string, the compiler treats the other two operands as strings too. The `2` gets concatenated to `'1'`, so it's like `'1' + 2 = "12"` and `"12" + 2 = "122"`.
+
+The binary `+` is the only operator that supports strings in such a way. Other arithmetic operators work only with numbers and always convert their operands to numbers.
+
+Here's the demo for subtraction and division:
+
+```js run
+alert( 6 - '2' ); // 4, converts '2' to a number
+alert( '6' / '2' ); // 3, converts both operands to numbers
 ```
 
 ## Konwersja na liczbę, jednoargumentowy +
@@ -133,6 +220,7 @@ Użycie nawiasów powoduje zmianę priorytetu, dlatego jeśli nie jesteśmy usat
 
 W języku JavaScript istnieje wiele operatorów, a każdy operator ma nadany jakiś priorytet. Najpierw wykonywane są te z wyższym priorytetem. Jeśli obok siebie znajdą się operatory o takich samych priorytetach, wykonywane są w kolejności od lewej do prawej.
 
+<<<<<<< HEAD:1-js/02-first-steps/07-operators/article.md
 Poniżej znajduje się fragment [tabeli kolejności wykonywania działań](https://developer.mozilla.org/en/JavaScript/Reference/operators/operator_precedence) (nie musisz jej znać na pamięć; zwróć tylko uwagę, że jednoargumentowe operatory mają zawsze wyższy priorytet niż ich dwuargumentowe odpowiedniki):
 
 | Priorytet | Nazwa                    | Symbol |
@@ -148,10 +236,33 @@ Poniżej znajduje się fragment [tabeli kolejności wykonywania działań](https
 | 3         | przypisanie              | `=`    |
 | ...       | ...                      | ...    |
 
+=======
+Here's an extract from the [precedence table](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence) (you don't need to remember this, but note that unary operators are higher than corresponding binary ones):
+
+| Precedence | Name | Sign |
+|------------|------|------|
+| ... | ... | ... |
+| 14 | unary plus | `+` |
+| 14 | unary negation | `-` |
+| 13 | exponentiation | `**` |
+| 12 | multiplication | `*` |
+| 12 | division | `/` |
+| 11 | addition | `+` |
+| 11 | subtraction | `-` |
+| ... | ... | ... |
+| 2 | assignment | `=` |
+| ... | ... | ... |
+
+As we can see, the "unary plus" has a priority of `14` which is higher than the `11` of "addition" (binary plus). That's why, in the expression `"+apples + +oranges"`, unary pluses work before the addition.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3:1-js/02-first-steps/08-operators/article.md
 
 Jak widać, "jednoargumentowy plus" ma priotytet równy `16`, czyli większy niż `13` przypisany do "dodawania" (jednoargumentowego plusa). To dlatego w wyrażeniu `"+apples + +oranges"` jednoargumentowe plusy aplikowane są w pierwszej kolejności.
 
+<<<<<<< HEAD:1-js/02-first-steps/07-operators/article.md
 ## Przypisanie
+=======
+Let's note that an assignment `=` is also an operator. It is listed in the precedence table with the very low priority of `2`.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3:1-js/02-first-steps/08-operators/article.md
 
 Zauważ, że operator przypisania `=` także jest operatorem. Został wymieniony w tabeli kolejności wykonywania działań z bardzo niskim priorytetem, `3`.
 
@@ -163,11 +274,15 @@ let x = 2 * 2 + 1;
 alert( x ); // 5
 ```
 
+<<<<<<< HEAD:1-js/02-first-steps/07-operators/article.md
 Można także zastosować przypisanie wielokrotne:
+=======
+### Assignment = returns a value
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3:1-js/02-first-steps/08-operators/article.md
 
-```js run
-let a, b, c;
+The fact of `=` being an operator, not a "magical" language construct has an interesting implication.
 
+<<<<<<< HEAD:1-js/02-first-steps/07-operators/article.md
 *!*
 a = b = c = 2 + 2;
 */!*
@@ -181,6 +296,9 @@ Przypisania wielokrotne wykonywane są od prawej do lewej. Najpierw obliczana je
 
 ````smart header="Operator przypisania `\"=\"` zwraca wartość"
 Operatory zawsze zwracają jakąś wartość. Jest to oczywiste w przypadku większości z nich, np. dodawania `+` czy mnożenia `*`. Ale nie każdy jednak wie, że przypisanie też zwraca wartość.
+=======
+All operators in JavaScript return a value. That's obvious for `+` and `-`, but also true for `=`.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3:1-js/02-first-steps/08-operators/article.md
 
 Wywołanie `x = value` przypisuje wartość `value` do `x`, *a następnie ją zwraca*.
 
@@ -200,6 +318,7 @@ alert( c ); // 0
 
 W powyższym kodzie wyrażenie `(a = b + 1)` zwraca wartość, która została przypisana do `a` (czyli `3`), a następnie ta wartość jest używana w kolejnych operacjach.
 
+<<<<<<< HEAD:1-js/02-first-steps/07-operators/article.md
 Śmiesznie to wygląda, prawda? Musimy jednak o tym wiedzieć, zważywszy na fakt, iż w wielu bibliotekach javascriptowych napotkamy taki zapis. Radzimy jednak nie pisać tak we własnym kodzie. Tego typu sztuczki sprawiają, że kod jest mniej czytelny.
 ````
 
@@ -238,11 +357,80 @@ Na przykład:
 ```js run
 alert( 4 ** (1/2) ); // 2 (potęgowanie przez 1/2 to to samo, co pierwiastek - tak mówi matematyka)
 alert( 8 ** (1/3) ); // 2 (potęgowanie przez 1/3 to to samo, co pierwiastek trzeciego stopnia)
+=======
+Funny code, isn't it? We should understand how it works, because sometimes we see it in JavaScript libraries.
+
+Although, please don't write the code like that. Such tricks definitely don't make code clearer or readable.
+
+### Chaining assignments
+
+Another interesting feature is the ability to chain assignments:
+
+```js run
+let a, b, c;
+
+*!*
+a = b = c = 2 + 2;
+*/!*
+
+alert( a ); // 4
+alert( b ); // 4
+alert( c ); // 4
+```
+
+Chained assignments evaluate from right to left. First, the rightmost expression `2 + 2` is evaluated and then assigned to the variables on the left: `c`, `b` and `a`. At the end, all the variables share a single value.
+
+Once again, for the purposes of readability it's better to split such code into few lines:
+
+```js
+c = 2 + 2;
+b = c;
+a = c;
+```
+That's easier to read, especially when eye-scanning the code fast.
+
+## Modify-in-place
+
+We often need to apply an operator to a variable and store the new result in that same variable.
+
+For example:
+
+```js
+let n = 2;
+n = n + 5;
+n = n * 2;
+```
+
+This notation can be shortened using the operators `+=` and `*=`:
+
+```js run
+let n = 2;
+n += 5; // now n = 7 (same as n = n + 5)
+n *= 2; // now n = 14 (same as n = n * 2)
+
+alert( n ); // 14
+```
+
+Short "modify-and-assign" operators exist for all arithmetical and bitwise operators: `/=`, `-=`, etc.
+
+Such operators have the same precedence as a normal assignment, so they run after most other calculations:
+
+```js run
+let n = 2;
+
+n *= 3 + 5; // right part evaluated first, same as n *= 8
+
+alert( n ); // 16
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3:1-js/02-first-steps/08-operators/article.md
 ```
 
 ## Inkrementacja/dekrementacja
 
+<<<<<<< HEAD:1-js/02-first-steps/07-operators/article.md
 <!-- Nie można używać -- w tytule, bo wbudowany parser zamienia to na - -->
+=======
+<!-- Can't use -- in title, because the built-in parser turns it into a 'long dash' – -->
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3:1-js/02-first-steps/08-operators/article.md
 
 Zwiększanie i zmniejszanie liczby o 1 to jedne z najczęściej wykonywanych operacji na liczbach.
 
@@ -369,6 +557,7 @@ Lista operatorów:
 - RIGHT SHIFT ( `>>` ) - przesunięcie bitowe w prawo
 - ZERO-FILL RIGHT SHIFT ( `>>>` ) - przesunięcie w prawo przy zerowym wypełnieniu
 
+<<<<<<< HEAD:1-js/02-first-steps/07-operators/article.md
 Operatory te stosowane są dość rzadko. Aby je zrozumieć, należałoby sięgnąć do niskopoziomowych reprezentacji liczb, co na tym poziomie nie jest zbyt dobrym posunięciem, zwłaszcza że nie będziemy z nich korzystać jeszcze przez długi czas. Jeśli zaciekawił cię ten temat, możesz przeczytać artykuł o [operatorach binarnych](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators) na MDN. Jednak lepiej zajrzeć tam dopiero wtedy, gdy faktycznie będziesz ich potrzebować.
 
 ## Modyfikacja w miejscu
@@ -404,6 +593,9 @@ n *= 3 + 5;
 
 alert( n ); // 16  (najpierw wykonywana jest prawa strona, równoznaczne z: n *= 8)
 ```
+=======
+These operators are used very rarely, when we need to fiddle with numbers on the very lowest (bitwise) level. We won't need these operators any time soon, as web development has little use of them, but in some special areas, such as cryptography, they are useful. You can read the [Bitwise Operators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#bitwise_operators) chapter on MDN when a need arises.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3:1-js/02-first-steps/08-operators/article.md
 
 ## Przecinek
 
diff --git a/1-js/02-first-steps/08-comparison/1-comparison-questions/solution.md b/1-js/02-first-steps/09-comparison/1-comparison-questions/solution.md
similarity index 54%
rename from 1-js/02-first-steps/08-comparison/1-comparison-questions/solution.md
rename to 1-js/02-first-steps/09-comparison/1-comparison-questions/solution.md
index 86132a089..a833d1ac1 100644
--- a/1-js/02-first-steps/08-comparison/1-comparison-questions/solution.md
+++ b/1-js/02-first-steps/09-comparison/1-comparison-questions/solution.md
@@ -12,6 +12,7 @@ null === +"\n0\n" → false
 
 Wytłumaczenie rozwiązania:
 
+<<<<<<< HEAD:1-js/02-first-steps/08-comparison/1-comparison-questions/solution.md
 1. Oczywiście true.
 2. Porównanie słownikowe, dlatego zwróci false. `"a"` jest mniejsze niż `"p"`
 3. Ponownie porównanie słownikowe, pierwszy znak `"2"` jest większy niż pierwszy znak drugiego stringu `"1"`.
@@ -19,3 +20,12 @@ Wytłumaczenie rozwiązania:
 5. Ścisła porównanie jest rygorystyczne. Obie wartości mają rózne typy, stąd `false`.
 6. Podobnie, jak w `(4)`, `null` i `undefined` są równe tylko ze sobą.
 7. Ścisłe porównanie róznych typów.
+=======
+1. Obviously, true.
+2. Dictionary comparison, hence false. `"a"` is smaller than `"p"`.
+3. Again, dictionary comparison, first char `"2"` is greater than the first char `"1"`.
+4. Values `null` and `undefined` equal each other only.
+5. Strict equality is strict. Different types from both sides lead to false.
+6. Similar to `(4)`, `null` only equals `undefined`.
+7. Strict equality of different types.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3:1-js/02-first-steps/09-comparison/1-comparison-questions/solution.md
diff --git a/1-js/02-first-steps/08-comparison/1-comparison-questions/task.md b/1-js/02-first-steps/09-comparison/1-comparison-questions/task.md
similarity index 100%
rename from 1-js/02-first-steps/08-comparison/1-comparison-questions/task.md
rename to 1-js/02-first-steps/09-comparison/1-comparison-questions/task.md
diff --git a/1-js/02-first-steps/08-comparison/article.md b/1-js/02-first-steps/09-comparison/article.md
similarity index 79%
rename from 1-js/02-first-steps/08-comparison/article.md
rename to 1-js/02-first-steps/09-comparison/article.md
index d26136881..078cd1be2 100644
--- a/1-js/02-first-steps/08-comparison/article.md
+++ b/1-js/02-first-steps/09-comparison/article.md
@@ -1,15 +1,34 @@
 # Porównania
 
+<<<<<<< HEAD:1-js/02-first-steps/08-comparison/article.md
 Na matematyce poznaliśmy porównania: 
 
 - Większe/mniejsze niż: <code>a &gt; b</code>, <code>a &lt; b</code>.
 - Większe/mniejsze niż lub równe: <code>a &gt;= b</code>, <code>a &lt;= b</code>.
 - Równe: `a == b` (zauważ, że jest tutaj podwójny znak `=`. Pojedyncze użycie `a = b` oznacza przypisanie).
 - Nierówne. W matematyce zapiszemy to jako <code>&ne;</code>, ale w JavaScript jest to zapisane jako wykrzyknik przed znakiem równości: <code>a != b</code>.
+=======
+We know many comparison operators from maths.
+
+In JavaScript they are written like this:
+
+- Greater/less than: <code>a &gt; b</code>, <code>a &lt; b</code>.
+- Greater/less than or equals: <code>a &gt;= b</code>, <code>a &lt;= b</code>.
+- Equals: `a == b`, please note the double equality sign `==` means the equality test, while a single one `a = b` means an assignment.
+- Not equals: In maths the notation is <code>&ne;</code>, but in JavaScript it's written as <code>a != b</code>.
+
+In this article we'll learn more about different types of comparisons, how JavaScript makes them, including important peculiarities.
+
+At the end you'll find a good recipe to avoid "JavaScript quirks"-related issues.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3:1-js/02-first-steps/09-comparison/article.md
 
 ## Wynikiem jest Boolean
 
+<<<<<<< HEAD:1-js/02-first-steps/08-comparison/article.md
 Jak wszystkie inne operatory porównanie zwraca wartość. W tym przypadku wartością jest Boolean.
+=======
+All comparison operators return a boolean value:
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3:1-js/02-first-steps/09-comparison/article.md
 
 - `true` -- oznacza "tak", "poprawnie" albo "prawda".
 - `false` -- oznacza "nie", "źle" albo "fałsz".
@@ -51,7 +70,13 @@ Algorytm porównuje dwa ciągi w prosty sposób:
 4. Powtarzaj dopóki nie nastapi koniec łańcucha znaków.
 5. Jeśli oba ciągi mają taką samą długość, to są równe. W przeciwnym przypadku dłuższy łańcuch jest większy.
 
+<<<<<<< HEAD:1-js/02-first-steps/08-comparison/article.md
 W powyższych przypadkach porównanie `'Z' > 'A'` zwróci rezultat w pierwszym podejściu. Porównanie `"Brat"` z `"Brak"` będzie porównywane znak po znaku:
+=======
+In the first example above, the comparison `'Z' > 'A'` gets to a result at the first step.
+
+The second comparison `'Glow'` and `'Glee'` needs more steps as strings are compared character-by-character:
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3:1-js/02-first-steps/09-comparison/article.md
 
 1. `B` jest takie same jak `B`.
 2. `r` jest takie same jak `r`.
@@ -194,6 +219,7 @@ Dostaliśmy takie rezultaty ponieważ:
 - Porównanie `(1)` i `(2)` zwraca `false` ponieważ `undefined` zostaje skonwertowane do `NaN` i `NaN` jest specjalną numeryczną wartością, która zawsze zwraca `false` dla wszystkich porównań.
 - Sprawdzanie równości `(3)` zwraca `false` ponieważ `undefined` jest równe tylko `null`, `undefined` i żadnej innej wartości.
 
+<<<<<<< HEAD:1-js/02-first-steps/08-comparison/article.md
 ### Unikanie problemów
 
 Dlaczego w ogóle przeszliśmy przez te przykłady? Czy powinniśmy pamiętać o tych osobliwych rzeczach cały czas? Nie do końca. Tak właściwie to te podstępne rzeczy staną się jasne z czasem, ale jest jeden porządny sposób na uniknięcie związanych z nimi problemów:
@@ -201,6 +227,14 @@ Dlaczego w ogóle przeszliśmy przez te przykłady? Czy powinniśmy pamiętać o
 Po prostu traktuj każde porównanie z `undefined/null` używając znaku ścisłej identyczności `===` zachowując wszelkie środki ostrożności.
 
 Nie używaj porównań `>= > < <=` ze zmiennymi, które mogą być `null/undefined`. Chyba że wiesz co robisz. Jeśli zmienna może mieć te wartości sprawdź je oddzielnie.
+=======
+### Avoid problems
+
+Why did we go over these examples? Should we remember these peculiarities all the time? Well, not really. Actually, these tricky things will gradually become familiar over time, but there's a solid way to avoid problems with them:
+
+- Treat any comparison with `undefined/null` except the strict equality `===` with exceptional care.
+- Don't use comparisons `>= > < <=` with a variable which may be `null/undefined`, unless you're really sure of what you're doing. If a variable can have these values, check for them separately.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3:1-js/02-first-steps/09-comparison/article.md
 
 ## Podsumowanie
 
diff --git a/1-js/02-first-steps/10-ifelse/2-check-standard/task.md b/1-js/02-first-steps/10-ifelse/2-check-standard/task.md
index 1aba6477b..1254e1dcf 100644
--- a/1-js/02-first-steps/10-ifelse/2-check-standard/task.md
+++ b/1-js/02-first-steps/10-ifelse/2-check-standard/task.md
@@ -6,8 +6,12 @@ importance: 2
 
 Używając instrukcji `if..else`, napisz kod który będzie pytał: 'Jaka jest "oficjalna" nazwa JavaScript?'
 
+<<<<<<< HEAD
 Jeżeli odwiedzający wpisze "ECMAScript", wtedy 
 If the visitor enters "ECMAScript", then zwróć wynik "Racja!", w przeciwnym wypadku -- zwróć wynik: "Nie wiedziałeś? ECMAScript!"
+=======
+If the visitor enters "ECMAScript", then output "Right!", otherwise -- output: "You don't know? ECMAScript!"
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ![](ifelse_task2.svg)
 
diff --git a/1-js/02-first-steps/10-ifelse/article.md b/1-js/02-first-steps/10-ifelse/article.md
index f7c525b81..1e830f4fc 100644
--- a/1-js/02-first-steps/10-ifelse/article.md
+++ b/1-js/02-first-steps/10-ifelse/article.md
@@ -1,4 +1,8 @@
+<<<<<<< HEAD
 # Operatory warunkowe: if, '?'
+=======
+# Conditional branching: if, '?'
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 Czasami potrzebujemy wykonać różne akcje w zależności od warunków.
 
@@ -68,7 +72,11 @@ if (cond) {
 
 ## Klauzula "else"
 
+<<<<<<< HEAD
 Wyrażenie `if` może opcjonalnie zawierać blok "else", który wykona się w przypadku gdy sprawdzany warunek jest fałszywy  (ang. *falsy*).
+=======
+The `if` statement may contain an optional `else` block. It executes when the condition is falsy.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 Na przykład:
 ```js run
@@ -182,7 +190,16 @@ Za pierwszym razem może być ciężko zrozumieć co właściwie się dzieje, al
 3. Jeśli tak -- zwraca `'Witaj!'`. W przeciwnym wypadku kontynuuje wyrażenie za dwukropkiem '":"' i sprawdza czy `age < 100`.
 4. Jeśli tak -- zwraca `'Pozdrowienia!'`.  W przeciwnym wypadku kontynuuje wyrażenie za ostatnim dwukropkiem '":"' i zwraca  `'Cóż za niespotykany wiek!'`.
 
+<<<<<<< HEAD
 Oto jak powyższy kod wyglądał by używając `if..else`
+=======
+1. The first question mark checks whether `age < 3`.
+2. If true -- it returns `'Hi, baby!'`. Otherwise, it continues to the expression after the colon ":", checking `age < 18`.
+3. If that's true -- it returns `'Hello!'`. Otherwise, it continues to the expression after the next colon ":", checking `age < 100`.
+4. If that's true -- it returns `'Greetings!'`. Otherwise, it continues to the expression after the last colon ":", returning `'What an unusual age!'`.
+
+Here's how this looks using `if..else`:
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ```js
 if (age < 3) {
diff --git a/1-js/02-first-steps/11-logical-operators/2-alert-or/solution.md b/1-js/02-first-steps/11-logical-operators/2-alert-or/solution.md
index 8f4d664e8..f85b56366 100644
--- a/1-js/02-first-steps/11-logical-operators/2-alert-or/solution.md
+++ b/1-js/02-first-steps/11-logical-operators/2-alert-or/solution.md
@@ -6,7 +6,7 @@ alert( alert(1) || 2 || alert(3) );
 
 The call to `alert` does not return a value. Or, in other words, it returns `undefined`.
 
-1. The first OR `||` evaluates it's left operand `alert(1)`. That shows the first message with `1`.
+1. The first OR `||` evaluates its left operand `alert(1)`. That shows the first message with `1`.
 2. The `alert` returns `undefined`, so OR goes on to the second operand searching for a truthy value.
 3. The second operand `2` is truthy, so the execution is halted, `2` is returned and then shown by the outer alert.
 
diff --git a/1-js/02-first-steps/11-logical-operators/3-alert-1-null-2/solution.md b/1-js/02-first-steps/11-logical-operators/3-alert-1-null-2/solution.md
index 5c2455ef4..368b59409 100644
--- a/1-js/02-first-steps/11-logical-operators/3-alert-1-null-2/solution.md
+++ b/1-js/02-first-steps/11-logical-operators/3-alert-1-null-2/solution.md
@@ -1,6 +1,6 @@
 The answer: `null`, because it's the first falsy value from the list.
 
 ```js run
-alert( 1 && null && 2 );
+alert(1 && null && 2);
 ```
 
diff --git a/1-js/02-first-steps/11-logical-operators/6-check-if-in-range/task.md b/1-js/02-first-steps/11-logical-operators/6-check-if-in-range/task.md
index cc00ca9fc..fc9e336c1 100644
--- a/1-js/02-first-steps/11-logical-operators/6-check-if-in-range/task.md
+++ b/1-js/02-first-steps/11-logical-operators/6-check-if-in-range/task.md
@@ -4,6 +4,6 @@ importance: 3
 
 # Check the range between
 
-Write an "if" condition to check that `age` is between `14` and `90` inclusively.
+Write an `if` condition to check that `age` is between `14` and `90` inclusively.
 
 "Inclusively" means that `age` can reach the edges `14` or `90`.
diff --git a/1-js/02-first-steps/11-logical-operators/7-check-if-out-range/task.md b/1-js/02-first-steps/11-logical-operators/7-check-if-out-range/task.md
index 7c22d6ad1..9b947d00f 100644
--- a/1-js/02-first-steps/11-logical-operators/7-check-if-out-range/task.md
+++ b/1-js/02-first-steps/11-logical-operators/7-check-if-out-range/task.md
@@ -4,6 +4,6 @@ importance: 3
 
 # Check the range outside
 
-Write an `if` condition to check that `age` is NOT between 14 and 90 inclusively.
+Write an `if` condition to check that `age` is NOT between `14` and `90` inclusively.
 
 Create two variants: the first one using NOT `!`, the second one -- without it.
diff --git a/1-js/02-first-steps/11-logical-operators/9-check-login/solution.md b/1-js/02-first-steps/11-logical-operators/9-check-login/solution.md
index a30db7aae..604606259 100644
--- a/1-js/02-first-steps/11-logical-operators/9-check-login/solution.md
+++ b/1-js/02-first-steps/11-logical-operators/9-check-login/solution.md
@@ -3,19 +3,19 @@
 ```js run demo
 let userName = prompt("Who's there?", '');
 
-if (userName == 'Admin') {
+if (userName === 'Admin') {
 
   let pass = prompt('Password?', '');
 
-  if (pass == 'TheMaster') {
+  if (pass === 'TheMaster') {
     alert( 'Welcome!' );
-  } else if (pass == '' || pass == null) {
+  } else if (pass === '' || pass === null) {
     alert( 'Canceled' );
   } else {
     alert( 'Wrong password' );
   }
 
-} else if (userName == '' || userName == null) {
+} else if (userName === '' || userName === null) {
   alert( 'Canceled' );
 } else {
   alert( "I don't know you" );
diff --git a/1-js/02-first-steps/11-logical-operators/article.md b/1-js/02-first-steps/11-logical-operators/article.md
index 25f8ff7f5..78c4fd2f1 100644
--- a/1-js/02-first-steps/11-logical-operators/article.md
+++ b/1-js/02-first-steps/11-logical-operators/article.md
@@ -1,6 +1,6 @@
 # Logical operators
 
-There are three logical operators in JavaScript: `||` (OR), `&&` (AND), `!` (NOT).
+There are four logical operators in JavaScript: `||` (OR), `&&` (AND), `!` (NOT), `??` (Nullish Coalescing). Here we cover the first three, the `??` operator is in the next article.
 
 Although they are called "logical", they can be applied to values of any type, not only boolean. Their result can also be of any type.
 
@@ -64,7 +64,7 @@ if (hour < 10 || hour > 18 || isWeekend) {
 }
 ```
 
-## OR "||" finds the first truthy value
+## OR "||" finds the first truthy value [#or-finds-the-first-truthy-value]
 
 The logic described above is somewhat classical. Now, let's bring in the "extra" features of JavaScript.
 
@@ -84,16 +84,16 @@ The OR `||` operator does the following:
 
 A value is returned in its original form, without the conversion.
 
-In other words, a chain of OR `"||"` returns the first truthy value or the last one if no truthy value is found.
+In other words, a chain of OR `||` returns the first truthy value or the last one if no truthy value is found.
 
 For instance:
 
 ```js run
 alert( 1 || 0 ); // 1 (1 is truthy)
-alert( true || 'no matter what' ); // (true is truthy)
 
 alert( null || 1 ); // 1 (1 is the first truthy value)
 alert( null || 0 || 1 ); // 1 (the first truthy value)
+
 alert( undefined || null || 0 ); // 0 (all falsy, returns the last value)
 ```
 
@@ -101,53 +101,40 @@ This leads to some interesting usage compared to a "pure, classical, boolean-onl
 
 1. **Getting the first truthy value from a list of variables or expressions.**
 
-    Imagine we have a list of variables which can either contain data or be `null/undefined`. How can we find the first one with data?
+    For instance, we have `firstName`, `lastName` and `nickName` variables, all optional (i.e. can be undefined or have falsy values).
 
-    We can use OR `||`:
+    Let's use OR `||` to choose the one that has the data and show it (or `"Anonymous"` if nothing set):
 
     ```js run
-    let currentUser = null;
-    let defaultUser = "John";
+    let firstName = "";
+    let lastName = "";
+    let nickName = "SuperCoder";
 
     *!*
-    let name = currentUser || defaultUser || "unnamed";
+    alert( firstName || lastName || nickName || "Anonymous"); // SuperCoder
     */!*
-
-    alert( name ); // selects "John" – the first truthy value
     ```
 
-    If both `currentUser` and `defaultUser` were falsy, `"unnamed"` would be the result.
-2. **Short-circuit evaluation.**
-
-    Operands can be not only values, but arbitrary expressions. OR evaluates and tests them from left to right. The evaluation stops when a truthy value is reached, and the value is returned. This process is called "a short-circuit evaluation" because it goes as short as possible from left to right.
+    If all variables were falsy, `"Anonymous"` would show up.
 
-    This is clearly seen when the expression given as the second argument has a side effect like a variable assignment.
+2. **Short-circuit evaluation.**
 
-    In the example below, `x` does not get assigned:
+    Another feature of OR `||` operator is the so-called "short-circuit" evaluation.
 
-    ```js run no-beautify
-    let x;
+    It means that `||` processes its arguments until the first truthy value is reached, and then the value is returned immediately, without even touching the other argument.
 
-    *!*true*/!* || (x = 1);
+    The importance of this feature becomes obvious if an operand isn't just a value, but an expression with a side effect, such as a variable assignment or a function call.
 
-    alert(x); // undefined, because (x = 1) not evaluated
-    ```
-
-    If, instead, the first argument is `false`, `||` evaluates the second one, thus running the assignment:
+    In the example below, only the second message is printed:
 
     ```js run no-beautify
-    let x;
-
-    *!*false*/!* || (x = 1);
-
-    alert(x); // 1
+    *!*true*/!* || alert("not printed");
+    *!*false*/!* || alert("printed");
     ```
 
-    An assignment is a simple case. There may be side effects, that won't show up if the evaluation doesn't reach them.
+    In the first line, the OR `||` operator stops the evaluation immediately upon seeing `true`, so the `alert` isn't run.
 
-    As we can see, such a use case is a "shorter way of doing `if`". The first operand is converted to boolean. If it's false, the second one is evaluated.
-
-    Most of time, it's better to use a "regular" `if` to keep the code easy to understand, but sometimes this can be handy.
+    Sometimes, people use this feature to execute commands only if the condition on the left part is falsy.
 
 ## && (AND)
 
@@ -236,7 +223,8 @@ The precedence of AND `&&` operator is higher than OR `||`.
 So the code `a && b || c && d` is essentially the same as if the `&&` expressions were in parentheses: `(a && b) || (c && d)`.
 ````
 
-Just like OR, the AND `&&` operator can sometimes replace `if`.
+````warn header="Don't replace `if` with `||` or `&&`"
+Sometimes, people use the AND `&&` operator as a "shorter way to write `if`".
 
 For instance:
 
@@ -253,14 +241,12 @@ So we basically have an analogue for:
 ```js run
 let x = 1;
 
-if (x > 0) {
-  alert( 'Greater than zero!' );
-}
+if (x > 0) alert( 'Greater than zero!' );
 ```
 
-The variant with `&&` appears shorter. But `if` is more obvious and tends to be a little bit more readable.
+Although, the variant with `&&` appears shorter, `if` is more obvious and tends to be a little bit more readable. So we recommend using every construct for its purpose: use `if` if we want `if` and use `&&` if we want AND.
+````
 
-So we recommend using every construct for its purpose: use `if` if we want if and use `&&` if we want AND.
 
 ## ! (NOT)
 
diff --git a/1-js/02-first-steps/12-nullish-coalescing-operator/article.md b/1-js/02-first-steps/12-nullish-coalescing-operator/article.md
index 676849f86..8534fa910 100644
--- a/1-js/02-first-steps/12-nullish-coalescing-operator/article.md
+++ b/1-js/02-first-steps/12-nullish-coalescing-operator/article.md
@@ -1,3 +1,4 @@
+<<<<<<< HEAD
 # Operator null'owego scalania '??'
 
 [recent browser="new"]
@@ -16,26 +17,61 @@ Innymi słowy, `??` zwraca pierwszy argument, którego wartość jest inna niż
 Operator null'owego scalania nie jest całkiem nowy. Jest to po prostu ładna składnia, aby dostać pierwszą zdefiniowaną wartość z dwóch dostępnych.
 
 Możemy zapisać `result = a ?? b` używając operatorów, które już znamy:
+=======
+# Nullish coalescing operator '??'
+
+[recent browser="new"]
+
+The nullish coalescing operator is written as two question marks `??`.
+
+As it treats `null` and `undefined` similarly, we'll use a special term here, in this article. For brevity, we'll say that a value is "defined" when it's neither `null` nor `undefined`.
+
+The result of `a ?? b` is:
+- if `a` is defined, then `a`,
+- if `a` isn't defined, then `b`.
+
+In other words, `??` returns the first argument if it's not `null/undefined`. Otherwise, the second one.
+
+The nullish coalescing operator isn't anything completely new. It's just a nice syntax to get the first "defined" value of the two.
+
+We can rewrite `result = a ?? b` using the operators that we already know, like this:
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ```js
 result = (a !== null && a !== undefined) ? a : b;
 ```
 
+<<<<<<< HEAD
 Typowym przykładem użycia `??` jest dostarczenie domyślnej wartości dla potencjalnie niezdefiniowanej zmiennej.
 
 Dla przykładu, wyświetlamy `Anonim`, jeżeli zmienna `user` jest niezdefiniowana:
+=======
+Now it should be absolutely clear what `??` does. Let's see where it helps.
+
+The common use case for `??` is to provide a default value.
+
+For example, here we show `user` if its value isn't `null/undefined`, otherwise `Anonymous`:
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ```js run
 let user;
 
+<<<<<<< HEAD
 alert(user ?? "Anonim"); // Anonim
 ```
 
 Oczywiście, jeżeli zmienna `user` ma inną wartość niż `null/undefined`, wtedy powinniśmy zobaczyć jej wartość:
+=======
+alert(user ?? "Anonymous"); // Anonymous (user is undefined)
+```
+
+Here's the example with `user` assigned to a name:
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ```js run
 let user = "John";
 
+<<<<<<< HEAD
 alert(user ?? "Anonim"); // John
 ```
 
@@ -46,12 +82,25 @@ Powiedzmy, że mamy dane użytkownika w zmiennych `firstName`, `lastName` oraz `
 Chcielibyśmy wyświetlić nazwę użytkownika używając jednej z tych zmiennych, albo wyświetlić "Anonim", jeżeli wszystkie są niezdefiniowane.
 
 Użyjmy do tego operatora `??`:
+=======
+alert(user ?? "Anonymous"); // John (user is not null/undefined)
+```
+
+We can also use a sequence of `??` to select the first value from a list that isn't `null/undefined`.
+
+Let's say we have a user's data in variables `firstName`, `lastName` or `nickName`. All of them may be not defined, if the user decided not to fill in the corresponding values.
+
+We'd like to display the user name using one of these variables, or show "Anonymous" if all of them are `null/undefined`.
+
+Let's use the `??` operator for that:
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ```js run
 let firstName = null;
 let lastName = null;
 let nickName = "Supercoder";
 
+<<<<<<< HEAD
 // pokazuje pierwszą zdefiniowaną wartość:
 *!*
 alert(firstName ?? lastName ?? nickName ?? "Anonim"); // Supercoder
@@ -63,12 +112,26 @@ alert(firstName ?? lastName ?? nickName ?? "Anonim"); // Supercoder
 Operator OR `||` może być użyty w ten sam sposób co `??`, jak to było opisane w [poprzednim rozdziale](info:logical-operators#or-finds-the-first-truthy-value).
 
 Dla przykładu, w kodzie powyżej, możemy zastąpić `??` z `||` i wciąż otrzymać ten sam rezultat:
+=======
+// shows the first defined value:
+*!*
+alert(firstName ?? lastName ?? nickName ?? "Anonymous"); // Supercoder
+*/!*
+```
+
+## Comparison with ||
+
+The OR `||` operator can be used in the same way as `??`, as it was described in the [previous chapter](info:logical-operators#or-finds-the-first-truthy-value).
+
+For example, in the code above we could replace `??` with `||` and still get the same result:
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ```js run
 let firstName = null;
 let lastName = null;
 let nickName = "Supercoder";
 
+<<<<<<< HEAD
 // pokazuje pierwszą truthy wartość:
 *!*
 alert(firstName || lastName || nickName || "Anonim"); // Supercoder
@@ -88,6 +151,27 @@ Innymi słowy, `||` nie rozróżnia pomiędzy `false`, `0`, pustym stringiem `""
 W praktyce jednak, możemy chcieć użyć domyślnej wartości tylko wtedy jeżeli zmienna ma wartość `null/undefined`. To znaczy tylko wtedy kiedy wartość naprawdę jest nieznana/nie ustawiona.
 
 Na przykład, rozważmy:
+=======
+// shows the first truthy value:
+*!*
+alert(firstName || lastName || nickName || "Anonymous"); // Supercoder
+*/!*
+```
+
+Historically, the OR `||` operator was there first. It's been there since the beginning of JavaScript, so developers were using it for such purposes for a long time.
+
+On the other hand, the nullish coalescing operator `??` was added to JavaScript only recently, and the reason for that was that people weren't quite happy with `||`.
+
+The important difference between them is that:
+- `||` returns the first *truthy* value.
+- `??` returns the first *defined* value.
+
+In other words, `||` doesn't distinguish between `false`, `0`, an empty string `""` and `null/undefined`. They are all the same -- falsy values. If any of these is the first argument of `||`, then we'll get the second argument as the result.
+
+In practice though, we may want to use default value only when the variable is `null/undefined`. That is, when the value is really unknown/not set.
+
+For example, consider this:
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ```js run
 let height = 0;
@@ -96,6 +180,7 @@ alert(height || 100); // 100
 alert(height ?? 100); // 0
 ```
 
+<<<<<<< HEAD
 - Wyrażenie `height || 100` sprawdza `height` pod kątem falsy wartości, i tak też właśnie jest.
     - w takim razie wynikiem jest drugi argument, `100`.
 - Wyrażenie `height ?? 100` sprawdza `height` pod kątem `null/undefined`, a zmienna `height` nie jest żadną z tych wartości,
@@ -108,17 +193,38 @@ Jeżeli zerowa wysokość jest poprawną wartością, która nie powinna być za
 Priorytet operatora `??` jest raczej niski: `5` [tabela MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#Table). Więc `??` jest przetwarzane przed `=` i `?`, ale po większości innych operatorów, jak `+`, `*`.
 
 Więc jeżeli chcemy wybrać wartość używając `??` w wyrażeniu z innymi operatorami, rozważ dodanie nawiasów:
+=======
+- The `height || 100` checks `height` for being a falsy value, and it's `0`, falsy indeed.
+    - so the result of `||` is the second argument, `100`.
+- The `height ?? 100` checks `height` for being `null/undefined`, and it's not,
+    - so the result is `height` "as is", that is `0`.
+
+In practice, the zero height is often a valid value, that shouldn't be replaced with the default. So `??` does just the right thing.
+
+## Precedence
+
+The precedence of the `??` operator is the same as `||`. They both equal `3` in the [MDN table](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#Table).
+
+That means that, just like `||`, the nullish coalescing operator `??` is evaluated before `=` and `?`, but after most other operations, such as `+`, `*`.
+
+So we may need to add parentheses in expressions like this:
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ```js run
 let height = null;
 let width = null;
 
+<<<<<<< HEAD
 // ważne: użyj nawiasów
+=======
+// important: use parentheses
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 let area = (height ?? 100) * (width ?? 50);
 
 alert(area); // 5000
 ```
 
+<<<<<<< HEAD
 W innym wypadku, jeżeli ominiemy nawiasy, wtedy `*` ma większy priorytet niż `??`, więc wykona się najpierw, prowadząc do niewłaściwych wyników.
 
 ```js
@@ -146,11 +252,41 @@ Używaj nawiasów żeby uniknąć problemu:
 ```js run
 *!*
 let x = (1 && 2) ?? 3; // Działa
+=======
+Otherwise, if we omit parentheses, then as `*` has the higher precedence than `??`, it would execute first, leading to incorrect results.
+
+```js
+// without parentheses
+let area = height ?? 100 * width ?? 50;
+
+// ...works this way (not what we want):
+let area = height ?? (100 * width) ?? 50;
+```
+
+### Using ?? with && or ||
+
+Due to safety reasons, JavaScript forbids using `??` together with `&&` and `||` operators, unless the precedence is explicitly specified with parentheses.
+
+The code below triggers a syntax error:
+
+```js run
+let x = 1 && 2 ?? 3; // Syntax error
+```
+
+The limitation is surely debatable, it was added to the language specification with the purpose to avoid programming mistakes, when people start to switch from `||` to `??`.
+
+Use explicit parentheses to work around it:
+
+```js run
+*!*
+let x = (1 && 2) ?? 3; // Works
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 */!*
 
 alert(x); // 2
 ```
 
+<<<<<<< HEAD
 ## Podsumowanie
 
 - Operator null'owego scalania `??` dostarcza szybszego sposobu na wybranie pierwszej zdefiniowanej wartości z listy.
@@ -164,3 +300,18 @@ alert(x); // 2
 
 - Operator `??` ma bardzo niski priorytet, tylko trochę wyższy niż `?` i `=`, zatem rozważ dodanie nawiasów w wyrażeniu.
 - Zabronione jest użycie z `||` lub `&&` bez użycia nawiasów.
+=======
+## Summary
+
+- The nullish coalescing operator `??` provides a short way to choose the first "defined" value from a list.
+
+    It's used to assign default values to variables:
+
+    ```js
+    // set height=100, if height is null or undefined
+    height = height ?? 100;
+    ```
+
+- The operator `??` has a very low precedence, only a bit higher than `?` and `=`, so consider adding parentheses when using it in an expression.
+- It's forbidden to use it with `||` or `&&` without explicit parentheses.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
diff --git a/1-js/02-first-steps/13-while-for/1-loop-last-value/solution.md b/1-js/02-first-steps/13-while-for/1-loop-last-value/solution.md
new file mode 100644
index 000000000..43ee4aad3
--- /dev/null
+++ b/1-js/02-first-steps/13-while-for/1-loop-last-value/solution.md
@@ -0,0 +1,25 @@
+The answer: `1`.
+
+```js run
+let i = 3;
+
+while (i) {
+  alert( i-- );
+}
+```
+
+Every loop iteration decreases `i` by `1`. The check `while(i)` stops the loop when `i = 0`.
+
+Hence, the steps of the loop form the following sequence ("loop unrolled"):
+
+```js
+let i = 3;
+
+alert(i--); // shows 3, decreases i to 2
+
+alert(i--) // shows 2, decreases i to 1
+
+alert(i--) // shows 1, decreases i to 0
+
+// done, while(i) check stops the loop
+```
diff --git a/1-js/02-first-steps/13-while-for/1-loop-last-value/task.md b/1-js/02-first-steps/13-while-for/1-loop-last-value/task.md
new file mode 100644
index 000000000..3b847dfa2
--- /dev/null
+++ b/1-js/02-first-steps/13-while-for/1-loop-last-value/task.md
@@ -0,0 +1,15 @@
+importance: 3
+
+---
+
+# Last loop value
+
+What is the last value alerted by this code? Why?
+
+```js
+let i = 3;
+
+while (i) {
+  alert( i-- );
+}
+```
diff --git a/1-js/02-first-steps/13-while-for/2-which-value-while/solution.md b/1-js/02-first-steps/13-while-for/2-which-value-while/solution.md
new file mode 100644
index 000000000..495359876
--- /dev/null
+++ b/1-js/02-first-steps/13-while-for/2-which-value-while/solution.md
@@ -0,0 +1,30 @@
+The task demonstrates how postfix/prefix forms can lead to different results when used in comparisons.
+
+1. **From 1 to 4**
+
+    ```js run
+    let i = 0;
+    while (++i < 5) alert( i );
+    ```
+
+    The first value is `i = 1`, because `++i` first increments `i` and then returns the new value. So the first comparison is `1 < 5` and the `alert` shows `1`.
+
+    Then follow `2, 3, 4…` -- the values show up one after another. The comparison always uses the incremented value, because `++` is before the variable.
+
+    Finally, `i = 4` is incremented to `5`, the comparison `while(5 < 5)` fails, and the loop stops. So `5` is not shown.
+2. **From 1 to 5**
+
+    ```js run
+    let i = 0;
+    while (i++ < 5) alert( i );
+    ```
+
+    The first value is again `i = 1`. The postfix form of `i++` increments `i` and then returns the *old* value, so the comparison `i++ < 5` will use `i = 0` (contrary to `++i < 5`).
+
+    But the `alert` call is separate. It's another statement which executes after the increment and the comparison. So it gets the current `i = 1`.
+
+    Then follow `2, 3, 4…`
+
+    Let's stop on `i = 4`. The prefix form `++i` would increment it and use `5` in the comparison. But here we have the postfix form `i++`. So it increments `i` to `5`, but returns the old value. Hence the comparison is actually `while(4 < 5)` -- true, and the control goes on to `alert`.
+
+    The value `i = 5` is the last one, because on the next step `while(5 < 5)` is false.
diff --git a/1-js/02-first-steps/13-while-for/2-which-value-while/task.md b/1-js/02-first-steps/13-while-for/2-which-value-while/task.md
new file mode 100644
index 000000000..298213237
--- /dev/null
+++ b/1-js/02-first-steps/13-while-for/2-which-value-while/task.md
@@ -0,0 +1,22 @@
+importance: 4
+
+---
+
+# Which values does the while loop show?
+
+For every loop iteration, write down which value it outputs and then compare it with the solution.
+
+Both loops `alert` the same values, or not?
+
+1. The prefix form `++i`:
+
+    ```js
+    let i = 0;
+    while (++i < 5) alert( i );
+    ```
+2. The postfix form `i++`
+
+    ```js
+    let i = 0;
+    while (i++ < 5) alert( i );
+    ```
diff --git a/1-js/02-first-steps/13-while-for/3-which-value-for/solution.md b/1-js/02-first-steps/13-while-for/3-which-value-for/solution.md
new file mode 100644
index 000000000..e2e28e75b
--- /dev/null
+++ b/1-js/02-first-steps/13-while-for/3-which-value-for/solution.md
@@ -0,0 +1,17 @@
+**The answer: from `0` to `4` in both cases.**
+
+```js run
+for (let i = 0; i < 5; ++i) alert( i );
+
+for (let i = 0; i < 5; i++) alert( i );
+```
+
+That can be easily deducted from the algorithm of `for`:
+
+1. Execute once `i = 0` before everything (begin).
+2. Check the condition `i < 5`
+3. If `true` -- execute the loop body `alert(i)`, and then `i++`
+
+The increment `i++` is separated from the condition check (2). That's just another statement.
+
+The value returned by the increment is not used here, so there's no difference between `i++` and `++i`.
diff --git a/1-js/02-first-steps/13-while-for/3-which-value-for/task.md b/1-js/02-first-steps/13-while-for/3-which-value-for/task.md
new file mode 100644
index 000000000..bfefa63f5
--- /dev/null
+++ b/1-js/02-first-steps/13-while-for/3-which-value-for/task.md
@@ -0,0 +1,20 @@
+importance: 4
+
+---
+
+# Which values get shown by the "for" loop?
+
+For each loop write down which values it is going to show. Then compare with the answer.
+
+Both loops `alert` same values or not?
+
+1. The postfix form:
+
+    ```js
+    for (let i = 0; i < 5; i++) alert( i );
+    ```
+2. The prefix form:
+
+    ```js
+    for (let i = 0; i < 5; ++i) alert( i );
+    ```
diff --git a/1-js/02-first-steps/13-while-for/4-for-even/solution.md b/1-js/02-first-steps/13-while-for/4-for-even/solution.md
new file mode 100644
index 000000000..e8e66bb47
--- /dev/null
+++ b/1-js/02-first-steps/13-while-for/4-for-even/solution.md
@@ -0,0 +1,11 @@
+
+
+```js run demo
+for (let i = 2; i <= 10; i++) {
+  if (i % 2 == 0) {
+    alert( i );
+  }
+}
+```
+
+We use the "modulo" operator `%` to get the remainder and check for the evenness here.
diff --git a/1-js/02-first-steps/13-while-for/4-for-even/task.md b/1-js/02-first-steps/13-while-for/4-for-even/task.md
new file mode 100644
index 000000000..ff34e7e40
--- /dev/null
+++ b/1-js/02-first-steps/13-while-for/4-for-even/task.md
@@ -0,0 +1,9 @@
+importance: 5
+
+---
+
+# Output even numbers in the loop
+
+Use the `for` loop to output even numbers from `2` to `10`.
+
+[demo]
diff --git a/1-js/02-first-steps/13-while-for/5-replace-for-while/solution.md b/1-js/02-first-steps/13-while-for/5-replace-for-while/solution.md
new file mode 100644
index 000000000..612cf559c
--- /dev/null
+++ b/1-js/02-first-steps/13-while-for/5-replace-for-while/solution.md
@@ -0,0 +1,10 @@
+
+
+```js run
+let i = 0;
+while (i < 3) {
+  alert( `number ${i}!` );
+  i++;
+}
+```
+
diff --git a/1-js/02-first-steps/13-while-for/5-replace-for-while/task.md b/1-js/02-first-steps/13-while-for/5-replace-for-while/task.md
new file mode 100644
index 000000000..0c69d9c2d
--- /dev/null
+++ b/1-js/02-first-steps/13-while-for/5-replace-for-while/task.md
@@ -0,0 +1,14 @@
+importance: 5
+
+---
+
+# Replace "for" with "while"
+
+Rewrite the code changing the `for` loop to `while` without altering its behavior (the output should stay same).
+
+```js run
+for (let i = 0; i < 3; i++) {
+  alert( `number ${i}!` );
+}
+```
+
diff --git a/1-js/02-first-steps/13-while-for/6-repeat-until-correct/solution.md b/1-js/02-first-steps/13-while-for/6-repeat-until-correct/solution.md
new file mode 100644
index 000000000..c7de5f09b
--- /dev/null
+++ b/1-js/02-first-steps/13-while-for/6-repeat-until-correct/solution.md
@@ -0,0 +1,15 @@
+
+```js run demo
+let num;
+
+do {
+  num = prompt("Enter a number greater than 100?", 0);
+} while (num <= 100 && num);
+```
+
+The loop `do..while` repeats while both checks are truthy:
+
+1. The check for `num <= 100` -- that is, the entered value is still not greater than `100`.
+2. The check `&& num` is false when `num` is `null` or an empty string. Then the `while` loop stops too.
+
+P.S. If `num` is `null` then `num <= 100` is `true`, so without the 2nd check the loop wouldn't stop if the user clicks CANCEL. Both checks are required.
diff --git a/1-js/02-first-steps/13-while-for/6-repeat-until-correct/task.md b/1-js/02-first-steps/13-while-for/6-repeat-until-correct/task.md
new file mode 100644
index 000000000..0788ee76e
--- /dev/null
+++ b/1-js/02-first-steps/13-while-for/6-repeat-until-correct/task.md
@@ -0,0 +1,13 @@
+importance: 5
+
+---
+
+# Repeat until the input is correct
+
+Write a loop which prompts for a number greater than `100`. If the visitor enters another number -- ask them to input again.
+
+The loop must ask for a number until either the visitor enters a number greater than `100` or cancels the input/enters an empty line.
+
+Here we can assume that the visitor only inputs numbers. There's no need to implement a special handling for a non-numeric input in this task.
+
+[demo]
diff --git a/1-js/02-first-steps/13-while-for/7-list-primes/solution.md b/1-js/02-first-steps/13-while-for/7-list-primes/solution.md
new file mode 100644
index 000000000..b4b64b6fa
--- /dev/null
+++ b/1-js/02-first-steps/13-while-for/7-list-primes/solution.md
@@ -0,0 +1,29 @@
+There are many algorithms for this task.
+
+Let's use a nested loop:
+
+```js
+For each i in the interval {
+  check if i has a divisor from 1..i
+  if yes => the value is not a prime
+  if no => the value is a prime, show it
+}
+```
+
+The code using a label:
+
+```js run
+let n = 10;
+
+nextPrime:
+for (let i = 2; i <= n; i++) { // for each i...
+
+  for (let j = 2; j < i; j++) { // look for a divisor..
+    if (i % j == 0) continue nextPrime; // not a prime, go next i
+  }
+
+  alert( i ); // a prime
+}
+```
+
+There's a lot of space to optimize it. For instance, we could look for the divisors from `2` to square root of `i`. But anyway, if we want to be really efficient for large intervals, we need to change the approach and rely on advanced maths and complex algorithms like [Quadratic sieve](https://en.wikipedia.org/wiki/Quadratic_sieve), [General number field sieve](https://en.wikipedia.org/wiki/General_number_field_sieve) etc.
diff --git a/1-js/02-first-steps/13-while-for/7-list-primes/task.md b/1-js/02-first-steps/13-while-for/7-list-primes/task.md
new file mode 100644
index 000000000..6344b9f6f
--- /dev/null
+++ b/1-js/02-first-steps/13-while-for/7-list-primes/task.md
@@ -0,0 +1,17 @@
+importance: 3
+
+---
+
+# Output prime numbers
+
+An integer number greater than `1` is called a [prime](https://en.wikipedia.org/wiki/Prime_number) if it cannot be divided without a remainder by anything except `1` and itself.
+
+In other words, `n > 1` is a prime if it can't be evenly divided by anything except `1` and `n`.
+
+For example, `5` is a prime, because it cannot be divided without a remainder by `2`, `3` and `4`.
+
+**Write the code which outputs prime numbers in the interval from `2` to `n`.**
+
+For `n = 10` the result will be `2,3,5,7`.
+
+P.S. The code should work for any `n`, not be hard-tuned for any fixed value.
diff --git a/1-js/02-first-steps/13-while-for/article.md b/1-js/02-first-steps/13-while-for/article.md
new file mode 100644
index 000000000..d1b749888
--- /dev/null
+++ b/1-js/02-first-steps/13-while-for/article.md
@@ -0,0 +1,411 @@
+# Loops: while and for
+
+We often need to repeat actions.
+
+For example, outputting goods from a list one after another or just running the same code for each number from 1 to 10.
+
+*Loops* are a way to repeat the same code multiple times.
+
+```smart header="The for..of and for..in loops"
+A small announcement for advanced readers.
+
+This article covers only basic loops: `while`, `do..while` and `for(..;..;..)`.
+
+If you came to this article searching for other types of loops, here are the pointers:
+
+- See [for..in](info:object#forin) to loop over object properties.
+- See [for..of](info:array#loops) and [iterables](info:iterable) for looping over arrays and iterable objects.
+
+Otherwise, please read on.
+```
+
+## The "while" loop
+
+The `while` loop has the following syntax:
+
+```js
+while (condition) {
+  // code
+  // so-called "loop body"
+}
+```
+
+While the `condition` is truthy, the `code` from the loop body is executed.
+
+For instance, the loop below outputs `i` while `i < 3`:
+
+```js run
+let i = 0;
+while (i < 3) { // shows 0, then 1, then 2
+  alert( i );
+  i++;
+}
+```
+
+A single execution of the loop body is called *an iteration*. The loop in the example above makes three iterations.
+
+If `i++` was missing from the example above, the loop would repeat (in theory) forever. In practice, the browser provides ways to stop such loops, and in server-side JavaScript, we can kill the process.
+
+Any expression or variable can be a loop condition, not just comparisons: the condition is evaluated and converted to a boolean by `while`.
+
+For instance, a shorter way to write `while (i != 0)` is `while (i)`:
+
+```js run
+let i = 3;
+*!*
+while (i) { // when i becomes 0, the condition becomes falsy, and the loop stops
+*/!*
+  alert( i );
+  i--;
+}
+```
+
+````smart header="Curly braces are not required for a single-line body"
+If the loop body has a single statement, we can omit the curly braces `{…}`:
+
+```js run
+let i = 3;
+*!*
+while (i) alert(i--);
+*/!*
+```
+````
+
+## The "do..while" loop
+
+The condition check can be moved *below* the loop body using the `do..while` syntax:
+
+```js
+do {
+  // loop body
+} while (condition);
+```
+
+The loop will first execute the body, then check the condition, and, while it's truthy, execute it again and again.
+
+For example:
+
+```js run
+let i = 0;
+do {
+  alert( i );
+  i++;
+} while (i < 3);
+```
+
+This form of syntax should only be used when you want the body of the loop to execute **at least once** regardless of the condition being truthy. Usually, the other form is preferred: `while(…) {…}`.
+
+## The "for" loop
+
+The `for` loop is more complex, but it's also the most commonly used loop.
+
+It looks like this:
+
+```js
+for (begin; condition; step) {
+  // ... loop body ...
+}
+```
+
+Let's learn the meaning of these parts by example. The loop below runs `alert(i)` for `i` from `0` up to (but not including) `3`:
+
+```js run
+for (let i = 0; i < 3; i++) { // shows 0, then 1, then 2
+  alert(i);
+}
+```
+
+Let's examine the `for` statement part-by-part:
+
+| part  |          |                                                                            |
+|-------|----------|----------------------------------------------------------------------------|
+| begin | `let i = 0`    | Executes once upon entering the loop.                                      |
+| condition | `i < 3`| Checked before every loop iteration. If false, the loop stops.              |
+| body | `alert(i)`| Runs again and again while the condition is truthy.                         |
+| step| `i++`      | Executes after the body on each iteration. |
+
+The general loop algorithm works like this:
+
+```
+Run begin
+→ (if condition → run body and run step)
+→ (if condition → run body and run step)
+→ (if condition → run body and run step)
+→ ...
+```
+
+That is, `begin` executes once, and then it iterates: after each `condition` test, `body` and `step` are executed.
+
+If you are new to loops, it could help to go back to the example and reproduce how it runs step-by-step on a piece of paper.
+
+Here's exactly what happens in our case:
+
+```js
+// for (let i = 0; i < 3; i++) alert(i)
+
+// run begin
+let i = 0
+// if condition → run body and run step
+if (i < 3) { alert(i); i++ }
+// if condition → run body and run step
+if (i < 3) { alert(i); i++ }
+// if condition → run body and run step
+if (i < 3) { alert(i); i++ }
+// ...finish, because now i == 3
+```
+
+````smart header="Inline variable declaration"
+Here, the "counter" variable `i` is declared right in the loop. This is called an "inline" variable declaration. Such variables are visible only inside the loop.
+
+```js run
+for (*!*let*/!* i = 0; i < 3; i++) {
+  alert(i); // 0, 1, 2
+}
+alert(i); // error, no such variable
+```
+
+Instead of defining a variable, we could use an existing one:
+
+```js run
+let i = 0;
+
+for (i = 0; i < 3; i++) { // use an existing variable
+  alert(i); // 0, 1, 2
+}
+
+alert(i); // 3, visible, because declared outside of the loop
+```
+````
+
+### Skipping parts
+
+Any part of `for` can be skipped.
+
+For example, we can omit `begin` if we don't need to do anything at the loop start.
+
+Like here:
+
+```js run
+let i = 0; // we have i already declared and assigned
+
+for (; i < 3; i++) { // no need for "begin"
+  alert( i ); // 0, 1, 2
+}
+```
+
+We can also remove the `step` part:
+
+```js run
+let i = 0;
+
+for (; i < 3;) {
+  alert( i++ );
+}
+```
+
+This makes the loop identical to `while (i < 3)`.
+
+We can actually remove everything, creating an infinite loop:
+
+```js
+for (;;) {
+  // repeats without limits
+}
+```
+
+Please note that the two `for` semicolons `;` must be present. Otherwise, there would be a syntax error.
+
+## Breaking the loop
+
+Normally, a loop exits when its condition becomes falsy.
+
+But we can force the exit at any time using the special `break` directive.
+
+For example, the loop below asks the user for a series of numbers, "breaking" when no number is entered:
+
+```js run
+let sum = 0;
+
+while (true) {
+
+  let value = +prompt("Enter a number", '');
+
+*!*
+  if (!value) break; // (*)
+*/!*
+
+  sum += value;
+
+}
+alert( 'Sum: ' + sum );
+```
+
+The `break` directive is activated at the line `(*)` if the user enters an empty line or cancels the input. It stops the loop immediately, passing control to the first line after the loop. Namely, `alert`.
+
+The combination "infinite loop + `break` as needed" is great for situations when a loop's condition must be checked not in the beginning or end of the loop, but in the middle or even in several places of its body.
+
+## Continue to the next iteration [#continue]
+
+The `continue` directive is a "lighter version" of `break`. It doesn't stop the whole loop. Instead, it stops the current iteration and forces the loop to start a new one (if the condition allows).
+
+We can use it if we're done with the current iteration and would like to move on to the next one.
+
+The loop below uses `continue` to output only odd values:
+
+```js run no-beautify
+for (let i = 0; i < 10; i++) {
+
+  // if true, skip the remaining part of the body
+  *!*if (i % 2 == 0) continue;*/!*
+
+  alert(i); // 1, then 3, 5, 7, 9
+}
+```
+
+For even values of `i`, the `continue` directive stops executing the body and passes control to the next iteration of `for` (with the next number). So the `alert` is only called for odd values.
+
+````smart header="The `continue` directive helps decrease nesting"
+A loop that shows odd values could look like this:
+
+```js run
+for (let i = 0; i < 10; i++) {
+
+  if (i % 2) {
+    alert( i );
+  }
+
+}
+```
+
+From a technical point of view, this is identical to the example above. Surely, we can just wrap the code in an `if` block instead of using `continue`.
+
+But as a side effect, this created one more level of nesting (the `alert` call inside the curly braces). If the code inside of `if` is longer than a few lines, that may decrease the overall readability.
+````
+
+````warn header="No `break/continue` to the right side of '?'"
+Please note that syntax constructs that are not expressions cannot be used with the ternary operator `?`. In particular, directives such as `break/continue` aren't allowed there.
+
+For example, if we take this code:
+
+```js
+if (i > 5) {
+  alert(i);
+} else {
+  continue;
+}
+```
+
+...and rewrite it using a question mark:
+
+```js no-beautify
+(i > 5) ? alert(i) : *!*continue*/!*; // continue isn't allowed here
+```
+
+...it stops working: there's a syntax error.
+
+This is just another reason not to use the question mark operator `?` instead of `if`.
+````
+
+## Labels for break/continue
+
+Sometimes we need to break out from multiple nested loops at once.
+
+For example, in the code below we loop over `i` and `j`, prompting for the coordinates `(i, j)` from `(0,0)` to `(2,2)`:
+
+```js run no-beautify
+for (let i = 0; i < 3; i++) {
+
+  for (let j = 0; j < 3; j++) {
+
+    let input = prompt(`Value at coords (${i},${j})`, '');
+
+    // what if we want to exit from here to Done (below)?
+  }
+}
+
+alert('Done!');
+```
+
+We need a way to stop the process if the user cancels the input.
+
+The ordinary `break` after `input` would only break the inner loop. That's not sufficient -- labels, come to the rescue!
+
+A *label* is an identifier with a colon before a loop:
+
+```js
+labelName: for (...) {
+  ...
+}
+```
+
+The `break <labelName>` statement in the loop below breaks out to the label:
+
+```js run no-beautify
+*!*outer:*/!* for (let i = 0; i < 3; i++) {
+
+  for (let j = 0; j < 3; j++) {
+
+    let input = prompt(`Value at coords (${i},${j})`, '');
+
+    // if an empty string or canceled, then break out of both loops
+    if (!input) *!*break outer*/!*; // (*)
+
+    // do something with the value...
+  }
+}
+
+alert('Done!');
+```
+
+In the code above, `break outer` looks upwards for the label named `outer` and breaks out of that loop.
+
+So the control goes straight from `(*)` to `alert('Done!')`.
+
+We can also move the label onto a separate line:
+
+```js no-beautify
+outer:
+for (let i = 0; i < 3; i++) { ... }
+```
+
+The `continue` directive can also be used with a label. In this case, code execution jumps to the next iteration of the labeled loop.
+
+````warn header="Labels do not allow to \"jump\" anywhere"
+Labels do not allow us to jump into an arbitrary place in the code.
+
+For example, it is impossible to do this:
+
+```js
+break label; // jump to the label below (doesn't work)
+
+label: for (...)
+```
+
+A `break` directive must be inside a code block. Technically, any labelled code block will do, e.g.:
+
+```js
+label: {
+  // ...
+  break label; // works
+  // ...
+}
+```
+
+...Although, 99.9% of the time `break` is used inside loops, as we've seen in the examples above.
+
+A `continue` is only possible from inside a loop.
+````
+
+## Summary
+
+We covered 3 types of loops:
+
+- `while` -- The condition is checked before each iteration.
+- `do..while` -- The condition is checked after each iteration.
+- `for (;;)` -- The condition is checked before each iteration, additional settings available.
+
+To make an "infinite" loop, usually the `while(true)` construct is used. Such a loop, just like any other, can be stopped with the `break` directive.
+
+If we don't want to do anything in the current iteration and would like to forward to the next one, we can use the `continue` directive.
+
+`break/continue` support labels before the loop. A label is the only way for `break/continue` to escape a nested loop to go to an outer one.
diff --git a/1-js/02-first-steps/13-switch/1-rewrite-switch-if-else/solution.md b/1-js/02-first-steps/14-switch/1-rewrite-switch-if-else/solution.md
similarity index 100%
rename from 1-js/02-first-steps/13-switch/1-rewrite-switch-if-else/solution.md
rename to 1-js/02-first-steps/14-switch/1-rewrite-switch-if-else/solution.md
diff --git a/1-js/02-first-steps/13-switch/1-rewrite-switch-if-else/task.md b/1-js/02-first-steps/14-switch/1-rewrite-switch-if-else/task.md
similarity index 100%
rename from 1-js/02-first-steps/13-switch/1-rewrite-switch-if-else/task.md
rename to 1-js/02-first-steps/14-switch/1-rewrite-switch-if-else/task.md
diff --git a/1-js/02-first-steps/13-switch/2-rewrite-if-switch/solution.md b/1-js/02-first-steps/14-switch/2-rewrite-if-switch/solution.md
similarity index 100%
rename from 1-js/02-first-steps/13-switch/2-rewrite-if-switch/solution.md
rename to 1-js/02-first-steps/14-switch/2-rewrite-if-switch/solution.md
diff --git a/1-js/02-first-steps/13-switch/2-rewrite-if-switch/task.md b/1-js/02-first-steps/14-switch/2-rewrite-if-switch/task.md
similarity index 100%
rename from 1-js/02-first-steps/13-switch/2-rewrite-if-switch/task.md
rename to 1-js/02-first-steps/14-switch/2-rewrite-if-switch/task.md
diff --git a/1-js/02-first-steps/13-switch/article.md b/1-js/02-first-steps/14-switch/article.md
similarity index 97%
rename from 1-js/02-first-steps/13-switch/article.md
rename to 1-js/02-first-steps/14-switch/article.md
index dec40a537..d86babcec 100644
--- a/1-js/02-first-steps/13-switch/article.md
+++ b/1-js/02-first-steps/14-switch/article.md
@@ -47,7 +47,7 @@ switch (a) {
     break;
 */!*
   case 5:
-    alert( 'Too large' );
+    alert( 'Too big' );
     break;
   default:
     alert( "I don't know such values" );
@@ -117,7 +117,7 @@ Several variants of `case` which share the same code can be grouped.
 For example, if we want the same code to run for `case 3` and `case 5`:
 
 ```js run no-beautify
-let a = 2 + 2;
+let a = 3;
 
 switch (a) {
   case 4:
@@ -139,7 +139,7 @@ switch (a) {
 
 Now both `3` and `5` show the same message.
 
-The ability to "group" cases is a side-effect of how `switch/case` works without `break`. Here the execution of `case 3` starts from the line `(*)` and goes through `case 5`, because there's no `break`.
+The ability to "group" cases is a side effect of how `switch/case` works without `break`. Here the execution of `case 3` starts from the line `(*)` and goes through `case 5`, because there's no `break`.
 
 ## Type matters
 
diff --git a/1-js/02-first-steps/15-function-basics/1-if-else-required/solution.md b/1-js/02-first-steps/15-function-basics/1-if-else-required/solution.md
new file mode 100644
index 000000000..e3a0df77c
--- /dev/null
+++ b/1-js/02-first-steps/15-function-basics/1-if-else-required/solution.md
@@ -0,0 +1,3 @@
+No difference!
+
+In both cases, `return confirm('Did parents allow you?')` executes exactly when the `if` condition is falsy.
\ No newline at end of file
diff --git a/1-js/02-first-steps/14-function-basics/1-if-else-required/task.md b/1-js/02-first-steps/15-function-basics/1-if-else-required/task.md
similarity index 100%
rename from 1-js/02-first-steps/14-function-basics/1-if-else-required/task.md
rename to 1-js/02-first-steps/15-function-basics/1-if-else-required/task.md
diff --git a/1-js/02-first-steps/14-function-basics/2-rewrite-function-question-or/solution.md b/1-js/02-first-steps/15-function-basics/2-rewrite-function-question-or/solution.md
similarity index 54%
rename from 1-js/02-first-steps/14-function-basics/2-rewrite-function-question-or/solution.md
rename to 1-js/02-first-steps/15-function-basics/2-rewrite-function-question-or/solution.md
index d4f906f7b..8d37df148 100644
--- a/1-js/02-first-steps/14-function-basics/2-rewrite-function-question-or/solution.md
+++ b/1-js/02-first-steps/15-function-basics/2-rewrite-function-question-or/solution.md
@@ -14,4 +14,8 @@ function checkAge(age) {
 }
 ```
 
+<<<<<<< HEAD:1-js/02-first-steps/14-function-basics/2-rewrite-function-question-or/solution.md
 Zwróć uwagę że nawiasy wokół `age > 18` nie są tutaj wymagane. Są tutaj dla lepszej czytelności.
+=======
+Note that the parentheses around `age > 18` are not required here. They exist for better readability.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3:1-js/02-first-steps/15-function-basics/2-rewrite-function-question-or/solution.md
diff --git a/1-js/02-first-steps/14-function-basics/2-rewrite-function-question-or/task.md b/1-js/02-first-steps/15-function-basics/2-rewrite-function-question-or/task.md
similarity index 100%
rename from 1-js/02-first-steps/14-function-basics/2-rewrite-function-question-or/task.md
rename to 1-js/02-first-steps/15-function-basics/2-rewrite-function-question-or/task.md
diff --git a/1-js/02-first-steps/14-function-basics/3-min/solution.md b/1-js/02-first-steps/15-function-basics/3-min/solution.md
similarity index 100%
rename from 1-js/02-first-steps/14-function-basics/3-min/solution.md
rename to 1-js/02-first-steps/15-function-basics/3-min/solution.md
diff --git a/1-js/02-first-steps/14-function-basics/3-min/task.md b/1-js/02-first-steps/15-function-basics/3-min/task.md
similarity index 100%
rename from 1-js/02-first-steps/14-function-basics/3-min/task.md
rename to 1-js/02-first-steps/15-function-basics/3-min/task.md
diff --git a/1-js/02-first-steps/14-function-basics/4-pow/solution.md b/1-js/02-first-steps/15-function-basics/4-pow/solution.md
similarity index 100%
rename from 1-js/02-first-steps/14-function-basics/4-pow/solution.md
rename to 1-js/02-first-steps/15-function-basics/4-pow/solution.md
diff --git a/1-js/02-first-steps/14-function-basics/4-pow/task.md b/1-js/02-first-steps/15-function-basics/4-pow/task.md
similarity index 100%
rename from 1-js/02-first-steps/14-function-basics/4-pow/task.md
rename to 1-js/02-first-steps/15-function-basics/4-pow/task.md
diff --git a/1-js/02-first-steps/14-function-basics/article.md b/1-js/02-first-steps/15-function-basics/article.md
similarity index 72%
rename from 1-js/02-first-steps/14-function-basics/article.md
rename to 1-js/02-first-steps/15-function-basics/article.md
index 788a6c46a..1e7cb64d0 100644
--- a/1-js/02-first-steps/14-function-basics/article.md
+++ b/1-js/02-first-steps/15-function-basics/article.md
@@ -20,11 +20,19 @@ function showMessage() {
 }
 ```
 
+<<<<<<< HEAD:1-js/02-first-steps/14-function-basics/article.md
 Pierwsze jest słowo kluczowe `function`, następnie znajduję się *nazwa funkcji*, później lista *parametrów* pomiędzy nawiasami (rozdzielonych przecinkami, pusta w przykładzie powyżej) i na końcu blok kodu funkcji, nazywany również "ciałem funkcji", pomiędzy nawiasami klamrowymi.
 
 ```js
 function name(parametry) {
   ...ciało...
+=======
+The `function` keyword goes first, then goes the *name of the function*, then a list of *parameters* between the parentheses (comma-separated, empty in the example above, we'll see examples later) and finally the code of the function, also named "the function body", between curly braces.
+
+```js
+function name(parameter1, parameter2, ... parameterN) {
+ // body
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3:1-js/02-first-steps/15-function-basics/article.md
 }
 ```
 
@@ -137,11 +145,16 @@ Dobrą praktyką jest minimalizacja użycia zmiennych globalnych. Nowoczesny kod
 
 ## Parametry
 
+<<<<<<< HEAD:1-js/02-first-steps/14-function-basics/article.md
 Możemy przekazać arbitralne dane do funkcji używając parametrów (nazywanych również *argumentami funkcji*).
+=======
+We can pass arbitrary data to functions using parameters.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3:1-js/02-first-steps/15-function-basics/article.md
 
 W przykładzie poniżej, funkcja posiada dwa parametry: `from` i `text`.
 
 ```js run
+<<<<<<< HEAD:1-js/02-first-steps/14-function-basics/article.md
 function showMessage(*!*from, text*/!*) { // argumenty: from, text
   alert(from + ': ' + text);
 }
@@ -150,13 +163,20 @@ function showMessage(*!*from, text*/!*) { // argumenty: from, text
 showMessage('Anna', 'Cześć!'); // Ann: Cześć! (*)
 showMessage('Anna', "Co słychać?"); // Ann: Co słychać? (**)
 */!*
+=======
+function showMessage(*!*from, text*/!*) { // parameters: from, text
+  alert(from + ': ' + text);
+}
+
+*!*showMessage('Ann', 'Hello!');*/!* // Ann: Hello! (*)
+*!*showMessage('Ann', "What's up?");*/!* // Ann: What's up? (**)
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3:1-js/02-first-steps/15-function-basics/article.md
 ```
 
 Kiedy funkcja jest wywoływana w linijkach `(*)` oraz `(**)`, podane do niej parametry są kopiowane do lokalnych zmiennych `from` i `text`. Poźniej funkcja ich używa.
 
 Tutaj kolejny przykład: mamy zmienną `from` i przekazujemy ją do funkcji. Zwróć uwagę: funkcja zmienia `from`, ale zmiana nie jest widoczna na zewnątrz, ponieważ funkcja zawsze dostaje kopię jej wartości:
 
-
 ```js run
 function showMessage(from, text) {
 
@@ -175,9 +195,27 @@ showMessage(from, "Cześć"); // *Anna*: Cześć
 alert( from ); // Anna
 ```
 
+<<<<<<< HEAD:1-js/02-first-steps/14-function-basics/article.md
 ## Domyślna wartość
 
 Jeżeli parametr nie jest dostarczony do funckji, wówczas jego wartość przyjmuję `undefined`.
+=======
+When a value is passed as a function parameter, it's also called an *argument*.
+
+In other words, to put these terms straight:
+
+- A parameter is the variable listed inside the parentheses in the function declaration (it's a declaration time term).
+- An argument is the value that is passed to the function when it is called (it's a call time term).
+
+We declare functions listing their parameters, then call them passing arguments.
+
+In the example above, one might say: "the function `showMessage` is declared with two parameters, then called with two arguments: `from` and `"Hello"`".
+
+
+## Default values
+
+If a function is called, but an argument is not provided, then the corresponding value becomes `undefined`.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3:1-js/02-first-steps/15-function-basics/article.md
 
 Na przykład, wyżej wymieniona funckja `showMessage(from, text)` może zostać wywołana z jednym argumentem:
 
@@ -185,9 +223,15 @@ Na przykład, wyżej wymieniona funckja `showMessage(from, text)` może zostać
 showMessage('Anna');
 ```
 
+<<<<<<< HEAD:1-js/02-first-steps/14-function-basics/article.md
 To nie błąd. Takie wywołanie da wynik `"Anna: undefined"`. Nie ma argumentu `text`, więc funkcja zakłada że `text === undefined`.
 
 Jeżeli chcemy użyć "domyślnego" argumentu `text` w tym przypadku, możemy go okreslić po znaku `=`:
+=======
+That's not an error. Such a call would output `"*Ann*: undefined"`. As the value for `text` isn't passed, it becomes `undefined`.
+
+We can specify the so-called "default" (to use if omitted) value for a parameter in the function declaration, using `=`:
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3:1-js/02-first-steps/15-function-basics/article.md
 
 ```js run
 function showMessage(from, *!*text = "brak tekstu"*/!*) {
@@ -197,7 +241,17 @@ function showMessage(from, *!*text = "brak tekstu"*/!*) {
 showMessage("Anna"); // Anna: brak tekstu
 ```
 
+<<<<<<< HEAD:1-js/02-first-steps/14-function-basics/article.md
 Teraz jeżeli parametr `text` nie zostaje przekazany, przybiera wartość `"brak tekstu"`.
+=======
+Now if the `text` parameter is not passed, it will get the value `"no text given"`.
+
+The default value also jumps in if the parameter exists, but strictly equals `undefined`, like this:
+
+```js
+showMessage("Ann", undefined); // Ann: no text given
+```
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3:1-js/02-first-steps/15-function-basics/article.md
 
 W tym przypadku `"brak tekstu"` jest stringiem, ale może być bardziej złożonym wyrażeniem, co jest oceniane i przypisywane tylko w przypadku braku parametru. Więc, to również jest możliwe:
 
@@ -211,6 +265,7 @@ function showMessage(from, text = anotherFunction()) {
 ```smart header="Ewaluacja domyślnych parametrów"
 W JavaScripcie, domyślny parametr jest ewaluowany za każdym razem kiedy funkcja jest wywoływany bez tego parametru.
 
+<<<<<<< HEAD:1-js/02-first-steps/14-function-basics/article.md
 W przykładzie powyżej, `anotherFunction()` jest wywoływana za każdym razem kiedy `showMessage()` jest wywoływana bez parametru `text`.
 ```
 
@@ -218,6 +273,19 @@ W przykładzie powyżej, `anotherFunction()` jest wywoływana za każdym razem k
 Stare wersje JavaScriptu nie wspierają domyślnych parametrów. Są więc alternatywne sposóby na ich wspieranie, które możesz spotkać głównie w starszych skryptach.
 
 Na przykład, konkretne sprawdzenie czy zmienna jest `undefined`:
+=======
+In the example above, `anotherFunction()` isn't called at all, if the `text` parameter is provided.
+
+On the other hand, it's independently called every time when `text` is missing.
+```
+
+````smart header="Default parameters in old JavaScript code"
+Several years ago, JavaScript didn't support the syntax for default parameters. So people used other ways to specify them.
+
+Nowadays, we can come across them in old scripts.
+
+For example, an explicit check for `undefined`:
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3:1-js/02-first-steps/15-function-basics/article.md
 
 ```js
 function showMessage(from, text) {
@@ -231,21 +299,78 @@ function showMessage(from, text) {
 }
 ```
 
+<<<<<<< HEAD:1-js/02-first-steps/14-function-basics/article.md
 ...lub użycie operatora `||`:
 
 ```js
 function showMessage(from, text) {
   // jeżeli text przyjmuje wartość fałszywą, wówczas text przyjmuje wartość "domyślną"
   text = text || 'brak tekstu';
+=======
+...Or using the `||` operator:
+
+```js
+function showMessage(from, text) {
+  // If the value of text is falsy, assign the default value
+  // this assumes that text == "" is the same as no text at all
+  text = text || 'no text given';
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3:1-js/02-first-steps/15-function-basics/article.md
   ...
 }
 ```
-
-
 ````
 
 
+<<<<<<< HEAD:1-js/02-first-steps/14-function-basics/article.md
 ## Zwracanie wartości
+=======
+### Alternative default parameters
+
+Sometimes it makes sense to assign default values for parameters at a later stage after the function declaration.
+
+We can check if the parameter is passed during the function execution, by comparing it with `undefined`:
+
+```js run
+function showMessage(text) {
+  // ...
+
+*!*
+  if (text === undefined) { // if the parameter is missing
+    text = 'empty message';
+  }
+*/!*
+
+  alert(text);
+}
+
+showMessage(); // empty message
+```
+
+...Or we could use the `||` operator:
+
+```js
+function showMessage(text) {
+  // if text is undefined or otherwise falsy, set it to 'empty'
+  text = text || 'empty';
+  ...
+}
+```
+
+Modern JavaScript engines support the [nullish coalescing operator](info:nullish-coalescing-operator) `??`, it's better when most falsy values, such as `0`, should be considered "normal":
+
+```js run
+function showCount(count) {
+  // if count is undefined or null, show "unknown"
+  alert(count ?? "unknown");
+}
+
+showCount(0); // 0
+showCount(null); // unknown
+showCount(); // unknown
+```
+
+## Returning a value
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3:1-js/02-first-steps/15-function-basics/article.md
 
 Funkcja może zwracać wartość z powrotem do wywołującego ją kodu jako rezultat.
 
@@ -266,7 +391,7 @@ Może być wiele wystąpień dyrektywy `return` w pojedynczej funkcji. Na przyk
 
 ```js run
 function checkAge(age) {
-  if (age > 18) {
+  if (age >= 18) {
 *!*
     return true;
 */!*
@@ -397,9 +522,15 @@ Te przykłady zakładają powszechne znaczenie przedrostków. Ty i twój zespó
 ```smart header="Ultra-krótkie nazwy funkcji"
 Funkcje które są używane *bardzo często* czasami mają ultra-krótkie nazwy.
 
+<<<<<<< HEAD:1-js/02-first-steps/14-function-basics/article.md
 Na przykład, framework [jQuery](http://jquery.com) definiuje funkcje za pomocą `$`. Bibloteka [Lodash](http://lodash.com/) ma swoją główną funkcję nazwaną `_`.
 
 To są wyjątki. Ogólnie nazwy funkcji powinny być zwięzłe i opisowe.
+=======
+For example, the [jQuery](https://jquery.com/) framework defines a function with `$`. The [Lodash](https://lodash.com/) library has its core function named `_`.
+
+These are exceptions. Generally function names should be concise and descriptive.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3:1-js/02-first-steps/15-function-basics/article.md
 ```
 
 ## Funkcje == Komentarze
@@ -465,7 +596,11 @@ function name(parametry, rozdzielone, przecinkiem) {
 
 Aby kod był czysty i łatwy do zrozumienia, rekomendowane jest używanie głównie zmiennych lokalnych i parametrów wewnątrz funkcji, nie zewnętrznych zmiennych.
 
+<<<<<<< HEAD:1-js/02-first-steps/14-function-basics/article.md
 Zawsze łatwiejsze jest zrozumienie funkcji która otrzymuje parametry, pracuje z nimi i zwraca wynik niż funkcji która nie przyjmuje żadnych parametrów, ale modyfikuje zewnętrzne zmienne jako efekt uboczny.
+=======
+It is always easier to understand a function which gets parameters, works with them and returns a result than a function which gets no parameters, but modifies outer variables as a side effect.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3:1-js/02-first-steps/15-function-basics/article.md
 
 Nazewnictwo funkcji:
 
diff --git a/1-js/02-first-steps/15-function-expressions/article.md b/1-js/02-first-steps/16-function-expressions/article.md
similarity index 82%
rename from 1-js/02-first-steps/15-function-expressions/article.md
rename to 1-js/02-first-steps/16-function-expressions/article.md
index a8ccd6c6c..b952d5943 100644
--- a/1-js/02-first-steps/15-function-expressions/article.md
+++ b/1-js/02-first-steps/16-function-expressions/article.md
@@ -12,7 +12,9 @@ function sayHi() {
 
 There is another syntax for creating a function that is called a *Function Expression*.
 
-It looks like this:
+It allows us to create a new function in the middle of any expression.
+
+For example:
 
 ```js
 let sayHi = function() {
@@ -20,9 +22,19 @@ let sayHi = function() {
 };
 ```
 
-Here, the function is created and assigned to the variable explicitly, like any other value. No matter how the function is defined, it's just a value stored in the variable `sayHi`.
+Here we can see a variable `sayHi` getting a value, the new function, created as `function() { alert("Hello"); }`.
+
+As the function creation happens in the context of the assignment expression (to the right side of `=`), this is a *Function Expression*.
+
+Please note, there's no name after the `function` keyword. Omitting a name is allowed for Function Expressions.
+
+Here we immediately assign it to the variable, so the meaning of these code samples is the same: "create a function and put it into the variable `sayHi`".
+
+In more advanced situations, that we'll come across later, a function may be created and immediately called or scheduled for a later execution, not stored anywhere, thus remaining anonymous.
 
-The meaning of these code samples is the same: "create a function and put it into the variable `sayHi`".
+## Function is a value
+
+Let's reiterate: no matter how the function is created, a function is a value. Both examples above store a function in the `sayHi` variable.
 
 We can even print out that value using `alert`:
 
@@ -63,10 +75,10 @@ Here's what happens above in detail:
 2. Line `(2)` copies it into the variable `func`. Please note again: there are no parentheses after `sayHi`. If there were, then `func = sayHi()` would write  *the result of the call* `sayHi()` into `func`, not *the function* `sayHi` itself.
 3. Now the function can be called as both `sayHi()` and `func()`.
 
-Note that we could also have used a Function Expression to declare `sayHi`, in the first line:
+We could also have used a Function Expression to declare `sayHi`, in the first line:
 
 ```js
-let sayHi = function() {
+let sayHi = function() { // (1) create
   alert( "Hello" );
 };
 
@@ -78,7 +90,7 @@ Everything would work the same.
 
 
 ````smart header="Why is there a semicolon at the end?"
-You might wonder, why does Function Expression have a semicolon `;` at the end, but Function Declaration does not:
+You might wonder, why do Function Expressions have a semicolon `;` at the end, but Function Declarations do not:
 
 ```js
 function sayHi() {
@@ -90,9 +102,9 @@ let sayHi = function() {
 }*!*;*/!*
 ```
 
-The answer is simple:
-- There's no need for `;` at the end of code blocks and syntax structures that use them like `if { ... }`, `for {  }`, `function f { }` etc.
-- A Function Expression is used inside the statement: `let sayHi = ...;`, as a value. It's not a code block, but rather an assignment. The semicolon `;` is recommended at the end of statements, no matter what the value is. So the semicolon here is not related to the Function Expression itself, it just terminates the statement.
+The answer is simple: a Function Expression is created here as `function(…) {…}` inside the assignment statement: `let sayHi = …;`. The semicolon `;` is recommended at the end of the statement, it's not a part of the function syntax.
+
+The semicolon would be there for a simpler assignment, such as `let sayHi = 5;`, and it's also there for a function assignment.
 ````
 
 ## Callback functions
@@ -132,13 +144,13 @@ function showCancel() {
 ask("Do you agree?", showOk, showCancel);
 ```
 
-In practice, such functions are quite useful. The major difference between a real-life `ask` and the example above is that real-life functions use more complex ways to interact with the user than a simple `confirm`. In the browser, such function usually draws a nice-looking question window. But that's another story.
+In practice, such functions are quite useful. The major difference between a real-life `ask` and the example above is that real-life functions use more complex ways to interact with the user than a simple `confirm`. In the browser, such functions usually draw a nice-looking question window. But that's another story.
 
 **The arguments `showOk` and `showCancel` of `ask` are called *callback functions* or just *callbacks*.**
 
 The idea is that we pass a function and expect it to be "called back" later if necessary. In our case, `showOk` becomes the callback for "yes" answer, and `showCancel` for "no" answer.
 
-We can use Function Expressions to write the same function much shorter:
+We can use Function Expressions to write an equivalent, shorter function:
 
 ```js run no-beautify
 function ask(question, yes, no) {
@@ -174,7 +186,7 @@ Let's formulate the key differences between Function Declarations and Expression
 
 First, the syntax: how to differentiate between them in the code.
 
-- *Function Declaration:* a function, declared as a separate statement, in the main code flow.
+- *Function Declaration:* a function, declared as a separate statement, in the main code flow:
 
     ```js
     // Function Declaration
@@ -182,7 +194,7 @@ First, the syntax: how to differentiate between them in the code.
       return a + b;
     }
     ```
-- *Function Expression:* a function, created inside an expression or inside another syntax construct. Here, the function is created at the right side of the "assignment expression" `=`:
+- *Function Expression:* a function, created inside an expression or inside another syntax construct. Here, the function is created on the right side of the "assignment expression" `=`:
 
     ```js
     // Function Expression
@@ -279,7 +291,7 @@ if (age < 18) {
   welcome();               // \   (runs)
 */!*
                            //  |
-  function welcome() {     //  |  
+  function welcome() {     //  |
     alert("Hello!");       //  |  Function Declaration is available
   }                        //  |  everywhere in the block where it's declared
                            //  |
@@ -289,7 +301,7 @@ if (age < 18) {
 
 } else {
 
-  function welcome() {    
+  function welcome() {
     alert("Greetings!");
   }
 }
@@ -348,7 +360,7 @@ welcome(); // ok now
 
 
 ```smart header="When to choose Function Declaration versus Function Expression?"
-As a rule of thumb, when we need to declare a function, the first to consider is Function Declaration syntax. It gives more freedom in how to organize our code, because we can call such functions before they are declared.
+As a rule of thumb, when we need to declare a function, the first thing to consider is Function Declaration syntax. It gives more freedom in how to organize our code, because we can call such functions before they are declared.
 
 That's also better for readability, as it's easier to look up `function f(…) {…}` in the code than `let f = function(…) {…};`. Function Declarations are more "eye-catching".
 
diff --git a/1-js/02-first-steps/16-arrow-functions-basics/1-rewrite-arrow/solution.md b/1-js/02-first-steps/17-arrow-functions-basics/1-rewrite-arrow/solution.md
similarity index 86%
rename from 1-js/02-first-steps/16-arrow-functions-basics/1-rewrite-arrow/solution.md
rename to 1-js/02-first-steps/17-arrow-functions-basics/1-rewrite-arrow/solution.md
index 3ea112473..041db18bc 100644
--- a/1-js/02-first-steps/16-arrow-functions-basics/1-rewrite-arrow/solution.md
+++ b/1-js/02-first-steps/17-arrow-functions-basics/1-rewrite-arrow/solution.md
@@ -1,7 +1,7 @@
 
 ```js run
 function ask(question, yes, no) {
-  if (confirm(question)) yes()
+  if (confirm(question)) yes();
   else no();
 }
 
diff --git a/1-js/02-first-steps/16-arrow-functions-basics/1-rewrite-arrow/task.md b/1-js/02-first-steps/17-arrow-functions-basics/1-rewrite-arrow/task.md
similarity index 90%
rename from 1-js/02-first-steps/16-arrow-functions-basics/1-rewrite-arrow/task.md
rename to 1-js/02-first-steps/17-arrow-functions-basics/1-rewrite-arrow/task.md
index 2f44db27e..e18c08a83 100644
--- a/1-js/02-first-steps/16-arrow-functions-basics/1-rewrite-arrow/task.md
+++ b/1-js/02-first-steps/17-arrow-functions-basics/1-rewrite-arrow/task.md
@@ -5,7 +5,7 @@ Replace Function Expressions with arrow functions in the code below:
 
 ```js run
 function ask(question, yes, no) {
-  if (confirm(question)) yes()
+  if (confirm(question)) yes();
   else no();
 }
 
diff --git a/1-js/02-first-steps/16-arrow-functions-basics/article.md b/1-js/02-first-steps/17-arrow-functions-basics/article.md
similarity index 69%
rename from 1-js/02-first-steps/16-arrow-functions-basics/article.md
rename to 1-js/02-first-steps/17-arrow-functions-basics/article.md
index 02090f3c1..50c0d475d 100644
--- a/1-js/02-first-steps/16-arrow-functions-basics/article.md
+++ b/1-js/02-first-steps/17-arrow-functions-basics/article.md
@@ -5,15 +5,15 @@ There's another very simple and concise syntax for creating functions, that's of
 It's called "arrow functions", because it looks like this:
 
 ```js
-let func = (arg1, arg2, ...argN) => expression
+let func = (arg1, arg2, ..., argN) => expression;
 ```
 
-...This creates a function `func` that accepts arguments `arg1..argN`, then evaluates the `expression` on the right side with their use and returns its result.
+This creates a function `func` that accepts arguments `arg1..argN`, then evaluates the `expression` on the right side with their use and returns its result.
 
 In other words, it's the shorter version of:
 
 ```js
-let func = function(arg1, arg2, ...argN) {
+let func = function(arg1, arg2, ..., argN) {
   return expression;
 };
 ```
@@ -33,7 +33,7 @@ let sum = function(a, b) {
 alert( sum(1, 2) ); // 3
 ```
 
-As you can, see `(a, b) => a + b` means a function that accepts two arguments named `a` and `b`. Upon the execution, it evaluates the expression `a + b` and returns the result.
+As you can see, `(a, b) => a + b` means a function that accepts two arguments named `a` and `b`. Upon the execution, it evaluates the expression `a + b` and returns the result.
 
 - If we have only one argument, then parentheses around parameters can be omitted, making that even shorter.
 
@@ -48,7 +48,7 @@ As you can, see `(a, b) => a + b` means a function that accepts two arguments na
     alert( double(3) ); // 6
     ```
 
-- If there are no arguments, parentheses will be empty (but they should be present):
+- If there are no arguments, parentheses are empty, but they must be present:
 
     ```js run
     let sayHi = () => alert("Hello!");
@@ -64,10 +64,10 @@ For instance, to dynamically create a function:
 let age = prompt("What is your age?", 18);
 
 let welcome = (age < 18) ?
-  () => alert('Hello') :
+  () => alert('Hello!') :
   () => alert("Greetings!");
 
-welcome(); // ok now
+welcome();
 ```
 
 Arrow functions may appear unfamiliar and not very readable at first, but that quickly changes as the eyes get used to the structure.
@@ -76,9 +76,9 @@ They are very convenient for simple one-line actions, when we're just too lazy t
 
 ## Multiline arrow functions
 
-The examples above took arguments from the left of `=>` and evaluated the right-side expression with them.
+The arrow functions that we've seen so far were very simple. They took arguments from the left of `=>`, evaluated and returned the right-side expression with them.
 
-Sometimes we need something a little bit more complex, like multiple expressions or statements. It is also possible, but we should enclose them in curly braces. Then use a normal `return` within them.
+Sometimes we need a more complex function, with multiple expressions and statements. In that case, we can enclose them in curly braces. The major difference is that curly braces require a `return` within them to return a value (just like a regular function does).
 
 Like this:
 
@@ -86,7 +86,7 @@ Like this:
 let sum = (a, b) => {  // the curly brace opens a multiline function
   let result = a + b;
 *!*
-  return result; // if we use curly braces, then we need an explicit "return" 
+  return result; // if we use curly braces, then we need an explicit "return"
 */!*
 };
 
@@ -105,7 +105,7 @@ For now, we can already use arrow functions for one-line actions and callbacks.
 
 ## Summary
 
-Arrow functions are handy for one-liners. They come in two flavors:
+Arrow functions are handy for simple actions, especially for one-liners. They come in two flavors:
 
-1. Without curly braces: `(...args) => expression` -- the right side is an expression: the function evaluates it and returns the result.
+1. Without curly braces: `(...args) => expression` -- the right side is an expression: the function evaluates it and returns the result. Parentheses can be omitted, if there's only a single argument, e.g. `n => n*2`.
 2. With curly braces: `(...args) => { body }` -- brackets allow us to write multiple statements inside the function, but we need an explicit `return` to return something.
diff --git a/1-js/02-first-steps/17-javascript-specials/article.md b/1-js/02-first-steps/18-javascript-specials/article.md
similarity index 88%
rename from 1-js/02-first-steps/17-javascript-specials/article.md
rename to 1-js/02-first-steps/18-javascript-specials/article.md
index cfc043d7d..e7ddacac4 100644
--- a/1-js/02-first-steps/17-javascript-specials/article.md
+++ b/1-js/02-first-steps/18-javascript-specials/article.md
@@ -55,7 +55,7 @@ To fully enable all features of modern JavaScript, we should start scripts with
 
 The directive must be at the top of a script or at the beginning of a function body.
 
-Without `"use strict"`, everything still works, but some features behave in the old-fashion, "compatible" way. We'd generally prefer the modern behavior.
+Without `"use strict"`, everything still works, but some features behave in the old-fashioned, "compatible" way. We'd generally prefer the modern behavior.
 
 Some modern features of the language (like classes that we'll study in the future) enable strict mode implicitly.
 
@@ -81,9 +81,10 @@ let x = 5;
 x = "John";
 ```
 
-There are 7 data types:
+There are 8 data types:
 
 - `number` for both floating-point and integer numbers,
+- `bigint` for integer numbers of arbitrary length,
 - `string` for strings,
 - `boolean` for logical values: `true/false`,
 - `null` -- a type with a single value `null`, meaning "empty" or "does not exist",
@@ -102,13 +103,13 @@ More in: <info:variables> and <info:types>.
 
 We're using a browser as a working environment, so basic UI functions will be:
 
-[`prompt(question, [default])`](mdn:api/Window/prompt)
+[`prompt(question, [default])`](https://developer.mozilla.org/en-US/docs/Web/API/Window/prompt)
 : Ask a `question`, and return either what the visitor entered or `null` if they clicked "cancel".
 
-[`confirm(question)`](mdn:api/Window/confirm)
+[`confirm(question)`](https://developer.mozilla.org/en-US/docs/Web/API/Window/confirm)
 : Ask a `question` and suggest to choose between Ok and Cancel. The choice is returned as `true/false`.
 
-[`alert(message)`](mdn:api/Window/alert)
+[`alert(message)`](https://developer.mozilla.org/en-US/docs/Web/API/Window/alert)
 : Output a `message`.
 
 All these functions are *modal*, they pause the code execution and prevent the visitor from interacting with the page until they answer.
@@ -143,7 +144,7 @@ Assignments
 : There is a simple assignment: `a = b` and combined ones like `a *= 2`.
 
 Bitwise
-: Bitwise operators work with 32-bit integers at the lowest, bit-level: see the [docs](mdn:/JavaScript/Reference/Operators/Bitwise_Operators) when they are needed.
+: Bitwise operators work with 32-bit integers at the lowest, bit-level: see the [docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#bitwise_operators) when they are needed.
 
 Conditional
 : The only operator with three parameters: `cond ? resultA : resultB`. If `cond` is truthy, returns `resultA`, otherwise `resultB`.
@@ -151,6 +152,9 @@ Conditional
 Logical operators
 : Logical AND `&&` and OR `||` perform short-circuit evaluation and then return the value where it stopped (not necessary `true`/`false`). Logical NOT `!` converts the operand to boolean type and returns the inverse value.
 
+Nullish coalescing operator
+: The `??` operator provides a way to choose a defined value from a list of variables. The result of `a ?? b` is `a` unless it's `null/undefined`, then `b`.
+
 Comparisons
 : Equality check `==` for values of different types converts them to a number (except `null` and `undefined` that equal each other and nothing else), so these are equal:
 
@@ -170,7 +174,7 @@ Comparisons
 Other operators
 : There are few others, like a comma operator.
 
-More in: <info:operators>, <info:comparison>, <info:logical-operators>.
+More in: <info:operators>, <info:comparison>, <info:logical-operators>, <info:nullish-coalescing-operator>.
 
 ## Loops
 
@@ -212,6 +216,7 @@ let age = prompt('Your age?', 18);
 switch (age) {
   case 18:
     alert("Won't work"); // the result of prompt is a string, not a number
+    break;
 
   case "18":
     alert("This works!");
@@ -251,7 +256,7 @@ We covered three ways to create a function in JavaScript:
 3. Arrow functions:
 
     ```js
-    // expression at the right side
+    // expression on the right side
     let sum = (a, b) => a + b;
 
     // or multi-line syntax with { ... }, need return here:
@@ -268,7 +273,7 @@ We covered three ways to create a function in JavaScript:
     ```
 
 
-- Functions may have local variables: those declared inside its body. Such variables are only visible inside the function.
+- Functions may have local variables: those declared inside its body or its parameter list. Such variables are only visible inside the function.
 - Parameters can have default values: `function sum(a = 1, b = 2) {...}`.
 - Functions always return something. If there's no `return` statement, then the result is `undefined`.
 
diff --git a/1-js/02-first-steps/18-while-for/6-repeat-until-correct/solution.md b/1-js/02-first-steps/18-while-for/6-repeat-until-correct/solution.md
index 2e04a78c4..c7de5f09b 100644
--- a/1-js/02-first-steps/18-while-for/6-repeat-until-correct/solution.md
+++ b/1-js/02-first-steps/18-while-for/6-repeat-until-correct/solution.md
@@ -10,6 +10,6 @@ do {
 The loop `do..while` repeats while both checks are truthy:
 
 1. The check for `num <= 100` -- that is, the entered value is still not greater than `100`.
-2. The check `&& num` is false when `num` is `null` or a empty string. Then the `while` loop stops too.
+2. The check `&& num` is false when `num` is `null` or an empty string. Then the `while` loop stops too.
 
 P.S. If `num` is `null` then `num <= 100` is `true`, so without the 2nd check the loop wouldn't stop if the user clicks CANCEL. Both checks are required.
diff --git a/1-js/02-first-steps/18-while-for/article.md b/1-js/02-first-steps/18-while-for/article.md
index 382adadac..d1b749888 100644
--- a/1-js/02-first-steps/18-while-for/article.md
+++ b/1-js/02-first-steps/18-while-for/article.md
@@ -6,6 +6,19 @@ For example, outputting goods from a list one after another or just running the
 
 *Loops* are a way to repeat the same code multiple times.
 
+```smart header="The for..of and for..in loops"
+A small announcement for advanced readers.
+
+This article covers only basic loops: `while`, `do..while` and `for(..;..;..)`.
+
+If you came to this article searching for other types of loops, here are the pointers:
+
+- See [for..in](info:object#forin) to loop over object properties.
+- See [for..of](info:array#loops) and [iterables](info:iterable) for looping over arrays and iterable objects.
+
+Otherwise, please read on.
+```
+
 ## The "while" loop
 
 The `while` loop has the following syntax:
@@ -106,7 +119,7 @@ Let's examine the `for` statement part-by-part:
 
 | part  |          |                                                                            |
 |-------|----------|----------------------------------------------------------------------------|
-| begin | `i = 0`    | Executes once upon entering the loop.                                      |
+| begin | `let i = 0`    | Executes once upon entering the loop.                                      |
 | condition | `i < 3`| Checked before every loop iteration. If false, the loop stops.              |
 | body | `alert(i)`| Runs again and again while the condition is truthy.                         |
 | step| `i++`      | Executes after the body on each iteration. |
@@ -162,10 +175,8 @@ for (i = 0; i < 3; i++) { // use an existing variable
 
 alert(i); // 3, visible, because declared outside of the loop
 ```
-
 ````
 
-
 ### Skipping parts
 
 Any part of `for` can be skipped.
@@ -256,7 +267,7 @@ For even values of `i`, the `continue` directive stops executing the body and pa
 ````smart header="The `continue` directive helps decrease nesting"
 A loop that shows odd values could look like this:
 
-```js
+```js run
 for (let i = 0; i < 10; i++) {
 
   if (i % 2) {
@@ -268,7 +279,7 @@ for (let i = 0; i < 10; i++) {
 
 From a technical point of view, this is identical to the example above. Surely, we can just wrap the code in an `if` block instead of using `continue`.
 
-But as a side-effect, this created one more level of nesting (the `alert` call inside the curly braces). If the code inside of`if` is longer than a few lines, that may decrease the overall readability.
+But as a side effect, this created one more level of nesting (the `alert` call inside the curly braces). If the code inside of `if` is longer than a few lines, that may decrease the overall readability.
 ````
 
 ````warn header="No `break/continue` to the right side of '?'"
@@ -286,7 +297,6 @@ if (i > 5) {
 
 ...and rewrite it using a question mark:
 
-
 ```js no-beautify
 (i > 5) ? alert(i) : *!*continue*/!*; // continue isn't allowed here
 ```
@@ -318,9 +328,10 @@ alert('Done!');
 
 We need a way to stop the process if the user cancels the input.
 
-The ordinary `break` after `input` would only break the inner loop. That's not sufficient--labels, come to the rescue!
+The ordinary `break` after `input` would only break the inner loop. That's not sufficient -- labels, come to the rescue!
 
 A *label* is an identifier with a colon before a loop:
+
 ```js
 labelName: for (...) {
   ...
@@ -342,6 +353,7 @@ The `break <labelName>` statement in the loop below breaks out to the label:
     // do something with the value...
   }
 }
+
 alert('Done!');
 ```
 
@@ -362,13 +374,26 @@ The `continue` directive can also be used with a label. In this case, code execu
 Labels do not allow us to jump into an arbitrary place in the code.
 
 For example, it is impossible to do this:
+
 ```js
-break label; // doesn't jumps to the label below
+break label; // jump to the label below (doesn't work)
 
 label: for (...)
 ```
 
-A call to `break/continue` is only possible from inside a loop and the label must be somewhere above the directive.
+A `break` directive must be inside a code block. Technically, any labelled code block will do, e.g.:
+
+```js
+label: {
+  // ...
+  break label; // works
+  // ...
+}
+```
+
+...Although, 99.9% of the time `break` is used inside loops, as we've seen in the examples above.
+
+A `continue` is only possible from inside a loop.
 ````
 
 ## Summary
diff --git a/1-js/03-code-quality/01-debugging-chrome/article.md b/1-js/03-code-quality/01-debugging-chrome/article.md
index 1b0f4e377..4f50fb428 100644
--- a/1-js/03-code-quality/01-debugging-chrome/article.md
+++ b/1-js/03-code-quality/01-debugging-chrome/article.md
@@ -1,10 +1,10 @@
-# Debugging in Chrome
+# Debugging in the browser
 
 Before writing more complex code, let's talk about debugging.
 
 [Debugging](https://en.wikipedia.org/wiki/Debugging) is the process of finding and fixing errors within a script. All modern browsers and most other environments support debugging tools -- a special UI in developer tools that makes debugging much easier. It also allows to trace the code step by step to see what exactly is going on.
 
-We'll be using Chrome here, because it has enough features, most other browsers have a similar process`.
+We'll be using Chrome here, because it has enough features, most other browsers have a similar process.
 
 ## The "Sources" panel
 
@@ -24,11 +24,11 @@ Let's click it and select `hello.js` in the tree view. Here's what should show u
 
 ![](chrome-tabs.svg)
 
-Here we can see three zones:
+The Sources panel has 3 parts:
 
-1. The **Resources zone** lists HTML, JavaScript, CSS and other files, including images that are attached to the page. Chrome extensions may appear here too.
-2. The **Source zone** shows the source code.
-3. The **Information and control zone** is for debugging, we'll explore it soon.
+1. The **File Navigator** pane lists HTML, JavaScript, CSS and other files, including images that are attached to the page. Chrome extensions may appear here too.
+2. The **Code Editor** pane shows the source code.
+3. The **JavaScript Debugging** pane is for debugging, we'll explore it soon.
 
 Now you could click the same toggler <span class="devtools" style="background-position:-172px -122px"></span> again to hide the resources list and give the code some space.
 
@@ -38,7 +38,7 @@ If we press `key:Esc`, then a console opens below. We can type commands there an
 
 After a statement is executed, its result is shown below.
 
-For example, here `1+2` results in `3`, and `hello("debugger")` returns nothing, so the result is `undefined`:
+For example, here `1+2` results in `3`, while the function call `hello("debugger")` returns nothing, so the result is `undefined`:
 
 ![](chrome-sources-console.svg)
 
@@ -63,12 +63,12 @@ We can always find a list of breakpoints in the right panel. That's useful when
 - ...And so on.
 
 ```smart header="Conditional breakpoints"
-*Right click* on the line number allows to create a *conditional* breakpoint. It only triggers when the given expression is truthy.
+*Right click* on the line number allows to create a *conditional* breakpoint. It only triggers when the given expression, that you should provide when you create it, is truthy.
 
 That's handy when we need to stop only for a certain variable value or for certain function parameters.
 ```
 
-## Debugger command
+## The command "debugger"
 
 We can also pause the code by using the `debugger` command in it, like this:
 
@@ -84,8 +84,7 @@ function hello(name) {
 }
 ```
 
-That's very convenient when we are in a code editor and don't want to switch to the browser and look up the script in developer tools to set the breakpoint.
-
+Such command works only when the development tools are open, otherwise the browser ignores it.
 
 ## Pause and look around
 
@@ -99,7 +98,7 @@ Please open the informational dropdowns to the right (labeled with arrows). They
 
 1. **`Watch` -- shows current values for any expressions.**
 
-    You can click the plus `+` and input an expression. The debugger will show its value at any moment, automatically recalculating it in the process of execution.
+    You can click the plus `+` and input an expression. The debugger will show its value, automatically recalculating it in the process of execution.
 
 2. **`Call Stack` -- shows the nested calls chain.**
 
@@ -135,11 +134,11 @@ There are buttons for it at the top of the right panel. Let's engage them.
     Clicking this again and again will step through all script statements one by one.
 
 <span class="devtools" style="background-position:-62px -192px"></span> -- "Step over": run the next command, but *don't go into a function*, hotkey `key:F10`.
-: Similar to the previous the "Step" command, but behaves differently if the next statement is a function call. That is: not a built-in, like `alert`, but a function of our own.
+: Similar to the previous "Step" command, but behaves differently if the next statement is a function call (not a built-in, like `alert`, but a function of our own).
 
-    The "Step" command goes into it and pauses the execution at its first line, while "Step over" executes the nested function call invisibly, skipping the function internals.
+    If we compare them, the "Step" command goes into a nested function call and pauses the execution at its first line, while "Step over" executes the nested function call invisibly to us, skipping the function internals.
 
-    The execution is then paused immediately after that function.
+    The execution is then paused immediately after that function call.
 
     That's good if we're not interested to see what happens inside the function call.
 
@@ -155,7 +154,7 @@ There are buttons for it at the top of the right panel. Let's engage them.
 : That button does not move the execution. Just a mass on/off for breakpoints.
 
 <span class="devtools" style="background-position:-90px -146px"></span> -- enable/disable automatic pause in case of an error.
-: When enabled, and the developer tools is open, a script error automatically pauses the execution. Then we can analyze variables to see what went wrong. So if our script dies with an error, we can open debugger, enable this option and reload the page to see where it dies and what's the context at that moment.
+: When enabled, if the developer tools is open, an error during the script execution automatically pauses it. Then we can analyze variables in the debugger to see what went wrong. So if our script dies with an error, we can open debugger, enable this option and reload the page to see where it dies and what's the context at that moment.
 
 ```smart header="Continue to here"
 Right click on a line of code opens the context menu with a great option called "Continue to here".
@@ -187,7 +186,7 @@ As we can see, there are three main ways to pause a script:
 2. The `debugger` statements.
 3. An error (if dev tools are open and the button <span class="devtools" style="background-position:-90px -146px"></span> is "on").
 
-When paused, we can debug - examine variables and trace the code to see where the execution goes wrong.
+When paused, we can debug: examine variables and trace the code to see where the execution goes wrong.
 
 There are many more options in developer tools than covered here. The full manual is at <https://developers.google.com/web/tools/chrome-devtools>.
 
diff --git a/1-js/03-code-quality/02-coding-style/1-style-errors/solution.md b/1-js/03-code-quality/02-coding-style/1-style-errors/solution.md
index 764e36c63..4facc8b29 100644
--- a/1-js/03-code-quality/02-coding-style/1-style-errors/solution.md
+++ b/1-js/03-code-quality/02-coding-style/1-style-errors/solution.md
@@ -12,7 +12,7 @@ function pow(x,n)  // <- no space between arguments
 
 let x=prompt("x?",''), n=prompt("n?",'') // <-- technically possible,
 // but better make it 2 lines, also there's no spaces and missing ;
-if (n<0)  // <- no spaces inside (n < 0), and should be extra line above it
+if (n<=0)  // <- no spaces inside (n <= 0), and should be extra line above it
 {   // <- figure bracket on a separate line
   // below - long lines can be split into multiple lines for improved readability
   alert(`Power ${n} is not supported, please enter an integer number greater than zero`);
@@ -39,7 +39,7 @@ function pow(x, n) {
 let x = prompt("x?", "");
 let n = prompt("n?", "");
 
-if (n < 0) {
+if (n <= 0) {
   alert(`Power ${n} is not supported,
     please enter an integer number greater than zero`);
 } else {
diff --git a/1-js/03-code-quality/02-coding-style/article.md b/1-js/03-code-quality/02-coding-style/article.md
index bdcfec545..904f0a939 100644
--- a/1-js/03-code-quality/02-coding-style/article.md
+++ b/1-js/03-code-quality/02-coding-style/article.md
@@ -86,7 +86,7 @@ For example:
 ```js
 // backtick quotes ` allow to split the string into multiple lines
 let str = `
-  Ecma International's TC39 is a group of JavaScript developers,
+  ECMA International's TC39 is a group of JavaScript developers,
   implementers, academics, and more, collaborating with the community
   to maintain and evolve the definition of JavaScript.
 `;
@@ -116,7 +116,7 @@ There are two types of indents:
 
     One advantage of spaces over tabs is that spaces allow more flexible configurations of indents than the tab symbol.
 
-    For instance, we can align the arguments with the opening bracket, like this:
+    For instance, we can align the parameters with the opening bracket, like this:
 
     ```js no-beautify
     show(parameters,
@@ -285,7 +285,7 @@ Of course, a team can always write their own style guide, but usually there's no
 
 Some popular choices:
 
-- [Google JavaScript Style Guide](https://google.github.io/styleguide/javascriptguide.xml)
+- [Google JavaScript Style Guide](https://google.github.io/styleguide/jsguide.html)
 - [Airbnb JavaScript Style Guide](https://github.com/airbnb/javascript)
 - [Idiomatic.JS](https://github.com/rwaldron/idiomatic.js)
 - [StandardJS](https://standardjs.com/)
@@ -301,11 +301,11 @@ The great thing about them is that style-checking can also find some bugs, like
 
 Here are some well-known linting tools:
 
-- [JSLint](http://www.jslint.com/) -- one of the first linters.
-- [JSHint](http://www.jshint.com/) -- more settings than JSLint.
-- [ESLint](http://eslint.org/) -- probably the newest one.
+- [JSLint](https://www.jslint.com/) -- one of the first linters.
+- [JSHint](https://jshint.com/) -- more settings than JSLint.
+- [ESLint](https://eslint.org/) -- probably the newest one.
 
-All of them can do the job. The author uses [ESLint](http://eslint.org/).
+All of them can do the job. The author uses [ESLint](https://eslint.org/).
 
 Most linters are integrated with many popular editors: just enable the plugin in the editor and configure the style.
 
@@ -328,14 +328,14 @@ Here's an example of an `.eslintrc` file:
   },
   "rules": {
     "no-console": 0,
-    "indent": ["warning", 2]
+    "indent": 2
   }
 }
 ```
 
 Here the directive `"extends"` denotes that the configuration is based on the "eslint:recommended" set of settings. After that, we specify our own.
 
-It is also possible to download style rule sets from the web and extend them instead. See <http://eslint.org/docs/user-guide/getting-started> for more details about installation.
+It is also possible to download style rule sets from the web and extend them instead. See <https://eslint.org/docs/user-guide/getting-started> for more details about installation.
 
 Also certain IDEs have built-in linting, which is convenient but not as customizable as ESLint.
 
diff --git a/1-js/03-code-quality/03-comments/article.md b/1-js/03-code-quality/03-comments/article.md
index 381a74dcb..8276b7703 100644
--- a/1-js/03-code-quality/03-comments/article.md
+++ b/1-js/03-code-quality/03-comments/article.md
@@ -122,6 +122,7 @@ Udokumentuj parametry oraz użycie funkcji
 
     Na przykład:
 
+<<<<<<< HEAD
     ```js
     /**
       * Zwraca x podniesiony do n-tej potęgi.
@@ -140,6 +141,27 @@ Udokumentuj parametry oraz użycie funkcji
     Tak na marginesie, wiele edytorów, takich jak [WebStorm](https://www.jetbrains.com/webstorm/), jest w stanie dobrze je zrozumieć oraz używać ich do automatycznego uzupełniania i sprawdzania kodu.
 
     Istnieją również takie narzędzia jak [JSDoc 3](https://github.com/jsdoc3/jsdoc), które są w stanie generować dokumentację HTML z tych komentarzy. Możesz dowiedzieć się więcej na ten temat pod tym linkiem: <http://usejsdoc.org/>.
+=======
+For instance:
+```js
+/**
+ * Returns x raised to the n-th power.
+ *
+ * @param {number} x The number to raise.
+ * @param {number} n The power, must be a natural number.
+ * @return {number} x raised to the n-th power.
+ */
+function pow(x, n) {
+  ...
+}
+```
+
+Such comments allow us to understand the purpose of the function and use it the right way without looking in its code.
+
+By the way, many editors like [WebStorm](https://www.jetbrains.com/webstorm/) can understand them as well and use them to provide autocomplete and some automatic code-checking.
+
+Also, there are tools like [JSDoc 3](https://github.com/jsdoc/jsdoc) that can generate HTML-documentation from the comments. You can read more information about JSDoc at <https://jsdoc.app>.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 Dlaczego zadanie jest rozwiązane w taki sposób?
 : Co zostało napisane jest ważne. Jednakże to, czego _nie_ napisano, może być jeszcze ważniejsze w zrozumieniu, o co chodzi w kodzie. Dlaczego zadanie zostało rozwiązane dokładnie w taki sposób? Kod nie odpowie na to pytanie.
diff --git a/1-js/03-code-quality/04-ninja-code/article.md b/1-js/03-code-quality/04-ninja-code/article.md
index 6eda885df..105052352 100644
--- a/1-js/03-code-quality/04-ninja-code/article.md
+++ b/1-js/03-code-quality/04-ninja-code/article.md
@@ -1,8 +1,13 @@
 # Kod ninja
 
 
+<<<<<<< HEAD
 ```quote author="Konfucjusz"
 Bezużyteczną rzeczą jest uczyć się, lecz nie myśleć, a niebezpieczną myśleć, lecz nie uczyć się niczego.
+=======
+```quote author="Confucius (Analects)"
+Learning without thought is labor lost; thought without learning is perilous.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 ```
 
 Programiści ninja z przeszłości używali poniższych trików, by zmusić do myślenia umysły deweloperów.
@@ -42,7 +47,11 @@ Powiedz mu, że krótszy znaczy lepszy. Wprowadź go na ścieżkę ninja.
 Tao kryje się w milczeniu. Tylko Tao dobrze się zaczyna i dobrze kończy.
 ```
 
+<<<<<<< HEAD
 Kolejnym sposobem na szybsze programowanie jest używanie wszędzie jednoliterowych nazw zmiennych. Takich jak `a`, `b` czy `c`.
+=======
+Another way to code shorter is to use single-letter variable names everywhere. Like `a`, `b` or `c`.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 Zmienna o krótkiej nazwie znika w kodzie jak prawdziwy ninja w dżungli. Nikt nie będzie w stanie znaleźć jej przy pomocy wyszukiwarki edytora. A nawet jeśli komuś się to uda, nie będzie w stanie domyślić się, co oznacza `a` czy `b`.
 
@@ -103,8 +112,13 @@ Nie ma opcji, żeby ktoś był w stanie na szybko przejrzeć taki kod. A gdy jes
 
 ## Sprytne synonimy
 
+<<<<<<< HEAD
 ```quote author="Konfucjusz"
 Ciężko jest znaleźć czarnego kota w ciemnym pokoju, szczególnie jeżeli go tam nie ma.
+=======
+```quote author="Laozi (Tao Te Ching)"
+The Tao that can be told is not the eternal Tao. The name that can be named is not the eternal name.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 ```
 
 Używanie *podobnych* nazw do *tych samych* rzeczy ubarwia nieco życie i pokazuje publice twoją kreatywność.
diff --git a/1-js/03-code-quality/05-testing-mocha/article.md b/1-js/03-code-quality/05-testing-mocha/article.md
index 68ffcae4d..4c2b1aa5e 100644
--- a/1-js/03-code-quality/05-testing-mocha/article.md
+++ b/1-js/03-code-quality/05-testing-mocha/article.md
@@ -2,7 +2,7 @@
 
 Automated testing will be used in further tasks, and it's also widely used in real projects.
 
-## Why we need tests?
+## Why do we need tests?
 
 When we write a function, we can usually imagine what it should do: which parameters give which results.
 
@@ -51,7 +51,7 @@ describe("pow", function() {
 A spec has three main building blocks that you can see above:
 
 `describe("title", function() { ... })`
-: What functionality we're describing. In our case we're describing the function `pow`. Used to group "workers" -- the `it` blocks.
+: What functionality we're describing? In our case we're describing the function `pow`. Used to group "workers" -- the `it` blocks.
 
 `it("use case description", function() { ... })`
 : In the title of `it` we *in a human-readable way* describe the particular use case, and the second argument is a function that tests it.
@@ -69,7 +69,7 @@ The flow of development usually looks like this:
 
 1. An initial spec is written, with tests for the most basic functionality.
 2. An initial implementation is created.
-3. To check whether it works, we run the testing framework [Mocha](http://mochajs.org/) (more details soon) that runs the spec. While the functionality is not complete, errors are displayed. We make corrections until everything works.
+3. To check whether it works, we run the testing framework [Mocha](https://mochajs.org/) (more details soon) that runs the spec. While the functionality is not complete, errors are displayed. We make corrections until everything works.
 4. Now we have a working initial implementation with tests.
 5. We add more use cases to the spec, probably not yet supported by the implementations. Tests start to fail.
 6. Go to 3, update the implementation till tests give no errors.
@@ -79,15 +79,15 @@ So, the development is *iterative*. We write the spec, implement it, make sure t
 
 Let's see this development flow in our practical case.
 
-The first step is already complete: we have an initial spec for `pow`. Now, before making the implementation, let's use few JavaScript libraries to run the tests, just to see that they are working (they will all fail).
+The first step is already complete: we have an initial spec for `pow`. Now, before making the implementation, let's use a few JavaScript libraries to run the tests, just to see that they are working (they will all fail).
 
 ## The spec in action
 
 Here in the tutorial we'll be using the following JavaScript libraries for tests:
 
-- [Mocha](http://mochajs.org/) -- the core framework: it provides common testing functions including `describe` and `it` and the main function that runs tests.
-- [Chai](http://chaijs.com) -- the library with many assertions. It allows to use a lot of different assertions, for now we need only `assert.equal`.
-- [Sinon](http://sinonjs.org/) -- a library to spy over functions, emulate built-in functions and more, we'll need it much later.
+- [Mocha](https://mochajs.org/) -- the core framework: it provides common testing functions including `describe` and `it` and the main function that runs tests.
+- [Chai](https://www.chaijs.com/) -- the library with many assertions. It allows to use a lot of different assertions, for now we need only `assert.equal`.
+- [Sinon](https://sinonjs.org/) -- a library to spy over functions, emulate built-in functions and more, we'll need it much later.
 
 These libraries are suitable for both in-browser and server-side testing. Here we'll consider the browser variant.
 
@@ -338,14 +338,14 @@ The newly added tests fail, because our implementation does not support them. Th
 ```smart header="Other assertions"
 Please note the assertion `assert.isNaN`: it checks for `NaN`.
 
-There are other assertions in [Chai](http://chaijs.com) as well, for instance:
+There are other assertions in [Chai](https://www.chaijs.com/) as well, for instance:
 
 - `assert.equal(value1, value2)` -- checks the equality  `value1 == value2`.
 - `assert.strictEqual(value1, value2)` -- checks the strict equality `value1 === value2`.
 - `assert.notEqual`, `assert.notStrictEqual` -- inverse checks to the ones above.
 - `assert.isTrue(value)` -- checks that `value === true`
 - `assert.isFalse(value)` -- checks that `value === false`
-- ...the full list is in the [docs](http://chaijs.com/api/assert/)
+- ...the full list is in the [docs](https://www.chaijs.com/api/assert/)
 ```
 
 So we should add a couple of lines to `pow`:
diff --git a/1-js/03-code-quality/05-testing-mocha/beforeafter.view/test.js b/1-js/03-code-quality/05-testing-mocha/beforeafter.view/test.js
index cad51d3ee..d3de82546 100644
--- a/1-js/03-code-quality/05-testing-mocha/beforeafter.view/test.js
+++ b/1-js/03-code-quality/05-testing-mocha/beforeafter.view/test.js
@@ -1,5 +1,11 @@
 describe("test", function() {
+  
+   // Mocha usually waits for the tests for 2 seconds before considering them wrong
+  
+  this.timeout(200000); // With this code we increase this - in this case to 200,000 milliseconds
 
+  // This is because of the "alert" function, because if you delay pressing the "OK" button the tests will not pass!
+  
   before(() => alert("Testing started – before all tests"));
   after(() => alert("Testing finished – after all tests"));
 
diff --git a/1-js/03-code-quality/06-polyfills/article.md b/1-js/03-code-quality/06-polyfills/article.md
index 75db49d2f..19404b7b5 100644
--- a/1-js/03-code-quality/06-polyfills/article.md
+++ b/1-js/03-code-quality/06-polyfills/article.md
@@ -1,54 +1,91 @@
 
-# Polyfills
+# Polyfills and transpilers
 
-The JavaScript language steadily evolves. New proposals to the language appear regularly, they are analyzed and, if considered worthy, are appended to the list at <https://tc39.github.io/ecma262/> and then progress to the [specification](http://www.ecma-international.org/publications/standards/Ecma-262.htm).
+The JavaScript language steadily evolves. New proposals to the language appear regularly, they are analyzed and, if considered worthy, are appended to the list at <https://tc39.github.io/ecma262/> and then progress to the [specification](https://www.ecma-international.org/publications-and-standards/standards/ecma-262/).
 
 Teams behind JavaScript engines have their own ideas about what to implement first. They may decide to implement proposals that are in draft and postpone things that are already in the spec, because they are less interesting or just harder to do.
 
-So it's quite common for an engine to implement only the part of the standard.
+So it's quite common for an engine to implement only part of the standard.
 
-A good page to see the current state of support for language features is <https://kangax.github.io/compat-table/es6/> (it's big, we have a lot to study yet).
+A good page to see the current state of support for language features is <https://compat-table.github.io/compat-table/es6/> (it's big, we have a lot to study yet).
 
-## Babel
+As programmers, we'd like to use most recent features. The more good stuff - the better!
 
-When we use modern features of the language, some engines may fail to support such code. Just as said, not all features are implemented everywhere.
+On the other hand, how to make our modern code work on older engines that don't understand recent features yet?
 
-Here Babel comes to the rescue.
+There are two tools for that:
 
-[Babel](https://babeljs.io) is a [transpiler](https://en.wikipedia.org/wiki/Source-to-source_compiler). It rewrites modern JavaScript code into the previous standard.
+1. Transpilers.
+2. Polyfills.
 
-Actually, there are two parts in Babel:
+Here, in this chapter, our purpose is to get the gist of how they work, and their place in web development.
 
-1. First, the transpiler program, which rewrites the code. The developer runs it on their own computer. It rewrites the code into the older standard. And then the code is delivered to the website for users. Modern project build systems like [webpack](http://webpack.github.io/) provide means to run transpiler automatically on every code change, so that it's very easy to integrate into development process.
+## Transpilers
 
-2. Second, the polyfill.
+A [transpiler](https://en.wikipedia.org/wiki/Source-to-source_compiler) is a special piece of software that translates source code to another source code. It can parse ("read and understand") modern code and rewrite it using older syntax constructs, so that it'll also work in outdated engines.
 
-    New language features may include new built-in functions and syntax constructs.
-    The transpiler rewrites the code, transforming syntax constructs into older ones. But as for new built-in functions, we need to implement them. JavaScript is a highly dynamic language, scripts may add/modify any functions, so that they behave according to the modern standard.
+E.g. JavaScript before year 2020 didn't have the "nullish coalescing operator" `??`. So, if a visitor uses an outdated browser, it may fail to understand the code like `height = height ?? 100`.
 
-    A script that updates/adds new functions is called "polyfill". It "fills in" the gap and adds missing implementations.
+A transpiler would analyze our code and rewrite `height ?? 100` into `(height !== undefined && height !== null) ? height : 100`.
 
-    Two interesting polyfills are:
-    - [core js](https://github.com/zloirock/core-js) that supports a lot, allows to include only needed features.
-    - [polyfill.io](http://polyfill.io) service that provides a script with polyfills, depending on the features and user's browser.
+```js
+// before running the transpiler
+height = height ?? 100;
 
-So, if we're going to use modern language features, a transpiler and a polyfill are necessary.
+// after running the transpiler
+height = (height !== undefined && height !== null) ? height : 100;
+```
 
-## Examples in the tutorial
+Now the rewritten code is suitable for older JavaScript engines.
 
+Usually, a developer runs the transpiler on their own computer, and then deploys the transpiled code to the server.
 
-````online
-Most examples are runnable at-place, like this:
+Speaking of names, [Babel](https://babeljs.io) is one of the most prominent transpilers out there.
 
-```js run
-alert('Press the "Play" button in the upper-right corner to run');
-```
+Modern project build systems, such as [webpack](https://webpack.js.org/), provide a means to run a transpiler automatically on every code change, so it's very easy to integrate into the development process.
+
+## Polyfills
+
+New language features may include not only syntax constructs and operators, but also built-in functions.
+
+For example, `Math.trunc(n)` is a function that "cuts off" the decimal part of a number, e.g `Math.trunc(1.23)` returns `1`.
 
-Examples that use modern JS will work only if your browser supports it.
-````
+In some (very outdated) JavaScript engines, there's no `Math.trunc`, so such code will fail.
 
-```offline
-As you're reading the offline version, in PDF examples are not runnable. In EPUB some of them can run.
+As we're talking about new functions, not syntax changes, there's no need to transpile anything here. We just need to declare the missing function.
+
+A script that updates/adds new functions is called "polyfill". It "fills in" the gap and adds missing implementations.
+
+For this particular case, the polyfill for `Math.trunc` is a script that implements it, like this:
+
+```js
+if (!Math.trunc) { // if no such function
+  // implement it
+  Math.trunc = function(number) {
+    // Math.ceil and Math.floor exist even in ancient JavaScript engines
+    // they are covered later in the tutorial
+    return number < 0 ? Math.ceil(number) : Math.floor(number);
+  };
+}
 ```
 
-Google Chrome is usually the most up-to-date with language features, good to run bleeding-edge demos without any transpilers, but other modern browsers also work fine.
+JavaScript is a highly dynamic language. Scripts may add/modify any function, even built-in ones.
+
+Two interesting polyfill libraries are:
+- [core js](https://github.com/zloirock/core-js) that supports a lot, allows to include only needed features.
+
+
+## Summary
+
+In this chapter we'd like to motivate you to study modern and even "bleeding-edge" language features, even if they aren't yet well-supported by JavaScript engines.
+
+Just don't forget to use a transpiler (if using modern syntax or operators) and polyfills (to add functions that may be missing). They'll ensure that the code works.
+
+For example, later when you're familiar with JavaScript, you can setup a code build system based on [webpack](https://webpack.js.org/) with the [babel-loader](https://github.com/babel/babel-loader) plugin.
+
+Good resources that show the current state of support for various features:
+- <https://compat-table.github.io/compat-table/es6/> - for pure JavaScript.
+- <https://caniuse.com/> - for browser-related functions.
+
+P.S. Google Chrome is usually the most up-to-date with language features, try it if a tutorial demo fails. Most tutorial demos work with any modern browser though.
+
diff --git a/1-js/04-object-basics/01-object/4-const-object/solution.md b/1-js/04-object-basics/01-object/4-const-object/solution.md
deleted file mode 100644
index f73c2f92b..000000000
--- a/1-js/04-object-basics/01-object/4-const-object/solution.md
+++ /dev/null
@@ -1,19 +0,0 @@
-Sure, it works, no problem.
-
-The `const` only protects the variable itself from changing. 
-
-In other words, `user` stores a reference to the object. And it can't be changed. But the content of the object can.
-
-```js run
-const user = {
-  name: "John"
-};
-
-*!*
-// works
-user.name = "Pete";
-*/!*
-
-// error
-user = 123;
-```
diff --git a/1-js/04-object-basics/01-object/4-const-object/task.md b/1-js/04-object-basics/01-object/4-const-object/task.md
deleted file mode 100644
index a9aada631..000000000
--- a/1-js/04-object-basics/01-object/4-const-object/task.md
+++ /dev/null
@@ -1,18 +0,0 @@
-importance: 5
-
----
-
-# Constant objects?
-
-Is it possible to change an object declared with `const`? What do you think?
-
-```js
-const user = {
-  name: "John"
-};
-
-*!*
-// does it work?
-user.name = "Pete";
-*/!*
-```
diff --git a/1-js/04-object-basics/01-object/8-multiply-numeric/task.md b/1-js/04-object-basics/01-object/8-multiply-numeric/task.md
index 33eb89220..6878ca088 100644
--- a/1-js/04-object-basics/01-object/8-multiply-numeric/task.md
+++ b/1-js/04-object-basics/01-object/8-multiply-numeric/task.md
@@ -2,9 +2,9 @@ importance: 3
 
 ---
 
-# Multiply numeric properties by 2
+# Multiply numeric property values by 2
 
-Create a function `multiplyNumeric(obj)` that multiplies all numeric properties of `obj` by `2`.
+Create a function `multiplyNumeric(obj)` that multiplies all numeric property values of `obj` by `2`.
 
 For instance:
 
diff --git a/1-js/04-object-basics/01-object/article.md b/1-js/04-object-basics/01-object/article.md
index ea015e7ca..0fe5979fa 100644
--- a/1-js/04-object-basics/01-object/article.md
+++ b/1-js/04-object-basics/01-object/article.md
@@ -1,7 +1,7 @@
 
 # Objects
 
-As we know from the chapter <info:types>, there are seven data types in JavaScript. Six of them are called "primitive", because their values contain only a single thing (be it a string or a number or whatever).
+As we know from the chapter <info:types>, there are eight data types in JavaScript. Seven of them are called "primitive", because their values contain only a single thing (be it a string or a number or whatever).
 
 In contrast, objects are used to store keyed collections of various data and more complex entities. In JavaScript, objects penetrate almost every aspect of the language. So we must understand them first before going in-depth anywhere else.
 
@@ -44,7 +44,7 @@ The resulting `user` object can be imagined as a cabinet with two signed files l
 
 ![user object](object-user.svg)
 
-We can add, remove and read files from it any time.
+We can add, remove and read files from it at any time.
 
 Property values are accessible using the dot notation:
 
@@ -62,7 +62,7 @@ user.isAdmin = true;
 
 ![user object 2](object-user-isadmin.svg)
 
-To remove a property, we can use `delete` operator:
+To remove a property, we can use the `delete` operator:
 
 ```js
 delete user.age;
@@ -101,7 +101,9 @@ For multiword properties, the dot access doesn't work:
 user.likes birds = true
 ```
 
-That's because the dot requires the key to be a valid variable identifier. That is: no spaces and other limitations.
+JavaScript doesn't understand that. It thinks that we address `user.likes`, and then gives a syntax error when comes across unexpected `birds`.
+
+The dot requires the key to be a valid variable identifier. That implies: contains no spaces, doesn't start with a digit and doesn't include special characters (`$` and `_` are allowed).
 
 There's an alternative "square bracket notation" that works with any string:
 
@@ -159,7 +161,7 @@ alert( user.key ) // undefined
 
 ### Computed properties
 
-We can use square brackets in an object literal. That's called *computed properties*.
+We can use square brackets in an object literal, when creating an object. That's called *computed properties*.
 
 For instance:
 
@@ -199,50 +201,13 @@ let bag = {
 };
 ```
 
-Square brackets are much more powerful than the dot notation. They allow any property names and variables. But they are also more cumbersome to write.
+Square brackets are much more powerful than dot notation. They allow any property names and variables. But they are also more cumbersome to write.
 
 So most of the time, when property names are known and simple, the dot is used. And if we need something more complex, then we switch to square brackets.
 
-
-
-````smart header="Reserved words are allowed as property names"
-A variable cannot have a name equal to one of language-reserved words like "for", "let", "return" etc.
-
-But for an object property, there's no such restriction. Any name is fine:
-
-```js run
-let obj = {
-  for: 1,
-  let: 2,
-  return: 3
-};
-
-alert( obj.for + obj.let + obj.return );  // 6
-```
-
-Basically, any name is allowed, but there's a special one: `"__proto__"` that gets special treatment for historical reasons. For instance, we can't set it to a non-object value:
-
-```js run
-let obj = {};
-obj.__proto__ = 5;
-alert(obj.__proto__); // [object Object], didn't work as intended
-```
-
-As we see from the code, the assignment to a primitive `5` is ignored.
-
-That can become a source of bugs and even vulnerabilities if we intend to store arbitrary key-value pairs in an object, and allow a visitor to specify the keys.
-
-In that case the visitor may choose `__proto__` as the key, and the assignment logic will be ruined (as shown above).
-
-There is a way to make objects treat `__proto__` as a regular property, which we'll cover later, but first we need to know more about objects.
-
-There's also another data structure [Map](info:map-set), that we'll learn in the chapter <info:map-set>, which supports arbitrary keys.
-````
-
-
 ## Property value shorthand
 
-In real code we often use existing variables as values for property names.
+In real code, we often use existing variables as values for property names.
 
 For instance:
 
@@ -250,7 +215,7 @@ For instance:
 function makeUser(name, age) {
   return {
     name: name,
-    age: age
+    age: age,
     // ...other properties
   };
 }
@@ -268,7 +233,7 @@ function makeUser(name, age) {
 *!*
   return {
     name, // same as name: name
-    age   // same as age: age
+    age,  // same as age: age
     // ...
   };
 */!*
@@ -284,9 +249,57 @@ let user = {
 };
 ```
 
-## Existence check
 
-A notable objects feature is that it's possible to access any property. There will be no error if the property doesn't exist! Accessing a non-existing property just returns `undefined`. It provides a very common way to test whether the property exists -- to get it and compare vs undefined:
+## Property names limitations
+
+As we already know, a variable cannot have a name equal to one of the language-reserved words like "for", "let", "return" etc.
+
+But for an object property, there's no such restriction:
+
+```js run
+// these properties are all right
+let obj = {
+  for: 1,
+  let: 2,
+  return: 3
+};
+
+alert( obj.for + obj.let + obj.return );  // 6
+```
+
+In short, there are no limitations on property names. They can be any strings or symbols (a special type for identifiers, to be covered later).
+
+Other types are automatically converted to strings.
+
+For instance, a number `0` becomes a string `"0"` when used as a property key:
+
+```js run
+let obj = {
+  0: "test" // same as "0": "test"
+};
+
+// both alerts access the same property (the number 0 is converted to string "0")
+alert( obj["0"] ); // test
+alert( obj[0] ); // test (same property)
+```
+
+There's a minor gotcha with a special property named `__proto__`. We can't set it to a non-object value:
+
+```js run
+let obj = {};
+obj.__proto__ = 5; // assign a number
+alert(obj.__proto__); // [object Object] - the value is an object, didn't work as intended
+```
+
+As we see from the code, the assignment to a primitive `5` is ignored.
+
+We'll cover the special nature of `__proto__` in [subsequent chapters](info:prototype-inheritance), and suggest the [ways to fix](info:prototype-methods) such behavior.
+
+## Property existence test, "in" operator
+
+A notable feature of objects in JavaScript, compared to many other languages, is that it's possible to access any property. There will be no error if the property doesn't exist!
+
+Reading a non-existing property just returns `undefined`. So we can easily test whether the property exists:
 
 ```js run
 let user = {};
@@ -294,7 +307,7 @@ let user = {};
 alert( user.noSuchProperty === undefined ); // true means "no such property"
 ```
 
-There also exists a special operator `"in"` to check for the existence of a property.
+There's also a special operator `"in"` for that.
 
 The syntax is:
 ```js
@@ -312,17 +325,18 @@ alert( "blabla" in user ); // false, user.blabla doesn't exist
 
 Please note that on the left side of `in` there must be a *property name*. That's usually a quoted string.
 
-If we omit quotes, that would mean a variable containing the actual name will be tested. For instance:
+If we omit quotes, that means a variable should contain the actual name to be tested. For instance:
 
 ```js run
 let user = { age: 30 };
 
 let key = "age";
-alert( *!*key*/!* in user ); // true, takes the name from key and checks for such property
+alert( *!*key*/!* in user ); // true, property "age" exists
 ```
 
-````smart header="Using \"in\" for properties that store `undefined`"
-Usually, the strict comparison `"=== undefined"` check the property existance just fine. But there's a special case when it fails, but `"in"` works correctly.
+Why does the `in` operator exist? Isn't it enough to compare against `undefined`?
+
+Well, most of the time the comparison with `undefined` works fine. But there's a special case when it fails, but `"in"` works correctly.
 
 It's when an object property exists, but stores `undefined`:
 
@@ -336,13 +350,12 @@ alert( obj.test ); // it's undefined, so - no such property?
 alert( "test" in obj ); // true, the property does exist!
 ```
 
-
 In the code above, the property `obj.test` technically exists. So the `in` operator works right.
 
-Situations like this happen very rarely, because `undefined` is usually not assigned. We mostly use `null` for "unknown" or "empty" values. So the `in` operator is an exotic guest in the code.
-````
+Situations like this happen very rarely, because `undefined` should not be explicitly assigned. We mostly use `null` for "unknown" or "empty" values. So the `in` operator is an exotic guest in the code.
 
-## The "for..in" loop
+
+## The "for..in" loop [#forin]
 
 To walk over all keys of an object, there exists a special form of the loop: `for..in`. This is a completely different thing from the `for(;;)` construct that we studied before.
 
@@ -375,7 +388,6 @@ Note that all "for" constructs allow us to declare the looping variable inside t
 
 Also, we could use another variable name here instead of `key`. For instance, `"for (let prop in obj)"` is also widely used.
 
-
 ### Ordered like an object
 
 Are objects ordered? In other words, if we loop over an object, do we get all properties in the same order they were added? Can we rely on this?
@@ -400,7 +412,7 @@ for (let code in codes) {
 */!*
 ```
 
-The object may be used to suggest a list of options to the user. If we're making a site mainly for German audience then we probably want `49` to be the first.
+The object may be used to suggest a list of options to the user. If we're making a site mainly for a German audience then we probably want `49` to be the first.
 
 But if we run the code, we see a totally different picture:
 
@@ -412,9 +424,10 @@ The phone codes go in the ascending sorted order, because they are integers. So
 ````smart header="Integer properties? What's that?"
 The "integer property" term here means a string that can be converted to-and-from an integer without a change.
 
-So, "49" is an integer property name, because when it's transformed to an integer number and back, it's still the same. But "+49" and "1.2" are not:
+So, `"49"` is an integer property name, because when it's transformed to an integer number and back, it's still the same. But `"+49"` and `"1.2"` are not:
 
 ```js run
+// Number(...) explicitly converts to a number
 // Math.trunc is a built-in function that removes the decimal part
 alert( String(Math.trunc(Number("49"))) ); // "49", same, integer property
 alert( String(Math.trunc(Number("+49"))) ); // "49", not same "+49" ⇒ not integer property
@@ -459,262 +472,6 @@ for (let code in codes) {
 
 Now it works as intended.
 
-## Copying by reference
-
-One of the fundamental differences of objects vs primitives is that they are stored and copied "by reference".
-
-Primitive values: strings, numbers, booleans -- are assigned/copied "as a whole value".
-
-For instance:
-
-```js
-let message = "Hello!";
-let phrase = message;
-```
-
-As a result we have two independent variables, each one is storing the string `"Hello!"`.
-
-![](variable-copy-value.svg)
-
-Objects are not like that.
-
-**A variable stores not the object itself, but its "address in memory", in other words "a reference" to it.**
-
-Here's the picture for the object:
-
-```js
-let user = {
-  name: "John"
-};
-```
-
-![](variable-contains-reference.svg)
-
-Here, the object is stored somewhere in memory. And the variable `user` has a "reference" to it.
-
-**When an object variable is copied -- the reference is copied, the object is not duplicated.**
-
-If we imagine an object as a cabinet, then a variable is a key to it. Copying a variable duplicates the key, but not the cabinet itself.
-
-For instance:
-
-```js no-beautify
-let user = { name: "John" };
-
-let admin = user; // copy the reference
-```
-
-Now we have two variables, each one with the reference to the same object:
-
-![](variable-copy-reference.svg)
-
-We can use any variable to access the cabinet and modify its contents:
-
-```js run
-let user = { name: 'John' };
-
-let admin = user;
-
-*!*
-admin.name = 'Pete'; // changed by the "admin" reference
-*/!*
-
-alert(*!*user.name*/!*); // 'Pete', changes are seen from the "user" reference
-```
-
-The example above demonstrates that there is only one object. As if we had a cabinet with two keys and used one of them (`admin`) to get into it. Then, if we later use the other key (`user`) we would see changes.
-
-### Comparison by reference
-
-The equality `==` and strict equality `===` operators for objects work exactly the same.
-
-**Two objects are equal only if they are the same object.**
-
-For instance, if two variables reference the same object, they are equal:
-
-```js run
-let a = {};
-let b = a; // copy the reference
-
-alert( a == b ); // true, both variables reference the same object
-alert( a === b ); // true
-```
-
-And here two independent objects are not equal, even though both are empty:
-
-```js run
-let a = {};
-let b = {}; // two independent objects
-
-alert( a == b ); // false
-```
-
-For comparisons like `obj1 > obj2` or for a comparison against a primitive `obj == 5`, objects are converted to primitives. We'll study how object conversions work very soon, but to tell the truth, such comparisons are necessary very rarely and usually are a result of a coding mistake.
-
-### Const object
-
-An object declared as `const` *can* be changed.
-
-For instance:
-
-```js run
-const user = {
-  name: "John"
-};
-
-*!*
-user.age = 25; // (*)
-*/!*
-
-alert(user.age); // 25
-```
-
-It might seem that the line `(*)` would cause an error, but no, there's totally no problem. That's because `const` fixes only value of `user` itself. And here `user` stores the reference to the same object all the time. The line `(*)` goes *inside* the object, it doesn't reassign `user`.
-
-The `const` would give an error if we try to set `user` to something else, for instance:
-
-```js run
-const user = {
-  name: "John"
-};
-
-*!*
-// Error (can't reassign user)
-*/!*
-user = {
-  name: "Pete"
-};
-```
-
-...But what if we want to make constant object properties? So that `user.age = 25` would give an error. That's possible too. We'll cover it in the chapter <info:property-descriptors>.
-
-## Cloning and merging, Object.assign
-
-So, copying an object variable creates one more reference to the same object.
-
-But what if we need to duplicate an object? Create an independent copy, a clone?
-
-That's also doable, but a little bit more difficult, because there's no built-in method for that in JavaScript. Actually, that's rarely needed. Copying by reference is good most of the time.
-
-But if we really want that, then we need to create a new object and replicate the structure of the existing one by iterating over its properties and copying them on the primitive level.
-
-Like this:
-
-```js run
-let user = {
-  name: "John",
-  age: 30
-};
-
-*!*
-let clone = {}; // the new empty object
-
-// let's copy all user properties into it
-for (let key in user) {
-  clone[key] = user[key];
-}
-*/!*
-
-// now clone is a fully independent clone
-clone.name = "Pete"; // changed the data in it
-
-alert( user.name ); // still John in the original object
-```
-
-Also we can use the method [Object.assign](mdn:js/Object/assign) for that.
-
-The syntax is:
-
-```js
-Object.assign(dest, [src1, src2, src3...])
-```
-
-- Arguments `dest`, and `src1, ..., srcN` (can be as many as needed) are objects.
-- It copies the properties of all objects `src1, ..., srcN` into `dest`. In other words, properties of all arguments starting from the 2nd are copied into the 1st. Then it returns `dest`.
-
-For instance, we can use it to merge several objects into one:
-```js
-let user = { name: "John" };
-
-let permissions1 = { canView: true };
-let permissions2 = { canEdit: true };
-
-*!*
-// copies all properties from permissions1 and permissions2 into user
-Object.assign(user, permissions1, permissions2);
-*/!*
-
-// now user = { name: "John", canView: true, canEdit: true }
-```
-
-If the receiving object (`user`) already has the same named property, it will be overwritten:
-
-```js
-let user = { name: "John" };
-
-// overwrite name, add isAdmin
-Object.assign(user, { name: "Pete", isAdmin: true });
-
-// now user = { name: "Pete", isAdmin: true }
-```
-
-We also can use `Object.assign` to replace the loop for simple cloning:
-
-```js
-let user = {
-  name: "John",
-  age: 30
-};
-
-*!*
-let clone = Object.assign({}, user);
-*/!*
-```
-
-It copies all properties of `user` into the empty object and returns it. Actually, the same as the loop, but shorter.
-
-Until now we assumed that all properties of `user` are primitive. But properties can be references to other objects. What to do with them?
-
-Like this:
-```js run
-let user = {
-  name: "John",
-  sizes: {
-    height: 182,
-    width: 50
-  }
-};
-
-alert( user.sizes.height ); // 182
-```
-
-Now it's not enough to copy `clone.sizes = user.sizes`, because the `user.sizes` is an object, it will be copied by reference. So `clone` and `user` will share the same sizes:
-
-Like this:
-```js run
-let user = {
-  name: "John",
-  sizes: {
-    height: 182,
-    width: 50
-  }
-};
-
-let clone = Object.assign({}, user);
-
-alert( user.sizes === clone.sizes ); // true, same object
-
-// user and clone share sizes
-user.sizes.width++;       // change a property from one place
-alert(clone.sizes.width); // 51, see the result from the other one
-```
-
-To fix that, we should use the cloning loop that examines each value of `user[key]` and, if it's an object, then replicate its structure as well. That is called a "deep cloning".
-
-There's a standard algorithm for deep cloning that handles the case above and more complex cases, called the [Structured cloning algorithm](https://html.spec.whatwg.org/multipage/structured-data.html#safe-passing-of-structured-data). In order not to reinvent the wheel, we can use a working implementation of it from the JavaScript library [lodash](https://lodash.com), the method is called [_.cloneDeep(obj)](https://lodash.com/docs#cloneDeep).
-
-
-
 ## Summary
 
 Objects are associative arrays with several special features.
@@ -725,17 +482,13 @@ They store properties (key-value pairs), where:
 
 To access a property, we can use:
 - The dot notation: `obj.property`.
-- Square brackets notation `obj["property"]`. Square brackets allow to take the key from a variable, like `obj[varWithKey]`.
+- Square brackets notation `obj["property"]`. Square brackets allow taking the key from a variable, like `obj[varWithKey]`.
 
 Additional operators:
 - To delete a property: `delete obj.prop`.
 - To check if a property with the given key exists: `"key" in obj`.
 - To iterate over an object: `for (let key in obj)` loop.
 
-Objects are assigned and copied by reference. In other words, a variable stores not the "object value", but a "reference" (address in memory) for the value. So copying such a variable or passing it as a function argument copies that reference, not the object. All operations via copied references (like adding/removing properties) are performed on the same single object.
-
-To make a "real copy" (a clone) we can use `Object.assign` or  [_.cloneDeep(obj)](https://lodash.com/docs#cloneDeep).
-
 What we've studied in this chapter is called a "plain object", or just `Object`.
 
 There are many other kinds of objects in JavaScript:
diff --git a/1-js/04-object-basics/01-object/variable-copy-value.svg b/1-js/04-object-basics/01-object/variable-copy-value.svg
deleted file mode 100644
index e09f521fe..000000000
--- a/1-js/04-object-basics/01-object/variable-copy-value.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="359" height="143" viewBox="0 0 359 143"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:&apos;PT Mono&apos;;font-weight:700;font-style:normal;src:local(&apos;PT MonoBold&apos;),url(/font/PTMonoBold.woff2) format(&apos;woff2&apos;),url(/font/PTMonoBold.woff) format(&apos;woff&apos;),url(/font/PTMonoBold.ttf) format(&apos;truetype&apos;)}</style></defs><g id="combined" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="variable-copy-value.svg"><g id="noun_1211_cc-+-Message" transform="translate(11 6)"><g id="noun_1211_cc"><path id="Shape" fill="#E8C48F" d="M17 37.196h112.558v42.95c0 .373-.079.862-.279 1.294-.2.433-16.574 35.56-16.574 35.56V62.64l16.854-25.444L148 9H35.44L17 37.196zM17 66V38L2 66"/><g id="Rectangle-5-+-&quot;World!&quot;" transform="translate(15)"><path id="Rectangle-5" fill="#FFF9EB" stroke="#8A704D" stroke-width="2" d="M18.861 1.809L2 17.533l53.14 56.986L72 58.794 18.861 1.81z"/><text id="&quot;Hello!&quot;" fill="#8A704D" font-family="OpenSans-Bold, Open Sans" font-size="14" font-weight="bold" transform="rotate(47 38.202 38.946)"><tspan x="2.822" y="43.482">&quot;Hello!&quot;</tspan></text></g><path id="Shape" fill="#E8C48F" d="M0 68v54.73c0 3.42 1.484 5.27 4.387 5.27h100.086c3.122 0 5.527-2.548 5.527-3.476V68H0z"/></g><text id="message" fill="#FFF" font-family="OpenSans-Bold, Open Sans" font-size="18" font-weight="bold"><tspan x="17" y="105">message</tspan></text></g><g id="Group" transform="translate(210 6)"><path id="Shape" fill="#E8C48F" d="M17 37.196h113.417v42.95c0 .373-.08.862-.28 1.294-.202.433-16.702 35.56-16.702 35.56V62.64l16.983-25.444L149 9H35.582L17 37.196z"/><path id="Shape" fill="#E8C48F" d="M18 66V38L2 66"/><g id="Rectangle-5-+-&quot;World!&quot;" transform="translate(15)"><path id="Rectangle-5" fill="#FFF9EB" stroke="#8A704D" stroke-width="2" d="M19.117 1.8l-17.1 15.734 53.866 56.994 17.1-15.734L19.118 1.799z"/><text id="&quot;Hello!&quot;" fill="#8A704D" font-family="OpenSans-Bold, Open Sans" font-size="14" font-weight="bold" transform="rotate(47 38.162 37.693)"><tspan x="2.782" y="42.23">&quot;Hello!&quot;</tspan></text></g><path id="Shape" fill="#E8C48F" d="M0 68v54.73c0 3.42 1.497 5.27 4.427 5.27h100.996c3.15 0 5.577-2.548 5.577-3.476V68H0z"/><text id="phrase" fill="#FFF" font-family="OpenSans-Bold, Open Sans" font-size="18" font-weight="bold"><tspan x="25" y="105">phrase</tspan></text></g></g></g></svg>
\ No newline at end of file
diff --git a/1-js/04-object-basics/02-garbage-collection/garbage-collection-1.svg b/1-js/04-object-basics/02-garbage-collection/garbage-collection-1.svg
deleted file mode 100644
index 2563c8185..000000000
--- a/1-js/04-object-basics/02-garbage-collection/garbage-collection-1.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="463" height="204" viewBox="0 0 463 204"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:&apos;PT Mono&apos;;font-weight:700;font-style:normal;src:local(&apos;PT MonoBold&apos;),url(/font/PTMonoBold.woff2) format(&apos;woff2&apos;),url(/font/PTMonoBold.woff) format(&apos;woff&apos;),url(/font/PTMonoBold.ttf) format(&apos;truetype&apos;)}</style></defs><defs><path id="path-1" d="M0 0h80v28H0z"/><path id="path-3" d="M0 0h40v20H0z"/><path id="path-5" d="M0 0h40v20H0z"/><path id="path-7" d="M0 0h40v20H0z"/><path id="path-9" d="M0 0h40v20H0z"/><path id="path-11" d="M0 0h40v20H0z"/><path id="path-13" d="M0 0h40v20H0z"/><path id="path-15" d="M0 0h40v20H0z"/><path id="path-17" d="M0 0h40v20H0z"/><path id="path-19" d="M0 0h40v20H0z"/><path id="path-21" d="M0 0h40v20H0z"/><path id="path-23" d="M0 0h40v20H0z"/></defs><g id="garbage-collection" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="garbage-collection-1.svg"><g id="Rectangle-1-Clipped" transform="translate(106 8)"><mask id="mask-2" fill="#fff"><use xlink:href="#path-1"/></mask><g id="Rectangle-1" fill="#FFF9EB" stroke="#E8C48E" stroke-width="4" mask="url(#mask-2)"><path id="path-1" d="M0 0h80v28H0z"/></g></g><text id="&lt;global&gt;" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="115" y="26">&lt;global&gt;</tspan></text><g id="Rectangle-2-Clipped" transform="translate(360 99)"><mask id="mask-4" fill="#fff"><use xlink:href="#path-3"/></mask><g id="Rectangle-2" fill="#FFF9EB" fill-opacity=".8" stroke="#BCA68E" stroke-width="4" mask="url(#mask-4)"><path id="path-3" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-2-Clipped" transform="translate(267 99)"><mask id="mask-6" fill="#fff"><use xlink:href="#path-5"/></mask><g id="Rectangle-2-Copy-2" fill="#FFF9EB" fill-opacity=".8" stroke="#BCA68E" stroke-width="4" mask="url(#mask-6)"><path id="path-5" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-2-Clipped" transform="translate(126 79)"><mask id="mask-8" fill="#fff"><use xlink:href="#path-7"/></mask><g id="Rectangle-2-Copy-2" fill="#FFF9EB" stroke="#BCA68E" stroke-width="4" mask="url(#mask-8)"><path id="path-7" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-Clipped" transform="translate(313 53)"><mask id="mask-10" fill="#fff"><use xlink:href="#path-9"/></mask><g id="Rectangle-2-Copy" fill="#FFF9EB" fill-opacity=".8" stroke="#BCA68E" stroke-width="4" mask="url(#mask-10)"><path id="path-9" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-3-Clipped" transform="translate(176 129)"><mask id="mask-12" fill="#fff"><use xlink:href="#path-11"/></mask><g id="Rectangle-2-Copy-3" fill="#FFF9EB" stroke="#BCA68E" stroke-width="4" mask="url(#mask-12)"><path id="path-11" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-8-Clipped" transform="translate(196 69)"><mask id="mask-14" fill="#fff"><use xlink:href="#path-13"/></mask><g id="Rectangle-2-Copy-8" fill="#FFF9EB" stroke="#BCA68E" stroke-width="4" mask="url(#mask-14)"><path id="path-13" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-4-Clipped" transform="translate(128 139)"><mask id="mask-16" fill="#fff"><use xlink:href="#path-15"/></mask><g id="Rectangle-2-Copy-4" fill="#FFF9EB" stroke="#BCA68E" stroke-width="4" mask="url(#mask-16)"><path id="path-15" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-5-Clipped" transform="translate(76 131)"><mask id="mask-18" fill="#fff"><use xlink:href="#path-17"/></mask><g id="Rectangle-2-Copy-5" fill="#FFF9EB" stroke="#BCA68E" stroke-width="4" mask="url(#mask-18)"><path id="path-17" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-6-Clipped" transform="translate(76 71)"><mask id="mask-20" fill="#fff"><use xlink:href="#path-19"/></mask><g id="Rectangle-2-Copy-6" fill="#FFF9EB" stroke="#BCA68E" stroke-width="4" mask="url(#mask-20)"><path id="path-19" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-7-Clipped" transform="translate(27 57)"><mask id="mask-22" fill="#fff"><use xlink:href="#path-21"/></mask><g id="Rectangle-2-Copy-7" fill="#FFF9EB" stroke="#BCA68E" stroke-width="4" mask="url(#mask-22)"><path id="path-21" d="M0 0h40v20H0z"/></g></g><path id="Line" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M148.5 40.5v31"/><path id="Line-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M148.5 71.5l3-10.8h-6z"/><path id="Line-Copy" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M148.5 105.5v24"/><path id="Line-Copy-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M148.5 129.5l3-10.8h-6z"/><path id="Line-2" fill="#EE6B47" fill-opacity=".8" stroke="#EE6B47" stroke-width="2" d="M319.5 77.5l-19 16"/><path id="Line-2-decoration-1" fill="#EE6B47" fill-opacity=".8" stroke="#EE6B47" stroke-width="2" d="M300.5 93.5l10.193-4.662-3.864-4.59z"/><path id="Line-2" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M127.5 47.5l-19 16"/><path id="Line-2-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M108.5 63.5l10.193-4.662-3.864-4.59z"/><path id="Line-2-Copy-2" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M97.5 42.5l-23 9"/><path id="Line-2-Copy-2-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M74.5 51.5l11.15-1.142-2.186-5.587z"/><path id="Line-2-Copy" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M133.5 107.5l-19 16"/><path id="Line-2-Copy-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M114.5 123.5l10.193-4.662-3.864-4.59z"/><path id="Line" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M313.071 109.5h39.354"/><path id="Line-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M352.425 109.5l-10.8-3v6z"/><path id="Line" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M170.5 107.5l18 15"/><path id="Line-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M188.5 122.5l-6.376-9.219-3.841 4.61z"/><path id="Line-Copy-6" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M202.5 154.5l18 15"/><path id="Line-Copy-6-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M220.5 169.5l-6.376-9.219-3.841 4.61z"/><path id="Line-Copy-5" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M170.5 87.5l20-7"/><path id="Line-Copy-5-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M190.5 80.5l-11.185.736 1.982 5.663z"/><path id="Line-Copy-4" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M209.5 120.5l14-22"/><path id="Line-Copy-4-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M223.5 98.5l-8.33 7.5 5.063 3.222z"/><path id="Line-Copy-3" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M46.5 82.5l32 40"/><path id="Line-Copy-3-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M78.5 122.5l-4.404-10.307-4.685 3.748z"/><g id="Rectangle-2-Copy-9-Clipped" transform="translate(219 177)"><mask id="mask-24" fill="#fff"><use xlink:href="#path-23"/></mask><g id="Rectangle-2-Copy-9" fill="#FFF9EB" stroke="#BCA68E" stroke-width="4" mask="url(#mask-24)"><path id="path-25" d="M0 0h40v20H0z"/></g></g><path id="Line-Copy-2" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M187.5 41.5l21 21"/><path id="Line-Copy-2-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M208.5 62.5l-5.515-9.758-4.243 4.243z"/><path id="Line-Copy" fill="#EE6B47" fill-rule="nonzero" d="M357.5 79.5l14.212 6.56-4.686 3.747 3.255 4.068.625.781-1.562 1.25-.625-.781-3.255-4.069-4.684 3.749L357.5 79.5z"/></g></g></svg>
\ No newline at end of file
diff --git a/1-js/04-object-basics/02-garbage-collection/garbage-collection-2.svg b/1-js/04-object-basics/02-garbage-collection/garbage-collection-2.svg
deleted file mode 100644
index acd5025e9..000000000
--- a/1-js/04-object-basics/02-garbage-collection/garbage-collection-2.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="463" height="204" viewBox="0 0 463 204"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:&apos;PT Mono&apos;;font-weight:700;font-style:normal;src:local(&apos;PT MonoBold&apos;),url(/font/PTMonoBold.woff2) format(&apos;woff2&apos;),url(/font/PTMonoBold.woff) format(&apos;woff&apos;),url(/font/PTMonoBold.ttf) format(&apos;truetype&apos;)}</style></defs><defs><path id="path-1" d="M0 0h80v28H0z"/><path id="path-3" d="M0 0h40v20H0z"/><path id="path-5" d="M0 0h40v20H0z"/><path id="path-7" d="M0 0h40v20H0z"/><path id="path-9" d="M0 0h40v20H0z"/><path id="path-11" d="M0 0h40v20H0z"/><path id="path-13" d="M0 0h40v20H0z"/><path id="path-15" d="M0 0h40v20H0z"/><path id="path-17" d="M0 0h40v20H0z"/><path id="path-19" d="M0 0h40v20H0z"/><path id="path-21" d="M0 0h40v20H0z"/><path id="path-23" d="M0 0h40v20H0z"/></defs><g id="garbage-collection" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="garbage-collection-2.svg"><g id="Rectangle-1-Clipped" transform="translate(106 8)"><mask id="mask-2" fill="#fff"><use xlink:href="#path-1"/></mask><g id="Rectangle-1" fill="#FFF9EB" stroke="#E8C48E" stroke-width="4" mask="url(#mask-2)"><path id="path-1" d="M0 0h80v28H0z"/></g></g><text id="&lt;global&gt;" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="115" y="26">&lt;global&gt;</tspan></text><g id="Rectangle-2-Clipped" transform="translate(360 99)"><mask id="mask-4" fill="#fff"><use xlink:href="#path-3"/></mask><g id="Rectangle-2" fill="#FFF9EB" fill-opacity=".8" stroke="#BCA68E" stroke-width="4" mask="url(#mask-4)"><path id="path-3" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-2-Clipped" transform="translate(267 99)"><mask id="mask-6" fill="#fff"><use xlink:href="#path-5"/></mask><g id="Rectangle-2-Copy-2" fill="#FFF9EB" fill-opacity=".8" stroke="#BCA68E" stroke-width="4" mask="url(#mask-6)"><path id="path-5" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-2-Clipped" transform="translate(126 79)"><mask id="mask-8" fill="#fff"><use xlink:href="#path-7"/></mask><g id="Rectangle-2-Copy-2" fill="#FFF9EB" stroke="#BCA68E" stroke-width="4" mask="url(#mask-8)"><path id="path-7" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-Clipped" transform="translate(313 53)"><mask id="mask-10" fill="#fff"><use xlink:href="#path-9"/></mask><g id="Rectangle-2-Copy" fill="#FFF9EB" fill-opacity=".8" stroke="#BCA68E" stroke-width="4" mask="url(#mask-10)"><path id="path-9" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-3-Clipped" transform="translate(176 129)"><mask id="mask-12" fill="#fff"><use xlink:href="#path-11"/></mask><g id="Rectangle-2-Copy-3" fill="#FFF9EB" stroke="#BCA68E" stroke-width="4" mask="url(#mask-12)"><path id="path-11" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-8-Clipped" transform="translate(196 69)"><mask id="mask-14" fill="#fff"><use xlink:href="#path-13"/></mask><g id="Rectangle-2-Copy-8" fill="#FFF9EB" stroke="#BCA68E" stroke-width="4" mask="url(#mask-14)"><path id="path-13" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-4-Clipped" transform="translate(128 139)"><mask id="mask-16" fill="#fff"><use xlink:href="#path-15"/></mask><g id="Rectangle-2-Copy-4" fill="#FFF9EB" stroke="#BCA68E" stroke-width="4" mask="url(#mask-16)"><path id="path-15" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-5-Clipped" transform="translate(76 131)"><mask id="mask-18" fill="#fff"><use xlink:href="#path-17"/></mask><g id="Rectangle-2-Copy-5" fill="#FFF9EB" stroke="#BCA68E" stroke-width="4" mask="url(#mask-18)"><path id="path-17" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-6-Clipped" transform="translate(76 71)"><mask id="mask-20" fill="#fff"><use xlink:href="#path-19"/></mask><g id="Rectangle-2-Copy-6" fill="#FFF9EB" stroke="#BCA68E" stroke-width="4" mask="url(#mask-20)"><path id="path-19" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-7-Clipped" transform="translate(27 57)"><mask id="mask-22" fill="#fff"><use xlink:href="#path-21"/></mask><g id="Rectangle-2-Copy-7" fill="#FFF9EB" stroke="#BCA68E" stroke-width="4" mask="url(#mask-22)"><path id="path-21" d="M0 0h40v20H0z"/></g></g><path id="Line" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M148.5 40.5v31"/><path id="Line-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M148.5 71.5l3-10.8h-6z"/><path id="Line-Copy" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M148.5 105.5v24"/><path id="Line-Copy-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M148.5 129.5l3-10.8h-6z"/><path id="Line-2" fill="#EE6B47" fill-opacity=".8" stroke="#EE6B47" stroke-width="2" d="M319.5 77.5l-19 16"/><path id="Line-2-decoration-1" fill="#EE6B47" fill-opacity=".8" stroke="#EE6B47" stroke-width="2" d="M300.5 93.5l10.193-4.662-3.864-4.59z"/><path id="Line-2" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M127.5 47.5l-19 16"/><path id="Line-2-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M108.5 63.5l10.193-4.662-3.864-4.59z"/><path id="Line-2-Copy-2" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M97.5 42.5l-23 9"/><path id="Line-2-Copy-2-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M74.5 51.5l11.15-1.142-2.186-5.587z"/><path id="Line-2-Copy" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M133.5 107.5l-19 16"/><path id="Line-2-Copy-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M114.5 123.5l10.193-4.662-3.864-4.59z"/><path id="Line" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M313.071 109.5h39.354"/><path id="Line-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M352.425 109.5l-10.8-3v6z"/><path id="Line" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M170.5 107.5l18 15"/><path id="Line-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M188.5 122.5l-6.376-9.219-3.841 4.61z"/><path id="Line-Copy-6" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M202.5 154.5l18 15"/><path id="Line-Copy-6-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M220.5 169.5l-6.376-9.219-3.841 4.61z"/><path id="Line-Copy-5" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M170.5 87.5l20-7"/><path id="Line-Copy-5-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M190.5 80.5l-11.185.736 1.982 5.663z"/><path id="Line-Copy-4" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M209.5 120.5l14-22"/><path id="Line-Copy-4-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M223.5 98.5l-8.33 7.5 5.063 3.222z"/><path id="Line-Copy-3" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M46.5 82.5l32 40"/><path id="Line-Copy-3-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M78.5 122.5l-4.404-10.307-4.685 3.748z"/><g id="Group" fill="#417505" transform="rotate(-90 81 2)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><g id="Group-Copy" fill="#417505" transform="rotate(-90 49.5 19.5)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><g id="Group-Copy-4" fill="#417505" transform="rotate(-90 110 -19)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><g id="Rectangle-2-Copy-9-Clipped" transform="translate(219 177)"><mask id="mask-24" fill="#fff"><use xlink:href="#path-23"/></mask><g id="Rectangle-2-Copy-9" fill="#FFF9EB" stroke="#BCA68E" stroke-width="4" mask="url(#mask-24)"><path id="path-25" d="M0 0h40v20H0z"/></g></g><g id="Group-Copy-6" fill="#417505" transform="rotate(-90 140 -59)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><path id="Line-Copy-2" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M187.5 41.5l21 21"/><path id="Line-Copy-2-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M208.5 62.5l-5.515-9.758-4.243 4.243z"/><path id="Line-Copy" fill="#EE6B47" fill-rule="nonzero" d="M357.5 79.5l14.212 6.56-4.686 3.747 3.255 4.068.625.781-1.562 1.25-.625-.781-3.255-4.069-4.684 3.749L357.5 79.5z"/></g></g></svg>
\ No newline at end of file
diff --git a/1-js/04-object-basics/02-garbage-collection/garbage-collection-3.svg b/1-js/04-object-basics/02-garbage-collection/garbage-collection-3.svg
deleted file mode 100644
index 4421ec784..000000000
--- a/1-js/04-object-basics/02-garbage-collection/garbage-collection-3.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="463" height="204" viewBox="0 0 463 204"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:&apos;PT Mono&apos;;font-weight:700;font-style:normal;src:local(&apos;PT MonoBold&apos;),url(/font/PTMonoBold.woff2) format(&apos;woff2&apos;),url(/font/PTMonoBold.woff) format(&apos;woff&apos;),url(/font/PTMonoBold.ttf) format(&apos;truetype&apos;)}</style></defs><defs><path id="path-1" d="M0 0h80v28H0z"/><path id="path-3" d="M0 0h40v20H0z"/><path id="path-5" d="M0 0h40v20H0z"/><path id="path-7" d="M0 0h40v20H0z"/><path id="path-9" d="M0 0h40v20H0z"/><path id="path-11" d="M0 0h40v20H0z"/><path id="path-13" d="M0 0h40v20H0z"/><path id="path-15" d="M0 0h40v20H0z"/><path id="path-17" d="M0 0h40v20H0z"/><path id="path-19" d="M0 0h40v20H0z"/><path id="path-21" d="M0 0h40v20H0z"/><path id="path-23" d="M0 0h40v20H0z"/></defs><g id="garbage-collection" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="garbage-collection-3.svg"><g id="Rectangle-1-Clipped" transform="translate(106 8)"><mask id="mask-2" fill="#fff"><use xlink:href="#path-1"/></mask><g id="Rectangle-1" fill="#FFF9EB" stroke="#E8C48E" stroke-width="4" mask="url(#mask-2)"><path id="path-1" d="M0 0h80v28H0z"/></g></g><text id="&lt;global&gt;" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="115" y="26">&lt;global&gt;</tspan></text><g id="Rectangle-2-Clipped" transform="translate(360 99)"><mask id="mask-4" fill="#fff"><use xlink:href="#path-3"/></mask><g id="Rectangle-2" fill="#FFF9EB" fill-opacity=".8" stroke="#BCA68E" stroke-width="4" mask="url(#mask-4)"><path id="path-3" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-2-Clipped" transform="translate(267 99)"><mask id="mask-6" fill="#fff"><use xlink:href="#path-5"/></mask><g id="Rectangle-2-Copy-2" fill="#FFF9EB" fill-opacity=".8" stroke="#BCA68E" stroke-width="4" mask="url(#mask-6)"><path id="path-5" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-2-Clipped" transform="translate(126 79)"><mask id="mask-8" fill="#fff"><use xlink:href="#path-7"/></mask><g id="Rectangle-2-Copy-2" fill="#FFF9EB" stroke="#BCA68E" stroke-width="4" mask="url(#mask-8)"><path id="path-7" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-Clipped" transform="translate(313 53)"><mask id="mask-10" fill="#fff"><use xlink:href="#path-9"/></mask><g id="Rectangle-2-Copy" fill="#FFF9EB" fill-opacity=".8" stroke="#BCA68E" stroke-width="4" mask="url(#mask-10)"><path id="path-9" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-3-Clipped" transform="translate(176 129)"><mask id="mask-12" fill="#fff"><use xlink:href="#path-11"/></mask><g id="Rectangle-2-Copy-3" fill="#FFF9EB" stroke="#BCA68E" stroke-width="4" mask="url(#mask-12)"><path id="path-11" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-8-Clipped" transform="translate(196 69)"><mask id="mask-14" fill="#fff"><use xlink:href="#path-13"/></mask><g id="Rectangle-2-Copy-8" fill="#FFF9EB" stroke="#BCA68E" stroke-width="4" mask="url(#mask-14)"><path id="path-13" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-4-Clipped" transform="translate(128 139)"><mask id="mask-16" fill="#fff"><use xlink:href="#path-15"/></mask><g id="Rectangle-2-Copy-4" fill="#FFF9EB" stroke="#BCA68E" stroke-width="4" mask="url(#mask-16)"><path id="path-15" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-5-Clipped" transform="translate(76 131)"><mask id="mask-18" fill="#fff"><use xlink:href="#path-17"/></mask><g id="Rectangle-2-Copy-5" fill="#FFF9EB" stroke="#BCA68E" stroke-width="4" mask="url(#mask-18)"><path id="path-17" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-6-Clipped" transform="translate(76 71)"><mask id="mask-20" fill="#fff"><use xlink:href="#path-19"/></mask><g id="Rectangle-2-Copy-6" fill="#FFF9EB" stroke="#BCA68E" stroke-width="4" mask="url(#mask-20)"><path id="path-19" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-7-Clipped" transform="translate(27 57)"><mask id="mask-22" fill="#fff"><use xlink:href="#path-21"/></mask><g id="Rectangle-2-Copy-7" fill="#FFF9EB" stroke="#BCA68E" stroke-width="4" mask="url(#mask-22)"><path id="path-21" d="M0 0h40v20H0z"/></g></g><path id="Line" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M148.5 40.5v31"/><path id="Line-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M148.5 71.5l3-10.8h-6z"/><path id="Line-Copy" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M148.5 105.5v24"/><path id="Line-Copy-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M148.5 129.5l3-10.8h-6z"/><path id="Line-2" fill="#EE6B47" fill-opacity=".8" stroke="#EE6B47" stroke-width="2" d="M319.5 77.5l-19 16"/><path id="Line-2-decoration-1" fill="#EE6B47" fill-opacity=".8" stroke="#EE6B47" stroke-width="2" d="M300.5 93.5l10.193-4.662-3.864-4.59z"/><path id="Line-2" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M127.5 47.5l-19 16"/><path id="Line-2-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M108.5 63.5l10.193-4.662-3.864-4.59z"/><path id="Line-2-Copy-2" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M97.5 42.5l-23 9"/><path id="Line-2-Copy-2-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M74.5 51.5l11.15-1.142-2.186-5.587z"/><path id="Line-2-Copy" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M133.5 107.5l-19 16"/><path id="Line-2-Copy-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M114.5 123.5l10.193-4.662-3.864-4.59z"/><path id="Line" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M313.071 109.5h39.354"/><path id="Line-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M352.425 109.5l-10.8-3v6z"/><path id="Line" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M170.5 107.5l18 15"/><path id="Line-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M188.5 122.5l-6.376-9.219-3.841 4.61z"/><path id="Line-Copy-6" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M202.5 154.5l18 15"/><path id="Line-Copy-6-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M220.5 169.5l-6.376-9.219-3.841 4.61z"/><path id="Line-Copy-5" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M170.5 87.5l20-7"/><path id="Line-Copy-5-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M190.5 80.5l-11.185.736 1.982 5.663z"/><path id="Line-Copy-4" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M209.5 120.5l14-22"/><path id="Line-Copy-4-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M223.5 98.5l-8.33 7.5 5.063 3.222z"/><path id="Line-Copy-3" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M46.5 82.5l32 40"/><path id="Line-Copy-3-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M78.5 122.5l-4.404-10.307-4.685 3.748z"/><g id="Group" fill="#417505" transform="rotate(-90 81 2)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><g id="Group-Copy" fill="#417505" transform="rotate(-90 49.5 19.5)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><g id="Group-Copy-2" fill="#417505" transform="rotate(-90 111.5 32.5)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><g id="Group-Copy-3" fill="#417505" transform="rotate(-90 141 10)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><g id="Group-Copy-4" fill="#417505" transform="rotate(-90 110 -19)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><g id="Group-Copy-5" fill="#417505" transform="rotate(-90 160 -19)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><g id="Rectangle-2-Copy-9-Clipped" transform="translate(219 177)"><mask id="mask-24" fill="#fff"><use xlink:href="#path-23"/></mask><g id="Rectangle-2-Copy-9" fill="#FFF9EB" stroke="#BCA68E" stroke-width="4" mask="url(#mask-24)"><path id="path-25" d="M0 0h40v20H0z"/></g></g><g id="Group-Copy-6" fill="#417505" transform="rotate(-90 140 -59)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><path id="Line-Copy-2" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M187.5 41.5l21 21"/><path id="Line-Copy-2-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M208.5 62.5l-5.515-9.758-4.243 4.243z"/><path id="Line-Copy" fill="#EE6B47" fill-rule="nonzero" d="M357.5 79.5l14.212 6.56-4.686 3.747 3.255 4.068.625.781-1.562 1.25-.625-.781-3.255-4.069-4.684 3.749L357.5 79.5z"/></g></g></svg>
\ No newline at end of file
diff --git a/1-js/04-object-basics/02-garbage-collection/garbage-collection-4.svg b/1-js/04-object-basics/02-garbage-collection/garbage-collection-4.svg
deleted file mode 100644
index 74adc8135..000000000
--- a/1-js/04-object-basics/02-garbage-collection/garbage-collection-4.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="463" height="204" viewBox="0 0 463 204"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:&apos;PT Mono&apos;;font-weight:700;font-style:normal;src:local(&apos;PT MonoBold&apos;),url(/font/PTMonoBold.woff2) format(&apos;woff2&apos;),url(/font/PTMonoBold.woff) format(&apos;woff&apos;),url(/font/PTMonoBold.ttf) format(&apos;truetype&apos;)}</style></defs><defs><path id="path-1" d="M0 0h80v28H0z"/><path id="path-3" d="M0 0h40v20H0z"/><path id="path-5" d="M0 0h40v20H0z"/><path id="path-7" d="M0 0h40v20H0z"/><path id="path-9" d="M0 0h40v20H0z"/><path id="path-11" d="M0 0h40v20H0z"/><path id="path-13" d="M0 0h40v20H0z"/><path id="path-15" d="M0 0h40v20H0z"/><path id="path-17" d="M0 0h40v20H0z"/><path id="path-19" d="M0 0h40v20H0z"/><path id="path-21" d="M0 0h40v20H0z"/><path id="path-23" d="M0 0h40v20H0z"/></defs><g id="garbage-collection" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="garbage-collection-4.svg"><g id="Rectangle-1-Clipped" transform="translate(106 8)"><mask id="mask-2" fill="#fff"><use xlink:href="#path-1"/></mask><g id="Rectangle-1" fill="#FFF9EB" stroke="#E8C48E" stroke-width="4" mask="url(#mask-2)"><path id="path-1" d="M0 0h80v28H0z"/></g></g><text id="&lt;global&gt;" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="115" y="26">&lt;global&gt;</tspan></text><g id="Rectangle-2-Clipped" transform="translate(360 99)"><mask id="mask-4" fill="#fff"><use xlink:href="#path-3"/></mask><g id="Rectangle-2" fill="#FFF9EB" fill-opacity=".8" stroke="#BCA68E" stroke-width="4" mask="url(#mask-4)"><path id="path-3" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-2-Clipped" transform="translate(267 99)"><mask id="mask-6" fill="#fff"><use xlink:href="#path-5"/></mask><g id="Rectangle-2-Copy-2" fill="#FFF9EB" fill-opacity=".8" stroke="#BCA68E" stroke-width="4" mask="url(#mask-6)"><path id="path-5" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-2-Clipped" transform="translate(126 79)"><mask id="mask-8" fill="#fff"><use xlink:href="#path-7"/></mask><g id="Rectangle-2-Copy-2" fill="#FFF9EB" stroke="#BCA68E" stroke-width="4" mask="url(#mask-8)"><path id="path-7" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-Clipped" transform="translate(313 53)"><mask id="mask-10" fill="#fff"><use xlink:href="#path-9"/></mask><g id="Rectangle-2-Copy" fill="#FFF9EB" fill-opacity=".8" stroke="#BCA68E" stroke-width="4" mask="url(#mask-10)"><path id="path-9" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-3-Clipped" transform="translate(176 129)"><mask id="mask-12" fill="#fff"><use xlink:href="#path-11"/></mask><g id="Rectangle-2-Copy-3" fill="#FFF9EB" stroke="#BCA68E" stroke-width="4" mask="url(#mask-12)"><path id="path-11" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-8-Clipped" transform="translate(196 69)"><mask id="mask-14" fill="#fff"><use xlink:href="#path-13"/></mask><g id="Rectangle-2-Copy-8" fill="#FFF9EB" stroke="#BCA68E" stroke-width="4" mask="url(#mask-14)"><path id="path-13" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-4-Clipped" transform="translate(128 139)"><mask id="mask-16" fill="#fff"><use xlink:href="#path-15"/></mask><g id="Rectangle-2-Copy-4" fill="#FFF9EB" stroke="#BCA68E" stroke-width="4" mask="url(#mask-16)"><path id="path-15" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-5-Clipped" transform="translate(76 131)"><mask id="mask-18" fill="#fff"><use xlink:href="#path-17"/></mask><g id="Rectangle-2-Copy-5" fill="#FFF9EB" stroke="#BCA68E" stroke-width="4" mask="url(#mask-18)"><path id="path-17" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-6-Clipped" transform="translate(76 71)"><mask id="mask-20" fill="#fff"><use xlink:href="#path-19"/></mask><g id="Rectangle-2-Copy-6" fill="#FFF9EB" stroke="#BCA68E" stroke-width="4" mask="url(#mask-20)"><path id="path-19" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-7-Clipped" transform="translate(27 57)"><mask id="mask-22" fill="#fff"><use xlink:href="#path-21"/></mask><g id="Rectangle-2-Copy-7" fill="#FFF9EB" stroke="#BCA68E" stroke-width="4" mask="url(#mask-22)"><path id="path-21" d="M0 0h40v20H0z"/></g></g><path id="Line" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M148.5 40.5v31"/><path id="Line-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M148.5 71.5l3-10.8h-6z"/><path id="Line-Copy" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M148.5 105.5v24"/><path id="Line-Copy-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M148.5 129.5l3-10.8h-6z"/><path id="Line-2" fill="#EE6B47" fill-opacity=".8" stroke="#EE6B47" stroke-width="2" d="M319.5 77.5l-19 16"/><path id="Line-2-decoration-1" fill="#EE6B47" fill-opacity=".8" stroke="#EE6B47" stroke-width="2" d="M300.5 93.5l10.193-4.662-3.864-4.59z"/><path id="Line-2" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M127.5 47.5l-19 16"/><path id="Line-2-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M108.5 63.5l10.193-4.662-3.864-4.59z"/><path id="Line-2-Copy-2" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M97.5 42.5l-23 9"/><path id="Line-2-Copy-2-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M74.5 51.5l11.15-1.142-2.186-5.587z"/><path id="Line-2-Copy" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M133.5 107.5l-19 16"/><path id="Line-2-Copy-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M114.5 123.5l10.193-4.662-3.864-4.59z"/><path id="Line" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M313.071 109.5h39.354"/><path id="Line-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M352.425 109.5l-10.8-3v6z"/><path id="Line" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M170.5 107.5l18 15"/><path id="Line-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M188.5 122.5l-6.376-9.219-3.841 4.61z"/><path id="Line-Copy-6" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M202.5 154.5l18 15"/><path id="Line-Copy-6-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M220.5 169.5l-6.376-9.219-3.841 4.61z"/><path id="Line-Copy-5" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M170.5 87.5l20-7"/><path id="Line-Copy-5-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M190.5 80.5l-11.185.736 1.982 5.663z"/><path id="Line-Copy-4" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M209.5 120.5l14-22"/><path id="Line-Copy-4-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M223.5 98.5l-8.33 7.5 5.063 3.222z"/><path id="Line-Copy-3" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M46.5 82.5l32 40"/><path id="Line-Copy-3-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M78.5 122.5l-4.404-10.307-4.685 3.748z"/><g id="Group" fill="#417505" transform="rotate(-90 81 2)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><g id="Group-Copy" fill="#417505" transform="rotate(-90 49.5 19.5)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><g id="Group-Copy-2" fill="#417505" transform="rotate(-90 111.5 32.5)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><g id="Group-Copy-3" fill="#417505" transform="rotate(-90 141 10)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><g id="Group-Copy-4" fill="#417505" transform="rotate(-90 110 -19)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><g id="Group-Copy-5" fill="#417505" transform="rotate(-90 160 -19)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><g id="Rectangle-2-Copy-9-Clipped" transform="translate(219 177)"><mask id="mask-24" fill="#fff"><use xlink:href="#path-23"/></mask><g id="Rectangle-2-Copy-9" fill="#FFF9EB" stroke="#BCA68E" stroke-width="4" mask="url(#mask-24)"><path id="path-25" d="M0 0h40v20H0z"/></g></g><g id="Group-Copy-7" fill="#417505" transform="rotate(-90 205.5 -16.5)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><g id="Group-Copy-6" fill="#417505" transform="rotate(-90 140 -59)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><path id="Line-Copy-2" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M187.5 41.5l21 21"/><path id="Line-Copy-2-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M208.5 62.5l-5.515-9.758-4.243 4.243z"/><path id="Line-Copy" fill="#EE6B47" fill-rule="nonzero" d="M357.5 79.5l14.212 6.56-4.686 3.747 3.255 4.068.625.781-1.562 1.25-.625-.781-3.255-4.069-4.684 3.749L357.5 79.5z"/></g></g></svg>
\ No newline at end of file
diff --git a/1-js/04-object-basics/02-garbage-collection/garbage-collection-5.svg b/1-js/04-object-basics/02-garbage-collection/garbage-collection-5.svg
deleted file mode 100644
index abb127ab2..000000000
--- a/1-js/04-object-basics/02-garbage-collection/garbage-collection-5.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="463" height="204" viewBox="0 0 463 204"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:&apos;PT Mono&apos;;font-weight:700;font-style:normal;src:local(&apos;PT MonoBold&apos;),url(/font/PTMonoBold.woff2) format(&apos;woff2&apos;),url(/font/PTMonoBold.woff) format(&apos;woff&apos;),url(/font/PTMonoBold.ttf) format(&apos;truetype&apos;)}</style></defs><defs><path id="path-1" d="M0 0h146v88H0z"/><path id="path-3" d="M0 0h80v28H0z"/><path id="path-5" d="M0 0h40v20H0z"/><path id="path-7" d="M0 0h40v20H0z"/><path id="path-9" d="M0 0h40v20H0z"/><path id="path-11" d="M0 0h40v20H0z"/><path id="path-13" d="M0 0h40v20H0z"/><path id="path-15" d="M0 0h40v20H0z"/><path id="path-17" d="M0 0h40v20H0z"/><path id="path-19" d="M0 0h40v20H0z"/><path id="path-21" d="M0 0h40v20H0z"/><path id="path-23" d="M0 0h40v20H0z"/><path id="path-25" d="M0 0h40v20H0z"/></defs><g id="garbage-collection" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="garbage-collection-5.svg"><g id="Rectangle-5-Clipped" transform="translate(260 46)"><mask id="mask-2" fill="#fff"><use xlink:href="#path-1"/></mask><g id="Rectangle-5" stroke="#D0011B" stroke-width="4" mask="url(#mask-2)"><path id="path-23" d="M0 0h146v88H0z"/></g></g><g id="Rectangle-1-Clipped" transform="translate(106 8)"><mask id="mask-4" fill="#fff"><use xlink:href="#path-3"/></mask><g id="Rectangle-1" fill="#FFF9EB" stroke="#E8C48E" stroke-width="4" mask="url(#mask-4)"><path id="path-1" d="M0 0h80v28H0z"/></g></g><text id="&lt;global&gt;" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="115" y="26">&lt;global&gt;</tspan></text><g id="Rectangle-2-Clipped" transform="translate(360 99)"><mask id="mask-6" fill="#fff"><use xlink:href="#path-5"/></mask><g id="Rectangle-2" fill="#FFF9EB" fill-opacity=".8" stroke="#BCA68E" stroke-width="4" mask="url(#mask-6)"><path id="path-3" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-2-Clipped" transform="translate(267 99)"><mask id="mask-8" fill="#fff"><use xlink:href="#path-7"/></mask><g id="Rectangle-2-Copy-2" fill="#FFF9EB" fill-opacity=".8" stroke="#BCA68E" stroke-width="4" mask="url(#mask-8)"><path id="path-5" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-2-Clipped" transform="translate(126 79)"><mask id="mask-10" fill="#fff"><use xlink:href="#path-9"/></mask><g id="Rectangle-2-Copy-2" fill="#FFF9EB" stroke="#BCA68E" stroke-width="4" mask="url(#mask-10)"><path id="path-7" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-Clipped" transform="translate(313 53)"><mask id="mask-12" fill="#fff"><use xlink:href="#path-11"/></mask><g id="Rectangle-2-Copy" fill="#FFF9EB" fill-opacity=".8" stroke="#BCA68E" stroke-width="4" mask="url(#mask-12)"><path id="path-9" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-3-Clipped" transform="translate(176 129)"><mask id="mask-14" fill="#fff"><use xlink:href="#path-13"/></mask><g id="Rectangle-2-Copy-3" fill="#FFF9EB" stroke="#BCA68E" stroke-width="4" mask="url(#mask-14)"><path id="path-11" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-8-Clipped" transform="translate(196 69)"><mask id="mask-16" fill="#fff"><use xlink:href="#path-15"/></mask><g id="Rectangle-2-Copy-8" fill="#FFF9EB" stroke="#BCA68E" stroke-width="4" mask="url(#mask-16)"><path id="path-13" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-4-Clipped" transform="translate(128 139)"><mask id="mask-18" fill="#fff"><use xlink:href="#path-17"/></mask><g id="Rectangle-2-Copy-4" fill="#FFF9EB" stroke="#BCA68E" stroke-width="4" mask="url(#mask-18)"><path id="path-15" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-5-Clipped" transform="translate(76 131)"><mask id="mask-20" fill="#fff"><use xlink:href="#path-19"/></mask><g id="Rectangle-2-Copy-5" fill="#FFF9EB" stroke="#BCA68E" stroke-width="4" mask="url(#mask-20)"><path id="path-17" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-6-Clipped" transform="translate(76 71)"><mask id="mask-22" fill="#fff"><use xlink:href="#path-21"/></mask><g id="Rectangle-2-Copy-6" fill="#FFF9EB" stroke="#BCA68E" stroke-width="4" mask="url(#mask-22)"><path id="path-19" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-7-Clipped" transform="translate(27 57)"><mask id="mask-24" fill="#fff"><use xlink:href="#path-23"/></mask><g id="Rectangle-2-Copy-7" fill="#FFF9EB" stroke="#BCA68E" stroke-width="4" mask="url(#mask-24)"><path id="path-21" d="M0 0h40v20H0z"/></g></g><path id="Line" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M148.5 40.5v31"/><path id="Line-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M148.5 71.5l3-10.8h-6z"/><path id="Line-Copy" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M148.5 105.5v24"/><path id="Line-Copy-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M148.5 129.5l3-10.8h-6z"/><path id="Line-2" fill="#EE6B47" fill-opacity=".8" stroke="#EE6B47" stroke-width="2" d="M319.5 77.5l-19 16"/><path id="Line-2-decoration-1" fill="#EE6B47" fill-opacity=".8" stroke="#EE6B47" stroke-width="2" d="M300.5 93.5l10.193-4.662-3.864-4.59z"/><path id="Line-2" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M127.5 47.5l-19 16"/><path id="Line-2-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M108.5 63.5l10.193-4.662-3.864-4.59z"/><path id="Line-2-Copy-2" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M97.5 42.5l-23 9"/><path id="Line-2-Copy-2-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M74.5 51.5l11.15-1.142-2.186-5.587z"/><path id="Line-2-Copy" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M133.5 107.5l-19 16"/><path id="Line-2-Copy-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M114.5 123.5l10.193-4.662-3.864-4.59z"/><path id="Line" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M313.071 109.5h39.354"/><path id="Line-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M352.425 109.5l-10.8-3v6z"/><path id="Line" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M170.5 107.5l18 15"/><path id="Line-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M188.5 122.5l-6.376-9.219-3.841 4.61z"/><path id="Line-Copy-6" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M202.5 154.5l18 15"/><path id="Line-Copy-6-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M220.5 169.5l-6.376-9.219-3.841 4.61z"/><path id="Line-Copy-5" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M170.5 87.5l20-7"/><path id="Line-Copy-5-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M190.5 80.5l-11.185.736 1.982 5.663z"/><path id="Line-Copy-4" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M209.5 120.5l14-22"/><path id="Line-Copy-4-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M223.5 98.5l-8.33 7.5 5.063 3.222z"/><path id="Line-Copy-3" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M46.5 82.5l32 40"/><path id="Line-Copy-3-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M78.5 122.5l-4.404-10.307-4.685 3.748z"/><g id="noun_48910_cc" transform="translate(261 5)"><path id="Shape" d="M17.503 1.75h-5.006a.341.341 0 00-.34.342v1.125h5.686V2.092a.341.341 0 00-.34-.341z"/><path id="Shape" fill="#D0021B" d="M28.364 3.217H19.59V2.092A2.09 2.09 0 0017.503 0h-5.006c-1.15 0-2.087.938-2.087 2.092v1.125H1.637c-.7 0-1.266.568-1.266 1.269v.09c0 .7.567 1.267 1.266 1.267h26.727c.699 0 1.266-.567 1.266-1.268v-.09c0-.7-.567-1.268-1.266-1.268zm-10.52 0h-5.687V2.092c0-.188.153-.341.34-.341h5.006a.34.34 0 01.34.34v1.126zM26.054 6.281H3.728c-1.298 0-2.35-.224-2.35 1.077L3.14 33.196c0 1.3 1.052 2.409 2.35 2.409h18.802c1.298 0 2.35-1.11 2.35-2.409l1.763-25.838c0-1.301-1.053-1.077-2.35-1.077zM9.637 32.193c-.377.012-.691-.261-.704-.612l-.694-19.917c-.012-.351.283-.647.66-.66.376-.013.69.261.703.613l.694 19.916c.013.351-.283.647-.659.66zm6.044-.63c0 .352-.306.637-.682.637-.377 0-.682-.286-.682-.637V11.634c0-.351.305-.636.682-.636.376 0 .682.285.682.636v19.93zm5.384.018c-.012.351-.327.625-.704.612-.376-.013-.672-.308-.66-.66l.695-19.916c.012-.352.326-.626.703-.613.377.014.672.309.66.66l-.694 19.917z"/></g><text id="unreachables" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="296" y="29">unreachables</tspan></text><g id="Group" fill="#417505" transform="rotate(-90 81 2)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><g id="Group-Copy" fill="#417505" transform="rotate(-90 49.5 19.5)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><g id="Group-Copy-2" fill="#417505" transform="rotate(-90 111.5 32.5)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><g id="Group-Copy-3" fill="#417505" transform="rotate(-90 141 10)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><g id="Group-Copy-4" fill="#417505" transform="rotate(-90 110 -19)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><g id="Group-Copy-5" fill="#417505" transform="rotate(-90 160 -19)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><g id="Rectangle-2-Copy-9-Clipped" transform="translate(219 177)"><mask id="mask-26" fill="#fff"><use xlink:href="#path-25"/></mask><g id="Rectangle-2-Copy-9" fill="#FFF9EB" stroke="#BCA68E" stroke-width="4" mask="url(#mask-26)"><path id="path-25" d="M0 0h40v20H0z"/></g></g><g id="Group-Copy-7" fill="#417505" transform="rotate(-90 205.5 -16.5)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><g id="Group-Copy-6" fill="#417505" transform="rotate(-90 140 -59)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><path id="Line-Copy-2" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M187.5 41.5l21 21"/><path id="Line-Copy-2-decoration-1" fill="#EE6B47" stroke="#EE6B47" stroke-width="2" d="M208.5 62.5l-5.515-9.758-4.243 4.243z"/><path id="Line" fill="#EE6B47" fill-rule="nonzero" d="M357.5 79.5l14.212 6.56-4.686 3.747 3.255 4.068.625.781-1.562 1.25-.625-.781-3.255-4.069-4.684 3.749L357.5 79.5z"/></g></g></svg>
\ No newline at end of file
diff --git a/1-js/04-object-basics/02-object-copy/article.md b/1-js/04-object-basics/02-object-copy/article.md
new file mode 100644
index 000000000..e80f748ab
--- /dev/null
+++ b/1-js/04-object-basics/02-object-copy/article.md
@@ -0,0 +1,325 @@
+# Object references and copying
+
+One of the fundamental differences of objects versus primitives is that objects are stored and copied "by reference", whereas primitive values: strings, numbers, booleans, etc -- are always copied "as a whole value".
+
+That's easy to understand if we look a bit under the hood of what happens when we copy a value.
+
+Let's start with a primitive, such as a string.
+
+Here we put a copy of `message` into `phrase`:
+
+```js
+let message = "Hello!";
+let phrase = message;
+```
+
+As a result we have two independent variables, each one storing the string `"Hello!"`.
+
+![](variable-copy-value.svg)
+
+Quite an obvious result, right?
+
+Objects are not like that.
+
+**A variable assigned to an object stores not the object itself, but its "address in memory" -- in other words "a reference" to it.**
+
+Let's look at an example of such a variable:
+
+```js
+let user = {
+  name: "John"
+};
+```
+
+And here's how it's actually stored in memory:
+
+![](variable-contains-reference.svg)
+
+The object is stored somewhere in memory (at the right of the picture), while the `user` variable (at the left) has a "reference" to it.
+
+We may think of an object variable, such as `user`, like a sheet of paper with the address of the object on it.
+
+When we perform actions with the object, e.g. take a property `user.name`, the JavaScript engine looks at what's at that address and performs the operation on the actual object.
+
+Now here's why it's important.
+
+**When an object variable is copied, the reference is copied, but the object itself is not duplicated.**
+
+For instance:
+
+```js no-beautify
+let user = { name: "John" };
+
+let admin = user; // copy the reference
+```
+
+Now we have two variables, each storing a reference to the same object:
+
+![](variable-copy-reference.svg)
+
+As you can see, there's still one object, but now with two variables that reference it.
+
+We can use either variable to access the object and modify its contents:
+
+```js run
+let user = { name: 'John' };
+
+let admin = user;
+
+*!*
+admin.name = 'Pete'; // changed by the "admin" reference
+*/!*
+
+alert(*!*user.name*/!*); // 'Pete', changes are seen from the "user" reference
+```
+
+It's as if we had a cabinet with two keys and used one of them (`admin`) to get into it and make changes. Then, if we later use another key (`user`), we are still opening the same cabinet and can access the changed contents.
+
+## Comparison by reference
+
+Two objects are equal only if they are the same object.
+
+For instance, here `a` and `b` reference the same object, thus they are equal:
+
+```js run
+let a = {};
+let b = a; // copy the reference
+
+alert( a == b ); // true, both variables reference the same object
+alert( a === b ); // true
+```
+
+And here two independent objects are not equal, even though they look alike (both are empty):
+
+```js run
+let a = {};
+let b = {}; // two independent objects
+
+alert( a == b ); // false
+```
+
+For comparisons like `obj1 > obj2` or for a comparison against a primitive `obj == 5`, objects are converted to primitives. We'll study how object conversions work very soon, but to tell the truth, such comparisons are needed very rarely -- usually they appear as a result of a programming mistake.
+
+````smart header="Const objects can be modified"
+An important side effect of storing objects as references is that an object declared as `const` *can* be modified.
+
+For instance:
+
+```js run
+const user = {
+  name: "John"
+};
+
+*!*
+user.name = "Pete"; // (*)
+*/!*
+
+alert(user.name); // Pete
+```
+
+It might seem that the line `(*)` would cause an error, but it does not. The value of `user` is constant, it must always reference the same object, but properties of that object are free to change.
+
+In other words, the `const user` gives an error only if we try to set `user=...` as a whole.
+
+That said, if we really need to make constant object properties, it's also possible, but using totally different methods. We'll mention that in the chapter <info:property-descriptors>.
+````
+
+## Cloning and merging, Object.assign [#cloning-and-merging-object-assign]
+
+So, copying an object variable creates one more reference to the same object.
+
+But what if we need to duplicate an object?
+
+We can create a new object and replicate the structure of the existing one, by iterating over its properties and copying them on the primitive level.
+
+Like this:
+
+```js run
+let user = {
+  name: "John",
+  age: 30
+};
+
+*!*
+let clone = {}; // the new empty object
+
+// let's copy all user properties into it
+for (let key in user) {
+  clone[key] = user[key];
+}
+*/!*
+
+// now clone is a fully independent object with the same content
+clone.name = "Pete"; // changed the data in it
+
+alert( user.name ); // still John in the original object
+```
+
+We can also use the method [Object.assign](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign).
+
+The syntax is:
+
+```js
+Object.assign(dest, ...sources)
+```
+
+- The first argument `dest` is a target object.
+- Further arguments is a list of source objects.
+
+It copies the properties of all source objects into the target `dest`, and then returns it as the result.
+
+For example, we have `user` object, let's add a couple of permissions to it:
+
+```js run
+let user = { name: "John" };
+
+let permissions1 = { canView: true };
+let permissions2 = { canEdit: true };
+
+*!*
+// copies all properties from permissions1 and permissions2 into user
+Object.assign(user, permissions1, permissions2);
+*/!*
+
+// now user = { name: "John", canView: true, canEdit: true }
+alert(user.name); // John
+alert(user.canView); // true
+alert(user.canEdit); // true
+```
+
+If the copied property name already exists, it gets overwritten:
+
+```js run
+let user = { name: "John" };
+
+Object.assign(user, { name: "Pete" });
+
+alert(user.name); // now user = { name: "Pete" }
+```
+
+We also can use `Object.assign` to perform a simple object cloning:
+
+```js run
+let user = {
+  name: "John",
+  age: 30
+};
+
+*!*
+let clone = Object.assign({}, user);
+*/!*
+
+alert(clone.name); // John
+alert(clone.age); // 30
+```
+
+Here it copies all properties of `user` into the empty object and returns it.
+
+There are also other methods of cloning an object, e.g. using the [spread syntax](info:rest-parameters-spread) `clone = {...user}`, covered later in the tutorial.
+
+## Nested cloning
+
+Until now we assumed that all properties of `user` are primitive. But properties can be references to other objects.
+
+Like this:
+```js run
+let user = {
+  name: "John",
+  sizes: {
+    height: 182,
+    width: 50
+  }
+};
+
+alert( user.sizes.height ); // 182
+```
+
+Now it's not enough to copy `clone.sizes = user.sizes`, because `user.sizes` is an object, and will be copied by reference, so `clone` and `user` will share the same sizes:
+
+```js run
+let user = {
+  name: "John",
+  sizes: {
+    height: 182,
+    width: 50
+  }
+};
+
+let clone = Object.assign({}, user);
+
+alert( user.sizes === clone.sizes ); // true, same object
+
+// user and clone share sizes
+user.sizes.width = 60;    // change a property from one place
+alert(clone.sizes.width); // 60, get the result from the other one
+```
+
+To fix that and make `user` and `clone` truly separate objects, we should use a cloning loop that examines each value of `user[key]` and, if it's an object, then replicate its structure as well. That is called a "deep cloning" or "structured cloning". There's [structuredClone](https://developer.mozilla.org/en-US/docs/Web/API/structuredClone) method that implements deep cloning.
+
+
+### structuredClone
+
+The call `structuredClone(object)` clones the `object` with all nested properties.
+
+Here's how we can use it in our example:
+
+```js run
+let user = {
+  name: "John",
+  sizes: {
+    height: 182,
+    width: 50
+  }
+};
+
+*!*
+let clone = structuredClone(user);
+*/!*
+
+alert( user.sizes === clone.sizes ); // false, different objects
+
+// user and clone are totally unrelated now
+user.sizes.width = 60;    // change a property from one place
+alert(clone.sizes.width); // 50, not related
+```
+
+The `structuredClone` method can clone most data types, such as objects, arrays, primitive values.
+
+It also supports circular references, when an object property references the object itself (directly or via a chain or references).
+
+For instance:
+
+```js run
+let user = {};
+// let's create a circular reference:
+// user.me references the user itself
+user.me = user;
+
+let clone = structuredClone(user);
+alert(clone.me === clone); // true
+```
+
+As you can see, `clone.me` references the `clone`, not the `user`! So the circular reference was cloned correctly as well.
+
+Although, there are cases when `structuredClone` fails.
+
+For instance, when an object has a function property:
+
+```js run
+// error
+structuredClone({
+  f: function() {}
+});
+```
+
+Function properties aren't supported.
+
+To handle such complex cases we may need to use a combination of cloning methods, write custom code or, to not reinvent the wheel, take an existing implementation, for instance [_.cloneDeep(obj)](https://lodash.com/docs#cloneDeep) from the JavaScript library [lodash](https://lodash.com).
+
+## Summary
+
+Objects are assigned and copied by reference. In other words, a variable stores not the "object value", but a "reference" (address in memory) for the value. So copying such a variable or passing it as a function argument copies that reference, not the object itself.
+
+All operations via copied references (like adding/removing properties) are performed on the same single object.
+
+To make a "real copy" (a clone) we can use `Object.assign` for the so-called "shallow copy" (nested objects are copied by reference) or a "deep cloning" function `structuredClone` or use a custom cloning implementation, such as [_.cloneDeep(obj)](https://lodash.com/docs#cloneDeep).
diff --git a/1-js/04-object-basics/01-object/variable-contains-reference.svg b/1-js/04-object-basics/02-object-copy/variable-contains-reference.svg
similarity index 63%
rename from 1-js/04-object-basics/01-object/variable-contains-reference.svg
rename to 1-js/04-object-basics/02-object-copy/variable-contains-reference.svg
index a59c9210e..267f04578 100644
--- a/1-js/04-object-basics/01-object/variable-contains-reference.svg
+++ b/1-js/04-object-basics/02-object-copy/variable-contains-reference.svg
@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="370" height="249" viewBox="0 0 370 249"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:&apos;PT Mono&apos;;font-weight:700;font-style:normal;src:local(&apos;PT MonoBold&apos;),url(/font/PTMonoBold.woff2) format(&apos;woff2&apos;),url(/font/PTMonoBold.woff) format(&apos;woff&apos;),url(/font/PTMonoBold.ttf) format(&apos;truetype&apos;)}</style></defs><g id="combined" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="variable-contains-reference.svg"><g id="noun_1211_cc" fill="#E8C48F" transform="translate(12 119)"><path id="Shape" d="M17 28.196h112.558v42.95c0 .373-.079.862-.279 1.294-.2.433-16.574 35.56-16.574 35.56V53.64l16.854-25.444L148 0H35.44L17 28.196zM17 57V29L2 57"/><path id="Shape" d="M0 59v54.73c0 3.42 1.484 5.27 4.387 5.27h100.086c3.122 0 5.527-2.548 5.527-3.476V59H0z"/></g><text id="user" fill="#FFF" font-family="OpenSans-Bold, Open Sans" font-size="18" font-weight="bold"><tspan x="47" y="215">user</tspan></text><path id="Rectangle-4" fill="#FFF" d="M116 153h44v6h-44z"/><path id="Shape-3" fill="#EE6B47" d="M123.854 154.322l13.779-13.476c1.613-1.274 5.185-4.427 3.572-5.702-1.613-1.275-2.664-.472-4.275.803l-18.499 18.375c-1.613 1.275-1.613 2.845 0 4.12 0 0 21.483 20.067 22.774 20.067 3.005 0 2.677-1.821 1.064-3.096l-18.415-17.826H201.028c2.281 0 3.75.279 3.75-1.524 0-1.804-1.469-1.741-3.75-1.741h-77.174z" transform="matrix(-1 0 0 1 322 0)"/><g id="Rectangle-3-+-Shape" transform="translate(58 135)"><path id="Rectangle-3" fill="#FFF" d="M0 0h47v37H0z"/><path id="Shape" fill="#EE6B47" d="M44 33.772H4V4h40v29.772zM8.733 31.018h30.533L29.22 20.868l-1.902 1.889c-.824.812-2.003 1.277-3.242 1.277l-.021-.001c-1.244-.005-2.427-.48-3.246-1.304l-1.934-1.933-10.14 10.222zM6.791 8.726V29.04l10.122-10.202L6.79 8.726zm24.395 10.187L41.209 29.04V8.954l-10.023 9.96zM8.74 6.755l14.057 14.042c.304.305.766.48 1.27.482h.008c.496 0 .968-.173 1.264-.467L39.49 6.755H8.739z"/></g><path id="Rectangle-4-Copy" fill="#D1C4B1" stroke="#D1C4B1" stroke-width="4" d="M241.937 117l-16.667 20h130.46l-16.667-20h-97.126z" opacity=".5"/><g id="Group-2" transform="translate(271 10)"><g id="Group"><path id="Rectangle-7" fill="#FFF" d="M0 0h32v124H0z"/><path id="Combined-Shape" fill="#E8C48F" d="M32 0v124H0V0h32zM16.5 100a7.5 7.5 0 100 15 7.5 7.5 0 000-15zM28 5H4v87h24V5z"/></g><text id="name" fill="#EE6B47" font-family="PTMono-Bold, PT Mono" font-size="16" font-weight="bold" transform="rotate(-90 15.5 47.5)"><tspan x="-3.7" y="52.5">name</tspan></text></g><path id="Rectangle-4" fill="#FFF9EB" stroke="#BCA68E" stroke-width="4" d="M223 131h135v50H223z"/><path id="Rectangle-8" stroke="#BCA68E" stroke-width="3" d="M278.5 151.5h25v10h-25z"/></g></g></svg>
\ No newline at end of file
+<svg xmlns="http://www.w3.org/2000/svg" width="370" height="249" viewBox="0 0 370 249"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:&apos;PT Mono&apos;;font-weight:700;font-style:normal;src:local(&apos;PT MonoBold&apos;),url(/font/PTMonoBold.woff2) format(&apos;woff2&apos;),url(/font/PTMonoBold.woff) format(&apos;woff&apos;),url(/font/PTMonoBold.ttf) format(&apos;truetype&apos;)}</style></defs><g id="combined" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="variable-contains-reference.svg"><g id="noun_1211_cc" fill="#DBAF88" transform="translate(12 119)"><path id="Shape" d="M17 28.196h112.558v42.95c0 .373-.079.862-.279 1.294-.2.433-16.574 35.56-16.574 35.56V53.64l16.854-25.444L148 0H35.44L17 28.196zM17 57V29L2 57"/><path id="Shape" d="M0 59v54.73c0 3.42 1.484 5.27 4.387 5.27h100.086c3.122 0 5.527-2.548 5.527-3.476V59H0z"/></g><text id="user" fill="#FFF" font-family="OpenSans-Bold, Open Sans" font-size="18" font-weight="bold"><tspan x="47" y="215">user</tspan></text><path id="Rectangle-4" fill="#FFF" d="M116 153h44v6h-44z"/><path id="Shape-3" fill="#C06334" d="M123.854 154.322l13.779-13.476c1.613-1.274 5.185-4.427 3.572-5.702-1.613-1.275-2.664-.472-4.275.803l-18.499 18.375c-1.613 1.275-1.613 2.845 0 4.12 0 0 21.483 20.067 22.774 20.067 3.005 0 2.677-1.821 1.064-3.096l-18.415-17.826H201.028c2.281 0 3.75.279 3.75-1.524 0-1.804-1.469-1.741-3.75-1.741h-77.174z" transform="matrix(-1 0 0 1 322 0)"/><g id="Rectangle-3-+-Shape" transform="translate(58 135)"><path id="Rectangle-3" fill="#FFF" d="M0 0h47v37H0z"/><path id="Shape" fill="#C06334" d="M44 33.772H4V4h40v29.772zM8.733 31.018h30.533L29.22 20.868l-1.902 1.889c-.824.812-2.003 1.277-3.242 1.277l-.021-.001c-1.244-.005-2.427-.48-3.246-1.304l-1.934-1.933-10.14 10.222zM6.791 8.726V29.04l10.122-10.202L6.79 8.726zm24.395 10.187L41.209 29.04V8.954l-10.023 9.96zM8.74 6.755l14.057 14.042c.304.305.766.48 1.27.482h.008c.496 0 .968-.173 1.264-.467L39.49 6.755H8.739z"/></g><path id="Rectangle-4-Copy" fill="#DBAF88" stroke="#DBAF88" stroke-width="4" d="M339.063 117l16.667 20H225.27l16.667-20h97.126z" opacity=".5"/><g id="Group-2" transform="translate(271 10)"><g id="Group"><path id="Rectangle-7" fill="#FFF" d="M0 0h32v124H0z"/><path id="Combined-Shape" fill="#DBAF88" d="M32 0v124H0V0h32zM16.5 100a7.5 7.5 0 100 15 7.5 7.5 0 000-15zM28 5H4v87h24V5z"/></g><text id="name" fill="#C06334" font-family="PTMono-Bold, PT Mono" font-size="16" font-weight="bold" transform="rotate(-90 15.5 47.5)"><tspan x="-3.7" y="52.5">name</tspan></text></g><path id="Rectangle-4" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" d="M223 131h135v50H223z"/><path id="Rectangle-8" stroke="#DBAF88" stroke-width="3" d="M278.5 151.5h25v10h-25z"/></g></g></svg>
\ No newline at end of file
diff --git a/1-js/04-object-basics/01-object/variable-copy-reference.svg b/1-js/04-object-basics/02-object-copy/variable-copy-reference.svg
similarity index 73%
rename from 1-js/04-object-basics/01-object/variable-copy-reference.svg
rename to 1-js/04-object-basics/02-object-copy/variable-copy-reference.svg
index 5d0bc1594..a847fb200 100644
--- a/1-js/04-object-basics/01-object/variable-copy-reference.svg
+++ b/1-js/04-object-basics/02-object-copy/variable-copy-reference.svg
@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="599" height="260" viewBox="0 0 599 260"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:&apos;PT Mono&apos;;font-weight:700;font-style:normal;src:local(&apos;PT MonoBold&apos;),url(/font/PTMonoBold.woff2) format(&apos;woff2&apos;),url(/font/PTMonoBold.woff) format(&apos;woff&apos;),url(/font/PTMonoBold.ttf) format(&apos;truetype&apos;)}</style></defs><g id="combined" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="variable-copy-reference.svg"><g id="Group" transform="translate(11 125)"><g id="noun_1211_cc" fill="#E8C48F"><path id="Shape" d="M17 28.196h112.558v42.95c0 .373-.079.862-.279 1.294-.2.433-16.574 35.56-16.574 35.56V53.64l16.854-25.444L148 0H35.44L17 28.196zM17 57V29L2 57"/><path id="Shape" d="M0 59v54.73c0 3.42 1.484 5.27 4.387 5.27h100.086c3.122 0 5.527-2.548 5.527-3.476V59H0z"/></g><text id="user" fill="#FFF" font-family="OpenSans-Bold, Open Sans" font-size="18" font-weight="bold"><tspan x="35" y="96">user</tspan></text><g id="Rectangle-4-+-Shape-3" transform="translate(104 15)"><path id="Rectangle-4" fill="#FFF" d="M0 19h44v6H0z"/><path id="Shape-3" fill="#EE6B47" d="M7.854 20.322L21.633 6.846c1.613-1.274 5.185-4.427 3.572-5.702-1.613-1.275-2.664-.472-4.275.803L2.43 20.322c-1.613 1.275-1.613 2.845 0 4.12 0 0 21.483 20.067 22.774 20.067 3.005 0 2.677-1.821 1.064-3.096L7.854 23.587H85.028c2.281 0 3.75.279 3.75-1.524 0-1.804-1.469-1.741-3.75-1.741H7.854z" transform="matrix(-1 0 0 1 90 0)"/></g><g id="Rectangle-3-+-Shape" transform="translate(46 16)"><path id="Rectangle-3" fill="#FFF" d="M0 0h47v37H0z"/><path id="Shape" fill="#EE6B47" d="M44 33.772H4V4h40v29.772zM8.733 31.018h30.533L29.22 20.868l-1.902 1.889c-.824.812-2.003 1.277-3.242 1.277l-.021-.001c-1.244-.005-2.427-.48-3.246-1.304l-1.934-1.933-10.14 10.222zM6.791 8.726V29.04l10.122-10.202L6.79 8.726zm24.395 10.187L41.209 29.04V8.954l-10.023 9.96zM8.74 6.755l14.057 14.042c.304.305.766.48 1.27.482h.008c.496 0 .968-.173 1.264-.467L39.49 6.755H8.739z"/></g></g><g id="noun_1211_cc" fill="#E8C48F" transform="translate(418 125)"><path id="Shape" d="M17 28.196h112.558v42.95c0 .373-.079.862-.279 1.294-.2.433-16.574 35.56-16.574 35.56V53.64l16.854-25.444L148 0H35.44L17 28.196zM17 57V29L2 57"/><path id="Shape" d="M0 59v54.73c0 3.42 1.484 5.27 4.387 5.27h100.086c3.122 0 5.527-2.548 5.527-3.476V59H0z"/></g><text id="admin" fill="#FFF" font-family="OpenSans-Bold, Open Sans" font-size="18" font-weight="bold"><tspan x="446" y="221">admin</tspan></text><g id="Rectangle-4-+-Shape-3" transform="matrix(-1 0 0 1 451 140)"><path id="Rectangle-4" fill="#FFF" d="M0 19h44v6H0z"/><path id="Shape-3" fill="#EE6B47" d="M7.854 20.322L21.633 6.846c1.613-1.274 5.185-4.427 3.572-5.702-1.613-1.275-2.664-.472-4.275.803L2.43 20.322c-1.613 1.275-1.613 2.845 0 4.12 0 0 21.483 20.067 22.774 20.067 3.005 0 2.677-1.821 1.064-3.096L7.854 23.587H85.028c2.281 0 3.75.279 3.75-1.524 0-1.804-1.469-1.741-3.75-1.741H7.854z" transform="matrix(-1 0 0 1 90 0)"/></g><g id="Rectangle-3-+-Shape" transform="translate(464 141)"><path id="Rectangle-3" fill="#FFF" d="M0 0h47v37H0z"/><path id="Shape" fill="#EE6B47" d="M44 33.772H4V4h40v29.772zM8.733 31.018h30.533L29.22 20.868l-1.902 1.889c-.824.812-2.003 1.277-3.242 1.277l-.021-.001c-1.244-.005-2.427-.48-3.246-1.304l-1.934-1.933-10.14 10.222zM6.791 8.726V29.04l10.122-10.202L6.79 8.726zm24.395 10.187L41.209 29.04V8.954l-10.023 9.96zM8.74 6.755l14.057 14.042c.304.305.766.48 1.27.482h.008c.496 0 .968-.173 1.264-.467L39.49 6.755H8.739z"/></g><path id="Rectangle-4-Copy" fill="#D1C4B1" stroke="#D1C4B1" stroke-width="4" d="M235.937 125l-16.667 20h130.46l-16.667-20h-97.126z" opacity=".5"/><g id="Group-2" transform="translate(265 18)"><g id="Group"><path id="Rectangle-7" fill="#FFF" d="M0 0h32v124H0z"/><path id="Combined-Shape" fill="#E8C48F" d="M32 0v124H0V0h32zM16.5 100a7.5 7.5 0 100 15 7.5 7.5 0 000-15zM28 5H4v87h24V5z"/></g><text id="name" fill="#EE6B47" font-family="PTMono-Bold, PT Mono" font-size="16" font-weight="bold" transform="rotate(-90 15.5 47.5)"><tspan x="-3.7" y="52.5">name</tspan></text></g><path id="Rectangle-4" fill="#FFF9EB" stroke="#BCA68E" stroke-width="4" d="M217 139h135v50H217z"/><path id="Rectangle-8" stroke="#BCA68E" stroke-width="3" d="M272.5 159.5h25v10h-25z"/></g></g></svg>
\ No newline at end of file
+<svg xmlns="http://www.w3.org/2000/svg" width="599" height="260" viewBox="0 0 599 260"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:&apos;PT Mono&apos;;font-weight:700;font-style:normal;src:local(&apos;PT MonoBold&apos;),url(/font/PTMonoBold.woff2) format(&apos;woff2&apos;),url(/font/PTMonoBold.woff) format(&apos;woff&apos;),url(/font/PTMonoBold.ttf) format(&apos;truetype&apos;)}</style></defs><g id="combined" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="variable-copy-reference.svg"><g id="Group" transform="translate(11 125)"><g id="noun_1211_cc" fill="#DBAF88"><path id="Shape" d="M17 28.196h112.558v42.95c0 .373-.079.862-.279 1.294-.2.433-16.574 35.56-16.574 35.56V53.64l16.854-25.444L148 0H35.44L17 28.196zM17 57V29L2 57"/><path id="Shape" d="M0 59v54.73c0 3.42 1.484 5.27 4.387 5.27h100.086c3.122 0 5.527-2.548 5.527-3.476V59H0z"/></g><text id="user" fill="#FFF" font-family="OpenSans-Bold, Open Sans" font-size="18" font-weight="bold"><tspan x="35" y="96">user</tspan></text><g id="Rectangle-4-+-Shape-3" transform="translate(104 15)"><path id="Rectangle-4" fill="#FFF" d="M0 19h44v6H0z"/><path id="Shape-3" fill="#C06334" d="M7.854 20.322L21.633 6.846c1.613-1.274 5.185-4.427 3.572-5.702-1.613-1.275-2.664-.472-4.275.803L2.43 20.322c-1.613 1.275-1.613 2.845 0 4.12 0 0 21.483 20.067 22.774 20.067 3.005 0 2.677-1.821 1.064-3.096L7.854 23.587H85.028c2.281 0 3.75.279 3.75-1.524 0-1.804-1.469-1.741-3.75-1.741H7.854z" transform="matrix(-1 0 0 1 90 0)"/></g><g id="Rectangle-3-+-Shape" transform="translate(46 16)"><path id="Rectangle-3" fill="#FFF" d="M0 0h47v37H0z"/><path id="Shape" fill="#C06334" d="M44 33.772H4V4h40v29.772zM8.733 31.018h30.533L29.22 20.868l-1.902 1.889c-.824.812-2.003 1.277-3.242 1.277l-.021-.001c-1.244-.005-2.427-.48-3.246-1.304l-1.934-1.933-10.14 10.222zM6.791 8.726V29.04l10.122-10.202L6.79 8.726zm24.395 10.187L41.209 29.04V8.954l-10.023 9.96zM8.74 6.755l14.057 14.042c.304.305.766.48 1.27.482h.008c.496 0 .968-.173 1.264-.467L39.49 6.755H8.739z"/></g></g><g id="noun_1211_cc" fill="#DBAF88" transform="translate(418 125)"><path id="Shape" d="M17 28.196h112.558v42.95c0 .373-.079.862-.279 1.294-.2.433-16.574 35.56-16.574 35.56V53.64l16.854-25.444L148 0H35.44L17 28.196zM17 57V29L2 57"/><path id="Shape" d="M0 59v54.73c0 3.42 1.484 5.27 4.387 5.27h100.086c3.122 0 5.527-2.548 5.527-3.476V59H0z"/></g><text id="admin" fill="#FFF" font-family="OpenSans-Bold, Open Sans" font-size="18" font-weight="bold"><tspan x="446" y="221">admin</tspan></text><g id="Rectangle-4-+-Shape-3" transform="matrix(-1 0 0 1 451 140)"><path id="Rectangle-4" fill="#FFF" d="M0 19h44v6H0z"/><path id="Shape-3" fill="#C06334" d="M7.854 20.322L21.633 6.846c1.613-1.274 5.185-4.427 3.572-5.702-1.613-1.275-2.664-.472-4.275.803L2.43 20.322c-1.613 1.275-1.613 2.845 0 4.12 0 0 21.483 20.067 22.774 20.067 3.005 0 2.677-1.821 1.064-3.096L7.854 23.587H85.028c2.281 0 3.75.279 3.75-1.524 0-1.804-1.469-1.741-3.75-1.741H7.854z" transform="matrix(-1 0 0 1 90 0)"/></g><g id="Rectangle-3-+-Shape" transform="translate(464 141)"><path id="Rectangle-3" fill="#FFF" d="M0 0h47v37H0z"/><path id="Shape" fill="#C06334" d="M44 33.772H4V4h40v29.772zM8.733 31.018h30.533L29.22 20.868l-1.902 1.889c-.824.812-2.003 1.277-3.242 1.277l-.021-.001c-1.244-.005-2.427-.48-3.246-1.304l-1.934-1.933-10.14 10.222zM6.791 8.726V29.04l10.122-10.202L6.79 8.726zm24.395 10.187L41.209 29.04V8.954l-10.023 9.96zM8.74 6.755l14.057 14.042c.304.305.766.48 1.27.482h.008c.496 0 .968-.173 1.264-.467L39.49 6.755H8.739z"/></g><path id="Rectangle-4-Copy" fill="#DBAF88" stroke="#DBAF88" stroke-width="4" d="M333.063 125l16.667 20H219.27l16.667-20h97.126z" opacity=".5"/><g id="Group-2" transform="translate(265 18)"><g id="Group"><path id="Rectangle-7" fill="#FFF" d="M0 0h32v124H0z"/><path id="Combined-Shape" fill="#DBAF88" d="M32 0v124H0V0h32zM16.5 100a7.5 7.5 0 100 15 7.5 7.5 0 000-15zM28 5H4v87h24V5z"/></g><text id="name" fill="#C06334" font-family="PTMono-Bold, PT Mono" font-size="16" font-weight="bold" transform="rotate(-90 15.5 47.5)"><tspan x="-3.7" y="52.5">name</tspan></text></g><path id="Rectangle-4" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" d="M217 139h135v50H217z"/><path id="Rectangle-8" stroke="#DBAF88" stroke-width="3" d="M272.5 159.5h25v10h-25z"/></g></g></svg>
\ No newline at end of file
diff --git a/1-js/04-object-basics/02-object-copy/variable-copy-value.svg b/1-js/04-object-basics/02-object-copy/variable-copy-value.svg
new file mode 100644
index 000000000..0d6ca67bc
--- /dev/null
+++ b/1-js/04-object-basics/02-object-copy/variable-copy-value.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="359" height="143" viewBox="0 0 359 143"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:&apos;PT Mono&apos;;font-weight:700;font-style:normal;src:local(&apos;PT MonoBold&apos;),url(/font/PTMonoBold.woff2) format(&apos;woff2&apos;),url(/font/PTMonoBold.woff) format(&apos;woff&apos;),url(/font/PTMonoBold.ttf) format(&apos;truetype&apos;)}</style></defs><g id="combined" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="variable-copy-value.svg"><g id="noun_1211_cc-+-Message" transform="translate(11 6)"><g id="noun_1211_cc"><path id="Shape" fill="#DBAF88" d="M17 37.196h112.558v42.95c0 .373-.079.862-.279 1.294-.2.433-16.574 35.56-16.574 35.56V62.64l16.854-25.444L148 9H35.44L17 37.196zM17 66V38L2 66"/><g id="Rectangle-5-+-&quot;World!&quot;" transform="translate(15)"><path id="Rectangle-5" fill="#FBF2EC" stroke="#AF6E24" stroke-width="2" d="M18.861 1.809l53.14 56.985L55.14 74.52 1.999 17.533 18.86 1.81z"/><text id="&quot;Hello!&quot;" fill="#AF6E24" font-family="OpenSans-Bold, Open Sans" font-size="14" font-weight="bold" transform="rotate(47 38.202 38.946)"><tspan x="2.822" y="43.482">&quot;Hello!&quot;</tspan></text></g><path id="Shape" fill="#DBAF88" d="M0 68v54.73c0 3.42 1.484 5.27 4.387 5.27h100.086c3.122 0 5.527-2.548 5.527-3.476V68H0z"/></g><text id="message" fill="#FFF" font-family="OpenSans-Bold, Open Sans" font-size="18" font-weight="bold"><tspan x="17" y="105">message</tspan></text></g><g id="Group" transform="translate(210 6)"><path id="Shape" fill="#DBAF88" d="M17 37.196h113.417v42.95c0 .373-.08.862-.28 1.294-.202.433-16.702 35.56-16.702 35.56V62.64l16.983-25.444L149 9H35.582L17 37.196z"/><path id="Shape" fill="#DBAF88" d="M18 66V38L2 66"/><g id="Rectangle-5-+-&quot;World!&quot;" transform="translate(15)"><path id="Rectangle-5" fill="#FBF2EC" stroke="#AF6E24" stroke-width="2" d="M19.117 1.8l53.867 56.994-17.101 15.734L2.016 17.534 19.117 1.799z"/><text id="&quot;Hello!&quot;" fill="#AF6E24" font-family="OpenSans-Bold, Open Sans" font-size="14" font-weight="bold" transform="rotate(47 38.162 37.693)"><tspan x="2.782" y="42.23">&quot;Hello!&quot;</tspan></text></g><path id="Shape" fill="#DBAF88" d="M0 68v54.73c0 3.42 1.497 5.27 4.427 5.27h100.996c3.15 0 5.577-2.548 5.577-3.476V68H0z"/><text id="phrase" fill="#FFF" font-family="OpenSans-Bold, Open Sans" font-size="18" font-weight="bold"><tspan x="25" y="105">phrase</tspan></text></g></g></g></svg>
\ No newline at end of file
diff --git a/1-js/04-object-basics/02-garbage-collection/article.md b/1-js/04-object-basics/03-garbage-collection/article.md
similarity index 75%
rename from 1-js/04-object-basics/02-garbage-collection/article.md
rename to 1-js/04-object-basics/03-garbage-collection/article.md
index 672e26d43..1b576d629 100644
--- a/1-js/04-object-basics/02-garbage-collection/article.md
+++ b/1-js/04-object-basics/03-garbage-collection/article.md
@@ -14,8 +14,8 @@ Simply put, "reachable" values are those that are accessible or usable somehow.
 
     For instance:
 
-    - Local variables and parameters of the current function.
-    - Variables and parameters for other functions on the current chain of nested calls.
+    - The currently executing function, its local variables and parameters.
+    - Other functions on the current chain of nested calls, their local variables and parameters.
     - Global variables.
     - (there are some other, internal ones as well)
 
@@ -23,7 +23,7 @@ Simply put, "reachable" values are those that are accessible or usable somehow.
 
 2. Any other value is considered reachable if it's reachable from a root by a reference or by a chain of references.
 
-    For instance, if there's an object in a local variable, and that object has a property referencing another object, that object is considered reachable. And those that it references are also reachable. Detailed examples to follow.
+    For instance, if there's an object in a global variable, and that object has a property referencing another object, *that* object is considered reachable. And those that it references are also reachable. Detailed examples to follow.
 
 There's a background process in the JavaScript engine that is called [garbage collector](https://en.wikipedia.org/wiki/Garbage_collection_(computer_science)). It monitors all objects and removes those that have become unreachable.
 
@@ -74,7 +74,7 @@ Now if we do the same:
 user = null;
 ```
 
-...Then the object is still reachable via `admin` global variable, so it's in memory. If we overwrite `admin` too, then it can be removed.
+...Then the object is still reachable via `admin` global variable, so it must stay in memory. If we overwrite `admin` too, then it can be removed.
 
 ## Interlinked objects
 
@@ -169,11 +169,11 @@ The first step marks the roots:
 
 ![](garbage-collection-2.svg)
 
-Then their references are marked:
+Then we follow their references and mark referenced objects:
 
 ![](garbage-collection-3.svg)
 
-...And their references, while possible:
+...And continue to follow further references, while possible:
 
 ![](garbage-collection-4.svg)
 
@@ -183,12 +183,12 @@ Now the objects that could not be visited in the process are considered unreacha
 
 We can also imagine the process as spilling a huge bucket of paint from the roots, that flows through all references and marks all reachable objects. The unmarked ones are then removed.
 
-That's the concept of how garbage collection works. JavaScript engines apply many optimizations to make it run faster and not affect the execution.
+That's the concept of how garbage collection works. JavaScript engines apply many optimizations to make it run faster and not introduce any delays into the code execution.
 
 Some of the optimizations:
 
-- **Generational collection** -- objects are split into two sets: "new ones" and "old ones". Many  objects appear, do their job and die fast, they can be cleaned up aggressively. Those that survive for long enough, become "old" and are examined less often.
-- **Incremental collection** -- if there are many objects, and we try to walk and mark the whole object set at once, it may take some time and introduce visible delays in the execution. So the engine tries to split the garbage collection into pieces. Then the pieces are executed one by one, separately. That requires some extra bookkeeping between them to track changes, but we have many tiny delays instead of a big one.
+- **Generational collection** -- objects are split into two sets: "new ones" and "old ones". In typical code, many objects have a short life span: they appear, do their job and die fast, so it makes sense to track new objects and clear the memory from them if that's the case. Those that survive for long enough, become "old" and are examined less often.
+- **Incremental collection** -- if there are many objects, and we try to walk and mark the whole object set at once, it may take some time and introduce visible delays in the execution. So the engine splits the whole set of existing objects into multiple parts. And then clear these parts one after another. There are many small garbage collections instead of a total one. That requires some extra bookkeeping between them to track changes, but we get many tiny delays instead of a big one.
 - **Idle-time collection** -- the garbage collector tries to run only while the CPU is idle, to reduce the possible effect on the execution.
 
 There exist other optimizations and flavours of garbage collection algorithms. As much as I'd like to describe them here, I have to hold off, because different engines implement different tweaks and techniques. And, what's even more important, things change as engines develop, so studying deeper "in advance", without a real need is probably not worth that. Unless, of course, it is a matter of pure interest, then there will be some links for you below.
@@ -199,14 +199,14 @@ The main things to know:
 
 - Garbage collection is performed automatically. We cannot force or prevent it.
 - Objects are retained in memory while they are reachable.
-- Being referenced is not the same as being reachable (from a root): a pack of interlinked objects can become unreachable as a whole.
+- Being referenced is not the same as being reachable (from a root): a pack of interlinked objects can become unreachable as a whole, as we've seen in the example above.
 
 Modern engines implement advanced algorithms of garbage collection.
 
 A general book "The Garbage Collection Handbook: The Art of Automatic Memory Management" (R. Jones et al) covers some of them.
 
-If you are familiar with low-level programming, the more detailed information about V8 garbage collector is in the article [A tour of V8: Garbage Collection](http://jayconrod.com/posts/55/a-tour-of-v8-garbage-collection).
+If you are familiar with low-level programming, more detailed information about V8's garbage collector is in the article [A tour of V8: Garbage Collection](https://jayconrod.com/posts/55/a-tour-of-v8-garbage-collection).
 
-[V8 blog](https://v8.dev/) also publishes articles about changes in memory management from time to time. Naturally, to learn the garbage collection, you'd better prepare by learning about V8 internals in general and read the blog of [Vyacheslav Egorov](http://mrale.ph) who worked as one of V8 engineers. I'm saying: "V8", because it is best covered with articles in the internet. For other engines, many approaches are similar, but garbage collection differs in many aspects.
+The [V8 blog](https://v8.dev/) also publishes articles about changes in memory management from time to time. Naturally, to learn more about garbage collection, you'd better prepare by learning about V8 internals in general and read the blog of [Vyacheslav Egorov](https://mrale.ph) who worked as one of the V8 engineers. I'm saying: "V8", because it is best covered by articles on the internet. For other engines, many approaches are similar, but garbage collection differs in many aspects.
 
-In-depth knowledge of engines is good when you need low-level optimizations. It would be wise to plan that as the next step after you're familiar with the language.  
+In-depth knowledge of engines is good when you need low-level optimizations. It would be wise to plan that as the next step after you're familiar with the language.
diff --git a/1-js/04-object-basics/02-garbage-collection/family-delete-refs.svg b/1-js/04-object-basics/03-garbage-collection/family-delete-refs.svg
similarity index 57%
rename from 1-js/04-object-basics/02-garbage-collection/family-delete-refs.svg
rename to 1-js/04-object-basics/03-garbage-collection/family-delete-refs.svg
index 2ae1f664c..a582ca64b 100644
--- a/1-js/04-object-basics/02-garbage-collection/family-delete-refs.svg
+++ b/1-js/04-object-basics/03-garbage-collection/family-delete-refs.svg
@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="337" height="204" viewBox="0 0 337 204"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:&apos;PT Mono&apos;;font-weight:700;font-style:normal;src:local(&apos;PT MonoBold&apos;),url(/font/PTMonoBold.woff2) format(&apos;woff2&apos;),url(/font/PTMonoBold.woff) format(&apos;woff&apos;),url(/font/PTMonoBold.ttf) format(&apos;truetype&apos;)}</style></defs><g id="garbage-collection" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="family-delete-refs.svg"><path id="Line" fill="#9B9B9B" fill-rule="nonzero" d="M147.5 183.5v6h46v2h-46v6l-14-7 14-7z" opacity=".6"/><path id="Rectangle-1" fill="#FFF9EB" stroke="#E8C48E" stroke-width="2" d="M88 13h151v26H88z"/><text id="&lt;global-variable&gt;" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="92" y="30">&lt;global variable&gt;</tspan></text><path id="Rectangle-2" fill="#FFF9EB" stroke="#BCA68E" stroke-width="2" d="M123 80h78v26h-78z"/><text id="Object" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="139" y="96">Object</tspan></text><path id="Rectangle-3" fill="#FFF9EB" stroke="#BCA68E" stroke-width="2" d="M5 148h118v48H5z"/><text id="Object-2" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="39" y="165">Object</tspan></text><text id="wife" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="147" y="148">wife</tspan></text><text id="family" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="106" y="63">family</tspan></text><text id="name:-&quot;John&quot;" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="19" y="185">name: &quot;John&quot;</tspan></text><path id="Rectangle-4" fill="#FFF9EB" stroke="#BCA68E" stroke-width="2" d="M214 148h118v48H214z"/><text id="name:-&quot;Ann&quot;" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="230" y="185">name: &quot;Ann&quot;</tspan></text><text id="mother" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="242" y="127">mother</tspan></text><text id="Object-3" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="244" y="165">Object</tspan></text><path id="Line" fill="#EE6B47" fill-rule="nonzero" d="M164.5 43.5v18h6l-7 14-7-14h6v-18h2z"/><path id="Line-2" fill="#9B9B9B" fill-rule="nonzero" d="M114.75 111.108l1.142 1.642-.82.57-34.508 24.005 3.426 4.926L68.5 144.5l7.495-13.741 3.426 4.924 34.508-24.004.82-.571z" opacity=".6"/><path id="Line" fill="#EE6B47" fill-rule="nonzero" d="M180.5 149.5l14 7-14 7v-6h-48v-2h48v-6zM208.236 111.11l.827.563 35.427 24.121 3.377-4.96L255.5 144.5l-15.512-2.093 3.377-4.96-35.428-24.12-.826-.563 1.125-1.653z"/><path id="Line-Copy" stroke="#EE6B47" stroke-linecap="square" stroke-width="2" d="M100.5 118.5l-11 14"/><path id="Line-Copy-2" stroke="#EE6B47" stroke-linecap="square" stroke-width="2" d="M89.5 118.5l11 14"/><path id="Line-Copy-4" stroke="#EE6B47" stroke-linecap="square" stroke-width="2" d="M172.5 183.5l-11 14"/><path id="Line-Copy-3" stroke="#EE6B47" stroke-linecap="square" stroke-width="2" d="M161.5 183.5l11 14"/><text id="father" fill="#9B9B9B" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="35" y="127">father</tspan></text><text id="husband" fill="#9B9B9B" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="136" y="181">husband</tspan></text></g></g></svg>
\ No newline at end of file
+<svg xmlns="http://www.w3.org/2000/svg" width="337" height="204" viewBox="0 0 337 204"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:&apos;PT Mono&apos;;font-weight:700;font-style:normal;src:local(&apos;PT MonoBold&apos;),url(/font/PTMonoBold.woff2) format(&apos;woff2&apos;),url(/font/PTMonoBold.woff) format(&apos;woff&apos;),url(/font/PTMonoBold.ttf) format(&apos;truetype&apos;)}</style></defs><g id="garbage-collection" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="family-delete-refs.svg"><path id="Line" fill="#7E7C7B" fill-rule="nonzero" d="M147.5 183.5v6h46v2h-46v6l-14-7 14-7z" opacity=".6"/><path id="Rectangle-1" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M88 13h151v26H88z"/><text id="&lt;global-variable&gt;" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="92" y="30">&lt;global variable&gt;</tspan></text><path id="Rectangle-2" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M123 80h78v26h-78z"/><text id="Object" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="139" y="96">Object</tspan></text><path id="Rectangle-3" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M5 148h118v48H5z"/><text id="Object-2" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="39" y="165">Object</tspan></text><text id="wife" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="147" y="148">wife</tspan></text><text id="family" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="106" y="63">family</tspan></text><text id="name:-&quot;John&quot;" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="19" y="185">name: &quot;John&quot;</tspan></text><path id="Rectangle-4" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M214 148h118v48H214z"/><text id="name:-&quot;Ann&quot;" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="230" y="185">name: &quot;Ann&quot;</tspan></text><text id="mother" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="242" y="127">mother</tspan></text><text id="Object-3" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="244" y="165">Object</tspan></text><path id="Line" fill="#C06334" fill-rule="nonzero" d="M164.5 43.5v18h6l-7 14-7-14h6v-18h2z"/><path id="Line-2" fill="#7E7C7B" fill-rule="nonzero" d="M114.75 111.108l1.142 1.642-.82.57-34.508 24.005 3.426 4.926L68.5 144.5l7.495-13.741 3.426 4.924 34.508-24.004.82-.571z" opacity=".6"/><path id="Line" fill="#C06334" fill-rule="nonzero" d="M180.5 149.5l14 7-14 7v-6h-48v-2h48v-6zM208.236 111.11l.827.563 35.427 24.121 3.377-4.96L255.5 144.5l-15.512-2.093 3.377-4.96-35.428-24.12-.826-.563 1.125-1.653z"/><path id="Line-Copy" stroke="#C06334" stroke-linecap="square" stroke-width="2" d="M100.5 118.5l-11 14"/><path id="Line-Copy-2" stroke="#C06334" stroke-linecap="square" stroke-width="2" d="M89.5 118.5l11 14"/><path id="Line-Copy-4" stroke="#C06334" stroke-linecap="square" stroke-width="2" d="M172.5 183.5l-11 14"/><path id="Line-Copy-3" stroke="#C06334" stroke-linecap="square" stroke-width="2" d="M161.5 183.5l11 14"/><text id="father" fill="#7E7C7B" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="35" y="127">father</tspan></text><text id="husband" fill="#7E7C7B" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="136" y="181">husband</tspan></text></g></g></svg>
\ No newline at end of file
diff --git a/1-js/04-object-basics/02-garbage-collection/family-no-family.svg b/1-js/04-object-basics/03-garbage-collection/family-no-family.svg
similarity index 67%
rename from 1-js/04-object-basics/02-garbage-collection/family-no-family.svg
rename to 1-js/04-object-basics/03-garbage-collection/family-no-family.svg
index 655d1982e..c73dd6a48 100644
--- a/1-js/04-object-basics/02-garbage-collection/family-no-family.svg
+++ b/1-js/04-object-basics/03-garbage-collection/family-no-family.svg
@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="420" height="279" viewBox="0 0 420 279"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:&apos;PT Mono&apos;;font-weight:700;font-style:normal;src:local(&apos;PT MonoBold&apos;),url(/font/PTMonoBold.woff2) format(&apos;woff2&apos;),url(/font/PTMonoBold.woff) format(&apos;woff&apos;),url(/font/PTMonoBold.ttf) format(&apos;truetype&apos;)}</style></defs><g id="garbage-collection" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="family-no-family.svg"><path id="Line" fill="#EE6B47" fill-rule="nonzero" d="M211.5 228.5v6h46v2h-46v6l-14-7 14-7z"/><path id="Rectangle-1" fill="#FFF9EB" stroke="#E8C48E" stroke-width="2" d="M153 25h153v48H153z"/><text id="&lt;global&gt;" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="199" y="43">&lt;global&gt;</tspan></text><path id="Rectangle-2" fill="#FFF9EB" stroke="#BCA68E" stroke-width="2" d="M187 123h78v26h-78z"/><text id="Object" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="203" y="139">Object</tspan></text><path id="Rectangle-3" fill="#FFF9EB" stroke="#BCA68E" stroke-width="2" d="M69 193h118v48H69z"/><text id="Object-2" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="103" y="210">Object</tspan></text><text id="father" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="99" y="170">father</tspan></text><text id="wife" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="211" y="193">wife</tspan></text><text id="name:-&quot;John&quot;" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="83" y="230">name: &quot;John&quot;</tspan></text><path id="Rectangle-4" fill="#FFF9EB" stroke="#BCA68E" stroke-width="2" d="M278 193h118v48H278z"/><text id="name:-&quot;Ann&quot;" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="294" y="230">name: &quot;Ann&quot;</tspan></text><text id="mother" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="306" y="170">mother</tspan></text><text id="Object-3" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="308" y="210">Object</tspan></text><path id="Line-2" fill="#EE6B47" fill-rule="nonzero" d="M178.75 154.108l1.142 1.642-.82.57-34.508 24.005 3.426 4.926-15.49 2.249 7.495-13.741 3.426 4.924 34.508-24.004.82-.571z"/><path id="Line" fill="#EE6B47" fill-rule="nonzero" d="M244.5 194.5l14 7-14 7v-6h-48v-2h48v-6z"/><text id="husband" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="200" y="226">husband</tspan></text><path id="Line" fill="#EE6B47" fill-rule="nonzero" d="M272.236 154.11l.827.563 35.427 24.121 3.377-4.96L319.5 187.5l-15.512-2.093 3.377-4.96-35.428-24.12-.826-.563 1.125-1.653z"/><path id="Rectangle-5" stroke="#D0021B" stroke-width="2" d="M48 112h364v150H48z"/><text id="family:-null" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="183" y="66">family: null</tspan></text><g id="noun_48910_cc" transform="translate(8 110)"><path id="Shape" d="M17.503 1.75h-5.006a.341.341 0 00-.34.342v1.125h5.686V2.092a.341.341 0 00-.34-.341z"/><path id="Shape" fill="#D0021B" d="M28.364 3.217H19.59V2.092A2.09 2.09 0 0017.503 0h-5.006c-1.15 0-2.087.938-2.087 2.092v1.125H1.637c-.7 0-1.266.568-1.266 1.269v.09c0 .7.567 1.267 1.266 1.267h26.727c.699 0 1.266-.567 1.266-1.268v-.09c0-.7-.567-1.268-1.266-1.268zm-10.52 0h-5.687V2.092c0-.188.153-.341.34-.341h5.006a.34.34 0 01.34.34v1.126zM26.054 6.281H3.728c-1.298 0-2.35-.224-2.35 1.077L3.14 33.196c0 1.3 1.052 2.409 2.35 2.409h18.802c1.298 0 2.35-1.11 2.35-2.409l1.763-25.838c0-1.301-1.053-1.077-2.35-1.077zM9.637 32.193c-.377.012-.691-.261-.704-.612l-.694-19.917c-.012-.351.283-.647.66-.66.376-.013.69.261.703.613l.694 19.916c.013.351-.283.647-.659.66zm6.044-.63c0 .352-.306.637-.682.637-.377 0-.682-.286-.682-.637V11.634c0-.351.305-.636.682-.636.376 0 .682.285.682.636v19.93zm5.384.018c-.012.351-.327.625-.704.612-.376-.013-.672-.308-.66-.66l.695-19.916c.012-.352.326-.626.703-.613.377.014.672.309.66.66l-.694 19.917z"/></g></g></g></svg>
\ No newline at end of file
+<svg xmlns="http://www.w3.org/2000/svg" width="420" height="279" viewBox="0 0 420 279"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:&apos;PT Mono&apos;;font-weight:700;font-style:normal;src:local(&apos;PT MonoBold&apos;),url(/font/PTMonoBold.woff2) format(&apos;woff2&apos;),url(/font/PTMonoBold.woff) format(&apos;woff&apos;),url(/font/PTMonoBold.ttf) format(&apos;truetype&apos;)}</style></defs><g id="garbage-collection" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="family-no-family.svg"><path id="Line" fill="#C06334" fill-rule="nonzero" d="M211.5 228.5v6h46v2h-46v6l-14-7 14-7z"/><path id="Rectangle-1" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M153 25h153v48H153z"/><text id="&lt;global&gt;" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="199" y="43">&lt;global&gt;</tspan></text><path id="Rectangle-2" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M187 123h78v26h-78z"/><text id="Object" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="203" y="139">Object</tspan></text><path id="Rectangle-3" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M69 193h118v48H69z"/><text id="Object-2" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="103" y="210">Object</tspan></text><text id="father" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="99" y="170">father</tspan></text><text id="wife" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="211" y="193">wife</tspan></text><text id="name:-&quot;John&quot;" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="83" y="230">name: &quot;John&quot;</tspan></text><path id="Rectangle-4" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M278 193h118v48H278z"/><text id="name:-&quot;Ann&quot;" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="294" y="230">name: &quot;Ann&quot;</tspan></text><text id="mother" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="306" y="170">mother</tspan></text><text id="Object-3" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="308" y="210">Object</tspan></text><path id="Line-2" fill="#C06334" fill-rule="nonzero" d="M178.75 154.108l1.142 1.642-.82.57-34.508 24.005 3.426 4.926-15.49 2.249 7.495-13.741 3.426 4.924 34.508-24.004.82-.571z"/><path id="Line" fill="#C06334" fill-rule="nonzero" d="M244.5 194.5l14 7-14 7v-6h-48v-2h48v-6z"/><text id="husband" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="200" y="226">husband</tspan></text><path id="Line" fill="#C06334" fill-rule="nonzero" d="M272.236 154.11l.827.563 35.427 24.121 3.377-4.96L319.5 187.5l-15.512-2.093 3.377-4.96-35.428-24.12-.826-.563 1.125-1.653z"/><path id="Rectangle-5" stroke="#A7333A" stroke-width="2" d="M48 112h364v150H48z"/><text id="family:-null" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="183" y="66">family: null</tspan></text><g id="noun_48910_cc" transform="translate(8 110)"><path id="Shape" d="M17.503 1.75h-5.006a.341.341 0 00-.34.342v1.125h5.686V2.092a.341.341 0 00-.34-.341z"/><path id="Shape" fill="#A7333A" d="M28.364 3.217H19.59V2.092A2.09 2.09 0 0017.503 0h-5.006c-1.15 0-2.087.938-2.087 2.092v1.125H1.637c-.7 0-1.266.568-1.266 1.269v.09c0 .7.567 1.267 1.266 1.267h26.727c.699 0 1.266-.567 1.266-1.268v-.09c0-.7-.567-1.268-1.266-1.268zm-10.52 0h-5.687V2.092c0-.188.153-.341.34-.341h5.006a.34.34 0 01.34.34v1.126zM26.054 6.281H3.728c-1.298 0-2.35-.224-2.35 1.077L3.14 33.196c0 1.3 1.052 2.409 2.35 2.409h18.802c1.298 0 2.35-1.11 2.35-2.409l1.763-25.838c0-1.301-1.053-1.077-2.35-1.077zM9.637 32.193c-.377.012-.691-.261-.704-.612l-.694-19.917c-.012-.351.283-.647.66-.66.376-.013.69.261.703.613l.694 19.916c.013.351-.283.647-.659.66zm6.044-.63c0 .352-.306.637-.682.637-.377 0-.682-.286-.682-.637V11.634c0-.351.305-.636.682-.636.376 0 .682.285.682.636v19.93zm5.384.018c-.012.351-.327.625-.704.612-.376-.013-.672-.308-.66-.66l.695-19.916c.012-.352.326-.626.703-.613.377.014.672.309.66.66l-.694 19.917z"/></g></g></g></svg>
\ No newline at end of file
diff --git a/1-js/04-object-basics/02-garbage-collection/family-no-father-2.svg b/1-js/04-object-basics/03-garbage-collection/family-no-father-2.svg
similarity index 61%
rename from 1-js/04-object-basics/02-garbage-collection/family-no-father-2.svg
rename to 1-js/04-object-basics/03-garbage-collection/family-no-father-2.svg
index 11f4ada35..6bd13c0e8 100644
--- a/1-js/04-object-basics/02-garbage-collection/family-no-father-2.svg
+++ b/1-js/04-object-basics/03-garbage-collection/family-no-father-2.svg
@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="144" height="225" viewBox="0 0 144 225"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:&apos;PT Mono&apos;;font-weight:700;font-style:normal;src:local(&apos;PT MonoBold&apos;),url(/font/PTMonoBold.woff2) format(&apos;woff2&apos;),url(/font/PTMonoBold.woff) format(&apos;woff&apos;),url(/font/PTMonoBold.ttf) format(&apos;truetype&apos;)}</style></defs><g id="garbage-collection" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="family-no-father-2.svg"><path id="Rectangle-2" fill="#FFF9EB" stroke="#BCA68E" stroke-width="2" d="M34 91h78v26H34z"/><text id="Object" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="50" y="107">Object</tspan></text><text id="family" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="15" y="67">family</tspan></text><path id="Rectangle-4" fill="#FFF9EB" stroke="#BCA68E" stroke-width="2" d="M16 166h118v48H16z"/><text id="name:-&quot;Ann&quot;" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="34" y="203">name: &quot;Ann&quot;</tspan></text><text id="mother" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="16" y="142">mother</tspan></text><text id="Object-3" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="48" y="183">Object</tspan></text><path id="Line" fill="#EE6B47" fill-rule="nonzero" d="M75.5 47.5v18h6l-7 14-7-14h6v-18h2zM74.5 122.5v19h6l-7 14-7-14h6v-19h2z"/><path id="Rectangle-1" fill="#FFF9EB" stroke="#E8C48E" stroke-width="2" d="M27 16h93v26H27z"/><text id="&lt;global&gt;" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="43" y="33">&lt;global&gt;</tspan></text></g></g></svg>
\ No newline at end of file
+<svg xmlns="http://www.w3.org/2000/svg" width="144" height="225" viewBox="0 0 144 225"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:&apos;PT Mono&apos;;font-weight:700;font-style:normal;src:local(&apos;PT MonoBold&apos;),url(/font/PTMonoBold.woff2) format(&apos;woff2&apos;),url(/font/PTMonoBold.woff) format(&apos;woff&apos;),url(/font/PTMonoBold.ttf) format(&apos;truetype&apos;)}</style></defs><g id="garbage-collection" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="family-no-father-2.svg"><path id="Rectangle-2" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M34 91h78v26H34z"/><text id="Object" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="50" y="107">Object</tspan></text><text id="family" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="15" y="67">family</tspan></text><path id="Rectangle-4" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M16 166h118v48H16z"/><text id="name:-&quot;Ann&quot;" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="34" y="203">name: &quot;Ann&quot;</tspan></text><text id="mother" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="16" y="142">mother</tspan></text><text id="Object-3" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="48" y="183">Object</tspan></text><path id="Line" fill="#C06334" fill-rule="nonzero" d="M75.5 47.5v18h6l-7 14-7-14h6v-18h2zM74.5 122.5v19h6l-7 14-7-14h6v-19h2z"/><path id="Rectangle-1" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M27 16h93v26H27z"/><text id="&lt;global&gt;" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="43" y="33">&lt;global&gt;</tspan></text></g></g></svg>
\ No newline at end of file
diff --git a/1-js/04-object-basics/02-garbage-collection/family-no-father.svg b/1-js/04-object-basics/03-garbage-collection/family-no-father.svg
similarity index 68%
rename from 1-js/04-object-basics/02-garbage-collection/family-no-father.svg
rename to 1-js/04-object-basics/03-garbage-collection/family-no-father.svg
index b76c868e0..fd1f20607 100644
--- a/1-js/04-object-basics/02-garbage-collection/family-no-father.svg
+++ b/1-js/04-object-basics/03-garbage-collection/family-no-father.svg
@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="399" height="225" viewBox="0 0 399 225"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:&apos;PT Mono&apos;;font-weight:700;font-style:normal;src:local(&apos;PT MonoBold&apos;),url(/font/PTMonoBold.woff2) format(&apos;woff2&apos;),url(/font/PTMonoBold.woff) format(&apos;woff&apos;),url(/font/PTMonoBold.ttf) format(&apos;truetype&apos;)}</style></defs><g id="garbage-collection" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="family-no-father.svg"><path id="Rectangle-2" fill="#FFF9EB" stroke="#BCA68E" stroke-width="2" d="M187 78h78v26h-78z"/><text id="Object" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="203" y="94">Object</tspan></text><path id="Rectangle-3" fill="#FFF9EB" stroke="#BCA68E" stroke-width="2" d="M69 146h118v48H69z"/><text id="Object-2" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="103" y="163">Object</tspan></text><text id="wife" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="211" y="146">wife</tspan></text><text id="family" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="171" y="61">family</tspan></text><text id="name:-&quot;John&quot;" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="83" y="183">name: &quot;John&quot;</tspan></text><path id="Rectangle-4" fill="#FFF9EB" stroke="#BCA68E" stroke-width="2" d="M278 146h118v48H278z"/><text id="name:-&quot;Ann&quot;" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="299" y="183">name: &quot;Ann&quot;</tspan></text><text id="mother" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="306" y="125">mother</tspan></text><text id="Object-3" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="308" y="163">Object</tspan></text><path id="Line" fill="#EE6B47" fill-rule="nonzero" d="M228.5 41.5v18h6l-7 14-7-14h6v-18h2zM244.5 147.5l14 7-14 7v-6h-48v-2h48v-6zM272.236 109.11l.827.563 35.427 24.121 3.377-4.96L319.5 142.5l-15.512-2.093 3.377-4.96-35.428-24.12-.826-.563 1.125-1.653z"/><path id="Rectangle-5" stroke="#D0021B" stroke-width="2" d="M48 117h217v99H48z"/><g id="noun_48910_cc" transform="translate(7 114)"><path id="Shape" d="M17.503 1.75h-5.006a.341.341 0 00-.34.342v1.125h5.686V2.092a.341.341 0 00-.34-.341z"/><path id="Shape" fill="#D0021B" d="M28.364 3.217H19.59V2.092A2.09 2.09 0 0017.503 0h-5.006c-1.15 0-2.087.938-2.087 2.092v1.125H1.637c-.7 0-1.266.568-1.266 1.269v.09c0 .7.567 1.267 1.266 1.267h26.727c.699 0 1.266-.567 1.266-1.268v-.09c0-.7-.567-1.268-1.266-1.268zm-10.52 0h-5.687V2.092c0-.188.153-.341.34-.341h5.006a.34.34 0 01.34.34v1.126zM26.054 6.281H3.728c-1.298 0-2.35-.224-2.35 1.077L3.14 33.196c0 1.3 1.052 2.409 2.35 2.409h18.802c1.298 0 2.35-1.11 2.35-2.409l1.763-25.838c0-1.301-1.053-1.077-2.35-1.077zM9.637 32.193c-.377.012-.691-.261-.704-.612l-.694-19.917c-.012-.351.283-.647.66-.66.376-.013.69.261.703.613l.694 19.916c.013.351-.283.647-.659.66zm6.044-.63c0 .352-.306.637-.682.637-.377 0-.682-.286-.682-.637V11.634c0-.351.305-.636.682-.636.376 0 .682.285.682.636v19.93zm5.384.018c-.012.351-.327.625-.704.612-.376-.013-.672-.308-.66-.66l.695-19.916c.012-.352.326-.626.703-.613.377.014.672.309.66.66l-.694 19.917z"/></g><path id="Rectangle-1" fill="#FFF9EB" stroke="#E8C48E" stroke-width="2" d="M181 13h93v26h-93z"/><text id="&lt;global&gt;" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="197" y="30">&lt;global&gt;</tspan></text></g></g></svg>
\ No newline at end of file
+<svg xmlns="http://www.w3.org/2000/svg" width="399" height="225" viewBox="0 0 399 225"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:&apos;PT Mono&apos;;font-weight:700;font-style:normal;src:local(&apos;PT MonoBold&apos;),url(/font/PTMonoBold.woff2) format(&apos;woff2&apos;),url(/font/PTMonoBold.woff) format(&apos;woff&apos;),url(/font/PTMonoBold.ttf) format(&apos;truetype&apos;)}</style></defs><g id="garbage-collection" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="family-no-father.svg"><path id="Rectangle-2" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M187 78h78v26h-78z"/><text id="Object" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="203" y="94">Object</tspan></text><path id="Rectangle-3" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M69 146h118v48H69z"/><text id="Object-2" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="103" y="163">Object</tspan></text><text id="wife" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="211" y="146">wife</tspan></text><text id="family" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="171" y="61">family</tspan></text><text id="name:-&quot;John&quot;" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="83" y="183">name: &quot;John&quot;</tspan></text><path id="Rectangle-4" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M278 146h118v48H278z"/><text id="name:-&quot;Ann&quot;" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="299" y="183">name: &quot;Ann&quot;</tspan></text><text id="mother" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="306" y="125">mother</tspan></text><text id="Object-3" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="308" y="163">Object</tspan></text><path id="Line" fill="#C06334" fill-rule="nonzero" d="M228.5 41.5v18h6l-7 14-7-14h6v-18h2zM244.5 147.5l14 7-14 7v-6h-48v-2h48v-6zM272.236 109.11l.827.563 35.427 24.121 3.377-4.96L319.5 142.5l-15.512-2.093 3.377-4.96-35.428-24.12-.826-.563 1.125-1.653z"/><path id="Rectangle-5" stroke="#A7333A" stroke-width="2" d="M48 117h217v99H48z"/><g id="noun_48910_cc" transform="translate(7 114)"><path id="Shape" d="M17.503 1.75h-5.006a.341.341 0 00-.34.342v1.125h5.686V2.092a.341.341 0 00-.34-.341z"/><path id="Shape" fill="#A7333A" d="M28.364 3.217H19.59V2.092A2.09 2.09 0 0017.503 0h-5.006c-1.15 0-2.087.938-2.087 2.092v1.125H1.637c-.7 0-1.266.568-1.266 1.269v.09c0 .7.567 1.267 1.266 1.267h26.727c.699 0 1.266-.567 1.266-1.268v-.09c0-.7-.567-1.268-1.266-1.268zm-10.52 0h-5.687V2.092c0-.188.153-.341.34-.341h5.006a.34.34 0 01.34.34v1.126zM26.054 6.281H3.728c-1.298 0-2.35-.224-2.35 1.077L3.14 33.196c0 1.3 1.052 2.409 2.35 2.409h18.802c1.298 0 2.35-1.11 2.35-2.409l1.763-25.838c0-1.301-1.053-1.077-2.35-1.077zM9.637 32.193c-.377.012-.691-.261-.704-.612l-.694-19.917c-.012-.351.283-.647.66-.66.376-.013.69.261.703.613l.694 19.916c.013.351-.283.647-.659.66zm6.044-.63c0 .352-.306.637-.682.637-.377 0-.682-.286-.682-.637V11.634c0-.351.305-.636.682-.636.376 0 .682.285.682.636v19.93zm5.384.018c-.012.351-.327.625-.704.612-.376-.013-.672-.308-.66-.66l.695-19.916c.012-.352.326-.626.703-.613.377.014.672.309.66.66l-.694 19.917z"/></g><path id="Rectangle-1" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M181 13h93v26h-93z"/><text id="&lt;global&gt;" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="197" y="30">&lt;global&gt;</tspan></text></g></g></svg>
\ No newline at end of file
diff --git a/1-js/04-object-basics/02-garbage-collection/family.svg b/1-js/04-object-basics/03-garbage-collection/family.svg
similarity index 56%
rename from 1-js/04-object-basics/02-garbage-collection/family.svg
rename to 1-js/04-object-basics/03-garbage-collection/family.svg
index bec2f4ddc..fd0534874 100644
--- a/1-js/04-object-basics/02-garbage-collection/family.svg
+++ b/1-js/04-object-basics/03-garbage-collection/family.svg
@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="337" height="204" viewBox="0 0 337 204"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:&apos;PT Mono&apos;;font-weight:700;font-style:normal;src:local(&apos;PT MonoBold&apos;),url(/font/PTMonoBold.woff2) format(&apos;woff2&apos;),url(/font/PTMonoBold.woff) format(&apos;woff&apos;),url(/font/PTMonoBold.ttf) format(&apos;truetype&apos;)}</style></defs><g id="garbage-collection" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="family.svg"><path id="Line" fill="#EE6B47" fill-rule="nonzero" d="M147.5 183.5v6h46v2h-46v6l-14-7 14-7z"/><path id="Rectangle-2" fill="#FFF9EB" stroke="#BCA68E" stroke-width="2" d="M123 80h78v26h-78z"/><text id="Object" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="139" y="96">Object</tspan></text><path id="Rectangle-3" fill="#FFF9EB" stroke="#BCA68E" stroke-width="2" d="M5 148h118v48H5z"/><text id="Object-2" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="39" y="165">Object</tspan></text><text id="father" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="35" y="127">father</tspan></text><text id="wife" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="147" y="148">wife</tspan></text><text id="family" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="107" y="63">family</tspan></text><text id="name:-&quot;John&quot;" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="19" y="185">name: &quot;John&quot;</tspan></text><path id="Rectangle-4" fill="#FFF9EB" stroke="#BCA68E" stroke-width="2" d="M214 148h118v48H214z"/><text id="name:-&quot;Ann&quot;" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="230" y="185">name: &quot;Ann&quot;</tspan></text><text id="mother" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="242" y="127">mother</tspan></text><text id="Object-3" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="244" y="165">Object</tspan></text><path id="Line" fill="#EE6B47" fill-rule="nonzero" d="M164.5 43.5v18h6l-7 14-7-14h6v-18h2z"/><path id="Line-2" fill="#EE6B47" fill-rule="nonzero" d="M114.75 111.108l1.142 1.642-.82.57-34.508 24.005 3.426 4.926L68.5 144.5l7.495-13.741 3.426 4.924 34.508-24.004.82-.571z"/><path id="Line" fill="#EE6B47" fill-rule="nonzero" d="M180.5 149.5l14 7-14 7v-6h-48v-2h48v-6z"/><text id="husband" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="136" y="181">husband</tspan></text><path id="Line" fill="#EE6B47" fill-rule="nonzero" d="M208.236 111.11l.827.563 35.427 24.121 3.377-4.96L255.5 144.5l-15.512-2.093 3.377-4.96-35.428-24.12-.826-.563 1.125-1.653z"/><path id="Rectangle-1" fill="#FFF9EB" stroke="#E8C48E" stroke-width="2" d="M88 13h151v26H88z"/><text id="&lt;global-variable&gt;" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="92" y="30">&lt;global variable&gt;</tspan></text></g></g></svg>
\ No newline at end of file
+<svg xmlns="http://www.w3.org/2000/svg" width="337" height="204" viewBox="0 0 337 204"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:&apos;PT Mono&apos;;font-weight:700;font-style:normal;src:local(&apos;PT MonoBold&apos;),url(/font/PTMonoBold.woff2) format(&apos;woff2&apos;),url(/font/PTMonoBold.woff) format(&apos;woff&apos;),url(/font/PTMonoBold.ttf) format(&apos;truetype&apos;)}</style></defs><g id="garbage-collection" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="family.svg"><path id="Line" fill="#C06334" fill-rule="nonzero" d="M147.5 183.5v6h46v2h-46v6l-14-7 14-7z"/><path id="Rectangle-2" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M123 80h78v26h-78z"/><text id="Object" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="139" y="96">Object</tspan></text><path id="Rectangle-3" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M5 148h118v48H5z"/><text id="Object-2" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="39" y="165">Object</tspan></text><text id="father" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="35" y="127">father</tspan></text><text id="wife" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="147" y="148">wife</tspan></text><text id="family" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="107" y="63">family</tspan></text><text id="name:-&quot;John&quot;" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="19" y="185">name: &quot;John&quot;</tspan></text><path id="Rectangle-4" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M214 148h118v48H214z"/><text id="name:-&quot;Ann&quot;" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="230" y="185">name: &quot;Ann&quot;</tspan></text><text id="mother" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="242" y="127">mother</tspan></text><text id="Object-3" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="244" y="165">Object</tspan></text><path id="Line" fill="#C06334" fill-rule="nonzero" d="M164.5 43.5v18h6l-7 14-7-14h6v-18h2z"/><path id="Line-2" fill="#C06334" fill-rule="nonzero" d="M114.75 111.108l1.142 1.642-.82.57-34.508 24.005 3.426 4.926L68.5 144.5l7.495-13.741 3.426 4.924 34.508-24.004.82-.571z"/><path id="Line" fill="#C06334" fill-rule="nonzero" d="M180.5 149.5l14 7-14 7v-6h-48v-2h48v-6z"/><text id="husband" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="136" y="181">husband</tspan></text><path id="Line" fill="#C06334" fill-rule="nonzero" d="M208.236 111.11l.827.563 35.427 24.121 3.377-4.96L255.5 144.5l-15.512-2.093 3.377-4.96-35.428-24.12-.826-.563 1.125-1.653z"/><path id="Rectangle-1" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M88 13h151v26H88z"/><text id="&lt;global-variable&gt;" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="92" y="30">&lt;global variable&gt;</tspan></text></g></g></svg>
\ No newline at end of file
diff --git a/1-js/04-object-basics/03-garbage-collection/garbage-collection-1.svg b/1-js/04-object-basics/03-garbage-collection/garbage-collection-1.svg
new file mode 100644
index 000000000..5cac52e9a
--- /dev/null
+++ b/1-js/04-object-basics/03-garbage-collection/garbage-collection-1.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="463" height="204" viewBox="0 0 463 204"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:&apos;PT Mono&apos;;font-weight:700;font-style:normal;src:local(&apos;PT MonoBold&apos;),url(/font/PTMonoBold.woff2) format(&apos;woff2&apos;),url(/font/PTMonoBold.woff) format(&apos;woff&apos;),url(/font/PTMonoBold.ttf) format(&apos;truetype&apos;)}</style></defs><defs><path id="path-1" d="M0 0h80v28H0z"/><path id="path-3" d="M0 0h40v20H0z"/><path id="path-5" d="M0 0h40v20H0z"/><path id="path-7" d="M0 0h40v20H0z"/><path id="path-9" d="M0 0h40v20H0z"/><path id="path-11" d="M0 0h40v20H0z"/><path id="path-13" d="M0 0h40v20H0z"/><path id="path-15" d="M0 0h40v20H0z"/><path id="path-17" d="M0 0h40v20H0z"/><path id="path-19" d="M0 0h40v20H0z"/><path id="path-21" d="M0 0h40v20H0z"/><path id="path-23" d="M0 0h40v20H0z"/></defs><g id="garbage-collection" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="garbage-collection-1.svg"><g id="Rectangle-1-Clipped" transform="translate(106 8)"><mask id="mask-2" fill="#fff"><use xlink:href="#path-1"/></mask><g id="Rectangle-1" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-2)"><path id="path-1" d="M0 0h80v28H0z"/></g></g><text id="&lt;global&gt;" fill="#AF6E24" fill-rule="nonzero" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="115" y="26">&lt;global&gt;</tspan></text><g id="Rectangle-2-Clipped" transform="translate(360 99)"><mask id="mask-4" fill="#fff"><use xlink:href="#path-3"/></mask><g id="Rectangle-2" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-4)"><path id="path-3" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-2-Clipped" transform="translate(267 99)"><mask id="mask-6" fill="#fff"><use xlink:href="#path-5"/></mask><g id="Rectangle-2-Copy-2" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-6)"><path id="path-5" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-2-Clipped" transform="translate(126 79)"><mask id="mask-8" fill="#fff"><use xlink:href="#path-7"/></mask><g id="Rectangle-2-Copy-2" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-8)"><path id="path-7" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-Clipped" transform="translate(313 53)"><mask id="mask-10" fill="#fff"><use xlink:href="#path-9"/></mask><g id="Rectangle-2-Copy" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-10)"><path id="path-9" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-3-Clipped" transform="translate(176 129)"><mask id="mask-12" fill="#fff"><use xlink:href="#path-11"/></mask><g id="Rectangle-2-Copy-3" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-12)"><path id="path-11" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-8-Clipped" transform="translate(196 69)"><mask id="mask-14" fill="#fff"><use xlink:href="#path-13"/></mask><g id="Rectangle-2-Copy-8" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-14)"><path id="path-13" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-4-Clipped" transform="translate(128 139)"><mask id="mask-16" fill="#fff"><use xlink:href="#path-15"/></mask><g id="Rectangle-2-Copy-4" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-16)"><path id="path-15" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-5-Clipped" transform="translate(76 131)"><mask id="mask-18" fill="#fff"><use xlink:href="#path-17"/></mask><g id="Rectangle-2-Copy-5" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-18)"><path id="path-17" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-6-Clipped" transform="translate(76 71)"><mask id="mask-20" fill="#fff"><use xlink:href="#path-19"/></mask><g id="Rectangle-2-Copy-6" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-20)"><path id="path-19" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-7-Clipped" transform="translate(27 57)"><mask id="mask-22" fill="#fff"><use xlink:href="#path-21"/></mask><g id="Rectangle-2-Copy-7" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-22)"><path id="path-21" d="M0 0h40v20H0z"/></g></g><path id="Line" fill="#C06334" stroke="#C06334" stroke-width="2" d="M148.5 40.5v31"/><path id="Line-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M148.5 71.5l3-10.8h-6z"/><path id="Line-Copy" fill="#C06334" stroke="#C06334" stroke-width="2" d="M148.5 105.5v24"/><path id="Line-Copy-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M148.5 129.5l3-10.8h-6z"/><path id="Line-2" fill="#C06334" stroke="#C06334" stroke-width="2" d="M319.5 77.5l-19 16"/><path id="Line-2-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M300.5 93.5l10.193-4.662-3.864-4.59z"/><path id="Line-2" fill="#C06334" stroke="#C06334" stroke-width="2" d="M127.5 47.5l-19 16"/><path id="Line-2-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M108.5 63.5l10.193-4.662-3.864-4.59z"/><path id="Line-2-Copy-2" fill="#C06334" stroke="#C06334" stroke-width="2" d="M97.5 42.5l-23 9"/><path id="Line-2-Copy-2-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M74.5 51.5l11.15-1.142-2.186-5.587z"/><path id="Line-2-Copy" fill="#C06334" stroke="#C06334" stroke-width="2" d="M133.5 107.5l-19 16"/><path id="Line-2-Copy-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M114.5 123.5l10.193-4.662-3.864-4.59z"/><path id="Line" fill="#C06334" stroke="#C06334" stroke-width="2" d="M313.071 109.5h39.354"/><path id="Line-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M352.425 109.5l-10.8-3v6z"/><path id="Line" fill="#C06334" stroke="#C06334" stroke-width="2" d="M170.5 107.5l18 15"/><path id="Line-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M188.5 122.5l-6.376-9.219-3.841 4.61z"/><path id="Line-Copy-6" fill="#C06334" stroke="#C06334" stroke-width="2" d="M202.5 154.5l18 15"/><path id="Line-Copy-6-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M220.5 169.5l-6.376-9.219-3.841 4.61z"/><path id="Line-Copy-5" fill="#C06334" stroke="#C06334" stroke-width="2" d="M170.5 87.5l20-7"/><path id="Line-Copy-5-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M190.5 80.5l-11.185.736 1.982 5.663z"/><path id="Line-Copy-4" fill="#C06334" stroke="#C06334" stroke-width="2" d="M209.5 120.5l14-22"/><path id="Line-Copy-4-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M223.5 98.5l-8.33 7.5 5.063 3.222z"/><path id="Line-Copy-3" fill="#C06334" stroke="#C06334" stroke-width="2" d="M46.5 82.5l32 40"/><path id="Line-Copy-3-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M78.5 122.5l-4.404-10.307-4.685 3.748z"/><g id="Rectangle-2-Copy-9-Clipped" transform="translate(219 177)"><mask id="mask-24" fill="#fff"><use xlink:href="#path-23"/></mask><g id="Rectangle-2-Copy-9" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-24)"><path id="path-25" d="M0 0h40v20H0z"/></g></g><path id="Line-Copy-2" fill="#C06334" stroke="#C06334" stroke-width="2" d="M187.5 41.5l21 21"/><path id="Line-Copy-2-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M208.5 62.5l-5.515-9.758-4.243 4.243z"/><path id="Line-Copy" fill="#C06334" fill-rule="nonzero" d="M357.5 79.5l14.212 6.56-4.686 3.747 3.255 4.068.625.781-1.562 1.25-.625-.781-3.255-4.069-4.684 3.749L357.5 79.5z"/></g></g></svg>
\ No newline at end of file
diff --git a/1-js/04-object-basics/03-garbage-collection/garbage-collection-2.svg b/1-js/04-object-basics/03-garbage-collection/garbage-collection-2.svg
new file mode 100644
index 000000000..7dd3a693a
--- /dev/null
+++ b/1-js/04-object-basics/03-garbage-collection/garbage-collection-2.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="463" height="204" viewBox="0 0 463 204"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:&apos;PT Mono&apos;;font-weight:700;font-style:normal;src:local(&apos;PT MonoBold&apos;),url(/font/PTMonoBold.woff2) format(&apos;woff2&apos;),url(/font/PTMonoBold.woff) format(&apos;woff&apos;),url(/font/PTMonoBold.ttf) format(&apos;truetype&apos;)}</style></defs><defs><path id="path-1" d="M0 0h80v28H0z"/><path id="path-3" d="M0 0h40v20H0z"/><path id="path-5" d="M0 0h40v20H0z"/><path id="path-7" d="M0 0h40v20H0z"/><path id="path-9" d="M0 0h40v20H0z"/><path id="path-11" d="M0 0h40v20H0z"/><path id="path-13" d="M0 0h40v20H0z"/><path id="path-15" d="M0 0h40v20H0z"/><path id="path-17" d="M0 0h40v20H0z"/><path id="path-19" d="M0 0h40v20H0z"/><path id="path-21" d="M0 0h40v20H0z"/><path id="path-23" d="M0 0h40v20H0z"/></defs><g id="garbage-collection" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="garbage-collection-2.svg"><g id="Rectangle-1-Clipped" transform="translate(106 8)"><mask id="mask-2" fill="#fff"><use xlink:href="#path-1"/></mask><g id="Rectangle-1" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-2)"><path id="path-1" d="M0 0h80v28H0z"/></g></g><text id="&lt;global&gt;" fill="#AF6E24" fill-rule="nonzero" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="115" y="26">&lt;global&gt;</tspan></text><g id="Rectangle-2-Clipped" transform="translate(360 99)"><mask id="mask-4" fill="#fff"><use xlink:href="#path-3"/></mask><g id="Rectangle-2" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-4)"><path id="path-3" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-2-Clipped" transform="translate(267 99)"><mask id="mask-6" fill="#fff"><use xlink:href="#path-5"/></mask><g id="Rectangle-2-Copy-2" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-6)"><path id="path-5" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-2-Clipped" transform="translate(126 79)"><mask id="mask-8" fill="#fff"><use xlink:href="#path-7"/></mask><g id="Rectangle-2-Copy-2" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-8)"><path id="path-7" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-Clipped" transform="translate(313 53)"><mask id="mask-10" fill="#fff"><use xlink:href="#path-9"/></mask><g id="Rectangle-2-Copy" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-10)"><path id="path-9" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-3-Clipped" transform="translate(176 129)"><mask id="mask-12" fill="#fff"><use xlink:href="#path-11"/></mask><g id="Rectangle-2-Copy-3" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-12)"><path id="path-11" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-8-Clipped" transform="translate(196 69)"><mask id="mask-14" fill="#fff"><use xlink:href="#path-13"/></mask><g id="Rectangle-2-Copy-8" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-14)"><path id="path-13" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-4-Clipped" transform="translate(128 139)"><mask id="mask-16" fill="#fff"><use xlink:href="#path-15"/></mask><g id="Rectangle-2-Copy-4" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-16)"><path id="path-15" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-5-Clipped" transform="translate(76 131)"><mask id="mask-18" fill="#fff"><use xlink:href="#path-17"/></mask><g id="Rectangle-2-Copy-5" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-18)"><path id="path-17" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-6-Clipped" transform="translate(76 71)"><mask id="mask-20" fill="#fff"><use xlink:href="#path-19"/></mask><g id="Rectangle-2-Copy-6" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-20)"><path id="path-19" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-7-Clipped" transform="translate(27 57)"><mask id="mask-22" fill="#fff"><use xlink:href="#path-21"/></mask><g id="Rectangle-2-Copy-7" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-22)"><path id="path-21" d="M0 0h40v20H0z"/></g></g><path id="Line" fill="#C06334" stroke="#C06334" stroke-width="2" d="M148.5 40.5v31"/><path id="Line-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M148.5 71.5l3-10.8h-6z"/><path id="Line-Copy" fill="#C06334" stroke="#C06334" stroke-width="2" d="M148.5 105.5v24"/><path id="Line-Copy-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M148.5 129.5l3-10.8h-6z"/><path id="Line-2" fill="#C06334" stroke="#C06334" stroke-width="2" d="M319.5 77.5l-19 16"/><path id="Line-2-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M300.5 93.5l10.193-4.662-3.864-4.59z"/><path id="Line-2" fill="#C06334" stroke="#C06334" stroke-width="2" d="M127.5 47.5l-19 16"/><path id="Line-2-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M108.5 63.5l10.193-4.662-3.864-4.59z"/><path id="Line-2-Copy-2" fill="#C06334" stroke="#C06334" stroke-width="2" d="M97.5 42.5l-23 9"/><path id="Line-2-Copy-2-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M74.5 51.5l11.15-1.142-2.186-5.587z"/><path id="Line-2-Copy" fill="#C06334" stroke="#C06334" stroke-width="2" d="M133.5 107.5l-19 16"/><path id="Line-2-Copy-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M114.5 123.5l10.193-4.662-3.864-4.59z"/><path id="Line" fill="#C06334" stroke="#C06334" stroke-width="2" d="M313.071 109.5h39.354"/><path id="Line-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M352.425 109.5l-10.8-3v6z"/><path id="Line" fill="#C06334" stroke="#C06334" stroke-width="2" d="M170.5 107.5l18 15"/><path id="Line-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M188.5 122.5l-6.376-9.219-3.841 4.61z"/><path id="Line-Copy-6" fill="#C06334" stroke="#C06334" stroke-width="2" d="M202.5 154.5l18 15"/><path id="Line-Copy-6-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M220.5 169.5l-6.376-9.219-3.841 4.61z"/><path id="Line-Copy-5" fill="#C06334" stroke="#C06334" stroke-width="2" d="M170.5 87.5l20-7"/><path id="Line-Copy-5-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M190.5 80.5l-11.185.736 1.982 5.663z"/><path id="Line-Copy-4" fill="#C06334" stroke="#C06334" stroke-width="2" d="M209.5 120.5l14-22"/><path id="Line-Copy-4-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M223.5 98.5l-8.33 7.5 5.063 3.222z"/><path id="Line-Copy-3" fill="#C06334" stroke="#C06334" stroke-width="2" d="M46.5 82.5l32 40"/><path id="Line-Copy-3-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M78.5 122.5l-4.404-10.307-4.685 3.748z"/><g id="Group" fill="#478964" transform="rotate(-90 81 2)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><g id="Group-Copy" fill="#478964" transform="rotate(-90 49.5 19.5)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><g id="Group-Copy-4" fill="#478964" transform="rotate(-90 110 -19)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><g id="Rectangle-2-Copy-9-Clipped" transform="translate(219 177)"><mask id="mask-24" fill="#fff"><use xlink:href="#path-23"/></mask><g id="Rectangle-2-Copy-9" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-24)"><path id="path-25" d="M0 0h40v20H0z"/></g></g><g id="Group-Copy-6" fill="#478964" transform="rotate(-90 140 -59)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><path id="Line-Copy-2" fill="#C06334" stroke="#C06334" stroke-width="2" d="M187.5 41.5l21 21"/><path id="Line-Copy-2-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M208.5 62.5l-5.515-9.758-4.243 4.243z"/><path id="Line-Copy" fill="#C06334" fill-rule="nonzero" d="M357.5 79.5l14.212 6.56-4.686 3.747 3.255 4.068.625.781-1.562 1.25-.625-.781-3.255-4.069-4.684 3.749L357.5 79.5z"/></g></g></svg>
\ No newline at end of file
diff --git a/1-js/04-object-basics/03-garbage-collection/garbage-collection-3.svg b/1-js/04-object-basics/03-garbage-collection/garbage-collection-3.svg
new file mode 100644
index 000000000..106057787
--- /dev/null
+++ b/1-js/04-object-basics/03-garbage-collection/garbage-collection-3.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="463" height="204" viewBox="0 0 463 204"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:&apos;PT Mono&apos;;font-weight:700;font-style:normal;src:local(&apos;PT MonoBold&apos;),url(/font/PTMonoBold.woff2) format(&apos;woff2&apos;),url(/font/PTMonoBold.woff) format(&apos;woff&apos;),url(/font/PTMonoBold.ttf) format(&apos;truetype&apos;)}</style></defs><defs><path id="path-1" d="M0 0h80v28H0z"/><path id="path-3" d="M0 0h40v20H0z"/><path id="path-5" d="M0 0h40v20H0z"/><path id="path-7" d="M0 0h40v20H0z"/><path id="path-9" d="M0 0h40v20H0z"/><path id="path-11" d="M0 0h40v20H0z"/><path id="path-13" d="M0 0h40v20H0z"/><path id="path-15" d="M0 0h40v20H0z"/><path id="path-17" d="M0 0h40v20H0z"/><path id="path-19" d="M0 0h40v20H0z"/><path id="path-21" d="M0 0h40v20H0z"/><path id="path-23" d="M0 0h40v20H0z"/></defs><g id="garbage-collection" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="garbage-collection-3.svg"><g id="Rectangle-1-Clipped" transform="translate(106 8)"><mask id="mask-2" fill="#fff"><use xlink:href="#path-1"/></mask><g id="Rectangle-1" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-2)"><path id="path-1" d="M0 0h80v28H0z"/></g></g><text id="&lt;global&gt;" fill="#AF6E24" fill-rule="nonzero" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="115" y="26">&lt;global&gt;</tspan></text><g id="Rectangle-2-Clipped" transform="translate(360 99)"><mask id="mask-4" fill="#fff"><use xlink:href="#path-3"/></mask><g id="Rectangle-2" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-4)"><path id="path-3" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-2-Clipped" transform="translate(267 99)"><mask id="mask-6" fill="#fff"><use xlink:href="#path-5"/></mask><g id="Rectangle-2-Copy-2" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-6)"><path id="path-5" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-2-Clipped" transform="translate(126 79)"><mask id="mask-8" fill="#fff"><use xlink:href="#path-7"/></mask><g id="Rectangle-2-Copy-2" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-8)"><path id="path-7" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-Clipped" transform="translate(313 53)"><mask id="mask-10" fill="#fff"><use xlink:href="#path-9"/></mask><g id="Rectangle-2-Copy" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-10)"><path id="path-9" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-3-Clipped" transform="translate(176 129)"><mask id="mask-12" fill="#fff"><use xlink:href="#path-11"/></mask><g id="Rectangle-2-Copy-3" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-12)"><path id="path-11" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-8-Clipped" transform="translate(196 69)"><mask id="mask-14" fill="#fff"><use xlink:href="#path-13"/></mask><g id="Rectangle-2-Copy-8" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-14)"><path id="path-13" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-4-Clipped" transform="translate(128 139)"><mask id="mask-16" fill="#fff"><use xlink:href="#path-15"/></mask><g id="Rectangle-2-Copy-4" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-16)"><path id="path-15" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-5-Clipped" transform="translate(76 131)"><mask id="mask-18" fill="#fff"><use xlink:href="#path-17"/></mask><g id="Rectangle-2-Copy-5" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-18)"><path id="path-17" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-6-Clipped" transform="translate(76 71)"><mask id="mask-20" fill="#fff"><use xlink:href="#path-19"/></mask><g id="Rectangle-2-Copy-6" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-20)"><path id="path-19" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-7-Clipped" transform="translate(27 57)"><mask id="mask-22" fill="#fff"><use xlink:href="#path-21"/></mask><g id="Rectangle-2-Copy-7" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-22)"><path id="path-21" d="M0 0h40v20H0z"/></g></g><path id="Line" fill="#C06334" stroke="#C06334" stroke-width="2" d="M148.5 40.5v31"/><path id="Line-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M148.5 71.5l3-10.8h-6z"/><path id="Line-Copy" fill="#C06334" stroke="#C06334" stroke-width="2" d="M148.5 105.5v24"/><path id="Line-Copy-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M148.5 129.5l3-10.8h-6z"/><path id="Line-2" fill="#C06334" stroke="#C06334" stroke-width="2" d="M319.5 77.5l-19 16"/><path id="Line-2-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M300.5 93.5l10.193-4.662-3.864-4.59z"/><path id="Line-2" fill="#C06334" stroke="#C06334" stroke-width="2" d="M127.5 47.5l-19 16"/><path id="Line-2-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M108.5 63.5l10.193-4.662-3.864-4.59z"/><path id="Line-2-Copy-2" fill="#C06334" stroke="#C06334" stroke-width="2" d="M97.5 42.5l-23 9"/><path id="Line-2-Copy-2-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M74.5 51.5l11.15-1.142-2.186-5.587z"/><path id="Line-2-Copy" fill="#C06334" stroke="#C06334" stroke-width="2" d="M133.5 107.5l-19 16"/><path id="Line-2-Copy-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M114.5 123.5l10.193-4.662-3.864-4.59z"/><path id="Line" fill="#C06334" stroke="#C06334" stroke-width="2" d="M313.071 109.5h39.354"/><path id="Line-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M352.425 109.5l-10.8-3v6z"/><path id="Line" fill="#C06334" stroke="#C06334" stroke-width="2" d="M170.5 107.5l18 15"/><path id="Line-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M188.5 122.5l-6.376-9.219-3.841 4.61z"/><path id="Line-Copy-6" fill="#C06334" stroke="#C06334" stroke-width="2" d="M202.5 154.5l18 15"/><path id="Line-Copy-6-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M220.5 169.5l-6.376-9.219-3.841 4.61z"/><path id="Line-Copy-5" fill="#C06334" stroke="#C06334" stroke-width="2" d="M170.5 87.5l20-7"/><path id="Line-Copy-5-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M190.5 80.5l-11.185.736 1.982 5.663z"/><path id="Line-Copy-4" fill="#C06334" stroke="#C06334" stroke-width="2" d="M209.5 120.5l14-22"/><path id="Line-Copy-4-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M223.5 98.5l-8.33 7.5 5.063 3.222z"/><path id="Line-Copy-3" fill="#C06334" stroke="#C06334" stroke-width="2" d="M46.5 82.5l32 40"/><path id="Line-Copy-3-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M78.5 122.5l-4.404-10.307-4.685 3.748z"/><g id="Group" fill="#478964" transform="rotate(-90 81 2)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><g id="Group-Copy" fill="#478964" transform="rotate(-90 49.5 19.5)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><g id="Group-Copy-2" fill="#478964" transform="rotate(-90 111.5 32.5)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><g id="Group-Copy-3" fill="#478964" transform="rotate(-90 141 10)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><g id="Group-Copy-4" fill="#478964" transform="rotate(-90 110 -19)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><g id="Group-Copy-5" fill="#478964" transform="rotate(-90 160 -19)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><g id="Rectangle-2-Copy-9-Clipped" transform="translate(219 177)"><mask id="mask-24" fill="#fff"><use xlink:href="#path-23"/></mask><g id="Rectangle-2-Copy-9" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-24)"><path id="path-25" d="M0 0h40v20H0z"/></g></g><g id="Group-Copy-6" fill="#478964" transform="rotate(-90 140 -59)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><path id="Line-Copy-2" fill="#C06334" stroke="#C06334" stroke-width="2" d="M187.5 41.5l21 21"/><path id="Line-Copy-2-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M208.5 62.5l-5.515-9.758-4.243 4.243z"/><path id="Line-Copy" fill="#C06334" fill-rule="nonzero" d="M357.5 79.5l14.212 6.56-4.686 3.747 3.255 4.068.625.781-1.562 1.25-.625-.781-3.255-4.069-4.684 3.749L357.5 79.5z"/></g></g></svg>
\ No newline at end of file
diff --git a/1-js/04-object-basics/03-garbage-collection/garbage-collection-4.svg b/1-js/04-object-basics/03-garbage-collection/garbage-collection-4.svg
new file mode 100644
index 000000000..bd485adee
--- /dev/null
+++ b/1-js/04-object-basics/03-garbage-collection/garbage-collection-4.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="463" height="204" viewBox="0 0 463 204"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:&apos;PT Mono&apos;;font-weight:700;font-style:normal;src:local(&apos;PT MonoBold&apos;),url(/font/PTMonoBold.woff2) format(&apos;woff2&apos;),url(/font/PTMonoBold.woff) format(&apos;woff&apos;),url(/font/PTMonoBold.ttf) format(&apos;truetype&apos;)}</style></defs><defs><path id="path-1" d="M0 0h80v28H0z"/><path id="path-3" d="M0 0h40v20H0z"/><path id="path-5" d="M0 0h40v20H0z"/><path id="path-7" d="M0 0h40v20H0z"/><path id="path-9" d="M0 0h40v20H0z"/><path id="path-11" d="M0 0h40v20H0z"/><path id="path-13" d="M0 0h40v20H0z"/><path id="path-15" d="M0 0h40v20H0z"/><path id="path-17" d="M0 0h40v20H0z"/><path id="path-19" d="M0 0h40v20H0z"/><path id="path-21" d="M0 0h40v20H0z"/><path id="path-23" d="M0 0h40v20H0z"/></defs><g id="garbage-collection" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="garbage-collection-4.svg"><g id="Rectangle-1-Clipped" transform="translate(106 8)"><mask id="mask-2" fill="#fff"><use xlink:href="#path-1"/></mask><g id="Rectangle-1" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-2)"><path id="path-1" d="M0 0h80v28H0z"/></g></g><text id="&lt;global&gt;" fill="#AF6E24" fill-rule="nonzero" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="115" y="26">&lt;global&gt;</tspan></text><g id="Rectangle-2-Clipped" transform="translate(360 99)"><mask id="mask-4" fill="#fff"><use xlink:href="#path-3"/></mask><g id="Rectangle-2" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-4)"><path id="path-3" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-2-Clipped" transform="translate(267 99)"><mask id="mask-6" fill="#fff"><use xlink:href="#path-5"/></mask><g id="Rectangle-2-Copy-2" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-6)"><path id="path-5" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-2-Clipped" transform="translate(126 79)"><mask id="mask-8" fill="#fff"><use xlink:href="#path-7"/></mask><g id="Rectangle-2-Copy-2" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-8)"><path id="path-7" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-Clipped" transform="translate(313 53)"><mask id="mask-10" fill="#fff"><use xlink:href="#path-9"/></mask><g id="Rectangle-2-Copy" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-10)"><path id="path-9" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-3-Clipped" transform="translate(176 129)"><mask id="mask-12" fill="#fff"><use xlink:href="#path-11"/></mask><g id="Rectangle-2-Copy-3" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-12)"><path id="path-11" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-8-Clipped" transform="translate(196 69)"><mask id="mask-14" fill="#fff"><use xlink:href="#path-13"/></mask><g id="Rectangle-2-Copy-8" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-14)"><path id="path-13" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-4-Clipped" transform="translate(128 139)"><mask id="mask-16" fill="#fff"><use xlink:href="#path-15"/></mask><g id="Rectangle-2-Copy-4" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-16)"><path id="path-15" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-5-Clipped" transform="translate(76 131)"><mask id="mask-18" fill="#fff"><use xlink:href="#path-17"/></mask><g id="Rectangle-2-Copy-5" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-18)"><path id="path-17" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-6-Clipped" transform="translate(76 71)"><mask id="mask-20" fill="#fff"><use xlink:href="#path-19"/></mask><g id="Rectangle-2-Copy-6" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-20)"><path id="path-19" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-7-Clipped" transform="translate(27 57)"><mask id="mask-22" fill="#fff"><use xlink:href="#path-21"/></mask><g id="Rectangle-2-Copy-7" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-22)"><path id="path-21" d="M0 0h40v20H0z"/></g></g><path id="Line" fill="#C06334" stroke="#C06334" stroke-width="2" d="M148.5 40.5v31"/><path id="Line-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M148.5 71.5l3-10.8h-6z"/><path id="Line-Copy" fill="#C06334" stroke="#C06334" stroke-width="2" d="M148.5 105.5v24"/><path id="Line-Copy-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M148.5 129.5l3-10.8h-6z"/><path id="Line-2" fill="#C06334" stroke="#C06334" stroke-width="2" d="M319.5 77.5l-19 16"/><path id="Line-2-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M300.5 93.5l10.193-4.662-3.864-4.59z"/><path id="Line-2" fill="#C06334" stroke="#C06334" stroke-width="2" d="M127.5 47.5l-19 16"/><path id="Line-2-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M108.5 63.5l10.193-4.662-3.864-4.59z"/><path id="Line-2-Copy-2" fill="#C06334" stroke="#C06334" stroke-width="2" d="M97.5 42.5l-23 9"/><path id="Line-2-Copy-2-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M74.5 51.5l11.15-1.142-2.186-5.587z"/><path id="Line-2-Copy" fill="#C06334" stroke="#C06334" stroke-width="2" d="M133.5 107.5l-19 16"/><path id="Line-2-Copy-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M114.5 123.5l10.193-4.662-3.864-4.59z"/><path id="Line" fill="#C06334" stroke="#C06334" stroke-width="2" d="M313.071 109.5h39.354"/><path id="Line-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M352.425 109.5l-10.8-3v6z"/><path id="Line" fill="#C06334" stroke="#C06334" stroke-width="2" d="M170.5 107.5l18 15"/><path id="Line-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M188.5 122.5l-6.376-9.219-3.841 4.61z"/><path id="Line-Copy-6" fill="#C06334" stroke="#C06334" stroke-width="2" d="M202.5 154.5l18 15"/><path id="Line-Copy-6-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M220.5 169.5l-6.376-9.219-3.841 4.61z"/><path id="Line-Copy-5" fill="#C06334" stroke="#C06334" stroke-width="2" d="M170.5 87.5l20-7"/><path id="Line-Copy-5-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M190.5 80.5l-11.185.736 1.982 5.663z"/><path id="Line-Copy-4" fill="#C06334" stroke="#C06334" stroke-width="2" d="M209.5 120.5l14-22"/><path id="Line-Copy-4-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M223.5 98.5l-8.33 7.5 5.063 3.222z"/><path id="Line-Copy-3" fill="#C06334" stroke="#C06334" stroke-width="2" d="M46.5 82.5l32 40"/><path id="Line-Copy-3-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M78.5 122.5l-4.404-10.307-4.685 3.748z"/><g id="Group" fill="#478964" transform="rotate(-90 81 2)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><g id="Group-Copy" fill="#478964" transform="rotate(-90 49.5 19.5)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><g id="Group-Copy-2" fill="#478964" transform="rotate(-90 111.5 32.5)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><g id="Group-Copy-3" fill="#478964" transform="rotate(-90 141 10)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><g id="Group-Copy-4" fill="#478964" transform="rotate(-90 110 -19)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><g id="Group-Copy-5" fill="#478964" transform="rotate(-90 160 -19)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><g id="Rectangle-2-Copy-9-Clipped" transform="translate(219 177)"><mask id="mask-24" fill="#fff"><use xlink:href="#path-23"/></mask><g id="Rectangle-2-Copy-9" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-24)"><path id="path-25" d="M0 0h40v20H0z"/></g></g><g id="Group-Copy-7" fill="#478964" transform="rotate(-90 205.5 -16.5)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><g id="Group-Copy-6" fill="#478964" transform="rotate(-90 140 -59)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><path id="Line-Copy-2" fill="#C06334" stroke="#C06334" stroke-width="2" d="M187.5 41.5l21 21"/><path id="Line-Copy-2-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M208.5 62.5l-5.515-9.758-4.243 4.243z"/><path id="Line-Copy" fill="#C06334" fill-rule="nonzero" d="M357.5 79.5l14.212 6.56-4.686 3.747 3.255 4.068.625.781-1.562 1.25-.625-.781-3.255-4.069-4.684 3.749L357.5 79.5z"/></g></g></svg>
\ No newline at end of file
diff --git a/1-js/04-object-basics/03-garbage-collection/garbage-collection-5.svg b/1-js/04-object-basics/03-garbage-collection/garbage-collection-5.svg
new file mode 100644
index 000000000..2d85432bc
--- /dev/null
+++ b/1-js/04-object-basics/03-garbage-collection/garbage-collection-5.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="463" height="204" viewBox="0 0 463 204"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:&apos;PT Mono&apos;;font-weight:700;font-style:normal;src:local(&apos;PT MonoBold&apos;),url(/font/PTMonoBold.woff2) format(&apos;woff2&apos;),url(/font/PTMonoBold.woff) format(&apos;woff&apos;),url(/font/PTMonoBold.ttf) format(&apos;truetype&apos;)}</style></defs><defs><path id="path-1" d="M0 0h146v88H0z"/><path id="path-3" d="M0 0h80v28H0z"/><path id="path-5" d="M0 0h40v20H0z"/><path id="path-7" d="M0 0h40v20H0z"/><path id="path-9" d="M0 0h40v20H0z"/><path id="path-11" d="M0 0h40v20H0z"/><path id="path-13" d="M0 0h40v20H0z"/><path id="path-15" d="M0 0h40v20H0z"/><path id="path-17" d="M0 0h40v20H0z"/><path id="path-19" d="M0 0h40v20H0z"/><path id="path-21" d="M0 0h40v20H0z"/><path id="path-23" d="M0 0h40v20H0z"/><path id="path-25" d="M0 0h40v20H0z"/></defs><g id="garbage-collection" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="garbage-collection-5.svg"><g id="Rectangle-5-Clipped" transform="translate(260 46)"><mask id="mask-2" fill="#fff"><use xlink:href="#path-1"/></mask><g id="Rectangle-5" stroke="#A7333A" stroke-width="4" mask="url(#mask-2)"><path id="path-23" d="M0 0h146v88H0z"/></g></g><g id="Rectangle-1-Clipped" transform="translate(106 8)"><mask id="mask-4" fill="#fff"><use xlink:href="#path-3"/></mask><g id="Rectangle-1" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-4)"><path id="path-1" d="M0 0h80v28H0z"/></g></g><text id="&lt;global&gt;" fill="#AF6E24" fill-rule="nonzero" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="115" y="26">&lt;global&gt;</tspan></text><g id="Rectangle-2-Clipped" transform="translate(360 99)"><mask id="mask-6" fill="#fff"><use xlink:href="#path-5"/></mask><g id="Rectangle-2" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-6)"><path id="path-3" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-2-Clipped" transform="translate(267 99)"><mask id="mask-8" fill="#fff"><use xlink:href="#path-7"/></mask><g id="Rectangle-2-Copy-2" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-8)"><path id="path-5" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-2-Clipped" transform="translate(126 79)"><mask id="mask-10" fill="#fff"><use xlink:href="#path-9"/></mask><g id="Rectangle-2-Copy-2" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-10)"><path id="path-7" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-Clipped" transform="translate(313 53)"><mask id="mask-12" fill="#fff"><use xlink:href="#path-11"/></mask><g id="Rectangle-2-Copy" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-12)"><path id="path-9" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-3-Clipped" transform="translate(176 129)"><mask id="mask-14" fill="#fff"><use xlink:href="#path-13"/></mask><g id="Rectangle-2-Copy-3" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-14)"><path id="path-11" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-8-Clipped" transform="translate(196 69)"><mask id="mask-16" fill="#fff"><use xlink:href="#path-15"/></mask><g id="Rectangle-2-Copy-8" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-16)"><path id="path-13" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-4-Clipped" transform="translate(128 139)"><mask id="mask-18" fill="#fff"><use xlink:href="#path-17"/></mask><g id="Rectangle-2-Copy-4" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-18)"><path id="path-15" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-5-Clipped" transform="translate(76 131)"><mask id="mask-20" fill="#fff"><use xlink:href="#path-19"/></mask><g id="Rectangle-2-Copy-5" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-20)"><path id="path-17" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-6-Clipped" transform="translate(76 71)"><mask id="mask-22" fill="#fff"><use xlink:href="#path-21"/></mask><g id="Rectangle-2-Copy-6" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-22)"><path id="path-19" d="M0 0h40v20H0z"/></g></g><g id="Rectangle-2-Copy-7-Clipped" transform="translate(27 57)"><mask id="mask-24" fill="#fff"><use xlink:href="#path-23"/></mask><g id="Rectangle-2-Copy-7" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-24)"><path id="path-21" d="M0 0h40v20H0z"/></g></g><path id="Line" fill="#C06334" stroke="#C06334" stroke-width="2" d="M148.5 40.5v31"/><path id="Line-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M148.5 71.5l3-10.8h-6z"/><path id="Line-Copy" fill="#C06334" stroke="#C06334" stroke-width="2" d="M148.5 105.5v24"/><path id="Line-Copy-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M148.5 129.5l3-10.8h-6z"/><path id="Line-2" fill="#C06334" stroke="#C06334" stroke-width="2" d="M319.5 77.5l-19 16"/><path id="Line-2-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M300.5 93.5l10.193-4.662-3.864-4.59z"/><path id="Line-2" fill="#C06334" stroke="#C06334" stroke-width="2" d="M127.5 47.5l-19 16"/><path id="Line-2-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M108.5 63.5l10.193-4.662-3.864-4.59z"/><path id="Line-2-Copy-2" fill="#C06334" stroke="#C06334" stroke-width="2" d="M97.5 42.5l-23 9"/><path id="Line-2-Copy-2-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M74.5 51.5l11.15-1.142-2.186-5.587z"/><path id="Line-2-Copy" fill="#C06334" stroke="#C06334" stroke-width="2" d="M133.5 107.5l-19 16"/><path id="Line-2-Copy-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M114.5 123.5l10.193-4.662-3.864-4.59z"/><path id="Line" fill="#C06334" stroke="#C06334" stroke-width="2" d="M313.071 109.5h39.354"/><path id="Line-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M352.425 109.5l-10.8-3v6z"/><path id="Line" fill="#C06334" stroke="#C06334" stroke-width="2" d="M170.5 107.5l18 15"/><path id="Line-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M188.5 122.5l-6.376-9.219-3.841 4.61z"/><path id="Line-Copy-6" fill="#C06334" stroke="#C06334" stroke-width="2" d="M202.5 154.5l18 15"/><path id="Line-Copy-6-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M220.5 169.5l-6.376-9.219-3.841 4.61z"/><path id="Line-Copy-5" fill="#C06334" stroke="#C06334" stroke-width="2" d="M170.5 87.5l20-7"/><path id="Line-Copy-5-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M190.5 80.5l-11.185.736 1.982 5.663z"/><path id="Line-Copy-4" fill="#C06334" stroke="#C06334" stroke-width="2" d="M209.5 120.5l14-22"/><path id="Line-Copy-4-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M223.5 98.5l-8.33 7.5 5.063 3.222z"/><path id="Line-Copy-3" fill="#C06334" stroke="#C06334" stroke-width="2" d="M46.5 82.5l32 40"/><path id="Line-Copy-3-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M78.5 122.5l-4.404-10.307-4.685 3.748z"/><g id="noun_48910_cc" transform="translate(261 5)"><path id="Shape" d="M17.503 1.75h-5.006a.341.341 0 00-.34.342v1.125h5.686V2.092a.341.341 0 00-.34-.341z"/><path id="Shape" fill="#A7333A" d="M28.364 3.217H19.59V2.092A2.09 2.09 0 0017.503 0h-5.006c-1.15 0-2.087.938-2.087 2.092v1.125H1.637c-.7 0-1.266.568-1.266 1.269v.09c0 .7.567 1.267 1.266 1.267h26.727c.699 0 1.266-.567 1.266-1.268v-.09c0-.7-.567-1.268-1.266-1.268zm-10.52 0h-5.687V2.092c0-.188.153-.341.34-.341h5.006a.34.34 0 01.34.34v1.126zM26.054 6.281H3.728c-1.298 0-2.35-.224-2.35 1.077L3.14 33.196c0 1.3 1.052 2.409 2.35 2.409h18.802c1.298 0 2.35-1.11 2.35-2.409l1.763-25.838c0-1.301-1.053-1.077-2.35-1.077zM9.637 32.193c-.377.012-.691-.261-.704-.612l-.694-19.917c-.012-.351.283-.647.66-.66.376-.013.69.261.703.613l.694 19.916c.013.351-.283.647-.659.66zm6.044-.63c0 .352-.306.637-.682.637-.377 0-.682-.286-.682-.637V11.634c0-.351.305-.636.682-.636.376 0 .682.285.682.636v19.93zm5.384.018c-.012.351-.327.625-.704.612-.376-.013-.672-.308-.66-.66l.695-19.916c.012-.352.326-.626.703-.613.377.014.672.309.66.66l-.694 19.917z"/></g><text id="unreachables" fill="#AF6E24" fill-rule="nonzero" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="296" y="29">unreachables</tspan></text><g id="Group" fill="#478964" transform="rotate(-90 81 2)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><g id="Group-Copy" fill="#478964" transform="rotate(-90 49.5 19.5)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><g id="Group-Copy-2" fill="#478964" transform="rotate(-90 111.5 32.5)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><g id="Group-Copy-3" fill="#478964" transform="rotate(-90 141 10)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><g id="Group-Copy-4" fill="#478964" transform="rotate(-90 110 -19)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><g id="Group-Copy-5" fill="#478964" transform="rotate(-90 160 -19)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><g id="Rectangle-2-Copy-9-Clipped" transform="translate(219 177)"><mask id="mask-26" fill="#fff"><use xlink:href="#path-25"/></mask><g id="Rectangle-2-Copy-9" fill="#FBF2EC" stroke="#DBAF88" stroke-width="4" mask="url(#mask-26)"><path id="path-25" d="M0 0h40v20H0z"/></g></g><g id="Group-Copy-7" fill="#478964" transform="rotate(-90 205.5 -16.5)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><g id="Group-Copy-6" fill="#478964" transform="rotate(-90 140 -59)"><path id="Fill-72" d="M5.5 5.511l-.866-1.01.866-1.012V1L2.505 4.497H2.5l.003.003-.003.003h.005L5.5 8V5.511"/><path id="Fill-73" d="M4.5 1.098A3.406 3.406 0 001.098 4.5 3.406 3.406 0 004.5 7.902 3.406 3.406 0 007.902 4.5 3.406 3.406 0 004.5 1.098zM4.5 9A4.505 4.505 0 010 4.5C0 2.019 2.019 0 4.5 0S9 2.019 9 4.5 6.981 9 4.5 9z"/></g><path id="Line-Copy-2" fill="#C06334" stroke="#C06334" stroke-width="2" d="M187.5 41.5l21 21"/><path id="Line-Copy-2-decoration-1" fill="#C06334" stroke="#C06334" stroke-width="2" d="M208.5 62.5l-5.515-9.758-4.243 4.243z"/><path id="Line" fill="#C06334" fill-rule="nonzero" d="M357.5 79.5l14.212 6.56-4.686 3.747 3.255 4.068.625.781-1.562 1.25-.625-.781-3.255-4.069-4.684 3.749L357.5 79.5z"/></g></g></svg>
\ No newline at end of file
diff --git a/1-js/04-object-basics/02-garbage-collection/memory-user-john-admin.svg b/1-js/04-object-basics/03-garbage-collection/memory-user-john-admin.svg
similarity index 67%
rename from 1-js/04-object-basics/02-garbage-collection/memory-user-john-admin.svg
rename to 1-js/04-object-basics/03-garbage-collection/memory-user-john-admin.svg
index dc4cce1c7..191324354 100644
--- a/1-js/04-object-basics/02-garbage-collection/memory-user-john-admin.svg
+++ b/1-js/04-object-basics/03-garbage-collection/memory-user-john-admin.svg
@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="144" height="159" viewBox="0 0 144 159"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:&apos;PT Mono&apos;;font-weight:700;font-style:normal;src:local(&apos;PT MonoBold&apos;),url(/font/PTMonoBold.woff2) format(&apos;woff2&apos;),url(/font/PTMonoBold.woff) format(&apos;woff&apos;),url(/font/PTMonoBold.ttf) format(&apos;truetype&apos;)}</style></defs><g id="garbage-collection" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="memory-user-john-admin.svg"><text id="user" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="12" y="67">user</tspan></text><path id="Rectangle-4" fill="#FFF9EB" stroke="#BCA68E" stroke-width="2" d="M16 93h118v48H16z"/><text id="name:-&quot;John&quot;" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="30" y="130">name: &quot;John&quot;</tspan></text><text id="Object" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="44" y="110">Object</tspan></text><path id="Line" fill="#EE6B47" fill-rule="nonzero" d="M55.5 47.5v18h6l-7 14-7-14h6v-18h2z"/><text id="admin" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="92" y="67">admin</tspan></text><path id="Line-Copy" fill="#EE6B47" fill-rule="nonzero" d="M83.5 47.5v18h6l-7 14-7-14h6v-18h2z"/><path id="Rectangle-1" fill="#FFF9EB" stroke="#E8C48E" stroke-width="2" d="M27 16h93v26H27z"/><text id="&lt;global&gt;" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="43" y="33">&lt;global&gt;</tspan></text></g></g></svg>
\ No newline at end of file
+<svg xmlns="http://www.w3.org/2000/svg" width="144" height="159" viewBox="0 0 144 159"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:&apos;PT Mono&apos;;font-weight:700;font-style:normal;src:local(&apos;PT MonoBold&apos;),url(/font/PTMonoBold.woff2) format(&apos;woff2&apos;),url(/font/PTMonoBold.woff) format(&apos;woff&apos;),url(/font/PTMonoBold.ttf) format(&apos;truetype&apos;)}</style></defs><g id="garbage-collection" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="memory-user-john-admin.svg"><text id="user" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="12" y="67">user</tspan></text><path id="Rectangle-4" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M16 93h118v48H16z"/><text id="name:-&quot;John&quot;" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="30" y="130">name: &quot;John&quot;</tspan></text><text id="Object" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="44" y="110">Object</tspan></text><path id="Line" fill="#C06334" fill-rule="nonzero" d="M55.5 47.5v18h6l-7 14-7-14h6v-18h2z"/><text id="admin" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="92" y="67">admin</tspan></text><path id="Line-Copy" fill="#C06334" fill-rule="nonzero" d="M83.5 47.5v18h6l-7 14-7-14h6v-18h2z"/><path id="Rectangle-1" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M27 16h93v26H27z"/><text id="&lt;global&gt;" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="43" y="33">&lt;global&gt;</tspan></text></g></g></svg>
\ No newline at end of file
diff --git a/1-js/04-object-basics/02-garbage-collection/memory-user-john-lost.svg b/1-js/04-object-basics/03-garbage-collection/memory-user-john-lost.svg
similarity index 75%
rename from 1-js/04-object-basics/02-garbage-collection/memory-user-john-lost.svg
rename to 1-js/04-object-basics/03-garbage-collection/memory-user-john-lost.svg
index e75b8d465..07914a9ca 100644
--- a/1-js/04-object-basics/02-garbage-collection/memory-user-john-lost.svg
+++ b/1-js/04-object-basics/03-garbage-collection/memory-user-john-lost.svg
@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="225" height="159" viewBox="0 0 225 159"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:&apos;PT Mono&apos;;font-weight:700;font-style:normal;src:local(&apos;PT MonoBold&apos;),url(/font/PTMonoBold.woff2) format(&apos;woff2&apos;),url(/font/PTMonoBold.woff) format(&apos;woff&apos;),url(/font/PTMonoBold.ttf) format(&apos;truetype&apos;)}</style></defs><g id="garbage-collection" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="memory-user-john-lost.svg"><path id="Rectangle-4" fill="#FFF9EB" stroke="#BCA68E" stroke-width="2" d="M61 89h118v48H61z"/><text id="name:-&quot;John&quot;" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="83" y="126">name: &quot;John&quot;</tspan></text><text id="Object-3" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="97" y="106">Object</tspan></text><path id="Rectangle-1" fill="#FFF9EB" stroke="#E8C48E" stroke-width="2" d="M65 4h104v42H65z"/><text id="user:-null" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="79" y="40">user: null</tspan></text><text id="&lt;global&gt;" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="86" y="23">&lt;global&gt;</tspan></text><path id="Rectangle-5" stroke="#D0021B" stroke-width="2" d="M47 69h154v86H47z"/><g id="noun_48910_cc" transform="translate(8 65)"><path id="Shape" d="M17.503 1.75h-5.006a.341.341 0 00-.34.342v1.125h5.686V2.092a.341.341 0 00-.34-.341z"/><path id="Shape" fill="#D0021B" d="M28.364 3.217H19.59V2.092A2.09 2.09 0 0017.503 0h-5.006c-1.15 0-2.087.938-2.087 2.092v1.125H1.637c-.7 0-1.266.568-1.266 1.269v.09c0 .7.567 1.267 1.266 1.267h26.727c.699 0 1.266-.567 1.266-1.268v-.09c0-.7-.567-1.268-1.266-1.268zm-10.52 0h-5.687V2.092c0-.188.153-.341.34-.341h5.006a.34.34 0 01.34.34v1.126zM26.054 6.281H3.728c-1.298 0-2.35-.224-2.35 1.077L3.14 33.196c0 1.3 1.052 2.409 2.35 2.409h18.802c1.298 0 2.35-1.11 2.35-2.409l1.763-25.838c0-1.301-1.053-1.077-2.35-1.077zM9.637 32.193c-.377.012-.691-.261-.704-.612l-.694-19.917c-.012-.351.283-.647.66-.66.376-.013.69.261.703.613l.694 19.916c.013.351-.283.647-.659.66zm6.044-.63c0 .352-.306.637-.682.637-.377 0-.682-.286-.682-.637V11.634c0-.351.305-.636.682-.636.376 0 .682.285.682.636v19.93zm5.384.018c-.012.351-.327.625-.704.612-.376-.013-.672-.308-.66-.66l.695-19.916c.012-.352.326-.626.703-.613.377.014.672.309.66.66l-.694 19.917z"/></g></g></g></svg>
\ No newline at end of file
+<svg xmlns="http://www.w3.org/2000/svg" width="225" height="159" viewBox="0 0 225 159"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:&apos;PT Mono&apos;;font-weight:700;font-style:normal;src:local(&apos;PT MonoBold&apos;),url(/font/PTMonoBold.woff2) format(&apos;woff2&apos;),url(/font/PTMonoBold.woff) format(&apos;woff&apos;),url(/font/PTMonoBold.ttf) format(&apos;truetype&apos;)}</style></defs><g id="garbage-collection" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="memory-user-john-lost.svg"><path id="Rectangle-4" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M61 89h118v48H61z"/><text id="name:-&quot;John&quot;" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="83" y="126">name: &quot;John&quot;</tspan></text><text id="Object-3" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="97" y="106">Object</tspan></text><path id="Rectangle-1" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M65 4h104v42H65z"/><text id="user:-null" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="79" y="40">user: null</tspan></text><text id="&lt;global&gt;" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="86" y="23">&lt;global&gt;</tspan></text><path id="Rectangle-5" stroke="#A7333A" stroke-width="2" d="M47 69h154v86H47z"/><g id="noun_48910_cc" transform="translate(8 65)"><path id="Shape" d="M17.503 1.75h-5.006a.341.341 0 00-.34.342v1.125h5.686V2.092a.341.341 0 00-.34-.341z"/><path id="Shape" fill="#A7333A" d="M28.364 3.217H19.59V2.092A2.09 2.09 0 0017.503 0h-5.006c-1.15 0-2.087.938-2.087 2.092v1.125H1.637c-.7 0-1.266.568-1.266 1.269v.09c0 .7.567 1.267 1.266 1.267h26.727c.699 0 1.266-.567 1.266-1.268v-.09c0-.7-.567-1.268-1.266-1.268zm-10.52 0h-5.687V2.092c0-.188.153-.341.34-.341h5.006a.34.34 0 01.34.34v1.126zM26.054 6.281H3.728c-1.298 0-2.35-.224-2.35 1.077L3.14 33.196c0 1.3 1.052 2.409 2.35 2.409h18.802c1.298 0 2.35-1.11 2.35-2.409l1.763-25.838c0-1.301-1.053-1.077-2.35-1.077zM9.637 32.193c-.377.012-.691-.261-.704-.612l-.694-19.917c-.012-.351.283-.647.66-.66.376-.013.69.261.703.613l.694 19.916c.013.351-.283.647-.659.66zm6.044-.63c0 .352-.306.637-.682.637-.377 0-.682-.286-.682-.637V11.634c0-.351.305-.636.682-.636.376 0 .682.285.682.636v19.93zm5.384.018c-.012.351-.327.625-.704.612-.376-.013-.672-.308-.66-.66l.695-19.916c.012-.352.326-.626.703-.613.377.014.672.309.66.66l-.694 19.917z"/></g></g></g></svg>
\ No newline at end of file
diff --git a/1-js/04-object-basics/02-garbage-collection/memory-user-john.svg b/1-js/04-object-basics/03-garbage-collection/memory-user-john.svg
similarity index 70%
rename from 1-js/04-object-basics/02-garbage-collection/memory-user-john.svg
rename to 1-js/04-object-basics/03-garbage-collection/memory-user-john.svg
index 0191e3f07..15bd51afb 100644
--- a/1-js/04-object-basics/02-garbage-collection/memory-user-john.svg
+++ b/1-js/04-object-basics/03-garbage-collection/memory-user-john.svg
@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="144" height="150" viewBox="0 0 144 150"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:&apos;PT Mono&apos;;font-weight:700;font-style:normal;src:local(&apos;PT MonoBold&apos;),url(/font/PTMonoBold.woff2) format(&apos;woff2&apos;),url(/font/PTMonoBold.woff) format(&apos;woff&apos;),url(/font/PTMonoBold.ttf) format(&apos;truetype&apos;)}</style></defs><g id="garbage-collection" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="memory-user-john.svg"><text id="user" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="31" y="69">user</tspan></text><path id="Rectangle-4" fill="#FFF9EB" stroke="#BCA68E" stroke-width="2" d="M16 95h118v48H16z"/><text id="name:-&quot;John&quot;" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="32" y="132">name: &quot;John&quot;</tspan></text><text id="Object-3" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="46" y="112">Object</tspan></text><path id="Line" fill="#EE6B47" fill-rule="nonzero" d="M75.5 49.5v18h6l-7 14-7-14h6v-18h2z"/><path id="Rectangle-1" fill="#FFF9EB" stroke="#E8C48E" stroke-width="2" d="M27 12h93v26H27z"/><text id="&lt;global&gt;" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="43" y="29">&lt;global&gt;</tspan></text></g></g></svg>
\ No newline at end of file
+<svg xmlns="http://www.w3.org/2000/svg" width="144" height="150" viewBox="0 0 144 150"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:&apos;PT Mono&apos;;font-weight:700;font-style:normal;src:local(&apos;PT MonoBold&apos;),url(/font/PTMonoBold.woff2) format(&apos;woff2&apos;),url(/font/PTMonoBold.woff) format(&apos;woff&apos;),url(/font/PTMonoBold.ttf) format(&apos;truetype&apos;)}</style></defs><g id="garbage-collection" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="memory-user-john.svg"><text id="user" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="31" y="69">user</tspan></text><path id="Rectangle-4" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M16 95h118v48H16z"/><text id="name:-&quot;John&quot;" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="32" y="132">name: &quot;John&quot;</tspan></text><text id="Object-3" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="46" y="112">Object</tspan></text><path id="Line" fill="#C06334" fill-rule="nonzero" d="M75.5 49.5v18h6l-7 14-7-14h6v-18h2z"/><path id="Rectangle-1" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M27 12h93v26H27z"/><text id="&lt;global&gt;" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="43" y="29">&lt;global&gt;</tspan></text></g></g></svg>
\ No newline at end of file
diff --git a/1-js/04-object-basics/04-object-methods/4-object-property-this/solution.md b/1-js/04-object-basics/04-object-methods/4-object-property-this/solution.md
index c09c407a4..e75392389 100644
--- a/1-js/04-object-basics/04-object-methods/4-object-property-this/solution.md
+++ b/1-js/04-object-basics/04-object-methods/4-object-property-this/solution.md
@@ -7,7 +7,7 @@ function makeUser() {
     name: "John",
     ref: this
   };
-};
+}
 
 let user = makeUser();
 
@@ -45,7 +45,7 @@ function makeUser() {
     }
 */!*
   };
-};
+}
 
 let user = makeUser();
 
diff --git a/1-js/04-object-basics/04-object-methods/4-object-property-this/task.md b/1-js/04-object-basics/04-object-methods/4-object-property-this/task.md
index dd9630e08..c906ff6dc 100644
--- a/1-js/04-object-basics/04-object-methods/4-object-property-this/task.md
+++ b/1-js/04-object-basics/04-object-methods/4-object-property-this/task.md
@@ -14,7 +14,7 @@ function makeUser() {
     name: "John",
     ref: this
   };
-};
+}
 
 let user = makeUser();
 
diff --git a/1-js/04-object-basics/04-object-methods/7-calculator/_js.view/test.js b/1-js/04-object-basics/04-object-methods/7-calculator/_js.view/test.js
index 1f71eda4c..4decb76dc 100644
--- a/1-js/04-object-basics/04-object-methods/7-calculator/_js.view/test.js
+++ b/1-js/04-object-basics/04-object-methods/7-calculator/_js.view/test.js
@@ -15,6 +15,11 @@ describe("calculator", function() {
     afterEach(function() {
       prompt.restore();
     });
+    
+    it('the read get two values and saves them as object properties', function () {
+      assert.equal(calculator.a, 2);
+      assert.equal(calculator.b, 3);
+    });
 
     it("the sum is 5", function() {
       assert.equal(calculator.sum(), 5);
diff --git a/1-js/04-object-basics/04-object-methods/7-calculator/task.md b/1-js/04-object-basics/04-object-methods/7-calculator/task.md
index 2767dd32e..7a5cb0bd4 100644
--- a/1-js/04-object-basics/04-object-methods/7-calculator/task.md
+++ b/1-js/04-object-basics/04-object-methods/7-calculator/task.md
@@ -6,9 +6,15 @@ importance: 5
 
 Stwórz obiekt `calculator` z trzema metodami:
 
+<<<<<<< HEAD
 - `read()` pobiera dwie wartości z okienek dialogowych `prompt` i zachowuje je jako właściwości obiektu.
 - `sum()` zwraca sumę zachowanych wartości.
 - `mul()` mnoży zachowane wartości i zwraca wynik.
+=======
+- `read()` prompts for two values and saves them as object properties with names `a` and `b` respectively.
+- `sum()` returns the sum of saved values.
+- `mul()` multiplies saved values and returns the result.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ```js
 let calculator = {
@@ -21,4 +27,3 @@ alert( calculator.mul() );
 ```
 
 [demo]
-
diff --git a/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/solution.js b/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/solution.js
index e98fe6410..a35c009cc 100644
--- a/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/solution.js
+++ b/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/solution.js
@@ -11,5 +11,6 @@ let ladder = {
   },
   showStep: function() { 
     alert(this.step);
+    return this;
   }
 };
\ No newline at end of file
diff --git a/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/test.js b/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/test.js
index a2b17fcc4..b4f2459b7 100644
--- a/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/test.js
+++ b/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/test.js
@@ -32,6 +32,14 @@ describe('Ladder', function() {
   it('down().up().up().up() ', function() {
     assert.equal(ladder.down().up().up().up().step, 2);
   });
+
+  it('showStep() should return this', function() {
+    assert.equal(ladder.showStep(), ladder);
+  });
+ 
+  it('up().up().down().showStep().down().showStep()', function () {
+    assert.equal(ladder.up().up().down().showStep().down().showStep().step, 0)
+  });
   
   after(function() {
     ladder.step = 0;
diff --git a/1-js/04-object-basics/04-object-methods/8-chain-calls/solution.md b/1-js/04-object-basics/04-object-methods/8-chain-calls/solution.md
index 4818745a1..b4c326861 100644
--- a/1-js/04-object-basics/04-object-methods/8-chain-calls/solution.md
+++ b/1-js/04-object-basics/04-object-methods/8-chain-calls/solution.md
@@ -21,9 +21,9 @@ let ladder = {
     return this;
 */!*
   }
-}
+};
 
-ladder.up().up().down().up().down().showStep(); // 1
+ladder.up().up().down().showStep().down().showStep(); // shows 1 then 0
 ```
 
 Przy długich łańcuchach kodu, możemy każdy człon umieszczać w osobnej linijce, dla zwiększenia czytelności:
@@ -33,7 +33,7 @@ ladder
   .up()
   .up()
   .down()
-  .up()
+  .showStep() // 1
   .down()
-  .showStep(); // 1
+  .showStep(); // 0
 ```
diff --git a/1-js/04-object-basics/04-object-methods/8-chain-calls/task.md b/1-js/04-object-basics/04-object-methods/8-chain-calls/task.md
index 5cf9d59a3..d9c42b78e 100644
--- a/1-js/04-object-basics/04-object-methods/8-chain-calls/task.md
+++ b/1-js/04-object-basics/04-object-methods/8-chain-calls/task.md
@@ -4,7 +4,11 @@ importance: 2
 
 # Łączenie
 
+<<<<<<< HEAD
 Mamy tutaj obiekt `ladder` który pozwala wspinać się do góry i schodzić w dół:
+=======
+There's a `ladder` object that allows you to go up and down:
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ```js
 let ladder = {
@@ -21,19 +25,33 @@ let ladder = {
 };
 ```
 
+<<<<<<< HEAD
 Jeśli chcielibyśmy wykonać sekwencję ruchów, możemy zrobić to w ten sposób:
+=======
+Now, if we need to make several calls in sequence, we can do it like this:
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ```js
 ladder.up();
 ladder.up();
 ladder.down();
 ladder.showStep(); // 1
+ladder.down();
+ladder.showStep(); // 0
 ```
 
+<<<<<<< HEAD
 Zmodyfkuj kod dla `up`, `down` i `showStep` żeby można było połączyć wywołania metod, w taki sposób:
+=======
+Modify the code of `up`, `down`, and `showStep` to make the calls chainable, like this:
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ```js
-ladder.up().up().down().showStep(); // 1
+ladder.up().up().down().showStep().down().showStep(); // shows 1 then 0
 ```
 
+<<<<<<< HEAD
 Wiele bibliotek JavaScript wykorzystuje taki sposób pisania kodu.
+=======
+Such an approach is widely used across JavaScript libraries.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
diff --git a/1-js/04-object-basics/04-object-methods/article.md b/1-js/04-object-basics/04-object-methods/article.md
index 5e20f8d5c..1a3c39242 100644
--- a/1-js/04-object-basics/04-object-methods/article.md
+++ b/1-js/04-object-basics/04-object-methods/article.md
@@ -32,11 +32,19 @@ user.sayHi = function() {
 user.sayHi(); // Cześć!
 ```
 
+<<<<<<< HEAD
 Właśnie stworzyliśmy funkcję za pomocą Wyrażenia Funkcji i przypisaliśmy ją do właściwości `user.sayHi` obiektu.
 
 Następnie ją wywołaliśmy i nasz użytkownik potrafi teraz mówić!
 
 Funkcję, która jest właściwością obiektu nazywamy *metodą*.
+=======
+Here we've just used a Function Expression to create a function and assign it to the property `user.sayHi` of the object.
+
+Then we can call it as `user.sayHi()`. The user can now speak!
+
+A function that is a property of an object is called its *method*.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 Także mamy tutaj metodę `sayHi` obiektu `user`.
 
@@ -50,8 +58,13 @@ let user = {
 *!*
 // najpierw deklarujemy
 function sayHi() {
+<<<<<<< HEAD
   alert("Cześć!");
 };
+=======
+  alert("Hello!");
+}
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 // następnie dodajemy jako metodę
 user.sayHi = sayHi;
@@ -64,7 +77,11 @@ user.sayHi(); // Cześć!
 Kiedy piszemy kod wykorzystujący obiekty do reprezentowania różnych istnień, nazywamy to [programowaniem obiektowym](https://pl.wikipedia.org/wiki/Programowanie_obiektowe), w skrócie:
 "OOP".
 
+<<<<<<< HEAD
 OOP to bardzo rozległy i interesujący temat. Jak wybrać właściwe podmioty? Jak stworzyć zależności między nimi? Jest to cała architektura i istnieje wiele świetnych książek traktujących ten temat, jak np. "Wzorce projektowe. Elementy oprogramowania" autorstwa E.Gamma, R.Helm, R.Johnson, J.Vissides, lub  "Object-Oriented Analysis and Design with Applications" G.Booch, i wiele innych.
+=======
+OOP is a big thing, an interesting science of its own. How to choose the right entities? How to organize the interaction between them? That's architecture, and there are great books on that topic, like "Design Patterns: Elements of Reusable Object-Oriented Software" by E. Gamma, R. Helm, R. Johnson, J. Vissides or "Object-Oriented Analysis and Design with Applications" by G. Booch, and more.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 ```
 ### Skrót składniowy dla metod
 
@@ -82,7 +99,11 @@ user = {
 // skrócona składnia wygląda lepiej, prawda ? 
 user = {
 *!*
+<<<<<<< HEAD
   sayHi() { // to samo co "sayHi: function()"
+=======
+  sayHi() { // same as "sayHi: function(){...}"
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 */!*
     alert("Cześć");
   }
@@ -91,7 +112,11 @@ user = {
 
 Jak widzimy, możemy pominąć `"function"` i po prostu użyć `sayHi()`.
 
+<<<<<<< HEAD
 Prawde mowiąc, oba zapisy nie są całkowicie identyczne. Istnieją subtelne różnice między nimi, związane z dziedziczeniem (ten temat poruszymy później), ale na tem moment nie ma to znaczenia. W prawie każdym przypadku lepiej użyć krótszej składni.
+=======
+To tell the truth, the notations are not fully identical. There are subtle differences related to object inheritance (to be covered later), but for now they do not matter. In almost all cases, the shorter syntax is preferred.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ## "this" w metodach
 
@@ -161,14 +186,24 @@ let user = {
 let admin = user;
 user = null; // dla pewności nadpisujemy zmienną
 
+<<<<<<< HEAD
 admin.sayHi(); // Ups! wewnątrz sayHi(), wykorzystywana jest zła zmienna! Błąd!
+=======
+*!*
+admin.sayHi(); // TypeError: Cannot read property 'name' of null
+*/!*
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 ```
 
 Jeśli użylibyśmy `this.name` zamiast `user.name` wewnątrz `alert`, wtedy kod by zadziałał.
 
 ## "this" nie jest powiązane
 
+<<<<<<< HEAD
 W JavaScript słowo kluczowe `this` zachowuje się inaczej niż w innych językach programowania. Może ono być użyte w każdej funkcji.
+=======
+In JavaScript, keyword `this` behaves unlike most other programming languages. It can be used in any function, even if it's not a method of an object.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 Zapis taki jak w poniższym przykładzie nie powoduje błędu:
 
@@ -236,6 +271,7 @@ Koncepcja ewaluacji `this` podczas wykonywania kodu ma wady i zalety. Z jednej s
 Naszym zadaniem nie jest ocena czy taki wybór przy tworzeniu języka był dobry czy zły. Zastanawiamy się raczej jak z takim mechanizmem pracować, jakie zyskać dzięki temu korzyści i jak uniknąć problemów.
 ```
 
+<<<<<<< HEAD
 ## Internals: Referencje
 
 ```warn header="Zaawansowane szczegóły języka"
@@ -329,6 +365,9 @@ Każda inna operacja, jak przypisanie `hi = user.hi` odrzuca całkowicie Typ Ref
 Podsumowując, wartość `this` jest przekazywane we właściwy sposób jeśli funkcja jest wywoływana za pomocą kropki `obj.method()` lub nawiasów kwadratowych `obj[`method`]()` (obie składnie zadziałają tutaj identycznie). W dalszej części kursu, nauczymy się różnych możliwości aby rozwiązać ten problem, takich jak [func.bind()](/bind#solution-2-bind).
 
 ## Funkcje strzałkowe nie mają "this"
+=======
+## Arrow functions have no "this"
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 Funkcje strzałkowe są specjalnym typem funkcji: nie posiadają "własnego" `this`. Jeśli odnosimy się do `this` w takiej funkcji, jego wartość jest pobierana z zewnętrznej "normalnej" funkcji. 
 
diff --git a/1-js/04-object-basics/06-constructor-new/1-two-functions-one-object/task.md b/1-js/04-object-basics/06-constructor-new/1-two-functions-one-object/task.md
index 8c1fea8eb..e932a201a 100644
--- a/1-js/04-object-basics/06-constructor-new/1-two-functions-one-object/task.md
+++ b/1-js/04-object-basics/06-constructor-new/1-two-functions-one-object/task.md
@@ -4,14 +4,14 @@ importance: 2
 
 # Two functions – one object
 
-Is it possible to create functions `A` and `B` such as `new A()==new B()`?
+Is it possible to create functions `A` and `B` so that `new A() == new B()`?
 
 ```js no-beautify
 function A() { ... }
 function B() { ... }
 
-let a = new A;
-let b = new B;
+let a = new A();
+let b = new B();
 
 alert( a == b ); // true
 ```
diff --git a/1-js/04-object-basics/06-constructor-new/2-calculator-constructor/_js.view/test.js b/1-js/04-object-basics/06-constructor-new/2-calculator-constructor/_js.view/test.js
index 036053927..bba80e5c2 100644
--- a/1-js/04-object-basics/06-constructor-new/2-calculator-constructor/_js.view/test.js
+++ b/1-js/04-object-basics/06-constructor-new/2-calculator-constructor/_js.view/test.js
@@ -10,6 +10,11 @@ describe("calculator", function() {
     calculator = new Calculator();
     calculator.read();
   });
+  
+  it("the read method asks for two values using prompt and remembers them in object properties", function() {
+    assert.equal(calculator.a, 2);
+    assert.equal(calculator.b, 3);
+  });
 
   it("when 2 and 3 are entered, the sum is 5", function() {
     assert.equal(calculator.sum(), 5);
diff --git a/1-js/04-object-basics/06-constructor-new/2-calculator-constructor/task.md b/1-js/04-object-basics/06-constructor-new/2-calculator-constructor/task.md
index 60e7c373e..c862bec40 100644
--- a/1-js/04-object-basics/06-constructor-new/2-calculator-constructor/task.md
+++ b/1-js/04-object-basics/06-constructor-new/2-calculator-constructor/task.md
@@ -6,7 +6,7 @@ importance: 5
 
 Create a constructor function `Calculator` that creates objects with 3 methods:
 
-- `read()` asks for two values using `prompt` and remembers them in object properties.
+- `read()` prompts for two values and saves them as object properties with names `a` and `b` respectively.
 - `sum()` returns the sum of these properties.
 - `mul()` returns the multiplication product of these properties.
 
diff --git a/1-js/04-object-basics/06-constructor-new/article.md b/1-js/04-object-basics/06-constructor-new/article.md
index a885e35ff..a335464f1 100644
--- a/1-js/04-object-basics/06-constructor-new/article.md
+++ b/1-js/04-object-basics/06-constructor-new/article.md
@@ -1,6 +1,6 @@
 # Constructor, operator "new"
 
-The regular `{...}` syntax allows to create one object. But often we need to create many similar objects, like multiple users or menu items and so on.
+The regular `{...}` syntax allows us to create one object. But often we need to create many similar objects, like multiple users or menu items and so on.
 
 That can be done using constructor functions and the `"new"` operator.
 
@@ -64,13 +64,14 @@ Now if we want to create other users, we can call `new User("Ann")`, `new User("
 
 That's the main purpose of constructors -- to implement reusable object creation code.
 
-Let's note once again -- technically, any function can be used as a constructor. That is: any function can be run with `new`, and it will execute the algorithm above. The "capital letter first" is a common agreement, to make it clear that a function is to be run with `new`.
+Let's note once again -- technically, any function (except arrow functions, as they don't have `this`) can be used as a constructor. It can be run with `new`, and it will execute the algorithm above. The "capital letter first" is a common agreement, to make it clear that a function is to be run with `new`.
 
 ````smart header="new function() { ... }"
-If we have many lines of code all about creation of a single complex object, we can wrap them in constructor function, like this:
+If we have many lines of code all about creation of a single complex object, we can wrap them in an immediately called constructor function, like this:
 
 ```js
-let user = new function() {
+// create a function and immediately call it with new
+let user = new function() { 
   this.name = "John";
   this.isAdmin = false;
 
@@ -80,7 +81,7 @@ let user = new function() {
 };
 ```
 
-The constructor can't be called again, because it is not saved anywhere, just created and called. So this trick aims to encapsulate the code that constructs the single object, without future reuse.
+This constructor can't be called again, because it is not saved anywhere, just created and called. So this trick aims to encapsulate the code that constructs the single object, without future reuse.
 ````
 
 ## Constructor mode test: new.target
@@ -91,7 +92,7 @@ The syntax from this section is rarely used, skip it unless you want to know eve
 
 Inside a function, we can check whether it was called with `new` or without it, using a special `new.target` property.
 
-It is empty for regular calls and equals the function if called with `new`:
+It is undefined for regular calls and equals the function if called with `new`:
 
 ```js run
 function User() {
@@ -170,7 +171,7 @@ alert( new SmallUser().name );  // John
 Usually constructors don't have a `return` statement. Here we mention the special behavior with returning objects mainly for the sake of completeness.
 
 ````smart header="Omitting parentheses"
-By the way, we can omit parentheses after `new`, if it has no arguments:
+By the way, we can omit parentheses after `new`:
 
 ```js
 let user = new User; // <-- no parentheses
diff --git a/1-js/04-object-basics/07-optional-chaining/article.md b/1-js/04-object-basics/07-optional-chaining/article.md
index 84ac3384a..9393748ab 100644
--- a/1-js/04-object-basics/07-optional-chaining/article.md
+++ b/1-js/04-object-basics/07-optional-chaining/article.md
@@ -1,7 +1,12 @@
+<<<<<<< HEAD
+=======
+
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 # Optional chaining '?.'
 
 [recent browser="new"]
 
+<<<<<<< HEAD
 Optional chaining `?.` pozwala nam w bezpieczny sposób odczytać zagłębione właściwości obiektu, nawet jeśli któraś z nich "po drodze" nie istnieje.
 
 ## Problem nieistniejącej właściwości
@@ -36,6 +41,42 @@ Jeszcze raz, jeśli element nie istnieje, otrzymamy błąd próbując odczytać
 Jak możemy to zrobić?
 
 Oczywistym rozwiązaniem jest sprawdzenie wartości przy użyciu instrukcji warunkowej `if` lub conditional operator `?` przed odczytaniem wartości, jak na przykładzie:
+=======
+The optional chaining `?.` is a safe way to access nested object properties, even if an intermediate property doesn't exist.
+
+## The "non-existing property" problem
+
+If you've just started to read the tutorial and learn JavaScript, maybe the problem hasn't touched you yet, but it's quite common.
+
+As an example, let's say we have `user` objects that hold the information about our users.
+
+Most of our users have addresses in `user.address` property, with the street `user.address.street`, but some did not provide them.
+
+In such case, when we attempt to get `user.address.street`, and the user happens to be without an address, we get an error:
+
+```js run
+let user = {}; // a user without "address" property
+
+alert(user.address.street); // Error!
+```
+
+That's the expected result. JavaScript works like this. As `user.address` is `undefined`, an attempt to get `user.address.street` fails with an error.
+
+In many practical cases we'd prefer to get `undefined` instead of an error here (meaning "no street").
+
+...and another example. In Web development, we can get an object that corresponds to a web page element using a special method call, such as `document.querySelector('.elem')`, and it returns `null` when there's no such element.
+
+```js run
+// document.querySelector('.elem') is null if there's no element
+let html = document.querySelector('.elem').innerHTML; // error if it's null
+```
+
+Once again, if the element doesn't exist, we'll get an error accessing `.innerHTML` property of `null`. And in some cases, when the absence of the element is normal, we'd like to avoid the error and just accept `html = null` as the result.
+
+How can we do this?
+
+The obvious solution would be to check the value using `if` or the conditional operator `?`, before accessing its property, like this:
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ```js
 let user = {};
@@ -43,6 +84,7 @@ let user = {};
 alert(user.address ? user.address.street : undefined);
 ```
 
+<<<<<<< HEAD
 Działa, nie otrzymujemy błędu... Lecz ten sposób jest mało elegancki. Jak możesz zobaczyć, `"user.address"` występuje w kodzie podwójnie. Dla bardziej zagłębionych właściwości, staje się to problemem ponieważ wymagana jest większa ilość powtórzeń.
 
 Np. spróbujmy odczytać `user.address.street.name`.
@@ -93,10 +135,76 @@ alert(user?.address?.street); // undefined (brak błędu)
 Kod jest zwięzły i czysty, nie występują żadne powtórzenia.
 
 Odczytanie adresu jako `user?.address` działa nawet jeśli objekt `user` nie istnieje:
+=======
+It works, there's no error... But it's quite inelegant. As you can see, the `"user.address"` appears twice in the code.
+
+Here's how the same would look for `document.querySelector`:
+
+```js run
+let html = document.querySelector('.elem') ? document.querySelector('.elem').innerHTML : null;
+```
+
+We can see that the element search `document.querySelector('.elem')` is actually called twice here. Not good.
+
+For more deeply nested properties, it becomes even uglier, as more repetitions are required.
+
+E.g. let's get `user.address.street.name` in a similar fashion.
+
+```js
+let user = {}; // user has no address
+
+alert(user.address ? user.address.street ? user.address.street.name : null : null);
+```
+
+That's just awful, one may even have problems understanding such code.
+
+There's a little better way to write it, using the `&&` operator:
+
+```js run
+let user = {}; // user has no address
+
+alert( user.address && user.address.street && user.address.street.name ); // undefined (no error)
+```
+
+AND'ing the whole path to the property ensures that all components exist (if not, the evaluation stops), but also isn't ideal.
+
+As you can see, property names are still duplicated in the code. E.g. in the code above, `user.address` appears three times.
+
+That's why the optional chaining `?.` was added to the language. To solve this problem once and for all!
+
+## Optional chaining
+
+The optional chaining `?.` stops the evaluation if the value before `?.` is `undefined` or `null` and returns `undefined`.
+
+**Further in this article, for brevity, we'll be saying that something "exists" if it's not `null` and not `undefined`.**
+
+In other words, `value?.prop`:
+- works as `value.prop`, if `value` exists,
+- otherwise (when `value` is `undefined/null`) it returns `undefined`.
+
+Here's the safe way to access `user.address.street` using `?.`:
+
+```js run
+let user = {}; // user has no address
+
+alert( user?.address?.street ); // undefined (no error)
+```
+
+The code is short and clean, there's no duplication at all.
+
+Here's an example with `document.querySelector`:
+
+```js run
+let html = document.querySelector('.elem')?.innerHTML; // will be undefined, if there's no element
+```
+
+Reading the address with `user?.address` works even if `user` object doesn't exist:
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ```js run
 let user = null;
 
+<<<<<<< HEAD
 alert(user?.address); // undefined
 alert(user?.address.street); // undefined
 ```
@@ -131,11 +239,47 @@ Jak zostało powiedziane wcześniej, `?.` natychmiast zatrzymuje ("short-circuit
 Więc, jeśli występują jakieś dalsze wywołania funkcji lub efekty uboczne, nie zostaną one wykonane.
 
 Na przykład:
+=======
+alert( user?.address ); // undefined
+alert( user?.address.street ); // undefined
+```
+
+Please note: the `?.` syntax makes optional the value before it, but not any further.
+
+E.g. in `user?.address.street.name` the `?.` allows `user` to safely be `null/undefined` (and returns `undefined` in that case), but that's only for `user`. Further properties are accessed in a regular way. If we want some of them to be optional, then we'll need to replace more `.` with `?.`.
+
+```warn header="Don't overuse the optional chaining"
+We should use `?.` only where it's ok that something doesn't exist.
+
+For example, if according to our code logic `user` object must exist, but `address` is optional, then we should write `user.address?.street`, but not `user?.address?.street`.
+
+Then, if `user` happens to be undefined, we'll see a programming error about it and fix it. Otherwise, if we overuse `?.`, coding errors can be silenced where not appropriate, and become more difficult to debug.
+```
+
+````warn header="The variable before `?.` must be declared"
+If there's no variable `user` at all, then `user?.anything` triggers an error:
+
+```js run
+// ReferenceError: user is not defined
+user?.address;
+```
+The variable must be declared (e.g. `let/const/var user` or as a function parameter). The optional chaining works only for declared variables.
+````
+
+## Short-circuiting
+
+As it was said before, the `?.` immediately stops ("short-circuits") the evaluation if the left part doesn't exist.
+
+So, if there are any further function calls or operations to the right of `?.`, they won't be made.
+
+For instance:
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ```js run
 let user = null;
 let x = 0;
 
+<<<<<<< HEAD
 user?.sayHi(x++); // brak "sayHi", więc x++ nie zostanie wykonane
 
 alert(x); // 0, wartość nie została zwiększona
@@ -148,17 +292,36 @@ Optional chaining `?.` nie jest operatorem, lecz specjalnym znakiem składni, kt
 Na przykład, `?.()` jest używane do wywołania funkcji która może nie istnieć.
 
 W kodzie poniżej, niektórzy z naszych użytkowników posiadają metodę `admin`, a niektórzy nie:
+=======
+user?.sayHi(x++); // no "user", so the execution doesn't reach sayHi call and x++
+
+alert(x); // 0, value not incremented
+```
+
+## Other variants: ?.(), ?.[]
+
+The optional chaining `?.` is not an operator, but a special syntax construct, that also works with functions and square brackets.
+
+For example, `?.()` is used to call a function that may not exist.
+
+In the code below, some of our users have `admin` method, and some don't:
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ```js run
 let userAdmin = {
   admin() {
+<<<<<<< HEAD
     alert("Jestem administratorem");
+=======
+    alert("I am admin");
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
   }
 };
 
 let userGuest = {};
 
 *!*
+<<<<<<< HEAD
 userAdmin.admin?.(); // Jestem administratorem
 */!*
 
@@ -172,6 +335,21 @@ W tym wypadku, w obu liniach najpierw użyliśmy kropki (`userAdmin.admin`) aby
 Następnie `?.()` sprawdza lewą część: jeśli funkcja admin istnieje, wtedy zostaje wywołana (tak się dzieje w przypadku `userAdmin`). W innym wypadku (dla `userGuest`) wywołanie zatrzymuje się bez błędów.
 
 Składnia `?.[]` również działa, jeśli chcielibyśmy użyć nawiasów kwadratowych `[]` aby odczytać właściwości zamiast kropki `.`. Podobnie do poprzednich przykładów, pozwala to w bezpieczny sposób odczytać wartość z objektu który może nie istnieć.
+=======
+userAdmin.admin?.(); // I am admin
+*/!*
+
+*!*
+userGuest.admin?.(); // nothing happens (no such method)
+*/!*
+```
+
+Here, in both lines we first use the dot (`userAdmin.admin`) to get `admin` property, because we assume that the `user` object exists, so it's safe read from it.
+
+Then `?.()` checks the left part: if the `admin` function exists, then it runs (that's so for `userAdmin`). Otherwise (for `userGuest`) the evaluation stops without errors.
+
+The `?.[]` syntax also works, if we'd like to use brackets `[]` to access properties instead of dot `.`. Similar to previous cases, it allows to safely read a property from an object that may not exist.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ```js run
 let key = "firstName";
@@ -186,6 +364,7 @@ alert( user1?.[key] ); // John
 alert( user2?.[key] ); // undefined
 ```
 
+<<<<<<< HEAD
 Możemy również użyć `?.` w połączeniu z `delete`:
 
 ```js run
@@ -194,11 +373,22 @@ delete user?.name; // usuń user.name jeśli user istnieje
 
 ````warn header="Możemy użyć `?.` aby bezpiecznie odczytywać i usuwać, ale nie przypisywać"
 Optional chaining `?.` nie ma zastosowania po lewej stronie przypisania.
+=======
+Also we can use `?.` with `delete`:
+
+```js run
+delete user?.name; // delete user.name if user exists
+```
+
+````warn header="We can use `?.` for safe reading and deleting, but not writing"
+The optional chaining `?.` has no use on the left side of an assignment.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 For example:
 ```js run
 let user = null;
 
+<<<<<<< HEAD
 user?.name = "John"; // Błąd, nie działa
 // ponieważ jest to równoważne do undefined = "John"
 ```
@@ -219,3 +409,24 @@ Jak możemy zauważyć, wszystkie z nich są przystępne i proste w użyciu. Sk
 Ciąg `?.` pozwala w bezpieczny sposób uzyskać dostęp do zagnieżdzonych właściwości.
 
 Mimo wszystko, powinniśmy używać `?.` ostrożnie, tylko gdy akceptujemy to że lewa strona może nie istnieć. Tak aby wszelkie błędy nie zostały przed nami ukryte, jeśli już wystąpią.
+=======
+user?.name = "John"; // Error, doesn't work
+// because it evaluates to: undefined = "John"
+```
+
+````
+
+## Summary
+
+The optional chaining `?.` syntax has three forms:
+
+1. `obj?.prop` -- returns `obj.prop` if `obj` exists, otherwise `undefined`.
+2. `obj?.[prop]` -- returns `obj[prop]` if `obj` exists, otherwise `undefined`.
+3. `obj.method?.()` -- calls `obj.method()` if `obj.method` exists, otherwise returns `undefined`.
+
+As we can see, all of them are straightforward and simple to use. The `?.` checks the left part for `null/undefined` and allows the evaluation to proceed if it's not so.
+
+A chain of `?.` allows to safely access nested properties.
+
+Still, we should apply `?.` carefully, only where it's acceptable, according to our code logic, that the left part doesn't exist. So that it won't hide programming errors from us, if they occur.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
diff --git a/1-js/04-object-basics/03-symbol/article.md b/1-js/04-object-basics/08-symbol/article.md
similarity index 78%
rename from 1-js/04-object-basics/03-symbol/article.md
rename to 1-js/04-object-basics/08-symbol/article.md
index a17f85fe2..10a98af0a 100644
--- a/1-js/04-object-basics/03-symbol/article.md
+++ b/1-js/04-object-basics/08-symbol/article.md
@@ -1,9 +1,16 @@
 
 # Symbol type
 
-By specification, object property keys may be either of string type, or of symbol type. Not numbers, not booleans, only strings or symbols, these two types.
+By specification, only two primitive types may serve as object property keys:
 
-Till now we've been using only strings. Now let's see the benefits that symbols can give us.
+- string type, or
+- symbol type.
+
+Otherwise, if one uses another type, such as number, it's autoconverted to string. So that `obj[1]` is the same as `obj["1"]`, and `obj[true]` is the same as `obj["true"]`.
+
+Until now we've been using only strings.
+
+Now let's explore symbols, see what they can do for us.
 
 ## Symbols
 
@@ -12,18 +19,17 @@ A "symbol" represents a unique identifier.
 A value of this type can be created using `Symbol()`:
 
 ```js
-// id is a new symbol
 let id = Symbol();
 ```
 
-Upon creation, we can give symbol a description (also called a symbol name), mostly useful for debugging purposes:
+Upon creation, we can give symbols a description (also called a symbol name), mostly useful for debugging purposes:
 
-```js run
+```js
 // id is a symbol with the description "id"
 let id = Symbol("id");
 ```
 
-Symbols are guaranteed to be unique. Even if we create many symbols with the same description, they are different values. The description is just a label that doesn't affect anything.
+Symbols are guaranteed to be unique. Even if we create many symbols with exactly the same description, they are different values. The description is just a label that doesn't affect anything.
 
 For instance, here are two symbols with the same description -- they are not equal:
 
@@ -38,6 +44,8 @@ alert(id1 == id2); // false
 
 If you are familiar with Ruby or another language that also has some sort of "symbols" -- please don't be misguided. JavaScript symbols are different.
 
+So, to summarize, a symbol is a "primitive unique value" with an optional description. Let's see where we can use them.
+
 ````warn header="Symbols don't auto-convert to a string"
 Most values in JavaScript support implicit conversion to a string. For instance, we can `alert` almost any value, and it will work. Symbols are special. They don't auto-convert.
 
@@ -53,6 +61,7 @@ alert(id); // TypeError: Cannot convert a Symbol value to a string
 That's a "language guard" against messing up, because strings and symbols are fundamentally different and should not accidentally convert one into another.
 
 If we really want to show a symbol, we need to explicitly call `.toString()` on it, like here:
+
 ```js run
 let id = Symbol("id");
 *!*
@@ -61,6 +70,7 @@ alert(id.toString()); // Symbol(id), now it works
 ```
 
 Or get `symbol.description` property to show the description only:
+
 ```js run
 let id = Symbol("id");
 *!*
@@ -72,6 +82,7 @@ alert(id.description); // id
 
 ## "Hidden" properties
 
+
 Symbols allow us to create "hidden" properties of an object, that no other part of code can accidentally access or overwrite.
 
 For instance, if we're working with `user` objects, that belong to a third-party code. We'd like to add identifiers to them.
@@ -92,9 +103,9 @@ alert( user[id] ); // we can access the data using the symbol as the key
 
 What's the benefit of using `Symbol("id")` over a string `"id"`?
 
-As `user` objects belongs to another code, and that code also works with them, we shouldn't just add any fields to it. That's unsafe. But a symbol cannot be accessed accidentally, the third-party code probably won't even see it, so it's probably all right to do.
+As `user` objects belong to another codebase, it's unsafe to add fields to them, since we might affect pre-defined behavior in that other codebase. However, symbols cannot be accessed accidentally. The third-party code won't be aware of newly defined symbols, so it's safe to add symbols to the `user` objects.
 
-Also, imagine that another script wants to have its own identifier inside `user`, for its own purposes. That may be another JavaScript library, so that the scripts are completely unaware of each other.
+Also, imagine that another script wants to have its own identifier inside `user`, for its own purposes.
 
 Then that script can create its own `Symbol("id")`, like this:
 
@@ -109,7 +120,7 @@ There will be no conflict between our and their identifiers, because symbols are
 
 ...But if we used a string `"id"` instead of a symbol for the same purpose, then there *would* be a conflict:
 
-```js run
+```js
 let user = { name: "John" };
 
 // Our script uses "id" property
@@ -121,7 +132,7 @@ user.id = "Their id value"
 // Boom! overwritten by another script!
 ```
 
-### Symbols in a literal
+### Symbols in an object literal
 
 If we want to use a symbol in an object literal `{...}`, we need square brackets around it.
 
@@ -133,7 +144,7 @@ let id = Symbol("id");
 let user = {
   name: "John",
 *!*
-  [id]: 123 // not "id: 123"
+  [id]: 123 // not "id": 123
 */!*
 };
 ```
@@ -158,10 +169,10 @@ for (let key in user) alert(key); // name, age (no symbols)
 */!*
 
 // the direct access by the symbol works
-alert( "Direct: " + user[id] );
+alert( "Direct: " + user[id] ); // Direct: 123
 ```
 
-`Object.keys(user)` also ignores them. That's a part of the general "hiding symbolic properties" principle. If another script or a library loops over our object, it won't unexpectedly access a symbolic property.
+[Object.keys(user)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys) also ignores them. That's a part of the general "hiding symbolic properties" principle. If another script or a library loops over our object, it won't unexpectedly access a symbolic property.
 
 In contrast, [Object.assign](mdn:js/Object/assign) copies both string and symbol properties:
 
@@ -178,22 +189,6 @@ alert( clone[id] ); // 123
 
 There's no paradox here. That's by design. The idea is that when we clone an object or merge objects, we usually want *all* properties to be copied (including symbols like `id`).
 
-````smart header="Property keys of other types are coerced to strings"
-We can only use strings or symbols as keys in objects. Other types are converted to strings.
-
-For instance, a number `0` becomes a string `"0"` when used as a property key:
-
-```js run
-let obj = {
-  0: "test" // same as "0": "test"
-};
-
-// both alerts access the same property (the number 0 is converted to string "0")
-alert( obj["0"] ); // test
-alert( obj[0] ); // test (same property)
-```
-````
-
 ## Global symbols
 
 As we've seen, usually all symbols are different, even if they have the same name. But sometimes we want same-named symbols to be same entities. For instance, different parts of our application want to access symbol `"id"` meaning exactly the same property.
@@ -222,12 +217,12 @@ Symbols inside the registry are called *global symbols*. If we want an applicati
 ```smart header="That sounds like Ruby"
 In some programming languages, like Ruby, there's a single symbol per name.
 
-In JavaScript, as we can see, that's right for global symbols.
+In JavaScript, as we can see, that's true for global symbols.
 ```
 
 ### Symbol.keyFor
 
-For global symbols, not only `Symbol.for(key)` returns a symbol by name, but there's a reverse call: `Symbol.keyFor(sym)`, that does the reverse: returns a name by a global symbol.
+We have seen that for global symbols, `Symbol.for(key)` returns a symbol by name. To do the opposite -- return a name by global symbol -- we can use: `Symbol.keyFor(sym)`:
 
 For instance:
 
@@ -241,9 +236,9 @@ alert( Symbol.keyFor(sym) ); // name
 alert( Symbol.keyFor(sym2) ); // id
 ```
 
-The `Symbol.keyFor` internally uses the global symbol registry to look up the key for the symbol. So it doesn't work for non-global symbols. If the symbol is not global, it won't be able to find it and return `undefined`.
+The `Symbol.keyFor` internally uses the global symbol registry to look up the key for the symbol. So it doesn't work for non-global symbols. If the symbol is not global, it won't be able to find it and returns `undefined`.
 
-That said, any symbols have `description` property.
+That said, all symbols have the `description` property.
 
 For instance:
 
@@ -284,10 +279,11 @@ Symbols are always different values, even if they have the same name. If we want
 Symbols have two main use cases:
 
 1. "Hidden" object properties.
+
     If we want to add a property into an object that "belongs" to another script or a library, we can create a symbol and use it as a property key. A symbolic property does not appear in `for..in`, so it won't be accidentally processed together with other properties. Also it won't be accessed directly, because another script does not have our symbol. So the property will be protected from accidental use or overwrite.
 
     So we can "covertly" hide something into objects that we need, but others should not see, using symbolic properties.
 
 2. There are many system symbols used by JavaScript which are accessible as `Symbol.*`. We can use them to alter some built-in behaviors. For instance, later in the tutorial we'll use `Symbol.iterator` for [iterables](info:iterable), `Symbol.toPrimitive` to setup [object-to-primitive conversion](info:object-toprimitive) and so on.
 
-Technically, symbols are not 100% hidden. There is a built-in method [Object.getOwnPropertySymbols(obj)](mdn:js/Object/getOwnPropertySymbols) that allows us to get all symbols. Also there is a method named [Reflect.ownKeys(obj)](mdn:js/Reflect/ownKeys) that returns *all* keys of an object including symbolic ones. So they are not really hidden. But most libraries, built-in functions and syntax constructs don't use these methods.
+Technically, symbols are not 100% hidden. There is a built-in method [Object.getOwnPropertySymbols(obj)](mdn:js/Object/getOwnPropertySymbols) that allows us to get all symbols. Also there is a method named [Reflect.ownKeys(obj)](mdn:js/Reflect/ownKeys) that returns *all* keys of an object including symbolic ones. But most libraries, built-in functions and syntax constructs don't use these methods.
diff --git a/1-js/04-object-basics/05-object-toprimitive/article.md b/1-js/04-object-basics/09-object-toprimitive/article.md
similarity index 59%
rename from 1-js/04-object-basics/05-object-toprimitive/article.md
rename to 1-js/04-object-basics/09-object-toprimitive/article.md
index f6b715ce5..fa68da583 100644
--- a/1-js/04-object-basics/05-object-toprimitive/article.md
+++ b/1-js/04-object-basics/09-object-toprimitive/article.md
@@ -3,19 +3,40 @@
 
 What happens when objects are added `obj1 + obj2`, subtracted `obj1 - obj2` or printed using `alert(obj)`?
 
-In that case, objects are auto-converted to primitives, and then the operation is carried out.
+JavaScript doesn't allow you to customize how operators work on objects. Unlike some other programming languages, such as Ruby or C++, we can't implement a special object method to handle addition (or other operators).
+
+In case of such operations, objects are auto-converted to primitives, and then the operation is carried out over these primitives and results in a primitive value.
+
+That's an important limitation: the result of `obj1 + obj2` (or another math operation) can't be another object!
+
+E.g. we can't make objects representing vectors or matrices (or achievements or whatever), add them and expect a "summed" object as the result. Such architectural feats are automatically "off the board".
+
+So, because we can't technically do much here, there's no maths with objects in real projects. When it happens, with rare exceptions, it's because of a coding mistake.
+
+In this chapter we'll cover how an object converts to primitive and how to customize it.
+
+We have two purposes:
+
+1. It will allow us to understand what's going on in case of coding mistakes, when such an operation happened accidentally.
+2. There are exceptions, where such operations are possible and look good. E.g. subtracting or comparing dates (`Date` objects). We'll come across them later.
+
+## Conversion rules
 
 In the chapter <info:type-conversions> we've seen the rules for numeric, string and boolean conversions of primitives. But we left a gap for objects. Now, as we know about methods and symbols it becomes possible to fill it.
 
-1. All objects are `true` in a boolean context. There are only numeric and string conversions.
+1. There's no conversion to boolean. All objects are `true` in a boolean context, as simple as that. There exist only numeric and string conversions.
 2. The numeric conversion happens when we subtract objects or apply mathematical functions. For instance, `Date` objects (to be covered in the chapter <info:date>) can be subtracted, and the result of `date1 - date2` is the time difference between two dates.
-3. As for the string conversion -- it usually happens when we output an object like `alert(obj)` and in similar contexts.
+3. As for the string conversion -- it usually happens when we output an object with `alert(obj)` and in similar contexts.
+
+We can implement string and numeric conversion by ourselves, using special object methods.
 
-## ToPrimitive
+Now let's get into technical details, because it's the only way to cover the topic in-depth.
 
-We can fine-tune string and numeric conversion, using special object methods.
+## Hints
 
-There are three variants of type conversion, so-called "hints", described in the [specification](https://tc39.github.io/ecma262/#sec-toprimitive):
+How does JavaScript decide which conversion to apply?
+
+There are three variants of type conversion, that happen in various situations. They're called "hints", as described in the [specification](https://tc39.github.io/ecma262/#sec-toprimitive):
 
 `"string"`
 : For an object-to-string conversion, when we're doing an operation on an object that expects a string, like `alert`:
@@ -43,10 +64,12 @@ There are three variants of type conversion, so-called "hints", described in the
     let greater = user1 > user2;
     ```
 
+    Most built-in mathematical functions also include such conversion.
+
 `"default"`
 : Occurs in rare cases when the operator is "not sure" what type to expect.
 
-    For instance, binary plus `+` can work both with strings (concatenates them) and numbers (adds them), so both strings and numbers would do. So if the a binary plus gets an object as an argument, it uses the `"default"` hint to convert it.
+    For instance, binary plus `+` can work both with strings (concatenates them) and numbers (adds them). So if a binary plus gets an object as an argument, it uses the `"default"` hint to convert it.
 
     Also, if an object is compared using `==` with a string, number or a symbol, it's also unclear which conversion should be done, so the `"default"` hint is used.
 
@@ -60,21 +83,19 @@ There are three variants of type conversion, so-called "hints", described in the
 
     The greater and less comparison operators, such as `<` `>`, can work with both strings and numbers too. Still, they use the `"number"` hint, not `"default"`. That's for historical reasons.
 
-    In practice though, we don't need to remember these peculiar details, because all built-in objects except for one case (`Date` object, we'll learn it later) implement `"default"` conversion the same way as `"number"`. And we can do the same.
+In practice though, things are a bit simpler.
 
-```smart header="No `\"boolean\"` hint"
-Please note -- there are only three hints. It's that simple.
+All built-in objects except for one case (`Date` object, we'll learn it later) implement `"default"` conversion the same way as `"number"`. And we probably should do the same.
 
-There is no "boolean" hint (all objects are `true` in boolean context) or anything else. And if we treat `"default"` and `"number"` the same, like most built-ins do, then there are only two conversions.
-```
+Still, it's important to know about all 3 hints, soon we'll see why.
 
 **To do the conversion, JavaScript tries to find and call three object methods:**
 
 1. Call `obj[Symbol.toPrimitive](hint)` - the method with the symbolic key `Symbol.toPrimitive` (system symbol), if such method exists,
 2. Otherwise if hint is `"string"`
-    - try `obj.toString()` and `obj.valueOf()`, whatever exists.
+    - try calling `obj.toString()` or `obj.valueOf()`, whatever exists.
 3. Otherwise if hint is `"number"` or `"default"`
-    - try `obj.valueOf()` and `obj.toString()`, whatever exists.
+    - try calling `obj.valueOf()` or `obj.toString()`, whatever exists.
 
 ## Symbol.toPrimitive
 
@@ -82,11 +103,14 @@ Let's start from the first method. There's a built-in symbol named `Symbol.toPri
 
 ```js
 obj[Symbol.toPrimitive] = function(hint) {
-  // must return a primitive value
+  // here goes the code to convert this object to a primitive
+  // it must return a primitive value
   // hint = one of "string", "number", "default"
 };
 ```
 
+If the method `Symbol.toPrimitive` exists, it's used for all hints, and no more methods are needed.
+
 For instance, here `user` object implements it:
 
 ```js run
@@ -106,17 +130,16 @@ alert(+user); // hint: number -> 1000
 alert(user + 500); // hint: default -> 1500
 ```
 
-As we can see from the code, `user` becomes a self-descriptive string or a money amount depending on the conversion. The single method `user[Symbol.toPrimitive]` handles all conversion cases.
-
+As we can see from the code, `user` becomes a self-descriptive string or a money amount, depending on the conversion. The single method `user[Symbol.toPrimitive]` handles all conversion cases.
 
 ## toString/valueOf
 
-Methods `toString` and `valueOf` come from ancient times. They are not symbols (symbols did not exist that long ago), but rather "regular" string-named methods. They provide an alternative "old-style" way to implement the conversion.
+If there's no `Symbol.toPrimitive` then JavaScript tries to find methods `toString` and `valueOf`:
 
-If there's no `Symbol.toPrimitive` then JavaScript tries to find them and try in the order:
+- For the `"string"` hint: call `toString` method, and if it doesn't exist or if it returns an object instead of a primitive value, then call `valueOf` (so `toString` has the priority for string conversions).
+- For other hints: call `valueOf`, and if it doesn't exist or if it returns an object instead of a primitive value, then call `toString` (so `valueOf` has the priority for maths).
 
-- `toString -> valueOf` for "string" hint.
-- `valueOf -> toString` otherwise.
+Methods `toString` and `valueOf` come from ancient times. They are not symbols (symbols did not exist that long ago), but rather "regular" string-named methods. They provide an alternative "old-style" way to implement the conversion.
 
 These methods must return a primitive value. If `toString` or `valueOf` returns an object, then it's ignored (same as if there were no method).
 
@@ -136,9 +159,9 @@ alert(user.valueOf() === user); // true
 
 So if we try to use an object as a string, like in an `alert` or so, then by default we see `[object Object]`.
 
-And the default `valueOf` is mentioned here only for the sake of completeness, to avoid any confusion. As you can see, it returns the object itself, and so is ignored. Don't ask me why, that's for historical reasons. So we can assume it doesn't exist.
+The default `valueOf` is mentioned here only for the sake of completeness, to avoid any confusion. As you can see, it returns the object itself, and so is ignored. Don't ask me why, that's for historical reasons. So we can assume it doesn't exist.
 
-Let's implement these methods.
+Let's implement these methods to customize the conversion.
 
 For instance, here `user` does the same as above using a combination of `toString` and `valueOf` instead of `Symbol.toPrimitive`:
 
@@ -183,27 +206,27 @@ alert(user + 500); // toString -> John500
 
 In the absence of `Symbol.toPrimitive` and `valueOf`, `toString` will handle all primitive conversions.
 
-## Return types
+### A conversion can return any primitive type
 
 The important thing to know about all primitive-conversion methods is that they do not necessarily return the "hinted" primitive.
 
-There is no control whether `toString` returns exactly a string, or whether `Symbol.toPrimitive` method returns a number for a hint `"number"`.
+There is no control whether `toString` returns exactly a string, or whether `Symbol.toPrimitive` method returns a number for the hint `"number"`.
 
 The only mandatory thing: these methods must return a primitive, not an object.
 
 ```smart header="Historical notes"
 For historical reasons, if `toString` or `valueOf` returns an object, there's no error, but such value is ignored (like if the method didn't exist). That's because in ancient times there was no good "error" concept in JavaScript.
 
-In contrast, `Symbol.toPrimitive` *must* return a primitive, otherwise there will be an error.
+In contrast, `Symbol.toPrimitive` is stricter, it *must* return a primitive, otherwise there will be an error.
 ```
 
 ## Further conversions
 
 As we know already, many operators and functions perform type conversions, e.g. multiplication `*` converts operands to numbers.
 
-If we pass an object as an argument, then there are two stages:
+If we pass an object as an argument, then there are two stages of calculations:
 1. The object is converted to a primitive (using the rules described above).
-2. If the resulting primitive isn't of the right type, it's converted.
+2. If necessary for further calculations, the resulting primitive is also converted.
 
 For instance:
 
@@ -230,7 +253,7 @@ let obj = {
   }
 };
 
-alert(obj + 2); // 22 ("2" + 2), conversion to primitive returned a string => concatenation
+alert(obj + 2); // "22" ("2" + 2), conversion to primitive returned a string => concatenation
 ```
 
 ## Summary
@@ -240,16 +263,18 @@ The object-to-primitive conversion is called automatically by many built-in func
 There are 3 types (hints) of it:
 - `"string"` (for `alert` and other operations that need a string)
 - `"number"` (for maths)
-- `"default"` (few operators)
+- `"default"` (few operators, usually objects implement it the same way as `"number"`)
 
-The specification describes explicitly which operator uses which hint. There are very few operators that "don't know what to expect" and use the `"default"` hint. Usually for built-in objects `"default"` hint is handled the same way as `"number"`, so in practice the last two are often merged together.
+The specification describes explicitly which operator uses which hint.
 
 The conversion algorithm is:
 
 1. Call `obj[Symbol.toPrimitive](hint)` if the method exists,
 2. Otherwise if hint is `"string"`
-    - try `obj.toString()` and `obj.valueOf()`, whatever exists.
+    - try calling `obj.toString()` or `obj.valueOf()`, whatever exists.
 3. Otherwise if hint is `"number"` or `"default"`
-    - try `obj.valueOf()` and `obj.toString()`, whatever exists.
+    - try calling `obj.valueOf()` or `obj.toString()`, whatever exists.
+
+All these methods must return a primitive to work (if defined).
 
-In practice, it's often enough to implement only `obj.toString()` as a "catch-all" method for all conversions that return a "human-readable" representation of an object, for logging or debugging purposes.  
+In practice, it's often enough to implement only `obj.toString()` as a "catch-all" method for string conversions that should return a "human-readable" representation of an object, for logging or debugging purposes.
diff --git a/1-js/05-data-types/01-primitives-methods/1-string-new-property/task.md b/1-js/05-data-types/01-primitives-methods/1-string-new-property/task.md
index 5988fde5a..a48b24b3a 100644
--- a/1-js/05-data-types/01-primitives-methods/1-string-new-property/task.md
+++ b/1-js/05-data-types/01-primitives-methods/1-string-new-property/task.md
@@ -15,4 +15,8 @@ str.test = 5;
 alert(str.test);
 ```
 
+<<<<<<< HEAD
 Jak sądzisz, czy to zadziała? Co się pokaże?
+=======
+What do you think, will it work? What will be shown?
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
diff --git a/1-js/05-data-types/01-primitives-methods/article.md b/1-js/05-data-types/01-primitives-methods/article.md
index c92249e8d..432b51c6e 100644
--- a/1-js/05-data-types/01-primitives-methods/article.md
+++ b/1-js/05-data-types/01-primitives-methods/article.md
@@ -51,8 +51,38 @@ Rozwiązanie wygląda jest trochę dziwne. Oto ono:
  
 "Wrappery obiektów" są różne dla każdego typu podstawowego i nazywają się: `String`, `Number`, `Boolean` i `Symbol`. W ten sposób zapewniają różne zestawy metod.
 
+<<<<<<< HEAD
 Istnieje na przykład metoda typu tekstowego [str.toUpperCase()](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase) która zwraca skapitalizowane `str`.
 Oto jak działa:
+=======
+So here we've made an object `john` with the method `sayHi`.
+
+Many built-in objects already exist, such as those that work with dates, errors, HTML elements, etc. They have different properties and methods.
+
+But, these features come with a cost!
+
+Objects are "heavier" than primitives. They require additional resources to support the internal machinery.
+
+## A primitive as an object
+
+Here's the paradox faced by the creator of JavaScript:
+
+- There are many things one would want to do with a primitive, like a string or a number. It would be great to access them using methods.
+- Primitives must be as fast and lightweight as possible.
+
+The solution looks a little bit awkward, but here it is:
+
+1. Primitives are still primitive. A single value, as desired.
+2. The language allows access to methods and properties of strings, numbers, booleans and symbols.
+3. In order for that to work, a special "object wrapper" that provides the extra functionality is created, and then is destroyed.
+
+The "object wrappers" are different for each primitive type and are called: `String`, `Number`, `Boolean`, `Symbol` and `BigInt`. Thus, they provide different sets of methods.
+
+For instance, there exists a string method [str.toUpperCase()](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase) that returns a capitalized `str`.
+
+Here's how it works:
+
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 ```js run
 let str = "Cześć";
 
@@ -98,9 +128,16 @@ if (zero) { // zero jest prawdziwe, ponieważ jest obiektem
 }
 ```
 
+<<<<<<< HEAD
 Z drugiej strony, używając samych funkcji `String/Number/Boolean` bez operatora `new` jest całkowicie rozsądne i użyteczne. Zamieniają one wartości na odpowiadające im typy: typ tekstowy, liczbowy logiczny (typy podstawowe).
 
 Na przykład jest to całkowicie poprawne:
+=======
+On the other hand, using the same functions `String/Number/Boolean` without `new` is totally fine and useful thing. They convert a value to the corresponding type: to a string, a number, or a boolean (primitive).
+
+For example, this is entirely valid:
+
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 ```js
 let num = Number("123"); // zamienia ciąg znaków na liczbę
 ```
diff --git a/1-js/05-data-types/02-number/2-why-rounded-down/solution.md b/1-js/05-data-types/02-number/2-why-rounded-down/solution.md
index a17a4671a..4bcd74512 100644
--- a/1-js/05-data-types/02-number/2-why-rounded-down/solution.md
+++ b/1-js/05-data-types/02-number/2-why-rounded-down/solution.md
@@ -28,6 +28,6 @@ Note that `63.5` has no precision loss at all. That's because the decimal part `
 
 
 ```js run
-alert( Math.round(6.35 * 10) / 10); // 6.35 -> 63.5 -> 64(rounded) -> 6.4
+alert( Math.round(6.35 * 10) / 10 ); // 6.35 -> 63.5 -> 64(rounded) -> 6.4
 ```
 
diff --git a/1-js/05-data-types/02-number/article.md b/1-js/05-data-types/02-number/article.md
index d167b836e..96a7b622a 100644
--- a/1-js/05-data-types/02-number/article.md
+++ b/1-js/05-data-types/02-number/article.md
@@ -2,9 +2,9 @@
 
 In modern JavaScript, there are two types of numbers:
 
-1. Regular numbers in JavaScript are stored in 64-bit format [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754-2008_revision), also known as "double precision floating point numbers". These are numbers that we're using most of the time, and we'll talk about them in this chapter.
+1. Regular numbers in JavaScript are stored in 64-bit format [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754), also known as "double precision floating point numbers". These are numbers that we're using most of the time, and we'll talk about them in this chapter.
 
-2. BigInt numbers, to represent integers of arbitrary length. They are sometimes needed, because a regular number can't exceed <code>2<sup>53</sup></code> or be less than <code>-2<sup>53</sup></code>. As bigints are used in few special areas, we devote them a special chapter <info:bigint>.
+2. BigInt numbers represent integers of arbitrary length. They are sometimes needed because a regular integer number can't safely exceed <code>(2<sup>53</sup>-1)</code> or be less than <code>-(2<sup>53</sup>-1)</code>, as we mentioned earlier in the chapter <info:types>. As bigints are used in a few special areas, we devote them to a special chapter <info:bigint>.
 
 So here we'll talk about regular numbers. Let's expand our knowledge of them.
 
@@ -16,45 +16,56 @@ Imagine we need to write 1 billion. The obvious way is:
 let billion = 1000000000;
 ```
 
-But in real life, we usually avoid writing a long string of zeroes as it's easy to mistype. Also, we are lazy. We will usually write something like `"1bn"` for a billion or `"7.3bn"` for 7 billion 300 million. The same is true for most large numbers.
+We also can use underscore `_` as the separator:
 
-In JavaScript, we shorten a number by appending the letter `"e"` to the number and specifying the zeroes count:
+```js
+let billion = 1_000_000_000;
+```
+
+Here the underscore `_` plays the role of the "[syntactic sugar](https://en.wikipedia.org/wiki/Syntactic_sugar)", it makes the number more readable. The JavaScript engine simply ignores `_` between digits, so it's exactly the same one billion as above.
+
+In real life though, we try to avoid writing long sequences of zeroes. We're too lazy for that. We'll try to write something like `"1bn"` for a billion or `"7.3bn"` for 7 billion 300 million. The same is true for most large numbers.
+
+In JavaScript, we can shorten a number by appending the letter `"e"` to it and specifying the zeroes count:
 
 ```js run
 let billion = 1e9;  // 1 billion, literally: 1 and 9 zeroes
 
-alert( 7.3e9 );  // 7.3 billions (7,300,000,000)
+alert( 7.3e9 );  // 7.3 billions (same as 7300000000 or 7_300_000_000)
 ```
 
-In other words, `"e"` multiplies the number by `1` with the given zeroes count.
+In other words, `e` multiplies the number by `1` with the given zeroes count.
 
 ```js
-1e3 = 1 * 1000
-1.23e6 = 1.23 * 1000000
+1e3 === 1 * 1000; // e3 means *1000
+1.23e6 === 1.23 * 1000000; // e6 means *1000000
 ```
 
-Now let's write something very small. Say, 1 microsecond (one millionth of a second):
+Now let's write something very small. Say, 1 microsecond (one-millionth of a second):
 
 ```js
-let ms = 0.000001;
+let mсs = 0.000001;
 ```
 
-Just like before, using `"e"` can help. If we'd like to avoid writing the zeroes explicitly, we could say the same as:
+Just like before, using `"e"` can help. If we'd like to avoid writing the zeroes explicitly, we could write the same as:
 
 ```js
-let ms = 1e-6; // six zeroes to the left from 1
+let mcs = 1e-6; // five zeroes to the left from 1
 ```
 
-If we count the zeroes in `0.000001`, there are 6 of them. So naturally it's `1e-6`.  
+If we count the zeroes in `0.000001`, there are 6 of them. So naturally it's `1e-6`.
 
 In other words, a negative number after `"e"` means a division by 1 with the given number of zeroes:
 
 ```js
 // -3 divides by 1 with 3 zeroes
-1e-3 = 1 / 1000 (=0.001)
+1e-3 === 1 / 1000; // 0.001
 
 // -6 divides by 1 with 6 zeroes
-1.23e-6 = 1.23 / 1000000 (=0.00000123)
+1.23e-6 === 1.23 / 1000000; // 0.00000123
+
+// an example with a bigger number
+1234e-2 === 1234 / 100; // 12.34, decimal point moves 2 times
 ```
 
 ### Hex, binary and octal numbers
@@ -92,13 +103,13 @@ alert( num.toString(16) );  // ff
 alert( num.toString(2) );   // 11111111
 ```
 
-The `base` can vary from `2` to `36`. By default it's `10`.
+The `base` can vary from `2` to `36`. By default, it's `10`.
 
 Common use cases for this are:
 
 - **base=16** is used for hex colors, character encodings etc, digits can be `0..9` or `A..F`.
 - **base=2** is mostly for debugging bitwise operations, digits can be `0` or `1`.
-- **base=36** is the maximum, digits can be `0..9` or `A..Z`. The whole latin alphabet is used to represent a number. A funny, but useful case for `36` is when we need to turn a long numeric identifier into something shorter, for example to make a short url. Can simply represent it in the numeral system with base `36`:
+- **base=36** is the maximum, digits can be `0..9` or `A..Z`. The whole Latin alphabet is used to represent a number. A funny, but useful case for `36` is when we need to turn a long numeric identifier into something shorter, for example, to make a short url. Can simply represent it in the numeral system with base `36`:
 
     ```js run
     alert( 123456..toString(36) ); // 2n9c
@@ -110,6 +121,7 @@ Please note that two dots in `123456..toString(36)` is not a typo. If we want to
 If we placed a single dot: `123456.toString(36)`, then there would be an error, because JavaScript syntax implies the decimal part after the first dot. And if we place one more dot, then JavaScript knows that the decimal part is empty and now goes the method.
 
 Also could write `(123456).toString(36)`.
+
 ```
 
 ## Rounding
@@ -125,7 +137,7 @@ There are several built-in functions for rounding:
 : Rounds up: `3.1` becomes `4`, and `-1.1` becomes `-1`.
 
 `Math.round`
-: Rounds to the nearest integer: `3.1` becomes `3`, `3.6` becomes `4` and `-1.1` becomes `-1`.
+: Rounds to the nearest integer: `3.1` becomes `3`, `3.6` becomes `4`. In the middle cases `3.5` rounds up to `4`, and `-3.5` rounds up to `-3`.
 
 `Math.trunc` (not supported by Internet Explorer)
 : Removes anything after the decimal point without rounding: `3.1` becomes `3`, `-1.1` becomes `-1`.
@@ -135,8 +147,10 @@ Here's the table to summarize the differences between them:
 |   | `Math.floor` | `Math.ceil` | `Math.round` | `Math.trunc` |
 |---|---------|--------|---------|---------|
 |`3.1`|  `3`    |   `4`  |    `3`  |   `3`   |
+|`3.5`|  `3`    |   `4`  |    `4`  |   `3`   |
 |`3.6`|  `3`    |   `4`  |    `4`  |   `3`   |
 |`-1.1`|  `-2`    |   `-1`  |    `-1`  |   `-1`   |
+|`-1.5`|  `-2`    |   `-1`  |    `-1`  |   `-1`   |
 |`-1.6`|  `-2`    |   `-1`  |    `-2`  |   `-1`   |
 
 
@@ -152,7 +166,7 @@ There are two ways to do so:
     ```js run
     let num = 1.23456;
 
-    alert( Math.floor(num * 100) / 100 ); // 1.23456 -> 123.456 -> 123 -> 1.23
+    alert( Math.round(num * 100) / 100 ); // 1.23456 -> 123.456 -> 123 -> 1.23
     ```
 
 2. The method [toFixed(n)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed) rounds the number to `n` digits after the point and returns a string representation of the result.
@@ -169,20 +183,20 @@ There are two ways to do so:
     alert( num.toFixed(1) ); // "12.4"
     ```
 
-    Please note that result of `toFixed` is a string. If the decimal part is shorter than required, zeroes are appended to the end:
+    Please note that the result of `toFixed` is a string. If the decimal part is shorter than required, zeroes are appended to the end:
 
     ```js run
     let num = 12.34;
     alert( num.toFixed(5) ); // "12.34000", added zeroes to make exactly 5 digits
     ```
 
-    We can convert it to a number using the unary plus or a `Number()` call: `+num.toFixed(5)`.
+    We can convert it to a number using the unary plus or a `Number()` call, e.g. write `+num.toFixed(5)`.
 
 ## Imprecise calculations
 
-Internally, a number is represented in 64-bit format [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754-2008_revision), so there are exactly 64 bits to store a number: 52 of them are used to store the digits, 11 of them store the position of the decimal point (they are zero for integer numbers), and 1 bit is for the sign.
+Internally, a number is represented in 64-bit format [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754), so there are exactly 64 bits to store a number: 52 of them are used to store the digits, 11 of them store the position of the decimal point, and 1 bit is for the sign.
 
-If a number is too big, it would overflow the 64-bit storage, potentially giving an infinity:
+If a number is really huge, it may overflow the 64-bit storage and become a special numeric value `Infinity`:
 
 ```js run
 alert( 1e500 ); // Infinity
@@ -190,7 +204,7 @@ alert( 1e500 ); // Infinity
 
 What may be a little less obvious, but happens quite often, is the loss of precision.
 
-Consider this (falsy!) test:
+Consider this (falsy!) equality test:
 
 ```js run
 alert( 0.1 + 0.2 == 0.3 ); // *!*false*/!*
@@ -204,13 +218,19 @@ Strange! What is it then if not `0.3`?
 alert( 0.1 + 0.2 ); // 0.30000000000000004
 ```
 
-Ouch! There are more consequences than an incorrect comparison here. Imagine you're making an e-shopping site and the visitor puts `$0.10` and `$0.20` goods into their cart. The order total will be `$0.30000000000000004`. That would surprise anyone.
+Ouch! Imagine you're making an e-shopping site and the visitor puts `$0.10` and `$0.20` goods into their cart. The order total will be `$0.30000000000000004`. That would surprise anyone.
 
 But why does this happen?
 
 A number is stored in memory in its binary form, a sequence of bits - ones and zeroes. But fractions like `0.1`, `0.2` that look simple in the decimal numeric system are actually unending fractions in their binary form.
 
-In other words, what is `0.1`? It is one divided by ten `1/10`, one-tenth. In decimal numeral system such numbers are easily representable. Compare it to one-third: `1/3`. It becomes an endless fraction `0.33333(3)`.
+```js run
+alert(0.1.toString(2)); // 0.0001100110011001100110011001100110011001100110011001101
+alert(0.2.toString(2)); // 0.001100110011001100110011001100110011001100110011001101
+alert((0.1 + 0.2).toString(2)); // 0.0100110011001100110011001100110011001100110011001101
+```
+
+What is `0.1`? It is one divided by ten `1/10`, one-tenth. In the decimal numeral system, such numbers are easily representable. Compare it to one-third: `1/3`. It becomes an endless fraction `0.33333(3)`.
 
 So, division by powers `10` is guaranteed to work well in the decimal system, but division by `3` is not. For the same reason, in the binary numeral system, the division by powers of `2` is guaranteed to work, but `1/10` becomes an endless binary fraction.
 
@@ -230,14 +250,14 @@ That's why `0.1 + 0.2` is not exactly `0.3`.
 ```smart header="Not only JavaScript"
 The same issue exists in many other programming languages.
 
-PHP, Java, C, Perl, Ruby give exactly the same result, because they are based on the same numeric format.
+PHP, Java, C, Perl, and Ruby give exactly the same result, because they are based on the same numeric format.
 ```
 
 Can we work around the problem? Sure, the most reliable method is to round the result with the help of a method [toFixed(n)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed):
 
 ```js run
 let sum = 0.1 + 0.2;
-alert( sum.toFixed(2) ); // 0.30
+alert( sum.toFixed(2) ); // "0.30"
 ```
 
 Please note that `toFixed` always returns a string. It ensures that it has 2 digits after the decimal point. That's actually convenient if we have an e-shopping and need to show `$0.30`. For other cases, we can use the unary plus to coerce it into a number:
@@ -254,7 +274,7 @@ alert( (0.1 * 10 + 0.2 * 10) / 10 ); // 0.3
 alert( (0.28 * 100 + 0.14 * 100) / 100); // 0.4200000000000001
 ```
 
-So, multiply/divide approach reduces the error, but doesn't remove it totally.
+So, the multiply/divide approach reduces the error, but doesn't remove it totally.
 
 Sometimes we could try to evade fractions at all. Like if we're dealing with a shop, then we can store prices in cents instead of dollars. But what if we apply a discount of 30%? In practice, totally evading fractions is rarely possible. Just round them to cut "tails" when needed.
 
@@ -276,7 +296,7 @@ Another funny consequence of the internal representation of numbers is the exist
 
 That's because a sign is represented by a single bit, so it can be set or not set for any number including a zero.
 
-In most cases the distinction is unnoticeable, because operators are suited to treat them as the same.
+In most cases, the distinction is unnoticeable, because operators are suited to treat them as the same.
 ```
 
 ## Tests: isFinite and isNaN
@@ -296,7 +316,7 @@ They belong to the type `number`, but are not "normal" numbers, so there are spe
     alert( isNaN("str") ); // true
     ```
 
-    But do we need this function? Can't we just use the comparison `=== NaN`? Sorry, but the answer is no. The value `NaN` is unique in that it does not equal anything, including itself:
+    But do we need this function? Can't we just use the comparison `=== NaN`? Unfortunately not. The value `NaN` is unique in that it does not equal anything, including itself:
 
     ```js run
     alert( NaN === NaN ); // false
@@ -320,18 +340,46 @@ let num = +prompt("Enter a number", '');
 alert( isFinite(num) );
 ```
 
-Please note that an empty or a space-only string is treated as `0` in all numeric functions including `isFinite`.  
+Please note that an empty or a space-only string is treated as `0` in all numeric functions including `isFinite`.
+
+````smart header="`Number.isNaN` and `Number.isFinite`"
+[Number.isNaN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN) and [Number.isFinite](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isFinite) methods are the more "strict" versions of `isNaN` and `isFinite` functions. They do not autoconvert their argument into a number, but check if it belongs to the `number` type instead.
+
+- `Number.isNaN(value)` returns `true` if the argument belongs to the `number` type and it is `NaN`. In any other case, it returns `false`.
 
-```smart header="Compare with `Object.is`"
+    ```js run
+    alert( Number.isNaN(NaN) ); // true
+    alert( Number.isNaN("str" / 2) ); // true
+
+    // Note the difference:
+    alert( Number.isNaN("str") ); // false, because "str" belongs to the string type, not the number type
+    alert( isNaN("str") ); // true, because isNaN converts string "str" into a number and gets NaN as a result of this conversion
+    ```
+
+- `Number.isFinite(value)` returns `true` if the argument belongs to the `number` type and it is not `NaN/Infinity/-Infinity`. In any other case, it returns `false`.
+
+    ```js run
+    alert( Number.isFinite(123) ); // true
+    alert( Number.isFinite(Infinity) ); // false
+    alert( Number.isFinite(2 / 0) ); // false
 
-There is a special built-in method [Object.is](mdn:js/Object/is) that compares values like `===`, but is more reliable for two edge cases:
+    // Note the difference:
+    alert( Number.isFinite("123") ); // false, because "123" belongs to the string type, not the number type
+    alert( isFinite("123") ); // true, because isFinite converts string "123" into a number 123
+    ```
+
+In a way, `Number.isNaN` and `Number.isFinite` are simpler and more straightforward than `isNaN` and `isFinite` functions. In practice though, `isNaN` and `isFinite` are mostly used, as they're shorter to write.
+````
+
+```smart header="Comparison with `Object.is`"
+There is a special built-in method `Object.is` that compares values like `===`, but is more reliable for two edge cases:
 
 1. It works with `NaN`: `Object.is(NaN, NaN) === true`, that's a good thing.
-2. Values `0` and `-0` are different: `Object.is(0, -0) === false`, technically that's true, because internally the number has a sign bit that may be different even if all other bits are zeroes.
+2. Values `0` and `-0` are different: `Object.is(0, -0) === false`, technically that's correct because internally the number has a sign bit that may be different even if all other bits are zeroes.
 
 In all other cases, `Object.is(a, b)` is the same as `a === b`.
 
-This way of comparison is often used in JavaScript specification. When an internal algorithm needs to compare two values for being exactly the same, it uses `Object.is` (internally called [SameValue](https://tc39.github.io/ecma262/#sec-samevalue)).
+We mention `Object.is` here, because it's often used in JavaScript specification. When an internal algorithm needs to compare two values for being exactly the same, it uses `Object.is` (internally called [SameValue](https://tc39.github.io/ecma262/#sec-samevalue)).
 ```
 
 
@@ -345,7 +393,7 @@ alert( +"100px" ); // NaN
 
 The sole exception is spaces at the beginning or at the end of the string, as they are ignored.
 
-But in real life we often have values in units, like `"100px"` or `"12pt"` in CSS. Also in many countries the currency symbol goes after the amount, so we have `"19€"` and would like to extract a numeric value out of that.
+But in real life, we often have values in units, like `"100px"` or `"12pt"` in CSS. Also in many countries, the currency symbol goes after the amount, so we have `"19€"` and would like to extract a numeric value out of that.
 
 That's what `parseInt` and `parseFloat` are for.
 
@@ -383,7 +431,7 @@ JavaScript has a built-in [Math](https://developer.mozilla.org/en/docs/Web/JavaS
 A few examples:
 
 `Math.random()`
-: Returns a random number from 0 to 1 (not including 1)
+: Returns a random number from 0 to 1 (not including 1).
 
     ```js run
     alert( Math.random() ); // 0.1234567894322
@@ -391,8 +439,8 @@ A few examples:
     alert( Math.random() ); // ... (any random numbers)
     ```
 
-`Math.max(a, b, c...)` / `Math.min(a, b, c...)`
-: Returns the greatest/smallest from the arbitrary number of arguments.
+`Math.max(a, b, c...)` and `Math.min(a, b, c...)`
+: Returns the greatest and smallest from the arbitrary number of arguments.
 
     ```js run
     alert( Math.max(3, 5, -10, 0, 1) ); // 5
@@ -400,13 +448,13 @@ A few examples:
     ```
 
 `Math.pow(n, power)`
-: Returns `n` raised the given power
+: Returns `n` raised to the given power.
 
     ```js run
     alert( Math.pow(2, 10) ); // 2 in power 10 = 1024
     ```
 
-There are more functions and constants in `Math` object, including trigonometry, which you can find in the [docs for the Math](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Math) object.
+There are more functions and constants in `Math` object, including trigonometry, which you can find in the [docs for the Math object](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Math).
 
 ## Summary
 
@@ -417,10 +465,17 @@ To write numbers with many zeroes:
 
 For different numeral systems:
 
-- Can write numbers directly in hex (`0x`), octal (`0o`) and binary (`0b`) systems
+- Can write numbers directly in hex (`0x`), octal (`0o`) and binary (`0b`) systems.
 - `parseInt(str, base)` parses the string `str` into an integer in numeral system with given `base`, `2 ≤ base ≤ 36`.
 - `num.toString(base)` converts a number to a string in the numeral system with the given `base`.
 
+For regular number tests:
+
+- `isNaN(value)` converts its argument to a number and then tests it for being `NaN`
+- `Number.isNaN(value)` checks whether its argument belongs to the `number` type, and if so, tests it for being `NaN`
+- `isFinite(value)` converts its argument to a number and then tests it for not being `NaN/Infinity/-Infinity`
+- `Number.isFinite(value)` checks whether its argument belongs to the `number` type, and if so, tests it for not being `NaN/Infinity/-Infinity`
+
 For converting values like `12pt` and `100px` to a number:
 
 - Use `parseInt/parseFloat` for the "soft" conversion, which reads a number from a string and then returns the value they could read before the error.
@@ -432,4 +487,4 @@ For fractions:
 
 More mathematical functions:
 
-- See the [Math](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Math) object when you need them. The library is very small, but can cover basic needs.
+- See the [Math](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Math) object when you need them. The library is very small but can cover basic needs.
diff --git a/1-js/05-data-types/03-string/1-ucfirst/solution.md b/1-js/05-data-types/03-string/1-ucfirst/solution.md
index 9d5a2ecfd..0a6237dd8 100644
--- a/1-js/05-data-types/03-string/1-ucfirst/solution.md
+++ b/1-js/05-data-types/03-string/1-ucfirst/solution.md
@@ -8,12 +8,16 @@ let newStr = str[0].toUpperCase() + str.slice(1);
 
 Jest jednak mały problem. Jeśli `str` jest pusty, to `str[0]` zwróci `undefined`, a `undefined` nie ma metody `toUpperCase()`, więc otrzymamy błąd.
 
+<<<<<<< HEAD
 Są dwa wyjścia:
 
 1. Użyj `str.charAt(0)`, ponieważ ta metoda zawsze zwraca łańcuch znaków (może być pusty).
 2. Dodaj warunek na wypadek pustego łańcucha.
 
 Oto druga opcja:
+=======
+The easiest way out is to add a test for an empty string, like this:
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ```js run demo
 function ucFirst(str) {
@@ -24,4 +28,3 @@ function ucFirst(str) {
 
 alert( ucFirst("john") ); // John
 ```
-
diff --git a/1-js/05-data-types/03-string/3-truncate/solution.md b/1-js/05-data-types/03-string/3-truncate/solution.md
index 36233325f..04ffeca55 100644
--- a/1-js/05-data-types/03-string/3-truncate/solution.md
+++ b/1-js/05-data-types/03-string/3-truncate/solution.md
@@ -1,6 +1,10 @@
 Zwracany ciąg nie może być dłuższy niż `maxlength`, więc jeśli go skrócimy, to musimy usunąć o jeden znak mniej, aby zrobić miejsce na wielokropek.
 
+<<<<<<< HEAD
 Należy pamiętać, że wielokropek to '…' – dokładnie jeden znak specjalny Unicode. To nie to samo, co '. . .' – trzy kropki.
+=======
+Note that there is actually a single Unicode character for an ellipsis. That's not three dots.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ```js run demo
 function truncate(str, maxlength) {
diff --git a/1-js/05-data-types/03-string/3-truncate/task.md b/1-js/05-data-types/03-string/3-truncate/task.md
index 92003915c..84bcded2c 100644
--- a/1-js/05-data-types/03-string/3-truncate/task.md
+++ b/1-js/05-data-types/03-string/3-truncate/task.md
@@ -11,7 +11,13 @@ Wynik funkcji musi być tym samym ciągiem, jeśli obcięcie nie jest wymagane l
 Na przykład:
 
 ```js
+<<<<<<< HEAD
 truncate("Oto, co chciałbym powiedzieć na ten temat:", 20) = "Oto, co chciałbym p…"
 
 truncate("Cześć wszystkim!", 20) = "Cześć wszystkim!"
+=======
+truncate("What I'd like to tell on this topic is:", 20) == "What I'd like to te…"
+
+truncate("Hi everyone!", 20) == "Hi everyone!"
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 ```
diff --git a/1-js/05-data-types/03-string/article.md b/1-js/05-data-types/03-string/article.md
index 1cfa53e28..ef13d7fcb 100644
--- a/1-js/05-data-types/03-string/article.md
+++ b/1-js/05-data-types/03-string/article.md
@@ -46,9 +46,15 @@ let guestList = "Guests: // Error: Unexpected token ILLEGAL
   * John";
 ```
 
+<<<<<<< HEAD
 Pojedyncze i podwójne cudzysłowy pochodzą ze starożytnych czasów tworzenia języka, kiedy nie brano pod uwagę potrzeby wielowierszowych ciągów. Grawisy pojawiły się znacznie później i dzięki temu są bardziej wszechstronne.
 
 Grawisy umożliwia również określenie "funkcji szablonu" przed pierwszym grawisem. Składnia to: <code>func&#96;string&#96;</code>. Automatycznie wywoływana funkcja `func` pobiera osadzony w niej ciąg znaków i wyrażenia i może je przetwarzać. Nazywa się to „otagowanymi szablonami”. Ta funkcjonalność ułatwia implementację niestandardowych szablonów, ale jest rzadko używana w praktyce. Więcej na ten temat przeczytasz w [dokumentacji](mdn:/JavaScript/Reference/Template_literals#Tagged_templates). 
+=======
+Single and double quotes come from ancient times of language creation, when the need for multiline strings was not taken into account. Backticks appeared much later and thus are more versatile.
+
+Backticks also allow us to specify a "template function" before the first backtick. The syntax is: <code>func&#96;string&#96;</code>. The function `func` is called automatically, receives the string and embedded expressions and can process them. This feature is called "tagged templates", it's rarely seen, but you can read about it in the MDN: [Template literals](mdn:/JavaScript/Reference/Template_literals#Tagged_templates).
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ## Znaki specjalne
 
@@ -57,10 +63,17 @@ Ciągi wielowierszowe można również tworzyć za pomocą pojedynczych i podwó
 ```js run
 let guestList = "Guests:\n * John\n * Pete\n * Mary";
 
+<<<<<<< HEAD
 alert(guestList); // wielowierszowa lista gości
 ```
 
 Te dwie linie są takie same, po prostu napisane inaczej:
+=======
+alert(guestList); // a multiline list of guests, same as above
+```
+
+As a simpler example, these two lines are equal, just written differently:
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ```js run
 let str1 = "Hello\nWorld"; // nowa linia ze "znaku nowej linii"
@@ -72,12 +85,17 @@ World`;
 alert(str1 == str2); // true
 ```
 
+<<<<<<< HEAD
 Istnieją inne rzadziej używane "znaki specjalne".
 
 Oto pełna lista:
+=======
+There are other, less common special characters:
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 | Znak | Opis |
 |-----------|-------------|
+<<<<<<< HEAD
 |`\n`|Nowa linia|
 |`\r`|Znak powrotu: nie używany samodzielnie. Pliki tekstowe Windows używają kombinacji dwóch znaków `\r\n` do reprezentowania łamania wiersza. |
 |`\'`, `\"`|Cudzysłów|
@@ -99,6 +117,24 @@ alert( "\u{1F60D}" ); // 😍, symbol uśmiechniętej buźki (kolejny długi Uni
 Wszystkie znaki specjalne zaczynają się od odwrotnego ukośnika `\`, tzw. "znak ucieczki".
 
 Możemy go również użyć, jeśli chcemy wstawić cytat do łańcucha.
+=======
+|`\n`|New line|
+|`\r`|In Windows text files a combination of two characters `\r\n` represents a new break, while on non-Windows OS it's just `\n`. That's for historical reasons, most Windows software also understands `\n`. |
+|`\'`,&nbsp;`\"`,&nbsp;<code>\\`</code>|Quotes|
+|`\\`|Backslash|
+|`\t`|Tab|
+|`\b`, `\f`, `\v`| Backspace, Form Feed, Vertical Tab -- mentioned for completeness, coming from old times, not used nowadays (you can forget them right now). |
+
+As you can see, all special characters start with a backslash character `\`. It is also called an "escape character".
+
+Because it's so special, if we need to show an actual backslash `\` within the string, we need to double it:
+
+```js run
+alert( `The backslash: \\` ); // The backslash: \
+```
+
+So-called "escaped" quotes `\'`, `\"`, <code>\\`</code> are used to insert a quote into the same-quoted string.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 Na przykład:
 
@@ -108,12 +144,17 @@ alert( 'I*!*\'*/!*m the Walrus!' ); // *!*I'm*/!* the Walrus!
 
 Jak widać, wewnętrzny cytat musimy poprzedzić `\'`, ponieważ w przeciwnym razie oznaczałoby to koniec ciągu.
 
+<<<<<<< HEAD
 Oczywiście wymóg użycia "znaku ucieczki" dotyczy tylko tych samych cudzysłowów budujących łańcuch. Możemy więc użyć bardziej eleganckiego rozwiązania, używając podwójnych cudzysłowów lub znaków wstecznych dla tego ciągu:
+=======
+Of course, only the quotes that are the same as the enclosing ones need to be escaped. So, as a more elegant solution, we could switch to double quotes or backticks instead:
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ```js run
-alert( `I'm the Walrus!` ); // I'm the Walrus!
+alert( "I'm the Walrus!" ); // I'm the Walrus!
 ```
 
+<<<<<<< HEAD
 Zauważ, że znak ucieczki `\` służy tylko do poprawnego odczytania wiersza przez JavaScript i nie jest dopisywany do wiersza. Łańcuch nie ma go w pamięci. Widać to wyraźnie w wywołaniu funkcji `alert` na powyższym przykładzie.
 
 Ale co, jeśli musimy pokazać wsteczny ukośnik `\` w łańcuchu?
@@ -123,6 +164,9 @@ To możliwe, ale musimy go podwoić `\\`:
 ```js run
 alert( `The backslash: \\` ); // The backslash: \
 ```
+=======
+Besides these special characters, there's also a special notation for Unicode codes `\u…`, it's rarely used and is covered in the optional chapter about [Unicode](info:unicode).
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ## Długość łańcucha
 
@@ -137,33 +181,55 @@ Pamiętaj, że `\n` to pojedynczy "znak specjalny", więc długość łańcucha
 ```warn header="`length` jest wartością"
 Zdarza się, że osoby z praktyką w innych językach przypadkowo dodają nawiasy `str.length()`, zamiast po prostu `str.length`. To nie zadziała.
 
+<<<<<<< HEAD
 Należy pamiętać, że `str.length` jest właściwością numeryczną, a nie funkcją. Nie ma potrzeby dodawania po nim nawiasu.
+=======
+Please note that `str.length` is a numeric property, not a function. There is no need to add parenthesis after it. Not `.length()`, but `.length`.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 ```
 
 ## Dostęp do znaków
 
+<<<<<<< HEAD
 Aby uzyskać znak w pozycji `pos`, użyj nawiasów kwadratowych `[pos]` lub wywołaj metodę [str.charAt(pos)](https://developer.mozilla.org/pl/docs/Web/JavaScript/Reference/Global_Objects/String/charAt). Pierwszy znak zaczyna się od pozycji zerowej:
+=======
+To get a character at position `pos`, use square brackets `[pos]` or call the method [str.at(pos)](mdn:js/String/at). The first character starts from the zero position:
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ```js run
 let str = `Hello`;
 
 // zwraca pierwszy znak
 alert( str[0] ); // H
-alert( str.charAt(0) ); // H
+alert( str.at(0) ); // H
 
 // zwraca ostatni znak
 alert( str[str.length - 1] ); // o
+alert( str.at(-1) );
 ```
 
+<<<<<<< HEAD
 Nawiasy kwadratowe to nowoczesny sposób na uzyskanie znaku, natomiast `charAt` istnieje głównie ze względów historycznych.
 
 Jedyna różnica między nimi polega na tym, że jeśli nie zostanie znaleziony żaden znak, `[]` zwraca `undefined`, a `charAt` zwraca pusty ciąg:
+=======
+As you can see, the `.at(pos)` method has a benefit of allowing negative position. If `pos` is negative, then it's counted from the end of the string.
+
+So `.at(-1)` means the last character, and `.at(-2)` is the one before it, etc.
+
+The square brackets always return `undefined` for negative indexes, for instance:
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ```js run
 let str = `Hello`;
 
+<<<<<<< HEAD
 alert( str[1000] ); // undefined
 alert( str.charAt(1000) ); // '' (pusty ciąg)
+=======
+alert( str[-2] ); // undefined
+alert( str.at(-2) ); // l
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 ```
 
 Możemy również iterować po znakach, używając `for..of`:
@@ -212,7 +278,7 @@ alert( 'Interface'.toLowerCase() ); // interface
 
 Lub, jeśli chcemy, aby jeden znak był pisany małymi literami:
 
-```js
+```js run
 alert( 'Interface'[0].toLowerCase() ); // 'i'
 ```
 
@@ -237,7 +303,11 @@ alert( str.indexOf('widget') ); // -1, nie znaleziono, w wyszukiwaniu rozróżni
 alert( str.indexOf("id") ); // 1, "id" znajduje się na pozycji 1 (id w Widget)
 ```
 
+<<<<<<< HEAD
 Opcjonalny drugi parametr pozwala nam na wyszukiwanie zaczynając od podanej pozycji.
+=======
+The optional second parameter allows us to start searching from a given position.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 Na przykład pierwsze wystąpienie `"id"` występuje na pozycji `1`. Aby wyszukać następne wystąpienie, zacznijmy wyszukiwanie od pozycji `2`:
 
@@ -308,6 +378,7 @@ if (str.indexOf("Widget") != -1) {
 }
 ```
 
+<<<<<<< HEAD
 #### Trik bitowy NOT
 
 Istnieje stara sztuczka z użyciem [bitowego operatora NOT](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_NOT) `~`. Konwertuje liczbę na 32-bitową liczbę całkowitą (usuwa część dziesiętną, jeśli istnieje), a następnie odwraca wszystkie bity w reprezentacji binarnej.
@@ -347,6 +418,8 @@ Aby być precyzyjnym, należy wspomnieć, że z powodu iż, duże liczby są obc
 
 Aktualnie tę sztuczkę możemy zobaczyć tylko w starym kodzie, ponieważ współczesny JavaScript zapewnia metodę .includes (patrz poniżej).
 
+=======
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 ### includes, startsWith, endsWith
 
 Bardziej nowoczesna metoda [str.includes(substr, pos)](mdn:js/String/includes) zwraca `true/false` w zależności, czy `str` zawiera w sobie `substr`.
@@ -369,8 +442,13 @@ alert( "Widget".includes("id", 3) ); // false, od pozycji 3 "id nie występuje
 Metody [str.startsWith](mdn:js/String/startsWith) i [str.endsWith](mdn:js/String/endsWith) sprawdzają odpowiednio, czy łańcuch zaczyna się i kończy na określonym podciągu:
 
 ```js run
+<<<<<<< HEAD
 alert( "Widget".startsWith("Wid") ); // true, "Widget" zaczyna się od "Wid"
 alert( "Widget".endsWith("get") ); // true, "Widget" kończy się na "get"
+=======
+alert( "*!*Wid*/!*get".startsWith("Wid") ); // true, "Widget" starts with "Wid"
+alert( "Wid*!*get*/!*".endsWith("get") ); // true, "Widget" ends with "get"
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 ```
 
 ## Pobieranie podciągu
@@ -405,9 +483,15 @@ JavaScript ma 3 metody uzyskiwania podciągu: `substring`, `substr` i `slice`.
     ```
 
 `str.substring(start [, end])`
+<<<<<<< HEAD
 : Zwraca część ciągu _pomiędzy_ `start` i `end`.
 
     Jest to prawie to samo, co `slice`, z tą różnicą, że `start` może być większe niż `end`.
+=======
+: Returns the part of the string *between* `start` and `end` (not including `end`).
+
+    This is almost the same as `slice`, but it allows `start` to be greater than `end` (in this case it simply swaps `start` and `end` values).
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
     Na przykład:
 
@@ -443,18 +527,36 @@ JavaScript ma 3 metody uzyskiwania podciągu: `substring`, `substr` i `slice`.
     alert( str.substr(-4, 2) ); // 'gi', 2 znaki liczone od czwartej pozycji od końca
     ```
 
+<<<<<<< HEAD
 Podsumujmy te metody, aby uniknąć nieporozumień:
+=======
+    This method resides in the [Annex B](https://tc39.es/ecma262/#sec-string.prototype.substr) of the language specification. It means that only browser-hosted Javascript engines should support it, and it's not recommended to use it. In practice, it's supported everywhere.
+
+Let's recap these methods to avoid any confusion:
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 | metoda | wybiera... | wartości ujemne |
 |--------|-----------|-----------|
+<<<<<<< HEAD
 | `slice(start, end)` | od `start` do `end` (bez uwzględnienia `end`) | zezwala |
 | `substring(start, end)` | pomiędzy `start` i `end` | wartości ujemne oznaczają `0` |
 | `substr(start, length)` | `length` znaków od `start` | pozwala na wartość ujemną dla `start` |
+=======
+| `slice(start, end)` | from `start` to `end` (not including `end`) | allows negatives |
+| `substring(start, end)` | between `start` and `end` (not including `end`)| negative values mean `0` |
+| `substr(start, length)` | from `start` get `length` characters | allows negative `start` |
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ```smart header="Którą metodę wybrać?"
 Wszystkie metody robią robotę. Formalnie `substr` ma niewielką wadę: nie jest opisana w podstawowej specyfikacji JavaScript, ale w załączniku B. Dodatek ten opisuje cechy języka używanego w przeglądarkach, które istnieją głównie ze względów historycznych. Dlatego środowiska inne niż przeglądarki mogą go nie obsługiwać. Jednak w praktyce działa wszędzie.
 
+<<<<<<< HEAD
 Z pozostałych dwóch opcji, `slice` jest nieco bardziej elastyczne - pozwala na użycie wartości ujemny i jest krótsze. Wystarczy więc, że spośród tych metoda zapamiętasz `slice`.
+=======
+Of the other two variants, `slice` is a little bit more flexible, it allows negative arguments and shorter to write.
+
+So, for practical use it's enough to remember only `slice`.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 ```
 
 ## Porównywanie łańcuchów
@@ -477,6 +579,7 @@ Są jednak pewne niuanse.
 
     Może to prowadzić do dziwnych wyników podczas sortowania nazw krajów. Zazwyczaj ludzie spodziewaliby się, że `Zealand` znajdzie się na liście po `Österreich`.
 
+<<<<<<< HEAD
 Aby zrozumieć, co się dzieje, spójrzmy na wewnętrzną reprezentację ciągów w JavaScript.
 
 Wszystkie ciągi są zakodowane przy użyciu [UTF-16](https://pl.wikipedia.org/wiki/UTF-16). To oznacza, że każdy znak ma odpowiedni kod numeryczny. Istnieją specjalne metody, które pozwalają uzyskać znak dla danego kodu i odwrotnie.
@@ -487,7 +590,20 @@ Wszystkie ciągi są zakodowane przy użyciu [UTF-16](https://pl.wikipedia.org/w
     ```js run
     // różna wielkość tych samych liter ma różne kody
     alert( "z".codePointAt(0) ); // 122
+=======
+To understand what happens, we should be aware that strings in Javascript are encoded using [UTF-16](https://en.wikipedia.org/wiki/UTF-16). That is: each character has a corresponding numeric code.
+
+There are special methods that allow to get the character for the code and back:
+
+`str.codePointAt(pos)`
+: Returns a decimal number representing the code for the character at position `pos`:
+
+    ```js run
+    // different case letters have different codes
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
     alert( "Z".codePointAt(0) ); // 90
+    alert( "z".codePointAt(0) ); // 122
+    alert( "z".codePointAt(0).toString(16) ); // 7a (if we need a hexadecimal value)
     ```
 
 `String.fromCodePoint(code)`
@@ -495,6 +611,7 @@ Wszystkie ciągi są zakodowane przy użyciu [UTF-16](https://pl.wikipedia.org/w
 
     ```js run
     alert( String.fromCodePoint(90) ); // Z
+<<<<<<< HEAD
     ```
 
     Możemy również dodawać znaki Unicode według ich kodów, używając`\u`, a następnie kodu szesnastkowego:
@@ -502,6 +619,9 @@ Wszystkie ciągi są zakodowane przy użyciu [UTF-16](https://pl.wikipedia.org/w
     ```js run
     // 90 to 5a w systemie szesnastkowym
     alert( '\u005a' ); // Z
+=======
+    alert( String.fromCodePoint(0x5a) ); // Z (we can also use a hex value as an argument)
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
     ```
 
 Spójrzmy teraz na znaki o kodach `65..220` (alfabet łaciński i kilka extra znaków):
@@ -513,6 +633,7 @@ for (let i = 65; i <= 220; i++) {
   str += String.fromCodePoint(i);
 }
 alert( str );
+// Output:
 // ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„
 // ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜ
 ```
@@ -523,16 +644,27 @@ Teraz jest oczywiste, dlaczego `a > Z`.
 
 Znaki są porównywane według ich kodów numerycznych. Większy kod = większy znak. Kod `a` (97) jest większy niż kod `Z` (90).
 
+<<<<<<< HEAD
 - Wszystkie małe litery występują po wielkich literach, ponieważ ich kody są większe.
 - Niektóre litery, takie jak `Ö`, są całkowicie poza głównym alfabetem. Ta litera ma większy kod niż jakakolwiek litera od `a` do `z`.
 
 ### Prawidłowe porównania
+=======
+- All lowercase letters go after uppercase letters because their codes are greater.
+- Some letters like `Ö` stand apart from the main alphabet. Here, its code is greater than anything from `a` to `z`.
+
+### Correct comparisons [#correct-comparisons]
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 „Właściwy” algorytm porównywania łańcuchów jest bardziej skomplikowany, niż mogłoby się wydawać, ponieważ różne języki używają różnych alfabetów.
 
 Przeglądarka musi więc wiedzieć, jakiego języka użyć do porównania.
 
+<<<<<<< HEAD
 Na szczęście wszystkie nowoczesne przeglądarki (IE10- wymaga dodatkowej biblioteki [Intl.JS](https://github.com/andyearnshaw/Intl.js/)) obsługują standard internacjonalizacji [ECMA 402](http://www.ecma-international.org/ecma-402/1.0/ECMA-402.pdf), który zapewnia poprawne porównywanie ciągów w różnych językach z uwzględnieniem ich reguł.
+=======
+Luckily, modern browsers support the internationalization standard [ECMA-402](https://www.ecma-international.org/publications-and-standards/standards/ecma-402/).
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 Wywołanie [str.localeCompare(str2)](mdn:js/String/localeCompare) zwraca liczbę wskazującą, który ciąg jest większy zgodnie z zasadami języka:
 
@@ -548,6 +680,7 @@ alert( 'Österreich'.localeCompare('Zealand') ); // -1
 
 Ta metoda ma właściwie dwa dodatkowe argumenty określone w [dokumentacji](mdn:js/String/localeCompare). Pierwszy pozwala na określenie języka (domyślnie jest on pobierany ze środowiska) - od tego zależy kolejność liter. Drugi, to dodatkowe reguły, takie jak rozróżnianie wielkości liter, czy należy przestrzegać różnic między `"a"` i `"á"` itp.
 
+<<<<<<< HEAD
 ## Wewnętrzne części unicode
 
 ```warn header="Zaawansowana wiedza"
@@ -665,6 +798,17 @@ Jeśli chcesz dowiedzieć się więcej o regułach i wariantach normalizacji –
 - Aby pisać małymi/wielkimi literami, użyj: `toLowerCase/toUpperCase`.
 - Aby wyszukać podciąg, użyj `indexOf` lub `includes/startsWith/endsWith`, gdy chcesz tylko sprawdzić, czy podciąg występuje w łańcuchu.
 - Aby porównać ciągi znaków zgodnie z regułami języka, użyj: `localeCompare`.
+=======
+## Summary
+
+- There are 3 types of quotes. Backticks allow a string to span multiple lines and embed expressions `${…}`.
+- We can use special characters, such as a line break `\n`.
+- To get a character, use: `[]` or `at` method.
+- To get a substring, use: `slice` or `substring`.
+- To lowercase/uppercase a string, use: `toLowerCase/toUpperCase`.
+- To look for a substring, use: `indexOf`, or `includes/startsWith/endsWith` for simple checks.
+- To compare strings according to the language, use: `localeCompare`, otherwise they are compared by character codes.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 Istnieje kilka innych pomocnych metod:
 
@@ -672,4 +816,10 @@ Istnieje kilka innych pomocnych metod:
 - `str.repeat(n)` -- powtarza ciąg `n` razy.
 - ...i inne, które znajdziesz w [dokumentacji](https://developer.mozilla.org/pl/docs/Web/JavaScript/Reference/Global_Objects/String).
 
+<<<<<<< HEAD
 Istnieją również metody wyszukiwania i zastępowania za pomocą wyrażeń regularnych. Jest to jednak duży i osobny temat, więc został poświęcony mu osobny rozdział: <info:regular-expressions>.
+=======
+Strings also have methods for doing search/replace with regular expressions. But that's big topic, so it's explained in a separate tutorial section <info:regular-expressions>.
+
+Also, as of now it's important to know that strings are based on Unicode encoding, and hence there're issues with comparisons. There's more about Unicode in the chapter <info:unicode>.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
diff --git a/1-js/05-data-types/04-array/10-maximal-subarray/solution.md b/1-js/05-data-types/04-array/10-maximal-subarray/solution.md
index daadf494b..7e1ca3bde 100644
--- a/1-js/05-data-types/04-array/10-maximal-subarray/solution.md
+++ b/1-js/05-data-types/04-array/10-maximal-subarray/solution.md
@@ -57,9 +57,9 @@ alert( getMaxSubSum([1, 2, 3]) ); // 6
 alert( getMaxSubSum([100, -9, 2, -3, 5]) ); // 100
 ```
 
-The solution has a time complexety of [O(n<sup>2</sup>)](https://en.wikipedia.org/wiki/Big_O_notation). In other words, if we increase the array size 2 times, the algorithm will work 4 times longer.
+The solution has a time complexity of [O(n<sup>2</sup>)](https://en.wikipedia.org/wiki/Big_O_notation). In other words, if we increase the array size 2 times, the algorithm will work 4 times longer.
 
-For big arrays (1000, 10000 or more items) such algorithms can lead to a serious sluggishness.
+For big arrays (1000, 10000 or more items) such algorithms can lead to serious sluggishness.
 
 # Fast solution
 
@@ -91,4 +91,4 @@ alert( getMaxSubSum([-1, -2, -3]) ); // 0
 
 The algorithm requires exactly 1 array pass, so the time complexity is O(n).
 
-You can find more detail information about the algorithm here: [Maximum subarray problem](http://en.wikipedia.org/wiki/Maximum_subarray_problem). If it's still not obvious why that works, then please trace the algorithm on the examples above, see how it works, that's better than any words.
+You can find more detailed information about the algorithm here: [Maximum subarray problem](http://en.wikipedia.org/wiki/Maximum_subarray_problem). If it's still not obvious why that works, then please trace the algorithm on the examples above, see how it works, that's better than any words.
diff --git a/1-js/05-data-types/04-array/10-maximal-subarray/task.md b/1-js/05-data-types/04-array/10-maximal-subarray/task.md
index e63c4e625..f1a1d9f95 100644
--- a/1-js/05-data-types/04-array/10-maximal-subarray/task.md
+++ b/1-js/05-data-types/04-array/10-maximal-subarray/task.md
@@ -10,15 +10,15 @@ The task is: find the contiguous subarray of `arr` with the maximal sum of items
 
 Write the function `getMaxSubSum(arr)` that will return that sum.
 
-For instance: 
+For instance:
 
 ```js
-getMaxSubSum([-1, *!*2, 3*/!*, -9]) = 5 (the sum of highlighted items)
-getMaxSubSum([*!*2, -1, 2, 3*/!*, -9]) = 6
-getMaxSubSum([-1, 2, 3, -9, *!*11*/!*]) = 11
-getMaxSubSum([-2, -1, *!*1, 2*/!*]) = 3
-getMaxSubSum([*!*100*/!*, -9, 2, -3, 5]) = 100
-getMaxSubSum([*!*1, 2, 3*/!*]) = 6 (take all)
+getMaxSubSum([-1, *!*2, 3*/!*, -9]) == 5 (the sum of highlighted items)
+getMaxSubSum([*!*2, -1, 2, 3*/!*, -9]) == 6
+getMaxSubSum([-1, 2, 3, -9, *!*11*/!*]) == 11
+getMaxSubSum([-2, -1, *!*1, 2*/!*]) == 3
+getMaxSubSum([*!*100*/!*, -9, 2, -3, 5]) == 100
+getMaxSubSum([*!*1, 2, 3*/!*]) == 6 (take all)
 ```
 
 If all items are negative, it means that we take none (the subarray is empty), so the sum is zero:
diff --git a/1-js/05-data-types/04-array/2-create-array/task.md b/1-js/05-data-types/04-array/2-create-array/task.md
index 16d14071f..d4551c79c 100644
--- a/1-js/05-data-types/04-array/2-create-array/task.md
+++ b/1-js/05-data-types/04-array/2-create-array/task.md
@@ -8,7 +8,7 @@ Let's try 5 array operations.
 
 1. Create an array `styles` with items "Jazz" and "Blues".
 2. Append "Rock-n-Roll" to the end.
-3. Replace the value in the middle by "Classics". Your code for finding the middle value should work for any arrays with odd length.
+3. Replace the value in the middle with "Classics". Your code for finding the middle value should work for any arrays with odd length.
 4. Strip off the first value of the array and show it.
 5. Prepend `Rap` and `Reggae` to the array.
 
diff --git a/1-js/05-data-types/04-array/3-call-array-this/solution.md b/1-js/05-data-types/04-array/3-call-array-this/solution.md
index e994ae078..3cb0317cf 100644
--- a/1-js/05-data-types/04-array/3-call-array-this/solution.md
+++ b/1-js/05-data-types/04-array/3-call-array-this/solution.md
@@ -9,7 +9,7 @@ arr.push(function() {
   alert( this );
 })
 
-arr[2](); // "a","b",function
+arr[2](); // a,b,function(){...}
 ```
 
 The array has 3 values: initially it had two, plus the function. 
diff --git a/1-js/05-data-types/04-array/3-call-array-this/task.md b/1-js/05-data-types/04-array/3-call-array-this/task.md
index 340c5feef..f1e13499c 100644
--- a/1-js/05-data-types/04-array/3-call-array-this/task.md
+++ b/1-js/05-data-types/04-array/3-call-array-this/task.md
@@ -11,7 +11,7 @@ let arr = ["a", "b"];
 
 arr.push(function() {
   alert( this );
-})
+});
 
 arr[2](); // ?
 ```
diff --git a/1-js/05-data-types/04-array/article.md b/1-js/05-data-types/04-array/article.md
index 7dc54bd4b..e71e86a5b 100644
--- a/1-js/05-data-types/04-array/article.md
+++ b/1-js/05-data-types/04-array/article.md
@@ -92,6 +92,38 @@ let fruits = [
 The "trailing comma" style makes it easier to insert/remove items, because all lines become alike.
 ````
 
+## Get last elements with "at"
+
+[recent browser="new"]
+
+Let's say we want the last element of the array.
+
+Some programming languages allow the use of negative indexes for the same purpose, like `fruits[-1]`.
+
+Although, in JavaScript it won't work. The result will be `undefined`, because the index in square brackets is treated literally.
+
+We can explicitly calculate the last element index and then access it: `fruits[fruits.length - 1]`.
+
+```js run
+let fruits = ["Apple", "Orange", "Plum"];
+
+alert( fruits[fruits.length-1] ); // Plum
+```
+
+A bit cumbersome, isn't it? We need to write the variable name twice.
+
+Luckily, there's a shorter syntax: `fruits.at(-1)`:
+
+```js run
+let fruits = ["Apple", "Orange", "Plum"];
+
+// same as fruits[fruits.length-1]
+alert( fruits.at(-1) ); // Plum
+```
+
+In other words, `arr.at(i)`:
+- is exactly the same as `arr[i]`, if `i >= 0`.
+- for negative values of `i`, it steps back from the end of the array.
 
 ## Methods pop/push, shift/unshift
 
@@ -121,9 +153,9 @@ A stack is usually illustrated as a pack of cards: new cards are added to the to
 
 For stacks, the latest pushed item is received first, that's also called LIFO (Last-In-First-Out) principle. For queues, we have FIFO (First-In-First-Out).
 
-Arrays in JavaScript can work both as a queue and as a stack. They allow you to add/remove elements both to/from the beginning or the end.
+Arrays in JavaScript can work both as a queue and as a stack. They allow you to add/remove elements, both to/from the beginning or the end.
 
-In computer science the data structure that allows it is called [deque](https://en.wikipedia.org/wiki/Double-ended_queue).
+In computer science, the data structure that allows this, is called [deque](https://en.wikipedia.org/wiki/Double-ended_queue).
 
 **Methods that work with the end of the array:**
 
@@ -138,6 +170,8 @@ In computer science the data structure that allows it is called [deque](https://
     alert( fruits ); // Apple, Orange
     ```
 
+    Both `fruits.pop()` and `fruits.at(-1)` return the last element of the array, but `fruits.pop()` also modifies the array by removing it.
+
 `push`
 : Append the element to the end of the array:
 
@@ -156,7 +190,7 @@ In computer science the data structure that allows it is called [deque](https://
 `shift`
 : Extracts the first element of the array and returns it:
 
-    ```js
+    ```js run
     let fruits = ["Apple", "Orange", "Pear"];
 
     alert( fruits.shift() ); // remove Apple and alert it
@@ -167,7 +201,7 @@ In computer science the data structure that allows it is called [deque](https://
 `unshift`
 : Add the element to the beginning of the array:
 
-    ```js
+    ```js run
     let fruits = ["Orange", "Pear"];
 
     fruits.unshift('Apple');
@@ -193,7 +227,7 @@ An array is a special kind of object. The square brackets used to access a prope
 
 They extend objects providing special methods to work with ordered collections of data and also the `length` property. But at the core it's still an object.
 
-Remember, there are only 7 basic types in JavaScript. Array is an object and thus behaves like an object.
+Remember, there are only eight basic data types in JavaScript (see the [Data types](info:types) chapter for more info). Array is an object and thus behaves like an object.
 
 For instance, it is copied by reference:
 
@@ -209,7 +243,7 @@ arr.push("Pear"); // modify the array by reference
 alert( fruits ); // Banana, Pear - 2 items now
 ```
 
-...But what makes arrays really  special is their internal representation. The engine tries to store its elements in the contiguous memory area, one after another, just as depicted on the illustrations in this chapter, and there are other optimizations as well, to make arrays work really fast.
+...But what makes arrays really special is their internal representation. The engine tries to store its elements in the contiguous memory area, one after another, just as depicted on the illustrations in this chapter, and there are other optimizations as well, to make arrays work really fast.
 
 But they all break if we quit working with an array as with an "ordered collection" and start working with it as if it were a regular object.
 
@@ -247,7 +281,7 @@ Why is it faster to work with the end of an array than with its beginning? Let's
 fruits.shift(); // take 1 element from the start
 ```
 
-It's not enough to take and remove the element with the number `0`. Other elements need to be renumbered as well.
+It's not enough to take and remove the element with the index `0`. Other elements need to be renumbered as well.
 
 The `shift` operation must do 3 things:
 
@@ -365,11 +399,11 @@ There is one more syntax to create an array:
 let arr = *!*new Array*/!*("Apple", "Pear", "etc");
 ```
 
-It's rarely used, because square brackets `[]` are shorter. Also there's a tricky feature with it.
+It's rarely used, because square brackets `[]` are shorter. Also, there's a tricky feature with it.
 
 If `new Array` is called with a single argument which is a number, then it creates an array *without items, but with the given length*.
 
-Let's see how one can shoot themself in the foot:
+Let's see how one can shoot themselves in the foot:
 
 ```js run
 let arr = new Array(2); // will it create an array of [2] ?
@@ -379,9 +413,7 @@ alert( arr[0] ); // undefined! no elements.
 alert( arr.length ); // length 2
 ```
 
-In the code above, `new Array(number)` has all elements `undefined`.
-
-To evade such surprises, we usually use square brackets, unless we really know what we're doing.
+To avoid such surprises, we usually use square brackets, unless we really know what we're doing.
 
 ## Multidimensional arrays
 
@@ -394,7 +426,7 @@ let matrix = [
   [7, 8, 9]
 ];
 
-alert( matrix[1][1] ); // 5, the central element
+alert( matrix[0][1] ); // 2, the second value of the first inner array
 ```
 
 ## toString
@@ -429,25 +461,77 @@ alert( "1" + 1 ); // "11"
 alert( "1,2" + 1 ); // "1,21"
 ```
 
+## Don't compare arrays with ==
+
+Arrays in JavaScript, unlike some other programming languages, shouldn't be compared with operator `==`.
+
+This operator has no special treatment for arrays, it works with them as with any objects.
+
+Let's recall the rules:
+
+- Two objects are equal `==` only if they're references to the same object.
+- If one of the arguments of `==` is an object, and the other one is a primitive, then the object gets converted to primitive, as explained in the chapter <info:object-toprimitive>.
+- ...With an exception of `null` and `undefined` that equal `==` each other and nothing else.
+
+The strict comparison `===` is even simpler, as it doesn't convert types.
+
+So, if we compare arrays with `==`, they are never the same, unless we compare two variables that reference exactly the same array.
+
+For example:
+```js run
+alert( [] == [] ); // false
+alert( [0] == [0] ); // false
+```
+
+These arrays are technically different objects. So they aren't equal. The `==` operator doesn't do item-by-item comparison.
+
+Comparison with primitives may give seemingly strange results as well:
+
+```js run
+alert( 0 == [] ); // true
+
+alert('0' == [] ); // false
+```
+
+Here, in both cases, we compare a primitive with an array object. So the array `[]` gets converted to primitive for the purpose of comparison and becomes an empty string `''`.
+
+Then the comparison process goes on with the primitives, as described in the chapter <info:type-conversions>:
+
+```js run
+// after [] was converted to ''
+alert( 0 == '' ); // true, as '' becomes converted to number 0
+
+alert('0' == '' ); // false, no type conversion, different strings
+```
+
+So, how to compare arrays?
+
+That's simple: don't use the `==` operator. Instead, compare them item-by-item in a loop or using iteration methods explained in the next chapter.
+
 ## Summary
 
 Array is a special kind of object, suited to storing and managing ordered data items.
 
-- The declaration:
+The declaration:
 
-    ```js
-    // square brackets (usual)
-    let arr = [item1, item2...];
+```js
+// square brackets (usual)
+let arr = [item1, item2...];
 
-    // new Array (exceptionally rare)
-    let arr = new Array(item1, item2...);
-    ```
+// new Array (exceptionally rare)
+let arr = new Array(item1, item2...);
+```
 
-    The call to `new Array(number)` creates an array with the given length, but without elements.
+The call to `new Array(number)` creates an array with the given length, but without elements.
 
 - The `length` property is the array length or, to be precise, its last numeric index plus one. It is auto-adjusted by array methods.
 - If we shorten `length` manually, the array is truncated.
 
+Getting the elements:
+
+- we can get element by its index, like `arr[0]`
+- also we can use `at(i)` method that allows negative indexes. For negative values of `i`, it steps back from the end of the array. If `i >= 0`, it works same as `arr[i]`.
+
 We can use an array as a deque with the following operations:
 
 - `push(...items)` adds `items` to the end.
@@ -460,4 +544,8 @@ To loop over the elements of the array:
   - `for (let item of arr)` -- the modern syntax for items only,
   - `for (let i in arr)` -- never use.
 
-We will return to arrays and study more methods to add, remove, extract elements and sort arrays in the chapter <info:array-methods>.
+To compare arrays, don't use the `==` operator (as well as `>`, `<` and others), as they have no special treatment for arrays. They handle them as any objects, and it's not what we usually want.
+
+Instead you can use `for..of` loop to compare arrays item-by-item.
+
+We will continue with arrays and study more methods to add, remove, extract elements and sort arrays in the next chapter <info:array-methods>.
diff --git a/1-js/05-data-types/05-array-methods/12-reduce-object/_js.view/test.js b/1-js/05-data-types/05-array-methods/12-reduce-object/_js.view/test.js
index 02299e307..e48ba138d 100644
--- a/1-js/05-data-types/05-array-methods/12-reduce-object/_js.view/test.js
+++ b/1-js/05-data-types/05-array-methods/12-reduce-object/_js.view/test.js
@@ -8,13 +8,14 @@ describe("groupById", function() {
     ];
 
     assert.deepEqual(groupById(users), {
-      john: {id: 'john', name: "John Smith", age: 20}
+      john: {id: 'john', name: "John Smith", age: 20},
       ann: {id: 'ann', name: "Ann Smith", age: 24},
       pete: {id: 'pete', name: "Pete Peterson", age: 31},
     });
   });
 
   it("works with an empty array", function() {
+    users = [];
     assert.deepEqual(groupById(users), {});
   });
 });
diff --git a/1-js/05-data-types/05-array-methods/12-reduce-object/task.md b/1-js/05-data-types/05-array-methods/12-reduce-object/task.md
index 421f8cb8b..7f0082357 100644
--- a/1-js/05-data-types/05-array-methods/12-reduce-object/task.md
+++ b/1-js/05-data-types/05-array-methods/12-reduce-object/task.md
@@ -4,7 +4,7 @@ importance: 4
 
 # Create keyed object from array
 
-Let's say we received an array of users in the form `{id:..., name:..., age... }`.
+Let's say we received an array of users in the form `{id:..., name:..., age:... }`.
 
 Create a function `groupById(arr)` that creates an object from it, with `id` as the key, and array items as values.
 
@@ -20,10 +20,10 @@ let users = [
 let usersById = groupById(users);
 
 /*
-// after the call we have:
+// after the call we should have:
 
 usersById = {
-  john: {id: 'john', name: "John Smith", age: 20}
+  john: {id: 'john', name: "John Smith", age: 20},
   ann: {id: 'ann', name: "Ann Smith", age: 24},
   pete: {id: 'pete', name: "Pete Peterson", age: 31},
 }
diff --git a/1-js/05-data-types/05-array-methods/2-filter-range/task.md b/1-js/05-data-types/05-array-methods/2-filter-range/task.md
index 18b2c1d9b..46e47c93d 100644
--- a/1-js/05-data-types/05-array-methods/2-filter-range/task.md
+++ b/1-js/05-data-types/05-array-methods/2-filter-range/task.md
@@ -4,7 +4,7 @@ importance: 4
 
 # Filter range
 
-Write a function `filterRange(arr, a, b)` that gets an array `arr`, looks for elements between `a` and `b` in it and returns an array of them. 
+Write a function `filterRange(arr, a, b)` that gets an array `arr`, looks for elements with values higher or equal to `a` and lower or equal to `b` and return a result as an array.
 
 The function should not modify the array. It should return the new array.
 
diff --git a/1-js/05-data-types/05-array-methods/3-filter-range-in-place/_js.view/test.js b/1-js/05-data-types/05-array-methods/3-filter-range-in-place/_js.view/test.js
index db32d9a11..241b74c6e 100644
--- a/1-js/05-data-types/05-array-methods/3-filter-range-in-place/_js.view/test.js
+++ b/1-js/05-data-types/05-array-methods/3-filter-range-in-place/_js.view/test.js
@@ -4,13 +4,13 @@ describe("filterRangeInPlace", function() {
 
     let arr = [5, 3, 8, 1];
 
-    filterRangeInPlace(arr, 1, 4); 
+    filterRangeInPlace(arr, 2, 5); 
 
-    assert.deepEqual(arr, [3, 1]);
+    assert.deepEqual(arr, [5, 3]);
   });
 
   it("doesn't return anything", function() {
     assert.isUndefined(filterRangeInPlace([1,2,3], 1, 4)); 
   });
 
-});
\ No newline at end of file
+});
diff --git a/1-js/05-data-types/05-array-methods/6-calculator-extendable/_js.view/solution.js b/1-js/05-data-types/05-array-methods/6-calculator-extendable/_js.view/solution.js
index 45ef1619d..f62452a5f 100644
--- a/1-js/05-data-types/05-array-methods/6-calculator-extendable/_js.view/solution.js
+++ b/1-js/05-data-types/05-array-methods/6-calculator-extendable/_js.view/solution.js
@@ -10,14 +10,14 @@ function Calculator() {
     let split = str.split(' '),
       a = +split[0],
       op = split[1],
-      b = +split[2]
+      b = +split[2];
 
     if (!this.methods[op] || isNaN(a) || isNaN(b)) {
       return NaN;
     }
 
     return this.methods[op](a, b);
-  }
+  };
 
   this.addMethod = function(name, func) {
     this.methods[name] = func;
diff --git a/1-js/05-data-types/05-array-methods/7-map-objects/solution.md b/1-js/05-data-types/05-array-methods/7-map-objects/solution.md
index 5d8bf4a13..2d8d4fb0e 100644
--- a/1-js/05-data-types/05-array-methods/7-map-objects/solution.md
+++ b/1-js/05-data-types/05-array-methods/7-map-objects/solution.md
@@ -25,7 +25,7 @@ alert( usersMapped[0].id ); // 1
 alert( usersMapped[0].fullName ); // John Smith
 ```
 
-Please note that in for the arrow functions we need to use additional brackets. 
+Please note that in the arrow functions we need to use additional brackets. 
 
 We can't write like this:
 ```js
diff --git a/1-js/05-data-types/05-array-methods/8-sort-objects/solution.md b/1-js/05-data-types/05-array-methods/8-sort-objects/solution.md
index 9f1ade707..cfaf9761a 100644
--- a/1-js/05-data-types/05-array-methods/8-sort-objects/solution.md
+++ b/1-js/05-data-types/05-array-methods/8-sort-objects/solution.md
@@ -1,6 +1,6 @@
 ```js run no-beautify
 function sortByAge(arr) {
-  arr.sort((a, b) => a.age > b.age ? 1 : -1);
+  arr.sort((a, b) => a.age - b.age);
 }
 
 let john = { name: "John", age: 25 };
diff --git a/1-js/05-data-types/05-array-methods/article.md b/1-js/05-data-types/05-array-methods/article.md
index 301696440..853645958 100644
--- a/1-js/05-data-types/05-array-methods/article.md
+++ b/1-js/05-data-types/05-array-methods/article.md
@@ -1,6 +1,6 @@
 # Array methods
 
-Arrays provide a lot of methods. To make things easier, in this chapter they are split into groups.
+Arrays provide a lot of methods. To make things easier, in this chapter, they are split into groups.
 
 ## Add/remove items
 
@@ -32,19 +32,19 @@ alert( arr.length ); // 3
 
 The element was removed, but the array still has 3 elements, we can see that `arr.length == 3`.
 
-That's natural, because `delete obj.key` removes a value by the `key`. It's all it does. Fine for objects. But for arrays we usually want the rest of elements to shift and occupy the freed place. We expect to have a shorter array now.
+That's natural, because `delete obj.key` removes a value by the `key`. It's all it does. Fine for objects. But for arrays we usually want the rest of the elements to shift and occupy the freed place. We expect to have a shorter array now.
 
 So, special methods should be used.
 
-The [arr.splice(start)](mdn:js/Array/splice) method is a swiss army knife for arrays. It can do everything: insert, remove and replace elements.
+The [arr.splice](mdn:js/Array/splice) method is a Swiss army knife for arrays. It can do everything: insert, remove and replace elements.
 
 The syntax is:
 
 ```js
-arr.splice(index[, deleteCount, elem1, ..., elemN])
+arr.splice(start[, deleteCount, elem1, ..., elemN])
 ```
 
-It starts from the position `index`: removes `deleteCount` elements and then inserts `elem1, ..., elemN` at their place. Returns the array of removed elements.
+It modifies `arr` starting from the index `start`: removes `deleteCount` elements and then inserts `elem1, ..., elemN` at their place. Returns the array of removed elements.
 
 This method is easy to grasp by examples.
 
@@ -62,7 +62,7 @@ alert( arr ); // ["I", "JavaScript"]
 
 Easy, right? Starting from the index `1` it removed `1` element.
 
-In the next example we remove 3 elements and replace them with the other two:
+In the next example, we remove 3 elements and replace them with the other two:
 
 ```js run
 let arr = [*!*"I", "study", "JavaScript",*/!* "right", "now"];
@@ -84,7 +84,7 @@ let removed = arr.splice(0, 2);
 alert( removed ); // "I", "study" <-- array of removed elements
 ```
 
-The `splice` method is also able to insert the elements without any removals. For that we need to set `deleteCount` to `0`:
+The `splice` method is also able to insert the elements without any removals. For that, we need to set `deleteCount` to `0`:
 
 ```js run
 let arr = ["I", "study", "JavaScript"];
@@ -114,7 +114,7 @@ alert( arr ); // 1,2,3,4,5
 
 ### slice
 
-The method [arr.slice](mdn:js/Array/slice) is much simpler than similar-looking `arr.splice`.
+The method [arr.slice](mdn:js/Array/slice) is much simpler than the similar-looking `arr.splice`.
 
 The syntax is:
 
@@ -124,7 +124,7 @@ arr.slice([start], [end])
 
 It returns a new array copying to it all items from index `start` to `end` (not including `end`). Both `start` and `end` can be negative, in that case position from array end is assumed.
 
-It's similar to a string method `str.slice`, but instead of substrings it makes subarrays.
+It's similar to a string method `str.slice`, but instead of substrings, it makes subarrays.
 
 For instance:
 
@@ -206,7 +206,7 @@ The [arr.forEach](mdn:js/Array/forEach) method allows to run a function for ever
 The syntax:
 ```js
 arr.forEach(function(item, index, array) {
-  // ... do something with item
+  // ... do something with an item
 });
 ```
 
@@ -234,12 +234,13 @@ Now let's cover methods that search in an array.
 
 ### indexOf/lastIndexOf and includes
 
-The methods [arr.indexOf](mdn:js/Array/indexOf), [arr.lastIndexOf](mdn:js/Array/lastIndexOf) and [arr.includes](mdn:js/Array/includes) have the same syntax and do essentially the same as their string counterparts, but operate on items instead of characters:
+The methods [arr.indexOf](mdn:js/Array/indexOf) and [arr.includes](mdn:js/Array/includes) have the similar syntax and do essentially the same as their string counterparts, but operate on items instead of characters:
 
 - `arr.indexOf(item, from)` -- looks for `item` starting from index `from`, and returns the index where it was found, otherwise `-1`.
-- `arr.lastIndexOf(item, from)` -- same, but looks for from right to left.
 - `arr.includes(item, from)` -- looks for `item` starting from index `from`, returns `true` if found.
 
+Usually, these methods are used with only one argument: the `item` to search. By default, the search is from the beginning.
+
 For instance:
 
 ```js run
@@ -252,21 +253,33 @@ alert( arr.indexOf(null) ); // -1
 alert( arr.includes(1) ); // true
 ```
 
-Note that the methods use `===` comparison. So, if we look for `false`, it finds exactly `false` and not the zero.
+Please note that `indexOf` uses the strict equality `===` for comparison. So, if we look for `false`, it finds exactly `false` and not the zero.
 
-If we want to check for inclusion, and don't want to know the exact index, then `arr.includes` is preferred.
+If we want to check if `item` exists in the array and don't need the index, then `arr.includes` is preferred.
 
-Also, a very minor difference of `includes` is that it correctly handles `NaN`, unlike `indexOf/lastIndexOf`:
+The method [arr.lastIndexOf](mdn:js/Array/lastIndexOf) is the same as `indexOf`, but looks for from right to left.
+
+```js run
+let fruits = ['Apple', 'Orange', 'Apple']
+
+alert( fruits.indexOf('Apple') ); // 0 (first Apple)
+alert( fruits.lastIndexOf('Apple') ); // 2 (last Apple)
+```
+
+````smart header="The `includes` method handles `NaN` correctly"
+A minor, but noteworthy feature of `includes` is that it correctly handles `NaN`, unlike `indexOf`:
 
 ```js run
 const arr = [NaN];
-alert( arr.indexOf(NaN) ); // -1 (should be 0, but === equality doesn't work for NaN)
+alert( arr.indexOf(NaN) ); // -1 (wrong, should be 0)
 alert( arr.includes(NaN) );// true (correct)
 ```
+That's because `includes` was added to JavaScript much later and uses the more up-to-date comparison algorithm internally.
+````
 
-### find and findIndex
+### find and findIndex/findLastIndex
 
-Imagine we have an array of objects. How do we find an object with the specific condition?
+Imagine we have an array of objects. How do we find an object with a specific condition?
 
 Here the [arr.find(fn)](mdn:js/Array/find) method comes in handy.
 
@@ -284,7 +297,7 @@ The function is called for elements of the array, one after another:
 - `index` is its index.
 - `array` is the array itself.
 
-If it returns `true`, the search is stopped, the `item` is returned. If nothing found, `undefined` is returned.
+If it returns `true`, the search is stopped, the `item` is returned. If nothing is found, `undefined` is returned.
 
 For example, we have an array of users, each with the fields `id` and `name`. Let's find the one with `id == 1`:
 
@@ -300,11 +313,30 @@ let user = users.find(item => item.id == 1);
 alert(user.name); // John
 ```
 
-In real life arrays of objects is a common thing, so the `find` method is very useful.
+In real life, arrays of objects are a common thing, so the `find` method is very useful.
 
 Note that in the example we provide to `find` the function `item => item.id == 1` with one argument. That's typical, other arguments of this function are rarely used.
 
-The [arr.findIndex](mdn:js/Array/findIndex) method is essentially the same, but it returns the index where the element was found instead of the element itself and `-1` is returned when nothing is found.
+The [arr.findIndex](mdn:js/Array/findIndex) method has the same syntax but returns the index where the element was found instead of the element itself. The value of `-1` is returned if nothing is found.
+
+The [arr.findLastIndex](mdn:js/Array/findLastIndex) method is like `findIndex`, but searches from right to left, similar to `lastIndexOf`.
+
+Here's an example:
+
+```js run
+let users = [
+  {id: 1, name: "John"},
+  {id: 2, name: "Pete"},
+  {id: 3, name: "Mary"},
+  {id: 4, name: "John"}
+];
+
+// Find the index of the first John
+alert(users.findIndex(user => user.name == 'John')); // 0
+
+// Find the index of the last John
+alert(users.findLastIndex(user => user.name == 'John')); // 3
+```
 
 ### filter
 
@@ -389,6 +421,7 @@ Literally, all elements are converted to strings for comparisons. For strings, l
 To use our own sorting order, we need to supply a function as the argument of `arr.sort()`.
 
 The function should compare two arbitrary values and return:
+
 ```js
 function compare(a, b) {
   if (a > b) return 1; // if the first value is greater than the second
@@ -417,15 +450,16 @@ alert(arr);  // *!*1, 2, 15*/!*
 
 Now it works as intended.
 
-Let's step aside and think what's happening. The `arr` can be array of anything, right? It may contain numbers or strings or objects or whatever. We have a set of *some items*. To sort it, we need an *ordering function* that knows how to compare its elements. The default is a string order.
+Let's step aside and think about what's happening. The `arr` can be an array of anything, right? It may contain numbers or strings or objects or whatever. We have a set of *some items*. To sort it, we need an *ordering function* that knows how to compare its elements. The default is a string order.
 
-The `arr.sort(fn)` method implements a generic sorting algorithm. We don't need to care how it internally works (an optimized [quicksort](https://en.wikipedia.org/wiki/Quicksort) most of the time). It will walk the array, compare its elements using the provided function and reorder them, all we need is to provide the `fn` which does the comparison.
+The `arr.sort(fn)` method implements a generic sorting algorithm. We don't need to care how it internally works (an optimized [quicksort](https://en.wikipedia.org/wiki/Quicksort) or [Timsort](https://en.wikipedia.org/wiki/Timsort) most of the time). It will walk the array, compare its elements using the provided function and reorder them, all we need is to provide the `fn` which does the comparison.
 
-By the way, if we ever want to know which elements are compared -- nothing prevents from alerting them:
+By the way, if we ever want to know which elements are compared -- nothing prevents us from alerting them:
 
 ```js run
 [1, -2, 15, 2, 0, 8].sort(function(a, b) {
   alert( a + " <> " + b );
+  return a - b;
 });
 ```
 
@@ -492,7 +526,7 @@ Here's the situation from real life. We are writing a messaging app, and the per
 
 The [str.split(delim)](mdn:js/String/split) method does exactly that. It splits the string into an array by the given delimiter `delim`.
 
-In the example below, we split by a comma followed by space:
+In the example below, we split by a comma followed by a space:
 
 ```js run
 let names = 'Bilbo, Gandalf, Nazgul';
@@ -559,9 +593,9 @@ Arguments:
 - `index` -- is its position.
 - `array` -- is the array.
 
-As function is applied, the result of the previous function call is passed to the next one as the first argument.
+As the function is applied, the result of the previous function call is passed to the next one as the first argument.
 
-So, the first argument is essentially the accumulator that stores the combined result of all previous executions. And at the end it becomes the result of `reduce`.
+So, the first argument is essentially the accumulator that stores the combined result of all previous executions. And at the end, it becomes the result of `reduce`.
 
 Sounds complicated?
 
@@ -630,8 +664,7 @@ arr.reduce((sum, current) => sum + current);
 
 So it's advised to always specify the initial value.
 
-The method [arr.reduceRight](mdn:js/Array/reduceRight) does the same, but goes from right to left.
-
+The method [arr.reduceRight](mdn:js/Array/reduceRight) does the same but goes from right to left.
 
 ## Array.isArray
 
@@ -641,7 +674,7 @@ So `typeof` does not help to distinguish a plain object from an array:
 
 ```js run
 alert(typeof {}); // object
-alert(typeof []); // same
+alert(typeof []); // object (same)
 ```
 
 ...But arrays are used so often that there's a special method for that: [Array.isArray(value)](mdn:js/Array/isArray). It returns `true` if the `value` is an array, and `false` otherwise.
@@ -656,7 +689,7 @@ alert(Array.isArray([])); // true
 
 Almost all array methods that call functions -- like `find`, `filter`, `map`, with a notable exception of `sort`, accept an optional additional parameter `thisArg`.
 
-That parameter is not explained in the sections above, because it's rarely used. But for completeness we have to cover it.
+That parameter is not explained in the sections above, because it's rarely used. But for completeness, we have to cover it.
 
 Here's the full syntax of these methods:
 
@@ -700,7 +733,7 @@ alert(soldiers[1].age); // 23
 
 If in the example above we used `users.filter(army.canJoin)`, then `army.canJoin` would be called as a standalone function, with `this=undefined`, thus leading to an instant error.
 
-A call to `users.filter(army.canJoin, army)` can be replaced with `users.filter(user => army.canJoin(user))`, that does the same. The former is used more often, as it's a bit easier to understand for most people.
+A call to `users.filter(army.canJoin, army)` can be replaced with `users.filter(user => army.canJoin(user))`, that does the same. The latter is used more often, as it's a bit easier to understand for most people.
 
 ## Summary
 
@@ -711,12 +744,12 @@ A cheat sheet of array methods:
   - `pop()` -- extracts an item from the end,
   - `shift()` -- extracts an item from the beginning,
   - `unshift(...items)` -- adds items to the beginning.
-  - `splice(pos, deleteCount, ...items)` -- at index `pos` delete `deleteCount` elements and insert `items`.
-  - `slice(start, end)` -- creates a new array, copies elements from position `start` till `end` (not inclusive) into it.
+  - `splice(pos, deleteCount, ...items)` -- at index `pos` deletes `deleteCount` elements and inserts `items`.
+  - `slice(start, end)` -- creates a new array, copies elements from index `start` till `end` (not inclusive) into it.
   - `concat(...items)` -- returns a new array: copies all members of the current one and adds `items` to it. If any of `items` is an array, then its elements are taken.
 
 - To search among elements:
-  - `indexOf/lastIndexOf(item, pos)` -- look for `item` starting from position `pos`, return the index or `-1` if not found.
+  - `indexOf/lastIndexOf(item, pos)` -- look for `item` starting from position `pos`, and return the index or `-1` if not found.
   - `includes(value)` -- returns `true` if the array has `value`, otherwise `false`.
   - `find/filter(func)` -- filter elements through the function, return first/all values that make it return `true`.
   - `findIndex` is like `find`, but returns the index instead of a value.
@@ -729,26 +762,40 @@ A cheat sheet of array methods:
   - `sort(func)` -- sorts the array in-place, then returns it.
   - `reverse()` -- reverses the array in-place, then returns it.
   - `split/join` -- convert a string to array and back.
-  - `reduce(func, initial)` -- calculate a single value over the array by calling `func` for each element and passing an intermediate result between the calls.
+  - `reduce/reduceRight(func, initial)` -- calculate a single value over the array by calling `func` for each element and passing an intermediate result between the calls.
 
 - Additionally:
-  - `Array.isArray(arr)` checks `arr` for being an array.
+  - `Array.isArray(value)` checks `value` for being an array, if so returns `true`, otherwise `false`.
 
 Please note that methods `sort`, `reverse` and `splice` modify the array itself.
 
 These methods are the most used ones, they cover 99% of use cases. But there are few others:
 
-- [arr.some(fn)](mdn:js/Array/some)/[arr.every(fn)](mdn:js/Array/every) checks the array.
+- [arr.some(fn)](mdn:js/Array/some)/[arr.every(fn)](mdn:js/Array/every) check the array.
 
   The function `fn` is called on each element of the array similar to `map`. If any/all results are `true`, returns `true`, otherwise `false`.
 
+  These methods behave sort of like `||` and `&&` operators: if `fn` returns a truthy value, `arr.some()` immediately returns `true` and stops iterating over the rest of items; if `fn` returns a falsy value, `arr.every()` immediately returns `false` and stops iterating over the rest of items as well.
+
+  We can use `every` to compare arrays:
+
+  ```js run
+  function arraysEqual(arr1, arr2) {
+    return arr1.length === arr2.length && arr1.every((value, index) => value === arr2[index]);
+  }
+
+  alert( arraysEqual([1, 2], [1, 2])); // true
+  ```
+
 - [arr.fill(value, start, end)](mdn:js/Array/fill) -- fills the array with repeating `value` from index `start` to `end`.
 
 - [arr.copyWithin(target, start, end)](mdn:js/Array/copyWithin) -- copies its elements from position `start` till position `end` into *itself*, at position `target` (overwrites existing).
 
+- [arr.flat(depth)](mdn:js/Array/flat)/[arr.flatMap(fn)](mdn:js/Array/flatMap) create a new flat array from a multidimensional array.
+
 For the full list, see the [manual](mdn:js/Array).
 
-From the first sight it may seem that there are so many methods, quite difficult to remember. But actually that's much easier.
+At first sight, it may seem that there are so many methods, quite difficult to remember. But actually, that's much easier.
 
 Look through the cheat sheet just to be aware of them. Then solve the tasks of this chapter to practice, so that you have experience with array methods.
 
diff --git a/1-js/05-data-types/06-iterable/article.md b/1-js/05-data-types/06-iterable/article.md
index b55f8f018..e2c0d4f97 100644
--- a/1-js/05-data-types/06-iterable/article.md
+++ b/1-js/05-data-types/06-iterable/article.md
@@ -1,7 +1,7 @@
 
 # Iterables
 
-*Iterable* objects is a generalization of arrays. That's a concept that allows to make any object useable in a `for..of` loop.
+*Iterable* objects are a generalization of arrays. That's a concept that allows us to make any object useable in a `for..of` loop.
 
 Of course, Arrays are iterable. But there are many other built-in objects, that are iterable as well. For instance, strings are also iterable.
 
@@ -12,7 +12,7 @@ If an object isn't technically an array, but represents a collection (list, set)
 
 We can easily grasp the concept of iterables by making one of our own.
 
-For instance, we have an object, that is not an array, but looks suitable for `for..of`.
+For instance, we have an object that is not an array, but looks suitable for `for..of`.
 
 Like a `range` object that represents an interval of numbers:
 
@@ -26,12 +26,12 @@ let range = {
 // for(let num of range) ... num=1,2,3,4,5
 ```
 
-To make the `range` iterable (and thus let `for..of` work) we need to add a method to the object named `Symbol.iterator` (a special built-in symbol just for that).
+To make the `range` object iterable (and thus let `for..of` work) we need to add a method to the object named `Symbol.iterator` (a special built-in symbol just for that).
 
 1. When `for..of` starts, it calls that method once (or errors if not found). The method must return an *iterator* -- an object with the method `next`.
 2. Onward, `for..of` works *only with that returned object*.
 3. When `for..of` wants the next value, it calls `next()` on that object.
-4. The result of `next()` must have the form `{done: Boolean, value: any}`, where `done=true`  means that the iteration is finished, otherwise `value` is the next value.
+4. The result of `next()` must have the form `{done: Boolean, value: any}`, where `done=true` means that the loop is finished, otherwise `value` is the next value.
 
 Here's the full implementation for `range` with remarks:
 
@@ -45,10 +45,10 @@ let range = {
 range[Symbol.iterator] = function() {
 
   // ...it returns the iterator object:
-  // 2. Onward, for..of works only with this iterator, asking it for next values
+  // 2. Onward, for..of works only with the iterator object below, asking it for next values
   return {
     current: this.from,
-    last: this.to,      
+    last: this.to,
 
     // 3. next() is called on each iteration by the for..of loop
     next() {
@@ -140,7 +140,7 @@ for (let char of str) {
 
 ## Calling an iterator explicitly
 
-For deeper understanding let's see how to use an iterator explicitly.
+For deeper understanding, let's see how to use an iterator explicitly.
 
 We'll iterate over a string in exactly the same way as `for..of`, but with direct calls. This code creates a string iterator and gets values from it "manually":
 
@@ -165,16 +165,16 @@ That is rarely needed, but gives us more control over the process than `for..of`
 
 ## Iterables and array-likes [#array-like]
 
-There are two official terms that look similar, but are very different. Please make sure you understand them well to avoid the confusion.
+Two official terms look similar, but are very different. Please make sure you understand them well to avoid the confusion.
 
 - *Iterables* are objects that implement the `Symbol.iterator` method, as described above.
 - *Array-likes* are objects that have indexes and `length`, so they look like arrays.
 
-When we use JavaScript for practical tasks in browser or other environments, we may meet objects that are iterables or array-likes, or both.
+When we use JavaScript for practical tasks in a browser or any other environment, we may meet objects that are iterables or array-likes, or both.
 
 For instance, strings are both iterable (`for..of` works on them) and array-like (they have numeric indexes and `length`).
 
-But an iterable may be not array-like. And vice versa an array-like may be not iterable.
+But an iterable may not be array-like. And vice versa an array-like may not be iterable.
 
 For example, the `range` in the example above is iterable, but not array-like, because it does not have indexed properties and `length`.
 
@@ -218,22 +218,22 @@ alert(arr.pop()); // World (method works)
 
 The same happens for an iterable:
 
-```js
+```js run
 // assuming that range is taken from the example above
 let arr = Array.from(range);
 alert(arr); // 1,2,3,4,5 (array toString conversion works)
 ```
 
-The full syntax for `Array.from` allows to provide an optional "mapping" function:
+The full syntax for `Array.from` also allows us to provide an optional "mapping" function:
 ```js
 Array.from(obj[, mapFn, thisArg])
 ```
 
-The optional second argument `mapFn` can be a function that will be applied to each element before adding to the array, and `thisArg` allows to set `this` for it.
+The optional second argument `mapFn` can be a function that will be applied to each element before adding it to the array, and `thisArg` allows us to set `this` for it.
 
 For instance:
 
-```js
+```js run
 // assuming that range is taken from the example above
 
 // square each number
@@ -270,7 +270,7 @@ for (let char of str) {
 alert(chars);
 ```
 
-...But it is shorter.    
+...But it is shorter.
 
 We can even build surrogate-aware `slice` on it:
 
@@ -293,8 +293,8 @@ alert( str.slice(1, 3) ); // garbage (two pieces from different surrogate pairs)
 Objects that can be used in `for..of` are called *iterable*.
 
 - Technically, iterables must implement the method named `Symbol.iterator`.
-    - The result of `obj[Symbol.iterator]` is called an *iterator*. It handles the further iteration process.
-    - An iterator must have the method named `next()` that returns an object `{done: Boolean, value: any}`, here `done:true` denotes the iteration end, otherwise the `value` is the next value.
+    - The result of `obj[Symbol.iterator]()` is called an *iterator*. It handles further iteration process.
+    - An iterator must have the method named `next()` that returns an object `{done: Boolean, value: any}`, here `done:true` denotes the end of the iteration process, otherwise the `value` is the next value.
 - The `Symbol.iterator` method is called automatically by `for..of`, but we also can do it directly.
 - Built-in iterables like strings or arrays, also implement `Symbol.iterator`.
 - String iterator knows about surrogate pairs.
@@ -304,4 +304,4 @@ Objects that have indexed properties and `length` are called *array-like*. Such
 
 If we look inside the specification -- we'll see that most built-in methods assume that they work with iterables or array-likes instead of "real" arrays, because that's more abstract.
 
-`Array.from(obj[, mapFn, thisArg])` makes a real `Array` of an iterable or array-like `obj`, and we can then use array methods on it. The optional arguments `mapFn` and `thisArg` allow us to apply a function to each item.
+`Array.from(obj[, mapFn, thisArg])` makes a real `Array` from an iterable or array-like `obj`, and we can then use array methods on it. The optional arguments `mapFn` and `thisArg` allow us to apply a function to each item.
diff --git a/1-js/05-data-types/07-map-set/03-iterable-keys/task.md b/1-js/05-data-types/07-map-set/03-iterable-keys/task.md
index 25c74bfc2..81507647f 100644
--- a/1-js/05-data-types/07-map-set/03-iterable-keys/task.md
+++ b/1-js/05-data-types/07-map-set/03-iterable-keys/task.md
@@ -4,7 +4,7 @@ importance: 5
 
 # Iterable keys
 
-We'd like to get an array of `map.keys()` in a variable and then do apply array-specific methods to it, e.g. `.push`.
+We'd like to get an array of `map.keys()` in a variable and then apply array-specific methods to it, e.g. `.push`.
 
 But that doesn't work:
 
diff --git a/1-js/05-data-types/07-map-set/article.md b/1-js/05-data-types/07-map-set/article.md
index c4d7c21a4..37f5e48c2 100644
--- a/1-js/05-data-types/07-map-set/article.md
+++ b/1-js/05-data-types/07-map-set/article.md
@@ -1,26 +1,26 @@
 
 # Map and Set
 
-Now we've learned about the following complex data structures:
+Till now, we've learned about the following complex data structures:
 
-- Objects for storing keyed collections.
-- Arrays for storing ordered collections.
+- Objects are used for storing keyed collections.
+- Arrays are used for storing ordered collections.
 
 But that's not enough for real life. That's why `Map` and `Set` also exist.
 
 ## Map
 
-[Map](mdn:js/Map) is a collection of keyed data items, just like an `Object`. But the main difference is that `Map` allows keys of any type.
+[Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) is a collection of keyed data items, just like an `Object`. But the main difference is that `Map` allows keys of any type.
 
 Methods and properties are:
 
-- `new Map()` -- creates the map.
-- `map.set(key, value)` -- stores the value by the key.
-- `map.get(key)` -- returns the value by the key, `undefined` if `key` doesn't exist in map.
-- `map.has(key)` -- returns `true` if the `key` exists, `false` otherwise.
-- `map.delete(key)` -- removes the value by the key.
-- `map.clear()` -- removes everything from the map.
-- `map.size` -- returns the current element count.
+- [`new Map()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/Map) -- creates the map.
+- [`map.set(key, value)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/set) -- stores the value by the key.
+- [`map.get(key)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/get) -- returns the value by the key, `undefined` if `key` doesn't exist in map.
+- [`map.has(key)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/has) -- returns `true` if the `key` exists, `false` otherwise.
+- [`map.delete(key)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/delete) -- removes the element (the key/value pair) by the key.
+- [`map.clear()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/clear) -- removes everything from the map.
+- [`map.size`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/size) -- returns the current element count.
 
 For instance:
 
@@ -41,6 +41,12 @@ alert( map.size ); // 3
 
 As we can see, unlike objects, keys are not converted to strings. Any type of key is possible.
 
+```smart header="`map[key]` isn't the right way to use a `Map`"
+Although `map[key]` also works, e.g. we can set `map[key] = 2`, this is treating `map` as a plain JavaScript object, so it implies all corresponding limitations (only string/symbol keys and so on).
+
+So we should use `map` methods: `set`, `get` and so on.
+```
+
 **Map can also use objects as keys.**
 
 For instance:
@@ -57,24 +63,26 @@ visitsCountMap.set(john, 123);
 alert( visitsCountMap.get(john) ); // 123
 ```
 
-Using objects as keys is one of most notable and important `Map` features. For string keys, `Object` can be fine, but not for object keys.
+Using objects as keys is one of the most notable and important `Map` features. The same does not count for `Object`. String as a key in `Object` is fine, but we can't use another `Object` as a key in `Object`.
 
 Let's try:
 
 ```js run
 let john = { name: "John" };
+let ben = { name: "Ben" };
 
 let visitsCountObj = {}; // try to use an object
 
-visitsCountObj[john] = 123; // try to use john object as the key
+visitsCountObj[ben] = 234; // try to use ben object as the key
+visitsCountObj[john] = 123; // try to use john object as the key, ben object will get replaced
 
 *!*
 // That's what got written!
-alert( visitsCountObj["[object Object]"] ); // 123
+alert( visitsCountObj["[object Object]"] ); // 123 
 */!*
 ```
 
-As `visitsCountObj` is an object, it converts all keys, such as `john` to strings, so we've got the string key `"[object Object]"`. Definitely not what we want.
+As `visitsCountObj` is an object, it converts all `Object` keys, such as `john` and `ben` above, to same string `"[object Object]"`. Definitely not what we want.
 
 ```smart header="How `Map` compares keys"
 To test keys for equivalence, `Map` uses the algorithm [SameValueZero](https://tc39.github.io/ecma262/#sec-samevaluezero). It is roughly the same as strict equality `===`, but the difference is that `NaN` is considered equal to `NaN`. So `NaN` can be used as the key as well.
@@ -92,14 +100,13 @@ map.set('1', 'str1')
 ```
 ````
 
-
 ## Iteration over Map
 
 For looping over a `map`, there are 3 methods:
 
-- `map.keys()` -- returns an iterable for keys,
-- `map.values()` -- returns an iterable for values,
-- `map.entries()` -- returns an iterable for entries `[key, value]`, it's used by default in `for..of`.
+- [`map.keys()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/keys) -- returns an iterable for keys,
+- [`map.values()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/values) -- returns an iterable for values,
+- [`map.entries()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/entries) -- returns an iterable for entries `[key, value]`, it's used by default in `for..of`.
 
 For instance:
 
@@ -154,7 +161,7 @@ let map = new Map([
 alert( map.get('1') ); // str1
 ```
 
-If we have a plain object, and we'd like to create a `Map` from it, then we can use built-in method [Object.entries(obj)](mdn:js/Object/entries) that returns an array of key/value pairs for an object exactly in that format.
+If we have a plain object, and we'd like to create a `Map` from it, then we can use built-in method [Object.entries(obj)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries) that returns an array of key/value pairs for an object exactly in that format.
 
 So we can create a map from an object like this:
 
@@ -192,7 +199,7 @@ let prices = Object.fromEntries([
 alert(prices.orange); // 2
 ```
 
-We can use `Object.fromEntries` to get an plain object from `Map`.
+We can use `Object.fromEntries` to get a plain object from `Map`.
 
 E.g. we store the data in a `Map`, but we need to pass it to a 3rd-party code that expects a plain object.
 
@@ -214,7 +221,7 @@ let obj = Object.fromEntries(map.entries()); // make a plain object (*)
 alert(obj.orange); // 2
 ```
 
-A call to `map.entries()` returns an array of key/value pairs, exactly in the right format for `Object.fromEntries`.
+A call to `map.entries()` returns an iterable of key/value pairs, exactly in the right format for `Object.fromEntries`.
 
 We could also make line `(*)` shorter:
 ```js
@@ -225,16 +232,16 @@ That's the same, because `Object.fromEntries` expects an iterable object as the
 
 ## Set
 
-A `Set` is a special type collection - "set of values" (without keys), where each value may occur only once.
+A [`Set`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set) is a special type collection - "set of values" (without keys), where each value may occur only once.
 
 Its main methods are:
 
-- `new Set(iterable)` -- creates the set, and if an `iterable` object is provided (usually an array), copies values from it into the set.
-- `set.add(value)` -- adds a value, returns the set itself.
-- `set.delete(value)` -- removes the value, returns `true` if `value` existed at the moment of the call, otherwise `false`.
-- `set.has(value)` -- returns `true` if the value exists in the set, otherwise `false`.
-- `set.clear()` -- removes everything from the set.
-- `set.size` -- is the elements count.
+- [`new Set([iterable])`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/Set) -- creates the set, and if an `iterable` object is provided (usually an array), copies values from it into the set.
+- [`set.add(value)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/add) -- adds a value, returns the set itself.
+- [`set.delete(value)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/delete) -- removes the value, returns `true` if `value` existed at the moment of the call, otherwise `false`.
+- [`set.has(value)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/has) -- returns `true` if the value exists in the set, otherwise `false`.
+- [`set.clear()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/clear) -- removes everything from the set.
+- [`set.size`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/size) -- is the elements count.
 
 The main feature is that repeated calls of `set.add(value)` with the same value don't do anything. That's the reason why each value appears in a `Set` only once.
 
@@ -264,7 +271,7 @@ for (let user of set) {
 }
 ```
 
-The alternative to `Set` could be an array of users, and the code to check for duplicates on every insertion using [arr.find](mdn:js/Array/find). But the performance would be much worse, because this method walks through the whole array checking every element. `Set` is much better optimized internally for uniqueness checks.
+The alternative to `Set` could be an array of users, and the code to check for duplicates on every insertion using [arr.find](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find). But the performance would be much worse, because this method walks through the whole array checking every element. `Set` is much better optimized internally for uniqueness checks.
 
 ## Iteration over Set
 
@@ -283,42 +290,42 @@ set.forEach((value, valueAgain, set) => {
 
 Note the funny thing. The callback function passed in `forEach` has 3 arguments: a `value`, then *the same value* `valueAgain`, and then the target object. Indeed, the same value appears in the arguments twice.
 
-That's for compatibility with `Map` where the callback passed `forEach` has three arguments. Looks a bit strange, for sure. But may help to replace `Map` with `Set` in certain cases with ease, and vice versa.
+That's for compatibility with `Map` where the callback passed `forEach` has three arguments. Looks a bit strange, for sure. But this may help to replace `Map` with `Set` in certain cases with ease, and vice versa.
 
 The same methods `Map` has for iterators are also supported:
 
-- `set.keys()` -- returns an iterable object for values,
-- `set.values()` -- same as `set.keys()`, for compatibility with `Map`,
-- `set.entries()` -- returns an iterable object for entries `[value, value]`, exists for compatibility with `Map`.
+- [`set.keys()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/keys) -- returns an iterable object for values,
+- [`set.values()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/values) -- same as `set.keys()`, for compatibility with `Map`,
+- [`set.entries()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/entries) -- returns an iterable object for entries `[value, value]`, exists for compatibility with `Map`.
 
 ## Summary
 
-`Map` -- is a collection of keyed values.
+[`Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) -- is a collection of keyed values.
 
 Methods and properties:
 
-- `new Map([iterable])` -- creates the map, with optional `iterable` (e.g. array) of `[key,value]` pairs for initialization.
-- `map.set(key, value)` -- stores the value by the key.
-- `map.get(key)` -- returns the value by the key, `undefined` if `key` doesn't exist in map.
-- `map.has(key)` -- returns `true` if the `key` exists, `false` otherwise.
-- `map.delete(key)` -- removes the value by the key.
-- `map.clear()` -- removes everything from the map.
-- `map.size` -- returns the current element count.
+- [`new Map([iterable])`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/Map) -- creates the map, with optional `iterable` (e.g. array) of `[key,value]` pairs for initialization.
+- [`map.set(key, value)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/set) -- stores the value by the key, returns the map itself.
+- [`map.get(key)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/get) -- returns the value by the key, `undefined` if `key` doesn't exist in map.
+- [`map.has(key)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/has) -- returns `true` if the `key` exists, `false` otherwise.
+- [`map.delete(key)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/delete) -- removes the element by the key, returns `true` if `key` existed at the moment of the call, otherwise `false`.
+- [`map.clear()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/clear) -- removes everything from the map.
+- [`map.size`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/size) -- returns the current element count.
 
 The differences from a regular `Object`:
 
 - Any keys, objects can be keys.
 - Additional convenient methods, the `size` property.
 
-`Set` -- is a collection of unique values.
+[`Set`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set) -- is a collection of unique values.
 
 Methods and properties:
 
-- `new Set([iterable])` -- creates the set, with optional `iterable` (e.g. array) of values for initialization.
-- `set.add(value)` -- adds a value (does nothing if `value` exists), returns the set itself.
-- `set.delete(value)` -- removes the value, returns `true` if `value` existed at the moment of the call, otherwise `false`.
-- `set.has(value)` -- returns `true` if the value exists in the set, otherwise `false`.
-- `set.clear()` -- removes everything from the set.
-- `set.size` -- is the elements count.
+- [`new Set([iterable])`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/Set) -- creates the set, with optional `iterable` (e.g. array) of values for initialization.
+- [`set.add(value)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/add) -- adds a value (does nothing if `value` exists), returns the set itself.
+- [`set.delete(value)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/delete) -- removes the value, returns `true` if `value` existed at the moment of the call, otherwise `false`.
+- [`set.has(value)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/has) -- returns `true` if the value exists in the set, otherwise `false`.
+- [`set.clear()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/clear) -- removes everything from the set.
+- [`set.size`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/size) -- is the elements count.
 
 Iteration over `Map` and `Set` is always in the insertion order, so we can't say that these collections are unordered, but we can't reorder elements or directly get an element by its number.
diff --git a/1-js/05-data-types/08-weakmap-weakset/01-recipients-read/solution.md b/1-js/05-data-types/08-weakmap-weakset/01-recipients-read/solution.md
index 6a4c20baf..e2147ccfa 100644
--- a/1-js/05-data-types/08-weakmap-weakset/01-recipients-read/solution.md
+++ b/1-js/05-data-types/08-weakmap-weakset/01-recipients-read/solution.md
@@ -25,7 +25,7 @@ messages.shift();
 // now readMessages has 1 element (technically memory may be cleaned later)
 ```
 
-The `WeakSet` allows to store a set of messages and easily check for the existance of a message in it.
+The `WeakSet` allows to store a set of messages and easily check for the existence of a message in it.
 
 It cleans up itself automatically. The tradeoff is that we can't iterate over it,  can't get "all read messages" from it directly. But we can do it by iterating over all messages and filtering those that are in the set.
 
diff --git a/1-js/05-data-types/08-weakmap-weakset/article.md b/1-js/05-data-types/08-weakmap-weakset/article.md
index 11ff9d5eb..9795017d4 100644
--- a/1-js/05-data-types/08-weakmap-weakset/article.md
+++ b/1-js/05-data-types/08-weakmap-weakset/article.md
@@ -1,8 +1,10 @@
+
 # WeakMap and WeakSet
 
-As we know from the chapter <info:garbage-collection>, JavaScript engine stores a value in memory while it is reachable (and can potentially be used).
+As we know from the chapter <info:garbage-collection>, JavaScript engine keeps a value in memory while it is "reachable" and can potentially be used.
 
 For instance:
+
 ```js
 let john = { name: "John" };
 
@@ -30,7 +32,8 @@ let array = [ john ];
 john = null; // overwrite the reference
 
 *!*
-// john is stored inside the array, so it won't be garbage-collected
+// the object previously referenced by john is stored inside the array
+// therefore it won't be garbage-collected
 // we can get it as array[0]
 */!*
 ```
@@ -53,13 +56,13 @@ john = null; // overwrite the reference
 */!*
 ```
 
-`WeakMap` is fundamentally different in this aspect. It doesn't prevent garbage-collection of key objects.
+[`WeakMap`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap) is fundamentally different in this aspect. It doesn't prevent garbage-collection of key objects.
 
 Let's see what it means on examples.
 
 ## WeakMap
 
-The first difference from `Map` is that `WeakMap` keys must be objects, not primitive values:
+The first difference between [`Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) and [`WeakMap`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap) is that keys must be objects, not primitive values:
 
 ```js run
 let weakMap = new WeakMap();
@@ -93,16 +96,16 @@ Compare it with the regular `Map` example above. Now if `john` only exists as th
 
 `WeakMap` has only the following methods:
 
-- `weakMap.get(key)`
-- `weakMap.set(key, value)`
-- `weakMap.delete(key)`
-- `weakMap.has(key)`
+- [`weakMap.set(key, value)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap/set)
+- [`weakMap.get(key)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap/get)
+- [`weakMap.delete(key)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap/delete)
+- [`weakMap.has(key)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap/has)
 
 Why such a limitation? That's for technical reasons. If an object has lost all other references (like `john` in the code above), then it is to be garbage-collected automatically. But technically it's not exactly specified *when the cleanup happens*.
 
-The JavaScript engine decides that. It may choose to perform the memory cleanup immediately or to wait and do the cleaning later when more deletions happen. So, technically the current element count of a `WeakMap` is not known. The engine may have cleaned it up or not, or did it partially. For that reason, methods that access all keys/values are not supported.
+The JavaScript engine decides that. It may choose to perform the memory cleanup immediately or to wait and do the cleaning later when more deletions happen. So, technically, the current element count of a `WeakMap` is not known. The engine may have cleaned it up or not, or did it partially. For that reason, methods that access all keys/values are not supported.
 
-Now where do we need such data structure?
+Now, where do we need such a data structure?
 
 ## Use case: additional data
 
@@ -141,13 +144,12 @@ And here's another part of the code, maybe another file using it:
 let john = { name: "John" };
 
 countUser(john); // count his visits
-countUser(john);
 
 // later john leaves us
 john = null;
 ```
 
-Now `john` object should be garbage collected, but remains in memory, as it's a key in `visitsCountMap`.
+Now, `john` object should be garbage collected, but remains in memory, as it's a key in `visitsCountMap`.
 
 We need to clean `visitsCountMap` when we remove users, otherwise it will grow in memory indefinitely. Such cleaning can become a tedious task in complex architectures.
 
@@ -164,13 +166,13 @@ function countUser(user) {
 }
 ```
 
-Now we don't have to clean `visitsCountMap`. After `john` object becomes unreachable by all means except as a key of `WeakMap`, it gets removed from memory, along with the information by that key from `WeakMap`.
+Now we don't have to clean `visitsCountMap`. After `john` object becomes unreachable, by all means except as a key of `WeakMap`, it gets removed from memory, along with the information by that key from `WeakMap`.
 
 ## Use case: caching
 
-Another common example is caching: when a function result should be remembered ("cached"), so that future calls on the same object reuse it.
+Another common example is caching. We can store ("cache") results from a function, so that future calls on the same object can reuse it.
 
-We can use `Map` to store results, like this:
+To achieve that, we can use `Map` (not optimal scenario):
 
 ```js run
 // 📁 cache.js
@@ -182,6 +184,7 @@ function process(obj) {
     let result = /* calculations of the result for */ obj;
 
     cache.set(obj, result);
+    return result;
   }
 
   return cache.get(obj);
@@ -207,7 +210,7 @@ alert(cache.size); // 1 (Ouch! The object is still in cache, taking memory!)
 
 For multiple calls of `process(obj)` with the same object, it only calculates the result the first time, and then just takes it from `cache`. The downside is that we need to clean `cache` when the object is not needed any more.
 
-If we replace `Map` with `WeakMap`, then this problem disappears: the cached result will be removed from memory automatically after the object gets garbage collected.
+If we replace `Map` with `WeakMap`, then this problem disappears. The cached result will be removed from memory automatically after the object gets garbage collected.
 
 ```js run
 // 📁 cache.js
@@ -221,6 +224,7 @@ function process(obj) {
     let result = /* calculate the result for */ obj;
 
     cache.set(obj, result);
+    return result;
   }
 
   return cache.get(obj);
@@ -242,13 +246,13 @@ obj = null;
 
 ## WeakSet
 
-`WeakSet` behaves similarly:
+[`WeakSet`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet) behaves similarly:
 
 - It is analogous to `Set`, but we may only add objects to `WeakSet` (not primitives).
 - An object exists in the set while it is reachable from somewhere else.
-- Like `Set`, it supports `add`, `has` and `delete`, but not `size`, `keys()` and no iterations.
+- Like `Set`, it supports [`add`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Weakset/add), [`has`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Weakset/has) and [`delete`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Weakset/delete), but not `size`, `keys()` and no iterations.
 
-Being "weak", it also serves as an additional storage. But not for an arbitrary data, but rather for "yes/no" facts. A membership in `WeakSet` may mean something about the object.
+Being "weak", it also serves as additional storage. But not for arbitrary data, rather for "yes/no" facts. A membership in `WeakSet` may mean something about the object.
 
 For instance, we can add users to `WeakSet` to keep track of those who visited our site:
 
@@ -276,14 +280,16 @@ john = null;
 // visitedSet will be cleaned automatically
 ```
 
-The most notable limitation of `WeakMap` and `WeakSet` is the absence of iterations, and inability to get all current content. That may appear inconvenient, but does not prevent `WeakMap/WeakSet` from doing their main job -- be an "additional" storage of data for objects which are stored/managed at another place.
+The most notable limitation of `WeakMap` and `WeakSet` is the absence of iterations, and the inability to get all current content. That may appear inconvenient, but does not prevent `WeakMap/WeakSet` from doing their main job -- be an "additional" storage of data for objects which are stored/managed at another place.
 
 ## Summary
 
-`WeakMap` is `Map`-like collection that allows only objects as keys and removes them together with associated value once they become inaccessible by other means.
+[`WeakMap`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap) is `Map`-like collection that allows only objects as keys and removes them together with associated value once they become inaccessible by other means.
+
+[`WeakSet`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet) is `Set`-like collection that stores only objects and removes them once they become inaccessible by other means.
 
-`WeakSet` is `Set`-like collection that stores only objects and removes them once they become inaccessible by other means.
+Their main advantages are that they have weak reference to objects, so they can easily be removed by garbage collector.
 
-Both of them do not support methods and properties that refer to all keys or their count. Only individual operations are allowed.
+That comes at the cost of not having support for `clear`, `size`, `keys`, `values`...
 
-`WeakMap` and `WeakSet` are used as "secondary" data structures in addition to the "main" object storage. Once the object is removed from the main storage, if it is only found as the key of `WeakMap` or in a `WeakSet`, it will be cleaned up automatically.
+`WeakMap` and `WeakSet` are used as "secondary" data structures in addition to the "primary" object storage. Once the object is removed from the primary storage, if it is only found as the key of `WeakMap` or in a `WeakSet`, it will be cleaned up automatically.
diff --git a/1-js/05-data-types/09-keys-values-entries/article.md b/1-js/05-data-types/09-keys-values-entries/article.md
index 4af192515..bef678f53 100644
--- a/1-js/05-data-types/09-keys-values-entries/article.md
+++ b/1-js/05-data-types/09-keys-values-entries/article.md
@@ -74,10 +74,10 @@ Usually that's convenient. But if we want symbolic keys too, then there's a sepa
 
 Objects lack many methods that exist for arrays, e.g. `map`, `filter` and others.
 
-If we'd like to apply them, then we can use `Object.entries` followed `Object.fromEntries`:
+If we'd like to apply them, then we can use `Object.entries` followed by `Object.fromEntries`:
 
 1. Use `Object.entries(obj)` to get an array of key/value pairs from `obj`.
-2. Use array methods on that array, e.g. `map`.
+2. Use array methods on that array, e.g. `map`, to transform these key/value pairs.
 3. Use `Object.fromEntries(array)` on the resulting array to turn it back into an object.
 
 For example, we have an object with prices, and would like to double them:
@@ -91,12 +91,13 @@ let prices = {
 
 *!*
 let doublePrices = Object.fromEntries(
-  // convert to array, map, and then fromEntries gives back the object
-  Object.entries(prices).map(([key, value]) => [key, value * 2])
+  // convert prices to array, map each key/value pair into another pair
+  // and then fromEntries gives back the object
+  Object.entries(prices).map(entry => [entry[0], entry[1] * 2])
 );
 */!*
 
 alert(doublePrices.meat); // 8
-```   
+```
 
-It may look difficult from the first sight, but becomes easy to understand after you use it once or twice. We can make powerful chains of transforms this way. 
+It may look difficult at first sight, but becomes easy to understand after you use it once or twice. We can make powerful chains of transforms this way.
diff --git a/1-js/05-data-types/10-destructuring-assignment/6-max-salary/_js.view/solution.js b/1-js/05-data-types/10-destructuring-assignment/6-max-salary/_js.view/solution.js
index f4bd5c761..6538af42b 100644
--- a/1-js/05-data-types/10-destructuring-assignment/6-max-salary/_js.view/solution.js
+++ b/1-js/05-data-types/10-destructuring-assignment/6-max-salary/_js.view/solution.js
@@ -1,16 +1,14 @@
 function topSalary(salaries) {
 
-  let max = 0;
+  let maxSalary = 0;
   let maxName = null;
 
   for(const [name, salary] of Object.entries(salaries)) {
-    if (max < salary) {
-      max = salary;
+    if (maxSalary < salary) {
+      maxSalary = salary;
       maxName = name;
     }
   }
 
   return maxName;
-}
-
-
+}
\ No newline at end of file
diff --git a/1-js/05-data-types/10-destructuring-assignment/article.md b/1-js/05-data-types/10-destructuring-assignment/article.md
index 907c28cab..0c52741d1 100644
--- a/1-js/05-data-types/10-destructuring-assignment/article.md
+++ b/1-js/05-data-types/10-destructuring-assignment/article.md
@@ -2,19 +2,22 @@
 
 The two most used data structures in JavaScript are `Object` and `Array`.
 
-Objects allow us to create a single entity that stores data items by key, and arrays allow us to gather data items into an ordered collection.
+- Objects allow us to create a single entity that stores data items by key.
+- Arrays allow us to gather data items into an ordered list.
 
-But when we pass those to a function, it may need not an object/array as a whole, but rather individual pieces.
+However, when we pass these to a function, we may not need all of it. The function might only require certain elements or properties.
 
-*Destructuring assignment* is a special syntax that allows us to "unpack" arrays or objects into a bunch of variables, as sometimes that's more convenient. Destructuring also works great with complex functions that have a lot of parameters, default values, and so on.
+*Destructuring assignment* is a special syntax that allows us to "unpack" arrays or objects into a bunch of variables, as sometimes that's more convenient.
+
+Destructuring also works well with complex functions that have a lot of parameters, default values, and so on. Soon we'll see that.
 
 ## Array destructuring
 
-An example of how the array is destructured into variables:
+Here's an example of how an array is destructured into variables:
 
 ```js
-// we have an array with the name and surname
-let arr = ["Ilya", "Kantor"]
+// we have an array with a name and surname
+let arr = ["John", "Smith"]
 
 *!*
 // destructuring assignment
@@ -23,20 +26,24 @@ let arr = ["Ilya", "Kantor"]
 let [firstName, surname] = arr;
 */!*
 
-alert(firstName); // Ilya
-alert(surname);  // Kantor
+alert(firstName); // John
+alert(surname);  // Smith
 ```
 
 Now we can work with variables instead of array members.
 
 It looks great when combined with `split` or other array-returning methods:
 
-```js
-let [firstName, surname] = "Ilya Kantor".split(' ');
+```js run
+let [firstName, surname] = "John Smith".split(' ');
+alert(firstName); // John
+alert(surname);  // Smith
 ```
 
+As you can see, the syntax is simple. There are several peculiar details though. Let's see more examples to understand it better.
+
 ````smart header="\"Destructuring\" does not mean \"destructive\"."
-It's called "destructuring assignment," because it "destructurizes" by copying items into variables. But the array itself is not modified.
+It's called "destructuring assignment," because it "destructurizes" by copying items into variables. However, the array itself is not modified.
 
 It's just a shorter way to write:
 ```js
@@ -58,7 +65,7 @@ let [firstName, , title] = ["Julius", "Caesar", "Consul", "of the Roman Republic
 alert( title ); // Consul
 ```
 
-In the code above, the second element of the array is skipped, the third one is assigned to `title`, and the rest of the array items is also skipped (as there are no variables for them).
+In the code above, the second element of the array is skipped, the third one is assigned to `title`, and the rest of the array items are also skipped (as there are no variables for them).
 ````
 
 ````smart header="Works with any iterable on the right-side"
@@ -69,29 +76,28 @@ In the code above, the second element of the array is skipped, the third one is
 let [a, b, c] = "abc"; // ["a", "b", "c"]
 let [one, two, three] = new Set([1, 2, 3]);
 ```
-
+That works, because internally a destructuring assignment works by iterating over the right value. It's a kind of syntax sugar for calling `for..of` over the value to the right of `=` and assigning the values.
 ````
 
 
 ````smart header="Assign to anything at the left-side"
-
-We can use any "assignables" at the left side.
+We can use any "assignables" on the left side.
 
 For instance, an object property:
 ```js run
 let user = {};
-[user.name, user.surname] = "Ilya Kantor".split(' ');
+[user.name, user.surname] = "John Smith".split(' ');
 
-alert(user.name); // Ilya
+alert(user.name); // John
+alert(user.surname); // Smith
 ```
 
 ````
 
 ````smart header="Looping with .entries()"
+In the previous chapter, we saw the [Object.entries(obj)](mdn:js/Object/entries) method.
 
-In the previous chapter we saw the [Object.entries(obj)](mdn:js/Object/entries) method.
-
-We can use it with destructuring to loop over keys-and-values of an object:
+We can use it with destructuring to loop over the keys-and-values of an object:
 
 ```js run
 let user = {
@@ -99,7 +105,7 @@ let user = {
   age: 30
 };
 
-// loop over keys-and-values
+// loop over the keys-and-values
 *!*
 for (let [key, value] of Object.entries(user)) {
 */!*
@@ -107,7 +113,7 @@ for (let [key, value] of Object.entries(user)) {
 }
 ```
 
-...And the same for a map:
+The similar code for a `Map` is simpler, as it's iterable:
 
 ```js run
 let user = new Map();
@@ -115,35 +121,73 @@ user.set("name", "John");
 user.set("age", "30");
 
 *!*
+// Map iterates as [key, value] pairs, very convenient for destructuring
 for (let [key, value] of user) {
 */!*
   alert(`${key}:${value}`); // name:John, then age:30
 }
 ```
 ````
+
+````smart header="Swap variables trick"
+There's a well-known trick for swapping values of two variables using a destructuring assignment:
+
+```js run
+let guest = "Jane";
+let admin = "Pete";
+
+// Let's swap the values: make guest=Pete, admin=Jane
+*!*
+[guest, admin] = [admin, guest];
+*/!*
+
+alert(`${guest} ${admin}`); // Pete Jane (successfully swapped!)
+```
+
+Here we create a temporary array of two variables and immediately destructure it in swapped order.
+
+We can swap more than two variables this way.
+````
+
 ### The rest '...'
 
-If we want not just to get first values, but also to gather all that follows -- we can add one more parameter that gets "the rest" using three dots `"..."`:
+Usually, if the array is longer than the list at the left, the "extra" items are omitted.
+
+For example, here only two items are taken, and the rest is just ignored:
 
 ```js run
-let [name1, name2, *!*...rest*/!*] = ["Julius", "Caesar", *!*"Consul", "of the Roman Republic"*/!*];
+let [name1, name2] = ["Julius", "Caesar", "Consul", "of the Roman Republic"];
 
 alert(name1); // Julius
 alert(name2); // Caesar
+// Further items aren't assigned anywhere
+```
+
+If we'd like also to gather all that follows -- we can add one more parameter that gets "the rest" using three dots `"..."`:
+
+```js run
+let [name1, name2, *!*...rest*/!*] = ["Julius", "Caesar", *!*"Consul", "of the Roman Republic"*/!*];
 
 *!*
-// Note that type of `rest` is Array.
+// rest is an array of items, starting from the 3rd one
 alert(rest[0]); // Consul
 alert(rest[1]); // of the Roman Republic
 alert(rest.length); // 2
 */!*
 ```
 
-The value of `rest` is the array of the remaining array elements. We can use any other variable name in place of `rest`, just make sure it has three dots before it and goes last in the destructuring assignment.
+The value of `rest` is the array of the remaining array elements.
+
+We can use any other variable name in place of `rest`, just make sure it has three dots before it and goes last in the destructuring assignment.
+
+```js run
+let [name1, name2, *!*...titles*/!*] = ["Julius", "Caesar", "Consul", "of the Roman Republic"];
+// now titles = ["Consul", "of the Roman Republic"]
+```
 
 ### Default values
 
-If there are fewer values in the array than variables in the assignment, there will be no error. Absent values are considered undefined:
+If the array is shorter than the list of variables on the left, there will be no errors. Absent values are considered undefined:
 
 ```js run
 *!*
@@ -168,7 +212,7 @@ alert(surname); // Anonymous (default used)
 
 Default values can be more complex expressions or even function calls. They are evaluated only if the value is not provided.
 
-For instance, here we use the `prompt` function for two defaults. But it will run only for the missing one:
+For instance, here we use the `prompt` function for two defaults:
 
 ```js run
 // runs only prompt for surname
@@ -178,7 +222,7 @@ alert(name);    // Julius (from array)
 alert(surname); // whatever prompt gets
 ```
 
-
+Please note: the `prompt` will run only for the missing value (`surname`).
 
 ## Object destructuring
 
@@ -190,7 +234,7 @@ The basic syntax is:
 let {var1, var2} = {var1:…, var2:…}
 ```
 
-We have an existing object at the right side, that we want to split into variables. The left side contains a "pattern" for corresponding properties. In the simple case, that's a list of variable names in `{...}`.
+We should have an existing object on the right side, that we want to split into variables. The left side contains an object-like "pattern" for corresponding properties. In the simplest case, that's a list of variable names in `{...}`.
 
 For instance:
 
@@ -210,7 +254,9 @@ alert(width);  // 100
 alert(height); // 200
 ```
 
-Properties `options.title`, `options.width` and `options.height` are assigned to the corresponding variables. The order does not matter. This works too:
+Properties `options.title`, `options.width` and `options.height` are assigned to the corresponding variables.
+
+The order does not matter. This works too:
 
 ```js
 // changed the order in let {...}
@@ -219,7 +265,7 @@ let {height, width, title} = { title: "Menu", height: 200, width: 100 }
 
 The pattern on the left side may be more complex and specify the mapping between properties and variables.
 
-If we want to assign a property to a variable with another name, for instance, `options.width` to go into the variable named `w`, then we can set it using a colon:
+If we want to assign a property to a variable with another name, for instance, make `options.width` go into the variable named `w`, then we can set the variable name using a colon:
 
 ```js run
 let options = {
@@ -372,9 +418,9 @@ alert( title ); // Menu
 
 ## Nested destructuring
 
-If an object or an array contain other nested objects and arrays, we can use more complex left-side patterns to extract deeper portions.
+If an object or an array contains other nested objects and arrays, we can use more complex left-side patterns to extract deeper portions.
 
-In the code below `options` has another object in the property `size` and an array in the property `items`. The pattern at the left side of the assignment has the same structure to extract values from them:
+In the code below `options` has another object in the property `size` and an array in the property `items`. The pattern on the left side of the assignment has the same structure to extract values from them:
 
 ```js run
 let options = {
@@ -383,7 +429,7 @@ let options = {
     height: 200
   },
   items: ["Cake", "Donut"],
-  extra: true   
+  extra: true
 };
 
 // destructuring assignment split in multiple lines for clarity
@@ -403,7 +449,7 @@ alert(item1);  // Cake
 alert(item2);  // Donut
 ```
 
-All properties of `options` object except `extra` that is absent in the left part, are assigned to corresponding variables:
+All properties of `options` object except `extra` which is absent in the left part, are assigned to corresponding variables:
 
 ![](destructuring-complex.svg)
 
@@ -413,9 +459,9 @@ Note that there are no variables for `size` and `items`, as we take their conten
 
 ## Smart function parameters
 
-There are times when a function has many parameters, most of which are optional. That's especially true for user interfaces. Imagine a function that creates a menu. It may have a width, a height, a title, items list and so on.
+There are times when a function has many parameters, most of which are optional. That's especially true for user interfaces. Imagine a function that creates a menu. It may have a width, a height, a title, an item list and so on.
 
-Here's a bad way to write such function:
+Here's a bad way to write such a function:
 
 ```js
 function showMenu(title = "Untitled", width = 200, height = 100, items = []) {
@@ -423,7 +469,7 @@ function showMenu(title = "Untitled", width = 200, height = 100, items = []) {
 }
 ```
 
-In real-life, the problem is how to remember the order of arguments. Usually IDEs try to help us, especially if the code is well-documented, but still... Another problem is how to call a function when most parameters are ok by default.
+In real-life, the problem is how to remember the order of arguments. Usually, IDEs try to help us, especially if the code is well-documented, but still... Another problem is how to call a function when most parameters are ok by default.
 
 Like this?
 
@@ -488,7 +534,7 @@ function({
 })
 ```
 
-Then, for an object of parameters, there will be a variable `varName` for property `incomingProperty`, with `defaultValue` by default.
+Then, for an object of parameters, there will be a variable `varName` for the property `incomingProperty`, with `defaultValue` by default.
 
 Please note that such destructuring assumes that `showMenu()` does have an argument. If we want all values by default, then we should specify an empty object:
 
@@ -515,7 +561,7 @@ In the code above, the whole arguments object is `{}` by default, so there's alw
 - Destructuring assignment allows for instantly mapping an object or array onto many variables.
 - The full object syntax:
     ```js
-    let {prop : varName = default, ...rest} = object
+    let {prop : varName = defaultValue, ...rest} = object
     ```
 
     This means that property `prop` should go into the variable `varName` and, if no such property exists, then the `default` value should be used.
@@ -525,9 +571,9 @@ In the code above, the whole arguments object is `{}` by default, so there's alw
 - The full array syntax:
 
     ```js
-    let [item1 = default, item2, ...rest] = array
+    let [item1 = defaultValue, item2, ...rest] = array
     ```
 
-    The first item goes to `item1`; the second goes into `item2`, all the rest makes the array `rest`.
+    The first item goes to `item1`; the second goes into `item2`, and all the rest makes the array `rest`.
 
 - It's possible to extract data from nested arrays/objects, for that the left side must have the same structure as the right one.
diff --git a/1-js/05-data-types/11-date/1-new-date/solution.md b/1-js/05-data-types/11-date/1-new-date/solution.md
index 9bb1d749c..18286c336 100644
--- a/1-js/05-data-types/11-date/1-new-date/solution.md
+++ b/1-js/05-data-types/11-date/1-new-date/solution.md
@@ -2,7 +2,17 @@ The `new Date` constructor uses the local time zone. So the only important thing
 
 So February has number 1.
 
+Here's an example with numbers as date components:
+
+```js run
+//new Date(year, month, date, hour, minute, second, millisecond)
+let d1 = new Date(2012, 1, 20, 3, 12);
+alert( d1 );
+```
+We could also create a date from a string, like this:
+
 ```js run
-let d = new Date(2012, 1, 20, 3, 12);
-alert( d );
+//new Date(datastring)
+let d2 = new Date("2012-02-20T03:12");
+alert( d2 );
 ```
diff --git a/1-js/05-data-types/11-date/6-get-seconds-today/solution.md b/1-js/05-data-types/11-date/6-get-seconds-today/solution.md
index a483afe93..8f8e52b68 100644
--- a/1-js/05-data-types/11-date/6-get-seconds-today/solution.md
+++ b/1-js/05-data-types/11-date/6-get-seconds-today/solution.md
@@ -23,4 +23,6 @@ function getSecondsToday() {
   let d = new Date();
   return d.getHours() * 3600 + d.getMinutes() * 60 + d.getSeconds();
 }
+
+alert( getSecondsToday() );
 ```
diff --git a/1-js/05-data-types/11-date/8-format-date-relative/solution.md b/1-js/05-data-types/11-date/8-format-date-relative/solution.md
index 718618528..372485685 100644
--- a/1-js/05-data-types/11-date/8-format-date-relative/solution.md
+++ b/1-js/05-data-types/11-date/8-format-date-relative/solution.md
@@ -40,7 +40,7 @@ alert( formatDate(new Date(new Date - 30 * 1000)) ); // "30 sec. ago"
 
 alert( formatDate(new Date(new Date - 5 * 60 * 1000)) ); // "5 min. ago"
 
-// yesterday's date like 31.12.2016, 20:00
+// yesterday's date like 31.12.2016 20:00
 alert( formatDate(new Date(new Date - 86400 * 1000)) );
 ```
 
diff --git a/1-js/05-data-types/11-date/8-format-date-relative/task.md b/1-js/05-data-types/11-date/8-format-date-relative/task.md
index 4dc067375..9651b305f 100644
--- a/1-js/05-data-types/11-date/8-format-date-relative/task.md
+++ b/1-js/05-data-types/11-date/8-format-date-relative/task.md
@@ -20,6 +20,6 @@ alert( formatDate(new Date(new Date - 30 * 1000)) ); // "30 sec. ago"
 
 alert( formatDate(new Date(new Date - 5 * 60 * 1000)) ); // "5 min. ago"
 
-// yesterday's date like 31.12.16, 20:00
+// yesterday's date like 31.12.16 20:00
 alert( formatDate(new Date(new Date - 86400 * 1000)) );
 ```
diff --git a/1-js/05-data-types/11-date/article.md b/1-js/05-data-types/11-date/article.md
index 6f52a0d7c..6958a3a97 100644
--- a/1-js/05-data-types/11-date/article.md
+++ b/1-js/05-data-types/11-date/article.md
@@ -57,7 +57,7 @@ To create a new `Date` object call `new Date()` with one of the following argume
 `new Date(year, month, date, hours, minutes, seconds, ms)`
 : Create the date with the given components in the local time zone. Only the first two arguments are obligatory.
 
-    - The `year` must have 4 digits: `2013` is okay, `98` is not.
+    - The `year` should have 4 digits. For compatibility, 2 digits are also accepted and considered `19xx`, e.g. `98` is the same as `1998` here, but always using 4 digits is strongly encouraged.
     - The `month` count starts with `0` (Jan), up to `11` (Dec).
     - The `date` parameter is actually the day of month, if absent then `1` is assumed.
     - If `hours/minutes/seconds/ms` is absent, they are assumed to be equal `0`.
@@ -69,7 +69,7 @@ To create a new `Date` object call `new Date()` with one of the following argume
     new Date(2011, 0, 1); // the same, hours etc are 0 by default
     ```
 
-    The minimal precision is 1 ms (1/1000 sec):
+    The maximal precision is 1 ms (1/1000 sec):
 
     ```js run
     let date = new Date(2011, 0, 1, 2, 3, 4, 567);
@@ -124,7 +124,7 @@ Besides the given methods, there are two special ones that do not have a UTC-var
 : Returns the timestamp for the date -- a number of milliseconds passed from the January 1st of 1970 UTC+0.
 
 [getTimezoneOffset()](mdn:js/Date/getTimezoneOffset)
-: Returns the difference between the local time zone and UTC, in minutes:
+: Returns the difference between UTC and the local time zone, in minutes:
 
     ```js run
     // if you are in timezone UTC-1, outputs 60
@@ -348,7 +348,7 @@ let time1 = 0;
 let time2 = 0;
 
 *!*
-// run bench(upperSlice) and bench(upperLoop) each 10 times alternating
+// run bench(diffSubtract) and bench(diffGetTime) each 10 times alternating
 for (let i = 0; i < 10; i++) {
   time1 += bench(diffSubtract);
   time2 += bench(diffGetTime);
@@ -376,7 +376,7 @@ for (let i = 0; i < 10; i++) {
 ```warn header="Be careful doing microbenchmarking"
 Modern JavaScript engines perform many optimizations. They may tweak results of "artificial tests" compared to "normal usage", especially when we benchmark something very small, such as how an operator works, or a built-in function. So if you seriously want to understand performance, then please study how the JavaScript engine works. And then you probably won't need microbenchmarks at all.
 
-The great pack of articles about V8 can be found at <http://mrale.ph>.
+The great pack of articles about V8 can be found at <https://mrale.ph>.
 ```
 
 ## Date.parse from a string
@@ -388,7 +388,7 @@ The string format should be: `YYYY-MM-DDTHH:mm:ss.sssZ`, where:
 - `YYYY-MM-DD` -- is the date: year-month-day.
 - The character `"T"` is used as the delimiter.
 - `HH:mm:ss.sss` -- is the time: hours, minutes, seconds and milliseconds.
-- The optional `'Z'` part denotes the time zone in the format `+-hh:mm`. A single letter `Z` that would mean UTC+0.
+- The optional `'Z'` part denotes the time zone in the format `+-hh:mm`. A single letter `Z` would mean UTC+0.
 
 Shorter variants are also possible, like `YYYY-MM-DD` or `YYYY-MM` or even `YYYY`.
 
@@ -407,7 +407,7 @@ We can instantly create a `new Date` object from the timestamp:
 ```js run
 let date = new Date( Date.parse('2012-01-26T13:51:50.417-07:00') );
 
-alert(date);  
+alert(date);
 ```
 
 ## Summary
@@ -427,7 +427,7 @@ Sometimes we need more precise time measurements. JavaScript itself does not hav
 alert(`Loading started ${performance.now()}ms ago`);
 // Something like: "Loading started 34731.26000000001ms ago"
 // .26 is microseconds (260 microseconds)
-// more than 3 digits after the decimal point are precision errors, but only the first 3 are correct
+// more than 3 digits after the decimal point are precision errors, only the first 3 are correct
 ```
 
 Node.js has `microtime` module and other ways. Technically, almost any device and environment allows to get more precision, it's just not in `Date`.
diff --git a/1-js/05-data-types/12-json/article.md b/1-js/05-data-types/12-json/article.md
index a5f2974af..133ffb353 100644
--- a/1-js/05-data-types/12-json/article.md
+++ b/1-js/05-data-types/12-json/article.md
@@ -27,7 +27,7 @@ Luckily, there's no need to write the code to handle all this. The task has been
 
 ## JSON.stringify
 
-The [JSON](http://en.wikipedia.org/wiki/JSON) (JavaScript Object Notation) is a general format to represent values and objects. It is described as in [RFC 4627](http://tools.ietf.org/html/rfc4627) standard. Initially it was made for JavaScript, but many other languages have libraries to handle it as well.  So it's easy to use JSON for data exchange when the client uses JavaScript and the server is written on Ruby/PHP/Java/Whatever.
+The [JSON](https://en.wikipedia.org/wiki/JSON) (JavaScript Object Notation) is a general format to represent values and objects. It is described as in [RFC 4627](https://tools.ietf.org/html/rfc4627) standard. Initially it was made for JavaScript, but many other languages have libraries to handle it as well.  So it's easy to use JSON for data exchange when the client uses JavaScript and the server is written on Ruby/PHP/Java/Whatever.
 
 JavaScript provides methods:
 
@@ -41,7 +41,7 @@ let student = {
   age: 30,
   isAdmin: false,
   courses: ['html', 'css', 'js'],
-  wife: null
+  spouse: null
 };
 
 *!*
@@ -58,7 +58,7 @@ alert(json);
   "age": 30,
   "isAdmin": false,
   "courses": ["html", "css", "js"],
-  "wife": null
+  "spouse": null
 }
 */
 */!*
@@ -105,7 +105,7 @@ JSON is data-only language-independent specification, so some JavaScript-specifi
 Namely:
 
 - Function properties (methods).
-- Symbolic properties.
+- Symbolic keys and values.
 - Properties that store `undefined`.
 
 ```js run
@@ -276,6 +276,7 @@ name:         John
 name:         Alice
 place:        [object Object]
 number:       23
+occupiedBy: [object Object]
 */
 ```
 
@@ -328,6 +329,8 @@ alert(JSON.stringify(user, null, 2));
 */
 ```
 
+The third argument can also be a string. In this case, the string is used for indentation instead of a number of spaces.
+
 The `space` parameter is used solely for logging and nice-output purposes.
 
 ## Custom "toJSON"
@@ -402,7 +405,7 @@ To decode a JSON-string, we need another method named [JSON.parse](mdn:js/JSON/p
 
 The syntax:
 ```js
-let value = JSON.parse(str, [reviver]);
+let value = JSON.parse(str[, reviver]);
 ```
 
 str
@@ -448,7 +451,7 @@ let json = `{
 
 Besides, JSON does not support comments. Adding a comment to JSON makes it invalid.
 
-There's another format named [JSON5](http://json5.org/), which allows unquoted keys, comments etc. But this is a standalone library, not in the specification of the language.
+There's another format named [JSON5](https://json5.org/), which allows unquoted keys, comments etc. But this is a standalone library, not in the specification of the language.
 
 The regular JSON is that strict not because its developers are lazy, but to allow easy, reliable and very fast implementations of the parsing algorithm.
 
diff --git a/1-js/06-advanced-functions/01-recursion/01-sum-to/solution.md b/1-js/06-advanced-functions/01-recursion/01-sum-to/solution.md
index 3a281ef3f..11667f940 100644
--- a/1-js/06-advanced-functions/01-recursion/01-sum-to/solution.md
+++ b/1-js/06-advanced-functions/01-recursion/01-sum-to/solution.md
@@ -37,4 +37,4 @@ P.S. Naturally, the formula is the fastest solution. It uses only 3 operations f
 
 The loop variant is the second in terms of speed. In both the recursive and the loop variant we sum the same numbers. But the recursion involves nested calls and execution stack management. That also takes resources, so it's slower.
 
-P.P.S. Some engines support the "tail call" optimization: if a recursive call is the very last one in the function (like in `sumTo` above), then the outer function will not need to resume the execution, so the engine doesn't need to remember its execution context. That removes the burden on memory, so counting `sumTo(100000)` becomes possible. But if the JavaScript engine does not support tail call optimization (most of them don't), there will be an error: maximum stack size exceeded, because there's usually a limitation on the total stack size.
+P.P.S. Some engines support the "tail call" optimization: if a recursive call is the very last one in the function, with no other calculations performed, then the outer function will not need to resume the execution, so the engine doesn't need to remember its execution context. That removes the burden on memory. But if the JavaScript engine does not support tail call optimization (most of them don't), there will be an error: maximum stack size exceeded, because there's usually a limitation on the total stack size.
diff --git a/1-js/06-advanced-functions/01-recursion/02-factorial/solution.md b/1-js/06-advanced-functions/01-recursion/02-factorial/solution.md
index 59040a2b7..09e511db5 100644
--- a/1-js/06-advanced-functions/01-recursion/02-factorial/solution.md
+++ b/1-js/06-advanced-functions/01-recursion/02-factorial/solution.md
@@ -1,4 +1,4 @@
-By definition, a factorial is `n!` can be written as `n * (n-1)!`.
+By definition, a factorial `n!` can be written as `n * (n-1)!`.
 
 In other words, the result of `factorial(n)` can be calculated as `n` multiplied by the result of `factorial(n-1)`. And the call for `n-1` can recursively descend lower, and lower, till `1`.
 
diff --git a/1-js/06-advanced-functions/01-recursion/05-output-single-linked-list-reverse/solution.md b/1-js/06-advanced-functions/01-recursion/05-output-single-linked-list-reverse/solution.md
index 4357ff208..0eb76ea1c 100644
--- a/1-js/06-advanced-functions/01-recursion/05-output-single-linked-list-reverse/solution.md
+++ b/1-js/06-advanced-functions/01-recursion/05-output-single-linked-list-reverse/solution.md
@@ -33,7 +33,7 @@ printReverseList(list);
 
 # Using a loop
 
-The loop variant is also a little bit more complicated then the direct output.
+The loop variant is also a little bit more complicated than the direct output.
 
 There is no way to get the last value in our `list`. We also can't "go back".
 
diff --git a/1-js/06-advanced-functions/01-recursion/article.md b/1-js/06-advanced-functions/01-recursion/article.md
index 688badb02..5ae894474 100644
--- a/1-js/06-advanced-functions/01-recursion/article.md
+++ b/1-js/06-advanced-functions/01-recursion/article.md
@@ -61,7 +61,7 @@ When `pow(x, n)` is called, the execution splits into two branches:
               if n==1  = x
              /
 pow(x, n) =
-             \       
+             \
               else     = x * pow(x, n - 1)
 ```
 
@@ -132,7 +132,7 @@ We can sketch it as:
   </li>
 </ul>
 
-That's when the function starts to execute. The condition `n == 1` is false, so the flow continues into the second branch of `if`:
+That's when the function starts to execute. The condition `n == 1` is falsy, so the flow continues into the second branch of `if`:
 
 ```js run
 function pow(x, n) {
@@ -188,7 +188,7 @@ The new current execution context is on top (and bold), and previous remembered
 When we finish the subcall -- it is easy to resume the previous context, because it keeps both variables and the exact place of the code where it stopped.
 
 ```smart
-Here in the picture we use the word "line", as our example there's only one subcall in line, but generally a single line of code may contain multiple subcalls, like `pow(…) + pow(…) + somethingElse(…)`.
+Here in the picture we use the word "line", as in our example there's only one subcall in line, but generally a single line of code may contain multiple subcalls, like `pow(…) + pow(…) + somethingElse(…)`.
 
 So it would be more precise to say that the execution resumes "immediately after the subcall".
 ```
@@ -285,7 +285,7 @@ The iterative `pow` uses a single context changing `i` and `result` in the proce
 
 **Any recursion can be rewritten as a loop. The loop variant usually can be made more effective.**
 
-...But sometimes the rewrite is non-trivial, especially when function uses different recursive subcalls depending on conditions and merges their results or when the branching is more intricate. And the optimization may be unneeded and totally not worth the efforts.
+...But sometimes the rewrite is non-trivial, especially when a function uses different recursive subcalls depending on conditions and merges their results or when the branching is more intricate. And the optimization may be unneeded and totally not worth the efforts.
 
 Recursion can give a shorter code, easier to understand and support. Optimizations are not required in every place, mostly we need a good code, that's why it's used.
 
@@ -302,7 +302,7 @@ let company = {
     salary: 1000
   }, {
     name: 'Alice',
-    salary: 600
+    salary: 1600
   }],
 
   development: {
@@ -350,7 +350,7 @@ The algorithm is probably even easier to read from the code:
 
 ```js run
 let company = { // the same object, compressed for brevity
-  sales: [{name: 'John', salary: 1000}, {name: 'Alice', salary: 600 }],
+  sales: [{name: 'John', salary: 1000}, {name: 'Alice', salary: 1600 }],
   development: {
     sites: [{name: 'Peter', salary: 2000}, {name: 'Alex', salary: 1800 }],
     internals: [{name: 'Jack', salary: 1300}]
@@ -372,7 +372,7 @@ function sumSalaries(department) {
 }
 */!*
 
-alert(sumSalaries(company)); // 6700
+alert(sumSalaries(company)); // 7700
 ```
 
 The code is short and easy to understand (hopefully?). That's the power of recursion. It also works for any level of subdepartment nesting.
@@ -462,7 +462,7 @@ list.next.next.next = { value: 4 };
 list.next.next.next.next = null;
 ```
 
-Here we can even more clearer see that there are multiple objects, each one has the `value` and `next` pointing to the neighbour. The `list` variable is the first object in the chain, so following `next` pointers from it we can reach any element.
+Here we can even more clearly see that there are multiple objects, each one has the `value` and `next` pointing to the neighbour. The `list` variable is the first object in the chain, so following `next` pointers from it we can reach any element.
 
 The list can be easily split into multiple parts and later joined back:
 
@@ -535,7 +535,7 @@ Terms:
     list = { value, next -> list }
     ```
 
-    Trees like HTML elements tree or the department tree from this chapter are also naturally recursive: they branch and every branch can have other branches.
+    Trees like HTML elements tree or the department tree from this chapter are also naturally recursive: they have branches and every branch can have other branches.
 
     Recursive functions can be used to walk them as we've seen in the `sumSalary` example.
 
diff --git a/1-js/06-advanced-functions/02-rest-parameters-spread/article.md b/1-js/06-advanced-functions/02-rest-parameters-spread/article.md
index 74c85d4f4..dbdfbd6c0 100644
--- a/1-js/06-advanced-functions/02-rest-parameters-spread/article.md
+++ b/1-js/06-advanced-functions/02-rest-parameters-spread/article.md
@@ -23,7 +23,7 @@ function sum(a, b) {
 alert( sum(1, 2, 3, 4, 5) );
 ```
 
-There will be no error because of "excessive" arguments. But of course in the result only the first two will be counted.
+There will be no error because of "excessive" arguments. But of course in the result only the first two will be counted, so the result in the code above is `3`.
 
 The rest of the parameters can be included in the function definition by using three dots `...` followed by the name of the array that will contain them. The dots literally mean "gather the remaining parameters into an array".
 
@@ -225,6 +225,57 @@ But there's a subtle difference between `Array.from(obj)` and `[...obj]`:
 So, for the task of turning something into an array, `Array.from` tends to be more universal.
 
 
+## Copy an array/object
+
+Remember when we talked about `Object.assign()` [in the past](info:object-copy#cloning-and-merging-object-assign)?
+
+It is possible to do the same thing with the spread syntax.
+
+```js run
+let arr = [1, 2, 3];
+
+*!*
+let arrCopy = [...arr]; // spread the array into a list of parameters
+                        // then put the result into a new array
+*/!*
+
+// do the arrays have the same contents?
+alert(JSON.stringify(arr) === JSON.stringify(arrCopy)); // true
+
+// are the arrays equal?
+alert(arr === arrCopy); // false (not same reference)
+
+// modifying our initial array does not modify the copy:
+arr.push(4);
+alert(arr); // 1, 2, 3, 4
+alert(arrCopy); // 1, 2, 3
+```
+
+Note that it is possible to do the same thing to make a copy of an object:
+
+```js run
+let obj = { a: 1, b: 2, c: 3 };
+
+*!*
+let objCopy = { ...obj }; // spread the object into a list of parameters
+                          // then return the result in a new object
+*/!*
+
+// do the objects have the same contents?
+alert(JSON.stringify(obj) === JSON.stringify(objCopy)); // true
+
+// are the objects equal?
+alert(obj === objCopy); // false (not same reference)
+
+// modifying our initial object does not modify the copy:
+obj.d = 4;
+alert(JSON.stringify(obj)); // {"a":1,"b":2,"c":3,"d":4}
+alert(JSON.stringify(objCopy)); // {"a":1,"b":2,"c":3}
+```
+
+This way of copying an object is much shorter than `let objCopy = Object.assign({}, obj)` or for an array `let arrCopy = Object.assign([], arr)` so we prefer to use it whenever we can.
+
+
 ## Summary
 
 When we see `"..."` in the code, it is either rest parameters or the spread syntax.
diff --git a/1-js/06-advanced-functions/03-closure/10-make-army/lexenv-makearmy-empty.svg b/1-js/06-advanced-functions/03-closure/10-make-army/lexenv-makearmy-empty.svg
new file mode 100644
index 000000000..f8c7bd6ac
--- /dev/null
+++ b/1-js/06-advanced-functions/03-closure/10-make-army/lexenv-makearmy-empty.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="566" height="183" viewBox="0 0 566 183"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:&apos;PT Mono&apos;;font-weight:700;font-style:normal;src:local(&apos;PT MonoBold&apos;),url(/font/PTMonoBold.woff2) format(&apos;woff2&apos;),url(/font/PTMonoBold.woff) format(&apos;woff&apos;),url(/font/PTMonoBold.ttf) format(&apos;truetype&apos;)}</style></defs><g id="closure" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="lexenv-makearmy-empty.svg"><g id="shooters-=-[" fill-rule="nonzero" transform="translate(6.176 15.2)"><path id="shooters" fill="#181717" d="M4.956 7.91a.796.796 0 00-.35-.693 2.872 2.872 0 00-.868-.392 16.056 16.056 0 00-1.127-.273 6.502 6.502 0 01-1.127-.336 2.525 2.525 0 01-.868-.567c-.233-.238-.35-.572-.35-1.001 0-.355.077-.658.231-.91a1.94 1.94 0 01.609-.623c.252-.163.546-.285.882-.364.336-.08.686-.119 1.05-.119.653 0 1.216.082 1.687.245.471.163.847.334 1.127.511l-.448.882a11.79 11.79 0 00-1.001-.483c-.36-.154-.81-.231-1.351-.231-.205 0-.408.021-.609.063-.2.042-.383.105-.546.189a1.088 1.088 0 00-.392.329.825.825 0 00-.147.497c0 .243.117.43.35.56.233.13.523.24.868.329.345.089.721.173 1.127.252.406.08.782.194 1.127.343.345.15.635.35.868.602.233.252.35.593.35 1.022 0 .644-.254 1.176-.763 1.596-.509.42-1.272.63-2.289.63-.308 0-.611-.028-.91-.084a5.52 5.52 0 01-.84-.224 5.054 5.054 0 01-.714-.315A3.002 3.002 0 010 8.988l.56-.91c.112.112.261.226.448.343a4.229 4.229 0 001.337.539 3.76 3.76 0 001.484.021c.22-.042.413-.107.581-.196a1.08 1.08 0 00.399-.35.914.914 0 00.147-.525zM7.28 0h2.184v3.668h.07c.29-.327.625-.581 1.008-.763.383-.182.859-.273 1.428-.273.448 0 .838.047 1.169.14.331.093.602.257.812.49.21.233.366.553.469.959.103.406.154.922.154 1.547V9.8h-1.092V5.978c0-.401-.023-.751-.07-1.05a1.829 1.829 0 00-.273-.749c-.135-.2-.32-.352-.553-.455-.233-.103-.532-.154-.896-.154-.252 0-.5.044-.742.133-.243.089-.464.21-.665.364-.2.154-.373.34-.518.56-.145.22-.245.46-.301.721V9.8H8.386V.938H7.28V0zm9.142 6.3c0-1.13.294-2.023.882-2.681.588-.658 1.428-.987 2.52-.987.588 0 1.094.096 1.519.287.425.191.777.45 1.057.777.28.327.488.714.623 1.162.135.448.203.929.203 1.442 0 .56-.075 1.066-.224 1.519-.15.453-.369.838-.658 1.155-.29.317-.646.562-1.071.735a3.82 3.82 0 01-1.449.259c-.579 0-1.083-.096-1.512-.287a2.967 2.967 0 01-1.064-.777 3.168 3.168 0 01-.623-1.162 4.963 4.963 0 01-.203-1.442zm1.162 0c0 .327.04.653.119.98.08.327.208.62.385.882.177.261.408.471.693.63.285.159.632.238 1.043.238.747 0 1.309-.231 1.687-.693.378-.462.567-1.141.567-2.037 0-.336-.04-.665-.119-.987a2.608 2.608 0 00-.392-.875 2.066 2.066 0 00-.7-.63c-.285-.159-.632-.238-1.043-.238-.747 0-1.307.229-1.68.686-.373.457-.56 1.139-.56 2.044zm7.238 0c0-1.13.294-2.023.882-2.681.588-.658 1.428-.987 2.52-.987.588 0 1.094.096 1.519.287.425.191.777.45 1.057.777.28.327.488.714.623 1.162.135.448.203.929.203 1.442 0 .56-.075 1.066-.224 1.519-.15.453-.369.838-.658 1.155-.29.317-.646.562-1.071.735a3.82 3.82 0 01-1.449.259c-.579 0-1.083-.096-1.512-.287a2.967 2.967 0 01-1.064-.777 3.168 3.168 0 01-.623-1.162 4.963 4.963 0 01-.203-1.442zm1.162 0c0 .327.04.653.119.98.08.327.208.62.385.882.177.261.408.471.693.63.285.159.632.238 1.043.238.747 0 1.309-.231 1.687-.693.378-.462.567-1.141.567-2.037 0-.336-.04-.665-.119-.987a2.608 2.608 0 00-.392-.875 2.066 2.066 0 00-.7-.63c-.285-.159-.632-.238-1.043-.238-.747 0-1.307.229-1.68.686-.373.457-.56 1.139-.56 2.044zm6.874-3.5h1.666V1.414l1.092-.308V2.8h3.738v.938h-3.738v3.304c0 .681.166 1.185.497 1.512.331.327.805.49 1.421.49.42 0 .786-.08 1.099-.238.313-.159.595-.331.847-.518l.364.826a3.938 3.938 0 01-1.169.63 4.182 4.182 0 01-1.393.238 3.41 3.41 0 01-1.057-.161 2.426 2.426 0 01-.875-.497 2.38 2.38 0 01-.602-.861c-.15-.35-.224-.768-.224-1.253V3.738h-1.666V2.8zM48.23 8.918c-.168.15-.366.29-.595.42a4.39 4.39 0 01-.749.336c-.27.093-.553.166-.847.217-.294.051-.59.077-.889.077-.56 0-1.055-.086-1.484-.259a2.858 2.858 0 01-1.078-.742 3.234 3.234 0 01-.658-1.155 4.767 4.767 0 01-.224-1.512c0-.588.082-1.11.245-1.568.163-.457.399-.84.707-1.148a3.08 3.08 0 011.12-.707 4.187 4.187 0 011.47-.245c.392 0 .78.051 1.162.154.383.103.721.296 1.015.581.294.285.52.677.679 1.176.159.5.215 1.146.168 1.939h-5.418c0 .84.226 1.468.679 1.883.453.415 1.057.623 1.813.623.252 0 .502-.03.749-.091.247-.06.483-.133.707-.217a3.72 3.72 0 00.595-.28c.173-.103.306-.196.399-.28l.434.798zm-2.954-5.362c-.308 0-.6.033-.875.098a1.995 1.995 0 00-.728.329c-.21.154-.383.355-.518.602s-.222.553-.259.917h4.354c-.047-.616-.245-1.094-.595-1.435-.35-.34-.81-.511-1.379-.511zM50.148 9.8v-.938h1.89V3.738h-1.89V2.8h2.618l.224.91h.07c.317-.29.672-.537 1.064-.742.392-.205.859-.308 1.4-.308.317 0 .572.06.763.182.191.121.34.299.448.532.107.233.18.516.217.847.037.331.056.707.056 1.127l-.98.014c0-.597-.058-1.036-.175-1.316-.117-.28-.329-.42-.637-.42-.29 0-.55.042-.784.126a2.565 2.565 0 00-.609.308c-.173.121-.32.243-.441.364s-.21.224-.266.308v4.13h2.688V9.8h-5.656zm13.608-1.89a.796.796 0 00-.35-.693 2.872 2.872 0 00-.868-.392 16.056 16.056 0 00-1.127-.273 6.502 6.502 0 01-1.127-.336 2.525 2.525 0 01-.868-.567c-.233-.238-.35-.572-.35-1.001 0-.355.077-.658.231-.91a1.94 1.94 0 01.609-.623c.252-.163.546-.285.882-.364.336-.08.686-.119 1.05-.119.653 0 1.216.082 1.687.245.471.163.847.334 1.127.511l-.448.882a11.79 11.79 0 00-1.001-.483c-.36-.154-.81-.231-1.351-.231-.205 0-.408.021-.609.063-.2.042-.383.105-.546.189a1.088 1.088 0 00-.392.329.825.825 0 00-.147.497c0 .243.117.43.35.56.233.13.523.24.868.329.345.089.721.173 1.127.252.406.08.782.194 1.127.343.345.15.635.35.868.602.233.252.35.593.35 1.022 0 .644-.254 1.176-.763 1.596-.509.42-1.272.63-2.289.63-.308 0-.611-.028-.91-.084a5.52 5.52 0 01-.84-.224 5.054 5.054 0 01-.714-.315 3.002 3.002 0 01-.532-.357l.56-.91c.112.112.261.226.448.343a4.229 4.229 0 001.337.539 3.76 3.76 0 001.484.021c.22-.042.413-.107.581-.196a1.08 1.08 0 00.399-.35.914.914 0 00.147-.525z"/><path id="=" fill="#DBAF88" d="M75.376 3.402h6.496V4.41h-6.496V3.402zm0 2.296h6.496v1.008h-6.496V5.698z"/><path id="[" fill="#7E7C7B" d="M93.31 0h4.774v.98h-3.682v11.06h3.682v.98H93.31z"/><path id="function" fill="#1C85B5" d="M16.856 33.8v-.938h1.666v-5.124h-1.666V26.8h1.666v-.392c0-.877.229-1.512.686-1.904.457-.392 1.11-.588 1.96-.588.308 0 .583.019.826.056.243.037.504.112.784.224l-.252.91a2.862 2.862 0 00-.7-.203 4.295 4.295 0 00-.616-.049c-.616 0-1.036.152-1.26.455-.224.303-.336.8-.336 1.491h2.898v.938h-2.898v5.124h2.898v.938h-5.656zm12.25-7h1.988v4.774c0 .457.028.896.084 1.316h.938v.91h-1.862l-.042-1.19h-.056a2.938 2.938 0 01-.966.98c-.401.252-.887.378-1.456.378-.43 0-.796-.049-1.099-.147a1.556 1.556 0 01-.749-.511c-.196-.243-.34-.567-.434-.973-.093-.406-.14-.912-.14-1.519v-3.08h-.938V26.8h2.03v3.794c0 .383.016.726.049 1.029.033.303.1.56.203.77.103.21.254.369.455.476.2.107.469.161.805.161.485 0 .908-.159 1.267-.476.36-.317.632-.714.819-1.19v-3.626h-.896V26.8zm4.62 2.45a14.05 14.05 0 00-.063-1.176 4.657 4.657 0 00-.049-.364h-.938v-.91h1.876l.126 1.134h.07c.093-.159.217-.315.371-.469a2.91 2.91 0 011.225-.721c.252-.075.518-.112.798-.112.43 0 .81.047 1.141.14.331.093.607.259.826.497.22.238.385.56.497.966.112.406.168.922.168 1.547V33.8h-1.092v-3.808c0-.775-.126-1.358-.378-1.75-.252-.392-.71-.588-1.372-.588-.243 0-.478.049-.707.147a2.44 2.44 0 00-.623.385c-.187.159-.35.343-.49.553-.14.21-.243.432-.308.665V33.8h-1.078v-4.55zm13.244-1.372a5.531 5.531 0 00-.693-.189 3.61 3.61 0 00-.735-.077c-.915 0-1.596.215-2.044.644-.448.43-.672 1.11-.672 2.044 0 .41.065.777.196 1.099.13.322.317.595.56.819.243.224.534.397.875.518.34.121.716.182 1.127.182.439 0 .866-.075 1.281-.224.415-.15.763-.345 1.043-.588l.49.812c-.13.112-.294.229-.49.35a4.837 4.837 0 01-1.533.602 4.962 4.962 0 01-1.015.098c-.607 0-1.141-.086-1.603-.259a3.045 3.045 0 01-1.155-.742 3.176 3.176 0 01-.7-1.162 4.525 4.525 0 01-.238-1.505c0-.588.082-1.11.245-1.568.163-.457.399-.84.707-1.148a3.08 3.08 0 011.12-.707 4.187 4.187 0 011.47-.245c.69 0 1.253.06 1.687.182.434.121.8.257 1.099.406l-.014.042v1.946H46.97v-1.33zm2.688-1.078h1.666v-1.386l1.092-.308V26.8h3.738v.938h-3.738v3.304c0 .681.166 1.185.497 1.512.331.327.805.49 1.421.49.42 0 .786-.08 1.099-.238.313-.159.595-.331.847-.518l.364.826a3.938 3.938 0 01-1.169.63 4.182 4.182 0 01-1.393.238 3.41 3.41 0 01-1.057-.161 2.426 2.426 0 01-.875-.497 2.38 2.38 0 01-.602-.861c-.15-.35-.224-.768-.224-1.253v-3.472h-1.666V26.8zm9.436 7v-.938h2.436v-5.124h-2.436V26.8h3.556v6.062h2.38v.938h-5.936zm2.058-8.988c0-.252.084-.469.252-.651a.838.838 0 01.644-.273c.27 0 .497.091.679.273a.889.889 0 01.273.651.806.806 0 01-.273.616.963.963 0 01-.679.252.872.872 0 01-.644-.252.838.838 0 01-.252-.616zm5.67 5.488c0-1.13.294-2.023.882-2.681.588-.658 1.428-.987 2.52-.987.588 0 1.094.096 1.519.287.425.191.777.45 1.057.777.28.327.488.714.623 1.162.135.448.203.929.203 1.442 0 .56-.075 1.066-.224 1.519-.15.453-.369.838-.658 1.155-.29.317-.646.562-1.071.735a3.82 3.82 0 01-1.449.259c-.579 0-1.083-.096-1.512-.287a2.967 2.967 0 01-1.064-.777 3.168 3.168 0 01-.623-1.162 4.963 4.963 0 01-.203-1.442zm1.162 0c0 .327.04.653.119.98.08.327.208.62.385.882.177.261.408.471.693.63.285.159.632.238 1.043.238.747 0 1.309-.231 1.687-.693.378-.462.567-1.141.567-2.037 0-.336-.04-.665-.119-.987a2.608 2.608 0 00-.392-.875 2.066 2.066 0 00-.7-.63c-.285-.159-.632-.238-1.043-.238-.747 0-1.307.229-1.68.686-.373.457-.56 1.139-.56 2.044zm7.742-1.05a14.05 14.05 0 00-.063-1.176 4.657 4.657 0 00-.049-.364h-.938v-.91h1.876l.126 1.134h.07c.093-.159.217-.315.371-.469a2.91 2.91 0 011.225-.721c.252-.075.518-.112.798-.112.43 0 .81.047 1.141.14.331.093.607.259.826.497.22.238.385.56.497.966.112.406.168.922.168 1.547V33.8h-1.092v-3.808c0-.775-.126-1.358-.378-1.75-.252-.392-.71-.588-1.372-.588-.243 0-.478.049-.707.147a2.44 2.44 0 00-.623.385c-.187.159-.35.343-.49.553-.14.21-.243.432-.308.665V33.8h-1.078v-4.55z"/><path id="(){" fill="#7E7C7B" d="M97.272 36.768a6.964 6.964 0 01-1.757-.707 5.036 5.036 0 01-1.428-1.225c-.406-.504-.728-1.12-.966-1.848s-.357-1.591-.357-2.59c0-.99.121-1.855.364-2.597s.57-1.372.98-1.89c.41-.518.889-.933 1.435-1.246A6.005 6.005 0 0197.272 24l.35.882a7.086 7.086 0 00-1.512.623 3.928 3.928 0 00-1.183 1.022c-.331.425-.588.952-.77 1.582-.182.63-.273 1.393-.273 2.289 0 .905.11 1.678.329 2.317.22.64.509 1.171.868 1.596.36.425.76.756 1.204.994.443.238.889.404 1.337.497l-.35.966zm4.354-.966a4.965 4.965 0 001.337-.497 4.15 4.15 0 001.204-.994c.36-.425.649-.957.868-1.596.22-.64.329-1.412.329-2.317 0-.896-.091-1.659-.273-2.289-.182-.63-.439-1.157-.77-1.582a3.928 3.928 0 00-1.183-1.022 7.086 7.086 0 00-1.512-.623l.35-.882c.607.13 1.183.352 1.729.665a4.984 4.984 0 011.435 1.246c.41.518.737 1.148.98 1.89s.364 1.608.364 2.597c0 .999-.119 1.862-.357 2.59-.238.728-.56 1.344-.966 1.848a5.036 5.036 0 01-1.428 1.225 6.964 6.964 0 01-1.757.707l-.35-.966zm17.878-2.45c0-.401-.068-.749-.203-1.043a2.44 2.44 0 00-.504-.735c-.2-.196-.415-.34-.644-.434a1.641 1.641 0 00-.609-.14v-.98c.177 0 .38-.04.609-.119.229-.08.443-.21.644-.392.2-.182.369-.418.504-.707.135-.29.203-.649.203-1.078v-1.428c0-.336.054-.644.161-.924a2.22 2.22 0 01.448-.728c.191-.205.42-.366.686-.483.266-.117.558-.175.875-.175h2.03v.98h-1.54c-.588 0-.996.14-1.225.42-.229.28-.343.695-.343 1.246v1.358c0 .383-.07.723-.21 1.022a2.7 2.7 0 01-1.106 1.225c-.205.117-.373.184-.504.203v.084c.121.019.285.091.49.217.205.126.406.299.602.518.196.22.366.478.511.777.145.299.217.63.217.994v1.344c0 .57.121.99.364 1.26s.649.406 1.218.406h1.526v.98h-2.03c-.653 0-1.178-.194-1.575-.581-.397-.387-.595-.959-.595-1.715v-1.372z"/><path id="alert" fill="#181717" d="M134.736 27.346a4.447 4.447 0 011.358-.504 7.423 7.423 0 011.484-.154c.476 0 .866.075 1.169.224.303.15.541.343.714.581.173.238.29.509.35.812.06.303.091.609.091.917 0 .355-.01.733-.028 1.134-.019.401-.033.803-.042 1.204 0 .467.028.91.084 1.33h.938v.91h-1.862l-.126-1.05h-.07c-.056.084-.14.191-.252.322-.112.13-.259.259-.441.385a2.749 2.749 0 01-1.589.469c-.69 0-1.237-.177-1.638-.532-.401-.355-.602-.84-.602-1.456 0-.476.105-.873.315-1.19.21-.317.511-.56.903-.728.392-.168.866-.266 1.421-.294a9.544 9.544 0 011.869.112c.047-.43.054-.786.021-1.071-.033-.285-.107-.511-.224-.679a.938.938 0 00-.49-.357 2.482 2.482 0 00-.777-.105c-.42 0-.821.058-1.204.175-.383.117-.723.236-1.022.357l-.35-.812zm2.058 5.642c.261 0 .504-.042.728-.126a2.22 2.22 0 00.588-.322 2.133 2.133 0 00.672-.868v-.98a7.92 7.92 0 00-1.344-.126c-.41 0-.765.044-1.064.133-.299.089-.532.226-.7.413-.168.187-.252.43-.252.728 0 .308.105.576.315.805.21.229.562.343 1.057.343zM143.29 24h2.324v7.448c0 .57.096.97.287 1.204.191.233.474.35.847.35.261 0 .511-.047.749-.14.238-.093.502-.252.791-.476l.504.77c-.15.13-.313.247-.49.35a3.638 3.638 0 01-1.106.42 2.963 2.963 0 01-1.442-.077 1.579 1.579 0 01-.679-.427 1.897 1.897 0 01-.413-.777c-.093-.322-.14-.721-.14-1.197v-6.51h-1.232V24zm14.14 8.918c-.168.15-.366.29-.595.42a4.39 4.39 0 01-.749.336c-.27.093-.553.166-.847.217-.294.051-.59.077-.889.077-.56 0-1.055-.086-1.484-.259a2.858 2.858 0 01-1.078-.742 3.234 3.234 0 01-.658-1.155 4.767 4.767 0 01-.224-1.512c0-.588.082-1.11.245-1.568.163-.457.399-.84.707-1.148a3.08 3.08 0 011.12-.707 4.187 4.187 0 011.47-.245c.392 0 .78.051 1.162.154.383.103.721.296 1.015.581.294.285.52.677.679 1.176.159.5.215 1.146.168 1.939h-5.418c0 .84.226 1.468.679 1.883.453.415 1.057.623 1.813.623.252 0 .502-.03.749-.091.247-.06.483-.133.707-.217a3.72 3.72 0 00.595-.28c.173-.103.306-.196.399-.28l.434.798zm-2.954-5.362c-.308 0-.6.033-.875.098a1.995 1.995 0 00-.728.329c-.21.154-.383.355-.518.602s-.222.553-.259.917h4.354c-.047-.616-.245-1.094-.595-1.435-.35-.34-.81-.511-1.379-.511zm4.872 6.244v-.938h1.89v-5.124h-1.89V26.8h2.618l.224.91h.07c.317-.29.672-.537 1.064-.742.392-.205.859-.308 1.4-.308.317 0 .572.06.763.182.191.121.34.299.448.532.107.233.18.516.217.847.037.331.056.707.056 1.127l-.98.014c0-.597-.058-1.036-.175-1.316-.117-.28-.329-.42-.637-.42-.29 0-.55.042-.784.126a2.565 2.565 0 00-.609.308c-.173.121-.32.243-.441.364s-.21.224-.266.308v4.13h2.688v.938h-5.656zm7.91-7h1.666v-1.386l1.092-.308V26.8h3.738v.938h-3.738v3.304c0 .681.166 1.185.497 1.512.331.327.805.49 1.421.49.42 0 .786-.08 1.099-.238.313-.159.595-.331.847-.518l.364.826a3.938 3.938 0 01-1.169.63 4.182 4.182 0 01-1.393.238 3.41 3.41 0 01-1.057-.161 2.426 2.426 0 01-.875-.497 2.38 2.38 0 01-.602-.861c-.15-.35-.224-.768-.224-1.253v-3.472h-1.666V26.8z"/><path id="(" fill="#7E7C7B" d="M181.272 36.768a6.964 6.964 0 01-1.757-.707 5.036 5.036 0 01-1.428-1.225c-.406-.504-.728-1.12-.966-1.848s-.357-1.591-.357-2.59c0-.99.121-1.855.364-2.597s.57-1.372.98-1.89c.41-.518.889-.933 1.435-1.246a6.005 6.005 0 011.729-.665l.35.882a7.086 7.086 0 00-1.512.623 3.928 3.928 0 00-1.183 1.022c-.331.425-.588.952-.77 1.582-.182.63-.273 1.393-.273 2.289 0 .905.11 1.678.329 2.317.22.64.509 1.171.868 1.596.36.425.76.756 1.204.994.443.238.889.404 1.337.497l-.35.966z"/><path id="i" fill="#181717" d="M185.094 33.8v-.938h2.436v-5.124h-2.436V26.8h3.556v6.062h2.38v.938h-5.936zm2.058-8.988c0-.252.084-.469.252-.651a.838.838 0 01.644-.273c.27 0 .497.091.679.273a.889.889 0 01.273.651.806.806 0 01-.273.616.963.963 0 01-.679.252.872.872 0 01-.644-.252.838.838 0 01-.252-.616z"/><path id=");}," fill="#7E7C7B" d="M194.026 35.802a4.965 4.965 0 001.337-.497 4.15 4.15 0 001.204-.994c.36-.425.649-.957.868-1.596.22-.64.329-1.412.329-2.317 0-.896-.091-1.659-.273-2.289-.182-.63-.439-1.157-.77-1.582a3.928 3.928 0 00-1.183-1.022 7.086 7.086 0 00-1.512-.623l.35-.882c.607.13 1.183.352 1.729.665a4.984 4.984 0 011.435 1.246c.41.518.737 1.148.98 1.89s.364 1.608.364 2.597c0 .999-.119 1.862-.357 2.59-.238.728-.56 1.344-.966 1.848a5.036 5.036 0 01-1.428 1.225 6.964 6.964 0 01-1.757.707l-.35-.966zm9.604-2.772c0-.28.091-.506.273-.679.182-.173.418-.259.707-.259.355 0 .63.124.826.371.196.247.294.595.294 1.043a2.36 2.36 0 01-.637 1.659 2.465 2.465 0 01-.588.462c-.21.117-.404.203-.581.259l-.35-.546c.336-.13.625-.317.868-.56.243-.243.364-.537.364-.882-.13.028-.233.042-.308.042-.27 0-.483-.077-.637-.231-.154-.154-.231-.38-.231-.679zm.126-5.502c0-.299.084-.53.252-.693.168-.163.392-.245.672-.245.299 0 .532.082.7.245.168.163.252.394.252.693 0 .27-.084.495-.252.672-.168.177-.401.266-.7.266-.28 0-.504-.089-.672-.266a.938.938 0 01-.252-.672zm18.788 7.196c0 .756-.198 1.328-.595 1.715-.397.387-.922.581-1.575.581h-2.03v-.98h1.526c.57 0 .975-.135 1.218-.406.243-.27.364-.69.364-1.26V33.03c0-.364.07-.695.21-.994.14-.299.308-.558.504-.777.196-.22.397-.392.602-.518.205-.126.373-.198.504-.217v-.084c-.13-.019-.299-.086-.504-.203a2.7 2.7 0 01-1.106-1.225c-.14-.299-.21-.64-.21-1.022v-1.358c0-.55-.114-.966-.343-1.246-.229-.28-.637-.42-1.225-.42h-1.54v-.98h2.03c.317 0 .609.058.875.175.266.117.495.278.686.483.191.205.34.448.448.728.107.28.161.588.161.924v1.428c0 .43.068.789.203 1.078.135.29.303.525.504.707.2.182.415.313.644.392.229.08.432.119.609.119V31c-.177 0-.38.047-.609.14a2.011 2.011 0 00-.644.434 2.44 2.44 0 00-.504.735c-.135.294-.203.642-.203 1.043v1.372zm6.286-1.694c0-.28.091-.506.273-.679.182-.173.418-.259.707-.259.355 0 .63.124.826.371.196.247.294.595.294 1.043a2.36 2.36 0 01-.637 1.659 2.465 2.465 0 01-.588.462c-.21.117-.404.203-.581.259l-.35-.546c.336-.13.625-.317.868-.56.243-.243.364-.537.364-.882-.13.028-.233.042-.308.042-.27 0-.483-.077-.637-.231-.154-.154-.231-.38-.231-.679z"/><path id="function" fill="#1C85B5" d="M16.856 57.8v-.938h1.666v-5.124h-1.666V50.8h1.666v-.392c0-.877.229-1.512.686-1.904.457-.392 1.11-.588 1.96-.588.308 0 .583.019.826.056.243.037.504.112.784.224l-.252.91a2.862 2.862 0 00-.7-.203 4.295 4.295 0 00-.616-.049c-.616 0-1.036.152-1.26.455-.224.303-.336.8-.336 1.491h2.898v.938h-2.898v5.124h2.898v.938h-5.656zm12.25-7h1.988v4.774c0 .457.028.896.084 1.316h.938v.91h-1.862l-.042-1.19h-.056a2.938 2.938 0 01-.966.98c-.401.252-.887.378-1.456.378-.43 0-.796-.049-1.099-.147a1.556 1.556 0 01-.749-.511c-.196-.243-.34-.567-.434-.973-.093-.406-.14-.912-.14-1.519v-3.08h-.938V50.8h2.03v3.794c0 .383.016.726.049 1.029.033.303.1.56.203.77.103.21.254.369.455.476.2.107.469.161.805.161.485 0 .908-.159 1.267-.476.36-.317.632-.714.819-1.19v-3.626h-.896V50.8zm4.62 2.45a14.05 14.05 0 00-.063-1.176 4.657 4.657 0 00-.049-.364h-.938v-.91h1.876l.126 1.134h.07c.093-.159.217-.315.371-.469a2.91 2.91 0 011.225-.721c.252-.075.518-.112.798-.112.43 0 .81.047 1.141.14.331.093.607.259.826.497.22.238.385.56.497.966.112.406.168.922.168 1.547V57.8h-1.092v-3.808c0-.775-.126-1.358-.378-1.75-.252-.392-.71-.588-1.372-.588-.243 0-.478.049-.707.147a2.44 2.44 0 00-.623.385c-.187.159-.35.343-.49.553-.14.21-.243.432-.308.665V57.8h-1.078v-4.55zm13.244-1.372a5.531 5.531 0 00-.693-.189 3.61 3.61 0 00-.735-.077c-.915 0-1.596.215-2.044.644-.448.43-.672 1.11-.672 2.044 0 .41.065.777.196 1.099.13.322.317.595.56.819.243.224.534.397.875.518.34.121.716.182 1.127.182.439 0 .866-.075 1.281-.224.415-.15.763-.345 1.043-.588l.49.812c-.13.112-.294.229-.49.35a4.837 4.837 0 01-1.533.602 4.962 4.962 0 01-1.015.098c-.607 0-1.141-.086-1.603-.259a3.045 3.045 0 01-1.155-.742 3.176 3.176 0 01-.7-1.162 4.525 4.525 0 01-.238-1.505c0-.588.082-1.11.245-1.568.163-.457.399-.84.707-1.148a3.08 3.08 0 011.12-.707 4.187 4.187 0 011.47-.245c.69 0 1.253.06 1.687.182.434.121.8.257 1.099.406l-.014.042v1.946H46.97v-1.33zm2.688-1.078h1.666v-1.386l1.092-.308V50.8h3.738v.938h-3.738v3.304c0 .681.166 1.185.497 1.512.331.327.805.49 1.421.49.42 0 .786-.08 1.099-.238.313-.159.595-.331.847-.518l.364.826a3.938 3.938 0 01-1.169.63 4.182 4.182 0 01-1.393.238 3.41 3.41 0 01-1.057-.161 2.426 2.426 0 01-.875-.497 2.38 2.38 0 01-.602-.861c-.15-.35-.224-.768-.224-1.253v-3.472h-1.666V50.8zm9.436 7v-.938h2.436v-5.124h-2.436V50.8h3.556v6.062h2.38v.938h-5.936zm2.058-8.988c0-.252.084-.469.252-.651a.838.838 0 01.644-.273c.27 0 .497.091.679.273a.889.889 0 01.273.651.806.806 0 01-.273.616.963.963 0 01-.679.252.872.872 0 01-.644-.252.838.838 0 01-.252-.616zm5.67 5.488c0-1.13.294-2.023.882-2.681.588-.658 1.428-.987 2.52-.987.588 0 1.094.096 1.519.287.425.191.777.45 1.057.777.28.327.488.714.623 1.162.135.448.203.929.203 1.442 0 .56-.075 1.066-.224 1.519-.15.453-.369.838-.658 1.155-.29.317-.646.562-1.071.735a3.82 3.82 0 01-1.449.259c-.579 0-1.083-.096-1.512-.287a2.967 2.967 0 01-1.064-.777 3.168 3.168 0 01-.623-1.162 4.963 4.963 0 01-.203-1.442zm1.162 0c0 .327.04.653.119.98.08.327.208.62.385.882.177.261.408.471.693.63.285.159.632.238 1.043.238.747 0 1.309-.231 1.687-.693.378-.462.567-1.141.567-2.037 0-.336-.04-.665-.119-.987a2.608 2.608 0 00-.392-.875 2.066 2.066 0 00-.7-.63c-.285-.159-.632-.238-1.043-.238-.747 0-1.307.229-1.68.686-.373.457-.56 1.139-.56 2.044zm7.742-1.05a14.05 14.05 0 00-.063-1.176 4.657 4.657 0 00-.049-.364h-.938v-.91h1.876l.126 1.134h.07c.093-.159.217-.315.371-.469a2.91 2.91 0 011.225-.721c.252-.075.518-.112.798-.112.43 0 .81.047 1.141.14.331.093.607.259.826.497.22.238.385.56.497.966.112.406.168.922.168 1.547V57.8h-1.092v-3.808c0-.775-.126-1.358-.378-1.75-.252-.392-.71-.588-1.372-.588-.243 0-.478.049-.707.147a2.44 2.44 0 00-.623.385c-.187.159-.35.343-.49.553-.14.21-.243.432-.308.665V57.8h-1.078v-4.55z"/><path id="(){" fill="#7E7C7B" d="M97.272 60.768a6.964 6.964 0 01-1.757-.707 5.036 5.036 0 01-1.428-1.225c-.406-.504-.728-1.12-.966-1.848s-.357-1.591-.357-2.59c0-.99.121-1.855.364-2.597s.57-1.372.98-1.89c.41-.518.889-.933 1.435-1.246A6.005 6.005 0 0197.272 48l.35.882a7.086 7.086 0 00-1.512.623 3.928 3.928 0 00-1.183 1.022c-.331.425-.588.952-.77 1.582-.182.63-.273 1.393-.273 2.289 0 .905.11 1.678.329 2.317.22.64.509 1.171.868 1.596.36.425.76.756 1.204.994.443.238.889.404 1.337.497l-.35.966zm4.354-.966a4.965 4.965 0 001.337-.497 4.15 4.15 0 001.204-.994c.36-.425.649-.957.868-1.596.22-.64.329-1.412.329-2.317 0-.896-.091-1.659-.273-2.289-.182-.63-.439-1.157-.77-1.582a3.928 3.928 0 00-1.183-1.022 7.086 7.086 0 00-1.512-.623l.35-.882c.607.13 1.183.352 1.729.665a4.984 4.984 0 011.435 1.246c.41.518.737 1.148.98 1.89s.364 1.608.364 2.597c0 .999-.119 1.862-.357 2.59-.238.728-.56 1.344-.966 1.848a5.036 5.036 0 01-1.428 1.225 6.964 6.964 0 01-1.757.707l-.35-.966zm17.878-2.45c0-.401-.068-.749-.203-1.043a2.44 2.44 0 00-.504-.735c-.2-.196-.415-.34-.644-.434a1.641 1.641 0 00-.609-.14v-.98c.177 0 .38-.04.609-.119.229-.08.443-.21.644-.392.2-.182.369-.418.504-.707.135-.29.203-.649.203-1.078v-1.428c0-.336.054-.644.161-.924a2.22 2.22 0 01.448-.728c.191-.205.42-.366.686-.483.266-.117.558-.175.875-.175h2.03v.98h-1.54c-.588 0-.996.14-1.225.42-.229.28-.343.695-.343 1.246v1.358c0 .383-.07.723-.21 1.022a2.7 2.7 0 01-1.106 1.225c-.205.117-.373.184-.504.203v.084c.121.019.285.091.49.217.205.126.406.299.602.518.196.22.366.478.511.777.145.299.217.63.217.994v1.344c0 .57.121.99.364 1.26s.649.406 1.218.406h1.526v.98h-2.03c-.653 0-1.178-.194-1.575-.581-.397-.387-.595-.959-.595-1.715v-1.372z"/><path id="alert" fill="#181717" d="M134.736 51.346a4.447 4.447 0 011.358-.504 7.423 7.423 0 011.484-.154c.476 0 .866.075 1.169.224.303.15.541.343.714.581.173.238.29.509.35.812.06.303.091.609.091.917 0 .355-.01.733-.028 1.134-.019.401-.033.803-.042 1.204 0 .467.028.91.084 1.33h.938v.91h-1.862l-.126-1.05h-.07c-.056.084-.14.191-.252.322-.112.13-.259.259-.441.385a2.749 2.749 0 01-1.589.469c-.69 0-1.237-.177-1.638-.532-.401-.355-.602-.84-.602-1.456 0-.476.105-.873.315-1.19.21-.317.511-.56.903-.728.392-.168.866-.266 1.421-.294a9.544 9.544 0 011.869.112c.047-.43.054-.786.021-1.071-.033-.285-.107-.511-.224-.679a.938.938 0 00-.49-.357 2.482 2.482 0 00-.777-.105c-.42 0-.821.058-1.204.175-.383.117-.723.236-1.022.357l-.35-.812zm2.058 5.642c.261 0 .504-.042.728-.126a2.22 2.22 0 00.588-.322 2.133 2.133 0 00.672-.868v-.98a7.92 7.92 0 00-1.344-.126c-.41 0-.765.044-1.064.133-.299.089-.532.226-.7.413-.168.187-.252.43-.252.728 0 .308.105.576.315.805.21.229.562.343 1.057.343zM143.29 48h2.324v7.448c0 .57.096.97.287 1.204.191.233.474.35.847.35.261 0 .511-.047.749-.14.238-.093.502-.252.791-.476l.504.77c-.15.13-.313.247-.49.35a3.638 3.638 0 01-1.106.42 2.963 2.963 0 01-1.442-.077 1.579 1.579 0 01-.679-.427 1.897 1.897 0 01-.413-.777c-.093-.322-.14-.721-.14-1.197v-6.51h-1.232V48zm14.14 8.918c-.168.15-.366.29-.595.42a4.39 4.39 0 01-.749.336c-.27.093-.553.166-.847.217-.294.051-.59.077-.889.077-.56 0-1.055-.086-1.484-.259a2.858 2.858 0 01-1.078-.742 3.234 3.234 0 01-.658-1.155 4.767 4.767 0 01-.224-1.512c0-.588.082-1.11.245-1.568.163-.457.399-.84.707-1.148a3.08 3.08 0 011.12-.707 4.187 4.187 0 011.47-.245c.392 0 .78.051 1.162.154.383.103.721.296 1.015.581.294.285.52.677.679 1.176.159.5.215 1.146.168 1.939h-5.418c0 .84.226 1.468.679 1.883.453.415 1.057.623 1.813.623.252 0 .502-.03.749-.091.247-.06.483-.133.707-.217a3.72 3.72 0 00.595-.28c.173-.103.306-.196.399-.28l.434.798zm-2.954-5.362c-.308 0-.6.033-.875.098a1.995 1.995 0 00-.728.329c-.21.154-.383.355-.518.602s-.222.553-.259.917h4.354c-.047-.616-.245-1.094-.595-1.435-.35-.34-.81-.511-1.379-.511zm4.872 6.244v-.938h1.89v-5.124h-1.89V50.8h2.618l.224.91h.07c.317-.29.672-.537 1.064-.742.392-.205.859-.308 1.4-.308.317 0 .572.06.763.182.191.121.34.299.448.532.107.233.18.516.217.847.037.331.056.707.056 1.127l-.98.014c0-.597-.058-1.036-.175-1.316-.117-.28-.329-.42-.637-.42-.29 0-.55.042-.784.126a2.565 2.565 0 00-.609.308c-.173.121-.32.243-.441.364s-.21.224-.266.308v4.13h2.688v.938h-5.656zm7.91-7h1.666v-1.386l1.092-.308V50.8h3.738v.938h-3.738v3.304c0 .681.166 1.185.497 1.512.331.327.805.49 1.421.49.42 0 .786-.08 1.099-.238.313-.159.595-.331.847-.518l.364.826a3.938 3.938 0 01-1.169.63 4.182 4.182 0 01-1.393.238 3.41 3.41 0 01-1.057-.161 2.426 2.426 0 01-.875-.497 2.38 2.38 0 01-.602-.861c-.15-.35-.224-.768-.224-1.253v-3.472h-1.666V50.8z"/><path id="(" fill="#7E7C7B" d="M181.272 60.768a6.964 6.964 0 01-1.757-.707 5.036 5.036 0 01-1.428-1.225c-.406-.504-.728-1.12-.966-1.848s-.357-1.591-.357-2.59c0-.99.121-1.855.364-2.597s.57-1.372.98-1.89c.41-.518.889-.933 1.435-1.246a6.005 6.005 0 011.729-.665l.35.882a7.086 7.086 0 00-1.512.623 3.928 3.928 0 00-1.183 1.022c-.331.425-.588.952-.77 1.582-.182.63-.273 1.393-.273 2.289 0 .905.11 1.678.329 2.317.22.64.509 1.171.868 1.596.36.425.76.756 1.204.994.443.238.889.404 1.337.497l-.35.966z"/><path id="i" fill="#181717" d="M185.094 57.8v-.938h2.436v-5.124h-2.436V50.8h3.556v6.062h2.38v.938h-5.936zm2.058-8.988c0-.252.084-.469.252-.651a.838.838 0 01.644-.273c.27 0 .497.091.679.273a.889.889 0 01.273.651.806.806 0 01-.273.616.963.963 0 01-.679.252.872.872 0 01-.644-.252.838.838 0 01-.252-.616z"/><path id=");}," fill="#7E7C7B" d="M194.026 59.802a4.965 4.965 0 001.337-.497 4.15 4.15 0 001.204-.994c.36-.425.649-.957.868-1.596.22-.64.329-1.412.329-2.317 0-.896-.091-1.659-.273-2.289-.182-.63-.439-1.157-.77-1.582a3.928 3.928 0 00-1.183-1.022 7.086 7.086 0 00-1.512-.623l.35-.882c.607.13 1.183.352 1.729.665a4.984 4.984 0 011.435 1.246c.41.518.737 1.148.98 1.89s.364 1.608.364 2.597c0 .999-.119 1.862-.357 2.59-.238.728-.56 1.344-.966 1.848a5.036 5.036 0 01-1.428 1.225 6.964 6.964 0 01-1.757.707l-.35-.966zm9.604-2.772c0-.28.091-.506.273-.679.182-.173.418-.259.707-.259.355 0 .63.124.826.371.196.247.294.595.294 1.043a2.36 2.36 0 01-.637 1.659 2.465 2.465 0 01-.588.462c-.21.117-.404.203-.581.259l-.35-.546c.336-.13.625-.317.868-.56.243-.243.364-.537.364-.882-.13.028-.233.042-.308.042-.27 0-.483-.077-.637-.231-.154-.154-.231-.38-.231-.679zm.126-5.502c0-.299.084-.53.252-.693.168-.163.392-.245.672-.245.299 0 .532.082.7.245.168.163.252.394.252.693 0 .27-.084.495-.252.672-.168.177-.401.266-.7.266-.28 0-.504-.089-.672-.266a.938.938 0 01-.252-.672zm18.788 7.196c0 .756-.198 1.328-.595 1.715-.397.387-.922.581-1.575.581h-2.03v-.98h1.526c.57 0 .975-.135 1.218-.406.243-.27.364-.69.364-1.26V57.03c0-.364.07-.695.21-.994.14-.299.308-.558.504-.777.196-.22.397-.392.602-.518.205-.126.373-.198.504-.217v-.084c-.13-.019-.299-.086-.504-.203a2.7 2.7 0 01-1.106-1.225c-.14-.299-.21-.64-.21-1.022v-1.358c0-.55-.114-.966-.343-1.246-.229-.28-.637-.42-1.225-.42h-1.54v-.98h2.03c.317 0 .609.058.875.175.266.117.495.278.686.483.191.205.34.448.448.728.107.28.161.588.161.924v1.428c0 .43.068.789.203 1.078.135.29.303.525.504.707.2.182.415.313.644.392.229.08.432.119.609.119V55c-.177 0-.38.047-.609.14a2.011 2.011 0 00-.644.434 2.44 2.44 0 00-.504.735c-.135.294-.203.642-.203 1.043v1.372zm6.286-1.694c0-.28.091-.506.273-.679.182-.173.418-.259.707-.259.355 0 .63.124.826.371.196.247.294.595.294 1.043a2.36 2.36 0 01-.637 1.659 2.465 2.465 0 01-.588.462c-.21.117-.404.203-.581.259l-.35-.546c.336-.13.625-.317.868-.56.243-.243.364-.537.364-.882-.13.028-.233.042-.308.042-.27 0-.483-.077-.637-.231-.154-.154-.231-.38-.231-.679z"/><path id="function" fill="#1C85B5" d="M16.856 81.8v-.938h1.666v-5.124h-1.666V74.8h1.666v-.392c0-.877.229-1.512.686-1.904.457-.392 1.11-.588 1.96-.588.308 0 .583.019.826.056.243.037.504.112.784.224l-.252.91a2.862 2.862 0 00-.7-.203 4.295 4.295 0 00-.616-.049c-.616 0-1.036.152-1.26.455-.224.303-.336.8-.336 1.491h2.898v.938h-2.898v5.124h2.898v.938h-5.656zm12.25-7h1.988v4.774c0 .457.028.896.084 1.316h.938v.91h-1.862l-.042-1.19h-.056a2.938 2.938 0 01-.966.98c-.401.252-.887.378-1.456.378-.43 0-.796-.049-1.099-.147a1.556 1.556 0 01-.749-.511c-.196-.243-.34-.567-.434-.973-.093-.406-.14-.912-.14-1.519v-3.08h-.938V74.8h2.03v3.794c0 .383.016.726.049 1.029.033.303.1.56.203.77.103.21.254.369.455.476.2.107.469.161.805.161.485 0 .908-.159 1.267-.476.36-.317.632-.714.819-1.19v-3.626h-.896V74.8zm4.62 2.45a14.05 14.05 0 00-.063-1.176 4.657 4.657 0 00-.049-.364h-.938v-.91h1.876l.126 1.134h.07c.093-.159.217-.315.371-.469a2.91 2.91 0 011.225-.721c.252-.075.518-.112.798-.112.43 0 .81.047 1.141.14.331.093.607.259.826.497.22.238.385.56.497.966.112.406.168.922.168 1.547V81.8h-1.092v-3.808c0-.775-.126-1.358-.378-1.75-.252-.392-.71-.588-1.372-.588-.243 0-.478.049-.707.147a2.44 2.44 0 00-.623.385c-.187.159-.35.343-.49.553-.14.21-.243.432-.308.665V81.8h-1.078v-4.55zm13.244-1.372a5.531 5.531 0 00-.693-.189 3.61 3.61 0 00-.735-.077c-.915 0-1.596.215-2.044.644-.448.43-.672 1.11-.672 2.044 0 .41.065.777.196 1.099.13.322.317.595.56.819.243.224.534.397.875.518.34.121.716.182 1.127.182.439 0 .866-.075 1.281-.224.415-.15.763-.345 1.043-.588l.49.812c-.13.112-.294.229-.49.35a4.837 4.837 0 01-1.533.602 4.962 4.962 0 01-1.015.098c-.607 0-1.141-.086-1.603-.259a3.045 3.045 0 01-1.155-.742 3.176 3.176 0 01-.7-1.162 4.525 4.525 0 01-.238-1.505c0-.588.082-1.11.245-1.568.163-.457.399-.84.707-1.148a3.08 3.08 0 011.12-.707 4.187 4.187 0 011.47-.245c.69 0 1.253.06 1.687.182.434.121.8.257 1.099.406l-.014.042v1.946H46.97v-1.33zm2.688-1.078h1.666v-1.386l1.092-.308V74.8h3.738v.938h-3.738v3.304c0 .681.166 1.185.497 1.512.331.327.805.49 1.421.49.42 0 .786-.08 1.099-.238.313-.159.595-.331.847-.518l.364.826a3.938 3.938 0 01-1.169.63 4.182 4.182 0 01-1.393.238 3.41 3.41 0 01-1.057-.161 2.426 2.426 0 01-.875-.497 2.38 2.38 0 01-.602-.861c-.15-.35-.224-.768-.224-1.253v-3.472h-1.666V74.8zm9.436 7v-.938h2.436v-5.124h-2.436V74.8h3.556v6.062h2.38v.938h-5.936zm2.058-8.988c0-.252.084-.469.252-.651a.838.838 0 01.644-.273c.27 0 .497.091.679.273a.889.889 0 01.273.651.806.806 0 01-.273.616.963.963 0 01-.679.252.872.872 0 01-.644-.252.838.838 0 01-.252-.616zm5.67 5.488c0-1.13.294-2.023.882-2.681.588-.658 1.428-.987 2.52-.987.588 0 1.094.096 1.519.287.425.191.777.45 1.057.777.28.327.488.714.623 1.162.135.448.203.929.203 1.442 0 .56-.075 1.066-.224 1.519-.15.453-.369.838-.658 1.155-.29.317-.646.562-1.071.735a3.82 3.82 0 01-1.449.259c-.579 0-1.083-.096-1.512-.287a2.967 2.967 0 01-1.064-.777 3.168 3.168 0 01-.623-1.162 4.963 4.963 0 01-.203-1.442zm1.162 0c0 .327.04.653.119.98.08.327.208.62.385.882.177.261.408.471.693.63.285.159.632.238 1.043.238.747 0 1.309-.231 1.687-.693.378-.462.567-1.141.567-2.037 0-.336-.04-.665-.119-.987a2.608 2.608 0 00-.392-.875 2.066 2.066 0 00-.7-.63c-.285-.159-.632-.238-1.043-.238-.747 0-1.307.229-1.68.686-.373.457-.56 1.139-.56 2.044zm7.742-1.05a14.05 14.05 0 00-.063-1.176 4.657 4.657 0 00-.049-.364h-.938v-.91h1.876l.126 1.134h.07c.093-.159.217-.315.371-.469a2.91 2.91 0 011.225-.721c.252-.075.518-.112.798-.112.43 0 .81.047 1.141.14.331.093.607.259.826.497.22.238.385.56.497.966.112.406.168.922.168 1.547V81.8h-1.092v-3.808c0-.775-.126-1.358-.378-1.75-.252-.392-.71-.588-1.372-.588-.243 0-.478.049-.707.147a2.44 2.44 0 00-.623.385c-.187.159-.35.343-.49.553-.14.21-.243.432-.308.665V81.8h-1.078v-4.55z"/><path id="(){" fill="#7E7C7B" d="M97.272 84.768a6.964 6.964 0 01-1.757-.707 5.036 5.036 0 01-1.428-1.225c-.406-.504-.728-1.12-.966-1.848s-.357-1.591-.357-2.59c0-.99.121-1.855.364-2.597s.57-1.372.98-1.89c.41-.518.889-.933 1.435-1.246A6.005 6.005 0 0197.272 72l.35.882a7.086 7.086 0 00-1.512.623 3.928 3.928 0 00-1.183 1.022c-.331.425-.588.952-.77 1.582-.182.63-.273 1.393-.273 2.289 0 .905.11 1.678.329 2.317.22.64.509 1.171.868 1.596.36.425.76.756 1.204.994.443.238.889.404 1.337.497l-.35.966zm4.354-.966a4.965 4.965 0 001.337-.497 4.15 4.15 0 001.204-.994c.36-.425.649-.957.868-1.596.22-.64.329-1.412.329-2.317 0-.896-.091-1.659-.273-2.289-.182-.63-.439-1.157-.77-1.582a3.928 3.928 0 00-1.183-1.022 7.086 7.086 0 00-1.512-.623l.35-.882c.607.13 1.183.352 1.729.665a4.984 4.984 0 011.435 1.246c.41.518.737 1.148.98 1.89s.364 1.608.364 2.597c0 .999-.119 1.862-.357 2.59-.238.728-.56 1.344-.966 1.848a5.036 5.036 0 01-1.428 1.225 6.964 6.964 0 01-1.757.707l-.35-.966zm17.878-2.45c0-.401-.068-.749-.203-1.043a2.44 2.44 0 00-.504-.735c-.2-.196-.415-.34-.644-.434a1.641 1.641 0 00-.609-.14v-.98c.177 0 .38-.04.609-.119.229-.08.443-.21.644-.392.2-.182.369-.418.504-.707.135-.29.203-.649.203-1.078v-1.428c0-.336.054-.644.161-.924a2.22 2.22 0 01.448-.728c.191-.205.42-.366.686-.483.266-.117.558-.175.875-.175h2.03v.98h-1.54c-.588 0-.996.14-1.225.42-.229.28-.343.695-.343 1.246v1.358c0 .383-.07.723-.21 1.022a2.7 2.7 0 01-1.106 1.225c-.205.117-.373.184-.504.203v.084c.121.019.285.091.49.217.205.126.406.299.602.518.196.22.366.478.511.777.145.299.217.63.217.994v1.344c0 .57.121.99.364 1.26s.649.406 1.218.406h1.526v.98h-2.03c-.653 0-1.178-.194-1.575-.581-.397-.387-.595-.959-.595-1.715v-1.372z"/><path id="alert" fill="#181717" d="M134.736 75.346a4.447 4.447 0 011.358-.504 7.423 7.423 0 011.484-.154c.476 0 .866.075 1.169.224.303.15.541.343.714.581.173.238.29.509.35.812.06.303.091.609.091.917 0 .355-.01.733-.028 1.134-.019.401-.033.803-.042 1.204 0 .467.028.91.084 1.33h.938v.91h-1.862l-.126-1.05h-.07c-.056.084-.14.191-.252.322-.112.13-.259.259-.441.385a2.749 2.749 0 01-1.589.469c-.69 0-1.237-.177-1.638-.532-.401-.355-.602-.84-.602-1.456 0-.476.105-.873.315-1.19.21-.317.511-.56.903-.728.392-.168.866-.266 1.421-.294a9.544 9.544 0 011.869.112c.047-.43.054-.786.021-1.071-.033-.285-.107-.511-.224-.679a.938.938 0 00-.49-.357 2.482 2.482 0 00-.777-.105c-.42 0-.821.058-1.204.175-.383.117-.723.236-1.022.357l-.35-.812zm2.058 5.642c.261 0 .504-.042.728-.126a2.22 2.22 0 00.588-.322 2.133 2.133 0 00.672-.868v-.98a7.92 7.92 0 00-1.344-.126c-.41 0-.765.044-1.064.133-.299.089-.532.226-.7.413-.168.187-.252.43-.252.728 0 .308.105.576.315.805.21.229.562.343 1.057.343zM143.29 72h2.324v7.448c0 .57.096.97.287 1.204.191.233.474.35.847.35.261 0 .511-.047.749-.14.238-.093.502-.252.791-.476l.504.77c-.15.13-.313.247-.49.35a3.638 3.638 0 01-1.106.42 2.963 2.963 0 01-1.442-.077 1.579 1.579 0 01-.679-.427 1.897 1.897 0 01-.413-.777c-.093-.322-.14-.721-.14-1.197v-6.51h-1.232V72zm14.14 8.918c-.168.15-.366.29-.595.42a4.39 4.39 0 01-.749.336c-.27.093-.553.166-.847.217-.294.051-.59.077-.889.077-.56 0-1.055-.086-1.484-.259a2.858 2.858 0 01-1.078-.742 3.234 3.234 0 01-.658-1.155 4.767 4.767 0 01-.224-1.512c0-.588.082-1.11.245-1.568.163-.457.399-.84.707-1.148a3.08 3.08 0 011.12-.707 4.187 4.187 0 011.47-.245c.392 0 .78.051 1.162.154.383.103.721.296 1.015.581.294.285.52.677.679 1.176.159.5.215 1.146.168 1.939h-5.418c0 .84.226 1.468.679 1.883.453.415 1.057.623 1.813.623.252 0 .502-.03.749-.091.247-.06.483-.133.707-.217a3.72 3.72 0 00.595-.28c.173-.103.306-.196.399-.28l.434.798zm-2.954-5.362c-.308 0-.6.033-.875.098a1.995 1.995 0 00-.728.329c-.21.154-.383.355-.518.602s-.222.553-.259.917h4.354c-.047-.616-.245-1.094-.595-1.435-.35-.34-.81-.511-1.379-.511zm4.872 6.244v-.938h1.89v-5.124h-1.89V74.8h2.618l.224.91h.07c.317-.29.672-.537 1.064-.742.392-.205.859-.308 1.4-.308.317 0 .572.06.763.182.191.121.34.299.448.532.107.233.18.516.217.847.037.331.056.707.056 1.127l-.98.014c0-.597-.058-1.036-.175-1.316-.117-.28-.329-.42-.637-.42-.29 0-.55.042-.784.126a2.565 2.565 0 00-.609.308c-.173.121-.32.243-.441.364s-.21.224-.266.308v4.13h2.688v.938h-5.656zm7.91-7h1.666v-1.386l1.092-.308V74.8h3.738v.938h-3.738v3.304c0 .681.166 1.185.497 1.512.331.327.805.49 1.421.49.42 0 .786-.08 1.099-.238.313-.159.595-.331.847-.518l.364.826a3.938 3.938 0 01-1.169.63 4.182 4.182 0 01-1.393.238 3.41 3.41 0 01-1.057-.161 2.426 2.426 0 01-.875-.497 2.38 2.38 0 01-.602-.861c-.15-.35-.224-.768-.224-1.253v-3.472h-1.666V74.8z"/><path id="(" fill="#7E7C7B" d="M181.272 84.768a6.964 6.964 0 01-1.757-.707 5.036 5.036 0 01-1.428-1.225c-.406-.504-.728-1.12-.966-1.848s-.357-1.591-.357-2.59c0-.99.121-1.855.364-2.597s.57-1.372.98-1.89c.41-.518.889-.933 1.435-1.246a6.005 6.005 0 011.729-.665l.35.882a7.086 7.086 0 00-1.512.623 3.928 3.928 0 00-1.183 1.022c-.331.425-.588.952-.77 1.582-.182.63-.273 1.393-.273 2.289 0 .905.11 1.678.329 2.317.22.64.509 1.171.868 1.596.36.425.76.756 1.204.994.443.238.889.404 1.337.497l-.35.966z"/><path id="i" fill="#181717" d="M185.094 81.8v-.938h2.436v-5.124h-2.436V74.8h3.556v6.062h2.38v.938h-5.936zm2.058-8.988c0-.252.084-.469.252-.651a.838.838 0 01.644-.273c.27 0 .497.091.679.273a.889.889 0 01.273.651.806.806 0 01-.273.616.963.963 0 01-.679.252.872.872 0 01-.644-.252.838.838 0 01-.252-.616z"/><path id=");}," fill="#7E7C7B" d="M194.026 83.802a4.965 4.965 0 001.337-.497 4.15 4.15 0 001.204-.994c.36-.425.649-.957.868-1.596.22-.64.329-1.412.329-2.317 0-.896-.091-1.659-.273-2.289-.182-.63-.439-1.157-.77-1.582a3.928 3.928 0 00-1.183-1.022 7.086 7.086 0 00-1.512-.623l.35-.882c.607.13 1.183.352 1.729.665a4.984 4.984 0 011.435 1.246c.41.518.737 1.148.98 1.89s.364 1.608.364 2.597c0 .999-.119 1.862-.357 2.59-.238.728-.56 1.344-.966 1.848a5.036 5.036 0 01-1.428 1.225 6.964 6.964 0 01-1.757.707l-.35-.966zm9.604-2.772c0-.28.091-.506.273-.679.182-.173.418-.259.707-.259.355 0 .63.124.826.371.196.247.294.595.294 1.043a2.36 2.36 0 01-.637 1.659 2.465 2.465 0 01-.588.462c-.21.117-.404.203-.581.259l-.35-.546c.336-.13.625-.317.868-.56.243-.243.364-.537.364-.882-.13.028-.233.042-.308.042-.27 0-.483-.077-.637-.231-.154-.154-.231-.38-.231-.679zm.126-5.502c0-.299.084-.53.252-.693.168-.163.392-.245.672-.245.299 0 .532.082.7.245.168.163.252.394.252.693 0 .27-.084.495-.252.672-.168.177-.401.266-.7.266-.28 0-.504-.089-.672-.266a.938.938 0 01-.252-.672zm18.788 7.196c0 .756-.198 1.328-.595 1.715-.397.387-.922.581-1.575.581h-2.03v-.98h1.526c.57 0 .975-.135 1.218-.406.243-.27.364-.69.364-1.26V81.03c0-.364.07-.695.21-.994.14-.299.308-.558.504-.777.196-.22.397-.392.602-.518.205-.126.373-.198.504-.217v-.084c-.13-.019-.299-.086-.504-.203a2.7 2.7 0 01-1.106-1.225c-.14-.299-.21-.64-.21-1.022v-1.358c0-.55-.114-.966-.343-1.246-.229-.28-.637-.42-1.225-.42h-1.54v-.98h2.03c.317 0 .609.058.875.175.266.117.495.278.686.483.191.205.34.448.448.728.107.28.161.588.161.924v1.428c0 .43.068.789.203 1.078.135.29.303.525.504.707.2.182.415.313.644.392.229.08.432.119.609.119V79c-.177 0-.38.047-.609.14a2.011 2.011 0 00-.644.434 2.44 2.44 0 00-.504.735c-.135.294-.203.642-.203 1.043v1.372zm6.286-1.694c0-.28.091-.506.273-.679.182-.173.418-.259.707-.259.355 0 .63.124.826.371.196.247.294.595.294 1.043a2.36 2.36 0 01-.637 1.659 2.465 2.465 0 01-.588.462c-.21.117-.404.203-.581.259l-.35-.546c.336-.13.625-.317.868-.56.243-.243.364-.537.364-.882-.13.028-.233.042-.308.042-.27 0-.483-.077-.637-.231-.154-.154-.231-.38-.231-.679z"/><path id="..." fill="#181717" d="M18.886 105.03c0-.299.084-.53.252-.693.168-.163.392-.245.672-.245.299 0 .532.082.7.245.168.163.252.394.252.693 0 .27-.084.495-.252.672-.168.177-.401.266-.7.266-.28 0-.504-.089-.672-.266a.938.938 0 01-.252-.672zm8.4 0c0-.299.084-.53.252-.693.168-.163.392-.245.672-.245.299 0 .532.082.7.245.168.163.252.394.252.693 0 .27-.084.495-.252.672-.168.177-.401.266-.7.266-.28 0-.504-.089-.672-.266a.938.938 0 01-.252-.672zm8.4 0c0-.299.084-.53.252-.693.168-.163.392-.245.672-.245.299 0 .532.082.7.245.168.163.252.394.252.693 0 .27-.084.495-.252.672-.168.177-.401.266-.7.266-.28 0-.504-.089-.672-.266a.938.938 0 01-.252-.672z"/><path id="function" fill="#1C85B5" d="M16.856 129.8v-.938h1.666v-5.124h-1.666v-.938h1.666v-.392c0-.877.229-1.512.686-1.904.457-.392 1.11-.588 1.96-.588.308 0 .583.019.826.056.243.037.504.112.784.224l-.252.91a2.862 2.862 0 00-.7-.203 4.295 4.295 0 00-.616-.049c-.616 0-1.036.152-1.26.455-.224.303-.336.8-.336 1.491h2.898v.938h-2.898v5.124h2.898v.938h-5.656zm12.25-7h1.988v4.774c0 .457.028.896.084 1.316h.938v.91h-1.862l-.042-1.19h-.056a2.938 2.938 0 01-.966.98c-.401.252-.887.378-1.456.378-.43 0-.796-.049-1.099-.147a1.556 1.556 0 01-.749-.511c-.196-.243-.34-.567-.434-.973-.093-.406-.14-.912-.14-1.519v-3.08h-.938v-.938h2.03v3.794c0 .383.016.726.049 1.029.033.303.1.56.203.77.103.21.254.369.455.476.2.107.469.161.805.161.485 0 .908-.159 1.267-.476.36-.317.632-.714.819-1.19v-3.626h-.896v-.938zm4.62 2.45a14.05 14.05 0 00-.063-1.176 4.657 4.657 0 00-.049-.364h-.938v-.91h1.876l.126 1.134h.07c.093-.159.217-.315.371-.469a2.91 2.91 0 011.225-.721c.252-.075.518-.112.798-.112.43 0 .81.047 1.141.14.331.093.607.259.826.497.22.238.385.56.497.966.112.406.168.922.168 1.547v4.018h-1.092v-3.808c0-.775-.126-1.358-.378-1.75-.252-.392-.71-.588-1.372-.588-.243 0-.478.049-.707.147a2.44 2.44 0 00-.623.385c-.187.159-.35.343-.49.553-.14.21-.243.432-.308.665v4.396h-1.078v-4.55zm13.244-1.372a5.531 5.531 0 00-.693-.189 3.61 3.61 0 00-.735-.077c-.915 0-1.596.215-2.044.644-.448.43-.672 1.11-.672 2.044 0 .41.065.777.196 1.099.13.322.317.595.56.819.243.224.534.397.875.518.34.121.716.182 1.127.182.439 0 .866-.075 1.281-.224.415-.15.763-.345 1.043-.588l.49.812c-.13.112-.294.229-.49.35a4.837 4.837 0 01-1.533.602 4.962 4.962 0 01-1.015.098c-.607 0-1.141-.086-1.603-.259a3.045 3.045 0 01-1.155-.742 3.176 3.176 0 01-.7-1.162 4.525 4.525 0 01-.238-1.505c0-.588.082-1.11.245-1.568.163-.457.399-.84.707-1.148a3.08 3.08 0 011.12-.707 4.187 4.187 0 011.47-.245c.69 0 1.253.06 1.687.182.434.121.8.257 1.099.406l-.014.042v1.946H46.97v-1.33zm2.688-1.078h1.666v-1.386l1.092-.308v1.694h3.738v.938h-3.738v3.304c0 .681.166 1.185.497 1.512.331.327.805.49 1.421.49.42 0 .786-.08 1.099-.238.313-.159.595-.331.847-.518l.364.826a3.938 3.938 0 01-1.169.63 4.182 4.182 0 01-1.393.238 3.41 3.41 0 01-1.057-.161 2.426 2.426 0 01-.875-.497 2.38 2.38 0 01-.602-.861c-.15-.35-.224-.768-.224-1.253v-3.472h-1.666v-.938zm9.436 7v-.938h2.436v-5.124h-2.436v-.938h3.556v6.062h2.38v.938h-5.936zm2.058-8.988c0-.252.084-.469.252-.651a.838.838 0 01.644-.273c.27 0 .497.091.679.273a.889.889 0 01.273.651.806.806 0 01-.273.616.963.963 0 01-.679.252.872.872 0 01-.644-.252.838.838 0 01-.252-.616zm5.67 5.488c0-1.13.294-2.023.882-2.681.588-.658 1.428-.987 2.52-.987.588 0 1.094.096 1.519.287.425.191.777.45 1.057.777.28.327.488.714.623 1.162.135.448.203.929.203 1.442 0 .56-.075 1.066-.224 1.519-.15.453-.369.838-.658 1.155-.29.317-.646.562-1.071.735a3.82 3.82 0 01-1.449.259c-.579 0-1.083-.096-1.512-.287a2.967 2.967 0 01-1.064-.777 3.168 3.168 0 01-.623-1.162 4.963 4.963 0 01-.203-1.442zm1.162 0c0 .327.04.653.119.98.08.327.208.62.385.882.177.261.408.471.693.63.285.159.632.238 1.043.238.747 0 1.309-.231 1.687-.693.378-.462.567-1.141.567-2.037 0-.336-.04-.665-.119-.987a2.608 2.608 0 00-.392-.875 2.066 2.066 0 00-.7-.63c-.285-.159-.632-.238-1.043-.238-.747 0-1.307.229-1.68.686-.373.457-.56 1.139-.56 2.044zm7.742-1.05a14.05 14.05 0 00-.063-1.176 4.657 4.657 0 00-.049-.364h-.938v-.91h1.876l.126 1.134h.07c.093-.159.217-.315.371-.469a2.91 2.91 0 011.225-.721c.252-.075.518-.112.798-.112.43 0 .81.047 1.141.14.331.093.607.259.826.497.22.238.385.56.497.966.112.406.168.922.168 1.547v4.018h-1.092v-3.808c0-.775-.126-1.358-.378-1.75-.252-.392-.71-.588-1.372-.588-.243 0-.478.049-.707.147a2.44 2.44 0 00-.623.385c-.187.159-.35.343-.49.553-.14.21-.243.432-.308.665v4.396h-1.078v-4.55z"/><path id="(){" fill="#7E7C7B" d="M97.272 132.768a6.964 6.964 0 01-1.757-.707 5.036 5.036 0 01-1.428-1.225c-.406-.504-.728-1.12-.966-1.848s-.357-1.591-.357-2.59c0-.99.121-1.855.364-2.597s.57-1.372.98-1.89c.41-.518.889-.933 1.435-1.246a6.005 6.005 0 011.729-.665l.35.882a7.086 7.086 0 00-1.512.623 3.928 3.928 0 00-1.183 1.022c-.331.425-.588.952-.77 1.582-.182.63-.273 1.393-.273 2.289 0 .905.11 1.678.329 2.317.22.64.509 1.171.868 1.596.36.425.76.756 1.204.994.443.238.889.404 1.337.497l-.35.966zm4.354-.966a4.965 4.965 0 001.337-.497 4.15 4.15 0 001.204-.994c.36-.425.649-.957.868-1.596.22-.64.329-1.412.329-2.317 0-.896-.091-1.659-.273-2.289-.182-.63-.439-1.157-.77-1.582a3.928 3.928 0 00-1.183-1.022 7.086 7.086 0 00-1.512-.623l.35-.882c.607.13 1.183.352 1.729.665a4.984 4.984 0 011.435 1.246c.41.518.737 1.148.98 1.89s.364 1.608.364 2.597c0 .999-.119 1.862-.357 2.59-.238.728-.56 1.344-.966 1.848a5.036 5.036 0 01-1.428 1.225 6.964 6.964 0 01-1.757.707l-.35-.966zm17.878-2.45c0-.401-.068-.749-.203-1.043a2.44 2.44 0 00-.504-.735c-.2-.196-.415-.34-.644-.434a1.641 1.641 0 00-.609-.14v-.98c.177 0 .38-.04.609-.119.229-.08.443-.21.644-.392.2-.182.369-.418.504-.707.135-.29.203-.649.203-1.078v-1.428c0-.336.054-.644.161-.924a2.22 2.22 0 01.448-.728c.191-.205.42-.366.686-.483.266-.117.558-.175.875-.175h2.03v.98h-1.54c-.588 0-.996.14-1.225.42-.229.28-.343.695-.343 1.246v1.358c0 .383-.07.723-.21 1.022a2.7 2.7 0 01-1.106 1.225c-.205.117-.373.184-.504.203v.084c.121.019.285.091.49.217.205.126.406.299.602.518.196.22.366.478.511.777.145.299.217.63.217.994v1.344c0 .57.121.99.364 1.26s.649.406 1.218.406h1.526v.98h-2.03c-.653 0-1.178-.194-1.575-.581-.397-.387-.595-.959-.595-1.715v-1.372z"/><path id="alert" fill="#181717" d="M134.736 123.346a4.447 4.447 0 011.358-.504 7.423 7.423 0 011.484-.154c.476 0 .866.075 1.169.224.303.15.541.343.714.581.173.238.29.509.35.812.06.303.091.609.091.917 0 .355-.01.733-.028 1.134-.019.401-.033.803-.042 1.204 0 .467.028.91.084 1.33h.938v.91h-1.862l-.126-1.05h-.07c-.056.084-.14.191-.252.322-.112.13-.259.259-.441.385a2.749 2.749 0 01-1.589.469c-.69 0-1.237-.177-1.638-.532-.401-.355-.602-.84-.602-1.456 0-.476.105-.873.315-1.19.21-.317.511-.56.903-.728.392-.168.866-.266 1.421-.294a9.544 9.544 0 011.869.112c.047-.43.054-.786.021-1.071-.033-.285-.107-.511-.224-.679a.938.938 0 00-.49-.357 2.482 2.482 0 00-.777-.105c-.42 0-.821.058-1.204.175-.383.117-.723.236-1.022.357l-.35-.812zm2.058 5.642c.261 0 .504-.042.728-.126a2.22 2.22 0 00.588-.322 2.133 2.133 0 00.672-.868v-.98a7.92 7.92 0 00-1.344-.126c-.41 0-.765.044-1.064.133-.299.089-.532.226-.7.413-.168.187-.252.43-.252.728 0 .308.105.576.315.805.21.229.562.343 1.057.343zM143.29 120h2.324v7.448c0 .57.096.97.287 1.204.191.233.474.35.847.35.261 0 .511-.047.749-.14.238-.093.502-.252.791-.476l.504.77c-.15.13-.313.247-.49.35a3.638 3.638 0 01-1.106.42 2.963 2.963 0 01-1.442-.077 1.579 1.579 0 01-.679-.427 1.897 1.897 0 01-.413-.777c-.093-.322-.14-.721-.14-1.197v-6.51h-1.232V120zm14.14 8.918c-.168.15-.366.29-.595.42a4.39 4.39 0 01-.749.336c-.27.093-.553.166-.847.217-.294.051-.59.077-.889.077-.56 0-1.055-.086-1.484-.259a2.858 2.858 0 01-1.078-.742 3.234 3.234 0 01-.658-1.155 4.767 4.767 0 01-.224-1.512c0-.588.082-1.11.245-1.568.163-.457.399-.84.707-1.148a3.08 3.08 0 011.12-.707 4.187 4.187 0 011.47-.245c.392 0 .78.051 1.162.154.383.103.721.296 1.015.581.294.285.52.677.679 1.176.159.5.215 1.146.168 1.939h-5.418c0 .84.226 1.468.679 1.883.453.415 1.057.623 1.813.623.252 0 .502-.03.749-.091.247-.06.483-.133.707-.217a3.72 3.72 0 00.595-.28c.173-.103.306-.196.399-.28l.434.798zm-2.954-5.362c-.308 0-.6.033-.875.098a1.995 1.995 0 00-.728.329c-.21.154-.383.355-.518.602s-.222.553-.259.917h4.354c-.047-.616-.245-1.094-.595-1.435-.35-.34-.81-.511-1.379-.511zm4.872 6.244v-.938h1.89v-5.124h-1.89v-.938h2.618l.224.91h.07c.317-.29.672-.537 1.064-.742.392-.205.859-.308 1.4-.308.317 0 .572.06.763.182.191.121.34.299.448.532.107.233.18.516.217.847.037.331.056.707.056 1.127l-.98.014c0-.597-.058-1.036-.175-1.316-.117-.28-.329-.42-.637-.42-.29 0-.55.042-.784.126a2.565 2.565 0 00-.609.308c-.173.121-.32.243-.441.364s-.21.224-.266.308v4.13h2.688v.938h-5.656zm7.91-7h1.666v-1.386l1.092-.308v1.694h3.738v.938h-3.738v3.304c0 .681.166 1.185.497 1.512.331.327.805.49 1.421.49.42 0 .786-.08 1.099-.238.313-.159.595-.331.847-.518l.364.826a3.938 3.938 0 01-1.169.63 4.182 4.182 0 01-1.393.238 3.41 3.41 0 01-1.057-.161 2.426 2.426 0 01-.875-.497 2.38 2.38 0 01-.602-.861c-.15-.35-.224-.768-.224-1.253v-3.472h-1.666v-.938z"/><path id="(" fill="#7E7C7B" d="M181.272 132.768a6.964 6.964 0 01-1.757-.707 5.036 5.036 0 01-1.428-1.225c-.406-.504-.728-1.12-.966-1.848s-.357-1.591-.357-2.59c0-.99.121-1.855.364-2.597s.57-1.372.98-1.89c.41-.518.889-.933 1.435-1.246a6.005 6.005 0 011.729-.665l.35.882a7.086 7.086 0 00-1.512.623 3.928 3.928 0 00-1.183 1.022c-.331.425-.588.952-.77 1.582-.182.63-.273 1.393-.273 2.289 0 .905.11 1.678.329 2.317.22.64.509 1.171.868 1.596.36.425.76.756 1.204.994.443.238.889.404 1.337.497l-.35.966z"/><path id="i" fill="#181717" d="M185.094 129.8v-.938h2.436v-5.124h-2.436v-.938h3.556v6.062h2.38v.938h-5.936zm2.058-8.988c0-.252.084-.469.252-.651a.838.838 0 01.644-.273c.27 0 .497.091.679.273a.889.889 0 01.273.651.806.806 0 01-.273.616.963.963 0 01-.679.252.872.872 0 01-.644-.252.838.838 0 01-.252-.616z"/><path id=");}];" fill="#7E7C7B" d="M194.026 131.802a4.965 4.965 0 001.337-.497 4.15 4.15 0 001.204-.994c.36-.425.649-.957.868-1.596.22-.64.329-1.412.329-2.317 0-.896-.091-1.659-.273-2.289-.182-.63-.439-1.157-.77-1.582a3.928 3.928 0 00-1.183-1.022 7.086 7.086 0 00-1.512-.623l.35-.882c.607.13 1.183.352 1.729.665a4.984 4.984 0 011.435 1.246c.41.518.737 1.148.98 1.89s.364 1.608.364 2.597c0 .999-.119 1.862-.357 2.59-.238.728-.56 1.344-.966 1.848a5.036 5.036 0 01-1.428 1.225 6.964 6.964 0 01-1.757.707l-.35-.966zm9.604-2.772c0-.28.091-.506.273-.679.182-.173.418-.259.707-.259.355 0 .63.124.826.371.196.247.294.595.294 1.043a2.36 2.36 0 01-.637 1.659 2.465 2.465 0 01-.588.462c-.21.117-.404.203-.581.259l-.35-.546c.336-.13.625-.317.868-.56.243-.243.364-.537.364-.882-.13.028-.233.042-.308.042-.27 0-.483-.077-.637-.231-.154-.154-.231-.38-.231-.679zm.126-5.502c0-.299.084-.53.252-.693.168-.163.392-.245.672-.245.299 0 .532.082.7.245.168.163.252.394.252.693 0 .27-.084.495-.252.672-.168.177-.401.266-.7.266-.28 0-.504-.089-.672-.266a.938.938 0 01-.252-.672zm18.788 7.196c0 .756-.198 1.328-.595 1.715-.397.387-.922.581-1.575.581h-2.03v-.98h1.526c.57 0 .975-.135 1.218-.406.243-.27.364-.69.364-1.26v-1.344c0-.364.07-.695.21-.994.14-.299.308-.558.504-.777.196-.22.397-.392.602-.518.205-.126.373-.198.504-.217v-.084c-.13-.019-.299-.086-.504-.203a2.7 2.7 0 01-1.106-1.225c-.14-.299-.21-.64-.21-1.022v-1.358c0-.55-.114-.966-.343-1.246-.229-.28-.637-.42-1.225-.42h-1.54v-.98h2.03c.317 0 .609.058.875.175.266.117.495.278.686.483.191.205.34.448.448.728.107.28.161.588.161.924v1.428c0 .43.068.789.203 1.078.135.29.303.525.504.707.2.182.415.313.644.392.229.08.432.119.609.119v.98c-.177 0-.38.047-.609.14a2.011 2.011 0 00-.644.434 2.44 2.44 0 00-.504.735c-.135.294-.203.642-.203 1.043v1.372zM5.138 157.02H.35v-.98h3.696v-11.06H.35V144h4.788v13.02zm5.292-3.99c0-.28.091-.506.273-.679.182-.173.418-.259.707-.259.355 0 .63.124.826.371.196.247.294.595.294 1.043a2.36 2.36 0 01-.637 1.659 2.465 2.465 0 01-.588.462c-.21.117-.404.203-.581.259l-.35-.546c.336-.13.625-.317.868-.56.243-.243.364-.537.364-.882-.13.028-.233.042-.308.042-.27 0-.483-.077-.637-.231-.154-.154-.231-.38-.231-.679zm.126-5.502c0-.299.084-.53.252-.693.168-.163.392-.245.672-.245.299 0 .532.082.7.245.168.163.252.394.252.693 0 .27-.084.495-.252.672-.168.177-.401.266-.7.266-.28 0-.504-.089-.672-.266a.938.938 0 01-.252-.672z"/></g><g id="Group-Copy" transform="translate(366 66)"><path id="Line" fill="#C06334" fill-rule="nonzero" d="M16.5 15.5l14 7-14 7v-6h-14v-2h14v-6z"/><text id="outer" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="0" y="11">outer</tspan></text></g><g id="Group-Copy-2" fill="#C06334" fill-rule="nonzero" transform="translate(242 44)"><path id="Line" d="M13.5-5.5l14 7-14 7v-6h-14v-2h14v-6z"/></g><g id="Group-3" transform="translate(279 36)"><path id="Rectangle-1" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M1 1h75v18H1z"/><text id="&lt;empty&gt;" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="8" y="14">&lt;empty&gt;</tspan></text></g><g id="Group-Copy-3" fill="#C06334" fill-rule="nonzero" transform="translate(242 67)"><path id="Line" d="M13.5-5.5l14 7-14 7v-6h-14v-2h14v-6z"/></g><g id="Group-Copy-4" fill="#C06334" fill-rule="nonzero" transform="translate(242 90)"><path id="Line" d="M13.5-5.5l14 7-14 7v-6h-14v-2h14v-6z"/></g><g id="Group-Copy-5" fill="#C06334" fill-rule="nonzero" transform="translate(242 139)"><path id="Line" d="M13.5-5.5l14 7-14 7v-6h-14v-2h14v-6z"/></g><text id="makeArmy()-LexicalEn" fill="#AF6E24" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="415" y="59">makeArmy()</tspan>  <tspan x="415" y="74" font-family="PTMono-Regular, PT Mono" font-weight="normal">LexicalEnvironment</tspan></text><text id="while-iteration-Lexi" fill="#AF6E24" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="278" y="14">while iteration</tspan>  <tspan x="278" y="29" font-family="PTMono-Regular, PT Mono" font-weight="normal">LexicalEnvironment</tspan></text><g id="Group-3" transform="translate(279 59)"><path id="Rectangle-1" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M1 1h75v18H1z"/><text id="&lt;empty&gt;" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="8" y="14">&lt;empty&gt;</tspan></text></g><g id="Group-3" transform="translate(279 82)"><path id="Rectangle-1" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M1 1h75v18H1z"/><text id="&lt;empty&gt;" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="8" y="14">&lt;empty&gt;</tspan></text></g><g id="Group-3" transform="translate(279 131)"><path id="Rectangle-1" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M1 1h75v18H1z"/><text id="&lt;empty&gt;" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="8" y="14">&lt;empty&gt;</tspan></text></g><g id="Group-3" transform="translate(415 78)"><path id="Rectangle-1" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M1 1h53v18H1z"/><text id="i:-10" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="6" y="14">i: 10</tspan></text></g></g></g></svg>
\ No newline at end of file
diff --git a/1-js/06-advanced-functions/03-closure/10-make-army/lexenv-makearmy-for-fixed.svg b/1-js/06-advanced-functions/03-closure/10-make-army/lexenv-makearmy-for-fixed.svg
new file mode 100644
index 000000000..7611d0ef8
--- /dev/null
+++ b/1-js/06-advanced-functions/03-closure/10-make-army/lexenv-makearmy-for-fixed.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="566" height="183" viewBox="0 0 566 183"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:&apos;PT Mono&apos;;font-weight:700;font-style:normal;src:local(&apos;PT MonoBold&apos;),url(/font/PTMonoBold.woff2) format(&apos;woff2&apos;),url(/font/PTMonoBold.woff) format(&apos;woff&apos;),url(/font/PTMonoBold.ttf) format(&apos;truetype&apos;)}</style></defs><g id="closure" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="lexenv-makearmy-for-fixed.svg"><g id="shooters-=-[" fill-rule="nonzero" transform="translate(6.176 15.2)"><path id="shooters" fill="#181717" d="M4.956 7.91a.796.796 0 00-.35-.693 2.872 2.872 0 00-.868-.392 16.056 16.056 0 00-1.127-.273 6.502 6.502 0 01-1.127-.336 2.525 2.525 0 01-.868-.567c-.233-.238-.35-.572-.35-1.001 0-.355.077-.658.231-.91a1.94 1.94 0 01.609-.623c.252-.163.546-.285.882-.364.336-.08.686-.119 1.05-.119.653 0 1.216.082 1.687.245.471.163.847.334 1.127.511l-.448.882a11.79 11.79 0 00-1.001-.483c-.36-.154-.81-.231-1.351-.231-.205 0-.408.021-.609.063-.2.042-.383.105-.546.189a1.088 1.088 0 00-.392.329.825.825 0 00-.147.497c0 .243.117.43.35.56.233.13.523.24.868.329.345.089.721.173 1.127.252.406.08.782.194 1.127.343.345.15.635.35.868.602.233.252.35.593.35 1.022 0 .644-.254 1.176-.763 1.596-.509.42-1.272.63-2.289.63-.308 0-.611-.028-.91-.084a5.52 5.52 0 01-.84-.224 5.054 5.054 0 01-.714-.315A3.002 3.002 0 010 8.988l.56-.91c.112.112.261.226.448.343a4.229 4.229 0 001.337.539 3.76 3.76 0 001.484.021c.22-.042.413-.107.581-.196a1.08 1.08 0 00.399-.35.914.914 0 00.147-.525zM7.28 0h2.184v3.668h.07c.29-.327.625-.581 1.008-.763.383-.182.859-.273 1.428-.273.448 0 .838.047 1.169.14.331.093.602.257.812.49.21.233.366.553.469.959.103.406.154.922.154 1.547V9.8h-1.092V5.978c0-.401-.023-.751-.07-1.05a1.829 1.829 0 00-.273-.749c-.135-.2-.32-.352-.553-.455-.233-.103-.532-.154-.896-.154-.252 0-.5.044-.742.133-.243.089-.464.21-.665.364-.2.154-.373.34-.518.56-.145.22-.245.46-.301.721V9.8H8.386V.938H7.28V0zm9.142 6.3c0-1.13.294-2.023.882-2.681.588-.658 1.428-.987 2.52-.987.588 0 1.094.096 1.519.287.425.191.777.45 1.057.777.28.327.488.714.623 1.162.135.448.203.929.203 1.442 0 .56-.075 1.066-.224 1.519-.15.453-.369.838-.658 1.155-.29.317-.646.562-1.071.735a3.82 3.82 0 01-1.449.259c-.579 0-1.083-.096-1.512-.287a2.967 2.967 0 01-1.064-.777 3.168 3.168 0 01-.623-1.162 4.963 4.963 0 01-.203-1.442zm1.162 0c0 .327.04.653.119.98.08.327.208.62.385.882.177.261.408.471.693.63.285.159.632.238 1.043.238.747 0 1.309-.231 1.687-.693.378-.462.567-1.141.567-2.037 0-.336-.04-.665-.119-.987a2.608 2.608 0 00-.392-.875 2.066 2.066 0 00-.7-.63c-.285-.159-.632-.238-1.043-.238-.747 0-1.307.229-1.68.686-.373.457-.56 1.139-.56 2.044zm7.238 0c0-1.13.294-2.023.882-2.681.588-.658 1.428-.987 2.52-.987.588 0 1.094.096 1.519.287.425.191.777.45 1.057.777.28.327.488.714.623 1.162.135.448.203.929.203 1.442 0 .56-.075 1.066-.224 1.519-.15.453-.369.838-.658 1.155-.29.317-.646.562-1.071.735a3.82 3.82 0 01-1.449.259c-.579 0-1.083-.096-1.512-.287a2.967 2.967 0 01-1.064-.777 3.168 3.168 0 01-.623-1.162 4.963 4.963 0 01-.203-1.442zm1.162 0c0 .327.04.653.119.98.08.327.208.62.385.882.177.261.408.471.693.63.285.159.632.238 1.043.238.747 0 1.309-.231 1.687-.693.378-.462.567-1.141.567-2.037 0-.336-.04-.665-.119-.987a2.608 2.608 0 00-.392-.875 2.066 2.066 0 00-.7-.63c-.285-.159-.632-.238-1.043-.238-.747 0-1.307.229-1.68.686-.373.457-.56 1.139-.56 2.044zm6.874-3.5h1.666V1.414l1.092-.308V2.8h3.738v.938h-3.738v3.304c0 .681.166 1.185.497 1.512.331.327.805.49 1.421.49.42 0 .786-.08 1.099-.238.313-.159.595-.331.847-.518l.364.826a3.938 3.938 0 01-1.169.63 4.182 4.182 0 01-1.393.238 3.41 3.41 0 01-1.057-.161 2.426 2.426 0 01-.875-.497 2.38 2.38 0 01-.602-.861c-.15-.35-.224-.768-.224-1.253V3.738h-1.666V2.8zM48.23 8.918c-.168.15-.366.29-.595.42a4.39 4.39 0 01-.749.336c-.27.093-.553.166-.847.217-.294.051-.59.077-.889.077-.56 0-1.055-.086-1.484-.259a2.858 2.858 0 01-1.078-.742 3.234 3.234 0 01-.658-1.155 4.767 4.767 0 01-.224-1.512c0-.588.082-1.11.245-1.568.163-.457.399-.84.707-1.148a3.08 3.08 0 011.12-.707 4.187 4.187 0 011.47-.245c.392 0 .78.051 1.162.154.383.103.721.296 1.015.581.294.285.52.677.679 1.176.159.5.215 1.146.168 1.939h-5.418c0 .84.226 1.468.679 1.883.453.415 1.057.623 1.813.623.252 0 .502-.03.749-.091.247-.06.483-.133.707-.217a3.72 3.72 0 00.595-.28c.173-.103.306-.196.399-.28l.434.798zm-2.954-5.362c-.308 0-.6.033-.875.098a1.995 1.995 0 00-.728.329c-.21.154-.383.355-.518.602s-.222.553-.259.917h4.354c-.047-.616-.245-1.094-.595-1.435-.35-.34-.81-.511-1.379-.511zM50.148 9.8v-.938h1.89V3.738h-1.89V2.8h2.618l.224.91h.07c.317-.29.672-.537 1.064-.742.392-.205.859-.308 1.4-.308.317 0 .572.06.763.182.191.121.34.299.448.532.107.233.18.516.217.847.037.331.056.707.056 1.127l-.98.014c0-.597-.058-1.036-.175-1.316-.117-.28-.329-.42-.637-.42-.29 0-.55.042-.784.126a2.565 2.565 0 00-.609.308c-.173.121-.32.243-.441.364s-.21.224-.266.308v4.13h2.688V9.8h-5.656zm13.608-1.89a.796.796 0 00-.35-.693 2.872 2.872 0 00-.868-.392 16.056 16.056 0 00-1.127-.273 6.502 6.502 0 01-1.127-.336 2.525 2.525 0 01-.868-.567c-.233-.238-.35-.572-.35-1.001 0-.355.077-.658.231-.91a1.94 1.94 0 01.609-.623c.252-.163.546-.285.882-.364.336-.08.686-.119 1.05-.119.653 0 1.216.082 1.687.245.471.163.847.334 1.127.511l-.448.882a11.79 11.79 0 00-1.001-.483c-.36-.154-.81-.231-1.351-.231-.205 0-.408.021-.609.063-.2.042-.383.105-.546.189a1.088 1.088 0 00-.392.329.825.825 0 00-.147.497c0 .243.117.43.35.56.233.13.523.24.868.329.345.089.721.173 1.127.252.406.08.782.194 1.127.343.345.15.635.35.868.602.233.252.35.593.35 1.022 0 .644-.254 1.176-.763 1.596-.509.42-1.272.63-2.289.63-.308 0-.611-.028-.91-.084a5.52 5.52 0 01-.84-.224 5.054 5.054 0 01-.714-.315 3.002 3.002 0 01-.532-.357l.56-.91c.112.112.261.226.448.343a4.229 4.229 0 001.337.539 3.76 3.76 0 001.484.021c.22-.042.413-.107.581-.196a1.08 1.08 0 00.399-.35.914.914 0 00.147-.525z"/><path id="=" fill="#DBAF88" d="M75.376 3.402h6.496V4.41h-6.496V3.402zm0 2.296h6.496v1.008h-6.496V5.698z"/><path id="[" fill="#7E7C7B" d="M93.31 0h4.774v.98h-3.682v11.06h3.682v.98H93.31z"/><path id="function" fill="#1C85B5" d="M16.856 33.8v-.938h1.666v-5.124h-1.666V26.8h1.666v-.392c0-.877.229-1.512.686-1.904.457-.392 1.11-.588 1.96-.588.308 0 .583.019.826.056.243.037.504.112.784.224l-.252.91a2.862 2.862 0 00-.7-.203 4.295 4.295 0 00-.616-.049c-.616 0-1.036.152-1.26.455-.224.303-.336.8-.336 1.491h2.898v.938h-2.898v5.124h2.898v.938h-5.656zm12.25-7h1.988v4.774c0 .457.028.896.084 1.316h.938v.91h-1.862l-.042-1.19h-.056a2.938 2.938 0 01-.966.98c-.401.252-.887.378-1.456.378-.43 0-.796-.049-1.099-.147a1.556 1.556 0 01-.749-.511c-.196-.243-.34-.567-.434-.973-.093-.406-.14-.912-.14-1.519v-3.08h-.938V26.8h2.03v3.794c0 .383.016.726.049 1.029.033.303.1.56.203.77.103.21.254.369.455.476.2.107.469.161.805.161.485 0 .908-.159 1.267-.476.36-.317.632-.714.819-1.19v-3.626h-.896V26.8zm4.62 2.45a14.05 14.05 0 00-.063-1.176 4.657 4.657 0 00-.049-.364h-.938v-.91h1.876l.126 1.134h.07c.093-.159.217-.315.371-.469a2.91 2.91 0 011.225-.721c.252-.075.518-.112.798-.112.43 0 .81.047 1.141.14.331.093.607.259.826.497.22.238.385.56.497.966.112.406.168.922.168 1.547V33.8h-1.092v-3.808c0-.775-.126-1.358-.378-1.75-.252-.392-.71-.588-1.372-.588-.243 0-.478.049-.707.147a2.44 2.44 0 00-.623.385c-.187.159-.35.343-.49.553-.14.21-.243.432-.308.665V33.8h-1.078v-4.55zm13.244-1.372a5.531 5.531 0 00-.693-.189 3.61 3.61 0 00-.735-.077c-.915 0-1.596.215-2.044.644-.448.43-.672 1.11-.672 2.044 0 .41.065.777.196 1.099.13.322.317.595.56.819.243.224.534.397.875.518.34.121.716.182 1.127.182.439 0 .866-.075 1.281-.224.415-.15.763-.345 1.043-.588l.49.812c-.13.112-.294.229-.49.35a4.837 4.837 0 01-1.533.602 4.962 4.962 0 01-1.015.098c-.607 0-1.141-.086-1.603-.259a3.045 3.045 0 01-1.155-.742 3.176 3.176 0 01-.7-1.162 4.525 4.525 0 01-.238-1.505c0-.588.082-1.11.245-1.568.163-.457.399-.84.707-1.148a3.08 3.08 0 011.12-.707 4.187 4.187 0 011.47-.245c.69 0 1.253.06 1.687.182.434.121.8.257 1.099.406l-.014.042v1.946H46.97v-1.33zm2.688-1.078h1.666v-1.386l1.092-.308V26.8h3.738v.938h-3.738v3.304c0 .681.166 1.185.497 1.512.331.327.805.49 1.421.49.42 0 .786-.08 1.099-.238.313-.159.595-.331.847-.518l.364.826a3.938 3.938 0 01-1.169.63 4.182 4.182 0 01-1.393.238 3.41 3.41 0 01-1.057-.161 2.426 2.426 0 01-.875-.497 2.38 2.38 0 01-.602-.861c-.15-.35-.224-.768-.224-1.253v-3.472h-1.666V26.8zm9.436 7v-.938h2.436v-5.124h-2.436V26.8h3.556v6.062h2.38v.938h-5.936zm2.058-8.988c0-.252.084-.469.252-.651a.838.838 0 01.644-.273c.27 0 .497.091.679.273a.889.889 0 01.273.651.806.806 0 01-.273.616.963.963 0 01-.679.252.872.872 0 01-.644-.252.838.838 0 01-.252-.616zm5.67 5.488c0-1.13.294-2.023.882-2.681.588-.658 1.428-.987 2.52-.987.588 0 1.094.096 1.519.287.425.191.777.45 1.057.777.28.327.488.714.623 1.162.135.448.203.929.203 1.442 0 .56-.075 1.066-.224 1.519-.15.453-.369.838-.658 1.155-.29.317-.646.562-1.071.735a3.82 3.82 0 01-1.449.259c-.579 0-1.083-.096-1.512-.287a2.967 2.967 0 01-1.064-.777 3.168 3.168 0 01-.623-1.162 4.963 4.963 0 01-.203-1.442zm1.162 0c0 .327.04.653.119.98.08.327.208.62.385.882.177.261.408.471.693.63.285.159.632.238 1.043.238.747 0 1.309-.231 1.687-.693.378-.462.567-1.141.567-2.037 0-.336-.04-.665-.119-.987a2.608 2.608 0 00-.392-.875 2.066 2.066 0 00-.7-.63c-.285-.159-.632-.238-1.043-.238-.747 0-1.307.229-1.68.686-.373.457-.56 1.139-.56 2.044zm7.742-1.05a14.05 14.05 0 00-.063-1.176 4.657 4.657 0 00-.049-.364h-.938v-.91h1.876l.126 1.134h.07c.093-.159.217-.315.371-.469a2.91 2.91 0 011.225-.721c.252-.075.518-.112.798-.112.43 0 .81.047 1.141.14.331.093.607.259.826.497.22.238.385.56.497.966.112.406.168.922.168 1.547V33.8h-1.092v-3.808c0-.775-.126-1.358-.378-1.75-.252-.392-.71-.588-1.372-.588-.243 0-.478.049-.707.147a2.44 2.44 0 00-.623.385c-.187.159-.35.343-.49.553-.14.21-.243.432-.308.665V33.8h-1.078v-4.55z"/><path id="(){" fill="#7E7C7B" d="M97.272 36.768a6.964 6.964 0 01-1.757-.707 5.036 5.036 0 01-1.428-1.225c-.406-.504-.728-1.12-.966-1.848s-.357-1.591-.357-2.59c0-.99.121-1.855.364-2.597s.57-1.372.98-1.89c.41-.518.889-.933 1.435-1.246A6.005 6.005 0 0197.272 24l.35.882a7.086 7.086 0 00-1.512.623 3.928 3.928 0 00-1.183 1.022c-.331.425-.588.952-.77 1.582-.182.63-.273 1.393-.273 2.289 0 .905.11 1.678.329 2.317.22.64.509 1.171.868 1.596.36.425.76.756 1.204.994.443.238.889.404 1.337.497l-.35.966zm4.354-.966a4.965 4.965 0 001.337-.497 4.15 4.15 0 001.204-.994c.36-.425.649-.957.868-1.596.22-.64.329-1.412.329-2.317 0-.896-.091-1.659-.273-2.289-.182-.63-.439-1.157-.77-1.582a3.928 3.928 0 00-1.183-1.022 7.086 7.086 0 00-1.512-.623l.35-.882c.607.13 1.183.352 1.729.665a4.984 4.984 0 011.435 1.246c.41.518.737 1.148.98 1.89s.364 1.608.364 2.597c0 .999-.119 1.862-.357 2.59-.238.728-.56 1.344-.966 1.848a5.036 5.036 0 01-1.428 1.225 6.964 6.964 0 01-1.757.707l-.35-.966zm17.878-2.45c0-.401-.068-.749-.203-1.043a2.44 2.44 0 00-.504-.735c-.2-.196-.415-.34-.644-.434a1.641 1.641 0 00-.609-.14v-.98c.177 0 .38-.04.609-.119.229-.08.443-.21.644-.392.2-.182.369-.418.504-.707.135-.29.203-.649.203-1.078v-1.428c0-.336.054-.644.161-.924a2.22 2.22 0 01.448-.728c.191-.205.42-.366.686-.483.266-.117.558-.175.875-.175h2.03v.98h-1.54c-.588 0-.996.14-1.225.42-.229.28-.343.695-.343 1.246v1.358c0 .383-.07.723-.21 1.022a2.7 2.7 0 01-1.106 1.225c-.205.117-.373.184-.504.203v.084c.121.019.285.091.49.217.205.126.406.299.602.518.196.22.366.478.511.777.145.299.217.63.217.994v1.344c0 .57.121.99.364 1.26s.649.406 1.218.406h1.526v.98h-2.03c-.653 0-1.178-.194-1.575-.581-.397-.387-.595-.959-.595-1.715v-1.372z"/><path id="alert" fill="#181717" d="M134.736 27.346a4.447 4.447 0 011.358-.504 7.423 7.423 0 011.484-.154c.476 0 .866.075 1.169.224.303.15.541.343.714.581.173.238.29.509.35.812.06.303.091.609.091.917 0 .355-.01.733-.028 1.134-.019.401-.033.803-.042 1.204 0 .467.028.91.084 1.33h.938v.91h-1.862l-.126-1.05h-.07c-.056.084-.14.191-.252.322-.112.13-.259.259-.441.385a2.749 2.749 0 01-1.589.469c-.69 0-1.237-.177-1.638-.532-.401-.355-.602-.84-.602-1.456 0-.476.105-.873.315-1.19.21-.317.511-.56.903-.728.392-.168.866-.266 1.421-.294a9.544 9.544 0 011.869.112c.047-.43.054-.786.021-1.071-.033-.285-.107-.511-.224-.679a.938.938 0 00-.49-.357 2.482 2.482 0 00-.777-.105c-.42 0-.821.058-1.204.175-.383.117-.723.236-1.022.357l-.35-.812zm2.058 5.642c.261 0 .504-.042.728-.126a2.22 2.22 0 00.588-.322 2.133 2.133 0 00.672-.868v-.98a7.92 7.92 0 00-1.344-.126c-.41 0-.765.044-1.064.133-.299.089-.532.226-.7.413-.168.187-.252.43-.252.728 0 .308.105.576.315.805.21.229.562.343 1.057.343zM143.29 24h2.324v7.448c0 .57.096.97.287 1.204.191.233.474.35.847.35.261 0 .511-.047.749-.14.238-.093.502-.252.791-.476l.504.77c-.15.13-.313.247-.49.35a3.638 3.638 0 01-1.106.42 2.963 2.963 0 01-1.442-.077 1.579 1.579 0 01-.679-.427 1.897 1.897 0 01-.413-.777c-.093-.322-.14-.721-.14-1.197v-6.51h-1.232V24zm14.14 8.918c-.168.15-.366.29-.595.42a4.39 4.39 0 01-.749.336c-.27.093-.553.166-.847.217-.294.051-.59.077-.889.077-.56 0-1.055-.086-1.484-.259a2.858 2.858 0 01-1.078-.742 3.234 3.234 0 01-.658-1.155 4.767 4.767 0 01-.224-1.512c0-.588.082-1.11.245-1.568.163-.457.399-.84.707-1.148a3.08 3.08 0 011.12-.707 4.187 4.187 0 011.47-.245c.392 0 .78.051 1.162.154.383.103.721.296 1.015.581.294.285.52.677.679 1.176.159.5.215 1.146.168 1.939h-5.418c0 .84.226 1.468.679 1.883.453.415 1.057.623 1.813.623.252 0 .502-.03.749-.091.247-.06.483-.133.707-.217a3.72 3.72 0 00.595-.28c.173-.103.306-.196.399-.28l.434.798zm-2.954-5.362c-.308 0-.6.033-.875.098a1.995 1.995 0 00-.728.329c-.21.154-.383.355-.518.602s-.222.553-.259.917h4.354c-.047-.616-.245-1.094-.595-1.435-.35-.34-.81-.511-1.379-.511zm4.872 6.244v-.938h1.89v-5.124h-1.89V26.8h2.618l.224.91h.07c.317-.29.672-.537 1.064-.742.392-.205.859-.308 1.4-.308.317 0 .572.06.763.182.191.121.34.299.448.532.107.233.18.516.217.847.037.331.056.707.056 1.127l-.98.014c0-.597-.058-1.036-.175-1.316-.117-.28-.329-.42-.637-.42-.29 0-.55.042-.784.126a2.565 2.565 0 00-.609.308c-.173.121-.32.243-.441.364s-.21.224-.266.308v4.13h2.688v.938h-5.656zm7.91-7h1.666v-1.386l1.092-.308V26.8h3.738v.938h-3.738v3.304c0 .681.166 1.185.497 1.512.331.327.805.49 1.421.49.42 0 .786-.08 1.099-.238.313-.159.595-.331.847-.518l.364.826a3.938 3.938 0 01-1.169.63 4.182 4.182 0 01-1.393.238 3.41 3.41 0 01-1.057-.161 2.426 2.426 0 01-.875-.497 2.38 2.38 0 01-.602-.861c-.15-.35-.224-.768-.224-1.253v-3.472h-1.666V26.8z"/><path id="(" fill="#7E7C7B" d="M181.272 36.768a6.964 6.964 0 01-1.757-.707 5.036 5.036 0 01-1.428-1.225c-.406-.504-.728-1.12-.966-1.848s-.357-1.591-.357-2.59c0-.99.121-1.855.364-2.597s.57-1.372.98-1.89c.41-.518.889-.933 1.435-1.246a6.005 6.005 0 011.729-.665l.35.882a7.086 7.086 0 00-1.512.623 3.928 3.928 0 00-1.183 1.022c-.331.425-.588.952-.77 1.582-.182.63-.273 1.393-.273 2.289 0 .905.11 1.678.329 2.317.22.64.509 1.171.868 1.596.36.425.76.756 1.204.994.443.238.889.404 1.337.497l-.35.966z"/><path id="i" fill="#181717" d="M185.094 33.8v-.938h2.436v-5.124h-2.436V26.8h3.556v6.062h2.38v.938h-5.936zm2.058-8.988c0-.252.084-.469.252-.651a.838.838 0 01.644-.273c.27 0 .497.091.679.273a.889.889 0 01.273.651.806.806 0 01-.273.616.963.963 0 01-.679.252.872.872 0 01-.644-.252.838.838 0 01-.252-.616z"/><path id=");}," fill="#7E7C7B" d="M194.026 35.802a4.965 4.965 0 001.337-.497 4.15 4.15 0 001.204-.994c.36-.425.649-.957.868-1.596.22-.64.329-1.412.329-2.317 0-.896-.091-1.659-.273-2.289-.182-.63-.439-1.157-.77-1.582a3.928 3.928 0 00-1.183-1.022 7.086 7.086 0 00-1.512-.623l.35-.882c.607.13 1.183.352 1.729.665a4.984 4.984 0 011.435 1.246c.41.518.737 1.148.98 1.89s.364 1.608.364 2.597c0 .999-.119 1.862-.357 2.59-.238.728-.56 1.344-.966 1.848a5.036 5.036 0 01-1.428 1.225 6.964 6.964 0 01-1.757.707l-.35-.966zm9.604-2.772c0-.28.091-.506.273-.679.182-.173.418-.259.707-.259.355 0 .63.124.826.371.196.247.294.595.294 1.043a2.36 2.36 0 01-.637 1.659 2.465 2.465 0 01-.588.462c-.21.117-.404.203-.581.259l-.35-.546c.336-.13.625-.317.868-.56.243-.243.364-.537.364-.882-.13.028-.233.042-.308.042-.27 0-.483-.077-.637-.231-.154-.154-.231-.38-.231-.679zm.126-5.502c0-.299.084-.53.252-.693.168-.163.392-.245.672-.245.299 0 .532.082.7.245.168.163.252.394.252.693 0 .27-.084.495-.252.672-.168.177-.401.266-.7.266-.28 0-.504-.089-.672-.266a.938.938 0 01-.252-.672zm18.788 7.196c0 .756-.198 1.328-.595 1.715-.397.387-.922.581-1.575.581h-2.03v-.98h1.526c.57 0 .975-.135 1.218-.406.243-.27.364-.69.364-1.26V33.03c0-.364.07-.695.21-.994.14-.299.308-.558.504-.777.196-.22.397-.392.602-.518.205-.126.373-.198.504-.217v-.084c-.13-.019-.299-.086-.504-.203a2.7 2.7 0 01-1.106-1.225c-.14-.299-.21-.64-.21-1.022v-1.358c0-.55-.114-.966-.343-1.246-.229-.28-.637-.42-1.225-.42h-1.54v-.98h2.03c.317 0 .609.058.875.175.266.117.495.278.686.483.191.205.34.448.448.728.107.28.161.588.161.924v1.428c0 .43.068.789.203 1.078.135.29.303.525.504.707.2.182.415.313.644.392.229.08.432.119.609.119V31c-.177 0-.38.047-.609.14a2.011 2.011 0 00-.644.434 2.44 2.44 0 00-.504.735c-.135.294-.203.642-.203 1.043v1.372zm6.286-1.694c0-.28.091-.506.273-.679.182-.173.418-.259.707-.259.355 0 .63.124.826.371.196.247.294.595.294 1.043a2.36 2.36 0 01-.637 1.659 2.465 2.465 0 01-.588.462c-.21.117-.404.203-.581.259l-.35-.546c.336-.13.625-.317.868-.56.243-.243.364-.537.364-.882-.13.028-.233.042-.308.042-.27 0-.483-.077-.637-.231-.154-.154-.231-.38-.231-.679z"/><path id="function" fill="#1C85B5" d="M16.856 57.8v-.938h1.666v-5.124h-1.666V50.8h1.666v-.392c0-.877.229-1.512.686-1.904.457-.392 1.11-.588 1.96-.588.308 0 .583.019.826.056.243.037.504.112.784.224l-.252.91a2.862 2.862 0 00-.7-.203 4.295 4.295 0 00-.616-.049c-.616 0-1.036.152-1.26.455-.224.303-.336.8-.336 1.491h2.898v.938h-2.898v5.124h2.898v.938h-5.656zm12.25-7h1.988v4.774c0 .457.028.896.084 1.316h.938v.91h-1.862l-.042-1.19h-.056a2.938 2.938 0 01-.966.98c-.401.252-.887.378-1.456.378-.43 0-.796-.049-1.099-.147a1.556 1.556 0 01-.749-.511c-.196-.243-.34-.567-.434-.973-.093-.406-.14-.912-.14-1.519v-3.08h-.938V50.8h2.03v3.794c0 .383.016.726.049 1.029.033.303.1.56.203.77.103.21.254.369.455.476.2.107.469.161.805.161.485 0 .908-.159 1.267-.476.36-.317.632-.714.819-1.19v-3.626h-.896V50.8zm4.62 2.45a14.05 14.05 0 00-.063-1.176 4.657 4.657 0 00-.049-.364h-.938v-.91h1.876l.126 1.134h.07c.093-.159.217-.315.371-.469a2.91 2.91 0 011.225-.721c.252-.075.518-.112.798-.112.43 0 .81.047 1.141.14.331.093.607.259.826.497.22.238.385.56.497.966.112.406.168.922.168 1.547V57.8h-1.092v-3.808c0-.775-.126-1.358-.378-1.75-.252-.392-.71-.588-1.372-.588-.243 0-.478.049-.707.147a2.44 2.44 0 00-.623.385c-.187.159-.35.343-.49.553-.14.21-.243.432-.308.665V57.8h-1.078v-4.55zm13.244-1.372a5.531 5.531 0 00-.693-.189 3.61 3.61 0 00-.735-.077c-.915 0-1.596.215-2.044.644-.448.43-.672 1.11-.672 2.044 0 .41.065.777.196 1.099.13.322.317.595.56.819.243.224.534.397.875.518.34.121.716.182 1.127.182.439 0 .866-.075 1.281-.224.415-.15.763-.345 1.043-.588l.49.812c-.13.112-.294.229-.49.35a4.837 4.837 0 01-1.533.602 4.962 4.962 0 01-1.015.098c-.607 0-1.141-.086-1.603-.259a3.045 3.045 0 01-1.155-.742 3.176 3.176 0 01-.7-1.162 4.525 4.525 0 01-.238-1.505c0-.588.082-1.11.245-1.568.163-.457.399-.84.707-1.148a3.08 3.08 0 011.12-.707 4.187 4.187 0 011.47-.245c.69 0 1.253.06 1.687.182.434.121.8.257 1.099.406l-.014.042v1.946H46.97v-1.33zm2.688-1.078h1.666v-1.386l1.092-.308V50.8h3.738v.938h-3.738v3.304c0 .681.166 1.185.497 1.512.331.327.805.49 1.421.49.42 0 .786-.08 1.099-.238.313-.159.595-.331.847-.518l.364.826a3.938 3.938 0 01-1.169.63 4.182 4.182 0 01-1.393.238 3.41 3.41 0 01-1.057-.161 2.426 2.426 0 01-.875-.497 2.38 2.38 0 01-.602-.861c-.15-.35-.224-.768-.224-1.253v-3.472h-1.666V50.8zm9.436 7v-.938h2.436v-5.124h-2.436V50.8h3.556v6.062h2.38v.938h-5.936zm2.058-8.988c0-.252.084-.469.252-.651a.838.838 0 01.644-.273c.27 0 .497.091.679.273a.889.889 0 01.273.651.806.806 0 01-.273.616.963.963 0 01-.679.252.872.872 0 01-.644-.252.838.838 0 01-.252-.616zm5.67 5.488c0-1.13.294-2.023.882-2.681.588-.658 1.428-.987 2.52-.987.588 0 1.094.096 1.519.287.425.191.777.45 1.057.777.28.327.488.714.623 1.162.135.448.203.929.203 1.442 0 .56-.075 1.066-.224 1.519-.15.453-.369.838-.658 1.155-.29.317-.646.562-1.071.735a3.82 3.82 0 01-1.449.259c-.579 0-1.083-.096-1.512-.287a2.967 2.967 0 01-1.064-.777 3.168 3.168 0 01-.623-1.162 4.963 4.963 0 01-.203-1.442zm1.162 0c0 .327.04.653.119.98.08.327.208.62.385.882.177.261.408.471.693.63.285.159.632.238 1.043.238.747 0 1.309-.231 1.687-.693.378-.462.567-1.141.567-2.037 0-.336-.04-.665-.119-.987a2.608 2.608 0 00-.392-.875 2.066 2.066 0 00-.7-.63c-.285-.159-.632-.238-1.043-.238-.747 0-1.307.229-1.68.686-.373.457-.56 1.139-.56 2.044zm7.742-1.05a14.05 14.05 0 00-.063-1.176 4.657 4.657 0 00-.049-.364h-.938v-.91h1.876l.126 1.134h.07c.093-.159.217-.315.371-.469a2.91 2.91 0 011.225-.721c.252-.075.518-.112.798-.112.43 0 .81.047 1.141.14.331.093.607.259.826.497.22.238.385.56.497.966.112.406.168.922.168 1.547V57.8h-1.092v-3.808c0-.775-.126-1.358-.378-1.75-.252-.392-.71-.588-1.372-.588-.243 0-.478.049-.707.147a2.44 2.44 0 00-.623.385c-.187.159-.35.343-.49.553-.14.21-.243.432-.308.665V57.8h-1.078v-4.55z"/><path id="(){" fill="#7E7C7B" d="M97.272 60.768a6.964 6.964 0 01-1.757-.707 5.036 5.036 0 01-1.428-1.225c-.406-.504-.728-1.12-.966-1.848s-.357-1.591-.357-2.59c0-.99.121-1.855.364-2.597s.57-1.372.98-1.89c.41-.518.889-.933 1.435-1.246A6.005 6.005 0 0197.272 48l.35.882a7.086 7.086 0 00-1.512.623 3.928 3.928 0 00-1.183 1.022c-.331.425-.588.952-.77 1.582-.182.63-.273 1.393-.273 2.289 0 .905.11 1.678.329 2.317.22.64.509 1.171.868 1.596.36.425.76.756 1.204.994.443.238.889.404 1.337.497l-.35.966zm4.354-.966a4.965 4.965 0 001.337-.497 4.15 4.15 0 001.204-.994c.36-.425.649-.957.868-1.596.22-.64.329-1.412.329-2.317 0-.896-.091-1.659-.273-2.289-.182-.63-.439-1.157-.77-1.582a3.928 3.928 0 00-1.183-1.022 7.086 7.086 0 00-1.512-.623l.35-.882c.607.13 1.183.352 1.729.665a4.984 4.984 0 011.435 1.246c.41.518.737 1.148.98 1.89s.364 1.608.364 2.597c0 .999-.119 1.862-.357 2.59-.238.728-.56 1.344-.966 1.848a5.036 5.036 0 01-1.428 1.225 6.964 6.964 0 01-1.757.707l-.35-.966zm17.878-2.45c0-.401-.068-.749-.203-1.043a2.44 2.44 0 00-.504-.735c-.2-.196-.415-.34-.644-.434a1.641 1.641 0 00-.609-.14v-.98c.177 0 .38-.04.609-.119.229-.08.443-.21.644-.392.2-.182.369-.418.504-.707.135-.29.203-.649.203-1.078v-1.428c0-.336.054-.644.161-.924a2.22 2.22 0 01.448-.728c.191-.205.42-.366.686-.483.266-.117.558-.175.875-.175h2.03v.98h-1.54c-.588 0-.996.14-1.225.42-.229.28-.343.695-.343 1.246v1.358c0 .383-.07.723-.21 1.022a2.7 2.7 0 01-1.106 1.225c-.205.117-.373.184-.504.203v.084c.121.019.285.091.49.217.205.126.406.299.602.518.196.22.366.478.511.777.145.299.217.63.217.994v1.344c0 .57.121.99.364 1.26s.649.406 1.218.406h1.526v.98h-2.03c-.653 0-1.178-.194-1.575-.581-.397-.387-.595-.959-.595-1.715v-1.372z"/><path id="alert" fill="#181717" d="M134.736 51.346a4.447 4.447 0 011.358-.504 7.423 7.423 0 011.484-.154c.476 0 .866.075 1.169.224.303.15.541.343.714.581.173.238.29.509.35.812.06.303.091.609.091.917 0 .355-.01.733-.028 1.134-.019.401-.033.803-.042 1.204 0 .467.028.91.084 1.33h.938v.91h-1.862l-.126-1.05h-.07c-.056.084-.14.191-.252.322-.112.13-.259.259-.441.385a2.749 2.749 0 01-1.589.469c-.69 0-1.237-.177-1.638-.532-.401-.355-.602-.84-.602-1.456 0-.476.105-.873.315-1.19.21-.317.511-.56.903-.728.392-.168.866-.266 1.421-.294a9.544 9.544 0 011.869.112c.047-.43.054-.786.021-1.071-.033-.285-.107-.511-.224-.679a.938.938 0 00-.49-.357 2.482 2.482 0 00-.777-.105c-.42 0-.821.058-1.204.175-.383.117-.723.236-1.022.357l-.35-.812zm2.058 5.642c.261 0 .504-.042.728-.126a2.22 2.22 0 00.588-.322 2.133 2.133 0 00.672-.868v-.98a7.92 7.92 0 00-1.344-.126c-.41 0-.765.044-1.064.133-.299.089-.532.226-.7.413-.168.187-.252.43-.252.728 0 .308.105.576.315.805.21.229.562.343 1.057.343zM143.29 48h2.324v7.448c0 .57.096.97.287 1.204.191.233.474.35.847.35.261 0 .511-.047.749-.14.238-.093.502-.252.791-.476l.504.77c-.15.13-.313.247-.49.35a3.638 3.638 0 01-1.106.42 2.963 2.963 0 01-1.442-.077 1.579 1.579 0 01-.679-.427 1.897 1.897 0 01-.413-.777c-.093-.322-.14-.721-.14-1.197v-6.51h-1.232V48zm14.14 8.918c-.168.15-.366.29-.595.42a4.39 4.39 0 01-.749.336c-.27.093-.553.166-.847.217-.294.051-.59.077-.889.077-.56 0-1.055-.086-1.484-.259a2.858 2.858 0 01-1.078-.742 3.234 3.234 0 01-.658-1.155 4.767 4.767 0 01-.224-1.512c0-.588.082-1.11.245-1.568.163-.457.399-.84.707-1.148a3.08 3.08 0 011.12-.707 4.187 4.187 0 011.47-.245c.392 0 .78.051 1.162.154.383.103.721.296 1.015.581.294.285.52.677.679 1.176.159.5.215 1.146.168 1.939h-5.418c0 .84.226 1.468.679 1.883.453.415 1.057.623 1.813.623.252 0 .502-.03.749-.091.247-.06.483-.133.707-.217a3.72 3.72 0 00.595-.28c.173-.103.306-.196.399-.28l.434.798zm-2.954-5.362c-.308 0-.6.033-.875.098a1.995 1.995 0 00-.728.329c-.21.154-.383.355-.518.602s-.222.553-.259.917h4.354c-.047-.616-.245-1.094-.595-1.435-.35-.34-.81-.511-1.379-.511zm4.872 6.244v-.938h1.89v-5.124h-1.89V50.8h2.618l.224.91h.07c.317-.29.672-.537 1.064-.742.392-.205.859-.308 1.4-.308.317 0 .572.06.763.182.191.121.34.299.448.532.107.233.18.516.217.847.037.331.056.707.056 1.127l-.98.014c0-.597-.058-1.036-.175-1.316-.117-.28-.329-.42-.637-.42-.29 0-.55.042-.784.126a2.565 2.565 0 00-.609.308c-.173.121-.32.243-.441.364s-.21.224-.266.308v4.13h2.688v.938h-5.656zm7.91-7h1.666v-1.386l1.092-.308V50.8h3.738v.938h-3.738v3.304c0 .681.166 1.185.497 1.512.331.327.805.49 1.421.49.42 0 .786-.08 1.099-.238.313-.159.595-.331.847-.518l.364.826a3.938 3.938 0 01-1.169.63 4.182 4.182 0 01-1.393.238 3.41 3.41 0 01-1.057-.161 2.426 2.426 0 01-.875-.497 2.38 2.38 0 01-.602-.861c-.15-.35-.224-.768-.224-1.253v-3.472h-1.666V50.8z"/><path id="(" fill="#7E7C7B" d="M181.272 60.768a6.964 6.964 0 01-1.757-.707 5.036 5.036 0 01-1.428-1.225c-.406-.504-.728-1.12-.966-1.848s-.357-1.591-.357-2.59c0-.99.121-1.855.364-2.597s.57-1.372.98-1.89c.41-.518.889-.933 1.435-1.246a6.005 6.005 0 011.729-.665l.35.882a7.086 7.086 0 00-1.512.623 3.928 3.928 0 00-1.183 1.022c-.331.425-.588.952-.77 1.582-.182.63-.273 1.393-.273 2.289 0 .905.11 1.678.329 2.317.22.64.509 1.171.868 1.596.36.425.76.756 1.204.994.443.238.889.404 1.337.497l-.35.966z"/><path id="i" fill="#181717" d="M185.094 57.8v-.938h2.436v-5.124h-2.436V50.8h3.556v6.062h2.38v.938h-5.936zm2.058-8.988c0-.252.084-.469.252-.651a.838.838 0 01.644-.273c.27 0 .497.091.679.273a.889.889 0 01.273.651.806.806 0 01-.273.616.963.963 0 01-.679.252.872.872 0 01-.644-.252.838.838 0 01-.252-.616z"/><path id=");}," fill="#7E7C7B" d="M194.026 59.802a4.965 4.965 0 001.337-.497 4.15 4.15 0 001.204-.994c.36-.425.649-.957.868-1.596.22-.64.329-1.412.329-2.317 0-.896-.091-1.659-.273-2.289-.182-.63-.439-1.157-.77-1.582a3.928 3.928 0 00-1.183-1.022 7.086 7.086 0 00-1.512-.623l.35-.882c.607.13 1.183.352 1.729.665a4.984 4.984 0 011.435 1.246c.41.518.737 1.148.98 1.89s.364 1.608.364 2.597c0 .999-.119 1.862-.357 2.59-.238.728-.56 1.344-.966 1.848a5.036 5.036 0 01-1.428 1.225 6.964 6.964 0 01-1.757.707l-.35-.966zm9.604-2.772c0-.28.091-.506.273-.679.182-.173.418-.259.707-.259.355 0 .63.124.826.371.196.247.294.595.294 1.043a2.36 2.36 0 01-.637 1.659 2.465 2.465 0 01-.588.462c-.21.117-.404.203-.581.259l-.35-.546c.336-.13.625-.317.868-.56.243-.243.364-.537.364-.882-.13.028-.233.042-.308.042-.27 0-.483-.077-.637-.231-.154-.154-.231-.38-.231-.679zm.126-5.502c0-.299.084-.53.252-.693.168-.163.392-.245.672-.245.299 0 .532.082.7.245.168.163.252.394.252.693 0 .27-.084.495-.252.672-.168.177-.401.266-.7.266-.28 0-.504-.089-.672-.266a.938.938 0 01-.252-.672zm18.788 7.196c0 .756-.198 1.328-.595 1.715-.397.387-.922.581-1.575.581h-2.03v-.98h1.526c.57 0 .975-.135 1.218-.406.243-.27.364-.69.364-1.26V57.03c0-.364.07-.695.21-.994.14-.299.308-.558.504-.777.196-.22.397-.392.602-.518.205-.126.373-.198.504-.217v-.084c-.13-.019-.299-.086-.504-.203a2.7 2.7 0 01-1.106-1.225c-.14-.299-.21-.64-.21-1.022v-1.358c0-.55-.114-.966-.343-1.246-.229-.28-.637-.42-1.225-.42h-1.54v-.98h2.03c.317 0 .609.058.875.175.266.117.495.278.686.483.191.205.34.448.448.728.107.28.161.588.161.924v1.428c0 .43.068.789.203 1.078.135.29.303.525.504.707.2.182.415.313.644.392.229.08.432.119.609.119V55c-.177 0-.38.047-.609.14a2.011 2.011 0 00-.644.434 2.44 2.44 0 00-.504.735c-.135.294-.203.642-.203 1.043v1.372zm6.286-1.694c0-.28.091-.506.273-.679.182-.173.418-.259.707-.259.355 0 .63.124.826.371.196.247.294.595.294 1.043a2.36 2.36 0 01-.637 1.659 2.465 2.465 0 01-.588.462c-.21.117-.404.203-.581.259l-.35-.546c.336-.13.625-.317.868-.56.243-.243.364-.537.364-.882-.13.028-.233.042-.308.042-.27 0-.483-.077-.637-.231-.154-.154-.231-.38-.231-.679z"/><path id="function" fill="#1C85B5" d="M16.856 81.8v-.938h1.666v-5.124h-1.666V74.8h1.666v-.392c0-.877.229-1.512.686-1.904.457-.392 1.11-.588 1.96-.588.308 0 .583.019.826.056.243.037.504.112.784.224l-.252.91a2.862 2.862 0 00-.7-.203 4.295 4.295 0 00-.616-.049c-.616 0-1.036.152-1.26.455-.224.303-.336.8-.336 1.491h2.898v.938h-2.898v5.124h2.898v.938h-5.656zm12.25-7h1.988v4.774c0 .457.028.896.084 1.316h.938v.91h-1.862l-.042-1.19h-.056a2.938 2.938 0 01-.966.98c-.401.252-.887.378-1.456.378-.43 0-.796-.049-1.099-.147a1.556 1.556 0 01-.749-.511c-.196-.243-.34-.567-.434-.973-.093-.406-.14-.912-.14-1.519v-3.08h-.938V74.8h2.03v3.794c0 .383.016.726.049 1.029.033.303.1.56.203.77.103.21.254.369.455.476.2.107.469.161.805.161.485 0 .908-.159 1.267-.476.36-.317.632-.714.819-1.19v-3.626h-.896V74.8zm4.62 2.45a14.05 14.05 0 00-.063-1.176 4.657 4.657 0 00-.049-.364h-.938v-.91h1.876l.126 1.134h.07c.093-.159.217-.315.371-.469a2.91 2.91 0 011.225-.721c.252-.075.518-.112.798-.112.43 0 .81.047 1.141.14.331.093.607.259.826.497.22.238.385.56.497.966.112.406.168.922.168 1.547V81.8h-1.092v-3.808c0-.775-.126-1.358-.378-1.75-.252-.392-.71-.588-1.372-.588-.243 0-.478.049-.707.147a2.44 2.44 0 00-.623.385c-.187.159-.35.343-.49.553-.14.21-.243.432-.308.665V81.8h-1.078v-4.55zm13.244-1.372a5.531 5.531 0 00-.693-.189 3.61 3.61 0 00-.735-.077c-.915 0-1.596.215-2.044.644-.448.43-.672 1.11-.672 2.044 0 .41.065.777.196 1.099.13.322.317.595.56.819.243.224.534.397.875.518.34.121.716.182 1.127.182.439 0 .866-.075 1.281-.224.415-.15.763-.345 1.043-.588l.49.812c-.13.112-.294.229-.49.35a4.837 4.837 0 01-1.533.602 4.962 4.962 0 01-1.015.098c-.607 0-1.141-.086-1.603-.259a3.045 3.045 0 01-1.155-.742 3.176 3.176 0 01-.7-1.162 4.525 4.525 0 01-.238-1.505c0-.588.082-1.11.245-1.568.163-.457.399-.84.707-1.148a3.08 3.08 0 011.12-.707 4.187 4.187 0 011.47-.245c.69 0 1.253.06 1.687.182.434.121.8.257 1.099.406l-.014.042v1.946H46.97v-1.33zm2.688-1.078h1.666v-1.386l1.092-.308V74.8h3.738v.938h-3.738v3.304c0 .681.166 1.185.497 1.512.331.327.805.49 1.421.49.42 0 .786-.08 1.099-.238.313-.159.595-.331.847-.518l.364.826a3.938 3.938 0 01-1.169.63 4.182 4.182 0 01-1.393.238 3.41 3.41 0 01-1.057-.161 2.426 2.426 0 01-.875-.497 2.38 2.38 0 01-.602-.861c-.15-.35-.224-.768-.224-1.253v-3.472h-1.666V74.8zm9.436 7v-.938h2.436v-5.124h-2.436V74.8h3.556v6.062h2.38v.938h-5.936zm2.058-8.988c0-.252.084-.469.252-.651a.838.838 0 01.644-.273c.27 0 .497.091.679.273a.889.889 0 01.273.651.806.806 0 01-.273.616.963.963 0 01-.679.252.872.872 0 01-.644-.252.838.838 0 01-.252-.616zm5.67 5.488c0-1.13.294-2.023.882-2.681.588-.658 1.428-.987 2.52-.987.588 0 1.094.096 1.519.287.425.191.777.45 1.057.777.28.327.488.714.623 1.162.135.448.203.929.203 1.442 0 .56-.075 1.066-.224 1.519-.15.453-.369.838-.658 1.155-.29.317-.646.562-1.071.735a3.82 3.82 0 01-1.449.259c-.579 0-1.083-.096-1.512-.287a2.967 2.967 0 01-1.064-.777 3.168 3.168 0 01-.623-1.162 4.963 4.963 0 01-.203-1.442zm1.162 0c0 .327.04.653.119.98.08.327.208.62.385.882.177.261.408.471.693.63.285.159.632.238 1.043.238.747 0 1.309-.231 1.687-.693.378-.462.567-1.141.567-2.037 0-.336-.04-.665-.119-.987a2.608 2.608 0 00-.392-.875 2.066 2.066 0 00-.7-.63c-.285-.159-.632-.238-1.043-.238-.747 0-1.307.229-1.68.686-.373.457-.56 1.139-.56 2.044zm7.742-1.05a14.05 14.05 0 00-.063-1.176 4.657 4.657 0 00-.049-.364h-.938v-.91h1.876l.126 1.134h.07c.093-.159.217-.315.371-.469a2.91 2.91 0 011.225-.721c.252-.075.518-.112.798-.112.43 0 .81.047 1.141.14.331.093.607.259.826.497.22.238.385.56.497.966.112.406.168.922.168 1.547V81.8h-1.092v-3.808c0-.775-.126-1.358-.378-1.75-.252-.392-.71-.588-1.372-.588-.243 0-.478.049-.707.147a2.44 2.44 0 00-.623.385c-.187.159-.35.343-.49.553-.14.21-.243.432-.308.665V81.8h-1.078v-4.55z"/><path id="(){" fill="#7E7C7B" d="M97.272 84.768a6.964 6.964 0 01-1.757-.707 5.036 5.036 0 01-1.428-1.225c-.406-.504-.728-1.12-.966-1.848s-.357-1.591-.357-2.59c0-.99.121-1.855.364-2.597s.57-1.372.98-1.89c.41-.518.889-.933 1.435-1.246A6.005 6.005 0 0197.272 72l.35.882a7.086 7.086 0 00-1.512.623 3.928 3.928 0 00-1.183 1.022c-.331.425-.588.952-.77 1.582-.182.63-.273 1.393-.273 2.289 0 .905.11 1.678.329 2.317.22.64.509 1.171.868 1.596.36.425.76.756 1.204.994.443.238.889.404 1.337.497l-.35.966zm4.354-.966a4.965 4.965 0 001.337-.497 4.15 4.15 0 001.204-.994c.36-.425.649-.957.868-1.596.22-.64.329-1.412.329-2.317 0-.896-.091-1.659-.273-2.289-.182-.63-.439-1.157-.77-1.582a3.928 3.928 0 00-1.183-1.022 7.086 7.086 0 00-1.512-.623l.35-.882c.607.13 1.183.352 1.729.665a4.984 4.984 0 011.435 1.246c.41.518.737 1.148.98 1.89s.364 1.608.364 2.597c0 .999-.119 1.862-.357 2.59-.238.728-.56 1.344-.966 1.848a5.036 5.036 0 01-1.428 1.225 6.964 6.964 0 01-1.757.707l-.35-.966zm17.878-2.45c0-.401-.068-.749-.203-1.043a2.44 2.44 0 00-.504-.735c-.2-.196-.415-.34-.644-.434a1.641 1.641 0 00-.609-.14v-.98c.177 0 .38-.04.609-.119.229-.08.443-.21.644-.392.2-.182.369-.418.504-.707.135-.29.203-.649.203-1.078v-1.428c0-.336.054-.644.161-.924a2.22 2.22 0 01.448-.728c.191-.205.42-.366.686-.483.266-.117.558-.175.875-.175h2.03v.98h-1.54c-.588 0-.996.14-1.225.42-.229.28-.343.695-.343 1.246v1.358c0 .383-.07.723-.21 1.022a2.7 2.7 0 01-1.106 1.225c-.205.117-.373.184-.504.203v.084c.121.019.285.091.49.217.205.126.406.299.602.518.196.22.366.478.511.777.145.299.217.63.217.994v1.344c0 .57.121.99.364 1.26s.649.406 1.218.406h1.526v.98h-2.03c-.653 0-1.178-.194-1.575-.581-.397-.387-.595-.959-.595-1.715v-1.372z"/><path id="alert" fill="#181717" d="M134.736 75.346a4.447 4.447 0 011.358-.504 7.423 7.423 0 011.484-.154c.476 0 .866.075 1.169.224.303.15.541.343.714.581.173.238.29.509.35.812.06.303.091.609.091.917 0 .355-.01.733-.028 1.134-.019.401-.033.803-.042 1.204 0 .467.028.91.084 1.33h.938v.91h-1.862l-.126-1.05h-.07c-.056.084-.14.191-.252.322-.112.13-.259.259-.441.385a2.749 2.749 0 01-1.589.469c-.69 0-1.237-.177-1.638-.532-.401-.355-.602-.84-.602-1.456 0-.476.105-.873.315-1.19.21-.317.511-.56.903-.728.392-.168.866-.266 1.421-.294a9.544 9.544 0 011.869.112c.047-.43.054-.786.021-1.071-.033-.285-.107-.511-.224-.679a.938.938 0 00-.49-.357 2.482 2.482 0 00-.777-.105c-.42 0-.821.058-1.204.175-.383.117-.723.236-1.022.357l-.35-.812zm2.058 5.642c.261 0 .504-.042.728-.126a2.22 2.22 0 00.588-.322 2.133 2.133 0 00.672-.868v-.98a7.92 7.92 0 00-1.344-.126c-.41 0-.765.044-1.064.133-.299.089-.532.226-.7.413-.168.187-.252.43-.252.728 0 .308.105.576.315.805.21.229.562.343 1.057.343zM143.29 72h2.324v7.448c0 .57.096.97.287 1.204.191.233.474.35.847.35.261 0 .511-.047.749-.14.238-.093.502-.252.791-.476l.504.77c-.15.13-.313.247-.49.35a3.638 3.638 0 01-1.106.42 2.963 2.963 0 01-1.442-.077 1.579 1.579 0 01-.679-.427 1.897 1.897 0 01-.413-.777c-.093-.322-.14-.721-.14-1.197v-6.51h-1.232V72zm14.14 8.918c-.168.15-.366.29-.595.42a4.39 4.39 0 01-.749.336c-.27.093-.553.166-.847.217-.294.051-.59.077-.889.077-.56 0-1.055-.086-1.484-.259a2.858 2.858 0 01-1.078-.742 3.234 3.234 0 01-.658-1.155 4.767 4.767 0 01-.224-1.512c0-.588.082-1.11.245-1.568.163-.457.399-.84.707-1.148a3.08 3.08 0 011.12-.707 4.187 4.187 0 011.47-.245c.392 0 .78.051 1.162.154.383.103.721.296 1.015.581.294.285.52.677.679 1.176.159.5.215 1.146.168 1.939h-5.418c0 .84.226 1.468.679 1.883.453.415 1.057.623 1.813.623.252 0 .502-.03.749-.091.247-.06.483-.133.707-.217a3.72 3.72 0 00.595-.28c.173-.103.306-.196.399-.28l.434.798zm-2.954-5.362c-.308 0-.6.033-.875.098a1.995 1.995 0 00-.728.329c-.21.154-.383.355-.518.602s-.222.553-.259.917h4.354c-.047-.616-.245-1.094-.595-1.435-.35-.34-.81-.511-1.379-.511zm4.872 6.244v-.938h1.89v-5.124h-1.89V74.8h2.618l.224.91h.07c.317-.29.672-.537 1.064-.742.392-.205.859-.308 1.4-.308.317 0 .572.06.763.182.191.121.34.299.448.532.107.233.18.516.217.847.037.331.056.707.056 1.127l-.98.014c0-.597-.058-1.036-.175-1.316-.117-.28-.329-.42-.637-.42-.29 0-.55.042-.784.126a2.565 2.565 0 00-.609.308c-.173.121-.32.243-.441.364s-.21.224-.266.308v4.13h2.688v.938h-5.656zm7.91-7h1.666v-1.386l1.092-.308V74.8h3.738v.938h-3.738v3.304c0 .681.166 1.185.497 1.512.331.327.805.49 1.421.49.42 0 .786-.08 1.099-.238.313-.159.595-.331.847-.518l.364.826a3.938 3.938 0 01-1.169.63 4.182 4.182 0 01-1.393.238 3.41 3.41 0 01-1.057-.161 2.426 2.426 0 01-.875-.497 2.38 2.38 0 01-.602-.861c-.15-.35-.224-.768-.224-1.253v-3.472h-1.666V74.8z"/><path id="(" fill="#7E7C7B" d="M181.272 84.768a6.964 6.964 0 01-1.757-.707 5.036 5.036 0 01-1.428-1.225c-.406-.504-.728-1.12-.966-1.848s-.357-1.591-.357-2.59c0-.99.121-1.855.364-2.597s.57-1.372.98-1.89c.41-.518.889-.933 1.435-1.246a6.005 6.005 0 011.729-.665l.35.882a7.086 7.086 0 00-1.512.623 3.928 3.928 0 00-1.183 1.022c-.331.425-.588.952-.77 1.582-.182.63-.273 1.393-.273 2.289 0 .905.11 1.678.329 2.317.22.64.509 1.171.868 1.596.36.425.76.756 1.204.994.443.238.889.404 1.337.497l-.35.966z"/><path id="i" fill="#181717" d="M185.094 81.8v-.938h2.436v-5.124h-2.436V74.8h3.556v6.062h2.38v.938h-5.936zm2.058-8.988c0-.252.084-.469.252-.651a.838.838 0 01.644-.273c.27 0 .497.091.679.273a.889.889 0 01.273.651.806.806 0 01-.273.616.963.963 0 01-.679.252.872.872 0 01-.644-.252.838.838 0 01-.252-.616z"/><path id=");}," fill="#7E7C7B" d="M194.026 83.802a4.965 4.965 0 001.337-.497 4.15 4.15 0 001.204-.994c.36-.425.649-.957.868-1.596.22-.64.329-1.412.329-2.317 0-.896-.091-1.659-.273-2.289-.182-.63-.439-1.157-.77-1.582a3.928 3.928 0 00-1.183-1.022 7.086 7.086 0 00-1.512-.623l.35-.882c.607.13 1.183.352 1.729.665a4.984 4.984 0 011.435 1.246c.41.518.737 1.148.98 1.89s.364 1.608.364 2.597c0 .999-.119 1.862-.357 2.59-.238.728-.56 1.344-.966 1.848a5.036 5.036 0 01-1.428 1.225 6.964 6.964 0 01-1.757.707l-.35-.966zm9.604-2.772c0-.28.091-.506.273-.679.182-.173.418-.259.707-.259.355 0 .63.124.826.371.196.247.294.595.294 1.043a2.36 2.36 0 01-.637 1.659 2.465 2.465 0 01-.588.462c-.21.117-.404.203-.581.259l-.35-.546c.336-.13.625-.317.868-.56.243-.243.364-.537.364-.882-.13.028-.233.042-.308.042-.27 0-.483-.077-.637-.231-.154-.154-.231-.38-.231-.679zm.126-5.502c0-.299.084-.53.252-.693.168-.163.392-.245.672-.245.299 0 .532.082.7.245.168.163.252.394.252.693 0 .27-.084.495-.252.672-.168.177-.401.266-.7.266-.28 0-.504-.089-.672-.266a.938.938 0 01-.252-.672zm18.788 7.196c0 .756-.198 1.328-.595 1.715-.397.387-.922.581-1.575.581h-2.03v-.98h1.526c.57 0 .975-.135 1.218-.406.243-.27.364-.69.364-1.26V81.03c0-.364.07-.695.21-.994.14-.299.308-.558.504-.777.196-.22.397-.392.602-.518.205-.126.373-.198.504-.217v-.084c-.13-.019-.299-.086-.504-.203a2.7 2.7 0 01-1.106-1.225c-.14-.299-.21-.64-.21-1.022v-1.358c0-.55-.114-.966-.343-1.246-.229-.28-.637-.42-1.225-.42h-1.54v-.98h2.03c.317 0 .609.058.875.175.266.117.495.278.686.483.191.205.34.448.448.728.107.28.161.588.161.924v1.428c0 .43.068.789.203 1.078.135.29.303.525.504.707.2.182.415.313.644.392.229.08.432.119.609.119V79c-.177 0-.38.047-.609.14a2.011 2.011 0 00-.644.434 2.44 2.44 0 00-.504.735c-.135.294-.203.642-.203 1.043v1.372zm6.286-1.694c0-.28.091-.506.273-.679.182-.173.418-.259.707-.259.355 0 .63.124.826.371.196.247.294.595.294 1.043a2.36 2.36 0 01-.637 1.659 2.465 2.465 0 01-.588.462c-.21.117-.404.203-.581.259l-.35-.546c.336-.13.625-.317.868-.56.243-.243.364-.537.364-.882-.13.028-.233.042-.308.042-.27 0-.483-.077-.637-.231-.154-.154-.231-.38-.231-.679z"/><path id="..." fill="#181717" d="M18.886 105.03c0-.299.084-.53.252-.693.168-.163.392-.245.672-.245.299 0 .532.082.7.245.168.163.252.394.252.693 0 .27-.084.495-.252.672-.168.177-.401.266-.7.266-.28 0-.504-.089-.672-.266a.938.938 0 01-.252-.672zm8.4 0c0-.299.084-.53.252-.693.168-.163.392-.245.672-.245.299 0 .532.082.7.245.168.163.252.394.252.693 0 .27-.084.495-.252.672-.168.177-.401.266-.7.266-.28 0-.504-.089-.672-.266a.938.938 0 01-.252-.672zm8.4 0c0-.299.084-.53.252-.693.168-.163.392-.245.672-.245.299 0 .532.082.7.245.168.163.252.394.252.693 0 .27-.084.495-.252.672-.168.177-.401.266-.7.266-.28 0-.504-.089-.672-.266a.938.938 0 01-.252-.672z"/><path id="function" fill="#1C85B5" d="M16.856 129.8v-.938h1.666v-5.124h-1.666v-.938h1.666v-.392c0-.877.229-1.512.686-1.904.457-.392 1.11-.588 1.96-.588.308 0 .583.019.826.056.243.037.504.112.784.224l-.252.91a2.862 2.862 0 00-.7-.203 4.295 4.295 0 00-.616-.049c-.616 0-1.036.152-1.26.455-.224.303-.336.8-.336 1.491h2.898v.938h-2.898v5.124h2.898v.938h-5.656zm12.25-7h1.988v4.774c0 .457.028.896.084 1.316h.938v.91h-1.862l-.042-1.19h-.056a2.938 2.938 0 01-.966.98c-.401.252-.887.378-1.456.378-.43 0-.796-.049-1.099-.147a1.556 1.556 0 01-.749-.511c-.196-.243-.34-.567-.434-.973-.093-.406-.14-.912-.14-1.519v-3.08h-.938v-.938h2.03v3.794c0 .383.016.726.049 1.029.033.303.1.56.203.77.103.21.254.369.455.476.2.107.469.161.805.161.485 0 .908-.159 1.267-.476.36-.317.632-.714.819-1.19v-3.626h-.896v-.938zm4.62 2.45a14.05 14.05 0 00-.063-1.176 4.657 4.657 0 00-.049-.364h-.938v-.91h1.876l.126 1.134h.07c.093-.159.217-.315.371-.469a2.91 2.91 0 011.225-.721c.252-.075.518-.112.798-.112.43 0 .81.047 1.141.14.331.093.607.259.826.497.22.238.385.56.497.966.112.406.168.922.168 1.547v4.018h-1.092v-3.808c0-.775-.126-1.358-.378-1.75-.252-.392-.71-.588-1.372-.588-.243 0-.478.049-.707.147a2.44 2.44 0 00-.623.385c-.187.159-.35.343-.49.553-.14.21-.243.432-.308.665v4.396h-1.078v-4.55zm13.244-1.372a5.531 5.531 0 00-.693-.189 3.61 3.61 0 00-.735-.077c-.915 0-1.596.215-2.044.644-.448.43-.672 1.11-.672 2.044 0 .41.065.777.196 1.099.13.322.317.595.56.819.243.224.534.397.875.518.34.121.716.182 1.127.182.439 0 .866-.075 1.281-.224.415-.15.763-.345 1.043-.588l.49.812c-.13.112-.294.229-.49.35a4.837 4.837 0 01-1.533.602 4.962 4.962 0 01-1.015.098c-.607 0-1.141-.086-1.603-.259a3.045 3.045 0 01-1.155-.742 3.176 3.176 0 01-.7-1.162 4.525 4.525 0 01-.238-1.505c0-.588.082-1.11.245-1.568.163-.457.399-.84.707-1.148a3.08 3.08 0 011.12-.707 4.187 4.187 0 011.47-.245c.69 0 1.253.06 1.687.182.434.121.8.257 1.099.406l-.014.042v1.946H46.97v-1.33zm2.688-1.078h1.666v-1.386l1.092-.308v1.694h3.738v.938h-3.738v3.304c0 .681.166 1.185.497 1.512.331.327.805.49 1.421.49.42 0 .786-.08 1.099-.238.313-.159.595-.331.847-.518l.364.826a3.938 3.938 0 01-1.169.63 4.182 4.182 0 01-1.393.238 3.41 3.41 0 01-1.057-.161 2.426 2.426 0 01-.875-.497 2.38 2.38 0 01-.602-.861c-.15-.35-.224-.768-.224-1.253v-3.472h-1.666v-.938zm9.436 7v-.938h2.436v-5.124h-2.436v-.938h3.556v6.062h2.38v.938h-5.936zm2.058-8.988c0-.252.084-.469.252-.651a.838.838 0 01.644-.273c.27 0 .497.091.679.273a.889.889 0 01.273.651.806.806 0 01-.273.616.963.963 0 01-.679.252.872.872 0 01-.644-.252.838.838 0 01-.252-.616zm5.67 5.488c0-1.13.294-2.023.882-2.681.588-.658 1.428-.987 2.52-.987.588 0 1.094.096 1.519.287.425.191.777.45 1.057.777.28.327.488.714.623 1.162.135.448.203.929.203 1.442 0 .56-.075 1.066-.224 1.519-.15.453-.369.838-.658 1.155-.29.317-.646.562-1.071.735a3.82 3.82 0 01-1.449.259c-.579 0-1.083-.096-1.512-.287a2.967 2.967 0 01-1.064-.777 3.168 3.168 0 01-.623-1.162 4.963 4.963 0 01-.203-1.442zm1.162 0c0 .327.04.653.119.98.08.327.208.62.385.882.177.261.408.471.693.63.285.159.632.238 1.043.238.747 0 1.309-.231 1.687-.693.378-.462.567-1.141.567-2.037 0-.336-.04-.665-.119-.987a2.608 2.608 0 00-.392-.875 2.066 2.066 0 00-.7-.63c-.285-.159-.632-.238-1.043-.238-.747 0-1.307.229-1.68.686-.373.457-.56 1.139-.56 2.044zm7.742-1.05a14.05 14.05 0 00-.063-1.176 4.657 4.657 0 00-.049-.364h-.938v-.91h1.876l.126 1.134h.07c.093-.159.217-.315.371-.469a2.91 2.91 0 011.225-.721c.252-.075.518-.112.798-.112.43 0 .81.047 1.141.14.331.093.607.259.826.497.22.238.385.56.497.966.112.406.168.922.168 1.547v4.018h-1.092v-3.808c0-.775-.126-1.358-.378-1.75-.252-.392-.71-.588-1.372-.588-.243 0-.478.049-.707.147a2.44 2.44 0 00-.623.385c-.187.159-.35.343-.49.553-.14.21-.243.432-.308.665v4.396h-1.078v-4.55z"/><path id="(){" fill="#7E7C7B" d="M97.272 132.768a6.964 6.964 0 01-1.757-.707 5.036 5.036 0 01-1.428-1.225c-.406-.504-.728-1.12-.966-1.848s-.357-1.591-.357-2.59c0-.99.121-1.855.364-2.597s.57-1.372.98-1.89c.41-.518.889-.933 1.435-1.246a6.005 6.005 0 011.729-.665l.35.882a7.086 7.086 0 00-1.512.623 3.928 3.928 0 00-1.183 1.022c-.331.425-.588.952-.77 1.582-.182.63-.273 1.393-.273 2.289 0 .905.11 1.678.329 2.317.22.64.509 1.171.868 1.596.36.425.76.756 1.204.994.443.238.889.404 1.337.497l-.35.966zm4.354-.966a4.965 4.965 0 001.337-.497 4.15 4.15 0 001.204-.994c.36-.425.649-.957.868-1.596.22-.64.329-1.412.329-2.317 0-.896-.091-1.659-.273-2.289-.182-.63-.439-1.157-.77-1.582a3.928 3.928 0 00-1.183-1.022 7.086 7.086 0 00-1.512-.623l.35-.882c.607.13 1.183.352 1.729.665a4.984 4.984 0 011.435 1.246c.41.518.737 1.148.98 1.89s.364 1.608.364 2.597c0 .999-.119 1.862-.357 2.59-.238.728-.56 1.344-.966 1.848a5.036 5.036 0 01-1.428 1.225 6.964 6.964 0 01-1.757.707l-.35-.966zm17.878-2.45c0-.401-.068-.749-.203-1.043a2.44 2.44 0 00-.504-.735c-.2-.196-.415-.34-.644-.434a1.641 1.641 0 00-.609-.14v-.98c.177 0 .38-.04.609-.119.229-.08.443-.21.644-.392.2-.182.369-.418.504-.707.135-.29.203-.649.203-1.078v-1.428c0-.336.054-.644.161-.924a2.22 2.22 0 01.448-.728c.191-.205.42-.366.686-.483.266-.117.558-.175.875-.175h2.03v.98h-1.54c-.588 0-.996.14-1.225.42-.229.28-.343.695-.343 1.246v1.358c0 .383-.07.723-.21 1.022a2.7 2.7 0 01-1.106 1.225c-.205.117-.373.184-.504.203v.084c.121.019.285.091.49.217.205.126.406.299.602.518.196.22.366.478.511.777.145.299.217.63.217.994v1.344c0 .57.121.99.364 1.26s.649.406 1.218.406h1.526v.98h-2.03c-.653 0-1.178-.194-1.575-.581-.397-.387-.595-.959-.595-1.715v-1.372z"/><path id="alert" fill="#181717" d="M134.736 123.346a4.447 4.447 0 011.358-.504 7.423 7.423 0 011.484-.154c.476 0 .866.075 1.169.224.303.15.541.343.714.581.173.238.29.509.35.812.06.303.091.609.091.917 0 .355-.01.733-.028 1.134-.019.401-.033.803-.042 1.204 0 .467.028.91.084 1.33h.938v.91h-1.862l-.126-1.05h-.07c-.056.084-.14.191-.252.322-.112.13-.259.259-.441.385a2.749 2.749 0 01-1.589.469c-.69 0-1.237-.177-1.638-.532-.401-.355-.602-.84-.602-1.456 0-.476.105-.873.315-1.19.21-.317.511-.56.903-.728.392-.168.866-.266 1.421-.294a9.544 9.544 0 011.869.112c.047-.43.054-.786.021-1.071-.033-.285-.107-.511-.224-.679a.938.938 0 00-.49-.357 2.482 2.482 0 00-.777-.105c-.42 0-.821.058-1.204.175-.383.117-.723.236-1.022.357l-.35-.812zm2.058 5.642c.261 0 .504-.042.728-.126a2.22 2.22 0 00.588-.322 2.133 2.133 0 00.672-.868v-.98a7.92 7.92 0 00-1.344-.126c-.41 0-.765.044-1.064.133-.299.089-.532.226-.7.413-.168.187-.252.43-.252.728 0 .308.105.576.315.805.21.229.562.343 1.057.343zM143.29 120h2.324v7.448c0 .57.096.97.287 1.204.191.233.474.35.847.35.261 0 .511-.047.749-.14.238-.093.502-.252.791-.476l.504.77c-.15.13-.313.247-.49.35a3.638 3.638 0 01-1.106.42 2.963 2.963 0 01-1.442-.077 1.579 1.579 0 01-.679-.427 1.897 1.897 0 01-.413-.777c-.093-.322-.14-.721-.14-1.197v-6.51h-1.232V120zm14.14 8.918c-.168.15-.366.29-.595.42a4.39 4.39 0 01-.749.336c-.27.093-.553.166-.847.217-.294.051-.59.077-.889.077-.56 0-1.055-.086-1.484-.259a2.858 2.858 0 01-1.078-.742 3.234 3.234 0 01-.658-1.155 4.767 4.767 0 01-.224-1.512c0-.588.082-1.11.245-1.568.163-.457.399-.84.707-1.148a3.08 3.08 0 011.12-.707 4.187 4.187 0 011.47-.245c.392 0 .78.051 1.162.154.383.103.721.296 1.015.581.294.285.52.677.679 1.176.159.5.215 1.146.168 1.939h-5.418c0 .84.226 1.468.679 1.883.453.415 1.057.623 1.813.623.252 0 .502-.03.749-.091.247-.06.483-.133.707-.217a3.72 3.72 0 00.595-.28c.173-.103.306-.196.399-.28l.434.798zm-2.954-5.362c-.308 0-.6.033-.875.098a1.995 1.995 0 00-.728.329c-.21.154-.383.355-.518.602s-.222.553-.259.917h4.354c-.047-.616-.245-1.094-.595-1.435-.35-.34-.81-.511-1.379-.511zm4.872 6.244v-.938h1.89v-5.124h-1.89v-.938h2.618l.224.91h.07c.317-.29.672-.537 1.064-.742.392-.205.859-.308 1.4-.308.317 0 .572.06.763.182.191.121.34.299.448.532.107.233.18.516.217.847.037.331.056.707.056 1.127l-.98.014c0-.597-.058-1.036-.175-1.316-.117-.28-.329-.42-.637-.42-.29 0-.55.042-.784.126a2.565 2.565 0 00-.609.308c-.173.121-.32.243-.441.364s-.21.224-.266.308v4.13h2.688v.938h-5.656zm7.91-7h1.666v-1.386l1.092-.308v1.694h3.738v.938h-3.738v3.304c0 .681.166 1.185.497 1.512.331.327.805.49 1.421.49.42 0 .786-.08 1.099-.238.313-.159.595-.331.847-.518l.364.826a3.938 3.938 0 01-1.169.63 4.182 4.182 0 01-1.393.238 3.41 3.41 0 01-1.057-.161 2.426 2.426 0 01-.875-.497 2.38 2.38 0 01-.602-.861c-.15-.35-.224-.768-.224-1.253v-3.472h-1.666v-.938z"/><path id="(" fill="#7E7C7B" d="M181.272 132.768a6.964 6.964 0 01-1.757-.707 5.036 5.036 0 01-1.428-1.225c-.406-.504-.728-1.12-.966-1.848s-.357-1.591-.357-2.59c0-.99.121-1.855.364-2.597s.57-1.372.98-1.89c.41-.518.889-.933 1.435-1.246a6.005 6.005 0 011.729-.665l.35.882a7.086 7.086 0 00-1.512.623 3.928 3.928 0 00-1.183 1.022c-.331.425-.588.952-.77 1.582-.182.63-.273 1.393-.273 2.289 0 .905.11 1.678.329 2.317.22.64.509 1.171.868 1.596.36.425.76.756 1.204.994.443.238.889.404 1.337.497l-.35.966z"/><path id="i" fill="#181717" d="M185.094 129.8v-.938h2.436v-5.124h-2.436v-.938h3.556v6.062h2.38v.938h-5.936zm2.058-8.988c0-.252.084-.469.252-.651a.838.838 0 01.644-.273c.27 0 .497.091.679.273a.889.889 0 01.273.651.806.806 0 01-.273.616.963.963 0 01-.679.252.872.872 0 01-.644-.252.838.838 0 01-.252-.616z"/><path id=");}];" fill="#7E7C7B" d="M194.026 131.802a4.965 4.965 0 001.337-.497 4.15 4.15 0 001.204-.994c.36-.425.649-.957.868-1.596.22-.64.329-1.412.329-2.317 0-.896-.091-1.659-.273-2.289-.182-.63-.439-1.157-.77-1.582a3.928 3.928 0 00-1.183-1.022 7.086 7.086 0 00-1.512-.623l.35-.882c.607.13 1.183.352 1.729.665a4.984 4.984 0 011.435 1.246c.41.518.737 1.148.98 1.89s.364 1.608.364 2.597c0 .999-.119 1.862-.357 2.59-.238.728-.56 1.344-.966 1.848a5.036 5.036 0 01-1.428 1.225 6.964 6.964 0 01-1.757.707l-.35-.966zm9.604-2.772c0-.28.091-.506.273-.679.182-.173.418-.259.707-.259.355 0 .63.124.826.371.196.247.294.595.294 1.043a2.36 2.36 0 01-.637 1.659 2.465 2.465 0 01-.588.462c-.21.117-.404.203-.581.259l-.35-.546c.336-.13.625-.317.868-.56.243-.243.364-.537.364-.882-.13.028-.233.042-.308.042-.27 0-.483-.077-.637-.231-.154-.154-.231-.38-.231-.679zm.126-5.502c0-.299.084-.53.252-.693.168-.163.392-.245.672-.245.299 0 .532.082.7.245.168.163.252.394.252.693 0 .27-.084.495-.252.672-.168.177-.401.266-.7.266-.28 0-.504-.089-.672-.266a.938.938 0 01-.252-.672zm18.788 7.196c0 .756-.198 1.328-.595 1.715-.397.387-.922.581-1.575.581h-2.03v-.98h1.526c.57 0 .975-.135 1.218-.406.243-.27.364-.69.364-1.26v-1.344c0-.364.07-.695.21-.994.14-.299.308-.558.504-.777.196-.22.397-.392.602-.518.205-.126.373-.198.504-.217v-.084c-.13-.019-.299-.086-.504-.203a2.7 2.7 0 01-1.106-1.225c-.14-.299-.21-.64-.21-1.022v-1.358c0-.55-.114-.966-.343-1.246-.229-.28-.637-.42-1.225-.42h-1.54v-.98h2.03c.317 0 .609.058.875.175.266.117.495.278.686.483.191.205.34.448.448.728.107.28.161.588.161.924v1.428c0 .43.068.789.203 1.078.135.29.303.525.504.707.2.182.415.313.644.392.229.08.432.119.609.119v.98c-.177 0-.38.047-.609.14a2.011 2.011 0 00-.644.434 2.44 2.44 0 00-.504.735c-.135.294-.203.642-.203 1.043v1.372zM5.138 157.02H.35v-.98h3.696v-11.06H.35V144h4.788v13.02zm5.292-3.99c0-.28.091-.506.273-.679.182-.173.418-.259.707-.259.355 0 .63.124.826.371.196.247.294.595.294 1.043a2.36 2.36 0 01-.637 1.659 2.465 2.465 0 01-.588.462c-.21.117-.404.203-.581.259l-.35-.546c.336-.13.625-.317.868-.56.243-.243.364-.537.364-.882-.13.028-.233.042-.308.042-.27 0-.483-.077-.637-.231-.154-.154-.231-.38-.231-.679zm.126-5.502c0-.299.084-.53.252-.693.168-.163.392-.245.672-.245.299 0 .532.082.7.245.168.163.252.394.252.693 0 .27-.084.495-.252.672-.168.177-.401.266-.7.266-.28 0-.504-.089-.672-.266a.938.938 0 01-.252-.672z"/></g><g id="Group-Copy" transform="translate(350 66)"><path id="Line" fill="#C06334" fill-rule="nonzero" d="M16.5 15.5l14 7-14 7v-6h-14v-2h14v-6z"/><text id="outer" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="0" y="11">outer</tspan></text></g><g id="Group-Copy-2" fill="#C06334" fill-rule="nonzero" transform="translate(242 44)"><path id="Line" d="M13.5-5.5l14 7-14 7v-6h-14v-2h14v-6z"/></g><g id="Group-Copy-3" fill="#C06334" fill-rule="nonzero" transform="translate(242 67)"><path id="Line" d="M13.5-5.5l14 7-14 7v-6h-14v-2h14v-6z"/></g><g id="Group-Copy-4" fill="#C06334" fill-rule="nonzero" transform="translate(242 90)"><path id="Line" d="M13.5-5.5l14 7-14 7v-6h-14v-2h14v-6z"/></g><g id="Group-Copy-5" fill="#C06334" fill-rule="nonzero" transform="translate(242 139)"><path id="Line" d="M13.5-5.5l14 7-14 7v-6h-14v-2h14v-6z"/></g><text id="makeArmy()-LexicalEn" fill="#AF6E24" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="399" y="59">makeArmy()</tspan>  <tspan x="399" y="74" font-family="PTMono-Regular, PT Mono" font-weight="normal">LexicalEnvironment</tspan></text><text id="for-iteration-Lexica" fill="#AF6E24" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="278" y="14">for iteration</tspan>  <tspan x="278" y="29" font-family="PTMono-Regular, PT Mono" font-weight="normal">LexicalEnvironment</tspan></text><g id="Group-3" transform="translate(279 36)"><path id="Rectangle-1" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M1 1h52v18H1z"/><text id="i:-0" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="8" y="14">i: 0</tspan></text></g><g id="Group-3-Copy" transform="translate(279 59)"><path id="Rectangle-1" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M1 1h52v18H1z"/><text id="i:-1" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="8" y="14">i: 1</tspan></text></g><g id="Group-3-Copy-2" transform="translate(279 82)"><path id="Rectangle-1" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M1 1h52v18H1z"/><text id="i:-2" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="8" y="14">i: 2</tspan></text></g><g id="Group-3-Copy-3" transform="translate(279 131)"><path id="Rectangle-1" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M1 1h52v18H1z"/><text id="i:-10" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="7.447" y="13.51">i: 10</tspan></text></g><text id="..." fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="399" y="94">...</tspan></text></g></g></svg>
\ No newline at end of file
diff --git a/1-js/06-advanced-functions/03-closure/10-make-army/lexenv-makearmy-while-fixed.svg b/1-js/06-advanced-functions/03-closure/10-make-army/lexenv-makearmy-while-fixed.svg
new file mode 100644
index 000000000..d83ecbe76
--- /dev/null
+++ b/1-js/06-advanced-functions/03-closure/10-make-army/lexenv-makearmy-while-fixed.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="566" height="183" viewBox="0 0 566 183"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:&apos;PT Mono&apos;;font-weight:700;font-style:normal;src:local(&apos;PT MonoBold&apos;),url(/font/PTMonoBold.woff2) format(&apos;woff2&apos;),url(/font/PTMonoBold.woff) format(&apos;woff&apos;),url(/font/PTMonoBold.ttf) format(&apos;truetype&apos;)}</style></defs><g id="closure" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="lexenv-makearmy-while-fixed.svg"><g id="shooters-=-[-functio" fill-rule="nonzero" transform="translate(7.176 15.2)"><path id="shooters" fill="#181717" d="M2.996 9.968c1.017 0 1.78-.21 2.289-.63.509-.42.763-.952.763-1.596 0-.43-.117-.77-.35-1.022a2.536 2.536 0 00-.868-.602 5.479 5.479 0 00-1.127-.343 19.87 19.87 0 01-1.127-.252 3.633 3.633 0 01-.868-.329c-.233-.13-.35-.317-.35-.56 0-.196.049-.362.147-.497.098-.135.229-.245.392-.329.163-.084.345-.147.546-.189.2-.042.404-.063.609-.063.541 0 .992.077 1.351.231.36.154.693.315 1.001.483l.448-.882c-.28-.177-.656-.348-1.127-.511-.471-.163-1.034-.245-1.687-.245-.364 0-.714.04-1.05.119-.336.08-.63.2-.882.364a1.94 1.94 0 00-.609.623c-.154.252-.231.555-.231.91 0 .43.117.763.35 1.001.233.238.523.427.868.567.345.14.721.252 1.127.336.406.084.782.175 1.127.273.345.098.635.229.868.392.233.163.35.394.35.693 0 .205-.049.38-.147.525a1.08 1.08 0 01-.399.35 2.075 2.075 0 01-.581.196 3.76 3.76 0 01-1.484-.021 4.197 4.197 0 01-1.337-.539 2.536 2.536 0 01-.448-.343l-.56.91c.14.121.317.24.532.357.215.117.453.222.714.315.261.093.541.168.84.224.299.056.602.084.91.084zM9.464 9.8V5.348c.056-.261.156-.502.301-.721.145-.22.317-.406.518-.56.2-.154.422-.275.665-.364.243-.089.49-.133.742-.133.364 0 .663.051.896.154.233.103.418.254.553.455.135.2.226.45.273.749.047.299.07.649.07 1.05V9.8h1.092V5.768c0-.625-.051-1.141-.154-1.547-.103-.406-.259-.726-.469-.959a1.676 1.676 0 00-.812-.49 4.338 4.338 0 00-1.169-.14c-.57 0-1.045.091-1.428.273a3.135 3.135 0 00-1.008.763h-.07V0H7.28v.938h1.106V9.8h1.078zm10.36.168a3.82 3.82 0 001.449-.259 2.907 2.907 0 001.071-.735c.29-.317.509-.702.658-1.155.15-.453.224-.959.224-1.519 0-.513-.068-.994-.203-1.442a3.168 3.168 0 00-.623-1.162 2.981 2.981 0 00-1.057-.777c-.425-.191-.931-.287-1.519-.287-1.092 0-1.932.329-2.52.987-.588.658-.882 1.552-.882 2.681 0 .513.068.994.203 1.442.135.448.343.835.623 1.162.28.327.635.586 1.064.777.43.191.933.287 1.512.287zm0-.938c-.41 0-.758-.08-1.043-.238a2.001 2.001 0 01-.693-.63 2.683 2.683 0 01-.385-.882 4.14 4.14 0 01-.119-.98c0-.905.187-1.587.56-2.044.373-.457.933-.686 1.68-.686.41 0 .758.08 1.043.238.285.159.518.369.7.63.182.261.313.553.392.875.08.322.119.651.119.987 0 .896-.189 1.575-.567 2.037-.378.462-.94.693-1.687.693zm8.4.938a3.82 3.82 0 001.449-.259 2.907 2.907 0 001.071-.735c.29-.317.509-.702.658-1.155.15-.453.224-.959.224-1.519 0-.513-.068-.994-.203-1.442a3.168 3.168 0 00-.623-1.162 2.981 2.981 0 00-1.057-.777c-.425-.191-.931-.287-1.519-.287-1.092 0-1.932.329-2.52.987-.588.658-.882 1.552-.882 2.681 0 .513.068.994.203 1.442.135.448.343.835.623 1.162.28.327.635.586 1.064.777.43.191.933.287 1.512.287zm0-.938c-.41 0-.758-.08-1.043-.238a2.001 2.001 0 01-.693-.63 2.683 2.683 0 01-.385-.882 4.14 4.14 0 01-.119-.98c0-.905.187-1.587.56-2.044.373-.457.933-.686 1.68-.686.41 0 .758.08 1.043.238.285.159.518.369.7.63.182.261.313.553.392.875.08.322.119.651.119.987 0 .896-.189 1.575-.567 2.037-.378.462-.94.693-1.687.693zm9.058.952c.476 0 .94-.08 1.393-.238a3.938 3.938 0 001.169-.63l-.364-.826c-.252.187-.534.36-.847.518-.313.159-.679.238-1.099.238-.616 0-1.09-.163-1.421-.49-.331-.327-.497-.83-.497-1.512V3.738h3.738V2.8h-3.738V1.106l-1.092.308V2.8h-1.666v.938h1.666V7.21c0 .485.075.903.224 1.253.15.35.35.637.602.861.252.224.544.39.875.497a3.41 3.41 0 001.057.161zm7.868-.014c.299 0 .595-.026.889-.077.294-.051.576-.124.847-.217.27-.093.52-.205.749-.336.229-.13.427-.27.595-.42l-.434-.798a2.585 2.585 0 01-.399.28 3.72 3.72 0 01-.595.28c-.224.084-.46.156-.707.217-.247.06-.497.091-.749.091-.756 0-1.36-.208-1.813-.623-.453-.415-.679-1.043-.679-1.883h5.418c.047-.793-.01-1.44-.168-1.939-.159-.5-.385-.891-.679-1.176a2.295 2.295 0 00-1.015-.581 4.466 4.466 0 00-1.162-.154c-.541 0-1.031.082-1.47.245a3.08 3.08 0 00-1.12.707c-.308.308-.544.69-.707 1.148-.163.457-.245.98-.245 1.568 0 .56.075 1.064.224 1.512.15.448.369.833.658 1.155.29.322.649.57 1.078.742.43.173.924.259 1.484.259zm2.1-4.466h-4.354c.037-.364.124-.67.259-.917s.308-.448.518-.602c.21-.154.453-.264.728-.329a3.78 3.78 0 01.875-.098c.57 0 1.029.17 1.379.511.35.34.548.819.595 1.435zM55.804 9.8v-.938h-2.688v-4.13c.056-.084.145-.187.266-.308.121-.121.268-.243.441-.364s.376-.224.609-.308c.233-.084.495-.126.784-.126.308 0 .52.14.637.42.117.28.175.719.175 1.316l.98-.014c0-.42-.019-.796-.056-1.127a2.771 2.771 0 00-.217-.847 1.206 1.206 0 00-.448-.532c-.191-.121-.446-.182-.763-.182-.541 0-1.008.103-1.4.308a5.046 5.046 0 00-1.064.742h-.07l-.224-.91h-2.618v.938h1.89v5.124h-1.89V9.8h5.656zm5.992.168c1.017 0 1.78-.21 2.289-.63.509-.42.763-.952.763-1.596 0-.43-.117-.77-.35-1.022a2.536 2.536 0 00-.868-.602 5.479 5.479 0 00-1.127-.343 19.87 19.87 0 01-1.127-.252 3.633 3.633 0 01-.868-.329c-.233-.13-.35-.317-.35-.56 0-.196.049-.362.147-.497.098-.135.229-.245.392-.329.163-.084.345-.147.546-.189.2-.042.404-.063.609-.063.541 0 .992.077 1.351.231.36.154.693.315 1.001.483l.448-.882c-.28-.177-.656-.348-1.127-.511-.471-.163-1.034-.245-1.687-.245-.364 0-.714.04-1.05.119-.336.08-.63.2-.882.364a1.94 1.94 0 00-.609.623c-.154.252-.231.555-.231.91 0 .43.117.763.35 1.001.233.238.523.427.868.567.345.14.721.252 1.127.336.406.084.782.175 1.127.273.345.098.635.229.868.392.233.163.35.394.35.693 0 .205-.049.38-.147.525a1.08 1.08 0 01-.399.35 2.075 2.075 0 01-.581.196 3.76 3.76 0 01-1.484-.021 4.197 4.197 0 01-1.337-.539 2.536 2.536 0 01-.448-.343l-.56.91c.14.121.317.24.532.357.215.117.453.222.714.315.261.093.541.168.84.224.299.056.602.084.91.084z"/><path id="=" fill="#DBAF88" d="M81.872 4.41V3.402h-6.496V4.41h6.496zm0 2.296V5.698h-6.496v1.008h6.496z"/><path id="[" fill="#7E7C7B" d="M98.084 13.02v-.98h-3.682V.98h3.682V0H93.31v13.02z"/><path id="function" fill="#1C85B5" d="M22.512 33.8v-.938h-2.898v-5.124h2.898V26.8h-2.898c0-.69.112-1.188.336-1.491.224-.303.644-.455 1.26-.455.187 0 .392.016.616.049.224.033.457.1.7.203l.252-.91a3.603 3.603 0 00-.784-.224 5.473 5.473 0 00-.826-.056c-.85 0-1.503.196-1.96.588-.457.392-.686 1.027-.686 1.904v.392h-1.666v.938h1.666v5.124h-1.666v.938h5.656zm5.222.168c.57 0 1.055-.126 1.456-.378s.723-.579.966-.98h.056l.042 1.19h1.862v-.91h-.938a9.956 9.956 0 01-.084-1.316V26.8h-1.988v.938h.896v3.626c-.187.476-.46.873-.819 1.19-.36.317-.782.476-1.267.476-.336 0-.604-.054-.805-.161a1.046 1.046 0 01-.455-.476 2.317 2.317 0 01-.203-.77 9.693 9.693 0 01-.049-1.029V26.8h-2.03v.938h.938v3.08c0 .607.047 1.113.14 1.519.093.406.238.73.434.973s.446.413.749.511c.303.098.67.147 1.099.147zm7.07-.168v-4.396c.065-.233.168-.455.308-.665.14-.21.303-.394.49-.553a2.44 2.44 0 01.623-.385c.229-.098.464-.147.707-.147.663 0 1.12.196 1.372.588.252.392.378.975.378 1.75V33.8h1.092v-4.018c0-.625-.056-1.141-.168-1.547-.112-.406-.278-.728-.497-.966a1.738 1.738 0 00-.826-.497 4.219 4.219 0 00-1.141-.14 2.856 2.856 0 00-2.023.833c-.154.154-.278.31-.371.469h-.07l-.126-1.134h-1.876v.91h.938c.019.103.035.224.049.364a12.159 12.159 0 01.056.847c.005.135.007.245.007.329v4.55h1.078zm10.556.168c.364 0 .702-.033 1.015-.098a4.708 4.708 0 002.023-.952l-.49-.812c-.28.243-.628.439-1.043.588-.415.15-.842.224-1.281.224-.41 0-.786-.06-1.127-.182a2.517 2.517 0 01-.875-.518 2.248 2.248 0 01-.56-.819 2.902 2.902 0 01-.196-1.099c0-.933.224-1.615.672-2.044.448-.43 1.13-.644 2.044-.644.243 0 .488.026.735.077.247.051.478.114.693.189v1.33h1.008v-1.946l.014-.042a6.232 6.232 0 00-1.099-.406c-.434-.121-.996-.182-1.687-.182-.541 0-1.031.082-1.47.245a3.08 3.08 0 00-1.12.707c-.308.308-.544.69-.707 1.148-.163.457-.245.98-.245 1.568 0 .55.08 1.052.238 1.505.159.453.392.84.7 1.162.308.322.693.57 1.155.742.462.173.996.259 1.603.259zm8.722.014c.476 0 .94-.08 1.393-.238a3.938 3.938 0 001.169-.63l-.364-.826c-.252.187-.534.36-.847.518-.313.159-.679.238-1.099.238-.616 0-1.09-.163-1.421-.49-.331-.327-.497-.83-.497-1.512v-3.304h3.738V26.8h-3.738v-1.694l-1.092.308V26.8h-1.666v.938h1.666v3.472c0 .485.075.903.224 1.253.15.35.35.637.602.861.252.224.544.39.875.497a3.41 3.41 0 001.057.161zm7.966-8.302c.27 0 .497-.084.679-.252a.806.806 0 00.273-.616.889.889 0 00-.273-.651.922.922 0 00-.679-.273.838.838 0 00-.644.273.927.927 0 00-.252.651c0 .243.084.448.252.616a.872.872 0 00.644.252zm2.982 8.12v-.938h-2.38V26.8h-3.556v.938h2.436v5.124h-2.436v.938h5.936zm5.194.168a3.82 3.82 0 001.449-.259 2.907 2.907 0 001.071-.735c.29-.317.509-.702.658-1.155.15-.453.224-.959.224-1.519 0-.513-.068-.994-.203-1.442a3.168 3.168 0 00-.623-1.162 2.981 2.981 0 00-1.057-.777c-.425-.191-.931-.287-1.519-.287-1.092 0-1.932.329-2.52.987-.588.658-.882 1.552-.882 2.681 0 .513.068.994.203 1.442.135.448.343.835.623 1.162.28.327.635.586 1.064.777.43.191.933.287 1.512.287zm0-.938c-.41 0-.758-.08-1.043-.238a2.001 2.001 0 01-.693-.63 2.683 2.683 0 01-.385-.882 4.14 4.14 0 01-.119-.98c0-.905.187-1.587.56-2.044.373-.457.933-.686 1.68-.686.41 0 .758.08 1.043.238.285.159.518.369.7.63.182.261.313.553.392.875.08.322.119.651.119.987 0 .896-.189 1.575-.567 2.037-.378.462-.94.693-1.687.693zm6.58.77v-4.396c.065-.233.168-.455.308-.665.14-.21.303-.394.49-.553a2.44 2.44 0 01.623-.385c.229-.098.464-.147.707-.147.663 0 1.12.196 1.372.588.252.392.378.975.378 1.75V33.8h1.092v-4.018c0-.625-.056-1.141-.168-1.547-.112-.406-.278-.728-.497-.966a1.738 1.738 0 00-.826-.497 4.219 4.219 0 00-1.141-.14 2.856 2.856 0 00-2.023.833c-.154.154-.278.31-.371.469h-.07l-.126-1.134h-1.876v.91h.938c.019.103.035.224.049.364a12.159 12.159 0 01.056.847c.005.135.007.245.007.329v4.55h1.078z"/><path id="(){" fill="#7E7C7B" d="M97.272 36.768l.35-.966a4.965 4.965 0 01-1.337-.497 4.15 4.15 0 01-1.204-.994c-.36-.425-.649-.957-.868-1.596-.22-.64-.329-1.412-.329-2.317 0-.896.091-1.659.273-2.289.182-.63.439-1.157.77-1.582a3.928 3.928 0 011.183-1.022 7.086 7.086 0 011.512-.623l-.35-.882a6.005 6.005 0 00-1.729.665 4.984 4.984 0 00-1.435 1.246c-.41.518-.737 1.148-.98 1.89s-.364 1.608-.364 2.597c0 .999.119 1.862.357 2.59.238.728.56 1.344.966 1.848.406.504.882.912 1.428 1.225a6.964 6.964 0 001.757.707zm4.704 0a6.964 6.964 0 001.757-.707 5.036 5.036 0 001.428-1.225c.406-.504.728-1.12.966-1.848s.357-1.591.357-2.59c0-.99-.121-1.855-.364-2.597s-.57-1.372-.98-1.89a4.984 4.984 0 00-1.435-1.246 6.005 6.005 0 00-1.729-.665l-.35.882c.55.159 1.055.366 1.512.623.457.257.852.597 1.183 1.022.331.425.588.952.77 1.582.182.63.273 1.393.273 2.289 0 .905-.11 1.678-.329 2.317-.22.64-.509 1.171-.868 1.596a4.15 4.15 0 01-1.204.994 4.965 4.965 0 01-1.337.497l.35.966zm21.728.252v-.98h-1.526c-.57 0-.975-.135-1.218-.406-.243-.27-.364-.69-.364-1.26V33.03a2.25 2.25 0 00-.217-.994 3.347 3.347 0 00-.511-.777 2.744 2.744 0 00-.602-.518c-.205-.126-.369-.198-.49-.217v-.084c.13-.019.299-.086.504-.203a2.7 2.7 0 001.106-1.225c.14-.299.21-.64.21-1.022v-1.358c0-.55.114-.966.343-1.246.229-.28.637-.42 1.225-.42h1.54v-.98h-2.03c-.317 0-.609.058-.875.175a2.053 2.053 0 00-.686.483 2.22 2.22 0 00-.448.728c-.107.28-.161.588-.161.924v1.428c0 .43-.068.789-.203 1.078-.135.29-.303.525-.504.707a1.87 1.87 0 01-.644.392c-.229.08-.432.119-.609.119V31c.177 0 .38.047.609.14.229.093.443.238.644.434.2.196.369.441.504.735s.203.642.203 1.043v1.372c0 .756.198 1.328.595 1.715.397.387.922.581 1.575.581h2.03z"/><path id="alert" fill="#181717" d="M136.514 33.926a2.749 2.749 0 001.589-.469c.182-.126.329-.254.441-.385.112-.13.196-.238.252-.322h.07l.126 1.05h1.862v-.91h-.938c-.056-.42-.084-.863-.084-1.33.01-.401.023-.803.042-1.204.019-.401.028-.78.028-1.134 0-.308-.03-.614-.091-.917a2.049 2.049 0 00-.35-.812 1.893 1.893 0 00-.714-.581c-.303-.15-.693-.224-1.169-.224-.485 0-.98.051-1.484.154-.504.103-.957.27-1.358.504l.35.812c.299-.121.64-.24 1.022-.357a4.106 4.106 0 011.204-.175c.308 0 .567.035.777.105.21.07.373.189.49.357.117.168.191.394.224.679.033.285.026.642-.021 1.071a9.544 9.544 0 00-1.869-.112c-.555.028-1.029.126-1.421.294-.392.168-.693.41-.903.728-.21.317-.315.714-.315 1.19 0 .616.2 1.101.602 1.456.401.355.947.532 1.638.532zm.28-.938c-.495 0-.847-.114-1.057-.343a1.152 1.152 0 01-.315-.805c0-.299.084-.541.252-.728.168-.187.401-.324.7-.413a3.763 3.763 0 011.064-.133c.41 0 .859.042 1.344.126v.98a2.133 2.133 0 01-.672.868 2.22 2.22 0 01-.588.322 2.057 2.057 0 01-.728.126zm9.884.994c.159 0 .331-.019.518-.056a3.61 3.61 0 001.106-.42c.177-.103.34-.22.49-.35l-.504-.77c-.29.224-.553.383-.791.476-.238.093-.488.14-.749.14-.373 0-.656-.117-.847-.35-.191-.233-.287-.635-.287-1.204V24h-2.324v.938h1.232v6.51c0 .476.047.875.14 1.197.093.322.231.581.413.777.182.196.408.338.679.427.27.089.579.133.924.133zm7.672-.014c.299 0 .595-.026.889-.077.294-.051.576-.124.847-.217.27-.093.52-.205.749-.336.229-.13.427-.27.595-.42l-.434-.798a2.585 2.585 0 01-.399.28 3.72 3.72 0 01-.595.28c-.224.084-.46.156-.707.217-.247.06-.497.091-.749.091-.756 0-1.36-.208-1.813-.623-.453-.415-.679-1.043-.679-1.883h5.418c.047-.793-.01-1.44-.168-1.939-.159-.5-.385-.891-.679-1.176a2.295 2.295 0 00-1.015-.581 4.466 4.466 0 00-1.162-.154c-.541 0-1.031.082-1.47.245a3.08 3.08 0 00-1.12.707c-.308.308-.544.69-.707 1.148-.163.457-.245.98-.245 1.568 0 .56.075 1.064.224 1.512.15.448.369.833.658 1.155.29.322.649.57 1.078.742.43.173.924.259 1.484.259zm2.1-4.466h-4.354c.037-.364.124-.67.259-.917s.308-.448.518-.602c.21-.154.453-.264.728-.329a3.78 3.78 0 01.875-.098c.57 0 1.029.17 1.379.511.35.34.548.819.595 1.435zm8.554 4.298v-.938h-2.688v-4.13c.056-.084.145-.187.266-.308.121-.121.268-.243.441-.364s.376-.224.609-.308c.233-.084.495-.126.784-.126.308 0 .52.14.637.42.117.28.175.719.175 1.316l.98-.014c0-.42-.019-.796-.056-1.127a2.771 2.771 0 00-.217-.847 1.206 1.206 0 00-.448-.532c-.191-.121-.446-.182-.763-.182-.541 0-1.008.103-1.4.308a5.046 5.046 0 00-1.064.742h-.07l-.224-.91h-2.618v.938h1.89v5.124h-1.89v.938h5.656zm6.678.182c.476 0 .94-.08 1.393-.238a3.938 3.938 0 001.169-.63l-.364-.826c-.252.187-.534.36-.847.518-.313.159-.679.238-1.099.238-.616 0-1.09-.163-1.421-.49-.331-.327-.497-.83-.497-1.512v-3.304h3.738V26.8h-3.738v-1.694l-1.092.308V26.8h-1.666v.938h1.666v3.472c0 .485.075.903.224 1.253.15.35.35.637.602.861.252.224.544.39.875.497a3.41 3.41 0 001.057.161z"/><path id="(" fill="#7E7C7B" d="M181.272 36.768l.35-.966a4.965 4.965 0 01-1.337-.497 4.15 4.15 0 01-1.204-.994c-.36-.425-.649-.957-.868-1.596-.22-.64-.329-1.412-.329-2.317 0-.896.091-1.659.273-2.289.182-.63.439-1.157.77-1.582a3.928 3.928 0 011.183-1.022 7.086 7.086 0 011.512-.623l-.35-.882a6.005 6.005 0 00-1.729.665 4.984 4.984 0 00-1.435 1.246c-.41.518-.737 1.148-.98 1.89s-.364 1.608-.364 2.597c0 .999.119 1.862.357 2.59.238.728.56 1.344.966 1.848.406.504.882.912 1.428 1.225a6.964 6.964 0 001.757.707z"/><path id="j" fill="#181717" d="M188.636 25.68c.27 0 .497-.084.679-.252a.806.806 0 00.273-.616.889.889 0 00-.273-.651.922.922 0 00-.679-.273.838.838 0 00-.644.273.927.927 0 00-.252.651c0 .243.084.448.252.616a.872.872 0 00.644.252zm-1.904 11.088c.85 0 1.514-.231 1.995-.693.48-.462.721-1.164.721-2.107V26.8h-4.508v.938h3.388v6.02c0 .616-.119 1.099-.357 1.449-.238.35-.637.525-1.197.525-.345 0-.679-.07-1.001-.21a4.362 4.362 0 01-.861-.49l-.462.91a4.501 4.501 0 00.882.497c.205.089.427.166.665.231.238.065.483.098.735.098z"/><path id=");}," fill="#7E7C7B" d="M194.376 36.768a6.964 6.964 0 001.757-.707 5.036 5.036 0 001.428-1.225c.406-.504.728-1.12.966-1.848s.357-1.591.357-2.59c0-.99-.121-1.855-.364-2.597s-.57-1.372-.98-1.89a4.984 4.984 0 00-1.435-1.246 6.005 6.005 0 00-1.729-.665l-.35.882c.55.159 1.055.366 1.512.623.457.257.852.597 1.183 1.022.331.425.588.952.77 1.582.182.63.273 1.393.273 2.289 0 .905-.11 1.678-.329 2.317-.22.64-.509 1.171-.868 1.596a4.15 4.15 0 01-1.204.994 4.965 4.965 0 01-1.337.497l.35.966zm10.304-8.302c.299 0 .532-.089.7-.266a.938.938 0 00.252-.672c0-.299-.084-.53-.252-.693-.168-.163-.401-.245-.7-.245-.28 0-.504.082-.672.245-.168.163-.252.394-.252.693 0 .27.084.495.252.672.168.177.392.266.672.266zm-.756 7.42c.177-.056.371-.142.581-.259a2.42 2.42 0 001.043-1.162 2.36 2.36 0 00.182-.959c0-.448-.098-.796-.294-1.043-.196-.247-.471-.371-.826-.371-.29 0-.525.086-.707.259a.893.893 0 00-.273.679c0 .299.077.525.231.679.154.154.366.231.637.231.075 0 .177-.014.308-.042 0 .345-.121.64-.364.882-.243.243-.532.43-.868.56l.35.546zm16.45 1.134c.653 0 1.178-.194 1.575-.581.397-.387.595-.959.595-1.715v-1.372c0-.401.068-.749.203-1.043a2.44 2.44 0 01.504-.735c.2-.196.415-.34.644-.434.229-.093.432-.14.609-.14v-.98c-.177 0-.38-.04-.609-.119a1.87 1.87 0 01-.644-.392 2.193 2.193 0 01-.504-.707c-.135-.29-.203-.649-.203-1.078v-1.428c0-.336-.054-.644-.161-.924a2.22 2.22 0 00-.448-.728 2.053 2.053 0 00-.686-.483 2.155 2.155 0 00-.875-.175h-2.03v.98h1.54c.588 0 .996.14 1.225.42.229.28.343.695.343 1.246v1.358c0 .383.07.723.21 1.022a2.7 2.7 0 001.106 1.225c.205.117.373.184.504.203v.084c-.13.019-.299.091-.504.217a2.744 2.744 0 00-.602.518c-.196.22-.364.478-.504.777-.14.299-.21.63-.21.994v1.344c0 .57-.121.99-.364 1.26s-.649.406-1.218.406h-1.526v.98h2.03zm8.75-1.134c.177-.056.371-.142.581-.259a2.42 2.42 0 001.043-1.162 2.36 2.36 0 00.182-.959c0-.448-.098-.796-.294-1.043-.196-.247-.471-.371-.826-.371-.29 0-.525.086-.707.259a.893.893 0 00-.273.679c0 .299.077.525.231.679.154.154.366.231.637.231.075 0 .177-.014.308-.042 0 .345-.121.64-.364.882-.243.243-.532.43-.868.56l.35.546z"/><path id="function" fill="#1C85B5" d="M22.512 57.8v-.938h-2.898v-5.124h2.898V50.8h-2.898c0-.69.112-1.188.336-1.491.224-.303.644-.455 1.26-.455.187 0 .392.016.616.049.224.033.457.1.7.203l.252-.91a3.603 3.603 0 00-.784-.224 5.473 5.473 0 00-.826-.056c-.85 0-1.503.196-1.96.588-.457.392-.686 1.027-.686 1.904v.392h-1.666v.938h1.666v5.124h-1.666v.938h5.656zm5.222.168c.57 0 1.055-.126 1.456-.378s.723-.579.966-.98h.056l.042 1.19h1.862v-.91h-.938a9.956 9.956 0 01-.084-1.316V50.8h-1.988v.938h.896v3.626c-.187.476-.46.873-.819 1.19-.36.317-.782.476-1.267.476-.336 0-.604-.054-.805-.161a1.046 1.046 0 01-.455-.476 2.317 2.317 0 01-.203-.77 9.693 9.693 0 01-.049-1.029V50.8h-2.03v.938h.938v3.08c0 .607.047 1.113.14 1.519.093.406.238.73.434.973s.446.413.749.511c.303.098.67.147 1.099.147zm7.07-.168v-4.396c.065-.233.168-.455.308-.665.14-.21.303-.394.49-.553a2.44 2.44 0 01.623-.385c.229-.098.464-.147.707-.147.663 0 1.12.196 1.372.588.252.392.378.975.378 1.75V57.8h1.092v-4.018c0-.625-.056-1.141-.168-1.547-.112-.406-.278-.728-.497-.966a1.738 1.738 0 00-.826-.497 4.219 4.219 0 00-1.141-.14 2.856 2.856 0 00-2.023.833c-.154.154-.278.31-.371.469h-.07l-.126-1.134h-1.876v.91h.938c.019.103.035.224.049.364a12.159 12.159 0 01.056.847c.005.135.007.245.007.329v4.55h1.078zm10.556.168c.364 0 .702-.033 1.015-.098a4.708 4.708 0 002.023-.952l-.49-.812c-.28.243-.628.439-1.043.588-.415.15-.842.224-1.281.224-.41 0-.786-.06-1.127-.182a2.517 2.517 0 01-.875-.518 2.248 2.248 0 01-.56-.819 2.902 2.902 0 01-.196-1.099c0-.933.224-1.615.672-2.044.448-.43 1.13-.644 2.044-.644.243 0 .488.026.735.077.247.051.478.114.693.189v1.33h1.008v-1.946l.014-.042a6.232 6.232 0 00-1.099-.406c-.434-.121-.996-.182-1.687-.182-.541 0-1.031.082-1.47.245a3.08 3.08 0 00-1.12.707c-.308.308-.544.69-.707 1.148-.163.457-.245.98-.245 1.568 0 .55.08 1.052.238 1.505.159.453.392.84.7 1.162.308.322.693.57 1.155.742.462.173.996.259 1.603.259zm8.722.014c.476 0 .94-.08 1.393-.238a3.938 3.938 0 001.169-.63l-.364-.826c-.252.187-.534.36-.847.518-.313.159-.679.238-1.099.238-.616 0-1.09-.163-1.421-.49-.331-.327-.497-.83-.497-1.512v-3.304h3.738V50.8h-3.738v-1.694l-1.092.308V50.8h-1.666v.938h1.666v3.472c0 .485.075.903.224 1.253.15.35.35.637.602.861.252.224.544.39.875.497a3.41 3.41 0 001.057.161zm7.966-8.302c.27 0 .497-.084.679-.252a.806.806 0 00.273-.616.889.889 0 00-.273-.651.922.922 0 00-.679-.273.838.838 0 00-.644.273.927.927 0 00-.252.651c0 .243.084.448.252.616a.872.872 0 00.644.252zm2.982 8.12v-.938h-2.38V50.8h-3.556v.938h2.436v5.124h-2.436v.938h5.936zm5.194.168a3.82 3.82 0 001.449-.259 2.907 2.907 0 001.071-.735c.29-.317.509-.702.658-1.155.15-.453.224-.959.224-1.519 0-.513-.068-.994-.203-1.442a3.168 3.168 0 00-.623-1.162 2.981 2.981 0 00-1.057-.777c-.425-.191-.931-.287-1.519-.287-1.092 0-1.932.329-2.52.987-.588.658-.882 1.552-.882 2.681 0 .513.068.994.203 1.442.135.448.343.835.623 1.162.28.327.635.586 1.064.777.43.191.933.287 1.512.287zm0-.938c-.41 0-.758-.08-1.043-.238a2.001 2.001 0 01-.693-.63 2.683 2.683 0 01-.385-.882 4.14 4.14 0 01-.119-.98c0-.905.187-1.587.56-2.044.373-.457.933-.686 1.68-.686.41 0 .758.08 1.043.238.285.159.518.369.7.63.182.261.313.553.392.875.08.322.119.651.119.987 0 .896-.189 1.575-.567 2.037-.378.462-.94.693-1.687.693zm6.58.77v-4.396c.065-.233.168-.455.308-.665.14-.21.303-.394.49-.553a2.44 2.44 0 01.623-.385c.229-.098.464-.147.707-.147.663 0 1.12.196 1.372.588.252.392.378.975.378 1.75V57.8h1.092v-4.018c0-.625-.056-1.141-.168-1.547-.112-.406-.278-.728-.497-.966a1.738 1.738 0 00-.826-.497 4.219 4.219 0 00-1.141-.14 2.856 2.856 0 00-2.023.833c-.154.154-.278.31-.371.469h-.07l-.126-1.134h-1.876v.91h.938c.019.103.035.224.049.364a12.159 12.159 0 01.056.847c.005.135.007.245.007.329v4.55h1.078z"/><path id="(){" fill="#7E7C7B" d="M97.272 60.768l.35-.966a4.965 4.965 0 01-1.337-.497 4.15 4.15 0 01-1.204-.994c-.36-.425-.649-.957-.868-1.596-.22-.64-.329-1.412-.329-2.317 0-.896.091-1.659.273-2.289.182-.63.439-1.157.77-1.582a3.928 3.928 0 011.183-1.022 7.086 7.086 0 011.512-.623l-.35-.882a6.005 6.005 0 00-1.729.665 4.984 4.984 0 00-1.435 1.246c-.41.518-.737 1.148-.98 1.89s-.364 1.608-.364 2.597c0 .999.119 1.862.357 2.59.238.728.56 1.344.966 1.848.406.504.882.912 1.428 1.225a6.964 6.964 0 001.757.707zm4.704 0a6.964 6.964 0 001.757-.707 5.036 5.036 0 001.428-1.225c.406-.504.728-1.12.966-1.848s.357-1.591.357-2.59c0-.99-.121-1.855-.364-2.597s-.57-1.372-.98-1.89a4.984 4.984 0 00-1.435-1.246 6.005 6.005 0 00-1.729-.665l-.35.882c.55.159 1.055.366 1.512.623.457.257.852.597 1.183 1.022.331.425.588.952.77 1.582.182.63.273 1.393.273 2.289 0 .905-.11 1.678-.329 2.317-.22.64-.509 1.171-.868 1.596a4.15 4.15 0 01-1.204.994 4.965 4.965 0 01-1.337.497l.35.966zm21.728.252v-.98h-1.526c-.57 0-.975-.135-1.218-.406-.243-.27-.364-.69-.364-1.26V57.03a2.25 2.25 0 00-.217-.994 3.347 3.347 0 00-.511-.777 2.744 2.744 0 00-.602-.518c-.205-.126-.369-.198-.49-.217v-.084c.13-.019.299-.086.504-.203a2.7 2.7 0 001.106-1.225c.14-.299.21-.64.21-1.022v-1.358c0-.55.114-.966.343-1.246.229-.28.637-.42 1.225-.42h1.54v-.98h-2.03c-.317 0-.609.058-.875.175a2.053 2.053 0 00-.686.483 2.22 2.22 0 00-.448.728c-.107.28-.161.588-.161.924v1.428c0 .43-.068.789-.203 1.078-.135.29-.303.525-.504.707a1.87 1.87 0 01-.644.392c-.229.08-.432.119-.609.119V55c.177 0 .38.047.609.14.229.093.443.238.644.434.2.196.369.441.504.735s.203.642.203 1.043v1.372c0 .756.198 1.328.595 1.715.397.387.922.581 1.575.581h2.03z"/><path id="alert" fill="#181717" d="M136.514 57.926a2.749 2.749 0 001.589-.469c.182-.126.329-.254.441-.385.112-.13.196-.238.252-.322h.07l.126 1.05h1.862v-.91h-.938c-.056-.42-.084-.863-.084-1.33.01-.401.023-.803.042-1.204.019-.401.028-.78.028-1.134 0-.308-.03-.614-.091-.917a2.049 2.049 0 00-.35-.812 1.893 1.893 0 00-.714-.581c-.303-.15-.693-.224-1.169-.224-.485 0-.98.051-1.484.154-.504.103-.957.27-1.358.504l.35.812c.299-.121.64-.24 1.022-.357a4.106 4.106 0 011.204-.175c.308 0 .567.035.777.105.21.07.373.189.49.357.117.168.191.394.224.679.033.285.026.642-.021 1.071a9.544 9.544 0 00-1.869-.112c-.555.028-1.029.126-1.421.294-.392.168-.693.41-.903.728-.21.317-.315.714-.315 1.19 0 .616.2 1.101.602 1.456.401.355.947.532 1.638.532zm.28-.938c-.495 0-.847-.114-1.057-.343a1.152 1.152 0 01-.315-.805c0-.299.084-.541.252-.728.168-.187.401-.324.7-.413a3.763 3.763 0 011.064-.133c.41 0 .859.042 1.344.126v.98a2.133 2.133 0 01-.672.868 2.22 2.22 0 01-.588.322 2.057 2.057 0 01-.728.126zm9.884.994c.159 0 .331-.019.518-.056a3.61 3.61 0 001.106-.42c.177-.103.34-.22.49-.35l-.504-.77c-.29.224-.553.383-.791.476-.238.093-.488.14-.749.14-.373 0-.656-.117-.847-.35-.191-.233-.287-.635-.287-1.204V48h-2.324v.938h1.232v6.51c0 .476.047.875.14 1.197.093.322.231.581.413.777.182.196.408.338.679.427.27.089.579.133.924.133zm7.672-.014c.299 0 .595-.026.889-.077.294-.051.576-.124.847-.217.27-.093.52-.205.749-.336.229-.13.427-.27.595-.42l-.434-.798a2.585 2.585 0 01-.399.28 3.72 3.72 0 01-.595.28c-.224.084-.46.156-.707.217-.247.06-.497.091-.749.091-.756 0-1.36-.208-1.813-.623-.453-.415-.679-1.043-.679-1.883h5.418c.047-.793-.01-1.44-.168-1.939-.159-.5-.385-.891-.679-1.176a2.295 2.295 0 00-1.015-.581 4.466 4.466 0 00-1.162-.154c-.541 0-1.031.082-1.47.245a3.08 3.08 0 00-1.12.707c-.308.308-.544.69-.707 1.148-.163.457-.245.98-.245 1.568 0 .56.075 1.064.224 1.512.15.448.369.833.658 1.155.29.322.649.57 1.078.742.43.173.924.259 1.484.259zm2.1-4.466h-4.354c.037-.364.124-.67.259-.917s.308-.448.518-.602c.21-.154.453-.264.728-.329a3.78 3.78 0 01.875-.098c.57 0 1.029.17 1.379.511.35.34.548.819.595 1.435zm8.554 4.298v-.938h-2.688v-4.13c.056-.084.145-.187.266-.308.121-.121.268-.243.441-.364s.376-.224.609-.308c.233-.084.495-.126.784-.126.308 0 .52.14.637.42.117.28.175.719.175 1.316l.98-.014c0-.42-.019-.796-.056-1.127a2.771 2.771 0 00-.217-.847 1.206 1.206 0 00-.448-.532c-.191-.121-.446-.182-.763-.182-.541 0-1.008.103-1.4.308a5.046 5.046 0 00-1.064.742h-.07l-.224-.91h-2.618v.938h1.89v5.124h-1.89v.938h5.656zm6.678.182c.476 0 .94-.08 1.393-.238a3.938 3.938 0 001.169-.63l-.364-.826c-.252.187-.534.36-.847.518-.313.159-.679.238-1.099.238-.616 0-1.09-.163-1.421-.49-.331-.327-.497-.83-.497-1.512v-3.304h3.738V50.8h-3.738v-1.694l-1.092.308V50.8h-1.666v.938h1.666v3.472c0 .485.075.903.224 1.253.15.35.35.637.602.861.252.224.544.39.875.497a3.41 3.41 0 001.057.161z"/><path id="(" fill="#7E7C7B" d="M181.272 60.768l.35-.966a4.965 4.965 0 01-1.337-.497 4.15 4.15 0 01-1.204-.994c-.36-.425-.649-.957-.868-1.596-.22-.64-.329-1.412-.329-2.317 0-.896.091-1.659.273-2.289.182-.63.439-1.157.77-1.582a3.928 3.928 0 011.183-1.022 7.086 7.086 0 011.512-.623l-.35-.882a6.005 6.005 0 00-1.729.665 4.984 4.984 0 00-1.435 1.246c-.41.518-.737 1.148-.98 1.89s-.364 1.608-.364 2.597c0 .999.119 1.862.357 2.59.238.728.56 1.344.966 1.848.406.504.882.912 1.428 1.225a6.964 6.964 0 001.757.707z"/><path id="j" fill="#181717" d="M188.636 49.68c.27 0 .497-.084.679-.252a.806.806 0 00.273-.616.889.889 0 00-.273-.651.922.922 0 00-.679-.273.838.838 0 00-.644.273.927.927 0 00-.252.651c0 .243.084.448.252.616a.872.872 0 00.644.252zm-1.904 11.088c.85 0 1.514-.231 1.995-.693.48-.462.721-1.164.721-2.107V50.8h-4.508v.938h3.388v6.02c0 .616-.119 1.099-.357 1.449-.238.35-.637.525-1.197.525-.345 0-.679-.07-1.001-.21a4.362 4.362 0 01-.861-.49l-.462.91a4.501 4.501 0 00.882.497c.205.089.427.166.665.231.238.065.483.098.735.098z"/><path id=");}," fill="#7E7C7B" d="M194.376 60.768a6.964 6.964 0 001.757-.707 5.036 5.036 0 001.428-1.225c.406-.504.728-1.12.966-1.848s.357-1.591.357-2.59c0-.99-.121-1.855-.364-2.597s-.57-1.372-.98-1.89a4.984 4.984 0 00-1.435-1.246 6.005 6.005 0 00-1.729-.665l-.35.882c.55.159 1.055.366 1.512.623.457.257.852.597 1.183 1.022.331.425.588.952.77 1.582.182.63.273 1.393.273 2.289 0 .905-.11 1.678-.329 2.317-.22.64-.509 1.171-.868 1.596a4.15 4.15 0 01-1.204.994 4.965 4.965 0 01-1.337.497l.35.966zm10.304-8.302c.299 0 .532-.089.7-.266a.938.938 0 00.252-.672c0-.299-.084-.53-.252-.693-.168-.163-.401-.245-.7-.245-.28 0-.504.082-.672.245-.168.163-.252.394-.252.693 0 .27.084.495.252.672.168.177.392.266.672.266zm-.756 7.42c.177-.056.371-.142.581-.259a2.42 2.42 0 001.043-1.162 2.36 2.36 0 00.182-.959c0-.448-.098-.796-.294-1.043-.196-.247-.471-.371-.826-.371-.29 0-.525.086-.707.259a.893.893 0 00-.273.679c0 .299.077.525.231.679.154.154.366.231.637.231.075 0 .177-.014.308-.042 0 .345-.121.64-.364.882-.243.243-.532.43-.868.56l.35.546zm16.45 1.134c.653 0 1.178-.194 1.575-.581.397-.387.595-.959.595-1.715v-1.372c0-.401.068-.749.203-1.043a2.44 2.44 0 01.504-.735c.2-.196.415-.34.644-.434.229-.093.432-.14.609-.14v-.98c-.177 0-.38-.04-.609-.119a1.87 1.87 0 01-.644-.392 2.193 2.193 0 01-.504-.707c-.135-.29-.203-.649-.203-1.078v-1.428c0-.336-.054-.644-.161-.924a2.22 2.22 0 00-.448-.728 2.053 2.053 0 00-.686-.483 2.155 2.155 0 00-.875-.175h-2.03v.98h1.54c.588 0 .996.14 1.225.42.229.28.343.695.343 1.246v1.358c0 .383.07.723.21 1.022a2.7 2.7 0 001.106 1.225c.205.117.373.184.504.203v.084c-.13.019-.299.091-.504.217a2.744 2.744 0 00-.602.518c-.196.22-.364.478-.504.777-.14.299-.21.63-.21.994v1.344c0 .57-.121.99-.364 1.26s-.649.406-1.218.406h-1.526v.98h2.03zm8.75-1.134c.177-.056.371-.142.581-.259a2.42 2.42 0 001.043-1.162 2.36 2.36 0 00.182-.959c0-.448-.098-.796-.294-1.043-.196-.247-.471-.371-.826-.371-.29 0-.525.086-.707.259a.893.893 0 00-.273.679c0 .299.077.525.231.679.154.154.366.231.637.231.075 0 .177-.014.308-.042 0 .345-.121.64-.364.882-.243.243-.532.43-.868.56l.35.546z"/><path id="function" fill="#1C85B5" d="M22.512 81.8v-.938h-2.898v-5.124h2.898V74.8h-2.898c0-.69.112-1.188.336-1.491.224-.303.644-.455 1.26-.455.187 0 .392.016.616.049.224.033.457.1.7.203l.252-.91a3.603 3.603 0 00-.784-.224 5.473 5.473 0 00-.826-.056c-.85 0-1.503.196-1.96.588-.457.392-.686 1.027-.686 1.904v.392h-1.666v.938h1.666v5.124h-1.666v.938h5.656zm5.222.168c.57 0 1.055-.126 1.456-.378s.723-.579.966-.98h.056l.042 1.19h1.862v-.91h-.938a9.956 9.956 0 01-.084-1.316V74.8h-1.988v.938h.896v3.626c-.187.476-.46.873-.819 1.19-.36.317-.782.476-1.267.476-.336 0-.604-.054-.805-.161a1.046 1.046 0 01-.455-.476 2.317 2.317 0 01-.203-.77 9.693 9.693 0 01-.049-1.029V74.8h-2.03v.938h.938v3.08c0 .607.047 1.113.14 1.519.093.406.238.73.434.973s.446.413.749.511c.303.098.67.147 1.099.147zm7.07-.168v-4.396c.065-.233.168-.455.308-.665.14-.21.303-.394.49-.553a2.44 2.44 0 01.623-.385c.229-.098.464-.147.707-.147.663 0 1.12.196 1.372.588.252.392.378.975.378 1.75V81.8h1.092v-4.018c0-.625-.056-1.141-.168-1.547-.112-.406-.278-.728-.497-.966a1.738 1.738 0 00-.826-.497 4.219 4.219 0 00-1.141-.14 2.856 2.856 0 00-2.023.833c-.154.154-.278.31-.371.469h-.07l-.126-1.134h-1.876v.91h.938c.019.103.035.224.049.364a12.159 12.159 0 01.056.847c.005.135.007.245.007.329v4.55h1.078zm10.556.168c.364 0 .702-.033 1.015-.098a4.708 4.708 0 002.023-.952l-.49-.812c-.28.243-.628.439-1.043.588-.415.15-.842.224-1.281.224-.41 0-.786-.06-1.127-.182a2.517 2.517 0 01-.875-.518 2.248 2.248 0 01-.56-.819 2.902 2.902 0 01-.196-1.099c0-.933.224-1.615.672-2.044.448-.43 1.13-.644 2.044-.644.243 0 .488.026.735.077.247.051.478.114.693.189v1.33h1.008v-1.946l.014-.042a6.232 6.232 0 00-1.099-.406c-.434-.121-.996-.182-1.687-.182-.541 0-1.031.082-1.47.245a3.08 3.08 0 00-1.12.707c-.308.308-.544.69-.707 1.148-.163.457-.245.98-.245 1.568 0 .55.08 1.052.238 1.505.159.453.392.84.7 1.162.308.322.693.57 1.155.742.462.173.996.259 1.603.259zm8.722.014c.476 0 .94-.08 1.393-.238a3.938 3.938 0 001.169-.63l-.364-.826c-.252.187-.534.36-.847.518-.313.159-.679.238-1.099.238-.616 0-1.09-.163-1.421-.49-.331-.327-.497-.83-.497-1.512v-3.304h3.738V74.8h-3.738v-1.694l-1.092.308V74.8h-1.666v.938h1.666v3.472c0 .485.075.903.224 1.253.15.35.35.637.602.861.252.224.544.39.875.497a3.41 3.41 0 001.057.161zm7.966-8.302c.27 0 .497-.084.679-.252a.806.806 0 00.273-.616.889.889 0 00-.273-.651.922.922 0 00-.679-.273.838.838 0 00-.644.273.927.927 0 00-.252.651c0 .243.084.448.252.616a.872.872 0 00.644.252zm2.982 8.12v-.938h-2.38V74.8h-3.556v.938h2.436v5.124h-2.436v.938h5.936zm5.194.168a3.82 3.82 0 001.449-.259 2.907 2.907 0 001.071-.735c.29-.317.509-.702.658-1.155.15-.453.224-.959.224-1.519 0-.513-.068-.994-.203-1.442a3.168 3.168 0 00-.623-1.162 2.981 2.981 0 00-1.057-.777c-.425-.191-.931-.287-1.519-.287-1.092 0-1.932.329-2.52.987-.588.658-.882 1.552-.882 2.681 0 .513.068.994.203 1.442.135.448.343.835.623 1.162.28.327.635.586 1.064.777.43.191.933.287 1.512.287zm0-.938c-.41 0-.758-.08-1.043-.238a2.001 2.001 0 01-.693-.63 2.683 2.683 0 01-.385-.882 4.14 4.14 0 01-.119-.98c0-.905.187-1.587.56-2.044.373-.457.933-.686 1.68-.686.41 0 .758.08 1.043.238.285.159.518.369.7.63.182.261.313.553.392.875.08.322.119.651.119.987 0 .896-.189 1.575-.567 2.037-.378.462-.94.693-1.687.693zm6.58.77v-4.396c.065-.233.168-.455.308-.665.14-.21.303-.394.49-.553a2.44 2.44 0 01.623-.385c.229-.098.464-.147.707-.147.663 0 1.12.196 1.372.588.252.392.378.975.378 1.75V81.8h1.092v-4.018c0-.625-.056-1.141-.168-1.547-.112-.406-.278-.728-.497-.966a1.738 1.738 0 00-.826-.497 4.219 4.219 0 00-1.141-.14 2.856 2.856 0 00-2.023.833c-.154.154-.278.31-.371.469h-.07l-.126-1.134h-1.876v.91h.938c.019.103.035.224.049.364a12.159 12.159 0 01.056.847c.005.135.007.245.007.329v4.55h1.078z"/><path id="(){" fill="#7E7C7B" d="M97.272 84.768l.35-.966a4.965 4.965 0 01-1.337-.497 4.15 4.15 0 01-1.204-.994c-.36-.425-.649-.957-.868-1.596-.22-.64-.329-1.412-.329-2.317 0-.896.091-1.659.273-2.289.182-.63.439-1.157.77-1.582a3.928 3.928 0 011.183-1.022 7.086 7.086 0 011.512-.623l-.35-.882a6.005 6.005 0 00-1.729.665 4.984 4.984 0 00-1.435 1.246c-.41.518-.737 1.148-.98 1.89s-.364 1.608-.364 2.597c0 .999.119 1.862.357 2.59.238.728.56 1.344.966 1.848.406.504.882.912 1.428 1.225a6.964 6.964 0 001.757.707zm4.704 0a6.964 6.964 0 001.757-.707 5.036 5.036 0 001.428-1.225c.406-.504.728-1.12.966-1.848s.357-1.591.357-2.59c0-.99-.121-1.855-.364-2.597s-.57-1.372-.98-1.89a4.984 4.984 0 00-1.435-1.246 6.005 6.005 0 00-1.729-.665l-.35.882c.55.159 1.055.366 1.512.623.457.257.852.597 1.183 1.022.331.425.588.952.77 1.582.182.63.273 1.393.273 2.289 0 .905-.11 1.678-.329 2.317-.22.64-.509 1.171-.868 1.596a4.15 4.15 0 01-1.204.994 4.965 4.965 0 01-1.337.497l.35.966zm21.728.252v-.98h-1.526c-.57 0-.975-.135-1.218-.406-.243-.27-.364-.69-.364-1.26V81.03a2.25 2.25 0 00-.217-.994 3.347 3.347 0 00-.511-.777 2.744 2.744 0 00-.602-.518c-.205-.126-.369-.198-.49-.217v-.084c.13-.019.299-.086.504-.203a2.7 2.7 0 001.106-1.225c.14-.299.21-.64.21-1.022v-1.358c0-.55.114-.966.343-1.246.229-.28.637-.42 1.225-.42h1.54v-.98h-2.03c-.317 0-.609.058-.875.175a2.053 2.053 0 00-.686.483 2.22 2.22 0 00-.448.728c-.107.28-.161.588-.161.924v1.428c0 .43-.068.789-.203 1.078-.135.29-.303.525-.504.707a1.87 1.87 0 01-.644.392c-.229.08-.432.119-.609.119V79c.177 0 .38.047.609.14.229.093.443.238.644.434.2.196.369.441.504.735s.203.642.203 1.043v1.372c0 .756.198 1.328.595 1.715.397.387.922.581 1.575.581h2.03z"/><path id="alert" fill="#181717" d="M136.514 81.926a2.749 2.749 0 001.589-.469c.182-.126.329-.254.441-.385.112-.13.196-.238.252-.322h.07l.126 1.05h1.862v-.91h-.938c-.056-.42-.084-.863-.084-1.33.01-.401.023-.803.042-1.204.019-.401.028-.78.028-1.134 0-.308-.03-.614-.091-.917a2.049 2.049 0 00-.35-.812 1.893 1.893 0 00-.714-.581c-.303-.15-.693-.224-1.169-.224-.485 0-.98.051-1.484.154-.504.103-.957.27-1.358.504l.35.812c.299-.121.64-.24 1.022-.357a4.106 4.106 0 011.204-.175c.308 0 .567.035.777.105.21.07.373.189.49.357.117.168.191.394.224.679.033.285.026.642-.021 1.071a9.544 9.544 0 00-1.869-.112c-.555.028-1.029.126-1.421.294-.392.168-.693.41-.903.728-.21.317-.315.714-.315 1.19 0 .616.2 1.101.602 1.456.401.355.947.532 1.638.532zm.28-.938c-.495 0-.847-.114-1.057-.343a1.152 1.152 0 01-.315-.805c0-.299.084-.541.252-.728.168-.187.401-.324.7-.413a3.763 3.763 0 011.064-.133c.41 0 .859.042 1.344.126v.98a2.133 2.133 0 01-.672.868 2.22 2.22 0 01-.588.322 2.057 2.057 0 01-.728.126zm9.884.994c.159 0 .331-.019.518-.056a3.61 3.61 0 001.106-.42c.177-.103.34-.22.49-.35l-.504-.77c-.29.224-.553.383-.791.476-.238.093-.488.14-.749.14-.373 0-.656-.117-.847-.35-.191-.233-.287-.635-.287-1.204V72h-2.324v.938h1.232v6.51c0 .476.047.875.14 1.197.093.322.231.581.413.777.182.196.408.338.679.427.27.089.579.133.924.133zm7.672-.014c.299 0 .595-.026.889-.077.294-.051.576-.124.847-.217.27-.093.52-.205.749-.336.229-.13.427-.27.595-.42l-.434-.798a2.585 2.585 0 01-.399.28 3.72 3.72 0 01-.595.28c-.224.084-.46.156-.707.217-.247.06-.497.091-.749.091-.756 0-1.36-.208-1.813-.623-.453-.415-.679-1.043-.679-1.883h5.418c.047-.793-.01-1.44-.168-1.939-.159-.5-.385-.891-.679-1.176a2.295 2.295 0 00-1.015-.581 4.466 4.466 0 00-1.162-.154c-.541 0-1.031.082-1.47.245a3.08 3.08 0 00-1.12.707c-.308.308-.544.69-.707 1.148-.163.457-.245.98-.245 1.568 0 .56.075 1.064.224 1.512.15.448.369.833.658 1.155.29.322.649.57 1.078.742.43.173.924.259 1.484.259zm2.1-4.466h-4.354c.037-.364.124-.67.259-.917s.308-.448.518-.602c.21-.154.453-.264.728-.329a3.78 3.78 0 01.875-.098c.57 0 1.029.17 1.379.511.35.34.548.819.595 1.435zm8.554 4.298v-.938h-2.688v-4.13c.056-.084.145-.187.266-.308.121-.121.268-.243.441-.364s.376-.224.609-.308c.233-.084.495-.126.784-.126.308 0 .52.14.637.42.117.28.175.719.175 1.316l.98-.014c0-.42-.019-.796-.056-1.127a2.771 2.771 0 00-.217-.847 1.206 1.206 0 00-.448-.532c-.191-.121-.446-.182-.763-.182-.541 0-1.008.103-1.4.308a5.046 5.046 0 00-1.064.742h-.07l-.224-.91h-2.618v.938h1.89v5.124h-1.89v.938h5.656zm6.678.182c.476 0 .94-.08 1.393-.238a3.938 3.938 0 001.169-.63l-.364-.826c-.252.187-.534.36-.847.518-.313.159-.679.238-1.099.238-.616 0-1.09-.163-1.421-.49-.331-.327-.497-.83-.497-1.512v-3.304h3.738V74.8h-3.738v-1.694l-1.092.308V74.8h-1.666v.938h1.666v3.472c0 .485.075.903.224 1.253.15.35.35.637.602.861.252.224.544.39.875.497a3.41 3.41 0 001.057.161z"/><path id="(" fill="#7E7C7B" d="M181.272 84.768l.35-.966a4.965 4.965 0 01-1.337-.497 4.15 4.15 0 01-1.204-.994c-.36-.425-.649-.957-.868-1.596-.22-.64-.329-1.412-.329-2.317 0-.896.091-1.659.273-2.289.182-.63.439-1.157.77-1.582a3.928 3.928 0 011.183-1.022 7.086 7.086 0 011.512-.623l-.35-.882a6.005 6.005 0 00-1.729.665 4.984 4.984 0 00-1.435 1.246c-.41.518-.737 1.148-.98 1.89s-.364 1.608-.364 2.597c0 .999.119 1.862.357 2.59.238.728.56 1.344.966 1.848.406.504.882.912 1.428 1.225a6.964 6.964 0 001.757.707z"/><path id="j" fill="#181717" d="M188.636 73.68c.27 0 .497-.084.679-.252a.806.806 0 00.273-.616.889.889 0 00-.273-.651.922.922 0 00-.679-.273.838.838 0 00-.644.273.927.927 0 00-.252.651c0 .243.084.448.252.616a.872.872 0 00.644.252zm-1.904 11.088c.85 0 1.514-.231 1.995-.693.48-.462.721-1.164.721-2.107V74.8h-4.508v.938h3.388v6.02c0 .616-.119 1.099-.357 1.449-.238.35-.637.525-1.197.525-.345 0-.679-.07-1.001-.21a4.362 4.362 0 01-.861-.49l-.462.91a4.501 4.501 0 00.882.497c.205.089.427.166.665.231.238.065.483.098.735.098z"/><path id=");}," fill="#7E7C7B" d="M194.376 84.768a6.964 6.964 0 001.757-.707 5.036 5.036 0 001.428-1.225c.406-.504.728-1.12.966-1.848s.357-1.591.357-2.59c0-.99-.121-1.855-.364-2.597s-.57-1.372-.98-1.89a4.984 4.984 0 00-1.435-1.246 6.005 6.005 0 00-1.729-.665l-.35.882c.55.159 1.055.366 1.512.623.457.257.852.597 1.183 1.022.331.425.588.952.77 1.582.182.63.273 1.393.273 2.289 0 .905-.11 1.678-.329 2.317-.22.64-.509 1.171-.868 1.596a4.15 4.15 0 01-1.204.994 4.965 4.965 0 01-1.337.497l.35.966zm10.304-8.302c.299 0 .532-.089.7-.266a.938.938 0 00.252-.672c0-.299-.084-.53-.252-.693-.168-.163-.401-.245-.7-.245-.28 0-.504.082-.672.245-.168.163-.252.394-.252.693 0 .27.084.495.252.672.168.177.392.266.672.266zm-.756 7.42c.177-.056.371-.142.581-.259a2.42 2.42 0 001.043-1.162 2.36 2.36 0 00.182-.959c0-.448-.098-.796-.294-1.043-.196-.247-.471-.371-.826-.371-.29 0-.525.086-.707.259a.893.893 0 00-.273.679c0 .299.077.525.231.679.154.154.366.231.637.231.075 0 .177-.014.308-.042 0 .345-.121.64-.364.882-.243.243-.532.43-.868.56l.35.546zm16.45 1.134c.653 0 1.178-.194 1.575-.581.397-.387.595-.959.595-1.715v-1.372c0-.401.068-.749.203-1.043a2.44 2.44 0 01.504-.735c.2-.196.415-.34.644-.434.229-.093.432-.14.609-.14v-.98c-.177 0-.38-.04-.609-.119a1.87 1.87 0 01-.644-.392 2.193 2.193 0 01-.504-.707c-.135-.29-.203-.649-.203-1.078v-1.428c0-.336-.054-.644-.161-.924a2.22 2.22 0 00-.448-.728 2.053 2.053 0 00-.686-.483 2.155 2.155 0 00-.875-.175h-2.03v.98h1.54c.588 0 .996.14 1.225.42.229.28.343.695.343 1.246v1.358c0 .383.07.723.21 1.022a2.7 2.7 0 001.106 1.225c.205.117.373.184.504.203v.084c-.13.019-.299.091-.504.217a2.744 2.744 0 00-.602.518c-.196.22-.364.478-.504.777-.14.299-.21.63-.21.994v1.344c0 .57-.121.99-.364 1.26s-.649.406-1.218.406h-1.526v.98h2.03zm8.75-1.134c.177-.056.371-.142.581-.259a2.42 2.42 0 001.043-1.162 2.36 2.36 0 00.182-.959c0-.448-.098-.796-.294-1.043-.196-.247-.471-.371-.826-.371-.29 0-.525.086-.707.259a.893.893 0 00-.273.679c0 .299.077.525.231.679.154.154.366.231.637.231.075 0 .177-.014.308-.042 0 .345-.121.64-.364.882-.243.243-.532.43-.868.56l.35.546z"/><path id="..." fill="#181717" d="M19.81 105.968c.299 0 .532-.089.7-.266a.938.938 0 00.252-.672c0-.299-.084-.53-.252-.693-.168-.163-.401-.245-.7-.245-.28 0-.504.082-.672.245-.168.163-.252.394-.252.693 0 .27.084.495.252.672.168.177.392.266.672.266zm8.4 0c.299 0 .532-.089.7-.266a.938.938 0 00.252-.672c0-.299-.084-.53-.252-.693-.168-.163-.401-.245-.7-.245-.28 0-.504.082-.672.245-.168.163-.252.394-.252.693 0 .27.084.495.252.672.168.177.392.266.672.266zm8.4 0c.299 0 .532-.089.7-.266a.938.938 0 00.252-.672c0-.299-.084-.53-.252-.693-.168-.163-.401-.245-.7-.245-.28 0-.504.082-.672.245-.168.163-.252.394-.252.693 0 .27.084.495.252.672.168.177.392.266.672.266z"/><path id="function" fill="#1C85B5" d="M22.512 129.8v-.938h-2.898v-5.124h2.898v-.938h-2.898c0-.69.112-1.188.336-1.491.224-.303.644-.455 1.26-.455.187 0 .392.016.616.049.224.033.457.1.7.203l.252-.91a3.603 3.603 0 00-.784-.224 5.473 5.473 0 00-.826-.056c-.85 0-1.503.196-1.96.588-.457.392-.686 1.027-.686 1.904v.392h-1.666v.938h1.666v5.124h-1.666v.938h5.656zm5.222.168c.57 0 1.055-.126 1.456-.378s.723-.579.966-.98h.056l.042 1.19h1.862v-.91h-.938a9.956 9.956 0 01-.084-1.316V122.8h-1.988v.938h.896v3.626c-.187.476-.46.873-.819 1.19-.36.317-.782.476-1.267.476-.336 0-.604-.054-.805-.161a1.046 1.046 0 01-.455-.476 2.317 2.317 0 01-.203-.77 9.693 9.693 0 01-.049-1.029V122.8h-2.03v.938h.938v3.08c0 .607.047 1.113.14 1.519.093.406.238.73.434.973s.446.413.749.511c.303.098.67.147 1.099.147zm7.07-.168v-4.396c.065-.233.168-.455.308-.665.14-.21.303-.394.49-.553a2.44 2.44 0 01.623-.385c.229-.098.464-.147.707-.147.663 0 1.12.196 1.372.588.252.392.378.975.378 1.75v3.808h1.092v-4.018c0-.625-.056-1.141-.168-1.547-.112-.406-.278-.728-.497-.966a1.738 1.738 0 00-.826-.497 4.219 4.219 0 00-1.141-.14 2.856 2.856 0 00-2.023.833c-.154.154-.278.31-.371.469h-.07l-.126-1.134h-1.876v.91h.938c.019.103.035.224.049.364a12.158 12.158 0 01.056.847c.005.135.007.245.007.329v4.55h1.078zm10.556.168c.364 0 .702-.033 1.015-.098a4.708 4.708 0 002.023-.952l-.49-.812c-.28.243-.628.439-1.043.588-.415.15-.842.224-1.281.224-.41 0-.786-.06-1.127-.182a2.517 2.517 0 01-.875-.518 2.248 2.248 0 01-.56-.819 2.902 2.902 0 01-.196-1.099c0-.933.224-1.615.672-2.044.448-.43 1.13-.644 2.044-.644.243 0 .488.026.735.077.247.051.478.114.693.189v1.33h1.008v-1.946l.014-.042a6.232 6.232 0 00-1.099-.406c-.434-.121-.996-.182-1.687-.182-.541 0-1.031.082-1.47.245a3.08 3.08 0 00-1.12.707c-.308.308-.544.69-.707 1.148-.163.457-.245.98-.245 1.568 0 .55.08 1.052.238 1.505.159.453.392.84.7 1.162.308.322.693.57 1.155.742.462.173.996.259 1.603.259zm8.722.014c.476 0 .94-.08 1.393-.238a3.938 3.938 0 001.169-.63l-.364-.826c-.252.187-.534.36-.847.518-.313.159-.679.238-1.099.238-.616 0-1.09-.163-1.421-.49-.331-.327-.497-.83-.497-1.512v-3.304h3.738v-.938h-3.738v-1.694l-1.092.308v1.386h-1.666v.938h1.666v3.472c0 .485.075.903.224 1.253.15.35.35.637.602.861.252.224.544.39.875.497a3.41 3.41 0 001.057.161zm7.966-8.302c.27 0 .497-.084.679-.252a.806.806 0 00.273-.616.889.889 0 00-.273-.651.922.922 0 00-.679-.273.838.838 0 00-.644.273.927.927 0 00-.252.651c0 .243.084.448.252.616a.872.872 0 00.644.252zm2.982 8.12v-.938h-2.38V122.8h-3.556v.938h2.436v5.124h-2.436v.938h5.936zm5.194.168a3.82 3.82 0 001.449-.259 2.908 2.908 0 001.071-.735c.29-.317.509-.702.658-1.155.15-.453.224-.959.224-1.519 0-.513-.068-.994-.203-1.442a3.168 3.168 0 00-.623-1.162 2.981 2.981 0 00-1.057-.777c-.425-.191-.931-.287-1.519-.287-1.092 0-1.932.329-2.52.987-.588.658-.882 1.552-.882 2.681 0 .513.068.994.203 1.442.135.448.343.835.623 1.162.28.327.635.586 1.064.777.43.191.933.287 1.512.287zm0-.938c-.41 0-.758-.08-1.043-.238a2.001 2.001 0 01-.693-.63 2.683 2.683 0 01-.385-.882 4.14 4.14 0 01-.119-.98c0-.905.187-1.587.56-2.044.373-.457.933-.686 1.68-.686.41 0 .758.08 1.043.238.285.159.518.369.7.63.182.261.313.553.392.875.08.322.119.651.119.987 0 .896-.189 1.575-.567 2.037-.378.462-.94.693-1.687.693zm6.58.77v-4.396c.065-.233.168-.455.308-.665.14-.21.303-.394.49-.553a2.44 2.44 0 01.623-.385c.229-.098.464-.147.707-.147.663 0 1.12.196 1.372.588.252.392.378.975.378 1.75v3.808h1.092v-4.018c0-.625-.056-1.141-.168-1.547-.112-.406-.278-.728-.497-.966a1.738 1.738 0 00-.826-.497 4.219 4.219 0 00-1.141-.14 2.856 2.856 0 00-2.023.833c-.154.154-.278.31-.371.469h-.07l-.126-1.134h-1.876v.91h.938c.019.103.035.224.049.364a12.158 12.158 0 01.056.847c.005.135.007.245.007.329v4.55h1.078z"/><path id="(){" fill="#7E7C7B" d="M97.272 132.768l.35-.966a4.965 4.965 0 01-1.337-.497 4.15 4.15 0 01-1.204-.994c-.36-.425-.649-.957-.868-1.596-.22-.64-.329-1.412-.329-2.317 0-.896.091-1.659.273-2.289.182-.63.439-1.157.77-1.582a3.928 3.928 0 011.183-1.022 7.086 7.086 0 011.512-.623l-.35-.882a6.005 6.005 0 00-1.729.665 4.984 4.984 0 00-1.435 1.246c-.41.518-.737 1.148-.98 1.89s-.364 1.608-.364 2.597c0 .999.119 1.862.357 2.59.238.728.56 1.344.966 1.848.406.504.882.912 1.428 1.225a6.964 6.964 0 001.757.707zm4.704 0a6.964 6.964 0 001.757-.707 5.036 5.036 0 001.428-1.225c.406-.504.728-1.12.966-1.848s.357-1.591.357-2.59c0-.99-.121-1.855-.364-2.597s-.57-1.372-.98-1.89a4.984 4.984 0 00-1.435-1.246 6.005 6.005 0 00-1.729-.665l-.35.882c.55.159 1.055.366 1.512.623.457.257.852.597 1.183 1.022.331.425.588.952.77 1.582.182.63.273 1.393.273 2.289 0 .905-.11 1.678-.329 2.317-.22.64-.509 1.171-.868 1.596a4.15 4.15 0 01-1.204.994 4.965 4.965 0 01-1.337.497l.35.966zm21.728.252v-.98h-1.526c-.57 0-.975-.135-1.218-.406-.243-.27-.364-.69-.364-1.26v-1.344a2.25 2.25 0 00-.217-.994 3.347 3.347 0 00-.511-.777 2.744 2.744 0 00-.602-.518c-.205-.126-.369-.198-.49-.217v-.084c.13-.019.299-.086.504-.203a2.7 2.7 0 001.106-1.225c.14-.299.21-.64.21-1.022v-1.358c0-.55.114-.966.343-1.246.229-.28.637-.42 1.225-.42h1.54v-.98h-2.03c-.317 0-.609.058-.875.175a2.053 2.053 0 00-.686.483 2.22 2.22 0 00-.448.728c-.107.28-.161.588-.161.924v1.428c0 .43-.068.789-.203 1.078-.135.29-.303.525-.504.707a1.87 1.87 0 01-.644.392c-.229.08-.432.119-.609.119v.98c.177 0 .38.047.609.14.229.093.443.238.644.434.2.196.369.441.504.735s.203.642.203 1.043v1.372c0 .756.198 1.328.595 1.715.397.387.922.581 1.575.581h2.03z"/><path id="alert" fill="#181717" d="M136.514 129.926a2.749 2.749 0 001.589-.469c.182-.126.329-.254.441-.385.112-.13.196-.238.252-.322h.07l.126 1.05h1.862v-.91h-.938c-.056-.42-.084-.863-.084-1.33.01-.401.023-.803.042-1.204.019-.401.028-.78.028-1.134 0-.308-.03-.614-.091-.917a2.049 2.049 0 00-.35-.812 1.893 1.893 0 00-.714-.581c-.303-.15-.693-.224-1.169-.224-.485 0-.98.051-1.484.154-.504.103-.957.27-1.358.504l.35.812c.299-.121.64-.24 1.022-.357a4.106 4.106 0 011.204-.175c.308 0 .567.035.777.105.21.07.373.189.49.357.117.168.191.394.224.679.033.285.026.642-.021 1.071a9.544 9.544 0 00-1.869-.112c-.555.028-1.029.126-1.421.294-.392.168-.693.41-.903.728-.21.317-.315.714-.315 1.19 0 .616.2 1.101.602 1.456.401.355.947.532 1.638.532zm.28-.938c-.495 0-.847-.114-1.057-.343a1.152 1.152 0 01-.315-.805c0-.299.084-.541.252-.728.168-.187.401-.324.7-.413a3.763 3.763 0 011.064-.133c.41 0 .859.042 1.344.126v.98a2.133 2.133 0 01-.672.868 2.22 2.22 0 01-.588.322 2.057 2.057 0 01-.728.126zm9.884.994c.159 0 .331-.019.518-.056a3.61 3.61 0 001.106-.42c.177-.103.34-.22.49-.35l-.504-.77c-.29.224-.553.383-.791.476-.238.093-.488.14-.749.14-.373 0-.656-.117-.847-.35-.191-.233-.287-.635-.287-1.204V120h-2.324v.938h1.232v6.51c0 .476.047.875.14 1.197.093.322.231.581.413.777.182.196.408.338.679.427.27.089.579.133.924.133zm7.672-.014c.299 0 .595-.026.889-.077.294-.051.576-.124.847-.217.27-.093.52-.205.749-.336.229-.13.427-.27.595-.42l-.434-.798a2.585 2.585 0 01-.399.28 3.72 3.72 0 01-.595.28c-.224.084-.46.156-.707.217-.247.06-.497.091-.749.091-.756 0-1.36-.208-1.813-.623-.453-.415-.679-1.043-.679-1.883h5.418c.047-.793-.01-1.44-.168-1.939-.159-.5-.385-.891-.679-1.176a2.295 2.295 0 00-1.015-.581 4.466 4.466 0 00-1.162-.154c-.541 0-1.031.082-1.47.245a3.08 3.08 0 00-1.12.707c-.308.308-.544.69-.707 1.148-.163.457-.245.98-.245 1.568 0 .56.075 1.064.224 1.512.15.448.369.833.658 1.155.29.322.649.57 1.078.742.43.173.924.259 1.484.259zm2.1-4.466h-4.354c.037-.364.124-.67.259-.917s.308-.448.518-.602c.21-.154.453-.264.728-.329a3.78 3.78 0 01.875-.098c.57 0 1.029.17 1.379.511.35.34.548.819.595 1.435zm8.554 4.298v-.938h-2.688v-4.13c.056-.084.145-.187.266-.308.121-.121.268-.243.441-.364s.376-.224.609-.308c.233-.084.495-.126.784-.126.308 0 .52.14.637.42.117.28.175.719.175 1.316l.98-.014c0-.42-.019-.796-.056-1.127a2.771 2.771 0 00-.217-.847 1.206 1.206 0 00-.448-.532c-.191-.121-.446-.182-.763-.182-.541 0-1.008.103-1.4.308a5.046 5.046 0 00-1.064.742h-.07l-.224-.91h-2.618v.938h1.89v5.124h-1.89v.938h5.656zm6.678.182c.476 0 .94-.08 1.393-.238a3.938 3.938 0 001.169-.63l-.364-.826c-.252.187-.534.36-.847.518-.313.159-.679.238-1.099.238-.616 0-1.09-.163-1.421-.49-.331-.327-.497-.83-.497-1.512v-3.304h3.738v-.938h-3.738v-1.694l-1.092.308v1.386h-1.666v.938h1.666v3.472c0 .485.075.903.224 1.253.15.35.35.637.602.861.252.224.544.39.875.497a3.41 3.41 0 001.057.161z"/><path id="(" fill="#7E7C7B" d="M181.272 132.768l.35-.966a4.965 4.965 0 01-1.337-.497 4.15 4.15 0 01-1.204-.994c-.36-.425-.649-.957-.868-1.596-.22-.64-.329-1.412-.329-2.317 0-.896.091-1.659.273-2.289.182-.63.439-1.157.77-1.582a3.928 3.928 0 011.183-1.022 7.086 7.086 0 011.512-.623l-.35-.882a6.005 6.005 0 00-1.729.665 4.984 4.984 0 00-1.435 1.246c-.41.518-.737 1.148-.98 1.89s-.364 1.608-.364 2.597c0 .999.119 1.862.357 2.59.238.728.56 1.344.966 1.848.406.504.882.912 1.428 1.225a6.964 6.964 0 001.757.707z"/><path id="j" fill="#181717" d="M188.636 121.68c.27 0 .497-.084.679-.252a.806.806 0 00.273-.616.889.889 0 00-.273-.651.922.922 0 00-.679-.273.838.838 0 00-.644.273.927.927 0 00-.252.651c0 .243.084.448.252.616a.872.872 0 00.644.252zm-1.904 11.088c.85 0 1.514-.231 1.995-.693.48-.462.721-1.164.721-2.107V122.8h-4.508v.938h3.388v6.02c0 .616-.119 1.099-.357 1.449-.238.35-.637.525-1.197.525-.345 0-.679-.07-1.001-.21a4.362 4.362 0 01-.861-.49l-.462.91a4.501 4.501 0 00.882.497c.205.089.427.166.665.231.238.065.483.098.735.098z"/><path id=");}];" fill="#7E7C7B" d="M194.376 132.768a6.964 6.964 0 001.757-.707 5.036 5.036 0 001.428-1.225c.406-.504.728-1.12.966-1.848s.357-1.591.357-2.59c0-.99-.121-1.855-.364-2.597s-.57-1.372-.98-1.89a4.984 4.984 0 00-1.435-1.246 6.005 6.005 0 00-1.729-.665l-.35.882c.55.159 1.055.366 1.512.623.457.257.852.597 1.183 1.022.331.425.588.952.77 1.582.182.63.273 1.393.273 2.289 0 .905-.11 1.678-.329 2.317-.22.64-.509 1.171-.868 1.596a4.15 4.15 0 01-1.204.994 4.965 4.965 0 01-1.337.497l.35.966zm10.304-8.302c.299 0 .532-.089.7-.266a.938.938 0 00.252-.672c0-.299-.084-.53-.252-.693-.168-.163-.401-.245-.7-.245-.28 0-.504.082-.672.245-.168.163-.252.394-.252.693 0 .27.084.495.252.672.168.177.392.266.672.266zm-.756 7.42c.177-.056.371-.142.581-.259a2.42 2.42 0 001.043-1.162 2.36 2.36 0 00.182-.959c0-.448-.098-.796-.294-1.043-.196-.247-.471-.371-.826-.371-.29 0-.525.086-.707.259a.893.893 0 00-.273.679c0 .299.077.525.231.679.154.154.366.231.637.231.075 0 .177-.014.308-.042 0 .345-.121.64-.364.882-.243.243-.532.43-.868.56l.35.546zm16.45 1.134c.653 0 1.178-.194 1.575-.581.397-.387.595-.959.595-1.715v-1.372c0-.401.068-.749.203-1.043a2.44 2.44 0 01.504-.735c.2-.196.415-.34.644-.434.229-.093.432-.14.609-.14v-.98c-.177 0-.38-.04-.609-.119a1.87 1.87 0 01-.644-.392 2.193 2.193 0 01-.504-.707c-.135-.29-.203-.649-.203-1.078v-1.428c0-.336-.054-.644-.161-.924a2.22 2.22 0 00-.448-.728 2.053 2.053 0 00-.686-.483 2.155 2.155 0 00-.875-.175h-2.03v.98h1.54c.588 0 .996.14 1.225.42.229.28.343.695.343 1.246v1.358c0 .383.07.723.21 1.022a2.7 2.7 0 001.106 1.225c.205.117.373.184.504.203v.084c-.13.019-.299.091-.504.217a2.744 2.744 0 00-.602.518c-.196.22-.364.478-.504.777-.14.299-.21.63-.21.994v1.344c0 .57-.121.99-.364 1.26s-.649.406-1.218.406h-1.526v.98h2.03zm-215.236 24V144H.35v.98h3.696v11.06H.35v.98h4.788zm6.342-8.554c.299 0 .532-.089.7-.266a.938.938 0 00.252-.672c0-.299-.084-.53-.252-.693-.168-.163-.401-.245-.7-.245-.28 0-.504.082-.672.245-.168.163-.252.394-.252.693 0 .27.084.495.252.672.168.177.392.266.672.266zm-.756 7.42c.177-.056.371-.142.581-.259a2.42 2.42 0 001.043-1.162 2.36 2.36 0 00.182-.959c0-.448-.098-.796-.294-1.043-.196-.247-.471-.371-.826-.371-.29 0-.525.086-.707.259a.893.893 0 00-.273.679c0 .299.077.525.231.679.154.154.366.231.637.231.075 0 .177-.014.308-.042 0 .345-.121.64-.364.882-.243.243-.532.43-.868.56l.35.546z"/></g><g id="Group-Copy" transform="translate(354 66)"><path id="Line" fill="#C06334" fill-rule="nonzero" d="M16.5 15.5l14 7-14 7v-6h-14v-2h14v-6z"/><text id="outer" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="0" y="11">outer</tspan></text></g><g id="Group-Copy-2" fill="#C06334" fill-rule="nonzero" transform="translate(242 44)"><path id="Line" d="M13.5-5.5l14 7-14 7v-6h-14v-2h14v-6z"/></g><g id="Group-3" transform="translate(279 36)"><path id="Rectangle-1" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M1 1h52v18H1z"/><text id="j:-0" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="8" y="14">j: 0</tspan></text></g><g id="Group-Copy-3" fill="#C06334" fill-rule="nonzero" transform="translate(242 67)"><path id="Line" d="M13.5-5.5l14 7-14 7v-6h-14v-2h14v-6z"/></g><g id="Group-3-Copy" transform="translate(279 59)"><path id="Rectangle-1" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M1 1h52v18H1z"/><text id="j:-1" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="8" y="14">j: 1</tspan></text></g><g id="Group-Copy-4" fill="#C06334" fill-rule="nonzero" transform="translate(242 90)"><path id="Line" d="M13.5-5.5l14 7-14 7v-6h-14v-2h14v-6z"/></g><g id="Group-3-Copy-2" transform="translate(279 82)"><path id="Rectangle-1" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M1 1h52v18H1z"/><text id="j:-2" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="8" y="14">j: 2</tspan></text></g><g id="Group-Copy-5" fill="#C06334" fill-rule="nonzero" transform="translate(242 139)"><path id="Line" d="M13.5-5.5l14 7-14 7v-6h-14v-2h14v-6z"/></g><g id="Group-3-Copy-3" transform="translate(279 131)"><path id="Rectangle-1" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M1 1h52v18H1z"/><text id="j:-10" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="7.447" y="13.51">j: 10</tspan></text></g><text id="..." fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="403" y="94">...</tspan></text><text id="makeArmy()-LexicalEn" fill="#AF6E24" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="403" y="62">makeArmy()</tspan>  <tspan x="403" y="77" font-family="PTMono-Regular, PT Mono" font-weight="normal">LexicalEnvironment</tspan></text><text id="while-iteration-Lexi" fill="#AF6E24" font-family="PTMono-Bold, PT Mono" font-size="14" font-weight="bold"><tspan x="278" y="14">while iteration</tspan>  <tspan x="278" y="29" font-family="PTMono-Regular, PT Mono" font-weight="normal">LexicalEnvironment</tspan></text></g></g></svg>
\ No newline at end of file
diff --git a/1-js/06-advanced-functions/03-closure/10-make-army/lexenv-makearmy.svg b/1-js/06-advanced-functions/03-closure/10-make-army/lexenv-makearmy.svg
deleted file mode 100644
index c0a312ec7..000000000
--- a/1-js/06-advanced-functions/03-closure/10-make-army/lexenv-makearmy.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="566" height="183" viewBox="0 0 566 183"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:&apos;PT Mono&apos;;font-weight:700;font-style:normal;src:local(&apos;PT MonoBold&apos;),url(/font/PTMonoBold.woff2) format(&apos;woff2&apos;),url(/font/PTMonoBold.woff) format(&apos;woff&apos;),url(/font/PTMonoBold.ttf) format(&apos;truetype&apos;)}</style></defs><g id="closure" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="lexenv-makearmy.svg"><g id="shooters-=-[" fill-rule="nonzero" transform="translate(6.176 15.2)"><path id="shooters" fill="#000" d="M4.956 7.91a.796.796 0 00-.35-.693 2.872 2.872 0 00-.868-.392 16.056 16.056 0 00-1.127-.273 6.502 6.502 0 01-1.127-.336 2.525 2.525 0 01-.868-.567c-.233-.238-.35-.572-.35-1.001 0-.355.077-.658.231-.91a1.94 1.94 0 01.609-.623c.252-.163.546-.285.882-.364.336-.08.686-.119 1.05-.119.653 0 1.216.082 1.687.245.471.163.847.334 1.127.511l-.448.882a11.79 11.79 0 00-1.001-.483c-.36-.154-.81-.231-1.351-.231-.205 0-.408.021-.609.063-.2.042-.383.105-.546.189a1.088 1.088 0 00-.392.329.825.825 0 00-.147.497c0 .243.117.43.35.56.233.13.523.24.868.329.345.089.721.173 1.127.252.406.08.782.194 1.127.343.345.15.635.35.868.602.233.252.35.593.35 1.022 0 .644-.254 1.176-.763 1.596-.509.42-1.272.63-2.289.63-.308 0-.611-.028-.91-.084a5.52 5.52 0 01-.84-.224 5.054 5.054 0 01-.714-.315A3.002 3.002 0 010 8.988l.56-.91c.112.112.261.226.448.343a4.229 4.229 0 001.337.539 3.76 3.76 0 001.484.021c.22-.042.413-.107.581-.196a1.08 1.08 0 00.399-.35.914.914 0 00.147-.525zM7.28 0h2.184v3.668h.07c.29-.327.625-.581 1.008-.763.383-.182.859-.273 1.428-.273.448 0 .838.047 1.169.14.331.093.602.257.812.49.21.233.366.553.469.959.103.406.154.922.154 1.547V9.8h-1.092V5.978c0-.401-.023-.751-.07-1.05a1.829 1.829 0 00-.273-.749c-.135-.2-.32-.352-.553-.455-.233-.103-.532-.154-.896-.154-.252 0-.5.044-.742.133-.243.089-.464.21-.665.364-.2.154-.373.34-.518.56-.145.22-.245.46-.301.721V9.8H8.386V.938H7.28V0zm9.142 6.3c0-1.13.294-2.023.882-2.681.588-.658 1.428-.987 2.52-.987.588 0 1.094.096 1.519.287.425.191.777.45 1.057.777.28.327.488.714.623 1.162.135.448.203.929.203 1.442 0 .56-.075 1.066-.224 1.519-.15.453-.369.838-.658 1.155-.29.317-.646.562-1.071.735a3.82 3.82 0 01-1.449.259c-.579 0-1.083-.096-1.512-.287a2.967 2.967 0 01-1.064-.777 3.168 3.168 0 01-.623-1.162 4.963 4.963 0 01-.203-1.442zm1.162 0c0 .327.04.653.119.98.08.327.208.62.385.882.177.261.408.471.693.63.285.159.632.238 1.043.238.747 0 1.309-.231 1.687-.693.378-.462.567-1.141.567-2.037 0-.336-.04-.665-.119-.987a2.608 2.608 0 00-.392-.875 2.066 2.066 0 00-.7-.63c-.285-.159-.632-.238-1.043-.238-.747 0-1.307.229-1.68.686-.373.457-.56 1.139-.56 2.044zm7.238 0c0-1.13.294-2.023.882-2.681.588-.658 1.428-.987 2.52-.987.588 0 1.094.096 1.519.287.425.191.777.45 1.057.777.28.327.488.714.623 1.162.135.448.203.929.203 1.442 0 .56-.075 1.066-.224 1.519-.15.453-.369.838-.658 1.155-.29.317-.646.562-1.071.735a3.82 3.82 0 01-1.449.259c-.579 0-1.083-.096-1.512-.287a2.967 2.967 0 01-1.064-.777 3.168 3.168 0 01-.623-1.162 4.963 4.963 0 01-.203-1.442zm1.162 0c0 .327.04.653.119.98.08.327.208.62.385.882.177.261.408.471.693.63.285.159.632.238 1.043.238.747 0 1.309-.231 1.687-.693.378-.462.567-1.141.567-2.037 0-.336-.04-.665-.119-.987a2.608 2.608 0 00-.392-.875 2.066 2.066 0 00-.7-.63c-.285-.159-.632-.238-1.043-.238-.747 0-1.307.229-1.68.686-.373.457-.56 1.139-.56 2.044zm6.874-3.5h1.666V1.414l1.092-.308V2.8h3.738v.938h-3.738v3.304c0 .681.166 1.185.497 1.512.331.327.805.49 1.421.49.42 0 .786-.08 1.099-.238.313-.159.595-.331.847-.518l.364.826a3.938 3.938 0 01-1.169.63 4.182 4.182 0 01-1.393.238 3.41 3.41 0 01-1.057-.161 2.426 2.426 0 01-.875-.497 2.38 2.38 0 01-.602-.861c-.15-.35-.224-.768-.224-1.253V3.738h-1.666V2.8zM48.23 8.918c-.168.15-.366.29-.595.42a4.39 4.39 0 01-.749.336c-.27.093-.553.166-.847.217-.294.051-.59.077-.889.077-.56 0-1.055-.086-1.484-.259a2.858 2.858 0 01-1.078-.742 3.234 3.234 0 01-.658-1.155 4.767 4.767 0 01-.224-1.512c0-.588.082-1.11.245-1.568.163-.457.399-.84.707-1.148a3.08 3.08 0 011.12-.707 4.187 4.187 0 011.47-.245c.392 0 .78.051 1.162.154.383.103.721.296 1.015.581.294.285.52.677.679 1.176.159.5.215 1.146.168 1.939h-5.418c0 .84.226 1.468.679 1.883.453.415 1.057.623 1.813.623.252 0 .502-.03.749-.091.247-.06.483-.133.707-.217a3.72 3.72 0 00.595-.28c.173-.103.306-.196.399-.28l.434.798zm-2.954-5.362c-.308 0-.6.033-.875.098a1.995 1.995 0 00-.728.329c-.21.154-.383.355-.518.602s-.222.553-.259.917h4.354c-.047-.616-.245-1.094-.595-1.435-.35-.34-.81-.511-1.379-.511zM50.148 9.8v-.938h1.89V3.738h-1.89V2.8h2.618l.224.91h.07c.317-.29.672-.537 1.064-.742.392-.205.859-.308 1.4-.308.317 0 .572.06.763.182.191.121.34.299.448.532.107.233.18.516.217.847.037.331.056.707.056 1.127l-.98.014c0-.597-.058-1.036-.175-1.316-.117-.28-.329-.42-.637-.42-.29 0-.55.042-.784.126a2.565 2.565 0 00-.609.308c-.173.121-.32.243-.441.364s-.21.224-.266.308v4.13h2.688V9.8h-5.656zm13.608-1.89a.796.796 0 00-.35-.693 2.872 2.872 0 00-.868-.392 16.056 16.056 0 00-1.127-.273 6.502 6.502 0 01-1.127-.336 2.525 2.525 0 01-.868-.567c-.233-.238-.35-.572-.35-1.001 0-.355.077-.658.231-.91a1.94 1.94 0 01.609-.623c.252-.163.546-.285.882-.364.336-.08.686-.119 1.05-.119.653 0 1.216.082 1.687.245.471.163.847.334 1.127.511l-.448.882a11.79 11.79 0 00-1.001-.483c-.36-.154-.81-.231-1.351-.231-.205 0-.408.021-.609.063-.2.042-.383.105-.546.189a1.088 1.088 0 00-.392.329.825.825 0 00-.147.497c0 .243.117.43.35.56.233.13.523.24.868.329.345.089.721.173 1.127.252.406.08.782.194 1.127.343.345.15.635.35.868.602.233.252.35.593.35 1.022 0 .644-.254 1.176-.763 1.596-.509.42-1.272.63-2.289.63-.308 0-.611-.028-.91-.084a5.52 5.52 0 01-.84-.224 5.054 5.054 0 01-.714-.315 3.002 3.002 0 01-.532-.357l.56-.91c.112.112.261.226.448.343a4.229 4.229 0 001.337.539 3.76 3.76 0 001.484.021c.22-.042.413-.107.581-.196a1.08 1.08 0 00.399-.35.914.914 0 00.147-.525z"/><path id="=" fill="#A67F59" d="M75.376 3.402h6.496V4.41h-6.496V3.402zm0 2.296h6.496v1.008h-6.496V5.698z"/><path id="[" fill="#999" d="M93.31 0h4.774v.98h-3.682v11.06h3.682v.98H93.31z"/><path id="function" fill="#07A" d="M16.856 33.8v-.938h1.666v-5.124h-1.666V26.8h1.666v-.392c0-.877.229-1.512.686-1.904.457-.392 1.11-.588 1.96-.588.308 0 .583.019.826.056.243.037.504.112.784.224l-.252.91a2.862 2.862 0 00-.7-.203 4.295 4.295 0 00-.616-.049c-.616 0-1.036.152-1.26.455-.224.303-.336.8-.336 1.491h2.898v.938h-2.898v5.124h2.898v.938h-5.656zm12.25-7h1.988v4.774c0 .457.028.896.084 1.316h.938v.91h-1.862l-.042-1.19h-.056a2.938 2.938 0 01-.966.98c-.401.252-.887.378-1.456.378-.43 0-.796-.049-1.099-.147a1.556 1.556 0 01-.749-.511c-.196-.243-.34-.567-.434-.973-.093-.406-.14-.912-.14-1.519v-3.08h-.938V26.8h2.03v3.794c0 .383.016.726.049 1.029.033.303.1.56.203.77.103.21.254.369.455.476.2.107.469.161.805.161.485 0 .908-.159 1.267-.476.36-.317.632-.714.819-1.19v-3.626h-.896V26.8zm4.62 2.45a14.05 14.05 0 00-.063-1.176 4.657 4.657 0 00-.049-.364h-.938v-.91h1.876l.126 1.134h.07c.093-.159.217-.315.371-.469a2.91 2.91 0 011.225-.721c.252-.075.518-.112.798-.112.43 0 .81.047 1.141.14.331.093.607.259.826.497.22.238.385.56.497.966.112.406.168.922.168 1.547V33.8h-1.092v-3.808c0-.775-.126-1.358-.378-1.75-.252-.392-.71-.588-1.372-.588-.243 0-.478.049-.707.147a2.44 2.44 0 00-.623.385c-.187.159-.35.343-.49.553-.14.21-.243.432-.308.665V33.8h-1.078v-4.55zm13.244-1.372a5.531 5.531 0 00-.693-.189 3.61 3.61 0 00-.735-.077c-.915 0-1.596.215-2.044.644-.448.43-.672 1.11-.672 2.044 0 .41.065.777.196 1.099.13.322.317.595.56.819.243.224.534.397.875.518.34.121.716.182 1.127.182.439 0 .866-.075 1.281-.224.415-.15.763-.345 1.043-.588l.49.812c-.13.112-.294.229-.49.35a4.837 4.837 0 01-1.533.602 4.962 4.962 0 01-1.015.098c-.607 0-1.141-.086-1.603-.259a3.045 3.045 0 01-1.155-.742 3.176 3.176 0 01-.7-1.162 4.525 4.525 0 01-.238-1.505c0-.588.082-1.11.245-1.568.163-.457.399-.84.707-1.148a3.08 3.08 0 011.12-.707 4.187 4.187 0 011.47-.245c.69 0 1.253.06 1.687.182.434.121.8.257 1.099.406l-.014.042v1.946H46.97v-1.33zm2.688-1.078h1.666v-1.386l1.092-.308V26.8h3.738v.938h-3.738v3.304c0 .681.166 1.185.497 1.512.331.327.805.49 1.421.49.42 0 .786-.08 1.099-.238.313-.159.595-.331.847-.518l.364.826a3.938 3.938 0 01-1.169.63 4.182 4.182 0 01-1.393.238 3.41 3.41 0 01-1.057-.161 2.426 2.426 0 01-.875-.497 2.38 2.38 0 01-.602-.861c-.15-.35-.224-.768-.224-1.253v-3.472h-1.666V26.8zm9.436 7v-.938h2.436v-5.124h-2.436V26.8h3.556v6.062h2.38v.938h-5.936zm2.058-8.988c0-.252.084-.469.252-.651a.838.838 0 01.644-.273c.27 0 .497.091.679.273a.889.889 0 01.273.651.806.806 0 01-.273.616.963.963 0 01-.679.252.872.872 0 01-.644-.252.838.838 0 01-.252-.616zm5.67 5.488c0-1.13.294-2.023.882-2.681.588-.658 1.428-.987 2.52-.987.588 0 1.094.096 1.519.287.425.191.777.45 1.057.777.28.327.488.714.623 1.162.135.448.203.929.203 1.442 0 .56-.075 1.066-.224 1.519-.15.453-.369.838-.658 1.155-.29.317-.646.562-1.071.735a3.82 3.82 0 01-1.449.259c-.579 0-1.083-.096-1.512-.287a2.967 2.967 0 01-1.064-.777 3.168 3.168 0 01-.623-1.162 4.963 4.963 0 01-.203-1.442zm1.162 0c0 .327.04.653.119.98.08.327.208.62.385.882.177.261.408.471.693.63.285.159.632.238 1.043.238.747 0 1.309-.231 1.687-.693.378-.462.567-1.141.567-2.037 0-.336-.04-.665-.119-.987a2.608 2.608 0 00-.392-.875 2.066 2.066 0 00-.7-.63c-.285-.159-.632-.238-1.043-.238-.747 0-1.307.229-1.68.686-.373.457-.56 1.139-.56 2.044zm7.742-1.05a14.05 14.05 0 00-.063-1.176 4.657 4.657 0 00-.049-.364h-.938v-.91h1.876l.126 1.134h.07c.093-.159.217-.315.371-.469a2.91 2.91 0 011.225-.721c.252-.075.518-.112.798-.112.43 0 .81.047 1.141.14.331.093.607.259.826.497.22.238.385.56.497.966.112.406.168.922.168 1.547V33.8h-1.092v-3.808c0-.775-.126-1.358-.378-1.75-.252-.392-.71-.588-1.372-.588-.243 0-.478.049-.707.147a2.44 2.44 0 00-.623.385c-.187.159-.35.343-.49.553-.14.21-.243.432-.308.665V33.8h-1.078v-4.55z"/><path id="(){" fill="#999" d="M97.272 36.768a6.964 6.964 0 01-1.757-.707 5.036 5.036 0 01-1.428-1.225c-.406-.504-.728-1.12-.966-1.848s-.357-1.591-.357-2.59c0-.99.121-1.855.364-2.597s.57-1.372.98-1.89c.41-.518.889-.933 1.435-1.246A6.005 6.005 0 0197.272 24l.35.882a7.086 7.086 0 00-1.512.623 3.928 3.928 0 00-1.183 1.022c-.331.425-.588.952-.77 1.582-.182.63-.273 1.393-.273 2.289 0 .905.11 1.678.329 2.317.22.64.509 1.171.868 1.596.36.425.76.756 1.204.994.443.238.889.404 1.337.497l-.35.966zm4.354-.966a4.965 4.965 0 001.337-.497 4.15 4.15 0 001.204-.994c.36-.425.649-.957.868-1.596.22-.64.329-1.412.329-2.317 0-.896-.091-1.659-.273-2.289-.182-.63-.439-1.157-.77-1.582a3.928 3.928 0 00-1.183-1.022 7.086 7.086 0 00-1.512-.623l.35-.882c.607.13 1.183.352 1.729.665a4.984 4.984 0 011.435 1.246c.41.518.737 1.148.98 1.89s.364 1.608.364 2.597c0 .999-.119 1.862-.357 2.59-.238.728-.56 1.344-.966 1.848a5.036 5.036 0 01-1.428 1.225 6.964 6.964 0 01-1.757.707l-.35-.966zm17.878-2.45c0-.401-.068-.749-.203-1.043a2.44 2.44 0 00-.504-.735c-.2-.196-.415-.34-.644-.434a1.641 1.641 0 00-.609-.14v-.98c.177 0 .38-.04.609-.119.229-.08.443-.21.644-.392.2-.182.369-.418.504-.707.135-.29.203-.649.203-1.078v-1.428c0-.336.054-.644.161-.924a2.22 2.22 0 01.448-.728c.191-.205.42-.366.686-.483.266-.117.558-.175.875-.175h2.03v.98h-1.54c-.588 0-.996.14-1.225.42-.229.28-.343.695-.343 1.246v1.358c0 .383-.07.723-.21 1.022a2.7 2.7 0 01-1.106 1.225c-.205.117-.373.184-.504.203v.084c.121.019.285.091.49.217.205.126.406.299.602.518.196.22.366.478.511.777.145.299.217.63.217.994v1.344c0 .57.121.99.364 1.26s.649.406 1.218.406h1.526v.98h-2.03c-.653 0-1.178-.194-1.575-.581-.397-.387-.595-.959-.595-1.715v-1.372z"/><path id="alert" fill="#000" d="M134.736 27.346a4.447 4.447 0 011.358-.504 7.423 7.423 0 011.484-.154c.476 0 .866.075 1.169.224.303.15.541.343.714.581.173.238.29.509.35.812.06.303.091.609.091.917 0 .355-.01.733-.028 1.134-.019.401-.033.803-.042 1.204 0 .467.028.91.084 1.33h.938v.91h-1.862l-.126-1.05h-.07c-.056.084-.14.191-.252.322-.112.13-.259.259-.441.385a2.749 2.749 0 01-1.589.469c-.69 0-1.237-.177-1.638-.532-.401-.355-.602-.84-.602-1.456 0-.476.105-.873.315-1.19.21-.317.511-.56.903-.728.392-.168.866-.266 1.421-.294a9.544 9.544 0 011.869.112c.047-.43.054-.786.021-1.071-.033-.285-.107-.511-.224-.679a.938.938 0 00-.49-.357 2.482 2.482 0 00-.777-.105c-.42 0-.821.058-1.204.175-.383.117-.723.236-1.022.357l-.35-.812zm2.058 5.642c.261 0 .504-.042.728-.126a2.22 2.22 0 00.588-.322 2.133 2.133 0 00.672-.868v-.98a7.92 7.92 0 00-1.344-.126c-.41 0-.765.044-1.064.133-.299.089-.532.226-.7.413-.168.187-.252.43-.252.728 0 .308.105.576.315.805.21.229.562.343 1.057.343zM143.29 24h2.324v7.448c0 .57.096.97.287 1.204.191.233.474.35.847.35.261 0 .511-.047.749-.14.238-.093.502-.252.791-.476l.504.77c-.15.13-.313.247-.49.35a3.638 3.638 0 01-1.106.42 2.963 2.963 0 01-1.442-.077 1.579 1.579 0 01-.679-.427 1.897 1.897 0 01-.413-.777c-.093-.322-.14-.721-.14-1.197v-6.51h-1.232V24zm14.14 8.918c-.168.15-.366.29-.595.42a4.39 4.39 0 01-.749.336c-.27.093-.553.166-.847.217-.294.051-.59.077-.889.077-.56 0-1.055-.086-1.484-.259a2.858 2.858 0 01-1.078-.742 3.234 3.234 0 01-.658-1.155 4.767 4.767 0 01-.224-1.512c0-.588.082-1.11.245-1.568.163-.457.399-.84.707-1.148a3.08 3.08 0 011.12-.707 4.187 4.187 0 011.47-.245c.392 0 .78.051 1.162.154.383.103.721.296 1.015.581.294.285.52.677.679 1.176.159.5.215 1.146.168 1.939h-5.418c0 .84.226 1.468.679 1.883.453.415 1.057.623 1.813.623.252 0 .502-.03.749-.091.247-.06.483-.133.707-.217a3.72 3.72 0 00.595-.28c.173-.103.306-.196.399-.28l.434.798zm-2.954-5.362c-.308 0-.6.033-.875.098a1.995 1.995 0 00-.728.329c-.21.154-.383.355-.518.602s-.222.553-.259.917h4.354c-.047-.616-.245-1.094-.595-1.435-.35-.34-.81-.511-1.379-.511zm4.872 6.244v-.938h1.89v-5.124h-1.89V26.8h2.618l.224.91h.07c.317-.29.672-.537 1.064-.742.392-.205.859-.308 1.4-.308.317 0 .572.06.763.182.191.121.34.299.448.532.107.233.18.516.217.847.037.331.056.707.056 1.127l-.98.014c0-.597-.058-1.036-.175-1.316-.117-.28-.329-.42-.637-.42-.29 0-.55.042-.784.126a2.565 2.565 0 00-.609.308c-.173.121-.32.243-.441.364s-.21.224-.266.308v4.13h2.688v.938h-5.656zm7.91-7h1.666v-1.386l1.092-.308V26.8h3.738v.938h-3.738v3.304c0 .681.166 1.185.497 1.512.331.327.805.49 1.421.49.42 0 .786-.08 1.099-.238.313-.159.595-.331.847-.518l.364.826a3.938 3.938 0 01-1.169.63 4.182 4.182 0 01-1.393.238 3.41 3.41 0 01-1.057-.161 2.426 2.426 0 01-.875-.497 2.38 2.38 0 01-.602-.861c-.15-.35-.224-.768-.224-1.253v-3.472h-1.666V26.8z"/><path id="(" fill="#999" d="M181.272 36.768a6.964 6.964 0 01-1.757-.707 5.036 5.036 0 01-1.428-1.225c-.406-.504-.728-1.12-.966-1.848s-.357-1.591-.357-2.59c0-.99.121-1.855.364-2.597s.57-1.372.98-1.89c.41-.518.889-.933 1.435-1.246a6.005 6.005 0 011.729-.665l.35.882a7.086 7.086 0 00-1.512.623 3.928 3.928 0 00-1.183 1.022c-.331.425-.588.952-.77 1.582-.182.63-.273 1.393-.273 2.289 0 .905.11 1.678.329 2.317.22.64.509 1.171.868 1.596.36.425.76.756 1.204.994.443.238.889.404 1.337.497l-.35.966z"/><path id="i" fill="#000" d="M185.094 33.8v-.938h2.436v-5.124h-2.436V26.8h3.556v6.062h2.38v.938h-5.936zm2.058-8.988c0-.252.084-.469.252-.651a.838.838 0 01.644-.273c.27 0 .497.091.679.273a.889.889 0 01.273.651.806.806 0 01-.273.616.963.963 0 01-.679.252.872.872 0 01-.644-.252.838.838 0 01-.252-.616z"/><path id=");}," fill="#999" d="M194.026 35.802a4.965 4.965 0 001.337-.497 4.15 4.15 0 001.204-.994c.36-.425.649-.957.868-1.596.22-.64.329-1.412.329-2.317 0-.896-.091-1.659-.273-2.289-.182-.63-.439-1.157-.77-1.582a3.928 3.928 0 00-1.183-1.022 7.086 7.086 0 00-1.512-.623l.35-.882c.607.13 1.183.352 1.729.665a4.984 4.984 0 011.435 1.246c.41.518.737 1.148.98 1.89s.364 1.608.364 2.597c0 .999-.119 1.862-.357 2.59-.238.728-.56 1.344-.966 1.848a5.036 5.036 0 01-1.428 1.225 6.964 6.964 0 01-1.757.707l-.35-.966zm9.604-2.772c0-.28.091-.506.273-.679.182-.173.418-.259.707-.259.355 0 .63.124.826.371.196.247.294.595.294 1.043a2.36 2.36 0 01-.637 1.659 2.465 2.465 0 01-.588.462c-.21.117-.404.203-.581.259l-.35-.546c.336-.13.625-.317.868-.56.243-.243.364-.537.364-.882-.13.028-.233.042-.308.042-.27 0-.483-.077-.637-.231-.154-.154-.231-.38-.231-.679zm.126-5.502c0-.299.084-.53.252-.693.168-.163.392-.245.672-.245.299 0 .532.082.7.245.168.163.252.394.252.693 0 .27-.084.495-.252.672-.168.177-.401.266-.7.266-.28 0-.504-.089-.672-.266a.938.938 0 01-.252-.672zm18.788 7.196c0 .756-.198 1.328-.595 1.715-.397.387-.922.581-1.575.581h-2.03v-.98h1.526c.57 0 .975-.135 1.218-.406.243-.27.364-.69.364-1.26V33.03c0-.364.07-.695.21-.994.14-.299.308-.558.504-.777.196-.22.397-.392.602-.518.205-.126.373-.198.504-.217v-.084c-.13-.019-.299-.086-.504-.203a2.7 2.7 0 01-1.106-1.225c-.14-.299-.21-.64-.21-1.022v-1.358c0-.55-.114-.966-.343-1.246-.229-.28-.637-.42-1.225-.42h-1.54v-.98h2.03c.317 0 .609.058.875.175.266.117.495.278.686.483.191.205.34.448.448.728.107.28.161.588.161.924v1.428c0 .43.068.789.203 1.078.135.29.303.525.504.707.2.182.415.313.644.392.229.08.432.119.609.119V31c-.177 0-.38.047-.609.14a2.011 2.011 0 00-.644.434 2.44 2.44 0 00-.504.735c-.135.294-.203.642-.203 1.043v1.372zm6.286-1.694c0-.28.091-.506.273-.679.182-.173.418-.259.707-.259.355 0 .63.124.826.371.196.247.294.595.294 1.043a2.36 2.36 0 01-.637 1.659 2.465 2.465 0 01-.588.462c-.21.117-.404.203-.581.259l-.35-.546c.336-.13.625-.317.868-.56.243-.243.364-.537.364-.882-.13.028-.233.042-.308.042-.27 0-.483-.077-.637-.231-.154-.154-.231-.38-.231-.679z"/><path id="function" fill="#07A" d="M16.856 57.8v-.938h1.666v-5.124h-1.666V50.8h1.666v-.392c0-.877.229-1.512.686-1.904.457-.392 1.11-.588 1.96-.588.308 0 .583.019.826.056.243.037.504.112.784.224l-.252.91a2.862 2.862 0 00-.7-.203 4.295 4.295 0 00-.616-.049c-.616 0-1.036.152-1.26.455-.224.303-.336.8-.336 1.491h2.898v.938h-2.898v5.124h2.898v.938h-5.656zm12.25-7h1.988v4.774c0 .457.028.896.084 1.316h.938v.91h-1.862l-.042-1.19h-.056a2.938 2.938 0 01-.966.98c-.401.252-.887.378-1.456.378-.43 0-.796-.049-1.099-.147a1.556 1.556 0 01-.749-.511c-.196-.243-.34-.567-.434-.973-.093-.406-.14-.912-.14-1.519v-3.08h-.938V50.8h2.03v3.794c0 .383.016.726.049 1.029.033.303.1.56.203.77.103.21.254.369.455.476.2.107.469.161.805.161.485 0 .908-.159 1.267-.476.36-.317.632-.714.819-1.19v-3.626h-.896V50.8zm4.62 2.45a14.05 14.05 0 00-.063-1.176 4.657 4.657 0 00-.049-.364h-.938v-.91h1.876l.126 1.134h.07c.093-.159.217-.315.371-.469a2.91 2.91 0 011.225-.721c.252-.075.518-.112.798-.112.43 0 .81.047 1.141.14.331.093.607.259.826.497.22.238.385.56.497.966.112.406.168.922.168 1.547V57.8h-1.092v-3.808c0-.775-.126-1.358-.378-1.75-.252-.392-.71-.588-1.372-.588-.243 0-.478.049-.707.147a2.44 2.44 0 00-.623.385c-.187.159-.35.343-.49.553-.14.21-.243.432-.308.665V57.8h-1.078v-4.55zm13.244-1.372a5.531 5.531 0 00-.693-.189 3.61 3.61 0 00-.735-.077c-.915 0-1.596.215-2.044.644-.448.43-.672 1.11-.672 2.044 0 .41.065.777.196 1.099.13.322.317.595.56.819.243.224.534.397.875.518.34.121.716.182 1.127.182.439 0 .866-.075 1.281-.224.415-.15.763-.345 1.043-.588l.49.812c-.13.112-.294.229-.49.35a4.837 4.837 0 01-1.533.602 4.962 4.962 0 01-1.015.098c-.607 0-1.141-.086-1.603-.259a3.045 3.045 0 01-1.155-.742 3.176 3.176 0 01-.7-1.162 4.525 4.525 0 01-.238-1.505c0-.588.082-1.11.245-1.568.163-.457.399-.84.707-1.148a3.08 3.08 0 011.12-.707 4.187 4.187 0 011.47-.245c.69 0 1.253.06 1.687.182.434.121.8.257 1.099.406l-.014.042v1.946H46.97v-1.33zm2.688-1.078h1.666v-1.386l1.092-.308V50.8h3.738v.938h-3.738v3.304c0 .681.166 1.185.497 1.512.331.327.805.49 1.421.49.42 0 .786-.08 1.099-.238.313-.159.595-.331.847-.518l.364.826a3.938 3.938 0 01-1.169.63 4.182 4.182 0 01-1.393.238 3.41 3.41 0 01-1.057-.161 2.426 2.426 0 01-.875-.497 2.38 2.38 0 01-.602-.861c-.15-.35-.224-.768-.224-1.253v-3.472h-1.666V50.8zm9.436 7v-.938h2.436v-5.124h-2.436V50.8h3.556v6.062h2.38v.938h-5.936zm2.058-8.988c0-.252.084-.469.252-.651a.838.838 0 01.644-.273c.27 0 .497.091.679.273a.889.889 0 01.273.651.806.806 0 01-.273.616.963.963 0 01-.679.252.872.872 0 01-.644-.252.838.838 0 01-.252-.616zm5.67 5.488c0-1.13.294-2.023.882-2.681.588-.658 1.428-.987 2.52-.987.588 0 1.094.096 1.519.287.425.191.777.45 1.057.777.28.327.488.714.623 1.162.135.448.203.929.203 1.442 0 .56-.075 1.066-.224 1.519-.15.453-.369.838-.658 1.155-.29.317-.646.562-1.071.735a3.82 3.82 0 01-1.449.259c-.579 0-1.083-.096-1.512-.287a2.967 2.967 0 01-1.064-.777 3.168 3.168 0 01-.623-1.162 4.963 4.963 0 01-.203-1.442zm1.162 0c0 .327.04.653.119.98.08.327.208.62.385.882.177.261.408.471.693.63.285.159.632.238 1.043.238.747 0 1.309-.231 1.687-.693.378-.462.567-1.141.567-2.037 0-.336-.04-.665-.119-.987a2.608 2.608 0 00-.392-.875 2.066 2.066 0 00-.7-.63c-.285-.159-.632-.238-1.043-.238-.747 0-1.307.229-1.68.686-.373.457-.56 1.139-.56 2.044zm7.742-1.05a14.05 14.05 0 00-.063-1.176 4.657 4.657 0 00-.049-.364h-.938v-.91h1.876l.126 1.134h.07c.093-.159.217-.315.371-.469a2.91 2.91 0 011.225-.721c.252-.075.518-.112.798-.112.43 0 .81.047 1.141.14.331.093.607.259.826.497.22.238.385.56.497.966.112.406.168.922.168 1.547V57.8h-1.092v-3.808c0-.775-.126-1.358-.378-1.75-.252-.392-.71-.588-1.372-.588-.243 0-.478.049-.707.147a2.44 2.44 0 00-.623.385c-.187.159-.35.343-.49.553-.14.21-.243.432-.308.665V57.8h-1.078v-4.55z"/><path id="(){" fill="#999" d="M97.272 60.768a6.964 6.964 0 01-1.757-.707 5.036 5.036 0 01-1.428-1.225c-.406-.504-.728-1.12-.966-1.848s-.357-1.591-.357-2.59c0-.99.121-1.855.364-2.597s.57-1.372.98-1.89c.41-.518.889-.933 1.435-1.246A6.005 6.005 0 0197.272 48l.35.882a7.086 7.086 0 00-1.512.623 3.928 3.928 0 00-1.183 1.022c-.331.425-.588.952-.77 1.582-.182.63-.273 1.393-.273 2.289 0 .905.11 1.678.329 2.317.22.64.509 1.171.868 1.596.36.425.76.756 1.204.994.443.238.889.404 1.337.497l-.35.966zm4.354-.966a4.965 4.965 0 001.337-.497 4.15 4.15 0 001.204-.994c.36-.425.649-.957.868-1.596.22-.64.329-1.412.329-2.317 0-.896-.091-1.659-.273-2.289-.182-.63-.439-1.157-.77-1.582a3.928 3.928 0 00-1.183-1.022 7.086 7.086 0 00-1.512-.623l.35-.882c.607.13 1.183.352 1.729.665a4.984 4.984 0 011.435 1.246c.41.518.737 1.148.98 1.89s.364 1.608.364 2.597c0 .999-.119 1.862-.357 2.59-.238.728-.56 1.344-.966 1.848a5.036 5.036 0 01-1.428 1.225 6.964 6.964 0 01-1.757.707l-.35-.966zm17.878-2.45c0-.401-.068-.749-.203-1.043a2.44 2.44 0 00-.504-.735c-.2-.196-.415-.34-.644-.434a1.641 1.641 0 00-.609-.14v-.98c.177 0 .38-.04.609-.119.229-.08.443-.21.644-.392.2-.182.369-.418.504-.707.135-.29.203-.649.203-1.078v-1.428c0-.336.054-.644.161-.924a2.22 2.22 0 01.448-.728c.191-.205.42-.366.686-.483.266-.117.558-.175.875-.175h2.03v.98h-1.54c-.588 0-.996.14-1.225.42-.229.28-.343.695-.343 1.246v1.358c0 .383-.07.723-.21 1.022a2.7 2.7 0 01-1.106 1.225c-.205.117-.373.184-.504.203v.084c.121.019.285.091.49.217.205.126.406.299.602.518.196.22.366.478.511.777.145.299.217.63.217.994v1.344c0 .57.121.99.364 1.26s.649.406 1.218.406h1.526v.98h-2.03c-.653 0-1.178-.194-1.575-.581-.397-.387-.595-.959-.595-1.715v-1.372z"/><path id="alert" fill="#000" d="M134.736 51.346a4.447 4.447 0 011.358-.504 7.423 7.423 0 011.484-.154c.476 0 .866.075 1.169.224.303.15.541.343.714.581.173.238.29.509.35.812.06.303.091.609.091.917 0 .355-.01.733-.028 1.134-.019.401-.033.803-.042 1.204 0 .467.028.91.084 1.33h.938v.91h-1.862l-.126-1.05h-.07c-.056.084-.14.191-.252.322-.112.13-.259.259-.441.385a2.749 2.749 0 01-1.589.469c-.69 0-1.237-.177-1.638-.532-.401-.355-.602-.84-.602-1.456 0-.476.105-.873.315-1.19.21-.317.511-.56.903-.728.392-.168.866-.266 1.421-.294a9.544 9.544 0 011.869.112c.047-.43.054-.786.021-1.071-.033-.285-.107-.511-.224-.679a.938.938 0 00-.49-.357 2.482 2.482 0 00-.777-.105c-.42 0-.821.058-1.204.175-.383.117-.723.236-1.022.357l-.35-.812zm2.058 5.642c.261 0 .504-.042.728-.126a2.22 2.22 0 00.588-.322 2.133 2.133 0 00.672-.868v-.98a7.92 7.92 0 00-1.344-.126c-.41 0-.765.044-1.064.133-.299.089-.532.226-.7.413-.168.187-.252.43-.252.728 0 .308.105.576.315.805.21.229.562.343 1.057.343zM143.29 48h2.324v7.448c0 .57.096.97.287 1.204.191.233.474.35.847.35.261 0 .511-.047.749-.14.238-.093.502-.252.791-.476l.504.77c-.15.13-.313.247-.49.35a3.638 3.638 0 01-1.106.42 2.963 2.963 0 01-1.442-.077 1.579 1.579 0 01-.679-.427 1.897 1.897 0 01-.413-.777c-.093-.322-.14-.721-.14-1.197v-6.51h-1.232V48zm14.14 8.918c-.168.15-.366.29-.595.42a4.39 4.39 0 01-.749.336c-.27.093-.553.166-.847.217-.294.051-.59.077-.889.077-.56 0-1.055-.086-1.484-.259a2.858 2.858 0 01-1.078-.742 3.234 3.234 0 01-.658-1.155 4.767 4.767 0 01-.224-1.512c0-.588.082-1.11.245-1.568.163-.457.399-.84.707-1.148a3.08 3.08 0 011.12-.707 4.187 4.187 0 011.47-.245c.392 0 .78.051 1.162.154.383.103.721.296 1.015.581.294.285.52.677.679 1.176.159.5.215 1.146.168 1.939h-5.418c0 .84.226 1.468.679 1.883.453.415 1.057.623 1.813.623.252 0 .502-.03.749-.091.247-.06.483-.133.707-.217a3.72 3.72 0 00.595-.28c.173-.103.306-.196.399-.28l.434.798zm-2.954-5.362c-.308 0-.6.033-.875.098a1.995 1.995 0 00-.728.329c-.21.154-.383.355-.518.602s-.222.553-.259.917h4.354c-.047-.616-.245-1.094-.595-1.435-.35-.34-.81-.511-1.379-.511zm4.872 6.244v-.938h1.89v-5.124h-1.89V50.8h2.618l.224.91h.07c.317-.29.672-.537 1.064-.742.392-.205.859-.308 1.4-.308.317 0 .572.06.763.182.191.121.34.299.448.532.107.233.18.516.217.847.037.331.056.707.056 1.127l-.98.014c0-.597-.058-1.036-.175-1.316-.117-.28-.329-.42-.637-.42-.29 0-.55.042-.784.126a2.565 2.565 0 00-.609.308c-.173.121-.32.243-.441.364s-.21.224-.266.308v4.13h2.688v.938h-5.656zm7.91-7h1.666v-1.386l1.092-.308V50.8h3.738v.938h-3.738v3.304c0 .681.166 1.185.497 1.512.331.327.805.49 1.421.49.42 0 .786-.08 1.099-.238.313-.159.595-.331.847-.518l.364.826a3.938 3.938 0 01-1.169.63 4.182 4.182 0 01-1.393.238 3.41 3.41 0 01-1.057-.161 2.426 2.426 0 01-.875-.497 2.38 2.38 0 01-.602-.861c-.15-.35-.224-.768-.224-1.253v-3.472h-1.666V50.8z"/><path id="(" fill="#999" d="M181.272 60.768a6.964 6.964 0 01-1.757-.707 5.036 5.036 0 01-1.428-1.225c-.406-.504-.728-1.12-.966-1.848s-.357-1.591-.357-2.59c0-.99.121-1.855.364-2.597s.57-1.372.98-1.89c.41-.518.889-.933 1.435-1.246a6.005 6.005 0 011.729-.665l.35.882a7.086 7.086 0 00-1.512.623 3.928 3.928 0 00-1.183 1.022c-.331.425-.588.952-.77 1.582-.182.63-.273 1.393-.273 2.289 0 .905.11 1.678.329 2.317.22.64.509 1.171.868 1.596.36.425.76.756 1.204.994.443.238.889.404 1.337.497l-.35.966z"/><path id="i" fill="#000" d="M185.094 57.8v-.938h2.436v-5.124h-2.436V50.8h3.556v6.062h2.38v.938h-5.936zm2.058-8.988c0-.252.084-.469.252-.651a.838.838 0 01.644-.273c.27 0 .497.091.679.273a.889.889 0 01.273.651.806.806 0 01-.273.616.963.963 0 01-.679.252.872.872 0 01-.644-.252.838.838 0 01-.252-.616z"/><path id=");}," fill="#999" d="M194.026 59.802a4.965 4.965 0 001.337-.497 4.15 4.15 0 001.204-.994c.36-.425.649-.957.868-1.596.22-.64.329-1.412.329-2.317 0-.896-.091-1.659-.273-2.289-.182-.63-.439-1.157-.77-1.582a3.928 3.928 0 00-1.183-1.022 7.086 7.086 0 00-1.512-.623l.35-.882c.607.13 1.183.352 1.729.665a4.984 4.984 0 011.435 1.246c.41.518.737 1.148.98 1.89s.364 1.608.364 2.597c0 .999-.119 1.862-.357 2.59-.238.728-.56 1.344-.966 1.848a5.036 5.036 0 01-1.428 1.225 6.964 6.964 0 01-1.757.707l-.35-.966zm9.604-2.772c0-.28.091-.506.273-.679.182-.173.418-.259.707-.259.355 0 .63.124.826.371.196.247.294.595.294 1.043a2.36 2.36 0 01-.637 1.659 2.465 2.465 0 01-.588.462c-.21.117-.404.203-.581.259l-.35-.546c.336-.13.625-.317.868-.56.243-.243.364-.537.364-.882-.13.028-.233.042-.308.042-.27 0-.483-.077-.637-.231-.154-.154-.231-.38-.231-.679zm.126-5.502c0-.299.084-.53.252-.693.168-.163.392-.245.672-.245.299 0 .532.082.7.245.168.163.252.394.252.693 0 .27-.084.495-.252.672-.168.177-.401.266-.7.266-.28 0-.504-.089-.672-.266a.938.938 0 01-.252-.672zm18.788 7.196c0 .756-.198 1.328-.595 1.715-.397.387-.922.581-1.575.581h-2.03v-.98h1.526c.57 0 .975-.135 1.218-.406.243-.27.364-.69.364-1.26V57.03c0-.364.07-.695.21-.994.14-.299.308-.558.504-.777.196-.22.397-.392.602-.518.205-.126.373-.198.504-.217v-.084c-.13-.019-.299-.086-.504-.203a2.7 2.7 0 01-1.106-1.225c-.14-.299-.21-.64-.21-1.022v-1.358c0-.55-.114-.966-.343-1.246-.229-.28-.637-.42-1.225-.42h-1.54v-.98h2.03c.317 0 .609.058.875.175.266.117.495.278.686.483.191.205.34.448.448.728.107.28.161.588.161.924v1.428c0 .43.068.789.203 1.078.135.29.303.525.504.707.2.182.415.313.644.392.229.08.432.119.609.119V55c-.177 0-.38.047-.609.14a2.011 2.011 0 00-.644.434 2.44 2.44 0 00-.504.735c-.135.294-.203.642-.203 1.043v1.372zm6.286-1.694c0-.28.091-.506.273-.679.182-.173.418-.259.707-.259.355 0 .63.124.826.371.196.247.294.595.294 1.043a2.36 2.36 0 01-.637 1.659 2.465 2.465 0 01-.588.462c-.21.117-.404.203-.581.259l-.35-.546c.336-.13.625-.317.868-.56.243-.243.364-.537.364-.882-.13.028-.233.042-.308.042-.27 0-.483-.077-.637-.231-.154-.154-.231-.38-.231-.679z"/><path id="function" fill="#07A" d="M16.856 81.8v-.938h1.666v-5.124h-1.666V74.8h1.666v-.392c0-.877.229-1.512.686-1.904.457-.392 1.11-.588 1.96-.588.308 0 .583.019.826.056.243.037.504.112.784.224l-.252.91a2.862 2.862 0 00-.7-.203 4.295 4.295 0 00-.616-.049c-.616 0-1.036.152-1.26.455-.224.303-.336.8-.336 1.491h2.898v.938h-2.898v5.124h2.898v.938h-5.656zm12.25-7h1.988v4.774c0 .457.028.896.084 1.316h.938v.91h-1.862l-.042-1.19h-.056a2.938 2.938 0 01-.966.98c-.401.252-.887.378-1.456.378-.43 0-.796-.049-1.099-.147a1.556 1.556 0 01-.749-.511c-.196-.243-.34-.567-.434-.973-.093-.406-.14-.912-.14-1.519v-3.08h-.938V74.8h2.03v3.794c0 .383.016.726.049 1.029.033.303.1.56.203.77.103.21.254.369.455.476.2.107.469.161.805.161.485 0 .908-.159 1.267-.476.36-.317.632-.714.819-1.19v-3.626h-.896V74.8zm4.62 2.45a14.05 14.05 0 00-.063-1.176 4.657 4.657 0 00-.049-.364h-.938v-.91h1.876l.126 1.134h.07c.093-.159.217-.315.371-.469a2.91 2.91 0 011.225-.721c.252-.075.518-.112.798-.112.43 0 .81.047 1.141.14.331.093.607.259.826.497.22.238.385.56.497.966.112.406.168.922.168 1.547V81.8h-1.092v-3.808c0-.775-.126-1.358-.378-1.75-.252-.392-.71-.588-1.372-.588-.243 0-.478.049-.707.147a2.44 2.44 0 00-.623.385c-.187.159-.35.343-.49.553-.14.21-.243.432-.308.665V81.8h-1.078v-4.55zm13.244-1.372a5.531 5.531 0 00-.693-.189 3.61 3.61 0 00-.735-.077c-.915 0-1.596.215-2.044.644-.448.43-.672 1.11-.672 2.044 0 .41.065.777.196 1.099.13.322.317.595.56.819.243.224.534.397.875.518.34.121.716.182 1.127.182.439 0 .866-.075 1.281-.224.415-.15.763-.345 1.043-.588l.49.812c-.13.112-.294.229-.49.35a4.837 4.837 0 01-1.533.602 4.962 4.962 0 01-1.015.098c-.607 0-1.141-.086-1.603-.259a3.045 3.045 0 01-1.155-.742 3.176 3.176 0 01-.7-1.162 4.525 4.525 0 01-.238-1.505c0-.588.082-1.11.245-1.568.163-.457.399-.84.707-1.148a3.08 3.08 0 011.12-.707 4.187 4.187 0 011.47-.245c.69 0 1.253.06 1.687.182.434.121.8.257 1.099.406l-.014.042v1.946H46.97v-1.33zm2.688-1.078h1.666v-1.386l1.092-.308V74.8h3.738v.938h-3.738v3.304c0 .681.166 1.185.497 1.512.331.327.805.49 1.421.49.42 0 .786-.08 1.099-.238.313-.159.595-.331.847-.518l.364.826a3.938 3.938 0 01-1.169.63 4.182 4.182 0 01-1.393.238 3.41 3.41 0 01-1.057-.161 2.426 2.426 0 01-.875-.497 2.38 2.38 0 01-.602-.861c-.15-.35-.224-.768-.224-1.253v-3.472h-1.666V74.8zm9.436 7v-.938h2.436v-5.124h-2.436V74.8h3.556v6.062h2.38v.938h-5.936zm2.058-8.988c0-.252.084-.469.252-.651a.838.838 0 01.644-.273c.27 0 .497.091.679.273a.889.889 0 01.273.651.806.806 0 01-.273.616.963.963 0 01-.679.252.872.872 0 01-.644-.252.838.838 0 01-.252-.616zm5.67 5.488c0-1.13.294-2.023.882-2.681.588-.658 1.428-.987 2.52-.987.588 0 1.094.096 1.519.287.425.191.777.45 1.057.777.28.327.488.714.623 1.162.135.448.203.929.203 1.442 0 .56-.075 1.066-.224 1.519-.15.453-.369.838-.658 1.155-.29.317-.646.562-1.071.735a3.82 3.82 0 01-1.449.259c-.579 0-1.083-.096-1.512-.287a2.967 2.967 0 01-1.064-.777 3.168 3.168 0 01-.623-1.162 4.963 4.963 0 01-.203-1.442zm1.162 0c0 .327.04.653.119.98.08.327.208.62.385.882.177.261.408.471.693.63.285.159.632.238 1.043.238.747 0 1.309-.231 1.687-.693.378-.462.567-1.141.567-2.037 0-.336-.04-.665-.119-.987a2.608 2.608 0 00-.392-.875 2.066 2.066 0 00-.7-.63c-.285-.159-.632-.238-1.043-.238-.747 0-1.307.229-1.68.686-.373.457-.56 1.139-.56 2.044zm7.742-1.05a14.05 14.05 0 00-.063-1.176 4.657 4.657 0 00-.049-.364h-.938v-.91h1.876l.126 1.134h.07c.093-.159.217-.315.371-.469a2.91 2.91 0 011.225-.721c.252-.075.518-.112.798-.112.43 0 .81.047 1.141.14.331.093.607.259.826.497.22.238.385.56.497.966.112.406.168.922.168 1.547V81.8h-1.092v-3.808c0-.775-.126-1.358-.378-1.75-.252-.392-.71-.588-1.372-.588-.243 0-.478.049-.707.147a2.44 2.44 0 00-.623.385c-.187.159-.35.343-.49.553-.14.21-.243.432-.308.665V81.8h-1.078v-4.55z"/><path id="(){" fill="#999" d="M97.272 84.768a6.964 6.964 0 01-1.757-.707 5.036 5.036 0 01-1.428-1.225c-.406-.504-.728-1.12-.966-1.848s-.357-1.591-.357-2.59c0-.99.121-1.855.364-2.597s.57-1.372.98-1.89c.41-.518.889-.933 1.435-1.246A6.005 6.005 0 0197.272 72l.35.882a7.086 7.086 0 00-1.512.623 3.928 3.928 0 00-1.183 1.022c-.331.425-.588.952-.77 1.582-.182.63-.273 1.393-.273 2.289 0 .905.11 1.678.329 2.317.22.64.509 1.171.868 1.596.36.425.76.756 1.204.994.443.238.889.404 1.337.497l-.35.966zm4.354-.966a4.965 4.965 0 001.337-.497 4.15 4.15 0 001.204-.994c.36-.425.649-.957.868-1.596.22-.64.329-1.412.329-2.317 0-.896-.091-1.659-.273-2.289-.182-.63-.439-1.157-.77-1.582a3.928 3.928 0 00-1.183-1.022 7.086 7.086 0 00-1.512-.623l.35-.882c.607.13 1.183.352 1.729.665a4.984 4.984 0 011.435 1.246c.41.518.737 1.148.98 1.89s.364 1.608.364 2.597c0 .999-.119 1.862-.357 2.59-.238.728-.56 1.344-.966 1.848a5.036 5.036 0 01-1.428 1.225 6.964 6.964 0 01-1.757.707l-.35-.966zm17.878-2.45c0-.401-.068-.749-.203-1.043a2.44 2.44 0 00-.504-.735c-.2-.196-.415-.34-.644-.434a1.641 1.641 0 00-.609-.14v-.98c.177 0 .38-.04.609-.119.229-.08.443-.21.644-.392.2-.182.369-.418.504-.707.135-.29.203-.649.203-1.078v-1.428c0-.336.054-.644.161-.924a2.22 2.22 0 01.448-.728c.191-.205.42-.366.686-.483.266-.117.558-.175.875-.175h2.03v.98h-1.54c-.588 0-.996.14-1.225.42-.229.28-.343.695-.343 1.246v1.358c0 .383-.07.723-.21 1.022a2.7 2.7 0 01-1.106 1.225c-.205.117-.373.184-.504.203v.084c.121.019.285.091.49.217.205.126.406.299.602.518.196.22.366.478.511.777.145.299.217.63.217.994v1.344c0 .57.121.99.364 1.26s.649.406 1.218.406h1.526v.98h-2.03c-.653 0-1.178-.194-1.575-.581-.397-.387-.595-.959-.595-1.715v-1.372z"/><path id="alert" fill="#000" d="M134.736 75.346a4.447 4.447 0 011.358-.504 7.423 7.423 0 011.484-.154c.476 0 .866.075 1.169.224.303.15.541.343.714.581.173.238.29.509.35.812.06.303.091.609.091.917 0 .355-.01.733-.028 1.134-.019.401-.033.803-.042 1.204 0 .467.028.91.084 1.33h.938v.91h-1.862l-.126-1.05h-.07c-.056.084-.14.191-.252.322-.112.13-.259.259-.441.385a2.749 2.749 0 01-1.589.469c-.69 0-1.237-.177-1.638-.532-.401-.355-.602-.84-.602-1.456 0-.476.105-.873.315-1.19.21-.317.511-.56.903-.728.392-.168.866-.266 1.421-.294a9.544 9.544 0 011.869.112c.047-.43.054-.786.021-1.071-.033-.285-.107-.511-.224-.679a.938.938 0 00-.49-.357 2.482 2.482 0 00-.777-.105c-.42 0-.821.058-1.204.175-.383.117-.723.236-1.022.357l-.35-.812zm2.058 5.642c.261 0 .504-.042.728-.126a2.22 2.22 0 00.588-.322 2.133 2.133 0 00.672-.868v-.98a7.92 7.92 0 00-1.344-.126c-.41 0-.765.044-1.064.133-.299.089-.532.226-.7.413-.168.187-.252.43-.252.728 0 .308.105.576.315.805.21.229.562.343 1.057.343zM143.29 72h2.324v7.448c0 .57.096.97.287 1.204.191.233.474.35.847.35.261 0 .511-.047.749-.14.238-.093.502-.252.791-.476l.504.77c-.15.13-.313.247-.49.35a3.638 3.638 0 01-1.106.42 2.963 2.963 0 01-1.442-.077 1.579 1.579 0 01-.679-.427 1.897 1.897 0 01-.413-.777c-.093-.322-.14-.721-.14-1.197v-6.51h-1.232V72zm14.14 8.918c-.168.15-.366.29-.595.42a4.39 4.39 0 01-.749.336c-.27.093-.553.166-.847.217-.294.051-.59.077-.889.077-.56 0-1.055-.086-1.484-.259a2.858 2.858 0 01-1.078-.742 3.234 3.234 0 01-.658-1.155 4.767 4.767 0 01-.224-1.512c0-.588.082-1.11.245-1.568.163-.457.399-.84.707-1.148a3.08 3.08 0 011.12-.707 4.187 4.187 0 011.47-.245c.392 0 .78.051 1.162.154.383.103.721.296 1.015.581.294.285.52.677.679 1.176.159.5.215 1.146.168 1.939h-5.418c0 .84.226 1.468.679 1.883.453.415 1.057.623 1.813.623.252 0 .502-.03.749-.091.247-.06.483-.133.707-.217a3.72 3.72 0 00.595-.28c.173-.103.306-.196.399-.28l.434.798zm-2.954-5.362c-.308 0-.6.033-.875.098a1.995 1.995 0 00-.728.329c-.21.154-.383.355-.518.602s-.222.553-.259.917h4.354c-.047-.616-.245-1.094-.595-1.435-.35-.34-.81-.511-1.379-.511zm4.872 6.244v-.938h1.89v-5.124h-1.89V74.8h2.618l.224.91h.07c.317-.29.672-.537 1.064-.742.392-.205.859-.308 1.4-.308.317 0 .572.06.763.182.191.121.34.299.448.532.107.233.18.516.217.847.037.331.056.707.056 1.127l-.98.014c0-.597-.058-1.036-.175-1.316-.117-.28-.329-.42-.637-.42-.29 0-.55.042-.784.126a2.565 2.565 0 00-.609.308c-.173.121-.32.243-.441.364s-.21.224-.266.308v4.13h2.688v.938h-5.656zm7.91-7h1.666v-1.386l1.092-.308V74.8h3.738v.938h-3.738v3.304c0 .681.166 1.185.497 1.512.331.327.805.49 1.421.49.42 0 .786-.08 1.099-.238.313-.159.595-.331.847-.518l.364.826a3.938 3.938 0 01-1.169.63 4.182 4.182 0 01-1.393.238 3.41 3.41 0 01-1.057-.161 2.426 2.426 0 01-.875-.497 2.38 2.38 0 01-.602-.861c-.15-.35-.224-.768-.224-1.253v-3.472h-1.666V74.8z"/><path id="(" fill="#999" d="M181.272 84.768a6.964 6.964 0 01-1.757-.707 5.036 5.036 0 01-1.428-1.225c-.406-.504-.728-1.12-.966-1.848s-.357-1.591-.357-2.59c0-.99.121-1.855.364-2.597s.57-1.372.98-1.89c.41-.518.889-.933 1.435-1.246a6.005 6.005 0 011.729-.665l.35.882a7.086 7.086 0 00-1.512.623 3.928 3.928 0 00-1.183 1.022c-.331.425-.588.952-.77 1.582-.182.63-.273 1.393-.273 2.289 0 .905.11 1.678.329 2.317.22.64.509 1.171.868 1.596.36.425.76.756 1.204.994.443.238.889.404 1.337.497l-.35.966z"/><path id="i" fill="#000" d="M185.094 81.8v-.938h2.436v-5.124h-2.436V74.8h3.556v6.062h2.38v.938h-5.936zm2.058-8.988c0-.252.084-.469.252-.651a.838.838 0 01.644-.273c.27 0 .497.091.679.273a.889.889 0 01.273.651.806.806 0 01-.273.616.963.963 0 01-.679.252.872.872 0 01-.644-.252.838.838 0 01-.252-.616z"/><path id=");}," fill="#999" d="M194.026 83.802a4.965 4.965 0 001.337-.497 4.15 4.15 0 001.204-.994c.36-.425.649-.957.868-1.596.22-.64.329-1.412.329-2.317 0-.896-.091-1.659-.273-2.289-.182-.63-.439-1.157-.77-1.582a3.928 3.928 0 00-1.183-1.022 7.086 7.086 0 00-1.512-.623l.35-.882c.607.13 1.183.352 1.729.665a4.984 4.984 0 011.435 1.246c.41.518.737 1.148.98 1.89s.364 1.608.364 2.597c0 .999-.119 1.862-.357 2.59-.238.728-.56 1.344-.966 1.848a5.036 5.036 0 01-1.428 1.225 6.964 6.964 0 01-1.757.707l-.35-.966zm9.604-2.772c0-.28.091-.506.273-.679.182-.173.418-.259.707-.259.355 0 .63.124.826.371.196.247.294.595.294 1.043a2.36 2.36 0 01-.637 1.659 2.465 2.465 0 01-.588.462c-.21.117-.404.203-.581.259l-.35-.546c.336-.13.625-.317.868-.56.243-.243.364-.537.364-.882-.13.028-.233.042-.308.042-.27 0-.483-.077-.637-.231-.154-.154-.231-.38-.231-.679zm.126-5.502c0-.299.084-.53.252-.693.168-.163.392-.245.672-.245.299 0 .532.082.7.245.168.163.252.394.252.693 0 .27-.084.495-.252.672-.168.177-.401.266-.7.266-.28 0-.504-.089-.672-.266a.938.938 0 01-.252-.672zm18.788 7.196c0 .756-.198 1.328-.595 1.715-.397.387-.922.581-1.575.581h-2.03v-.98h1.526c.57 0 .975-.135 1.218-.406.243-.27.364-.69.364-1.26V81.03c0-.364.07-.695.21-.994.14-.299.308-.558.504-.777.196-.22.397-.392.602-.518.205-.126.373-.198.504-.217v-.084c-.13-.019-.299-.086-.504-.203a2.7 2.7 0 01-1.106-1.225c-.14-.299-.21-.64-.21-1.022v-1.358c0-.55-.114-.966-.343-1.246-.229-.28-.637-.42-1.225-.42h-1.54v-.98h2.03c.317 0 .609.058.875.175.266.117.495.278.686.483.191.205.34.448.448.728.107.28.161.588.161.924v1.428c0 .43.068.789.203 1.078.135.29.303.525.504.707.2.182.415.313.644.392.229.08.432.119.609.119V79c-.177 0-.38.047-.609.14a2.011 2.011 0 00-.644.434 2.44 2.44 0 00-.504.735c-.135.294-.203.642-.203 1.043v1.372zm6.286-1.694c0-.28.091-.506.273-.679.182-.173.418-.259.707-.259.355 0 .63.124.826.371.196.247.294.595.294 1.043a2.36 2.36 0 01-.637 1.659 2.465 2.465 0 01-.588.462c-.21.117-.404.203-.581.259l-.35-.546c.336-.13.625-.317.868-.56.243-.243.364-.537.364-.882-.13.028-.233.042-.308.042-.27 0-.483-.077-.637-.231-.154-.154-.231-.38-.231-.679z"/><path id="..." fill="#000" d="M18.886 105.03c0-.299.084-.53.252-.693.168-.163.392-.245.672-.245.299 0 .532.082.7.245.168.163.252.394.252.693 0 .27-.084.495-.252.672-.168.177-.401.266-.7.266-.28 0-.504-.089-.672-.266a.938.938 0 01-.252-.672zm8.4 0c0-.299.084-.53.252-.693.168-.163.392-.245.672-.245.299 0 .532.082.7.245.168.163.252.394.252.693 0 .27-.084.495-.252.672-.168.177-.401.266-.7.266-.28 0-.504-.089-.672-.266a.938.938 0 01-.252-.672zm8.4 0c0-.299.084-.53.252-.693.168-.163.392-.245.672-.245.299 0 .532.082.7.245.168.163.252.394.252.693 0 .27-.084.495-.252.672-.168.177-.401.266-.7.266-.28 0-.504-.089-.672-.266a.938.938 0 01-.252-.672z"/><path id="function" fill="#07A" d="M16.856 129.8v-.938h1.666v-5.124h-1.666v-.938h1.666v-.392c0-.877.229-1.512.686-1.904.457-.392 1.11-.588 1.96-.588.308 0 .583.019.826.056.243.037.504.112.784.224l-.252.91a2.862 2.862 0 00-.7-.203 4.295 4.295 0 00-.616-.049c-.616 0-1.036.152-1.26.455-.224.303-.336.8-.336 1.491h2.898v.938h-2.898v5.124h2.898v.938h-5.656zm12.25-7h1.988v4.774c0 .457.028.896.084 1.316h.938v.91h-1.862l-.042-1.19h-.056a2.938 2.938 0 01-.966.98c-.401.252-.887.378-1.456.378-.43 0-.796-.049-1.099-.147a1.556 1.556 0 01-.749-.511c-.196-.243-.34-.567-.434-.973-.093-.406-.14-.912-.14-1.519v-3.08h-.938v-.938h2.03v3.794c0 .383.016.726.049 1.029.033.303.1.56.203.77.103.21.254.369.455.476.2.107.469.161.805.161.485 0 .908-.159 1.267-.476.36-.317.632-.714.819-1.19v-3.626h-.896v-.938zm4.62 2.45a14.05 14.05 0 00-.063-1.176 4.657 4.657 0 00-.049-.364h-.938v-.91h1.876l.126 1.134h.07c.093-.159.217-.315.371-.469a2.91 2.91 0 011.225-.721c.252-.075.518-.112.798-.112.43 0 .81.047 1.141.14.331.093.607.259.826.497.22.238.385.56.497.966.112.406.168.922.168 1.547v4.018h-1.092v-3.808c0-.775-.126-1.358-.378-1.75-.252-.392-.71-.588-1.372-.588-.243 0-.478.049-.707.147a2.44 2.44 0 00-.623.385c-.187.159-.35.343-.49.553-.14.21-.243.432-.308.665v4.396h-1.078v-4.55zm13.244-1.372a5.531 5.531 0 00-.693-.189 3.61 3.61 0 00-.735-.077c-.915 0-1.596.215-2.044.644-.448.43-.672 1.11-.672 2.044 0 .41.065.777.196 1.099.13.322.317.595.56.819.243.224.534.397.875.518.34.121.716.182 1.127.182.439 0 .866-.075 1.281-.224.415-.15.763-.345 1.043-.588l.49.812c-.13.112-.294.229-.49.35a4.837 4.837 0 01-1.533.602 4.962 4.962 0 01-1.015.098c-.607 0-1.141-.086-1.603-.259a3.045 3.045 0 01-1.155-.742 3.176 3.176 0 01-.7-1.162 4.525 4.525 0 01-.238-1.505c0-.588.082-1.11.245-1.568.163-.457.399-.84.707-1.148a3.08 3.08 0 011.12-.707 4.187 4.187 0 011.47-.245c.69 0 1.253.06 1.687.182.434.121.8.257 1.099.406l-.014.042v1.946H46.97v-1.33zm2.688-1.078h1.666v-1.386l1.092-.308v1.694h3.738v.938h-3.738v3.304c0 .681.166 1.185.497 1.512.331.327.805.49 1.421.49.42 0 .786-.08 1.099-.238.313-.159.595-.331.847-.518l.364.826a3.938 3.938 0 01-1.169.63 4.182 4.182 0 01-1.393.238 3.41 3.41 0 01-1.057-.161 2.426 2.426 0 01-.875-.497 2.38 2.38 0 01-.602-.861c-.15-.35-.224-.768-.224-1.253v-3.472h-1.666v-.938zm9.436 7v-.938h2.436v-5.124h-2.436v-.938h3.556v6.062h2.38v.938h-5.936zm2.058-8.988c0-.252.084-.469.252-.651a.838.838 0 01.644-.273c.27 0 .497.091.679.273a.889.889 0 01.273.651.806.806 0 01-.273.616.963.963 0 01-.679.252.872.872 0 01-.644-.252.838.838 0 01-.252-.616zm5.67 5.488c0-1.13.294-2.023.882-2.681.588-.658 1.428-.987 2.52-.987.588 0 1.094.096 1.519.287.425.191.777.45 1.057.777.28.327.488.714.623 1.162.135.448.203.929.203 1.442 0 .56-.075 1.066-.224 1.519-.15.453-.369.838-.658 1.155-.29.317-.646.562-1.071.735a3.82 3.82 0 01-1.449.259c-.579 0-1.083-.096-1.512-.287a2.967 2.967 0 01-1.064-.777 3.168 3.168 0 01-.623-1.162 4.963 4.963 0 01-.203-1.442zm1.162 0c0 .327.04.653.119.98.08.327.208.62.385.882.177.261.408.471.693.63.285.159.632.238 1.043.238.747 0 1.309-.231 1.687-.693.378-.462.567-1.141.567-2.037 0-.336-.04-.665-.119-.987a2.608 2.608 0 00-.392-.875 2.066 2.066 0 00-.7-.63c-.285-.159-.632-.238-1.043-.238-.747 0-1.307.229-1.68.686-.373.457-.56 1.139-.56 2.044zm7.742-1.05a14.05 14.05 0 00-.063-1.176 4.657 4.657 0 00-.049-.364h-.938v-.91h1.876l.126 1.134h.07c.093-.159.217-.315.371-.469a2.91 2.91 0 011.225-.721c.252-.075.518-.112.798-.112.43 0 .81.047 1.141.14.331.093.607.259.826.497.22.238.385.56.497.966.112.406.168.922.168 1.547v4.018h-1.092v-3.808c0-.775-.126-1.358-.378-1.75-.252-.392-.71-.588-1.372-.588-.243 0-.478.049-.707.147a2.44 2.44 0 00-.623.385c-.187.159-.35.343-.49.553-.14.21-.243.432-.308.665v4.396h-1.078v-4.55z"/><path id="(){" fill="#999" d="M97.272 132.768a6.964 6.964 0 01-1.757-.707 5.036 5.036 0 01-1.428-1.225c-.406-.504-.728-1.12-.966-1.848s-.357-1.591-.357-2.59c0-.99.121-1.855.364-2.597s.57-1.372.98-1.89c.41-.518.889-.933 1.435-1.246a6.005 6.005 0 011.729-.665l.35.882a7.086 7.086 0 00-1.512.623 3.928 3.928 0 00-1.183 1.022c-.331.425-.588.952-.77 1.582-.182.63-.273 1.393-.273 2.289 0 .905.11 1.678.329 2.317.22.64.509 1.171.868 1.596.36.425.76.756 1.204.994.443.238.889.404 1.337.497l-.35.966zm4.354-.966a4.965 4.965 0 001.337-.497 4.15 4.15 0 001.204-.994c.36-.425.649-.957.868-1.596.22-.64.329-1.412.329-2.317 0-.896-.091-1.659-.273-2.289-.182-.63-.439-1.157-.77-1.582a3.928 3.928 0 00-1.183-1.022 7.086 7.086 0 00-1.512-.623l.35-.882c.607.13 1.183.352 1.729.665a4.984 4.984 0 011.435 1.246c.41.518.737 1.148.98 1.89s.364 1.608.364 2.597c0 .999-.119 1.862-.357 2.59-.238.728-.56 1.344-.966 1.848a5.036 5.036 0 01-1.428 1.225 6.964 6.964 0 01-1.757.707l-.35-.966zm17.878-2.45c0-.401-.068-.749-.203-1.043a2.44 2.44 0 00-.504-.735c-.2-.196-.415-.34-.644-.434a1.641 1.641 0 00-.609-.14v-.98c.177 0 .38-.04.609-.119.229-.08.443-.21.644-.392.2-.182.369-.418.504-.707.135-.29.203-.649.203-1.078v-1.428c0-.336.054-.644.161-.924a2.22 2.22 0 01.448-.728c.191-.205.42-.366.686-.483.266-.117.558-.175.875-.175h2.03v.98h-1.54c-.588 0-.996.14-1.225.42-.229.28-.343.695-.343 1.246v1.358c0 .383-.07.723-.21 1.022a2.7 2.7 0 01-1.106 1.225c-.205.117-.373.184-.504.203v.084c.121.019.285.091.49.217.205.126.406.299.602.518.196.22.366.478.511.777.145.299.217.63.217.994v1.344c0 .57.121.99.364 1.26s.649.406 1.218.406h1.526v.98h-2.03c-.653 0-1.178-.194-1.575-.581-.397-.387-.595-.959-.595-1.715v-1.372z"/><path id="alert" fill="#000" d="M134.736 123.346a4.447 4.447 0 011.358-.504 7.423 7.423 0 011.484-.154c.476 0 .866.075 1.169.224.303.15.541.343.714.581.173.238.29.509.35.812.06.303.091.609.091.917 0 .355-.01.733-.028 1.134-.019.401-.033.803-.042 1.204 0 .467.028.91.084 1.33h.938v.91h-1.862l-.126-1.05h-.07c-.056.084-.14.191-.252.322-.112.13-.259.259-.441.385a2.749 2.749 0 01-1.589.469c-.69 0-1.237-.177-1.638-.532-.401-.355-.602-.84-.602-1.456 0-.476.105-.873.315-1.19.21-.317.511-.56.903-.728.392-.168.866-.266 1.421-.294a9.544 9.544 0 011.869.112c.047-.43.054-.786.021-1.071-.033-.285-.107-.511-.224-.679a.938.938 0 00-.49-.357 2.482 2.482 0 00-.777-.105c-.42 0-.821.058-1.204.175-.383.117-.723.236-1.022.357l-.35-.812zm2.058 5.642c.261 0 .504-.042.728-.126a2.22 2.22 0 00.588-.322 2.133 2.133 0 00.672-.868v-.98a7.92 7.92 0 00-1.344-.126c-.41 0-.765.044-1.064.133-.299.089-.532.226-.7.413-.168.187-.252.43-.252.728 0 .308.105.576.315.805.21.229.562.343 1.057.343zM143.29 120h2.324v7.448c0 .57.096.97.287 1.204.191.233.474.35.847.35.261 0 .511-.047.749-.14.238-.093.502-.252.791-.476l.504.77c-.15.13-.313.247-.49.35a3.638 3.638 0 01-1.106.42 2.963 2.963 0 01-1.442-.077 1.579 1.579 0 01-.679-.427 1.897 1.897 0 01-.413-.777c-.093-.322-.14-.721-.14-1.197v-6.51h-1.232V120zm14.14 8.918c-.168.15-.366.29-.595.42a4.39 4.39 0 01-.749.336c-.27.093-.553.166-.847.217-.294.051-.59.077-.889.077-.56 0-1.055-.086-1.484-.259a2.858 2.858 0 01-1.078-.742 3.234 3.234 0 01-.658-1.155 4.767 4.767 0 01-.224-1.512c0-.588.082-1.11.245-1.568.163-.457.399-.84.707-1.148a3.08 3.08 0 011.12-.707 4.187 4.187 0 011.47-.245c.392 0 .78.051 1.162.154.383.103.721.296 1.015.581.294.285.52.677.679 1.176.159.5.215 1.146.168 1.939h-5.418c0 .84.226 1.468.679 1.883.453.415 1.057.623 1.813.623.252 0 .502-.03.749-.091.247-.06.483-.133.707-.217a3.72 3.72 0 00.595-.28c.173-.103.306-.196.399-.28l.434.798zm-2.954-5.362c-.308 0-.6.033-.875.098a1.995 1.995 0 00-.728.329c-.21.154-.383.355-.518.602s-.222.553-.259.917h4.354c-.047-.616-.245-1.094-.595-1.435-.35-.34-.81-.511-1.379-.511zm4.872 6.244v-.938h1.89v-5.124h-1.89v-.938h2.618l.224.91h.07c.317-.29.672-.537 1.064-.742.392-.205.859-.308 1.4-.308.317 0 .572.06.763.182.191.121.34.299.448.532.107.233.18.516.217.847.037.331.056.707.056 1.127l-.98.014c0-.597-.058-1.036-.175-1.316-.117-.28-.329-.42-.637-.42-.29 0-.55.042-.784.126a2.565 2.565 0 00-.609.308c-.173.121-.32.243-.441.364s-.21.224-.266.308v4.13h2.688v.938h-5.656zm7.91-7h1.666v-1.386l1.092-.308v1.694h3.738v.938h-3.738v3.304c0 .681.166 1.185.497 1.512.331.327.805.49 1.421.49.42 0 .786-.08 1.099-.238.313-.159.595-.331.847-.518l.364.826a3.938 3.938 0 01-1.169.63 4.182 4.182 0 01-1.393.238 3.41 3.41 0 01-1.057-.161 2.426 2.426 0 01-.875-.497 2.38 2.38 0 01-.602-.861c-.15-.35-.224-.768-.224-1.253v-3.472h-1.666v-.938z"/><path id="(" fill="#999" d="M181.272 132.768a6.964 6.964 0 01-1.757-.707 5.036 5.036 0 01-1.428-1.225c-.406-.504-.728-1.12-.966-1.848s-.357-1.591-.357-2.59c0-.99.121-1.855.364-2.597s.57-1.372.98-1.89c.41-.518.889-.933 1.435-1.246a6.005 6.005 0 011.729-.665l.35.882a7.086 7.086 0 00-1.512.623 3.928 3.928 0 00-1.183 1.022c-.331.425-.588.952-.77 1.582-.182.63-.273 1.393-.273 2.289 0 .905.11 1.678.329 2.317.22.64.509 1.171.868 1.596.36.425.76.756 1.204.994.443.238.889.404 1.337.497l-.35.966z"/><path id="i" fill="#000" d="M185.094 129.8v-.938h2.436v-5.124h-2.436v-.938h3.556v6.062h2.38v.938h-5.936zm2.058-8.988c0-.252.084-.469.252-.651a.838.838 0 01.644-.273c.27 0 .497.091.679.273a.889.889 0 01.273.651.806.806 0 01-.273.616.963.963 0 01-.679.252.872.872 0 01-.644-.252.838.838 0 01-.252-.616z"/><path id=");}];" fill="#999" d="M194.026 131.802a4.965 4.965 0 001.337-.497 4.15 4.15 0 001.204-.994c.36-.425.649-.957.868-1.596.22-.64.329-1.412.329-2.317 0-.896-.091-1.659-.273-2.289-.182-.63-.439-1.157-.77-1.582a3.928 3.928 0 00-1.183-1.022 7.086 7.086 0 00-1.512-.623l.35-.882c.607.13 1.183.352 1.729.665a4.984 4.984 0 011.435 1.246c.41.518.737 1.148.98 1.89s.364 1.608.364 2.597c0 .999-.119 1.862-.357 2.59-.238.728-.56 1.344-.966 1.848a5.036 5.036 0 01-1.428 1.225 6.964 6.964 0 01-1.757.707l-.35-.966zm9.604-2.772c0-.28.091-.506.273-.679.182-.173.418-.259.707-.259.355 0 .63.124.826.371.196.247.294.595.294 1.043a2.36 2.36 0 01-.637 1.659 2.465 2.465 0 01-.588.462c-.21.117-.404.203-.581.259l-.35-.546c.336-.13.625-.317.868-.56.243-.243.364-.537.364-.882-.13.028-.233.042-.308.042-.27 0-.483-.077-.637-.231-.154-.154-.231-.38-.231-.679zm.126-5.502c0-.299.084-.53.252-.693.168-.163.392-.245.672-.245.299 0 .532.082.7.245.168.163.252.394.252.693 0 .27-.084.495-.252.672-.168.177-.401.266-.7.266-.28 0-.504-.089-.672-.266a.938.938 0 01-.252-.672zm18.788 7.196c0 .756-.198 1.328-.595 1.715-.397.387-.922.581-1.575.581h-2.03v-.98h1.526c.57 0 .975-.135 1.218-.406.243-.27.364-.69.364-1.26v-1.344c0-.364.07-.695.21-.994.14-.299.308-.558.504-.777.196-.22.397-.392.602-.518.205-.126.373-.198.504-.217v-.084c-.13-.019-.299-.086-.504-.203a2.7 2.7 0 01-1.106-1.225c-.14-.299-.21-.64-.21-1.022v-1.358c0-.55-.114-.966-.343-1.246-.229-.28-.637-.42-1.225-.42h-1.54v-.98h2.03c.317 0 .609.058.875.175.266.117.495.278.686.483.191.205.34.448.448.728.107.28.161.588.161.924v1.428c0 .43.068.789.203 1.078.135.29.303.525.504.707.2.182.415.313.644.392.229.08.432.119.609.119v.98c-.177 0-.38.047-.609.14a2.011 2.011 0 00-.644.434 2.44 2.44 0 00-.504.735c-.135.294-.203.642-.203 1.043v1.372zM5.138 157.02H.35v-.98h3.696v-11.06H.35V144h4.788v13.02zm5.292-3.99c0-.28.091-.506.273-.679.182-.173.418-.259.707-.259.355 0 .63.124.826.371.196.247.294.595.294 1.043a2.36 2.36 0 01-.637 1.659 2.465 2.465 0 01-.588.462c-.21.117-.404.203-.581.259l-.35-.546c.336-.13.625-.317.868-.56.243-.243.364-.537.364-.882-.13.028-.233.042-.308.042-.27 0-.483-.077-.637-.231-.154-.154-.231-.38-.231-.679zm.126-5.502c0-.299.084-.53.252-.693.168-.163.392-.245.672-.245.299 0 .532.082.7.245.168.163.252.394.252.693 0 .27-.084.495-.252.672-.168.177-.401.266-.7.266-.28 0-.504-.089-.672-.266a.938.938 0 01-.252-.672z"/></g><g id="Group-Copy" transform="translate(354 66)"><path id="Line" fill="#EE6B47" fill-rule="nonzero" d="M16.5 15.5l14 7-14 7v-6h-14v-2h14v-6z"/><text id="outer" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal"><tspan x="0" y="11">outer</tspan></text></g><g id="Group-Copy-2" fill="#EE6B47" fill-rule="nonzero" transform="translate(242 44)"><path id="Line" d="M13.5-5.5l14 7-14 7v-6h-14v-2h14v-6z"/></g><g id="Group-3" transform="translate(279 36)"><path id="Rectangle-1" fill="#FFF9EB" stroke="#E8C48E" stroke-width="2" d="M1 1h52v18H1z"/><text id="i:-0" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="8" y="14">i: 0</tspan></text></g><g id="Group-Copy-3" fill="#EE6B47" fill-rule="nonzero" transform="translate(242 67)"><path id="Line" d="M13.5-5.5l14 7-14 7v-6h-14v-2h14v-6z"/></g><g id="Group-3-Copy" transform="translate(279 59)"><path id="Rectangle-1" fill="#FFF9EB" stroke="#E8C48E" stroke-width="2" d="M1 1h52v18H1z"/><text id="i:-1" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="8" y="14">i: 1</tspan></text></g><g id="Group-Copy-4" fill="#EE6B47" fill-rule="nonzero" transform="translate(242 90)"><path id="Line" d="M13.5-5.5l14 7-14 7v-6h-14v-2h14v-6z"/></g><g id="Group-3-Copy-2" transform="translate(279 82)"><path id="Rectangle-1" fill="#FFF9EB" stroke="#E8C48E" stroke-width="2" d="M1 1h52v18H1z"/><text id="i:-2" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="8" y="14">i: 2</tspan></text></g><g id="Group-Copy-5" fill="#EE6B47" fill-rule="nonzero" transform="translate(242 139)"><path id="Line" d="M13.5-5.5l14 7-14 7v-6h-14v-2h14v-6z"/></g><g id="Group-3-Copy-3" transform="translate(279 131)"><path id="Rectangle-1" fill="#FFF9EB" stroke="#E8C48E" stroke-width="2" d="M1 1h52v18H1z"/><text id="i:-10" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="7.447" y="13.51">i: 10</tspan></text></g><text id="..." fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="403" y="94">...</tspan></text><text id="makeArmy()-LexicalEn" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="403" y="64">makeArmy()</tspan> <tspan x="403" y="79">LexicalEnvironment</tspan></text><text id="for-block-LexicalEnv" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="278" y="14">for block</tspan> <tspan x="278" y="29">LexicalEnvironment</tspan></text></g></g></svg>
\ No newline at end of file
diff --git a/1-js/06-advanced-functions/03-closure/10-make-army/solution.md b/1-js/06-advanced-functions/03-closure/10-make-army/solution.md
index 0fb0b4a49..9d99aa717 100644
--- a/1-js/06-advanced-functions/03-closure/10-make-army/solution.md
+++ b/1-js/06-advanced-functions/03-closure/10-make-army/solution.md
@@ -1,12 +1,12 @@
 
-Let's examine what's done inside `makeArmy`, and the solution will become obvious.
+Let's examine what exactly happens inside `makeArmy`, and the solution will become obvious.
 
 1. It creates an empty array `shooters`:
 
     ```js
     let shooters = [];
     ```
-2. Fills it in the loop via `shooters.push(function...)`.
+2. Fills it with functions via `shooters.push(function)` in the loop.
 
     Every element is a function, so the resulting array looks like this:
 
@@ -26,95 +26,104 @@ Let's examine what's done inside `makeArmy`, and the solution will become obviou
     ```
 
 3. The array is returned from the function.
+    
+    Then, later, the call to any member, e.g. `army[5]()` will get the element `army[5]` from the array (which is a function) and calls it.
+    
+    Now why do all such functions show the same value, `10`?
+    
+    That's because there's no local variable `i` inside `shooter` functions. When such a function is called, it takes `i` from its outer lexical environment.
+    
+    Then, what will be the value of `i`?
+    
+    If we look at the source:
+    
+    ```js
+    function makeArmy() {
+      ...
+      let i = 0;
+      while (i < 10) {
+        let shooter = function() { // shooter function
+          alert( i ); // should show its number
+        };
+        shooters.push(shooter); // add function to the array
+        i++;
+      }
+      ...
+    }
+    ```
+    
+    We can see that all `shooter` functions are created in the lexical environment of `makeArmy()` function. But when `army[5]()` is called, `makeArmy` has already finished its job, and the final value of `i` is `10` (`while` stops at `i=10`).
+    
+    As the result, all `shooter` functions get the same value from the outer lexical environment and that is, the last value, `i=10`.
+    
+    ![](lexenv-makearmy-empty.svg)
+    
+    As you can see above, on each iteration of a `while {...}` block, a new lexical environment is created. So, to fix this, we can copy the value of `i` into a variable within the `while {...}` block, like this:
+    
+    ```js run
+    function makeArmy() {
+      let shooters = [];
+    
+      let i = 0;
+      while (i < 10) {
+        *!*
+          let j = i;
+        */!*
+          let shooter = function() { // shooter function
+            alert( *!*j*/!* ); // should show its number
+          };
+        shooters.push(shooter);
+        i++;
+      }
+    
+      return shooters;
+    }
+    
+    let army = makeArmy();
+    
+    // Now the code works correctly
+    army[0](); // 0
+    army[5](); // 5
+    ```
+    
+    Here `let j = i` declares an "iteration-local" variable `j` and copies `i` into it. Primitives are copied "by value", so we actually get an independent copy of `i`, belonging to the current loop iteration.
+    
+    The shooters work correctly, because the value of `i` now lives a little bit closer. Not in `makeArmy()` Lexical Environment, but in the Lexical Environment that corresponds to the current loop iteration:
+    
+    ![](lexenv-makearmy-while-fixed.svg)
+    
+    Such a problem could also be avoided if we used `for` in the beginning, like this:
+    
+    ```js run demo
+    function makeArmy() {
+    
+      let shooters = [];
+    
+    *!*
+      for(let i = 0; i < 10; i++) {
+    */!*
+        let shooter = function() { // shooter function
+          alert( i ); // should show its number
+        };
+        shooters.push(shooter);
+      }
+    
+      return shooters;
+    }
+    
+    let army = makeArmy();
+    
+    army[0](); // 0
+    army[5](); // 5
+    ```
+    
+    That's essentially the same, because `for` on each iteration generates a new lexical environment, with its own variable `i`. So `shooter` generated in every iteration references its own `i`, from that very iteration.
+    
+    ![](lexenv-makearmy-for-fixed.svg)
 
-Then, later, the call to `army[5]()` will get the element `army[5]` from the array (it will be a function) and call it.
-
-Now why all such functions show the same?
-
-That's because there's no local variable `i` inside `shooter` functions. When such a function is called, it takes `i` from its outer lexical environment.
-
-What will be the value of `i`?
-
-If we look at the source:
-
-```js
-function makeArmy() {
-  ...
-  let i = 0;
-  while (i < 10) {
-    let shooter = function() { // shooter function
-      alert( i ); // should show its number
-    };
-    ...
-  }
-  ...
-}
-```
-
-...We can see that it lives in the lexical environment associated with the current `makeArmy()` run. But when `army[5]()` is called, `makeArmy` has already finished its job, and `i` has the last value: `10` (the end of `while`).
-
-As a result, all `shooter` functions get from the outer lexical envrironment the same, last value `i=10`.
-
-We can fix it by moving the variable definition into the loop:
-
-```js run demo
-function makeArmy() {
-
-  let shooters = [];
-
-*!*
-  for(let i = 0; i < 10; i++) {
-*/!*
-    let shooter = function() { // shooter function
-      alert( i ); // should show its number
-    };
-    shooters.push(shooter);
-  }
-
-  return shooters;
-}
-
-let army = makeArmy();
-
-army[0](); // 0
-army[5](); // 5
-```
-
-Now it works correctly, because every time the code block in `for (let i=0...) {...}` is executed, a new Lexical Environment is created for it, with the corresponding variable `i`.
-
-So, the value of `i` now lives a little bit closer. Not in `makeArmy()` Lexical Environment, but in the Lexical Environment that corresponds the current loop iteration. That's why now it works.
-
-![](lexenv-makearmy.svg)
-
-Here we rewrote `while` into `for`.
-
-Another trick could be possible, let's see it for better understanding of the subject:
-
-```js run
-function makeArmy() {
-  let shooters = [];
-
-  let i = 0;
-  while (i < 10) {
-*!*
-    let j = i;
-*/!*
-    let shooter = function() { // shooter function
-      alert( *!*j*/!* ); // should show its number
-    };
-    shooters.push(shooter);
-    i++;
-  }
-
-  return shooters;
-}
-
-let army = makeArmy();
+Now, as you've put so much effort into reading this, and the final recipe is so simple - just use `for`, you may wonder -- was it worth that?
 
-army[0](); // 0
-army[5](); // 5
-```
+Well, if you could easily answer the question, you wouldn't read the solution. So, hopefully this task must have helped you to understand things a bit better. 
 
-The `while` loop, just like `for`, makes a new Lexical Environment for each run. So here we make sure that it gets the right value for a `shooter`.
+Besides, there are indeed cases when one prefers `while` to `for`, and other scenarios, where such problems are real.
 
-We copy `let j = i`. This makes a loop body local `j` and copies the value of `i` to it. Primitives are copied "by value", so we actually get a complete independent copy of `i`, belonging to the current loop iteration.
diff --git a/1-js/06-advanced-functions/03-closure/10-make-army/task.md b/1-js/06-advanced-functions/03-closure/10-make-army/task.md
index 93e64f2d0..f50c7dc20 100644
--- a/1-js/06-advanced-functions/03-closure/10-make-army/task.md
+++ b/1-js/06-advanced-functions/03-closure/10-make-army/task.md
@@ -14,22 +14,28 @@ function makeArmy() {
 
   let i = 0;
   while (i < 10) {
-    let shooter = function() { // shooter function
-      alert( i ); // should show its number
+    let shooter = function() { // create a shooter function,
+      alert( i ); // that should show its number
     };
-    shooters.push(shooter);
+    shooters.push(shooter); // and add it to the array
     i++;
   }
 
+  // ...and return the array of shooters
   return shooters;
 }
 
 let army = makeArmy();
 
-army[0](); // the shooter number 0 shows 10
-army[5](); // and number 5 also outputs 10...
-// ... all shooters show 10 instead of their 0, 1, 2, 3...
+*!*
+// all shooters show 10 instead of their numbers 0, 1, 2, 3...
+army[0](); // 10 from the shooter number 0
+army[1](); // 10 from the shooter number 1
+army[2](); // 10 ...and so on.
+*/!*
 ```
 
-Why do all of the shooters show the same value? Fix the code so that they work as intended.
+Why do all of the shooters show the same value? 
+
+Fix the code so that they work as intended.
 
diff --git a/1-js/06-advanced-functions/03-closure/5-function-in-if/task.md b/1-js/06-advanced-functions/03-closure/5-function-in-if/task.md
index d02c53b99..4e386eec5 100644
--- a/1-js/06-advanced-functions/03-closure/5-function-in-if/task.md
+++ b/1-js/06-advanced-functions/03-closure/5-function-in-if/task.md
@@ -1,4 +1,6 @@
+importance: 5
 
+---
 # Function in if
 
 Look at the code. What will be the result of the call at the last line?
diff --git a/1-js/06-advanced-functions/03-closure/7-let-scope/solution.md b/1-js/06-advanced-functions/03-closure/7-let-scope/solution.md
index f20ac9e5d..b16b35290 100644
--- a/1-js/06-advanced-functions/03-closure/7-let-scope/solution.md
+++ b/1-js/06-advanced-functions/03-closure/7-let-scope/solution.md
@@ -15,7 +15,7 @@ function func() {
 func();
 ```
 
-In this example we can observe the peculiar difference between a "non-existing" and "unitialized" variable.
+In this example we can observe the peculiar difference between a "non-existing" and "uninitialized" variable.
 
 As you may have read in the article [](info:closure), a variable starts in the "uninitialized" state from the moment when the execution enters a code block (or a function). And it stays uninitalized until the corresponding `let` statement.
 
@@ -27,11 +27,11 @@ The code above demonstrates it.
 function func() {
 *!*
   // the local variable x is known to the engine from the beginning of the function,
-  // but "unitialized" (unusable) until let ("dead zone")
+  // but "uninitialized" (unusable) until let ("dead zone")
   // hence the error
 */!*
 
-  console.log(x); // ReferenceError: Cannot access 'vx before initialization
+  console.log(x); // ReferenceError: Cannot access 'x' before initialization
 
   let x = 2;
 }
diff --git a/1-js/06-advanced-functions/03-closure/9-sort-by-field/_js.view/solution.js b/1-js/06-advanced-functions/03-closure/9-sort-by-field/_js.view/solution.js
new file mode 100644
index 000000000..8a71c869d
--- /dev/null
+++ b/1-js/06-advanced-functions/03-closure/9-sort-by-field/_js.view/solution.js
@@ -0,0 +1,3 @@
+function byField(fieldName){
+  return (a, b) => a[fieldName] > b[fieldName] ? 1 : -1;
+}
diff --git a/1-js/06-advanced-functions/03-closure/9-sort-by-field/_js.view/source.js b/1-js/06-advanced-functions/03-closure/9-sort-by-field/_js.view/source.js
new file mode 100644
index 000000000..23b433834
--- /dev/null
+++ b/1-js/06-advanced-functions/03-closure/9-sort-by-field/_js.view/source.js
@@ -0,0 +1,5 @@
+function byField(fieldName){
+
+  // Your code goes here.
+
+}
diff --git a/1-js/06-advanced-functions/03-closure/9-sort-by-field/_js.view/test.js b/1-js/06-advanced-functions/03-closure/9-sort-by-field/_js.view/test.js
new file mode 100644
index 000000000..802f28c4d
--- /dev/null
+++ b/1-js/06-advanced-functions/03-closure/9-sort-by-field/_js.view/test.js
@@ -0,0 +1,39 @@
+describe("byField", function(){
+
+  let users = [
+    { name: "John", age: 20, surname: "Johnson" },
+    { name: "Pete", age: 18, surname: "Peterson" },
+    { name: "Ann", age: 19, surname: "Hathaway" },
+  ];
+
+  it("sorts users by name", function(){
+    let nameSortedKey = [
+      { name: "Ann", age: 19, surname: "Hathaway" },
+      { name: "John", age: 20, surname: "Johnson"},
+      { name: "Pete", age: 18, surname: "Peterson" },
+    ];
+    let nameSortedAnswer = users.sort(byField("name"));
+    assert.deepEqual(nameSortedKey, nameSortedAnswer);
+  });
+
+  it("sorts users by age", function(){
+    let ageSortedKey = [
+      { name: "Pete", age: 18, surname: "Peterson" },
+      { name: "Ann", age: 19, surname: "Hathaway" },
+      { name: "John", age: 20, surname: "Johnson"},
+    ];
+    let ageSortedAnswer = users.sort(byField("age"));
+    assert.deepEqual(ageSortedKey, ageSortedAnswer);
+  });
+
+  it("sorts users by surname", function(){
+    let surnameSortedKey = [
+      { name: "Ann", age: 19, surname: "Hathaway" },
+      { name: "John", age: 20, surname: "Johnson"},
+      { name: "Pete", age: 18, surname: "Peterson" },
+    ];
+    let surnameSortedAnswer = users.sort(byField("surname"));
+    assert.deepEqual(surnameSortedAnswer, surnameSortedKey);
+  });
+
+});
diff --git a/1-js/06-advanced-functions/03-closure/9-sort-by-field/solution.md b/1-js/06-advanced-functions/03-closure/9-sort-by-field/solution.md
index bd57085ea..8b1378917 100644
--- a/1-js/06-advanced-functions/03-closure/9-sort-by-field/solution.md
+++ b/1-js/06-advanced-functions/03-closure/9-sort-by-field/solution.md
@@ -1,22 +1 @@
 
-
-```js run
-let users = [
-  { name: "John", age: 20, surname: "Johnson" }, 
-  { name: "Pete", age: 18, surname: "Peterson" },
-  { name: "Ann", age: 19, surname: "Hathaway" }
-];
-
-*!*
-function byField(field) {
-  return (a, b) => a[field] > b[field] ? 1 : -1;
-}
-*/!*
-
-users.sort(byField('name'));
-users.forEach(user => alert(user.name)); // Ann, John, Pete
-
-users.sort(byField('age'));
-users.forEach(user => alert(user.name)); // Pete, Ann, John
-```
-
diff --git a/1-js/06-advanced-functions/03-closure/article.md b/1-js/06-advanced-functions/03-closure/article.md
index 0f3bc8cc8..cb43a7968 100644
--- a/1-js/06-advanced-functions/03-closure/article.md
+++ b/1-js/06-advanced-functions/03-closure/article.md
@@ -1,11 +1,15 @@
 
-# Variable scope
+# Variable scope, closure
 
-JavaScript is a very function-oriented language. It gives us a lot of freedom. A function can be created dynamically, passed as an argument to another function and called from a totally different place of code later.
+JavaScript is a very function-oriented language. It gives us a lot of freedom. A function can be created at any moment, passed as an argument to another function, and then called from a totally different place of code later.
 
-We already know that a function can access variables outside of it.
+We already know that a function can access variables outside of it ("outer" variables).
 
-Now let's expand our knowledge to include more complex scenarios.
+But what happens if outer variables change since a function is created? Will the function get newer values or the old ones?
+
+And what if a function is passed along as an argument and called from another place of code, will it get access to outer variables at the new place?
+
+Let's expand our knowledge to understand these scenarios and more complex ones.
 
 ```smart header="We'll talk about `let/const` variables here"
 In JavaScript, there are 3 ways to declare a variable: `let`, `const` (the modern ones), and `var` (the remnant of the past).
@@ -142,7 +146,7 @@ Despite being simple, slightly modified variants of that code have practical use
 
 How does this work? If we create multiple counters, will they be independent? What's going on with the variables here?
 
-Undestanding such things is great for the overall knowledge of JavaScript and beneficial for more complex scenarios. So let's go a bit in-depth.
+Understanding such things is great for the overall knowledge of JavaScript and beneficial for more complex scenarios. So let's go a bit in-depth.
 
 ## Lexical Environment
 
@@ -182,8 +186,8 @@ Here's a little bit longer code:
 Rectangles on the right-hand side demonstrate how the global Lexical Environment changes during the execution:
 
 1. When the script starts, the Lexical Environment is pre-populated with all declared variables.
-    - Initially, they are in the "Uninitialized" state. That's a special internal state, it means that the engine knows about the variable, but won't allow to use it before `let`. It's almost the same as if the variable didn't exist.
-2. Then `let phrase` definition appears. There's no assignment yet, so its value is `undefined`. We can use the variable since this moment.
+    - Initially, they are in the "Uninitialized" state. That's a special internal state, it means that the engine knows about the variable, but it cannot be referenced until it has been declared with `let`. It's almost the same as if the variable didn't exist.
+2. Then `let phrase` definition appears. There's no assignment yet, so its value is `undefined`. We can use the variable from this point forward.
 3. `phrase` is assigned a value.
 4. `phrase` changes the value.
 
@@ -286,7 +290,7 @@ Later, when `counter()` is called, a new Lexical Environment is created for the
 
 ![](closure-makecounter-nested-call.svg)
 
-Now when the code inside `counter()` looks for `count` variable, it first searches its own Lexical Environment (empty, as there are no local variables there), then the Lexical Environment of the outer `makeCounter()` call, where finds it and changes.
+Now when the code inside `counter()` looks for `count` variable, it first searches its own Lexical Environment (empty, as there are no local variables there), then the Lexical Environment of the outer `makeCounter()` call, where it finds and changes it.
 
 **A variable is updated in the Lexical Environment where it lives.**
 
@@ -310,7 +314,7 @@ When on an interview, a frontend developer gets a question about "what's a closu
 
 Usually, a Lexical Environment is removed from memory with all the variables after the function call finishes. That's because there are no references to it. As any JavaScript object, it's only kept in memory while it's reachable.
 
-...But if there's a nested function that is still reachable after the end of a function, then it has `[[Environment]]` property that references the lexical environment.
+However, if there's a nested function that is still reachable after the end of a function, then it has `[[Environment]]` property that references the lexical environment.
 
 In that case the Lexical Environment is still reachable even after the completion of the function, so it stays alive.
 
@@ -329,7 +333,7 @@ let g = f(); // g.[[Environment]] stores a reference to the Lexical Environment
 // of the corresponding f() call
 ```
 
-Please note that if `f()` is called many times, and resulting functions are saved, then all corresponding Lexical Environment objects will also be retained in memory. All 3 of them in the code below:
+Please note that if `f()` is called many times, and resulting functions are saved, then all corresponding Lexical Environment objects will also be retained in memory. In the code below, all 3 of them:
 
 ```js
 function f() {
@@ -345,7 +349,7 @@ let arr = [f(), f(), f()];
 
 A Lexical Environment object dies when it becomes unreachable (just like any other object). In other words, it exists only while there's at least one nested function referencing it.
 
-In the code below, after the nested function is removed, its enclosing Lexical Environment (and hence the `value`) is cleaned from memory;
+In the code below, after the nested function is removed, its enclosing Lexical Environment (and hence the `value`) is cleaned from memory:
 
 ```js
 function f() {
@@ -367,7 +371,7 @@ As we've seen, in theory while a function is alive, all outer variables are also
 
 But in practice, JavaScript engines try to optimize that. They analyze variable usage and if it's obvious from the code that an outer variable is not used -- it is removed.
 
-**An important side effect in V8 (Chrome, Opera) is that such variable will become unavailable in debugging.**
+**An important side effect in V8 (Chrome, Edge, Opera) is that such variable will become unavailable in debugging.**
 
 Try running the example below in Chrome with the Developer Tools open.
 
@@ -409,6 +413,6 @@ let g = f();
 g();
 ```
 
-This feature of V8 is good to know. If you are debugging with Chrome/Opera, sooner or later you will meet it.
+This feature of V8 is good to know. If you are debugging with Chrome/Edge/Opera, sooner or later you will meet it.
 
-That is not a bug in the debugger, but rather a special feature of V8. Perhaps it will be changed sometime. You always can check for it by running the examples on this page.
+That is not a bug in the debugger, but rather a special feature of V8. Perhaps it will be changed sometime. You can always check for it by running the examples on this page.
diff --git a/1-js/06-advanced-functions/04-var/article.md b/1-js/06-advanced-functions/04-var/article.md
index ab8068f8b..28d7a76ec 100644
--- a/1-js/06-advanced-functions/04-var/article.md
+++ b/1-js/06-advanced-functions/04-var/article.md
@@ -4,7 +4,7 @@
 ```smart header="This article is for understanding old scripts"
 The information in this article is useful for understanding old scripts.
 
-That's not how we write a new code.
+That's not how we write new code.
 ```
 
 In the very first chapter about [variables](info:variables), we mentioned three ways of variable declaration:
@@ -13,31 +13,22 @@ In the very first chapter about [variables](info:variables), we mentioned three
 2. `const`
 3. `var`
 
-`let` and `const` behave exactly the same way in terms of Lexical Environments.
-
-But `var` is a very different beast, that originates from very old times. It's generally not used in modern scripts, but still lurks in the old ones.
-
-If you don't plan on meeting such scripts you may even skip this chapter or postpone it, but then there's a chance that it bites you later.
-
-From the first sight, `var` behaves similar to `let`. That is, declares a variable:
+The `var` declaration is similar to `let`. Most of the time we can replace `let` by `var` or vice-versa and expect things to work:
 
 ```js run
-function sayHi() {
-  var phrase = "Hello"; // local variable, "var" instead of "let"
-
-  alert(phrase); // Hello
-}
+var message = "Hi";
+alert(message); // Hi
+```
 
-sayHi();
+But internally `var` is a very different beast, that originates from very old times. It's generally not used in modern scripts, but still lurks in the old ones.
 
-alert(phrase); // Error, phrase is not defined
-```
+If you don't plan on meeting such scripts you may even skip this chapter or postpone it.
 
-...But here are the differences.
+On the other hand, it's important to understand differences when migrating old scripts from `var` to `let`, to avoid odd errors.
 
 ## "var" has no block scope
 
-Variables, declared with `var`, are either function-wide or global. They are visible through blocks.
+Variables, declared with `var`, are either function-scoped or global-scoped. They are visible through blocks.
 
 For instance:
 
@@ -61,19 +52,21 @@ if (true) {
 }
 
 *!*
-alert(test); // Error: test is not defined
+alert(test); // ReferenceError: test is not defined
 */!*
 ```
 
 The same thing for loops: `var` cannot be block- or loop-local:
 
-```js
+```js run
 for (var i = 0; i < 10; i++) {
+  var one = 1;
   // ...
 }
 
 *!*
-alert(i); // 10, "i" is visible after loop, it's a global variable
+alert(i);   // 10, "i" is visible after loop, it's a global variable
+alert(one); // 1, "one" is visible after loop, it's a global variable
 */!*
 ```
 
@@ -89,12 +82,32 @@ function sayHi() {
 }
 
 sayHi();
-alert(phrase); // Error: phrase is not defined (Check the Developer Console)
+alert(phrase); // ReferenceError: phrase is not defined
+```
+
+As we can see, `var` pierces through `if`, `for` or other code blocks. That's because a long time ago in JavaScript, blocks had no Lexical Environments, and `var` is a remnant of that.
+
+## "var" tolerates redeclarations
+
+If we declare the same variable with `let` twice in the same scope, that's an error:
+
+```js run
+let user;
+let user; // SyntaxError: 'user' has already been declared
 ```
 
-As we can see, `var` pierces through `if`, `for` or other code blocks. That's because a long time ago in JavaScript blocks had no Lexical Environments. And `var` is a remnant of that.
+With `var`, we can redeclare a variable any number of times. If we use `var` with an already-declared variable, it's just ignored:
+
+```js run
+var user = "Pete";
+
+var user = "John"; // this "var" does nothing (already declared)
+// ...it doesn't trigger an error
+
+alert(user); // John
+```
 
-## "var" declarations are processed at the function start
+## "var" variables can be declared below their use
 
 `var` declarations are processed when the function starts (or script starts for globals).
 
@@ -153,11 +166,11 @@ So in the example above, `if (false)` branch never executes, but that doesn't ma
 
 **Declarations are hoisted, but assignments are not.**
 
-That's better to demonstrate with an example, like this:
+That's best demonstrated with an example:
 
 ```js run
 function sayHi() {
-  alert(phrase);  
+  alert(phrase);
 
 *!*
   var phrase = "Hello";
@@ -192,11 +205,11 @@ sayHi();
 
 Because all `var` declarations are processed at the function start, we can reference them at any place. But variables are undefined until the assignments.
 
-In both examples above `alert` runs without an error, because the variable `phrase` exists. But its value is not yet assigned, so it shows `undefined`.
+In both examples above, `alert` runs without an error, because the variable `phrase` exists. But its value is not yet assigned, so it shows `undefined`.
 
-### IIFE
+## IIFE
 
-As in the past there was only `var`, and it has no block-level visibility, programmers invented a way to emulate it. What they did was called "immediately-invoked function expressions" (abbreviated as IIFE).
+In the past, as there was only `var`, and it has no block-level visibility, programmers invented a way to emulate it. What they did was called "immediately-invoked function expressions" (abbreviated as IIFE).
 
 That's not something we should use nowadays, but you can find them in old scripts.
 
@@ -205,22 +218,22 @@ An IIFE looks like this:
 ```js run
 (function() {
 
-  let message = "Hello";
+  var message = "Hello";
 
   alert(message); // Hello
 
 })();
 ```
 
-Here a Function Expression is created and immediately called. So the code executes right away and has its own private variables.
+Here, a Function Expression is created and immediately called. So the code executes right away and has its own private variables.
 
-The Function Expression is wrapped with parenthesis `(function {...})`, because when JavaScript meets `"function"` in the main code flow, it understands it as the start of a Function Declaration. But a Function Declaration must have a name, so this kind of code will give an error:
+The Function Expression is wrapped with parenthesis `(function {...})`, because when JavaScript engine encounters `"function"` in the main code, it understands it as the start of a Function Declaration. But a Function Declaration must have a name, so this kind of code will give an error:
 
 ```js run
-// Try to declare and immediately call a function
-function() { // <-- Error: Unexpected token (
+// Tries to declare and immediately call a function
+function() { // <-- SyntaxError: Function statements require a function name
 
-  let message = "Hello";
+  var message = "Hello";
 
   alert(message); // Hello
 
@@ -243,11 +256,11 @@ There exist other ways besides parentheses to tell JavaScript that we mean a Fun
 ```js run
 // Ways to create IIFE
 
-(function() {
+*!*(*/!*function() {
   alert("Parentheses around the function");
 }*!*)*/!*();
 
-(function() {
+*!*(*/!*function() {
   alert("Parentheses around the whole thing");
 }()*!*)*/!*;
 
@@ -266,7 +279,7 @@ In all the above cases we declare a Function Expression and run it immediately.
 
 There are two main differences of `var` compared to `let/const`:
 
-1. `var` variables have no block scope, they are visible minimum at the function level.
+1. `var` variables have no block scope, their visibility is scoped to current function, or global, if declared outside function.
 2. `var` declarations are processed at function start (script start for globals).
 
 There's one more very minor difference related to the global object, that we'll cover in the next chapter.
diff --git a/1-js/06-advanced-functions/05-global-object/article.md b/1-js/06-advanced-functions/05-global-object/article.md
index 3d195a978..cf4839d94 100644
--- a/1-js/06-advanced-functions/05-global-object/article.md
+++ b/1-js/06-advanced-functions/05-global-object/article.md
@@ -5,7 +5,7 @@ The global object provides variables and functions that are available anywhere.
 
 In a browser it is named `window`, for Node.js it is `global`, for other environments it may have another name.
 
-Recently, `globalThis` was added to the language, as a standardized name for a global object, that should be supported across all environments. In some browsers, namely non-Chromium Edge, `globalThis` is not yet supported, but can be easily polyfilled.
+Recently, `globalThis` was added to the language, as a standardized name for a global object, that should be supported across all environments. It's supported in all major browsers.
 
 We'll use `window` here, assuming that our environment is a browser. If your script may run in other environments, it's better to use `globalThis` instead.
 
@@ -25,7 +25,9 @@ var gVar = 5;
 alert(window.gVar); // 5 (became a property of the global object)
 ```
 
-Please don't rely on that! This behavior exists for compatibility reasons. Modern scripts use [JavaScript modules](info:modules) where such thing doesn't happen.
+Function declarations have the same effect (statements with `function` keyword in the main code flow, not function expressions).
+
+Please don't rely on that! This behavior exists for compatibility reasons. Modern scripts use [JavaScript modules](info:modules) where such a thing doesn't happen.
 
 If we used `let` instead, such thing wouldn't happen:
 
@@ -81,7 +83,7 @@ if (!window.Promise) {
     That includes JavaScript built-ins, such as `Array` and environment-specific values, such as `window.innerHeight` -- the window height in the browser.
 - The global object has a universal name `globalThis`.
 
-    ...But more often is referred by "old-school" environment-specific names, such as `window` (browser) and `global` (Node.js). As `globalThis` is a recent proposal, it's not supported in non-Chromium Edge (but can be polyfilled).
+    ...But more often is referred by "old-school" environment-specific names, such as `window` (browser) and `global` (Node.js).
 - We should store values in the global object only if they're truly global for our project. And keep their number at minimum.
 - In-browser, unless we're using [modules](info:modules), global functions and variables declared with `var` become a property of the global object.
 - To make our code future-proof and easier to understand, we should access properties of the global object directly, as `window.x`.
diff --git a/1-js/06-advanced-functions/06-function-object/5-sum-many-brackets/_js.view/solution.js b/1-js/06-advanced-functions/06-function-object/5-sum-many-brackets/_js.view/solution.js
new file mode 100644
index 000000000..c7d7d734e
--- /dev/null
+++ b/1-js/06-advanced-functions/06-function-object/5-sum-many-brackets/_js.view/solution.js
@@ -0,0 +1,15 @@
+function sum(a) {
+
+  let currentSum = a;
+
+  function f(b) {
+    currentSum += b;
+    return f;
+  }
+
+  f.toString = function() {
+    return currentSum;
+  };
+
+  return f;
+}
diff --git a/1-js/06-advanced-functions/06-function-object/5-sum-many-brackets/_js.view/source.js b/1-js/06-advanced-functions/06-function-object/5-sum-many-brackets/_js.view/source.js
new file mode 100644
index 000000000..f10dca5dc
--- /dev/null
+++ b/1-js/06-advanced-functions/06-function-object/5-sum-many-brackets/_js.view/source.js
@@ -0,0 +1,12 @@
+function sum(a){
+  // Your code goes here.
+
+}
+
+/*
+sum(1)(2) == 3; // 1 + 2
+sum(1)(2)(3) == 6; // 1 + 2 + 3
+sum(5)(-1)(2) == 6
+sum(6)(-1)(-2)(-3) == 0
+sum(0)(1)(2)(3)(4)(5) == 15
+*/
diff --git a/1-js/06-advanced-functions/06-function-object/5-sum-many-brackets/_js.view/test.js b/1-js/06-advanced-functions/06-function-object/5-sum-many-brackets/_js.view/test.js
new file mode 100644
index 000000000..ed567d330
--- /dev/null
+++ b/1-js/06-advanced-functions/06-function-object/5-sum-many-brackets/_js.view/test.js
@@ -0,0 +1,19 @@
+describe("sum", function(){
+  
+  it("sum(1)(2) == 3", function(){
+    assert.equal(3, sum(1)(2));
+  });
+
+  it("sum(5)(-1)(2) == 6", function(){
+    assert.equal(6, sum(5)(-1)(2));
+  });
+  
+  it("sum(6)(-1)(-2)(-3) == 0", function(){
+    assert.equal(0, sum(6)(-1)(-2)(-3));
+  });
+
+  it("sum(0)(1)(2)(3)(4)(5) == 15", function(){
+    assert.equal(15, sum(0)(1)(2)(3)(4)(5));
+  });
+});
+
diff --git a/1-js/06-advanced-functions/06-function-object/5-sum-many-brackets/solution.md b/1-js/06-advanced-functions/06-function-object/5-sum-many-brackets/solution.md
index 5c9326912..e97039f72 100644
--- a/1-js/06-advanced-functions/06-function-object/5-sum-many-brackets/solution.md
+++ b/1-js/06-advanced-functions/06-function-object/5-sum-many-brackets/solution.md
@@ -5,7 +5,7 @@
 
 Now the code:
 
-```js run
+```js demo run
 function sum(a) {
 
   let currentSum = a;
@@ -52,4 +52,4 @@ function f(b) {
 }
 ```
 
-This `f` will be used in the next call, again return itself, so many times as needed. Then, when used as a number or a string -- the `toString` returns the `currentSum`. We could also use `Symbol.toPrimitive` or `valueOf` here for the conversion.
+This `f` will be used in the next call, again return itself, as many times as needed. Then, when used as a number or a string -- the `toString` returns the `currentSum`. We could also use `Symbol.toPrimitive` or `valueOf` here for the conversion.
diff --git a/1-js/06-advanced-functions/06-function-object/article.md b/1-js/06-advanced-functions/06-function-object/article.md
index ed848c0c5..c84f4e52f 100644
--- a/1-js/06-advanced-functions/06-function-object/article.md
+++ b/1-js/06-advanced-functions/06-function-object/article.md
@@ -326,7 +326,7 @@ welcome(); // Hello, Guest (nested call works)
 
 Now it works, because the name `"func"` is function-local. It is not taken from outside (and not visible there). The specification guarantees that it will always reference the current function.
 
-The outer code still has it's variable `sayHi` or `welcome`. And `func` is an "internal function name", how the function can call itself internally.
+The outer code still has its variable `sayHi` or `welcome`. And `func` is an "internal function name", the way for the function to can call itself reliably.
 
 ```smart header="There's no such thing for Function Declaration"
 The "internal name" feature described here is only available for Function Expressions, not for Function Declarations. For Function Declarations, there is no syntax for adding an "internal" name.
@@ -347,7 +347,7 @@ If the function is declared as a Function Expression (not in the main code flow)
 
 Also, functions may carry additional properties. Many well-known JavaScript libraries make great use of this feature.
 
-They create a "main" function and attach many other "helper" functions to it. For instance, the [jQuery](https://jquery.com) library creates a function named `$`. The [lodash](https://lodash.com) library creates a function `_`, and then adds `_.clone`, `_.keyBy` and other properties to it (see the [docs](https://lodash.com/docs) when you want learn more about them). Actually, they do it to lessen their pollution of the global space, so that a single library gives only one global variable. That reduces the possibility of naming conflicts.
+They create a "main" function and attach many other "helper" functions to it. For instance, the [jQuery](https://jquery.com) library creates a function named `$`. The [lodash](https://lodash.com) library creates a function `_`, and then adds `_.clone`, `_.keyBy` and other properties to it (see the [docs](https://lodash.com/docs) when you want to learn more about them). Actually, they do it to lessen their pollution of the global space, so that a single library gives only one global variable. That reduces the possibility of naming conflicts.
 
 
 So, a function can do a useful job by itself and also carry a bunch of other functionality in properties.
diff --git a/1-js/06-advanced-functions/07-new-function/article.md b/1-js/06-advanced-functions/07-new-function/article.md
index 3214ba376..ffe264a4e 100644
--- a/1-js/06-advanced-functions/07-new-function/article.md
+++ b/1-js/06-advanced-functions/07-new-function/article.md
@@ -92,7 +92,7 @@ What if it could access the outer variables?
 
 The problem is that before JavaScript is published to production, it's compressed using a *minifier* -- a special program that shrinks code by removing extra comments, spaces and -- what's important, renames local variables into shorter ones.
 
-For instance, if a function has `let userName`, minifier replaces it `let a` (or another letter if this one is occupied), and does it everywhere. That's usually a safe thing to do, because the variable is local, nothing outside the function can access it. And inside the function, minifier replaces every mention of it. Minifiers are smart, they analyze the code structure, so they don't break anything. They're not just a dumb find-and-replace.
+For instance, if a function has `let userName`, minifier replaces it with `let a` (or another letter if this one is occupied), and does it everywhere. That's usually a safe thing to do, because the variable is local, nothing outside the function can access it. And inside the function, minifier replaces every mention of it. Minifiers are smart, they analyze the code structure, so they don't break anything. They're not just a dumb find-and-replace.
 
 So if `new Function` had access to outer variables, it would be unable to find renamed  `userName`.
 
diff --git a/1-js/06-advanced-functions/08-settimeout-setinterval/article.md b/1-js/06-advanced-functions/08-settimeout-setinterval/article.md
index 95fddea65..f96959988 100644
--- a/1-js/06-advanced-functions/08-settimeout-setinterval/article.md
+++ b/1-js/06-advanced-functions/08-settimeout-setinterval/article.md
@@ -27,7 +27,7 @@ Usually, that's a function. For historical reasons, a string of code can be pass
 : The delay before run, in milliseconds (1000 ms = 1 second), by default 0.
 
 `arg1`, `arg2`...
-: Arguments for the function (not supported in IE9-)
+: Arguments for the function
 
 For instance, this code calls `sayHi()` after one second:
 
@@ -102,7 +102,7 @@ As we can see from `alert` output, in a browser the timer identifier is a number
 
 Again, there is no universal specification for these methods, so that's fine.
 
-For browsers, timers are described in the [timers section](https://www.w3.org/TR/html5/webappapis.html#timers) of HTML5 standard.
+For browsers, timers are described in the [timers section](https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#timers) of HTML Living Standard.
 
 ## setInterval
 
@@ -129,7 +129,7 @@ setTimeout(() => { clearInterval(timerId); alert('stop'); }, 5000);
 ```smart header="Time goes on while `alert` is shown"
 In most browsers, including Chrome and Firefox the internal timer continues "ticking" while showing `alert/confirm/prompt`.
 
-So if you run the code above and don't dismiss the `alert` window for some time, then in the next `alert` will be shown immediately as you do it. The actual interval between alerts will be shorter than 2 seconds.
+So if you run the code above and don't dismiss the `alert` window for some time, then the next `alert` will be shown immediately as you do it. The actual interval between alerts will be shorter than 2 seconds.
 ```
 
 ## Nested setTimeout
@@ -232,7 +232,7 @@ setTimeout(function() {...}, 100);
 
 For `setInterval` the function stays in memory until `clearInterval` is called.
 
-There's a side-effect. A function references the outer lexical environment, so, while it lives, outer variables live too. They may take much more memory than the function itself. So when we don't need the scheduled function anymore, it's better to cancel it, even if it's very small.
+There's a side effect. A function references the outer lexical environment, so, while it lives, outer variables live too. They may take much more memory than the function itself. So when we don't need the scheduled function anymore, it's better to cancel it, even if it's very small.
 ````
 
 ## Zero delay setTimeout
@@ -256,7 +256,7 @@ The first line "puts the call into calendar after 0ms". But the scheduler will o
 There are also advanced browser-related use cases of zero-delay timeout, that we'll discuss in the chapter <info:event-loop>.
 
 ````smart header="Zero delay is in fact not zero (in a browser)"
-In the browser, there's a limitation of how often nested timers can run. The [HTML5 standard](https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#timers) says: "after five nested timers, the interval is forced to be at least 4 milliseconds.".
+In the browser, there's a limitation of how often nested timers can run. The [HTML Living Standard](https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#timers) says: "after five nested timers, the interval is forced to be at least 4 milliseconds.".
 
 Let's demonstrate what it means with the example below. The `setTimeout` call in it re-schedules itself with zero delay. Each call remembers the real time from the previous one in the `times` array. What do the real delays look like? Let's see:
 
@@ -281,7 +281,7 @@ The similar thing happens if we use `setInterval` instead of `setTimeout`: `setI
 
 That limitation comes from ancient times and many scripts rely on it, so it exists for historical reasons.
 
-For server-side JavaScript, that limitation does not exist, and there exist other ways to schedule an immediate asynchronous job, like [setImmediate](https://nodejs.org/api/timers.html) for Node.js. So this note is browser-specific.
+For server-side JavaScript, that limitation does not exist, and there exist other ways to schedule an immediate asynchronous job, like [setImmediate](https://nodejs.org/api/timers.html#timers_setimmediate_callback_args) for Node.js. So this note is browser-specific.
 ````
 
 ## Summary
@@ -290,13 +290,13 @@ For server-side JavaScript, that limitation does not exist, and there exist othe
 - To cancel the execution, we should call `clearTimeout/clearInterval` with the value returned by `setTimeout/setInterval`.
 - Nested `setTimeout` calls are a more flexible alternative to `setInterval`, allowing us to set the time *between* executions more precisely.
 - Zero delay scheduling with `setTimeout(func, 0)` (the same as `setTimeout(func)`) is used to schedule the call "as soon as possible, but after the current script is complete".
-- The browser limits the minimal delay for five or more nested call of `setTimeout` or for `setInterval` (after 5th call) to 4ms. That's for historical reasons.
+- The browser limits the minimal delay for five or more nested calls of `setTimeout` or for `setInterval` (after 5th call) to 4ms. That's for historical reasons.
 
 Please note that all scheduling methods do not *guarantee* the exact delay.
 
 For example, the in-browser timer may slow down for a lot of reasons:
 - The CPU is overloaded.
 - The browser tab is in the background mode.
-- The laptop is on battery.
+- The laptop is on battery saving mode.
 
 All that may increase the minimal timer resolution (the minimal delay) to 300ms or even 1000ms depending on the browser and OS-level performance settings.
diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/_js.view/solution.js b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/_js.view/solution.js
index 065a77d1f..661dd0cf4 100644
--- a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/_js.view/solution.js
+++ b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/_js.view/solution.js
@@ -1,15 +1,7 @@
-function debounce(f, ms) {
-
-  let isCooldown = false;
-
+function debounce(func, ms) {
+  let timeout;
   return function() {
-    if (isCooldown) return;
-
-    f.apply(this, arguments);
-
-    isCooldown = true;
-
-    setTimeout(() => isCooldown = false, ms);
+    clearTimeout(timeout);
+    timeout = setTimeout(() => func.apply(this, arguments), ms);
   };
-
-}
\ No newline at end of file
+}
diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/_js.view/test.js b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/_js.view/test.js
index 8136b873c..750e649f8 100644
--- a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/_js.view/test.js
+++ b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/_js.view/test.js
@@ -1,50 +1,48 @@
-describe("debounce", function() {
-  before(function() {
+describe('debounce', function () {
+  before(function () {
     this.clock = sinon.useFakeTimers();
   });
 
-  after(function() {
+  after(function () {
     this.clock.restore();
   });
 
-  it("trigger the fuction execution immediately", function () {
-    let mode;
-    const f = () => mode='leading';
-    
-    debounce(f, 1000)(); // runs without a delay
-  
-    assert.equal(mode, 'leading');
+  it('for one call - runs it after given ms', function () {
+    const f = sinon.spy();
+    const debounced = debounce(f, 1000);
+
+    debounced('test');
+    assert(f.notCalled, 'not called immediately');
+    this.clock.tick(1000);
+    assert(f.calledOnceWith('test'), 'called after 1000ms');
   });
-  
-  it("calls the function at maximum once in ms milliseconds", function() {
-    let log = '';
 
-    function f(a) {
-      log += a;
-    }
+  it('for 3 calls - runs the last one after given ms', function () {
+    const f = sinon.spy();
+    const debounced = debounce(f, 1000);
 
-    f = debounce(f, 1000);
+    debounced('a');
+    setTimeout(() => debounced('b'), 200); // ignored (too early)
+    setTimeout(() => debounced('c'), 500); // runs (1000 ms passed)
+    this.clock.tick(1000);
 
-    f(1); // runs at once
-    f(2); // ignored
+    assert(f.notCalled, 'not called after 1000ms');
 
-    setTimeout(() => f(3), 100);  // ignored (too early)
-    setTimeout(() => f(4), 1100); // runs (1000 ms passed)
-    setTimeout(() => f(5), 1500); // ignored (less than 1000 ms from the last run)
+    this.clock.tick(500);
 
-    this.clock.tick(5000);
-    assert.equal(log, "14");
+    assert(f.calledOnceWith('c'), 'called after 1500ms');
   });
 
-  it("keeps the context of the call", function() {
+  it('keeps the context of the call', function () {
     let obj = {
       f() {
         assert.equal(this, obj);
-      }
+      },
     };
 
     obj.f = debounce(obj.f, 1000);
-    obj.f("test");
+    obj.f('test');
+    this.clock.tick(5000);
   });
-
+  
 });
diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/debounce.svg b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/debounce.svg
new file mode 100644
index 000000000..e624ce020
--- /dev/null
+++ b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/debounce.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="500" height="183" viewBox="0 0 500 183"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:&apos;PT Mono&apos;;font-weight:700;font-style:normal;src:local(&apos;PT MonoBold&apos;),url(/font/PTMonoBold.woff2) format(&apos;woff2&apos;),url(/font/PTMonoBold.woff) format(&apos;woff&apos;),url(/font/PTMonoBold.ttf) format(&apos;truetype&apos;)}</style></defs><g id="combined" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="debounce.svg"><text id="200ms" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="117" y="142">200ms</tspan></text><text id="1500ms" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="321" y="142">1500ms</tspan></text><text id="1000ms" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="242" y="80">1000ms</tspan></text><path id="Shape" fill="#C06334" stroke="#C06334" stroke-linecap="square" stroke-width="3" d="M343.378 28.32L350.92 12 331 33.024l9.674 2.932L334.797 52 353 31.253l-9.622-2.932zm4.369-11.617l-5.669 12.226 9.206 2.767-13.887 15.989 4.525-12.338-9.206-2.766 15.031-15.878z"/><text id="0" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="93" y="142">0</tspan></text><text id="c" fill="#C06334" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="333" y="72">c</tspan></text><text id="f(a)" fill="#C06334" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="81" y="164">f(a)</tspan></text><text id="f(b)" fill="#C06334" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="121" y="164">f(b)</tspan></text><text id="f(c)" fill="#C06334" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="181" y="164">f(c)</tspan></text><text id="500ms" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="177" y="142">500ms</tspan></text><text id="time" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="427" y="125">time</tspan></text><text id="calls:" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="7" y="164">calls:</tspan></text><path id="Line" fill="#DBAF88" fill-rule="nonzero" d="M432.369 94.388l.871.49 12 6.75 1.55.872-1.55.872-12 6.75-.871.49-.98-1.743.87-.49 8.673-4.879H48v-2h392.932l-8.672-4.878-.872-.49.98-1.744z"/><text id="after-1000ms" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="358" y="36"> after 1000ms</tspan></text><path id="Line-Copy" stroke="#DBAF88" stroke-linecap="square" stroke-width="2" d="M137.5 125V80M97.5 125V80M197.5 125V80"/><path id="Line-2" stroke="#C06334" stroke-linecap="square" stroke-width="3" d="M337.5 125V80"/><path id="Line-25" fill="#DBAF88" fill-rule="nonzero" d="M212.631 77.888l.98 1.743-.87.49L204.066 85H206v2h-1.933l8.673 4.878.872.49-.98 1.744-.872-.49-12-6.75-1.55-.872 1.55-.872 12-6.75.871-.49zm108.738 0l.871.49 12 6.75 1.55.872-1.55.872-12 6.75-.871.49-.98-1.743.87-.49L329.933 87H329v-2h.932l-8.672-4.878-.872-.49.98-1.744zM214 85v2h-5v-2h5zm8 0v2h-5v-2h5zm8 0v2h-5v-2h5zm8 0v2h-5v-2h5zm8 0v2h-5v-2h5zm8 0v2h-5v-2h5zm8 0v2h-5v-2h5zm8 0v2h-5v-2h5zm8 0v2h-5v-2h5zm8 0v2h-5v-2h5zm8 0v2h-5v-2h5zm8 0v2h-5v-2h5zm8 0v2h-5v-2h5zm8 0v2h-5v-2h5zm8 0v2h-5v-2h5z"/></g></g></svg>
\ No newline at end of file
diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/debounce.view/index.html b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/debounce.view/index.html
new file mode 100644
index 000000000..e3b4d5842
--- /dev/null
+++ b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/debounce.view/index.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
+
+Function <code>handler</code> is called on this input:
+<br>
+<input id="input1" placeholder="type here">
+
+<p>
+
+Debounced function <code>debounce(handler, 1000)</code> is called on this input:
+<br>
+<input id="input2" placeholder="type here">
+
+<p>
+<button id="result">The <code>handler</code> puts the result here</button>
+
+<script>
+  function handler(event) {
+    result.innerHTML = event.target.value;
+  }
+
+  input1.oninput = handler;
+  input2.oninput = _.debounce(handler, 1000);
+</script>
\ No newline at end of file
diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/solution.md b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/solution.md
index 4f5867ded..83e75f315 100644
--- a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/solution.md
+++ b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/solution.md
@@ -1,28 +1,13 @@
 ```js demo
-function debounce(f, ms) {
-
-  let isCooldown = false;
-
+function debounce(func, ms) {
+  let timeout;
   return function() {
-    if (isCooldown) return;
-
-    f.apply(this, arguments);
-
-    isCooldown = true;
-
-    setTimeout(() => isCooldown = false, ms);
+    clearTimeout(timeout);
+    timeout = setTimeout(() => func.apply(this, arguments), ms);
   };
-
 }
-```
-
-A call to `debounce` returns a wrapper. There may be two states:
 
-- `isCooldown = false` -- ready to run.
-- `isCooldown = true` -- waiting for the timeout.
-
-In the first call `isCooldown` is falsy, so the call proceeds, and the state changes to `true`.
+```
 
-While `isCooldown` is true, all other calls are ignored.
+A call to `debounce` returns a wrapper. When called, it schedules the original function call after given `ms` and cancels the previous such timeout.
 
-Then `setTimeout` reverts it to `false` after the given delay.
diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md
index 2620f1c71..5b0fcc5f8 100644
--- a/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md
+++ b/1-js/06-advanced-functions/09-call-apply-decorators/03-debounce/task.md
@@ -4,21 +4,48 @@ importance: 5
 
 # Debounce decorator
 
-The result of `debounce(f, ms)` decorator should be a wrapper that passes the call to `f` at maximum once per `ms` milliseconds.
+The result of `debounce(f, ms)` decorator is a wrapper that suspends calls to `f` until there's `ms` milliseconds of inactivity (no calls, "cooldown period"), then invokes `f` once with the latest arguments.
 
-In other words, when we call a "debounced" function, it guarantees that all future calls to the function made less than `ms` milliseconds after the previous call will be ignored.
+In other words, `debounce` is like a secretary that accepts "phone calls", and waits until there's `ms` milliseconds of being quiet. And only then it transfers the latest call information to "the boss" (calls the actual `f`).
 
-For instance:
+For instance, we had a function `f` and replaced it with `f = debounce(f, 1000)`.
 
-```js no-beautify
-let f = debounce(alert, 1000);
+Then if the wrapped function is called at 0ms, 200ms and 500ms, and then there are no calls, then the actual `f` will be only called once, at 1500ms. That is: after the cooldown period of 1000ms from the last call.
 
-f(1); // runs immediately
-f(2); // ignored
+![](debounce.svg)
 
-setTimeout( () => f(3), 100); // ignored ( only 100 ms passed )
-setTimeout( () => f(4), 1100); // runs
-setTimeout( () => f(5), 1500); // ignored (less than 1000 ms from the last run)
+...And it will get the arguments of the very last call, other calls are ignored.
+
+Here's the code for it (uses the debounce decorator from the [Lodash library](https://lodash.com/docs/4.17.15#debounce)):
+
+```js
+let f = _.debounce(alert, 1000);
+
+f("a");
+setTimeout( () => f("b"), 200);
+setTimeout( () => f("c"), 500);
+// debounced function waits 1000ms after the last call and then runs: alert("c")
+```
+
+Now a practical example. Let's say, the user types something, and we'd like to send a request to the server when the input is finished.
+
+There's no point in sending the request for every character typed. Instead we'd like to wait, and then process the whole result.
+
+In a web-browser, we can setup an event handler -- a function that's called on every change of an input field. Normally, an event handler is called very often, for every typed key. But if we `debounce` it by 1000ms, then it will be only called once, after 1000ms after the last input.
+
+```online
+
+In this live example, the handler puts the result into a box below, try it:
+
+[iframe border=1 src="debounce" height=200]
+
+See? The second input calls the debounced function, so its content is processed after 1000ms from the last input.
 ```
 
-In practice `debounce` is useful for functions that retrieve/update something when we know that nothing new can be done in such a short period of time, so it's better not to waste resources.
+So, `debounce` is a great way to process a sequence of events: be it a sequence of key presses, mouse movements or something else.
+
+It waits the given time after the last call, and then runs its function, that can process the result.
+
+The task is to implement `debounce` decorator.
+
+Hint: that's just a few lines if you think about it :)
diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/_js.view/test.js b/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/_js.view/test.js
index d2cf8e151..e671438f6 100644
--- a/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/_js.view/test.js
+++ b/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/_js.view/test.js
@@ -7,8 +7,8 @@ describe("throttle(f, 1000)", function() {
   }
 
   before(function() {
-    f1000 = throttle(f, 1000);
     this.clock = sinon.useFakeTimers();
+    f1000 = throttle(f, 1000);
   });
 
   it("the first call runs now", function() {
diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/solution.md b/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/solution.md
index cf851f771..6950664be 100644
--- a/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/solution.md
+++ b/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/solution.md
@@ -12,11 +12,10 @@ function throttle(func, ms) {
       savedThis = this;
       return;
     }
+    isThrottled = true;
 
     func.apply(this, arguments); // (1)
 
-    isThrottled = true;
-
     setTimeout(function() {
       isThrottled = false; // (3)
       if (savedArgs) {
diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md b/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md
index 9e08874af..cbd473196 100644
--- a/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md
+++ b/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md
@@ -4,16 +4,21 @@ importance: 5
 
 # Throttle decorator
 
-Create a "throttling" decorator `throttle(f, ms)` -- that returns a wrapper, passing the call to `f` at maximum once per `ms` milliseconds. Those calls that fall into the "cooldown" period, are ignored.
+Create a "throttling" decorator `throttle(f, ms)` -- that returns a wrapper.
 
-**The difference with `debounce` -- if an ignored call is the last during the cooldown, then it executes at the end of the delay.**
+When it's called multiple times, it passes the call to `f` at maximum once per `ms` milliseconds.
+
+Compared to the debounce decorator, the behavior is completely different:
+- `debounce` runs the function once after the "cooldown" period. Good for processing the final result.
+- `throttle` runs it not more often than given `ms` time. Good for regular updates that shouldn't be very often.
+
+In other words, `throttle` is like a secretary that accepts phone calls, but bothers the boss (calls the actual `f`) not more often than once per `ms` milliseconds.
 
 Let's check the real-life application to better understand that requirement and to see where it comes from.
 
 **For instance, we want to track mouse movements.**
 
 In a browser we can setup a function to run at every mouse movement and get the pointer location as it moves. During an active mouse usage, this function usually runs very frequently, can be something like 100 times per second (every 10 ms).
-
 **We'd like to update some information on the web-page when the pointer moves.**
 
 ...But updating function `update()` is too heavy to do it on every micro-movement. There is also no sense in updating more often than once per 100ms.
diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/article.md b/1-js/06-advanced-functions/09-call-apply-decorators/article.md
index f9bc89169..c5d785493 100644
--- a/1-js/06-advanced-functions/09-call-apply-decorators/article.md
+++ b/1-js/06-advanced-functions/09-call-apply-decorators/article.md
@@ -36,11 +36,11 @@ function cachingDecorator(func) {
 
 slow = cachingDecorator(slow);
 
-alert( slow(1) ); // slow(1) is cached
-alert( "Again: " + slow(1) ); // the same
+alert( slow(1) ); // slow(1) is cached and the result returned
+alert( "Again: " + slow(1) ); // slow(1) result returned from cache
 
-alert( slow(2) ); // slow(2) is cached
-alert( "Again: " + slow(2) ); // the same as the previous line
+alert( slow(2) ); // slow(2) is cached and the result returned
+alert( "Again: " + slow(2) ); // slow(2) result returned from cache
 ```
 
 In the code above `cachingDecorator` is a *decorator*: a special function that takes another function and alters its behavior.
@@ -209,7 +209,7 @@ To make it all clear, let's see more deeply how `this` is passed along:
 2. So when `worker.slow(2)` is executed, the wrapper gets `2` as an argument and `this=worker` (it's the object before dot).
 3. Inside the wrapper, assuming the result is not yet cached, `func.call(this, x)` passes the current `this` (`=worker`) and the current argument (`=2`) to the original method.
 
-## Going multi-argument with "func.apply"
+## Going multi-argument
 
 Now let's make `cachingDecorator` even more universal. Till now it was working only with single-argument functions.
 
@@ -236,7 +236,7 @@ There are many solutions possible:
 
 For many practical applications, the 3rd variant is good enough, so we'll stick to it.
 
-Also we need to replace `func.call(this, x)` with `func.call(this, ...arguments)`, to pass all arguments to the wrapped function call, not just the first one.
+Also we need to pass not just `x`, but all arguments in `func.call`. Let's recall that in a `function()` we can get a pseudo-array of its arguments as `arguments`, so `func.call(this, x)` should be replaced with `func.call(this, ...arguments)`.
 
 Here's a more powerful `cachingDecorator`:
 
@@ -284,6 +284,8 @@ There are two changes:
 - In the line `(*)` it calls `hash` to create a single key from `arguments`. Here we use a simple "joining" function that turns arguments `(3, 5)` into the key `"3,5"`. More complex cases may require other hashing functions.
 - Then `(**)` uses `func.call(this, ...arguments)` to pass both the context and all arguments the wrapper got (not just the first one) to the original function.
 
+## func.apply
+
 Instead of `func.call(this, ...arguments)` we could use `func.apply(this, arguments)`.
 
 The syntax of built-in method [func.apply](mdn:js/Function/apply) is:
@@ -299,18 +301,18 @@ The only syntax difference between `call` and `apply` is that `call` expects a l
 So these two calls are almost equivalent:
 
 ```js
-func.call(context, ...args); // pass an array as list with spread syntax
-func.apply(context, args);   // is same as using apply
+func.call(context, ...args);
+func.apply(context, args);
 ```
 
-There's only a minor difference:
+They perform the same call of `func` with given context and arguments.
+
+There's only a subtle difference regarding `args`:
 
 - The spread syntax `...` allows to pass *iterable* `args` as the list to `call`.
 - The `apply` accepts only *array-like* `args`.
 
-So, these calls complement each other. Where we expect an iterable, `call` works, where we expect an array-like, `apply` works.
-
-And for objects that are both iterable and array-like, like a real array, we technically could use any of them, but `apply` will probably be faster, because most JavaScript engines internally optimize it better.
+...And for objects that are both iterable and array-like, such as a real array, we can use any of them, but `apply` will probably be faster, because most JavaScript engines internally optimize it better.
 
 Passing all arguments along with the context to another function is called *call forwarding*.
 
@@ -344,7 +346,7 @@ function hash(args) {
 }
 ```
 
-...Unfortunately, that won't work. Because we are calling `hash(arguments)` and `arguments` object is both iterable and array-like, but not a real array.
+...Unfortunately, that won't work. Because we are calling `hash(arguments)`, and `arguments` object is both iterable and array-like, but not a real array.
 
 So calling `join` on it would fail, as we can see below:
 
diff --git a/1-js/06-advanced-functions/10-bind/5-question-use-bind/solution.md b/1-js/06-advanced-functions/10-bind/5-question-use-bind/solution.md
index 403107ca6..4a381c0b4 100644
--- a/1-js/06-advanced-functions/10-bind/5-question-use-bind/solution.md
+++ b/1-js/06-advanced-functions/10-bind/5-question-use-bind/solution.md
@@ -1,5 +1,5 @@
 
-The error occurs because `ask` gets functions `loginOk/loginFail` without the object.
+The error occurs because `askPassword` gets functions `loginOk/loginFail` without the object.
 
 When it calls them, they naturally assume `this=undefined`.
 
diff --git a/1-js/06-advanced-functions/10-bind/article.md b/1-js/06-advanced-functions/10-bind/article.md
index 787c7d68e..6d65e7dd1 100644
--- a/1-js/06-advanced-functions/10-bind/article.md
+++ b/1-js/06-advanced-functions/10-bind/article.md
@@ -167,7 +167,7 @@ sayHi(); // Hello, John!
 setTimeout(sayHi, 1000); // Hello, John!
 
 // even if the value of user changes within 1 second
-// sayHi uses the pre-bound value
+// sayHi uses the pre-bound value which is reference to the old user object
 user = {
   sayHi() { alert("Another user in setTimeout!"); }
 };
@@ -187,8 +187,8 @@ let user = {
 
 let say = user.say.bind(user);
 
-say("Hello"); // Hello, John ("Hello" argument is passed to say)
-say("Bye"); // Bye, John ("Bye" is passed to say)
+say("Hello"); // Hello, John! ("Hello" argument is passed to say)
+say("Bye"); // Bye, John! ("Bye" is passed to say)
 ```
 
 ````smart header="Convenience method: `bindAll`"
@@ -202,7 +202,7 @@ for (let key in user) {
 }
 ```
 
-JavaScript libraries also provide functions for convenient mass binding , e.g. [_.bindAll(obj)](http://lodash.com/docs#bindAll) in lodash.
+JavaScript libraries also provide functions for convenient mass binding , e.g. [_.bindAll(object, methodNames)](https://lodash.com/docs#bindAll) in lodash.
 ````
 
 ## Partial functions
@@ -247,7 +247,7 @@ The call to `mul.bind(null, 2)` creates a new function `double` that passes call
 
 That's called [partial function application](https://en.wikipedia.org/wiki/Partial_application) -- we create a new function by fixing some parameters of the existing one.
 
-Please note that here we actually don't use `this` here. But `bind` requires it, so we must put in something like `null`.
+Please note that we actually don't use `this` here. But `bind` requires it, so we must put in something like `null`.
 
 The function `triple` in the code below triples the value:
 
diff --git a/1-js/06-advanced-functions/12-arrow-functions/article.md b/1-js/06-advanced-functions/12-arrow-functions/article.md
index f5caeaece..8730277ad 100644
--- a/1-js/06-advanced-functions/12-arrow-functions/article.md
+++ b/1-js/06-advanced-functions/12-arrow-functions/article.md
@@ -52,7 +52,7 @@ let group = {
 *!*
     this.students.forEach(function(student) {
       // Error: Cannot read property 'title' of undefined
-      alert(this.title + ': ' + student)
+      alert(this.title + ': ' + student);
     });
 */!*
   }
@@ -87,7 +87,7 @@ For instance, `defer(f, ms)` gets a function and returns a wrapper around it tha
 ```js run
 function defer(f, ms) {
   return function() {
-    setTimeout(() => f.apply(this, arguments), ms)
+    setTimeout(() => f.apply(this, arguments), ms);
   };
 }
 
diff --git a/1-js/07-object-properties/01-property-descriptors/article.md b/1-js/07-object-properties/01-property-descriptors/article.md
index 3593bffae..0a945b377 100644
--- a/1-js/07-object-properties/01-property-descriptors/article.md
+++ b/1-js/07-object-properties/01-property-descriptors/article.md
@@ -19,7 +19,7 @@ We didn't see them yet, because generally they do not show up. When we create a
 
 First, let's see how to get those flags.
 
-The method [Object.getOwnPropertyDescriptor](mdn:js/Object/getOwnPropertyDescriptor) allows to query the *full* information about a property.
+The method [Object.getOwnPropertyDescriptor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor) allows to query the *full* information about a property.
 
 The syntax is:
 ```js
@@ -54,7 +54,7 @@ alert( JSON.stringify(descriptor, null, 2 ) );
 */
 ```
 
-To change the flags, we can use [Object.defineProperty](mdn:js/Object/defineProperty).
+To change the flags, we can use [Object.defineProperty](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty).
 
 The syntax is:
 
@@ -123,7 +123,7 @@ user.name = "Pete"; // Error: Cannot assign to read only property 'name'
 Now no one can change the name of our user, unless they apply their own `defineProperty` to override ours.
 
 ```smart header="Errors appear only in strict mode"
-In the non-strict mode, no errors occur when writing to non-writable properties and such. But the operation still won't succeed. Flag-violating actions are just silently ignored in non-strict.
+In non-strict mode, no errors occur when writing to non-writable properties and such. But the operation still won't succeed. Flag-violating actions are just silently ignored in non-strict.
 ```
 
 Here's the same example, but the property is created from scratch:
@@ -194,7 +194,7 @@ alert(Object.keys(user)); // name
 
 The non-configurable flag (`configurable:false`) is sometimes preset for built-in objects and properties.
 
-A non-configurable property can not be deleted.
+A non-configurable property can't be deleted, its attributes can't be modified.
 
 For instance, `Math.PI` is non-writable, non-enumerable and non-configurable:
 
@@ -214,49 +214,67 @@ alert( JSON.stringify(descriptor, null, 2 ) );
 So, a programmer is unable to change the value of `Math.PI` or overwrite it.
 
 ```js run
-Math.PI = 3; // Error
+Math.PI = 3; // Error, because it has writable: false
 
 // delete Math.PI won't work either
 ```
 
+We also can't change `Math.PI` to be `writable` again:
+
+```js run
+// Error, because of configurable: false
+Object.defineProperty(Math, "PI", { writable: true });
+```
+
+There's absolutely nothing we can do with `Math.PI`.
+
 Making a property non-configurable is a one-way road. We cannot change it back with `defineProperty`.
 
-To be precise, non-configurability imposes several restrictions on `defineProperty`:
-1. Can't change `configurable` flag.
-2. Can't change `enumerable` flag.
-3. Can't change `writable: false` to `true` (the other way round works).
-4. Can't change `get/set` for an accessor property (but can assign them if absent).
+**Please note: `configurable: false` prevents changes of property flags and its deletion, while allowing to change its value.**
 
-Here we are making `user.name` a "forever sealed" constant:
+Here `user.name` is non-configurable, but we can still change it (as it's writable):
 
 ```js run
-let user = { };
+let user = {
+  name: "John"
+};
+
+Object.defineProperty(user, "name", {
+  configurable: false
+});
+
+user.name = "Pete"; // works fine
+delete user.name; // Error
+```
+
+And here we make `user.name` a "forever sealed" constant, just like the built-in `Math.PI`:
+
+```js run
+let user = {
+  name: "John"
+};
 
 Object.defineProperty(user, "name", {
-  value: "John",
   writable: false,
   configurable: false
 });
 
-*!*
 // won't be able to change user.name or its flags
 // all this won't work:
-//   user.name = "Pete"
-//   delete user.name
-//   defineProperty(user, "name", { value: "Pete" })
-Object.defineProperty(user, "name", {writable: true}); // Error
-*/!*
+user.name = "Pete";
+delete user.name;
+Object.defineProperty(user, "name", { value: "Pete" });
 ```
 
-```smart header="\"Non-configurable\" doesn't mean \"non-writable\""
-Notable exception: a value of non-configurable, but writable property can be changed.
+```smart header="The only attribute change possible: writable true -> false"
+There's a minor exception about changing flags.
 
-The idea of `configurable: false` is to prevent changes to property flags and its deletion, not changes to its value.
+We can change `writable: true` to `false` for a non-configurable property, thus preventing its value modification (to add another layer of protection). Not the other way around though.
 ```
 
 ## Object.defineProperties
 
-There's a method [Object.defineProperties(obj, descriptors)](mdn:js/Object/defineProperties) that allows to define many properties at once.
+There's a method [Object.defineProperties(obj, descriptors)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperties) that allows to define many properties at once.
 
 The syntax is:
 
@@ -282,7 +300,7 @@ So, we can set many properties at once.
 
 ## Object.getOwnPropertyDescriptors
 
-To get all property descriptors at once, we can use the method [Object.getOwnPropertyDescriptors(obj)](mdn:js/Object/getOwnPropertyDescriptors).
+To get all property descriptors at once, we can use the method [Object.getOwnPropertyDescriptors(obj)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptors).
 
 Together with `Object.defineProperties` it can be used as a "flags-aware" way of cloning an object:
 
@@ -300,7 +318,7 @@ for (let key in user) {
 
 ...But that does not copy flags. So if we want a "better" clone then `Object.defineProperties` is preferred.
 
-Another difference is that `for..in` ignores symbolic properties, but `Object.getOwnPropertyDescriptors` returns *all* property descriptors including symbolic ones.
+Another difference is that `for..in` ignores symbolic and non-enumerable properties, but `Object.getOwnPropertyDescriptors` returns *all* property descriptors including symbolic and non-enumerable ones.
 
 ## Sealing an object globally
 
@@ -308,24 +326,24 @@ Property descriptors work at the level of individual properties.
 
 There are also methods that limit access to the *whole* object:
 
-[Object.preventExtensions(obj)](mdn:js/Object/preventExtensions)
+[Object.preventExtensions(obj)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/preventExtensions)
 : Forbids the addition of new properties to the object.
 
-[Object.seal(obj)](mdn:js/Object/seal)
+[Object.seal(obj)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/seal)
 : Forbids adding/removing of properties. Sets `configurable: false` for all existing properties.
 
-[Object.freeze(obj)](mdn:js/Object/freeze)
+[Object.freeze(obj)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze)
 : Forbids adding/removing/changing of properties. Sets `configurable: false, writable: false` for all existing properties.
 
 And also there are tests for them:
 
-[Object.isExtensible(obj)](mdn:js/Object/isExtensible)
+[Object.isExtensible(obj)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible)
 : Returns `false` if adding properties is forbidden, otherwise `true`.
 
-[Object.isSealed(obj)](mdn:js/Object/isSealed)
+[Object.isSealed(obj)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed)
 : Returns `true` if adding/removing properties is forbidden, and all existing properties have `configurable: false`.
 
-[Object.isFrozen(obj)](mdn:js/Object/isFrozen)
+[Object.isFrozen(obj)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen)
 : Returns `true` if adding/removing/changing properties is forbidden, and all current properties are `configurable: false, writable: false`.
 
 These methods are rarely used in practice.
diff --git a/1-js/07-object-properties/02-property-accessors/article.md b/1-js/07-object-properties/02-property-accessors/article.md
index 52c152811..c2aa35d53 100644
--- a/1-js/07-object-properties/02-property-accessors/article.md
+++ b/1-js/07-object-properties/02-property-accessors/article.md
@@ -1,11 +1,11 @@
 
 # Property getters and setters
 
-There are two kinds of properties.
+There are two kinds of object properties.
 
 The first kind is *data properties*. We already know how to work with them. All properties that we've been using until now were data properties.
 
-The second type of properties is something new. It's *accessor properties*. They are essentially functions that work on getting and setting a value, but look like regular properties to an external code.
+The second type of property is something new. It's an *accessor property*. They are essentially functions that execute on getting and setting a value, but look like regular properties to an external code.
 
 ## Getters and setters
 
@@ -53,7 +53,7 @@ alert(user.fullName); // John Smith
 */!*
 ```
 
-From outside, an accessor property looks like a regular one. That's the idea of accessor properties. We don't *call* `user.fullName` as a function, we *read* it normally: the getter runs behind the scenes.
+From the outside, an accessor property looks like a regular one. That's the idea of accessor properties. We don't *call* `user.fullName` as a function, we *read* it normally: the getter runs behind the scenes.
 
 As of now, `fullName` has only a getter. If we attempt to assign `user.fullName=`, there will be an error:
 
@@ -134,7 +134,7 @@ alert(user.fullName); // John Smith
 for(let key in user) alert(key); // name, surname
 ```
 
-Please note once again that a property can be either an accessor (has `get/set` methods) or a data property (has a `value`), not both.
+Please note that a property can be either an accessor (has `get/set` methods) or a data property (has a `value`), not both.
 
 If we try to supply both `get` and `value` in the same descriptor, there will be an error:
 
diff --git a/1-js/08-prototypes/01-prototype-inheritance/article.md b/1-js/08-prototypes/01-prototype-inheritance/article.md
index 69e7c5f5c..ef6c7ffeb 100644
--- a/1-js/08-prototypes/01-prototype-inheritance/article.md
+++ b/1-js/08-prototypes/01-prototype-inheritance/article.md
@@ -12,11 +12,11 @@ In JavaScript, objects have a special hidden property `[[Prototype]]` (as named
 
 ![prototype](object-prototype-empty.svg)
 
-The prototype is a little bit "magical". When we want to read a property from `object`, and it's missing, JavaScript automatically takes it from the prototype. In programming, such thing is called "prototypal inheritance". Many cool language features and programming techniques are based on it.
+When we read a property from `object`, and it's missing, JavaScript automatically takes it from the prototype. In programming, this is called "prototypal inheritance". And soon we'll study many examples of such inheritance, as well as cooler language features built upon it.
 
 The property `[[Prototype]]` is internal and hidden, but there are many ways to set it.
 
-One of them is to use `__proto__`, like this:
+One of them is to use the special name `__proto__`, like this:
 
 ```js run
 let animal = {
@@ -27,19 +27,11 @@ let rabbit = {
 };
 
 *!*
-rabbit.__proto__ = animal;
+rabbit.__proto__ = animal; // sets rabbit.[[Prototype]] = animal
 */!*
 ```
 
-```smart header="`__proto__` is a historical getter/setter for `[[Prototype]]`"
-Please note that `__proto__` is *not the same* as `[[Prototype]]`. That's a getter/setter for it.
-
-It exists for historical reasons. In modern language it is replaced with functions `Object.getPrototypeOf/Object.setPrototypeOf` that also get/set the prototype. We'll study the reasons for that and these functions later.
-
-By the specification, `__proto__` must only be supported by browsers, but in fact all environments including server-side support it. For now, as `__proto__` notation is a little bit more intuitively obvious, we'll use it in the examples.
-```
-
-If we look for a property in `rabbit`, and it's missing, JavaScript automatically takes it from `animal`.
+Now if we read a property from `rabbit`, and it's missing, JavaScript will automatically take it from `animal`.
 
 For instance:
 
@@ -62,7 +54,7 @@ alert( rabbit.eats ); // true (**)
 alert( rabbit.jumps ); // true
 ```
 
-Here the line `(*)` sets `animal` to be a prototype of `rabbit`.
+Here the line `(*)` sets `animal` to be the prototype of `rabbit`.
 
 Then, when `alert` tries to read property `rabbit.eats` `(**)`, it's not in `rabbit`, so JavaScript follows the `[[Prototype]]` reference and finds it in `animal` (look from the bottom up):
 
@@ -130,6 +122,8 @@ alert(longEar.jumps); // true (from rabbit)
 
 ![](proto-animal-rabbit-chain.svg)
 
+Now if we read something from `longEar`, and it's missing, JavaScript will look for it in `rabbit`, and then in `animal`.
+
 There are only two limitations:
 
 1. The references can't go in circles. JavaScript will throw an error if we try to assign `__proto__` in a circle.
@@ -137,6 +131,18 @@ There are only two limitations:
 
 Also it may be obvious, but still: there can be only one `[[Prototype]]`. An object may not inherit from two others.
 
+```smart header="`__proto__` is a historical getter/setter for `[[Prototype]]`"
+It's a common mistake of novice developers not to know the difference between these two.
+
+Please note that `__proto__` is *not the same* as the internal `[[Prototype]]` property. It's a getter/setter for `[[Prototype]]`. Later we'll see situations where it matters, for now let's just keep it in mind, as we build our understanding of JavaScript language.
+
+The `__proto__` property is a bit outdated. It exists for historical reasons, modern JavaScript suggests that we should use `Object.getPrototypeOf/Object.setPrototypeOf` functions instead that get/set the prototype. We'll also cover these functions later.
+
+By the specification, `__proto__` must only be supported by browsers. In fact though, all environments including server-side support `__proto__`, so we're quite safe using it.
+
+As the `__proto__` notation is a bit more intuitively obvious, we use it in the examples.
+```
+
 ## Writing doesn't use prototype
 
 The prototype is only used for reading properties.
@@ -197,6 +203,9 @@ alert(admin.fullName); // John Smith (*)
 
 // setter triggers!
 admin.fullName = "Alice Cooper"; // (**)
+
+alert(admin.fullName); // Alice Cooper, state of admin modified
+alert(user.fullName); // John Smith, state of user protected
 ```
 
 Here in the line `(*)` the property `admin.fullName` has a getter in the prototype `user`, so it is called. And in the line `(**)` the property has a setter in the prototype, so it is called.
@@ -277,7 +286,7 @@ for(let prop in rabbit) alert(prop); // jumps, then eats
 */!*
 ```
 
-If that's not what we want, and we'd like to exclude inherited properties, there's a built-in method [obj.hasOwnProperty(key)](mdn:js/Object/hasOwnProperty): it returns `true` if `obj` has its own (not inherited) property named `key`.
+If that's not what we want, and we'd like to exclude inherited properties, there's a built-in method [obj.hasOwnProperty(key)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty): it returns `true` if `obj` has its own (not inherited) property named `key`.
 
 So we can filter out inherited properties (or do something else with them):
 
diff --git a/1-js/08-prototypes/02-function-prototype/4-new-object-same-constructor/solution.md b/1-js/08-prototypes/02-function-prototype/4-new-object-same-constructor/solution.md
index 0073e252e..372d50dd6 100644
--- a/1-js/08-prototypes/02-function-prototype/4-new-object-same-constructor/solution.md
+++ b/1-js/08-prototypes/02-function-prototype/4-new-object-same-constructor/solution.md
@@ -38,7 +38,12 @@ Why `user2.name` is `undefined`?
 Here's how `new user.constructor('Pete')` works:
 
 1. First, it looks for `constructor` in `user`. Nothing.
-2. Then it follows the prototype chain. The prototype of `user` is `User.prototype`, and it also has nothing.
-3. The value of `User.prototype` is a plain object `{}`, its prototype is `Object.prototype`. And there is `Object.prototype.constructor == Object`. So it is used.
+2. Then it follows the prototype chain. The prototype of `user` is `User.prototype`, and it also has no `constructor` (because we "forgot" to set it right!).
+3. Going further up the chain, `User.prototype` is a plain object, its prototype is the built-in `Object.prototype`. 
+4. Finally, for the built-in `Object.prototype`, there's a built-in `Object.prototype.constructor == Object`. So it is used.
 
-At the end, we have `let user2 = new Object('Pete')`. The built-in `Object` constructor ignores arguments, it always creates an empty object, similar to `let user2 = {}`, that's what we have in `user2` after all.
+Finally, at the end, we have `let user2 = new Object('Pete')`. 
+
+Probably, that's not what we want. We'd like to create `new User`, not `new Object`. That's the outcome of the missing `constructor`.
+
+(Just in case you're curious, the `new Object(...)` call converts its argument to an object. That's a theoretical thing, in practice no one calls `new Object` with a value, and generally we don't use `new Object` to make objects at all).
\ No newline at end of file
diff --git a/1-js/08-prototypes/02-function-prototype/article.md b/1-js/08-prototypes/02-function-prototype/article.md
index c106d1d90..b1ef51826 100644
--- a/1-js/08-prototypes/02-function-prototype/article.md
+++ b/1-js/08-prototypes/02-function-prototype/article.md
@@ -41,7 +41,7 @@ That's the resulting picture:
 On the picture, `"prototype"` is a horizontal arrow, meaning a regular property, and `[[Prototype]]` is vertical, meaning the inheritance of `rabbit` from `animal`.
 
 ```smart header="`F.prototype` only used at `new F` time"
-`F.prototype` property is only used when `new F` is called, it assigns `[[Prototype]]` of the new object. After that, there's no connection between `F.prototype` and the new object. Think of it as a "one-time gift".
+`F.prototype` property is only used when `new F` is called, it assigns `[[Prototype]]` of the new object.
 
 If, after the creation, `F.prototype` property changes (`F.prototype = <another object>`), then new objects created by `new F` will have another object as `[[Prototype]]`, but already existing objects keep the old one.
 ```
diff --git a/1-js/08-prototypes/03-native-prototypes/article.md b/1-js/08-prototypes/03-native-prototypes/article.md
index 378936c9a..bdfc86dd8 100644
--- a/1-js/08-prototypes/03-native-prototypes/article.md
+++ b/1-js/08-prototypes/03-native-prototypes/article.md
@@ -2,7 +2,7 @@
 
 The `"prototype"` property is widely used by the core of JavaScript itself. All built-in constructor functions use it.
 
-First we'll see at the details, and then how to use it for adding new capabilities to built-in objects.
+First we'll look at the details, and then how to use it for adding new capabilities to built-in objects.
 
 ## Object.prototype
 
@@ -33,7 +33,9 @@ We can check it like this:
 let obj = {};
 
 alert(obj.__proto__ === Object.prototype); // true
-// obj.toString === obj.__proto__.toString == Object.prototype.toString
+
+alert(obj.toString === obj.__proto__.toString); //true
+alert(obj.toString === Object.prototype.toString); //true
 ```
 
 Please note that there is no more `[[Prototype]]` in the chain above `Object.prototype`:
diff --git a/1-js/08-prototypes/04-prototype-methods/2-dictionary-tostring/solution.md b/1-js/08-prototypes/04-prototype-methods/2-dictionary-tostring/solution.md
index a92e17900..f3c9cf0e5 100644
--- a/1-js/08-prototypes/04-prototype-methods/2-dictionary-tostring/solution.md
+++ b/1-js/08-prototypes/04-prototype-methods/2-dictionary-tostring/solution.md
@@ -28,4 +28,4 @@ alert(dictionary); // "apple,__proto__"
 
 When we create a property using a descriptor, its flags are `false` by default. So in the code above, `dictionary.toString` is non-enumerable.
 
-See the the chapter [](info:property-descriptors) for review.
+See the chapter [](info:property-descriptors) for review.
diff --git a/1-js/08-prototypes/04-prototype-methods/article.md b/1-js/08-prototypes/04-prototype-methods/article.md
index 80f5a956a..34b977e9f 100644
--- a/1-js/08-prototypes/04-prototype-methods/article.md
+++ b/1-js/08-prototypes/04-prototype-methods/article.md
@@ -3,15 +3,18 @@
 
 In the first chapter of this section, we mentioned that there are modern methods to setup a prototype.
 
-The `__proto__` is considered outdated and somewhat deprecated (in browser-only part of the JavaScript standard).
+Setting or reading the prototype with `obj.__proto__` is considered outdated and somewhat deprecated (moved to the so-called "Annex B" of the JavaScript standard, meant for browsers only).
 
-The modern methods are:
+The modern methods to get/set a prototype are:
 
-- [Object.create(proto[, descriptors])](mdn:js/Object/create) -- creates an empty object with given `proto` as `[[Prototype]]` and optional property descriptors.
 - [Object.getPrototypeOf(obj)](mdn:js/Object/getPrototypeOf) -- returns the `[[Prototype]]` of `obj`.
 - [Object.setPrototypeOf(obj, proto)](mdn:js/Object/setPrototypeOf) -- sets the `[[Prototype]]` of `obj` to `proto`.
 
-These should be used instead of `__proto__`.
+The only usage of `__proto__`, that's not frowned upon, is as a property when creating a new object: `{ __proto__: ... }`.
+
+Although, there's a special method for this too:
+
+- [Object.create(proto[, descriptors])](mdn:js/Object/create) -- creates an empty object with given `proto` as `[[Prototype]]` and optional property descriptors.
 
 For instance:
 
@@ -22,7 +25,7 @@ let animal = {
 
 // create a new object with animal as a prototype
 *!*
-let rabbit = Object.create(animal);
+let rabbit = Object.create(animal); // same as {__proto__: animal}
 */!*
 
 alert(rabbit.eats); // true
@@ -36,7 +39,9 @@ Object.setPrototypeOf(rabbit, {}); // change the prototype of rabbit to {}
 */!*
 ```
 
-`Object.create` has an optional second argument: property descriptors. We can provide additional properties to the new object there, like this:
+The `Object.create` method is a bit more powerful, as it has an optional second argument: property descriptors.
+
+We can provide additional properties to the new object there, like this:
 
 ```js run
 let animal = {
@@ -57,27 +62,34 @@ The descriptors are in the same format as described in the chapter <info:propert
 We can use `Object.create` to perform an object cloning more powerful than copying properties in `for..in`:
 
 ```js
-// fully identical shallow clone of obj
-let clone = Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj));
+let clone = Object.create(
+  Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj)
+);
 ```
 
 This call makes a truly exact copy of `obj`, including all properties: enumerable and non-enumerable, data properties and setters/getters -- everything, and with the right `[[Prototype]]`.
 
-## Brief history
 
-If we count all the ways to manage `[[Prototype]]`, there are a lot! Many ways to do the same!
+## Brief history
 
-Why?
+There're so many ways to manage `[[Prototype]]`. How did that happen? Why?
 
 That's for historical reasons.
 
-- The `"prototype"` property of a constructor function has worked since very ancient times.
-- Later, in the year 2012, `Object.create` appeared in the standard. It gave the ability to create objects with a given prototype, but did not provide the ability to get/set it. So browsers implemented the non-standard `__proto__` accessor that allowed the user to get/set a prototype at any time.
+The prototypal inheritance was in the language since its dawn, but the ways to manage it evolved over time.
+
+- The `prototype` property of a constructor function has worked since very ancient times. It's the oldest way to create objects with a given prototype.
+- Later, in the year 2012, `Object.create` appeared in the standard. It gave the ability to create objects with a given prototype, but did not provide the ability to get/set it. Some browsers implemented the non-standard `__proto__` accessor that allowed the user to get/set a prototype at any time, to give more flexibility to developers.
 - Later, in the year 2015, `Object.setPrototypeOf` and `Object.getPrototypeOf` were added to the standard, to perform the same functionality as `__proto__`. As `__proto__` was de-facto implemented everywhere, it was kind-of deprecated and made its way to the Annex B of the standard, that is: optional for non-browser environments.
+- Later, in the year 2022, it was officially allowed to use `__proto__` in object literals `{...}` (moved out of Annex B), but not as a getter/setter `obj.__proto__` (still in Annex B).
+
+Why was `__proto__` replaced by the functions `getPrototypeOf/setPrototypeOf`?
+
+Why was `__proto__` partially rehabilitated and its usage allowed in `{...}`, but not as a getter/setter?
 
-As of now we have all these ways at our disposal.
+That's an interesting question, requiring us to understand why `__proto__` is bad.
 
-Why was `__proto__` replaced by the functions `getPrototypeOf/setPrototypeOf`? That's an interesting question, requiring us to understand why `__proto__` is bad. Read on to get the answer.
+And soon we'll get the answer.
 
 ```warn header="Don't change `[[Prototype]]` on existing objects if speed matters"
 Technically, we can get/set `[[Prototype]]` at any time. But usually we only set it once at the object creation time and don't modify it anymore: `rabbit` inherits from `animal`, and that is not going to change.
@@ -102,25 +114,36 @@ obj[key] = "some value";
 alert(obj[key]); // [object Object], not "some value"!
 ```
 
-Here, if the user types in `__proto__`, the assignment is ignored!
+Here, if the user types in `__proto__`, the assignment in line 4 is ignored!
 
-That shouldn't surprise us. The `__proto__` property is special: it must be either an object or `null`. A string can not become a prototype.
+That could surely be surprising for a non-developer, but pretty understandable for us. The `__proto__` property is special: it must be either an object or `null`. A string can not become a prototype. That's why an assignment a string to `__proto__` is ignored.
 
 But we didn't *intend* to implement such behavior, right? We want to store key/value pairs, and the key named `"__proto__"` was not properly saved. So that's a bug!
 
-Here the consequences are not terrible. But in other cases we may be assigning object values, and then the prototype may indeed be changed. As a result, the execution will go wrong in totally unexpected ways.
+Here the consequences are not terrible. But in other cases we may be storing objects instead of strings in `obj`, and then the prototype will indeed be changed. As a result, the execution will go wrong in totally unexpected ways.
 
 What's worse -- usually developers do not think about such possibility at all. That makes such bugs hard to notice and even turn them into vulnerabilities, especially when JavaScript is used on server-side.
 
-Unexpected things also may happen when assigning to `toString`, which is a function by default, and to other built-in methods.
+Unexpected things also may happen when assigning to `obj.toString`, as it's a built-in object method.
 
 How can we avoid this problem?
 
-First, we can just switch to using `Map`, then everything's fine.
+First, we can just switch to using `Map` for storage instead of plain objects, then everything's fine:
 
-But `Object` can also serve us well here, because language creators gave thought to that problem long ago.
+```js run
+let map = new Map();
+
+let key = prompt("What's the key?", "__proto__");
+map.set(key, "some value");
+
+alert(map.get(key)); // "some value" (as intended)
+```
 
-`__proto__` is not a property of an object, but an accessor property of `Object.prototype`:
+...But `Object` syntax is often more appealing, as it's more concise.
+
+Fortunately, we *can* use objects, because language creators gave thought to that problem long ago.
+
+As we know, `__proto__` is not a property of an object, but an accessor property of `Object.prototype`:
 
 ![](object-prototype-2.svg)
 
@@ -128,11 +151,12 @@ So, if `obj.__proto__` is read or set, the corresponding getter/setter is called
 
 As it was said in the beginning of this tutorial section: `__proto__` is a way to access `[[Prototype]]`, it is not `[[Prototype]]` itself.
 
-Now, if we want to use an object as an associative array, we can do it with a little trick:
+Now, if we intend to use an object as an associative array and be free of such problems, we can do it with a little trick:
 
 ```js run
 *!*
 let obj = Object.create(null);
+// or: obj = { __proto__: null }
 */!*
 
 let key = prompt("What's the key?", "__proto__");
@@ -174,32 +198,26 @@ alert(Object.keys(chineseDictionary)); // hello,bye
 
 ## Summary
 
-Modern methods to set up and directly access the prototype are:
-
-- [Object.create(proto[, descriptors])](mdn:js/Object/create) -- creates an empty object with a given `proto` as `[[Prototype]]` (can be `null`) and optional property descriptors.
-- [Object.getPrototypeOf(obj)](mdn:js/Object.getPrototypeOf) -- returns the `[[Prototype]]` of `obj` (same as `__proto__` getter).
-- [Object.setPrototypeOf(obj, proto)](mdn:js/Object.setPrototypeOf) -- sets the `[[Prototype]]` of `obj` to `proto` (same as `__proto__` setter).
+- To create an object with the given prototype, use:
 
-The built-in `__proto__` getter/setter is unsafe if we'd want to put user-generated keys into an object. Just because a user may enter `"__proto__"` as the key, and there'll be an error, with hopefully light, but generally unpredictable consequences.
+    - literal syntax: `{ __proto__: ... }`, allows to specify multiple properties
+    - or [Object.create(proto[, descriptors])](mdn:js/Object/create), allows to specify property descriptors.
 
-So we can either use `Object.create(null)` to create a "very plain" object without `__proto__`, or stick to `Map` objects for that.
+    The `Object.create` provides an easy way to shallow-copy an object with all descriptors:
 
-Also, `Object.create` provides an easy way to shallow-copy an object with all descriptors:
+    ```js
+    let clone = Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj));
+    ```
 
-```js
-let clone = Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj));
-```
+- Modern methods to get/set the prototype are:
 
-We also made it clear that `__proto__` is a getter/setter for `[[Prototype]]` and resides in `Object.prototype`, just like other methods.
+    - [Object.getPrototypeOf(obj)](mdn:js/Object/getPrototypeOf) -- returns the `[[Prototype]]` of `obj` (same as `__proto__` getter).
+    - [Object.setPrototypeOf(obj, proto)](mdn:js/Object/setPrototypeOf) -- sets the `[[Prototype]]` of `obj` to `proto` (same as `__proto__` setter).
 
-We can create an object without a prototype by `Object.create(null)`. Such objects are used as "pure dictionaries", they have no issues with `"__proto__"` as the key.
+- Getting/setting the prototype using the built-in `__proto__` getter/setter isn't recommended, it's now in the Annex B of the specification.
 
-Other methods:
+- We also covered prototype-less objects, created with `Object.create(null)` or `{__proto__: null}`.
 
-- [Object.keys(obj)](mdn:js/Object/keys) / [Object.values(obj)](mdn:js/Object/values) / [Object.entries(obj)](mdn:js/Object/entries) -- returns an array of enumerable own string property names/values/key-value pairs.
-- [Object.getOwnPropertySymbols(obj)](mdn:js/Object/getOwnPropertySymbols) -- returns an array of all own symbolic keys.
-- [Object.getOwnPropertyNames(obj)](mdn:js/Object/getOwnPropertyNames) -- returns an array of all own string keys.
-- [Reflect.ownKeys(obj)](mdn:js/Reflect/ownKeys) -- returns an array of all own keys.
-- [obj.hasOwnProperty(key)](mdn:js/Object/hasOwnProperty): returns `true` if `obj` has its own (not inherited) key named `key`.
+    These objects are used as dictionaries, to store any (possibly user-generated) keys.
 
-All methods that return object properties (like `Object.keys` and others) -- return "own" properties. If we want inherited ones, we can use `for..in`.
+    Normally, objects inherit built-in methods and `__proto__` getter/setter from `Object.prototype`, making corresponding keys "occupied" and potentially causing side effects. With `null` prototype, objects are truly empty.
diff --git a/1-js/09-classes/01-class/1-rewrite-to-class/task.md b/1-js/09-classes/01-class/1-rewrite-to-class/task.md
index 05365e410..4477de679 100644
--- a/1-js/09-classes/01-class/1-rewrite-to-class/task.md
+++ b/1-js/09-classes/01-class/1-rewrite-to-class/task.md
@@ -4,6 +4,6 @@ importance: 5
 
 # Rewrite to class
 
-The `Clock` class is written in functional style. Rewrite it the "class" syntax.
+The `Clock` class (see the sandbox) is written in functional style. Rewrite it in the "class" syntax.
 
 P.S. The clock ticks in the console, open it to see.
diff --git a/1-js/09-classes/01-class/article.md b/1-js/09-classes/01-class/article.md
index 83ee2c4fe..135d24929 100644
--- a/1-js/09-classes/01-class/article.md
+++ b/1-js/09-classes/01-class/article.md
@@ -51,7 +51,7 @@ user.sayHi();
 
 When `new User("John")` is called:
 1. A new object is created.
-2. The `constructor` runs with the given argument and assigns `this.name` to it.
+2. The `constructor` runs with the given argument and assigns it to `this.name`.
 
 ...Then we can call object methods, such as `user.sayHi()`.
 
@@ -110,7 +110,7 @@ alert(typeof User); // function
 alert(User === User.prototype.constructor); // true
 
 // The methods are in User.prototype, e.g:
-alert(User.prototype.sayHi); // alert(this.name);
+alert(User.prototype.sayHi); // the code of the sayHi method
 
 // there are exactly two methods in the prototype
 alert(Object.getOwnPropertyNames(User.prototype)); // constructor, sayHi
@@ -118,7 +118,7 @@ alert(Object.getOwnPropertyNames(User.prototype)); // constructor, sayHi
 
 ## Not just a syntactic sugar
 
-Sometimes people say that `class` is a "syntactic sugar" (syntax that is designed to make things easier to read, but doesn't introduce anything new), because we could actually declare the same without `class` keyword at all:
+Sometimes people say that `class` is a "syntactic sugar" (syntax that is designed to make things easier to read, but doesn't introduce anything new), because we could actually declare the same thing without using the `class` keyword at all:
 
 ```js run
 // rewriting class User in pure functions
@@ -127,7 +127,7 @@ Sometimes people say that `class` is a "syntactic sugar" (syntax that is designe
 function User(name) {
   this.name = name;
 }
-// any function prototype has constructor property by default,
+// a function prototype has "constructor" property by default,
 // so we don't need to create it
 
 // 2. Add the method to prototype
@@ -144,9 +144,9 @@ The result of this definition is about the same. So, there are indeed reasons wh
 
 Still, there are important differences.
 
-1. First, a function created by `class` is labelled by a special internal property `[[FunctionKind]]:"classConstructor"`. So it's not entirely the same as creating it manually.
+1. First, a function created by `class` is labelled by a special internal property `[[IsClassConstructor]]: true`. So it's not entirely the same as creating it manually.
 
-    And unlike a regular function, a class constructor must be called with `new`:
+    The language checks for that property in a variety of places. For example, unlike a regular function, it must be called with `new`:
 
     ```js run
     class User {
@@ -166,6 +166,7 @@ Still, there are important differences.
 
     alert(User); // class User { ... }
     ```
+    There are other differences, we'll see them soon.
 
 2. Class methods are non-enumerable.
     A class definition sets `enumerable` flag to `false` for all methods in the `"prototype"`.
@@ -209,7 +210,6 @@ new User().sayHi(); // works, shows MyClass definition
 alert(MyClass); // error, MyClass name isn't visible outside of the class
 ```
 
-
 We can even make classes dynamically "on-demand", like this:
 
 ```js run
@@ -218,7 +218,7 @@ function makeClass(phrase) {
   return class {
     sayHi() {
       alert(phrase);
-    };
+    }
   };
 }
 
@@ -229,7 +229,7 @@ new User().sayHi(); // Hello
 ```
 
 
-## Getters/setters, other shorthands
+## Getters/setters
 
 Just like literal objects, classes may include getters/setters, computed properties etc.
 
@@ -264,25 +264,14 @@ class User {
 let user = new User("John");
 alert(user.name); // John
 
-user = new User(""); // Name too short.
+user = new User(""); // Name is too short.
 ```
 
-The class declaration creates getters and setters in `User.prototype`, like this:
+Technically, such class declaration works by creating getters and setters in `User.prototype`.
 
-```js
-Object.defineProperties(User.prototype, {
-  name: {
-    get() {
-      return this._name
-    },
-    set(name) {
-      // ...
-    }
-  }
-});
-```
+## Computed names [...]
 
-Here's an example with a computed property name in brackets `[...]`:
+Here's an example with a computed method name using brackets `[...]`:
 
 ```js run
 class User {
@@ -298,18 +287,24 @@ class User {
 new User().sayHi();
 ```
 
-## Class properties
+Such features are easy to remember, as they resemble that of literal objects.
+
+## Class fields
 
 ```warn header="Old browsers may need a polyfill"
-Class-level properties are a recent addition to the language.
+Class fields are a recent addition to the language.
 ```
 
-In the example above, `User` only had methods. Let's add a property:
+Previously, our classes only had methods.
+
+"Class fields" is a syntax that allows to add any properties.
+
+For instance, let's add `name` property to `class User`:
 
 ```js run
 class User {
 *!*
-  name = "Anonymous";
+  name = "John";
 */!*
 
   sayHi() {
@@ -317,13 +312,94 @@ class User {
   }
 }
 
-new User().sayHi();
+new User().sayHi(); // Hello, John!
+```
+
+So, we just write "<property name> = <value>" in the declaration, and that's it.
 
-alert(User.prototype.sayHi); // placed in User.prototype
-alert(User.prototype.name); // undefined, not placed in User.prototype
+The important difference of class fields is that they are set on individual objects, not `User.prototype`:
+
+```js run
+class User {
+*!*
+  name = "John";
+*/!*
+}
+
+let user = new User();
+alert(user.name); // John
+alert(User.prototype.name); // undefined
 ```
 
-The property `name` is not placed into `User.prototype`. Instead, it is created by `new` before calling the constructor, it's a property of the object itself.
+We can also assign values using more complex expressions and function calls:
+
+```js run
+class User {
+*!*
+  name = prompt("Name, please?", "John");
+*/!*
+}
+
+let user = new User();
+alert(user.name); // John
+```
+
+
+### Making bound methods with class fields
+
+As demonstrated in the chapter <info:bind> functions in JavaScript have a dynamic `this`. It depends on the context of the call.
+
+So if an object method is passed around and called in another context, `this` won't be a reference to its object any more.
+
+For instance, this code will show `undefined`:
+
+```js run
+class Button {
+  constructor(value) {
+    this.value = value;
+  }
+
+  click() {
+    alert(this.value);
+  }
+}
+
+let button = new Button("hello");
+
+*!*
+setTimeout(button.click, 1000); // undefined
+*/!*
+```
+
+The problem is called "losing `this`".
+
+There are two approaches to fixing it, as discussed in the chapter <info:bind>:
+
+1. Pass a wrapper-function, such as `setTimeout(() => button.click(), 1000)`.
+2. Bind the method to object, e.g. in the constructor.
+
+Class fields provide another, quite elegant syntax:
+
+```js run
+class Button {
+  constructor(value) {
+    this.value = value;
+  }
+*!*
+  click = () => {
+    alert(this.value);
+  }
+*/!*
+}
+
+let button = new Button("hello");
+
+setTimeout(button.click, 1000); // hello
+```
+
+The class field `click = () => {...}` is created on a per-object basis, there's a separate function for each `Button` object, with `this` inside it referencing that object. We can pass `button.click` around anywhere, and the value of `this` will always be correct.
+
+That's especially useful in browser environment, for event listeners.
 
 ## Summary
 
diff --git a/1-js/09-classes/02-class-inheritance/2-clock-class-extended/solution.view/extended-clock.js b/1-js/09-classes/02-class-inheritance/2-clock-class-extended/solution.view/extended-clock.js
index ca613ca5e..be2053cfc 100644
--- a/1-js/09-classes/02-class-inheritance/2-clock-class-extended/solution.view/extended-clock.js
+++ b/1-js/09-classes/02-class-inheritance/2-clock-class-extended/solution.view/extended-clock.js
@@ -1,7 +1,7 @@
 class ExtendedClock extends Clock {
   constructor(options) {
     super(options);
-    let { precision=1000 } = options;
+    let { precision = 1000 } = options;
     this.precision = precision;
   }
 
diff --git a/1-js/09-classes/02-class-inheritance/article.md b/1-js/09-classes/02-class-inheritance/article.md
index f031b4163..464042d82 100644
--- a/1-js/09-classes/02-class-inheritance/article.md
+++ b/1-js/09-classes/02-class-inheritance/article.md
@@ -16,7 +16,7 @@ class Animal {
     this.name = name;
   }
   run(speed) {
-    this.speed += speed;
+    this.speed = speed;
     alert(`${this.name} runs with speed ${this.speed}.`);
   }
   stop() {
@@ -55,7 +55,7 @@ rabbit.run(5); // White Rabbit runs with speed 5.
 rabbit.hide(); // White Rabbit hides!
 ```
 
-Object of `Rabbit` class have access to both `Rabbit` methods, such as `rabbit.hide()`, and also to `Animal` methods, such as `rabbit.run()`.
+Object of `Rabbit` class have access both to `Rabbit` methods, such as `rabbit.hide()`, and also to `Animal` methods, such as `rabbit.run()`.
 
 Internally, `extends` keyword works using the good old prototype mechanics. It sets `Rabbit.prototype.[[Prototype]]` to `Animal.prototype`. So, if a method is not found in `Rabbit.prototype`, JavaScript takes it from `Animal.prototype`.
 
@@ -76,8 +76,8 @@ For instance, a function call that generates the parent class:
 ```js run
 function f(phrase) {
   return class {
-    sayHi() { alert(phrase) }
-  }
+    sayHi() { alert(phrase); }
+  };
 }
 
 *!*
@@ -106,7 +106,7 @@ class Rabbit extends Animal {
 }
 ```
 
-Usually we don't want to totally replace a parent method, but rather to build on top of it to tweak or extend its functionality. We do something in our method, but call the parent method before/after it or in the process.
+Usually, however, we don't want to totally replace a parent method, but rather to build on top of it to tweak or extend its functionality. We do something in our method, but call the parent method before/after it or in the process.
 
 Classes provide `"super"` keyword for that.
 
@@ -124,7 +124,7 @@ class Animal {
   }
 
   run(speed) {
-    this.speed += speed;
+    this.speed = speed;
     alert(`${this.name} runs with speed ${this.speed}.`);
   }
 
@@ -151,7 +151,7 @@ class Rabbit extends Animal {
 let rabbit = new Rabbit("White Rabbit");
 
 rabbit.run(5); // White Rabbit runs with speed 5.
-rabbit.stop(); // White Rabbit stands still. White rabbit hides!
+rabbit.stop(); // White Rabbit stands still. White Rabbit hides!
 ```
 
 Now `Rabbit` has the `stop` method that calls the parent `super.stop()` in the process.
@@ -160,6 +160,7 @@ Now `Rabbit` has the `stop` method that calls the parent `super.stop()` in the p
 As was mentioned in the chapter <info:arrow-functions>, arrow functions do not have `super`.
 
 If accessed, it's taken from the outer function. For instance:
+
 ```js
 class Rabbit extends Animal {
   stop() {
@@ -176,7 +177,6 @@ setTimeout(function() { super.stop() }, 1000);
 ```
 ````
 
-
 ## Overriding constructor
 
 With constructors it gets a little bit tricky.
@@ -230,7 +230,9 @@ let rabbit = new Rabbit("White Rabbit", 10); // Error: this is not defined.
 
 Whoops! We've got an error. Now we can't create rabbits. What went wrong?
 
-The short answer is: constructors in inheriting classes must call `super(...)`, and (!) do it before using `this`.
+The short answer is:
+
+- **Constructors in inheriting classes must call `super(...)`, and (!) do it before using `this`.**
 
 ...But why? What's going on here? Indeed, the requirement seems strange.
 
@@ -243,7 +245,7 @@ That label affects its behavior with `new`.
 - When a regular function is executed with `new`, it creates an empty object and assigns it to `this`.
 - But when a derived constructor runs, it doesn't do this. It expects the parent constructor to do this job.
 
-So a derived constructor must call `super` in order to execute its parent (non-derived) constructor, otherwise the object for `this` won't be created. And we'll get an error.
+So a derived constructor must call `super` in order to execute its parent (base) constructor, otherwise the object for `this` won't be created. And we'll get an error.
 
 For the `Rabbit` constructor to work, it needs to call `super()` before using `this`, like here:
 
@@ -278,6 +280,99 @@ alert(rabbit.earLength); // 10
 */!*
 ```
 
+### Overriding class fields: a tricky note
+
+```warn header="Advanced note"
+This note assumes you have a certain experience with classes, maybe in other programming languages.
+
+It provides better insight into the language and also explains the behavior that might be a source of bugs (but not very often).
+
+If you find it difficult to understand, just go on, continue reading, then return to it some time later.
+```
+
+We can override not only methods, but also class fields.
+
+Although, there's a tricky behavior when we access an overridden field in parent constructor, quite different from most other programming languages.
+
+Consider this example:
+
+```js run
+class Animal {
+  name = 'animal';
+
+  constructor() {
+    alert(this.name); // (*)
+  }
+}
+
+class Rabbit extends Animal {
+  name = 'rabbit';
+}
+
+new Animal(); // animal
+*!*
+new Rabbit(); // animal
+*/!*
+```
+
+Here, class `Rabbit` extends `Animal` and overrides the `name` field with its own value.
+
+There's no own constructor in `Rabbit`, so `Animal` constructor is called.
+
+What's interesting is that in both cases: `new Animal()` and `new Rabbit()`, the `alert` in the line `(*)` shows `animal`.
+
+**In other words, the parent constructor always uses its own field value, not the overridden one.**
+
+What's odd about it?
+
+If it's not clear yet, please compare with methods.
+
+Here's the same code, but instead of `this.name` field we call `this.showName()` method:
+
+```js run
+class Animal {
+  showName() {  // instead of this.name = 'animal'
+    alert('animal');
+  }
+
+  constructor() {
+    this.showName(); // instead of alert(this.name);
+  }
+}
+
+class Rabbit extends Animal {
+  showName() {
+    alert('rabbit');
+  }
+}
+
+new Animal(); // animal
+*!*
+new Rabbit(); // rabbit
+*/!*
+```
+
+Please note: now the output is different.
+
+And that's what we naturally expect. When the parent constructor is called in the derived class, it uses the overridden method.
+
+...But for class fields it's not so. As said, the parent constructor always uses the parent field.
+
+Why is there a difference?
+
+Well, the reason is the field initialization order. The class field is initialized:
+- Before constructor for the base class (that doesn't extend anything),
+- Immediately after `super()` for the derived class.
+
+In our case, `Rabbit` is the derived class. There's no `constructor()` in it. As said previously, that's the same as if there was an empty constructor with only `super(...args)`.
+
+So, `new Rabbit()` calls `super()`, thus executing the parent constructor, and (per the rule for derived classes) only after that its class fields are initialized. At the time of the parent constructor execution, there are no `Rabbit` class fields yet, that's why `Animal` fields are used.
+
+This subtle difference between fields and methods is specific to JavaScript.
+
+Luckily, this behavior only reveals itself if an overridden field is used in the parent constructor. Then it may be difficult to understand what's going on, so we're explaining it here.
+
+If it becomes a problem, one can fix it by using methods or getters/setters instead of fields.
 
 ## Super: internals, [[HomeObject]]
 
@@ -438,7 +533,7 @@ It works as intended, due to `[[HomeObject]]` mechanics. A method, such as `long
 
 As we've known before, generally functions are "free", not bound to objects in JavaScript. So they can be copied between objects and called with another `this`.
 
-The very existance of `[[HomeObject]]` violates that principle, because methods remember their objects. `[[HomeObject]]` can't be changed, so this bond is forever.
+The very existence of `[[HomeObject]]` violates that principle, because methods remember their objects. `[[HomeObject]]` can't be changed, so this bond is forever.
 
 The only place in the language where `[[HomeObject]]` is used -- is `super`. So, if a method does not use `super`, then we can still consider it free and copy between objects. But with `super` things may go wrong.
 
@@ -447,7 +542,7 @@ Here's the demo of a wrong `super` result after copying:
 ```js run
 let animal = {
   sayHi() {
-    console.log(`I'm an animal`);
+    alert(`I'm an animal`);
   }
 };
 
@@ -461,7 +556,7 @@ let rabbit = {
 
 let plant = {
   sayHi() {
-    console.log("I'm a plant");
+    alert("I'm a plant");
   }
 };
 
@@ -478,7 +573,7 @@ tree.sayHi();  // I'm an animal (?!?)
 */!*
 ```
 
-A call to `tree.sayHi()` shows "I'm an animal". Definitevely wrong.
+A call to `tree.sayHi()` shows "I'm an animal". Definitely wrong.
 
 The reason is simple:
 - In the line `(*)`, the method `tree.sayHi` was copied from `rabbit`. Maybe we just wanted to avoid code duplication?
diff --git a/1-js/09-classes/02-class-inheritance/3-class-extend-object/rabbit-extends-object.svg b/1-js/09-classes/03-static-properties-methods/3-class-extend-object/rabbit-extends-object.svg
similarity index 59%
rename from 1-js/09-classes/02-class-inheritance/3-class-extend-object/rabbit-extends-object.svg
rename to 1-js/09-classes/03-static-properties-methods/3-class-extend-object/rabbit-extends-object.svg
index 34d783b4d..915ab9aa6 100644
--- a/1-js/09-classes/02-class-inheritance/3-class-extend-object/rabbit-extends-object.svg
+++ b/1-js/09-classes/03-static-properties-methods/3-class-extend-object/rabbit-extends-object.svg
@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="458" height="344" viewBox="0 0 458 344"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:&apos;PT Mono&apos;;font-weight:700;font-style:normal;src:local(&apos;PT MonoBold&apos;),url(/font/PTMonoBold.woff2) format(&apos;woff2&apos;),url(/font/PTMonoBold.woff) format(&apos;woff&apos;),url(/font/PTMonoBold.ttf) format(&apos;truetype&apos;)}</style></defs><g id="inheritance" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="rabbit-extends-object.svg"><path id="Rectangle-1" fill="#FFF9EB" stroke="#E8C48E" stroke-width="2" d="M228 61v68h178V61H228z"/><text id="call:-function-bind:" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="238" y="80">call: function</tspan> <tspan x="238" y="95">bind: function</tspan> <tspan x="238" y="110">...</tspan></text><path id="Rectangle-1-Copy" fill="#FFF9EB" stroke="#E8C48E" stroke-width="2" d="M228 303h178v28H228z"/><text id="Function.prototype" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="227" y="53">Function.prototype</tspan></text><path id="Rectangle-1-Copy-4" fill="#FFF9EB" stroke="#E8C48E" stroke-width="2" d="M228 202v28h178v-28H228z"/><text id="constructor" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="238" y="220">constructor</tspan></text><text id="Object" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="227" y="194">Object</tspan></text><text id="Rabbit" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="233" y="292">Rabbit</tspan></text><path id="Line" fill="#EE6B47" fill-rule="nonzero" d="M316.5 143.5l7 14h-6v28h-2v-28h-6l7-14z"/><text id="[[Prototype]]" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="326" y="167">[[Prototype]]</tspan></text><path id="Line-Copy-3" fill="#EE6B47" fill-rule="nonzero" d="M316.5 247.5l7 14h-6v28h-2v-28h-6l7-14z"/><text id="[[Prototype]]-Copy" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="326" y="271">[[Prototype]]</tspan></text><text id="constructor-copy" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="236" y="321">constructor</tspan></text><path id="Rectangle-1-Copy-3" fill="#FFF9EB" stroke="#E8C48E" stroke-width="2" d="M8 61h178v68H8z"/><text id="call:-function-bind:-copy" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="18" y="80">call: function</tspan> <tspan x="18" y="95">bind: function</tspan> <tspan x="18" y="110">...</tspan></text><path id="Rectangle-1-Copy-2" fill="#FFF9EB" stroke="#E8C48E" stroke-width="2" d="M8 201h178v28H8z"/><text id="Function.prototype-Copy" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="7" y="53">Function.prototype</tspan></text><text id="Rabbit-Copy" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="13" y="190">Rabbit</tspan></text><path id="Line-Copy-4" fill="#EE6B47" fill-rule="nonzero" d="M96.5 145.5l7 14h-6v28h-2v-28h-6l7-14z"/><text id="[[Prototype]]-Copy-2" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="106" y="169">[[Prototype]]</tspan></text><text id="constructor-copy-2" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="16" y="219">constructor</tspan></text><text id="class-Rabbit" fill="#EE6B47" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="14" y="18">class Rabbit</tspan></text><text id="class-Rabbit-extends" fill="#EE6B47" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="224" y="18">class Rabbit extends Object</tspan></text></g></g></svg>
\ No newline at end of file
+<svg xmlns="http://www.w3.org/2000/svg" width="458" height="344" viewBox="0 0 458 344"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:&apos;PT Mono&apos;;font-weight:700;font-style:normal;src:local(&apos;PT MonoBold&apos;),url(/font/PTMonoBold.woff2) format(&apos;woff2&apos;),url(/font/PTMonoBold.woff) format(&apos;woff&apos;),url(/font/PTMonoBold.ttf) format(&apos;truetype&apos;)}</style></defs><g id="inheritance" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="rabbit-extends-object.svg"><path id="Rectangle-1" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M406 61v68H228V61h178z"/><text id="call:-function-bind:" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="238" y="80">call: function</tspan> <tspan x="238" y="95">bind: function</tspan> <tspan x="238" y="110">...</tspan></text><path id="Rectangle-1-Copy" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M228 303h178v28H228z"/><text id="Function.prototype" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="227" y="53">Function.prototype</tspan></text><path id="Rectangle-1-Copy-4" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M406 202v28H228v-28h178z"/><text id="constructor" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="238" y="220">constructor</tspan></text><text id="Object" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="227" y="194">Object</tspan></text><text id="Rabbit" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="233" y="292">Rabbit</tspan></text><path id="Line" fill="#C06334" fill-rule="nonzero" d="M316.5 143.5l7 14h-6v28h-2v-28h-6l7-14z"/><text id="[[Prototype]]" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="326" y="167">[[Prototype]]</tspan></text><path id="Line-Copy-3" fill="#C06334" fill-rule="nonzero" d="M316.5 247.5l7 14h-6v28h-2v-28h-6l7-14z"/><text id="[[Prototype]]-Copy" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="326" y="271">[[Prototype]]</tspan></text><text id="constructor-copy" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="236" y="321">constructor</tspan></text><path id="Rectangle-1-Copy-3" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M8 61h178v68H8z"/><text id="call:-function-bind:-copy" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="18" y="80">call: function</tspan> <tspan x="18" y="95">bind: function</tspan> <tspan x="18" y="110">...</tspan></text><path id="Rectangle-1-Copy-2" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M8 201h178v28H8z"/><text id="Function.prototype-Copy" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="7" y="53">Function.prototype</tspan></text><text id="Rabbit-Copy" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="13" y="190">Rabbit</tspan></text><path id="Line-Copy-4" fill="#C06334" fill-rule="nonzero" d="M96.5 145.5l7 14h-6v28h-2v-28h-6l7-14z"/><text id="[[Prototype]]-Copy-2" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="106" y="169">[[Prototype]]</tspan></text><text id="constructor-copy-2" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="16" y="219">constructor</tspan></text><text id="class-Rabbit" fill="#C06334" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="14" y="18">class Rabbit</tspan></text><text id="class-Rabbit-extends" fill="#C06334" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="224" y="18">class Rabbit extends Object</tspan></text></g></g></svg>
\ No newline at end of file
diff --git a/1-js/09-classes/02-class-inheritance/3-class-extend-object/solution.md b/1-js/09-classes/03-static-properties-methods/3-class-extend-object/solution.md
similarity index 79%
rename from 1-js/09-classes/02-class-inheritance/3-class-extend-object/solution.md
rename to 1-js/09-classes/03-static-properties-methods/3-class-extend-object/solution.md
index ca9e80601..cb9829ce0 100644
--- a/1-js/09-classes/02-class-inheritance/3-class-extend-object/solution.md
+++ b/1-js/09-classes/03-static-properties-methods/3-class-extend-object/solution.md
@@ -21,14 +21,14 @@ alert( rabbit.hasOwnProperty('name') ); // true
 
 But that's not all yet.
 
-Even after the fix, there's still important difference in `"class Rabbit extends Object"` versus `class Rabbit`.
+Even after the fix, there's still an important difference between `"class Rabbit extends Object"` and `class Rabbit`.
 
 As we know, the "extends" syntax sets up two prototypes:
 
 1. Between `"prototype"` of the constructor functions (for methods).
 2. Between the constructor functions themselves (for static methods).
 
-In our case, for `class Rabbit extends Object` it means:
+In the case of `class Rabbit extends Object` it means:
 
 ```js run
 class Rabbit extends Object {}
@@ -37,7 +37,7 @@ alert( Rabbit.prototype.__proto__ === Object.prototype ); // (1) true
 alert( Rabbit.__proto__ === Object ); // (2) true
 ```
 
-So `Rabbit` now provides access to static methods of `Object` via `Rabbit`, like this:
+So `Rabbit` now provides access to the static methods of `Object` via `Rabbit`, like this:
 
 ```js run
 class Rabbit extends Object {}
@@ -67,7 +67,7 @@ alert ( Rabbit.getOwnPropertyNames({a: 1, b: 2})); // Error
 
 So `Rabbit` doesn't provide access to static methods of `Object` in that case.
 
-By the way, `Function.prototype` has "generic" function methods, like `call`, `bind` etc. They are ultimately available in both cases, because for the built-in `Object` constructor, `Object.__proto__ === Function.prototype`.
+By the way, `Function.prototype` also has "generic" function methods, like `call`, `bind` etc. They are ultimately available in both cases, because for the built-in `Object` constructor, `Object.__proto__ === Function.prototype`.
 
 Here's the picture:
 
diff --git a/1-js/09-classes/02-class-inheritance/3-class-extend-object/task.md b/1-js/09-classes/03-static-properties-methods/3-class-extend-object/task.md
similarity index 92%
rename from 1-js/09-classes/02-class-inheritance/3-class-extend-object/task.md
rename to 1-js/09-classes/03-static-properties-methods/3-class-extend-object/task.md
index b82a4255e..1d0f98a74 100644
--- a/1-js/09-classes/02-class-inheritance/3-class-extend-object/task.md
+++ b/1-js/09-classes/03-static-properties-methods/3-class-extend-object/task.md
@@ -1,4 +1,4 @@
-importance: 5
+importance: 3
 
 ---
 
@@ -38,5 +38,5 @@ class Rabbit extends Object {
 
 let rabbit = new Rabbit("Rab");
 
-alert( rabbit.hasOwnProperty('name') ); // true
+alert( rabbit.hasOwnProperty('name') ); // Error
 ```
diff --git a/1-js/09-classes/03-static-properties-methods/article.md b/1-js/09-classes/03-static-properties-methods/article.md
index ab08f2ded..4b493a5e8 100644
--- a/1-js/09-classes/03-static-properties-methods/article.md
+++ b/1-js/09-classes/03-static-properties-methods/article.md
@@ -1,9 +1,9 @@
 
 # Static properties and methods
 
-We can also assign a method to the class function itself, not to its `"prototype"`. Such methods are called *static*.
+We can also assign a method to the class as a whole. Such methods are called *static*.
 
-In a class, they are prepended by `static` keyword, like this:
+In a class declaration, they are prepended by `static` keyword, like this:
 
 ```js run
 class User {
@@ -31,9 +31,11 @@ User.staticMethod(); // true
 
 The value of `this` in `User.staticMethod()` call is the class constructor `User` itself (the "object before dot" rule).
 
-Usually, static methods are used to implement functions that belong to the class, but not to any particular object of it.
+Usually, static methods are used to implement functions that belong to the class as a whole, but not to any particular object of it.
 
-For instance, we have `Article` objects and need a function to compare them. A natural solution would be to add `Article.compare` method, like this:
+For instance, we have `Article` objects and need a function to compare them.
+
+A natural solution would be to add `Article.compare` static method:
 
 ```js run
 class Article {
@@ -63,9 +65,11 @@ articles.sort(Article.compare);
 alert( articles[0].title ); // CSS
 ```
 
-Here `Article.compare` stands "above" articles, as a means to compare them. It's not a method of an article, but rather of the whole class.
+Here `Article.compare` method stands "above" articles, as a means to compare them. It's not a method of an article, but rather of the whole class.
+
+Another example would be a so-called "factory" method.
 
-Another example would be a so-called "factory" method. Imagine, we need few ways to create an article:
+Let's say, we need multiple ways to create an article:
 
 1. Create by given parameters (`title`, `date` etc).
 2. Create an empty article with today's date.
@@ -73,7 +77,7 @@ Another example would be a so-called "factory" method. Imagine, we need few ways
 
 The first way can be implemented by the constructor. And for the second one we can make a static method of the class.
 
-Like `Article.createTodays()` here:
+Such as `Article.createTodays()` here:
 
 ```js run
 class Article {
@@ -101,10 +105,21 @@ Static methods are also used in database-related classes to search/save/remove e
 
 ```js
 // assuming Article is a special class for managing articles
-// static method to remove the article:
+// static method to remove the article by id:
 Article.remove({id: 12345});
 ```
 
+````warn header="Static methods aren't available for individual objects"
+Static methods are callable on classes, not on individual objects.
+
+E.g. such code won't work:
+
+```js
+// ...
+article.createTodays(); /// Error: article.createTodays is not a function
+```
+````
+
 ## Static properties
 
 [recent browser=Chrome]
@@ -125,7 +140,7 @@ That is the same as a direct assignment to `Article`:
 Article.publisher = "Ilya Kantor";
 ```
 
-## Inheritance of static properties and methods
+## Inheritance of static properties and methods [#statics-and-inheritance]
 
 Static properties and methods are inherited.
 
diff --git a/1-js/09-classes/04-private-protected-properties-methods/article.md b/1-js/09-classes/04-private-protected-properties-methods/article.md
index 60ed0ef1b..91efb89ee 100644
--- a/1-js/09-classes/04-private-protected-properties-methods/article.md
+++ b/1-js/09-classes/04-private-protected-properties-methods/article.md
@@ -96,7 +96,9 @@ class CoffeeMachine {
   _waterAmount = 0;
 
   set waterAmount(value) {
-    if (value < 0) throw new Error("Negative water");
+    if (value < 0) {
+      value = 0;
+    }
     this._waterAmount = value;
   }
 
@@ -114,10 +116,10 @@ class CoffeeMachine {
 let coffeeMachine = new CoffeeMachine(100);
 
 // add water
-coffeeMachine.waterAmount = -10; // Error: Negative water
+coffeeMachine.waterAmount = -10; // _waterAmount will become 0, not -10
 ```
 
-Now the access is under control, so setting the water below zero fails.
+Now the access is under control, so setting the water amount below zero becomes impossible.
 
 ## Read-only "power"
 
@@ -159,7 +161,7 @@ class CoffeeMachine {
   _waterAmount = 0;
 
   *!*setWaterAmount(value)*/!* {
-    if (value < 0) throw new Error("Negative water");
+    if (value < 0) value = 0;
     this._waterAmount = value;
   }
 
@@ -190,7 +192,7 @@ There's a finished JavaScript proposal, almost in the standard, that provides la
 
 Privates should start with `#`. They are only accessible from inside the class.
 
-For instance, here's a private `#waterLimit` property and the water-checking private method `#checkWater`:
+For instance, here's a private `#waterLimit` property and the water-checking private method `#fixWaterAmount`:
 
 ```js run
 class CoffeeMachine {
@@ -199,19 +201,23 @@ class CoffeeMachine {
 */!*
 
 *!*
-  #checkWater(value) {
-    if (value < 0) throw new Error("Negative water");
-    if (value > this.#waterLimit) throw new Error("Too much water");
+  #fixWaterAmount(value) {
+    if (value < 0) return 0;
+    if (value > this.#waterLimit) return this.#waterLimit;
   }
 */!*
 
+  setWaterAmount(value) {
+    this.#waterLimit = this.#fixWaterAmount(value);
+  }
+
 }
 
 let coffeeMachine = new CoffeeMachine();
 
 *!*
 // can't access privates from outside of the class
-coffeeMachine.#checkWater(); // Error
+coffeeMachine.#fixWaterAmount(123); // Error
 coffeeMachine.#waterLimit = 1000; // Error
 */!*
 ```
@@ -232,7 +238,7 @@ class CoffeeMachine {
   }
 
   set waterAmount(value) {
-    if (value < 0) throw new Error("Negative water");
+    if (value < 0) value = 0;
     this.#waterAmount = value;
   }
 }
diff --git a/1-js/09-classes/06-instanceof/article.md b/1-js/09-classes/06-instanceof/article.md
index aa973da06..f9db989ca 100644
--- a/1-js/09-classes/06-instanceof/article.md
+++ b/1-js/09-classes/06-instanceof/article.md
@@ -2,7 +2,7 @@
 
 The `instanceof` operator allows to check whether an object belongs to a certain class. It also takes inheritance into account.
 
-Such a check may be necessary in many cases. Here we'll use it for building a *polymorphic* function, the one that treats arguments differently depending on their type.
+Such a check may be necessary in many cases. For example, it can be used for building a *polymorphic* function, the one that treats arguments differently depending on their type.
 
 ## The instanceof operator [#ref-instanceof]
 
@@ -93,7 +93,7 @@ The algorithm of `obj instanceof Class` works roughly as follows:
     alert(rabbit instanceof Animal); // true
     */!*
 
-    // rabbit.__proto__ === Rabbit.prototype
+    // rabbit.__proto__ === Animal.prototype (no match)
     *!*
     // rabbit.__proto__.__proto__ === Animal.prototype (match!)
     */!*
@@ -190,7 +190,7 @@ For most environment-specific objects, there is such a property. Here are some b
 
 ```js run
 // toStringTag for the environment-specific object and class:
-alert( window[Symbol.toStringTag]); // window
+alert( window[Symbol.toStringTag]); // Window
 alert( XMLHttpRequest.prototype[Symbol.toStringTag] ); // XMLHttpRequest
 
 alert( {}.toString.call(window) ); // [object Window]
diff --git a/1-js/09-classes/07-mixins/article.md b/1-js/09-classes/07-mixins/article.md
index 2ec196105..526b832ef 100644
--- a/1-js/09-classes/07-mixins/article.md
+++ b/1-js/09-classes/07-mixins/article.md
@@ -69,7 +69,7 @@ let sayMixin = {
 };
 
 let sayHiMixin = {
-  __proto__: sayMixin, // (or we could use Object.create to set the prototype here)
+  __proto__: sayMixin, // (or we could use Object.setPrototypeOf to set the prototype here)
 
   sayHi() {
     *!*
@@ -103,7 +103,7 @@ Here's the diagram (see the right part):
 
 That's because methods `sayHi` and `sayBye` were initially created in `sayHiMixin`. So even though they got copied, their `[[HomeObject]]` internal property references `sayHiMixin`, as shown in the picture above.
 
-As `super` looks for parent methods in `[[HomeObject]].[[Prototype]]`, that means it searches `sayHiMixin.[[Prototype]]`, not `User.[[Prototype]]`.
+As `super` looks for parent methods in `[[HomeObject]].[[Prototype]]`, that means it searches `sayHiMixin.[[Prototype]]`.
 
 ## EventMixin
 
@@ -140,7 +140,7 @@ let eventMixin = {
    *  menu.off('select', handler)
    */
   off(eventName, handler) {
-    let handlers = this._eventHandlers && this._eventHandlers[eventName];
+    let handlers = this._eventHandlers?.[eventName];
     if (!handlers) return;
     for (let i = 0; i < handlers.length; i++) {
       if (handlers[i] === handler) {
@@ -154,7 +154,7 @@ let eventMixin = {
    *  this.trigger('select', data1, data2);
    */
   trigger(eventName, ...args) {
-    if (!this._eventHandlers || !this._eventHandlers[eventName]) {
+    if (!this._eventHandlers?.[eventName]) {
       return; // no handlers for that event name
     }
 
diff --git a/1-js/09-classes/07-mixins/head.html b/1-js/09-classes/07-mixins/head.html
index 77ea38b20..20e3a6354 100644
--- a/1-js/09-classes/07-mixins/head.html
+++ b/1-js/09-classes/07-mixins/head.html
@@ -18,7 +18,7 @@
    *  menu.off('select', handler)
    */
   off(eventName, handler) {
-    let handlers = this._eventHandlers && this._eventHandlers[eventName];
+    let handlers = this._eventHandlers?.[eventName];
     if (!handlers) return;
     for(let i = 0; i < handlers.length; i++) {
       if (handlers[i] == handler) {
diff --git a/1-js/10-error-handling/1-try-catch/1-finally-or-code-after/solution.md b/1-js/10-error-handling/1-try-catch/1-finally-or-code-after/solution.md
index 303431d6d..ec0dabc9a 100644
--- a/1-js/10-error-handling/1-try-catch/1-finally-or-code-after/solution.md
+++ b/1-js/10-error-handling/1-try-catch/1-finally-or-code-after/solution.md
@@ -1,8 +1,8 @@
 The difference becomes obvious when we look at the code inside a function.
 
-The behavior is different if there's a "jump out" of `try..catch`.
+The behavior is different if there's a "jump out" of `try...catch`.
 
-For instance, when there's a `return` inside `try..catch`. The `finally` clause works in case of *any* exit from `try..catch`, even via the `return` statement: right after `try..catch` is done, but before the calling code gets the control.
+For instance, when there's a `return` inside `try...catch`. The `finally` clause works in case of *any* exit from `try...catch`, even via the `return` statement: right after `try...catch` is done, but before the calling code gets the control.
 
 ```js run
 function f() {
@@ -11,7 +11,7 @@ function f() {
 *!*
     return "result";
 */!*
-  } catch (e) {
+  } catch (err) {
     /// ...
   } finally {
     alert('cleanup!');
@@ -28,11 +28,11 @@ function f() {
   try {
     alert('start');
     throw new Error("an error");
-  } catch (e) {
+  } catch (err) {
     // ...
     if("can't handle the error") {
 *!*
-      throw e;
+      throw err;
 */!*
     }
 
diff --git a/1-js/10-error-handling/1-try-catch/1-finally-or-code-after/task.md b/1-js/10-error-handling/1-try-catch/1-finally-or-code-after/task.md
index c573cc232..b6dc81326 100644
--- a/1-js/10-error-handling/1-try-catch/1-finally-or-code-after/task.md
+++ b/1-js/10-error-handling/1-try-catch/1-finally-or-code-after/task.md
@@ -6,12 +6,12 @@ importance: 5
 
 Compare the two code fragments.
 
-1. The first one uses `finally` to execute the code after `try..catch`:
+1. The first one uses `finally` to execute the code after `try...catch`:
 
     ```js
     try {
       work work
-    } catch (e) {
+    } catch (err) {
       handle errors
     } finally {
     *!*
@@ -19,12 +19,12 @@ Compare the two code fragments.
     */!*
     }
     ```
-2. The second fragment puts the cleaning right after `try..catch`:
+2. The second fragment puts the cleaning right after `try...catch`:
 
     ```js
     try {
       work work
-    } catch (e) {
+    } catch (err) {
       handle errors
     }
 
diff --git a/1-js/10-error-handling/1-try-catch/article.md b/1-js/10-error-handling/1-try-catch/article.md
index 149a95f1f..bf548373a 100644
--- a/1-js/10-error-handling/1-try-catch/article.md
+++ b/1-js/10-error-handling/1-try-catch/article.md
@@ -1,14 +1,14 @@
-# Error handling, "try..catch"
+# Error handling, "try...catch"
 
 No matter how great we are at programming, sometimes our scripts have errors. They may occur because of our mistakes, an unexpected user input, an erroneous server response, and for a thousand other reasons.
 
 Usually, a script "dies" (immediately stops) in case of an error, printing it to console.
 
-But there's a syntax construct `try..catch` that allows to "catch" errors and, instead of dying, do something more reasonable.
+But there's a syntax construct `try...catch` that allows us to "catch" errors so the script can, instead of dying, do something more reasonable.
 
-## The "try..catch" syntax
+## The "try...catch" syntax
 
-The `try..catch` construct has two main blocks: `try`, and then `catch`:
+The `try...catch` construct has two main blocks: `try`, and then `catch`:
 
 ```js
 try {
@@ -25,14 +25,14 @@ try {
 It works like this:
 
 1. First, the code in `try {...}` is executed.
-2. If there were no errors, then `catch(err)` is ignored: the execution reaches the end of `try` and goes on, skipping `catch`.
-3. If an error occurs, then `try` execution is stopped, and the control flows to the beginning of `catch(err)`. The `err` variable (can use any name for it) will contain an error object with details about what happened.
+2. If there were no errors, then `catch (err)` is ignored: the execution reaches the end of `try` and goes on, skipping `catch`.
+3. If an error occurs, then the `try` execution is stopped, and control flows to the beginning of `catch (err)`. The `err` variable (we can use any name for it) will contain an error object with details about what happened.
 
 ![](try-catch-flow.svg)
 
-So, an error inside the `try {…}` block does not kill the script: we have a chance to handle it in `catch`.
+So, an error inside the `try {...}` block does not kill the script -- we have a chance to handle it in `catch`.
 
-Let's see examples.
+Let's look at some examples.
 
 - An errorless example: shows `alert` `(1)` and `(2)`:
 
@@ -45,7 +45,7 @@ Let's see examples.
 
       alert('End of try runs');   // *!*(2) <--*/!*
 
-    } catch(err) {
+    } catch (err) {
 
       alert('Catch is ignored, because there are no errors'); // (3)
 
@@ -64,7 +64,7 @@ Let's see examples.
 
       alert('End of try (never reached)');  // (2)
 
-    } catch(err) {
+    } catch (err) {
 
       alert(`Error has occurred!`); // *!*(3) <--*/!*
 
@@ -72,45 +72,45 @@ Let's see examples.
     ```
 
 
-````warn header="`try..catch` only works for runtime errors"
-For `try..catch` to work, the code must be runnable. In other words, it should be valid JavaScript.
+````warn header="`try...catch` only works for runtime errors"
+For `try...catch` to work, the code must be runnable. In other words, it should be valid JavaScript.
 
 It won't work if the code is syntactically wrong, for instance it has unmatched curly braces:
 
 ```js run
 try {
   {{{{{{{{{{{{
-} catch(e) {
+} catch (err) {
   alert("The engine can't understand this code, it's invalid");
 }
 ```
 
 The JavaScript engine first reads the code, and then runs it. The errors that occur on the reading phase are called "parse-time" errors and are unrecoverable (from inside that code). That's because the engine can't understand the code.
 
-So, `try..catch` can only handle errors that occur in the valid code. Such errors are called "runtime errors" or, sometimes, "exceptions".
+So, `try...catch` can only handle errors that occur in valid code. Such errors are called "runtime errors" or, sometimes, "exceptions".
 ````
 
 
-````warn header="`try..catch` works synchronously"
-If an exception happens in "scheduled" code, like in `setTimeout`, then `try..catch` won't catch it:
+````warn header="`try...catch` works synchronously"
+If an exception happens in "scheduled" code, like in `setTimeout`, then `try...catch` won't catch it:
 
 ```js run
 try {
   setTimeout(function() {
     noSuchVariable; // script will die here
   }, 1000);
-} catch (e) {
+} catch (err) {
   alert( "won't work" );
 }
 ```
 
-That's because the function itself is executed later, when the engine has already left the `try..catch` construct.
+That's because the function itself is executed later, when the engine has already left the `try...catch` construct.
 
-To catch an exception inside a scheduled function, `try..catch` must be inside that function:
+To catch an exception inside a scheduled function, `try...catch` must be inside that function:
 ```js run
 setTimeout(function() {
   try {    
-    noSuchVariable; // try..catch handles the error!
+    noSuchVariable; // try...catch handles the error!
   } catch {
     alert( "error is caught here!" );
   }
@@ -125,7 +125,7 @@ When an error occurs, JavaScript generates an object containing the details abou
 ```js
 try {
   // ...
-} catch(err) { // <-- the "error object", could use another word instead of err
+} catch (err) { // <-- the "error object", could use another word instead of err
   // ...
 }
 ```
@@ -150,7 +150,7 @@ try {
 *!*
   lalala; // error, variable is not defined!
 */!*
-} catch(err) {
+} catch (err) {
   alert(err.name); // ReferenceError
   alert(err.message); // lalala is not defined
   alert(err.stack); // ReferenceError: lalala is not defined at (...call stack)
@@ -175,9 +175,9 @@ try {
 }
 ```
 
-## Using "try..catch"
+## Using "try...catch"
 
-Let's explore a real-life use case of `try..catch`.
+Let's explore a real-life use case of `try...catch`.
 
 As we already know, JavaScript supports the [JSON.parse(str)](mdn:js/JSON/parse) method to read JSON-encoded values.
 
@@ -205,7 +205,7 @@ Should we be satisfied with that? Of course not!
 
 This way, if something's wrong with the data, the visitor will never know that (unless they open the developer console). And people really don't like when something "just dies" without any error message.
 
-Let's use `try..catch` to handle the error:
+Let's use `try...catch` to handle the error:
 
 ```js run
 let json = "{ bad json }";
@@ -217,12 +217,12 @@ try {
 */!*
   alert( user.name ); // doesn't work
 
-} catch (e) {
+} catch (err) {
 *!*
   // ...the execution jumps here
   alert( "Our apologies, the data has errors, we'll try to request it one more time." );
-  alert( e.name );
-  alert( e.message );
+  alert( err.name );
+  alert( err.message );
 */!*
 }
 ```
@@ -245,7 +245,7 @@ try {
   alert( user.name ); // no name!
 */!*
 
-} catch (e) {
+} catch (err) {
   alert( "doesn't execute" );
 }
 ```
@@ -294,11 +294,11 @@ Let's see what kind of error `JSON.parse` generates:
 ```js run
 try {
   JSON.parse("{ bad json o_O }");
-} catch(e) {
+} catch (err) {
 *!*
-  alert(e.name); // SyntaxError
+  alert(err.name); // SyntaxError
 */!*
-  alert(e.message); // Unexpected token b in JSON at position 2
+  alert(err.message); // Unexpected token b in JSON at position 2
 }
 ```
 
@@ -323,8 +323,8 @@ try {
 
   alert( user.name );
 
-} catch(e) {
-  alert( "JSON Error: " + e.message ); // JSON Error: Incomplete data: no name
+} catch (err) {
+  alert( "JSON Error: " + err.message ); // JSON Error: Incomplete data: no name
 }
 ```
 
@@ -334,7 +334,7 @@ Now `catch` became a single place for all error handling: both for `JSON.parse`
 
 ## Rethrowing
 
-In the example above we use `try..catch` to handle incorrect data. But is it possible that *another unexpected error* occurs within the `try {...}` block? Like a programming error (variable is not defined) or something else, not just this "incorrect data" thing.
+In the example above we use `try...catch` to handle incorrect data. But is it possible that *another unexpected error* occurs within the `try {...}` block? Like a programming error (variable is not defined) or something else, not just this "incorrect data" thing.
 
 For example:
 
@@ -345,7 +345,7 @@ try {
   user = JSON.parse(json); // <-- forgot to put "let" before user
 
   // ...
-} catch(err) {
+} catch (err) {
   alert("JSON Error: " + err); // JSON Error: ReferenceError: user is not defined
   // (no JSON Error actually)
 }
@@ -353,29 +353,33 @@ try {
 
 Of course, everything's possible! Programmers do make mistakes. Even in open-source utilities used by millions for decades -- suddenly a bug may be discovered that leads to terrible hacks.
 
-In our case, `try..catch` is meant to catch "incorrect data" errors. But by its nature, `catch` gets *all* errors from `try`. Here it gets an unexpected error, but still shows the same `"JSON Error"` message. That's wrong and also makes the code more difficult to debug.
+In our case, `try...catch` is placed to catch "incorrect data" errors. But by its nature, `catch` gets *all* errors from `try`. Here it gets an unexpected error, but still shows the same `"JSON Error"` message. That's wrong and also makes the code more difficult to debug.
+
+To avoid such problems, we can employ the "rethrowing" technique. The rule is simple:
+
+**Catch should only process errors that it knows and "rethrow" all others.**
+
+The "rethrowing" technique can be explained in more detail as:
+
+1. Catch gets all errors.
+2. In the `catch (err) {...}` block we analyze the error object `err`.
+3. If we don't know how to handle it, we do `throw err`.
 
-Fortunately, we can find out which error we get, for instance from its `name`:
+Usually, we can check the error type using the `instanceof` operator:
 
 ```js run
 try {
   user = { /*...*/ };
-} catch(e) {
+} catch (err) {
 *!*
-  alert(e.name); // "ReferenceError" for accessing an undefined variable
+  if (err instanceof ReferenceError) {
 */!*
+    alert('ReferenceError'); // "ReferenceError" for accessing an undefined variable
+  }
 }
 ```
 
-The rule is simple:
-
-**Catch should only process errors that it knows and "rethrow" all others.**
-
-The "rethrowing" technique can be explained in more detail as:
-
-1. Catch gets all errors.
-2. In the `catch(err) {...}` block we analyze the error object `err`.
-2. If we don't know how to handle it, we do `throw err`.
+We can also get the error class name from `err.name` property. All native errors have it. Another option is to read `err.constructor.name`.
 
 In the code below, we use rethrowing so that `catch` only handles `SyntaxError`:
 
@@ -395,24 +399,24 @@ try {
 
   alert( user.name );
 
-} catch(e) {
+} catch (err) {
 
 *!*
-  if (e.name == "SyntaxError") {
-    alert( "JSON Error: " + e.message );
+  if (err instanceof SyntaxError) {
+    alert( "JSON Error: " + err.message );
   } else {
-    throw e; // rethrow (*)
+    throw err; // rethrow (*)
   }
 */!*
 
 }
 ```
 
-The error throwing on line `(*)` from inside `catch` block "falls out" of `try..catch` and can be either caught by an outer `try..catch` construct (if it exists), or it kills the script.
+The error throwing on line `(*)` from inside `catch` block "falls out" of `try...catch` and can be either caught by an outer `try...catch` construct (if it exists), or it kills the script.
 
 So the `catch` block actually handles only errors that it knows how to deal with and "skips" all others.
 
-The example below demonstrates how such errors can be caught by one more level of `try..catch`:
+The example below demonstrates how such errors can be caught by one more level of `try...catch`:
 
 ```js run
 function readData() {
@@ -423,11 +427,11 @@ function readData() {
 *!*
     blabla(); // error!
 */!*
-  } catch (e) {
+  } catch (err) {
     // ...
-    if (e.name != 'SyntaxError') {
+    if (!(err instanceof SyntaxError)) {
 *!*
-      throw e; // rethrow (don't know how to deal with it)
+      throw err; // rethrow (don't know how to deal with it)
 */!*
     }
   }
@@ -435,20 +439,20 @@ function readData() {
 
 try {
   readData();
-} catch (e) {
+} catch (err) {
 *!*
-  alert( "External catch got: " + e ); // caught it!
+  alert( "External catch got: " + err ); // caught it!
 */!*
 }
 ```
 
-Here `readData` only knows how to handle `SyntaxError`, while the outer `try..catch` knows how to handle everything.
+Here `readData` only knows how to handle `SyntaxError`, while the outer `try...catch` knows how to handle everything.
 
-## try..catch..finally
+## try...catch...finally
 
 Wait, that's not all.
 
-The `try..catch` construct may have one more code clause: `finally`.
+The `try...catch` construct may have one more code clause: `finally`.
 
 If it exists, it runs in all cases:
 
@@ -460,7 +464,7 @@ The extended syntax looks like this:
 ```js
 *!*try*/!* {
    ... try to execute the code ...
-} *!*catch*/!*(e) {
+} *!*catch*/!* (err) {
    ... handle errors ...
 } *!*finally*/!* {
    ... execute always ...
@@ -473,7 +477,7 @@ Try running this code:
 try {
   alert( 'try' );
   if (confirm('Make an error?')) BAD_CODE();
-} catch (e) {
+} catch (err) {
   alert( 'catch' );
 } finally {
   alert( 'finally' );
@@ -509,7 +513,7 @@ let start = Date.now();
 
 try {
   result = fib(num);
-} catch (e) {
+} catch (err) {
   result = 0;
 *!*
 } finally {
@@ -527,14 +531,14 @@ You can check by running the code with entering `35` into `prompt` -- it execute
 In other words, the function may finish with `return` or `throw`, that doesn't matter. The `finally` clause executes in both cases.
 
 
-```smart header="Variables are local inside `try..catch..finally`"
-Please note that `result` and `diff` variables in the code above are declared *before* `try..catch`.
+```smart header="Variables are local inside `try...catch...finally`"
+Please note that `result` and `diff` variables in the code above are declared *before* `try...catch`.
 
 Otherwise, if we declared `let` in `try` block, it would only be visible inside of it.
 ```
 
 ````smart header="`finally` and `return`"
-The `finally` clause works for *any* exit from `try..catch`. That includes an explicit `return`.
+The `finally` clause works for *any* exit from `try...catch`. That includes an explicit `return`.
 
 In the example below, there's a `return` in `try`. In this case, `finally` is executed just before the control returns to the outer code.
 
@@ -546,7 +550,7 @@ function func() {
     return 1;
 */!*
 
-  } catch (e) {
+  } catch (err) {
     /* ... */
   } finally {
 *!*
@@ -559,9 +563,9 @@ alert( func() ); // first works alert from finally, and then this one
 ```
 ````
 
-````smart header="`try..finally`"
+````smart header="`try...finally`"
 
-The `try..finally` construct, without `catch` clause, is also useful. We apply it when we don't want to handle errors here (let them fall through), but want to be sure that processes that we started are finalized.
+The `try...finally` construct, without `catch` clause, is also useful. We apply it when we don't want to handle errors here (let them fall through), but want to be sure that processes that we started are finalized.
 
 ```js
 function func() {
@@ -582,7 +586,7 @@ In the code above, an error inside `try` always falls out, because there's no `c
 The information from this section is not a part of the core JavaScript.
 ```
 
-Let's imagine we've got a fatal error outside of `try..catch`, and the script died. Like a programming error or some other terrible thing.
+Let's imagine we've got a fatal error outside of `try...catch`, and the script died. Like a programming error or some other terrible thing.
 
 Is there a way to react on such occurrences? We may want to log the error, show something to the user (normally they don't see error messages), etc.
 
@@ -628,7 +632,7 @@ For instance:
 
 The role of the global handler `window.onerror` is usually not to recover the script execution -- that's probably impossible in case of programming errors, but to send the error message to developers.
 
-There are also web-services that provide error-logging for such cases, like <https://errorception.com> or <http://www.muscula.com>.
+There are also web-services that provide error-logging for such cases, like <https://errorception.com> or <https://www.muscula.com>.
 
 They work like this:
 
@@ -639,14 +643,14 @@ They work like this:
 
 ## Summary
 
-The `try..catch` construct allows to handle runtime errors. It literally allows to "try" running the code and "catch" errors that may occur in it.
+The `try...catch` construct allows to handle runtime errors. It literally allows to "try" running the code and "catch" errors that may occur in it.
 
 The syntax is:
 
 ```js
 try {
   // run this code
-} catch(err) {
+} catch (err) {
   // if an error happened, then jump here
   // err is the error object
 } finally {
@@ -654,7 +658,7 @@ try {
 }
 ```
 
-There may be no `catch` section or no `finally`, so shorter constructs `try..catch` and `try..finally` are also valid.
+There may be no `catch` section or no `finally`, so shorter constructs `try...catch` and `try...finally` are also valid.
 
 Error objects have following properties:
 
@@ -662,10 +666,10 @@ Error objects have following properties:
 - `name` -- the string with error name (error constructor name).
 - `stack` (non-standard, but well-supported) -- the stack at the moment of error creation.
 
-If an error object is not needed, we can omit it by using `catch {` instead of `catch(err) {`.
+If an error object is not needed, we can omit it by using `catch {` instead of `catch (err) {`.
 
 We can also generate our own errors using the `throw` operator. Technically, the argument of `throw` can be anything, but usually it's an error object inheriting from the built-in `Error` class. More on extending errors in the next chapter.
 
 *Rethrowing* is a very important pattern of error handling: a `catch` block usually expects and knows how to handle the particular error type, so it should rethrow errors it doesn't know.
 
-Even if we don't have `try..catch`, most environments allow us to setup a "global" error handler to catch errors that "fall out". In-browser, that's `window.onerror`.
+Even if we don't have `try...catch`, most environments allow us to setup a "global" error handler to catch errors that "fall out". In-browser, that's `window.onerror`.
diff --git a/1-js/10-error-handling/2-custom-errors/article.md b/1-js/10-error-handling/2-custom-errors/article.md
index b48313322..d28b07439 100644
--- a/1-js/10-error-handling/2-custom-errors/article.md
+++ b/1-js/10-error-handling/2-custom-errors/article.md
@@ -21,9 +21,9 @@ Internally, we'll use `JSON.parse`. If it receives malformed `json`, then it thr
 
 Our function `readUser(json)` will not only read JSON, but check ("validate") the data. If there are no required fields, or the format is wrong, then that's an error. And that's not a `SyntaxError`, because the data is syntactically correct, but another kind of error. We'll call it `ValidationError` and create a class for it. An error of that kind should also carry the information about the offending field.
 
-Our `ValidationError` class should inherit from the built-in `Error` class.
+Our `ValidationError` class should inherit from the `Error` class.
 
-That class is built-in, but here's its approximate code so we can understand what we're extending:
+The `Error` class is built-in, but here's its approximate code so we can understand what we're extending:
 
 ```js
 // The "pseudocode" for the built-in Error class defined by JavaScript itself
@@ -38,7 +38,7 @@ class Error {
 
 Now let's inherit `ValidationError` from it and try it in action:
 
-```js run untrusted
+```js run
 *!*
 class ValidationError extends Error {
 */!*
@@ -117,15 +117,15 @@ We could also look at `err.name`, like this:
 // instead of (err instanceof SyntaxError)
 } else if (err.name == "SyntaxError") { // (*)
 // ...
-```  
+```
 
 The `instanceof` version is much better, because in the future we are going to extend `ValidationError`, make subtypes of it, like `PropertyRequiredError`. And `instanceof` check will continue to work for new inheriting classes. So that's future-proof.
 
-Also it's important that if `catch` meets an unknown error, then it rethrows it in the line `(**)`. The `catch` block only knows how to handle validation and syntax errors, other kinds (due to a typo in the code or other unknown ones) should fall through.
+Also it's important that if `catch` meets an unknown error, then it rethrows it in the line `(**)`. The `catch` block only knows how to handle validation and syntax errors, other kinds (caused by a typo in the code or other unknown reasons) should fall through.
 
 ## Further inheritance
 
-The `ValidationError` class is very generic. Many things may go wrong. The property may be absent or it may be in a wrong format (like a string value for `age`). Let's make a more concrete class `PropertyRequiredError`, exactly for absent properties. It will carry additional information about the property that's missing.
+The `ValidationError` class is very generic. Many things may go wrong. The property may be absent or it may be in a wrong format (like a string value for `age` instead of a number). Let's make a more concrete class `PropertyRequiredError`, exactly for absent properties. It will carry additional information about the property that's missing.
 
 ```js run
 class ValidationError extends Error {
@@ -215,11 +215,39 @@ Now custom errors are much shorter, especially `ValidationError`, as we got rid
 
 The purpose of the function `readUser` in the code above is "to read the user data". There may occur different kinds of errors in the process. Right now we have `SyntaxError` and `ValidationError`, but in the future `readUser` function may grow and probably generate other kinds of errors.
 
-The code which calls `readUser` should handle these errors. Right now it uses multiple `if`s in the `catch` block, that check the class and handle known errors and rethrow the unknown ones. But if the `readUser` function generates several kinds of errors, then we should ask ourselves: do we really want to check for all error types one-by-one in every code that calls `readUser`?
+The code which calls `readUser` should handle these errors. Right now it uses multiple `if`s in the `catch` block, that check the class and handle known errors and rethrow the unknown ones.
+
+The scheme is like this:
+
+```js
+try {
+  ...
+  readUser()  // the potential error source
+  ...
+} catch (err) {
+  if (err instanceof ValidationError) {
+    // handle validation errors
+  } else if (err instanceof SyntaxError) {
+    // handle syntax errors
+  } else {
+    throw err; // unknown error, rethrow it
+  }
+}
+```
+
+In the code above we can see two types of errors, but there can be more.
+
+If the `readUser` function generates several kinds of errors, then we should ask ourselves: do we really want to check for all error types one-by-one every time?
+
+Often the answer is "No": we'd like to be "one level above all that". We just want to know if there was a "data reading error" -- why exactly it happened is often irrelevant (the error message describes it). Or, even better, we'd like to have a way to get the error details, but only if we need to.
+
+The technique that we describe here is called "wrapping exceptions".
 
-Often the answer is "No": the outer code wants to be "one level above all that", it just wants to have some kind of "data reading error" -- why exactly it happened is often irrelevant (the error message describes it). Or, even better, it could have a way to get the error details, but only if we need to.
+1. We'll make a new class `ReadError` to represent a generic "data reading" error.
+2. The function `readUser` will catch data reading errors that occur inside it, such as `ValidationError` and `SyntaxError`, and generate a `ReadError` instead.
+3. The `ReadError` object will keep the reference to the original error in its `cause` property.
 
-So let's make a new class `ReadError` to represent such errors. If an error occurs inside `readUser`, we'll catch it there and generate `ReadError`. We'll also keep the reference to the original error in its `cause` property. Then the outer code will only have to check for `ReadError`.
+Then the code that calls `readUser` will only have to check for `ReadError`, not for every kind of data reading errors. And if it needs more details of an error, it can check its `cause` property.
 
 Here's the code that defines `ReadError` and demonstrates its use in `readUser` and `try..catch`:
 
@@ -293,7 +321,7 @@ In the code above, `readUser` works exactly as described -- catches syntax and v
 
 So the outer code checks `instanceof ReadError` and that's it. No need to list all possible error types.
 
-The approach is called "wrapping exceptions", because we take "low level exceptions" and "wrap" them into `ReadError` that is more abstract and more convenient to use for the calling code. It is widely used in object-oriented programming.
+The approach is called "wrapping exceptions", because we take "low level" exceptions and "wrap" them into `ReadError` that is more abstract. It is widely used in object-oriented programming.
 
 ## Summary
 
diff --git a/1-js/11-async/01-callbacks/article.md b/1-js/11-async/01-callbacks/article.md
index a98851ac0..57115a909 100644
--- a/1-js/11-async/01-callbacks/article.md
+++ b/1-js/11-async/01-callbacks/article.md
@@ -10,9 +10,9 @@ If you're not familiar with these methods, and their usage in the examples is co
 Although, we'll try to make things clear anyway. There won't be anything really complex browser-wise.
 ```
 
-Many actions in JavaScript are *asynchronous*. In other words, we initiate them now, but they finish later.
+Many functions are provided by JavaScript host environments that allow you to schedule *asynchronous* actions. In other words, actions that we initiate now, but they finish later.
 
-For instance, we can schedule such actions using `setTimeout`.
+For instance, one such function is the `setTimeout` function.
 
 There are other real-world examples of asynchronous actions, e.g. loading scripts and modules (we'll cover them in later chapters).
 
@@ -28,7 +28,7 @@ function loadScript(src) {
 }
 ```
 
-It appends to the document the new, dynamically created, tag `<script src="…">` with given `src`. The browser automatically starts loading it and executes when complete.
+It inserts into the document a new, dynamically created, tag `<script src="…">` with the given `src`. The browser automatically starts loading it and executes when complete.
 
 We can use this function like this:
 
@@ -77,6 +77,8 @@ function loadScript(src, *!*callback*/!*) {
 }
 ```
 
+The `onload` event is described in the article <info:onload-onerror#loading-a-script>, it basically executes a function after the script is loaded and executed.
+
 Now if we want to call new functions from the script, we should write that in the callback:
 
 ```js
@@ -102,14 +104,14 @@ function loadScript(src, callback) {
 *!*
 loadScript('https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.2.0/lodash.js', script => {
   alert(`Cool, the script ${script.src} is loaded`);
-  alert( _ ); // function declared in the loaded script
+  alert( _ ); // _ is a function declared in the loaded script
 });
 */!*
 ```
 
 That's called a "callback-based" style of asynchronous programming. A function that does something asynchronously should provide a `callback` argument where we put the function to run after it's complete.
 
-Here we did it in `loadScript`, but of course, it's a general approach.
+Here we did it in `loadScript`, but of course it's a general approach.
 
 ## Callback in callback
 
@@ -146,7 +148,7 @@ loadScript('/my/script.js', function(script) {
     });
 */!*
 
-  })
+  });
 
 });
 ```
@@ -196,9 +198,9 @@ So the single `callback` function is used both for reporting errors and passing
 
 ## Pyramid of Doom
 
-From the first look, it's a viable way of asynchronous coding. And indeed it is. For one or maybe two nested calls it looks fine.
+At first glance, it looks like a viable approach to asynchronous coding. And indeed it is. For one or maybe two nested calls it looks fine.
 
-But for multiple asynchronous actions that follow one after another we'll have code like this:
+But for multiple asynchronous actions that follow one after another, we'll have code like this:
 
 ```js
 loadScript('1.js', function(error, script) {
@@ -223,14 +225,14 @@ loadScript('1.js', function(error, script) {
         });
 
       }
-    })
+    });
   }
 });
 ```
 
 In the code above:
-1. We load `1.js`, then if there's no error.
-2. We load `2.js`, then if there's no error.
+1. We load `1.js`, then if there's no error...
+2. We load `2.js`, then if there's no error...
 3. We load `3.js`, then if there's no error -- do something else `(*)`.
 
 As calls become more nested, the code becomes deeper and increasingly more difficult to manage, especially if we have real code instead of `...` that may include more loops, conditional statements and so on.
@@ -256,7 +258,7 @@ loadScript('1.js', function(error, script) {
           }
         });
       }
-    })
+    });
   }
 });
 -->
@@ -296,10 +298,10 @@ function step3(error, script) {
   } else {
     // ...continue after all scripts are loaded (*)
   }
-};
+}
 ```
 
-See? It does the same, and there's no deep nesting now because we made every action a separate top-level function.
+See? It does the same thing, and there's no deep nesting now because we made every action a separate top-level function.
 
 It works, but the code looks like a torn apart spreadsheet. It's difficult to read, and you probably noticed that one needs to eye-jump between pieces while reading it. That's inconvenient, especially if the reader is not familiar with the code and doesn't know where to eye-jump.
 
@@ -307,4 +309,4 @@ Also, the functions named `step*` are all of single use, they are created only t
 
 We'd like to have something better.
 
-Luckily, there are other ways to avoid such pyramids. One of the best ways is to use "promises," described in the next chapter.
+Luckily, there are other ways to avoid such pyramids. One of the best ways is to use "promises", described in the next chapter.
diff --git a/1-js/11-async/02-promise-basics/03-animate-circle-promise/solution.view/index.html b/1-js/11-async/02-promise-basics/03-animate-circle-promise/solution.view/index.html
index 3229daf89..6052f009e 100644
--- a/1-js/11-async/02-promise-basics/03-animate-circle-promise/solution.view/index.html
+++ b/1-js/11-async/02-promise-basics/03-animate-circle-promise/solution.view/index.html
@@ -10,7 +10,7 @@
       text-align: center;
     }
     .circle {
-      transition-property: width, height, margin-left, margin-top;
+      transition-property: width, height;
       transition-duration: 2s;
       position: fixed;
       transform: translateX(-50%) translateY(-50%);
diff --git a/1-js/11-async/02-promise-basics/article.md b/1-js/11-async/02-promise-basics/article.md
index 9a3dc6fa5..b15643f0a 100644
--- a/1-js/11-async/02-promise-basics/article.md
+++ b/1-js/11-async/02-promise-basics/article.md
@@ -1,10 +1,10 @@
 # Promise
 
-Imagine that you're a top singer, and fans ask day and night for your upcoming single.
+Imagine that you're a top singer, and fans ask day and night for your upcoming song.
 
 To get some relief, you promise to send it to them when it's published. You give your fans a list. They can fill in their email addresses, so that when the song becomes available, all subscribed parties instantly receive it. And even if something goes very wrong, say, a fire in the studio, so that you can't publish the song, they will still be notified.
 
-Everyone is happy: you, because the people don't crowd you anymore, and fans, because they won't miss the single.
+Everyone is happy: you, because the people don't crowd you anymore, and fans, because they won't miss the song.
 
 This is a real-life analogy for things we often have in programming:
 
@@ -26,17 +26,17 @@ The function passed to `new Promise` is called the *executor*. When `new Promise
 
 Its arguments `resolve` and `reject` are callbacks provided by JavaScript itself. Our code is only inside the executor.
 
-When the executor obtains the result, be it soon or late - doesn't matter, it should call one of these callbacks:
+When the executor obtains the result, be it soon or late, doesn't matter, it should call one of these callbacks:
 
-- `resolve(value)` — if the job finished successfully, with result `value`.
-- `reject(error)` — if an error occurred, `error` is the error object.
+- `resolve(value)` — if the job is finished successfully, with result `value`.
+- `reject(error)` — if an error has occurred, `error` is the error object.
 
-So to summarize: the executor runs automatically, it should do a job, and then call either `resolve` or `reject`.
+So to summarize: the executor runs automatically and attempts to perform a job. When it is finished with the attempt, it calls `resolve` if it was successful or `reject` if there was an error.
 
-The `promise` object returned by `new Promise` constructor has internal properties:
+The `promise` object returned by the `new Promise` constructor has these internal properties:
 
 - `state` — initially `"pending"`, then changes to either `"fulfilled"` when `resolve` is called or `"rejected"` when `reject` is called.
-- `result` — initially `undefined`, then changes to `value` when `resolve(value)` called or `error` when `reject(error)` is called.
+- `result` — initially `undefined`, then changes to `value` when `resolve(value)` is called or `error` when `reject(error)` is called.
 
 So the executor eventually moves `promise` to one of these states:
 
@@ -46,7 +46,7 @@ Later we'll see how "fans" can subscribe to these changes.
 
 Here's an example of a promise constructor and a simple executor function with  "producing code" that takes time (via `setTimeout`):
 
-```js run
+```js
 let promise = new Promise(function(resolve, reject) {
   // the function is executed automatically when the promise is constructed
 
@@ -58,9 +58,9 @@ let promise = new Promise(function(resolve, reject) {
 We can see two things by running the code above:
 
 1. The executor is called automatically and immediately (by `new Promise`).
-2. The executor receives two arguments: `resolve` and `reject` — these functions are pre-defined by the JavaScript engine. So we don't need to create them. We should only call one of them when ready.
+2. The executor receives two arguments: `resolve` and `reject`. These functions are pre-defined by the JavaScript engine, so we don't need to create them. We should only call one of them when ready.
 
-    After one second of "processing" the executor calls `resolve("done")` to produce the result. This changes the state of the `promise` object:
+    After one second of "processing", the executor calls `resolve("done")` to produce the result. This changes the state of the `promise` object:
 
     ![](promise-resolve-1.svg)
 
@@ -79,7 +79,7 @@ The call to `reject(...)` moves the promise object to `"rejected"` state:
 
 ![](promise-reject-1.svg)
 
-To summarize, the executor should do a job (something that takes time usually) and then call `resolve` or `reject` to change the state of the corresponding promise object.
+To summarize, the executor should perform a job (usually something that takes time) and then call `resolve` or `reject` to change the state of the corresponding promise object.
 
 A promise that is either resolved or rejected is called "settled", as opposed to an initially "pending" promise.
 
@@ -127,9 +127,9 @@ That's fine. We immediately have a resolved promise.
 The properties `state` and `result` of the Promise object are internal. We can't directly access them. We can use the methods `.then`/`.catch`/`.finally` for that. They are described below.
 ```
 
-## Consumers: then, catch, finally
+## Consumers: then, catch
 
-A Promise object serves as a link between the executor (the "producing code" or "singer") and the consuming functions (the "fans"), which will receive the result or error. Consuming functions can be registered (subscribed) using methods `.then`, `.catch` and `.finally`.
+A Promise object serves as a link between the executor (the "producing code" or "singer") and the consuming functions (the "fans"), which will receive the result or error. Consuming functions can be registered (subscribed) using the methods `.then` and `.catch`.
 
 ### then
 
@@ -144,9 +144,9 @@ promise.then(
 );
 ```
 
-The first argument of `.then` is a function that runs when the promise is resolved, and receives the result.
+The first argument of `.then` is a function that runs when the promise is resolved and receives the result.
 
-The second argument of `.then` is a function that runs when the promise is rejected, and receives the error.
+The second argument of `.then` is a function that runs when the promise is rejected and receives the error.
 
 For instance, here's a reaction to a successfully resolved promise:
 
@@ -166,7 +166,7 @@ promise.then(
 
 The first function was executed.
 
-And in the case of a rejection -- the second one:
+And in the case of a rejection, the second one:
 
 ```js run
 let promise = new Promise(function(resolve, reject) {
@@ -205,66 +205,90 @@ let promise = new Promise((resolve, reject) => {
 });
 
 *!*
-// .catch(f) is the same as .then(null, f)
+// .catch(f) is the same as promise.then(null, f)
 promise.catch(alert); // shows "Error: Whoops!" after 1 second
 */!*
 ```
 
 The call `.catch(f)` is a complete analog of `.then(null, f)`, it's just a shorthand.
 
-### finally
+## Cleanup: finally
 
 Just like there's a `finally` clause in a regular `try {...} catch {...}`, there's `finally` in promises.
 
-The call `.finally(f)` is similar to `.then(f, f)` in the sense that `f` always runs when the promise is settled: be it resolve or reject.
+The call `.finally(f)` is similar to `.then(f, f)` in the sense that `f` runs always, when the promise is settled: be it resolve or reject.
+
+The idea of `finally` is to set up a handler for performing cleanup/finalizing after the previous operations are complete.
 
-`finally` is a good handler for performing cleanup, e.g. stopping our loading indicators, as they are not needed anymore, no matter what the outcome is.
+E.g. stopping loading indicators, closing no longer needed connections, etc.
 
-Like this:
+Think of it as a party finisher. No matter was a party good or bad, how many friends were in it, we still need (or at least should) do a cleanup after it.
+
+The code may look like this:
 
 ```js
 new Promise((resolve, reject) => {
-  /* do something that takes time, and then call resolve/reject */
+  /* do something that takes time, and then call resolve or maybe reject */
 })
 *!*
   // runs when the promise is settled, doesn't matter successfully or not
   .finally(() => stop loading indicator)
+  // so the loading indicator is always stopped before we go on
 */!*
   .then(result => show result, err => show error)
 ```
 
-It's not exactly an alias of `then(f,f)` though. There are several important differences:
+Please note that `finally(f)` isn't exactly an alias of `then(f,f)` though.
+
+There are important differences:
 
 1. A `finally` handler has no arguments. In `finally` we don't know whether the promise is successful or not. That's all right, as our task is usually to perform "general" finalizing procedures.
-2. A `finally` handler passes through results and errors to the next handler.
+
+    Please take a look at the example above: as you can see, the `finally` handler has no arguments, and the promise outcome is handled by the next handler.
+2. A `finally` handler "passes through" the result or error to the next suitable handler.
 
     For instance, here the result is passed through `finally` to `then`:
+
     ```js run
     new Promise((resolve, reject) => {
-      setTimeout(() => resolve("result"), 2000)
+      setTimeout(() => resolve("value"), 2000);
     })
-      .finally(() => alert("Promise ready"))
-      .then(result => alert(result)); // <-- .then handles the result
+      .finally(() => alert("Promise ready")) // triggers first
+      .then(result => alert(result)); // <-- .then shows "value"
     ```
 
-    And here there's an error in the promise, passed through `finally` to `catch`:
+    As you can see, the `value` returned by the first promise is passed through `finally` to the next `then`.
+
+    That's very convenient, because `finally` is not meant to process a promise result. As said, it's a place to do generic cleanup, no matter what the outcome was.
+
+    And here's an example of an error, for us to see how it's passed through `finally` to `catch`:
 
     ```js run
     new Promise((resolve, reject) => {
       throw new Error("error");
     })
-      .finally(() => alert("Promise ready"))
-      .catch(err => alert(err));  // <-- .catch handles the error object
-    ```  
+      .finally(() => alert("Promise ready")) // triggers first
+      .catch(err => alert(err));  // <-- .catch shows the error
+    ```
+
+3. A `finally` handler also shouldn't return anything. If it does, the returned value is silently ignored.
+
+    The only exception to this rule is when a `finally` handler throws an error. Then this error goes to the next handler, instead of any previous outcome.
+
+To summarize:
+
+- A `finally` handler doesn't get the outcome of the previous handler (it has no arguments). This outcome is passed through instead, to the next suitable handler.
+- If a `finally` handler returns something, it's ignored.
+- When `finally` throws an error, then the execution goes to the nearest error handler.
 
-    That's very convenient, because `finally` is not meant to process a promise result. So it passes it through.
+These features are helpful and make things work just the right way if we use `finally` how it's supposed to be used: for generic cleanup procedures.
 
-    We'll talk more about promise chaining and result-passing between handlers in the next chapter.
+````smart header="We can attach handlers to settled promises"
+If a promise is pending, `.then/catch/finally` handlers wait for its outcome.
 
-3. Last, but not least, `.finally(f)` is a more convenient syntax than `.then(f, f)`: no need to duplicate the function `f`.
+Sometimes, it might be that a promise is already settled when we add a handler to it.
 
-````smart header="On settled promises handlers run immediately"
-If a promise is pending, `.then/catch/finally` handlers wait for it. Otherwise, if a promise has already settled, they execute immediately:
+In such case, these handlers just run immediately:
 
 ```js run
 // the promise becomes resolved immediately upon creation
@@ -273,15 +297,15 @@ let promise = new Promise(resolve => resolve("done!"));
 promise.then(alert); // done! (shows up right now)
 ```
 
-Note that this is different, and more powerful than the real life "subscription list" scenario. If the singer has already released their song and then a person signs up on the subscription list, they probably won't receive that song. Subscriptions in real life must be done prior to the event.
+Note that this makes promises more powerful than the real life "subscription list" scenario. If the singer has already released their song and then a person signs up on the subscription list, they probably won't receive that song. Subscriptions in real life must be done prior to the event.
 
-Promises are more flexible. We can add handlers any time: if the result is already there, our handlers get it immediately.
+Promises are more flexible. We can add handlers any time: if the result is already there, they just execute.
 ````
 
-Next, let's see more practical examples of how promises can help us write asynchronous code.
-
 ## Example: loadScript [#loadscript]
 
+Next, let's see more practical examples of how promises can help us write asynchronous code.
+
 We've got the `loadScript` function for loading a script from the previous chapter.
 
 Here's the callback-based variant, just to remind us of it:
@@ -303,7 +327,7 @@ Let's rewrite it using Promises.
 The new function `loadScript` will not require a callback. Instead, it will create and return a Promise object that resolves when the loading is complete. The outer code can add handlers (subscribing functions) to it using `.then`:
 
 ```js run
-function loadScript(src) {  
+function loadScript(src) {
   return new Promise(function(resolve, reject) {
     let script = document.createElement('script');
     script.src = src;
diff --git a/1-js/11-async/03-promise-chaining/article.md b/1-js/11-async/03-promise-chaining/article.md
index 7dd9fb67f..a33ca258c 100644
--- a/1-js/11-async/03-promise-chaining/article.md
+++ b/1-js/11-async/03-promise-chaining/article.md
@@ -36,15 +36,15 @@ The idea is that the result is passed through the chain of `.then` handlers.
 
 Here the flow is:
 1. The initial promise resolves in 1 second `(*)`,
-2. Then the `.then` handler is called `(**)`.
-3. The value that it returns is passed to the next `.then` handler `(***)`
+2. Then the `.then` handler is called `(**)`, which in turn creates a new promise (resolved with `2` value).
+3. The next `then` `(***)` gets the result of the previous one, processes it (doubles) and passes it to the next handler.
 4. ...and so on.
 
 As the result is passed along the chain of handlers, we can see a sequence of `alert` calls: `1` -> `2` -> `4`.
 
 ![](promise-then-chain.svg)
 
-The whole thing works, because a call to `promise.then` returns a promise, so that we can call the next `.then` on it.
+The whole thing works, because every call to a `.then` returns a new promise, so that we can call the next `.then` on it.
 
 When a handler returns a value, it becomes the result of that promise, so the next `.then` is called with it.
 
@@ -72,7 +72,7 @@ promise.then(function(result) {
 });
 ```
 
-What we did here is just several handlers to one promise. They don't pass the result to each other; instead they process it independently.
+What we did here is just adding several handlers to one promise. They don't pass the result to each other; instead they process it independently.
 
 Here's the picture (compare it with the chaining above):
 
@@ -120,7 +120,7 @@ new Promise(function(resolve, reject) {
 });
 ```
 
-Here the first `.then` shows `1` and returns `new Promise(…)` in the line `(*)`. After one second it resolves, and the result (the argument of `resolve`, here it's `result * 2`) is passed on to handler of the second `.then`. That handler is in the line `(**)`, it shows `2` and does the same thing.
+Here the first `.then` shows `1` and returns `new Promise(…)` in the line `(*)`. After one second it resolves, and the result (the argument of `resolve`, here it's `result * 2`) is passed on to the handler of the second `.then`. That handler is in the line `(**)`, it shows `2` and does the same thing.
 
 So the output is the same as in the previous example: 1 -> 2 -> 4, but now with 1 second delay between `alert` calls.
 
@@ -224,7 +224,7 @@ This feature allows us to integrate custom objects with promise chains without h
 
 ## Bigger example: fetch
 
-In frontend programming promises are often used for network requests. So let's see an extended example of that.
+In frontend programming, promises are often used for network requests. So let's see an extended example of that.
 
 We'll use the [fetch](info:fetch) method to load the information about the user from the remote server. It has a lot of optional parameters covered in [separate chapters](info:fetch), but the basic syntax is quite simple:
 
@@ -248,11 +248,11 @@ fetch('/article/promise-chaining/user.json')
   })
   .then(function(text) {
     // ...and here's the content of the remote file
-    alert(text); // {"name": "iliakan", isAdmin: true}
+    alert(text); // {"name": "iliakan", "isAdmin": true}
   });
 ```
 
-There is also a method `response.json()` that reads the remote data and parses it as JSON. In our case that's even more convenient, so let's switch to it.
+The `response` object returned from `fetch` also includes the method `response.json()` that reads the remote data and parses it as JSON. In our case that's even more convenient, so let's switch to it.
 
 We'll also use arrow functions for brevity:
 
@@ -265,7 +265,7 @@ fetch('/article/promise-chaining/user.json')
 
 Now let's do something with the loaded user.
 
-For instance, we can make one more requests to GitHub, load the user profile and show the avatar:
+For instance, we can make one more request to GitHub, load the user profile and show the avatar:
 
 ```js run
 // Make a request for user.json
@@ -332,8 +332,7 @@ function loadJson(url) {
 }
 
 function loadGithubUser(name) {
-  return fetch(`https://api.github.com/users/${name}`)
-    .then(response => response.json());
+  return loadJson(`https://api.github.com/users/${name}`);
 }
 
 function showAvatar(githubUser) {
diff --git a/1-js/11-async/04-promise-error-handling/article.md b/1-js/11-async/04-promise-error-handling/article.md
index ad7be2439..c5b4206ab 100644
--- a/1-js/11-async/04-promise-error-handling/article.md
+++ b/1-js/11-async/04-promise-error-handling/article.md
@@ -92,7 +92,7 @@ new Promise((resolve, reject) => {
 }).catch(alert); // ReferenceError: blabla is not defined
 ```
 
-The final `.catch` not only catches explicit rejections, but also occasional errors in the handlers above.
+The final `.catch` not only catches explicit rejections, but also accidental errors in the handlers above.
 
 ## Rethrowing
 
@@ -100,7 +100,7 @@ As we already noticed, `.catch` at the end of the chain is similar to `try..catc
 
 In a regular `try..catch` we can analyze the error and maybe rethrow it if it can't be handled. The same thing is possible for promises.
 
-If we `throw` inside `.catch`, then the control goes to the next closest error handler. And if we handle the error and finish normally, then it continues to the closest successful `.then` handler.
+If we `throw` inside `.catch`, then the control goes to the next closest error handler. And if we handle the error and finish normally, then it continues to the next closest successful `.then` handler.
 
 In the example below the `.catch` successfully handles the error:
 
@@ -122,7 +122,7 @@ Here the `.catch` block finishes normally. So the next successful `.then` handle
 In the example below we see the other situation with `.catch`. The handler `(*)` catches the error and just can't handle it (e.g. it only knows how to handle `URIError`), so it throws it again:
 
 ```js run
-// the execution: catch -> catch -> then
+// the execution: catch -> catch
 new Promise((resolve, reject) => {
 
   throw new Error("Whoops!");
@@ -199,6 +199,7 @@ In non-browser environments like Node.js there are other ways to track unhandled
 ## Summary
 
 - `.catch` handles errors in promises of all kinds: be it a `reject()` call, or an error thrown in a handler.
+- `.then` also catches errors in the same manner, if given the second argument (which is the error handler).
 - We should place `.catch` exactly in places where we want to handle errors and know how to handle them. The handler should analyze errors (custom error classes help) and rethrow unknown ones (maybe they are programming mistakes).
 - It's ok not to use `.catch` at all, if there's no way to recover from an error.
 - In any case we should have the `unhandledrejection` event handler (for browsers, and analogs for other environments) to track unhandled errors and inform the user (and probably our server) about them, so that our app never "just dies".
diff --git a/1-js/11-async/05-promise-api/article.md b/1-js/11-async/05-promise-api/article.md
index 56d75b74f..7be84ce2c 100644
--- a/1-js/11-async/05-promise-api/article.md
+++ b/1-js/11-async/05-promise-api/article.md
@@ -1,6 +1,6 @@
 # Promise API
 
-There are 5 static methods in the `Promise` class. We'll quickly cover their use cases here.
+There are 6 static methods in the `Promise` class. We'll quickly cover their use cases here.
 
 ## Promise.all
 
@@ -13,12 +13,12 @@ That's what `Promise.all` is for.
 The syntax is:
 
 ```js
-let promise = Promise.all([...promises...]);
+let promise = Promise.all(iterable);
 ```
 
-`Promise.all` takes an array of promises (it technically can be any iterable, but is usually an array) and returns a new promise.
+`Promise.all` takes an iterable (usually, an array of promises) and returns a new promise.
 
-The new promise resolves when all listed promises are settled, and the array of their results becomes its result.
+The new promise resolves when all listed promises are resolved, and the array of their results becomes its result.
 
 For instance, the `Promise.all` below settles after 3 seconds, and then its result is an array `[1, 2, 3]`:
 
@@ -176,22 +176,21 @@ So for each promise we get its status and `value/error`.
 If the browser doesn't support `Promise.allSettled`, it's easy to polyfill:
 
 ```js
-if(!Promise.allSettled) {
-  Promise.allSettled = function(promises) {
-    return Promise.all(promises.map(p => Promise.resolve(p).then(value => ({
-      state: 'fulfilled',
-      value
-    }), reason => ({
-      state: 'rejected',
-      reason
-    }))));
+if (!Promise.allSettled) {
+  const rejectHandler = reason => ({ status: 'rejected', reason });
+
+  const resolveHandler = value => ({ status: 'fulfilled', value });
+
+  Promise.allSettled = function (promises) {
+    const convertedPromises = promises.map(p => Promise.resolve(p).then(resolveHandler, rejectHandler));
+    return Promise.all(convertedPromises);
   };
 }
 ```
 
 In this code, `promises.map` takes input values, turns them into promises (just in case a non-promise was passed) with `p => Promise.resolve(p)`, and then adds `.then` handler to every one.
 
-That handler turns a successful result `v` into `{state:'fulfilled', value:v}`, and an error `r` into `{state:'rejected', reason:r}`. That's exactly the format of `Promise.allSettled`.
+That handler turns a successful result `value` into `{status:'fulfilled', value}`, and an error `reason` into `{status:'rejected', reason}`. That's exactly the format of `Promise.allSettled`.
 
 Now we can use `Promise.allSettled` to get the results of *all* given promises, even if some of them reject.
 
@@ -218,6 +217,43 @@ Promise.race([
 The first promise here was fastest, so it became the result. After the first settled promise "wins the race", all further results/errors are ignored.
 
 
+## Promise.any
+
+Similar to `Promise.race`, but waits only for the first fulfilled promise and gets its result. If all of the given promises are rejected, then the returned promise is rejected with [`AggregateError`](mdn:js/AggregateError) - a special error object that stores all promise errors in its `errors` property.
+
+The syntax is:
+
+```js
+let promise = Promise.any(iterable);
+```
+
+For instance, here the result will be `1`:
+
+```js run
+Promise.any([
+  new Promise((resolve, reject) => setTimeout(() => reject(new Error("Whoops!")), 1000)),
+  new Promise((resolve, reject) => setTimeout(() => resolve(1), 2000)),
+  new Promise((resolve, reject) => setTimeout(() => resolve(3), 3000))
+]).then(alert); // 1
+```
+
+The first promise here was fastest, but it was rejected, so the second promise became the result. After the first fulfilled promise "wins the race", all further results are ignored.
+
+Here's an example when all promises fail:
+
+```js run
+Promise.any([
+  new Promise((resolve, reject) => setTimeout(() => reject(new Error("Ouch!")), 1000)),
+  new Promise((resolve, reject) => setTimeout(() => reject(new Error("Error!")), 2000))
+]).catch(error => {
+  console.log(error.constructor.name); // AggregateError
+  console.log(error.errors[0]); // Error: Ouch!
+  console.log(error.errors[1]); // Error: Error!
+});
+```
+
+As you can see, error objects for failed promises are available in the `errors` property of the `AggregateError` object.
+
 ## Promise.resolve/reject
 
 Methods `Promise.resolve` and `Promise.reject` are rarely needed in modern code, because `async/await` syntax (we'll cover it [a bit later](info:async-await)) makes them somewhat obsolete.
@@ -273,14 +309,15 @@ In practice, this method is almost never used.
 
 ## Summary
 
-There are 5 static methods of `Promise` class:
+There are 6 static methods of `Promise` class:
 
 1. `Promise.all(promises)` -- waits for all promises to resolve and returns an array of their results. If any of the given promises rejects, it becomes the error of `Promise.all`, and all other results are ignored.
 2. `Promise.allSettled(promises)` (recently added method) -- waits for all promises to settle and returns their results as an array of objects with:
-    - `state`: `"fulfilled"` or `"rejected"`
+    - `status`: `"fulfilled"` or `"rejected"`
     - `value` (if fulfilled) or `reason` (if rejected).
 3. `Promise.race(promises)` -- waits for the first promise to settle, and its result/error becomes the outcome.
-4. `Promise.resolve(value)` -- makes a resolved promise with the given value.
-5. `Promise.reject(error)` -- makes a rejected promise with the given error.
+4. `Promise.any(promises)` (recently added method) -- waits for the first promise to fulfill, and its result becomes the outcome. If all of the given promises are rejected, [`AggregateError`](mdn:js/AggregateError) becomes the error of `Promise.any`.
+5. `Promise.resolve(value)` -- makes a resolved promise with the given value.
+6. `Promise.reject(error)` -- makes a rejected promise with the given error.
 
-Of these five, `Promise.all` is probably the most common in practice.
+Of all these, `Promise.all` is probably the most common in practice.
diff --git a/1-js/11-async/06-promisify/article.md b/1-js/11-async/06-promisify/article.md
index 66e8a222d..855678e5b 100644
--- a/1-js/11-async/06-promisify/article.md
+++ b/1-js/11-async/06-promisify/article.md
@@ -4,6 +4,8 @@
 
 Such transformations are often required in real-life, as many functions and libraries are callback-based. But promises are more convenient, so it makes sense to promisify them.
 
+For better understanding, let's see an example.
+
 For instance, we have `loadScript(src, callback)` from the chapter <info:callbacks>.
 
 ```js run
@@ -21,37 +23,44 @@ function loadScript(src, callback) {
 // loadScript('path/script.js', (err, script) => {...})
 ```
 
-Let's promisify it. The new `loadScriptPromise(src)` function achieves the same result, but it accepts only `src` (no `callback`) and returns a promise.
+The function loads a script with the given `src`, and then calls `callback(err)` in case of an error, or `callback(null, script)` in case of successful loading. That's a widespread agreement for using callbacks, we saw it before.
+
+Let's promisify it.
+
+We'll make a new function `loadScriptPromise(src)`, that does the same (loads the script), but returns a promise instead of using callbacks.
+
+In other words, we pass it only `src` (no `callback`) and get a promise in return, that resolves with `script` when the load is successful, and rejects with the error otherwise.
 
+Here it is:
 ```js
 let loadScriptPromise = function(src) {
   return new Promise((resolve, reject) => {
     loadScript(src, (err, script) => {
-      if (err) reject(err)
+      if (err) reject(err);
       else resolve(script);
     });
-  })
-}
+  });
+};
 
 // usage:
 // loadScriptPromise('path/script.js').then(...)
 ```
 
-Now `loadScriptPromise` fits well in promise-based code.
+As we can see, the new function is a wrapper around the original `loadScript` function. It calls it providing its own callback that translates to promise `resolve/reject`.
 
-As we can see, it delegates all the work to the original `loadScript`, providing its own callback that translates to promise `resolve/reject`.
+Now `loadScriptPromise` fits well in promise-based code. If we like promises more than callbacks (and soon we'll see more reasons for that), then we will use it instead.
 
-In practice we'll probably need to promisify many functions, so it makes sense to use a helper. We'll call it `promisify(f)`: it accepts a to-promisify function `f` and returns a wrapper function.
+In practice we may need to promisify more than one function, so it makes sense to use a helper.
 
-That wrapper does the same as in the code above: returns a promise and passes the call to the original `f`, tracking the result in a custom callback:
+We'll call it `promisify(f)`: it accepts a to-promisify function `f` and returns a wrapper function.
 
 ```js
 function promisify(f) {
-  return function (...args) { // return a wrapper-function
+  return function (...args) { // return a wrapper-function (*)
     return new Promise((resolve, reject) => {
-      function callback(err, result) { // our custom callback for f
+      function callback(err, result) { // our custom callback for f (**)
         if (err) {
-          return reject(err);
+          reject(err);
         } else {
           resolve(result);
         }
@@ -62,18 +71,25 @@ function promisify(f) {
       f.call(this, ...args); // call the original function
     });
   };
-};
+}
 
 // usage:
 let loadScriptPromise = promisify(loadScript);
 loadScriptPromise(...).then(...);
 ```
 
-Here we assume that the original function expects a callback with two arguments `(err, result)`. That's what we encounter most often. Then our custom callback is in exactly the right format, and `promisify` works great for such a case.
+The code may look a bit complex, but it's essentially the same that we wrote above, while promisifying `loadScript` function.
+
+A call to `promisify(f)` returns a wrapper around `f` `(*)`. That wrapper returns a promise and forwards the call to the original `f`, tracking the result in the custom callback `(**)`.
+
+Here, `promisify` assumes that the original function expects a callback with exactly two arguments `(err, result)`. That's what we encounter most often. Then our custom callback is in exactly the right format, and `promisify` works great for such a case.
 
 But what if the original `f` expects a callback with more arguments `callback(err, res1, res2, ...)`?
 
-Here's a more advanced version of `promisify`: if called as `promisify(f, true)`, the promise result will be an array of callback results `[res1, res2, ...]`:
+We can improve our helper. Let's make a more advanced version of `promisify`.
+
+- When called as `promisify(f)` it should work similar to the version above.
+- When called as `promisify(f, true)`, it should return the promise that resolves with the array of callback results. That's exactly for callbacks with many arguments.
 
 ```js
 // promisify(f, true) to get array of results
@@ -82,7 +98,7 @@ function promisify(f, manyArgs = false) {
     return new Promise((resolve, reject) => {
       function *!*callback(err, ...results*/!*) { // our custom callback for f
         if (err) {
-          return reject(err);
+          reject(err);
         } else {
           // resolve with all callback results if manyArgs is specified
           *!*resolve(manyArgs ? results : results[0]);*/!*
@@ -94,19 +110,21 @@ function promisify(f, manyArgs = false) {
       f.call(this, ...args);
     });
   };
-};
+}
 
 // usage:
 f = promisify(f, true);
-f(...).then(arrayOfResults => ..., err => ...)
+f(...).then(arrayOfResults => ..., err => ...);
 ```
 
+As you can see it's essentially the same as above, but `resolve` is called with only one or all arguments depending on whether `manyArgs` is truthy.
+
 For more exotic callback formats, like those without `err` at all: `callback(result)`, we can promisify such functions manually without using the helper.
 
 There are also modules with a bit more flexible promisification functions, e.g. [es6-promisify](https://github.com/digitaldesignlabs/es6-promisify). In Node.js, there's a built-in `util.promisify` function for that.
 
 ```smart
-Promisification is a great approach, especially when you use `async/await` (see the next chapter), but not a total replacement for callbacks.
+Promisification is a great approach, especially when you use `async/await` (covered later in the chapter <info:async-await>), but not a total replacement for callbacks.
 
 Remember, a promise may have only one result, but a callback may technically be called many times.
 
diff --git a/1-js/11-async/07-microtask-queue/article.md b/1-js/11-async/07-microtask-queue/article.md
index 7e8e351a6..014dd93c0 100644
--- a/1-js/11-async/07-microtask-queue/article.md
+++ b/1-js/11-async/07-microtask-queue/article.md
@@ -3,9 +3,9 @@
 
 Promise handlers `.then`/`.catch`/`.finally` are always asynchronous.
 
-Even when a Promise is immediately resolved, the code on the lines *below* `.then`/`.catch`/`.finally` will still execute before these handlers .
+Even when a Promise is immediately resolved, the code on the lines *below* `.then`/`.catch`/`.finally` will still execute before these handlers.
 
-Here's the demo:
+Here's a demo:
 
 ```js run
 let promise = Promise.resolve();
@@ -23,14 +23,14 @@ Why did the `.then` trigger afterwards? What's going on?
 
 ## Microtasks queue
 
-Asynchronous tasks need proper management. For that, the standard specifies an internal queue `PromiseJobs`, more often referred to as "microtask queue" (v8 term).
+Asynchronous tasks need proper management. For that, the ECMA standard specifies an internal queue `PromiseJobs`, more often referred to as the "microtask queue" (V8 term).
 
-As said in the [specification](https://tc39.github.io/ecma262/#sec-jobs-and-job-queues):
+As stated in the [specification](https://tc39.github.io/ecma262/#sec-jobs-and-job-queues):
 
 - The queue is first-in-first-out: tasks enqueued first are run first.
 - Execution of a task is initiated only when nothing else is running.
 
-Or, to say that simply, when a promise is ready, its `.then/catch/finally` handlers are put into the queue. They are not executed yet. When the JavaScript engine becomes free from the current code, it takes a task from the queue and executes it.
+Or, to put it more simply, when a promise is ready, its `.then/catch/finally` handlers are put into the queue; they are not executed yet. When the JavaScript engine becomes free from the current code, it takes a task from the queue and executes it.
 
 That's why "code finished" in the example above shows first.
 
@@ -38,9 +38,9 @@ That's why "code finished" in the example above shows first.
 
 Promise handlers always go through this internal queue.
 
-If there's a chain with multiple `.then/catch/finally`, then every one of them is executed asynchronously. That is, it first gets queued, and executed when the current code is complete and previously queued handlers are finished.
+If there's a chain with multiple `.then/catch/finally`, then every one of them is executed asynchronously. That is, it first gets queued, then executed when the current code is complete and previously queued handlers are finished.
 
-**What if the order matters for us? How can we make `code finished` run after `promise done`?**
+**What if the order matters for us? How can we make `code finished` appear after `promise done`?**
 
 Easy, just put it into the queue with `.then`:
 
@@ -54,11 +54,11 @@ Now the order is as intended.
 
 ## Unhandled rejection
 
-Remember the `unhandledrejection` event from the chapter <info:promise-error-handling>?
+Remember the `unhandledrejection` event from the article <info:promise-error-handling>?
 
 Now we can see exactly how JavaScript finds out that there was an unhandled rejection.
 
-**"Unhandled rejection" occurs when a promise error is not handled at the end of the microtask queue.**
+**An "unhandled rejection" occurs when a promise error is not handled at the end of the microtask queue.**
 
 Normally, if we expect an error, we add `.catch` to the promise chain to handle it:
 
@@ -72,7 +72,7 @@ promise.catch(err => alert('caught'));
 window.addEventListener('unhandledrejection', event => alert(event.reason));
 ```
 
-...But if we forget to add `.catch`, then, after the microtask queue is empty, the engine triggers the event:
+But if we forget to add `.catch`, then, after the microtask queue is empty, the engine triggers the event:
 
 ```js run
 let promise = Promise.reject(new Error("Promise Failed!"));
@@ -93,20 +93,20 @@ setTimeout(() => promise.catch(err => alert('caught')), 1000);
 window.addEventListener('unhandledrejection', event => alert(event.reason));
 ```
 
-Now, if you run it, we'll see `Promise Failed!` first and then `caught`. 
+Now, if we run it, we'll see `Promise Failed!` first and then `caught`.
 
-If we didn't know about the microtasks queue, we could wonder: "Why did `unhandledrejection` handler run? We did catch the error!".
+If we didn't know about the microtasks queue, we could wonder: "Why did `unhandledrejection` handler run? We did catch and handle the error!"
 
-But now we understand that `unhandledrejection` is generated when the microtask queue is complete: the engine examines promises and, if any of them is in "rejected" state, then the event triggers.
+But now we understand that `unhandledrejection` is generated when the microtask queue is complete: the engine examines promises and, if any of them is in the "rejected" state, then the event triggers.
 
-In the example above, `.catch` added by `setTimeout` also triggers, but later, after `unhandledrejection` has already occurred, so that doesn't change anything.
+In the example above, `.catch` added by `setTimeout` also triggers. But it does so later, after `unhandledrejection` has already occurred, so it doesn't change anything.
 
 ## Summary
 
-Promise handling is always asynchronous, as all promise actions pass through the internal "promise jobs" queue, also called "microtask queue" (v8 term).
+Promise handling is always asynchronous, as all promise actions pass through the internal "promise jobs" queue, also called "microtask queue" (V8 term).
 
-So, `.then/catch/finally` handlers are always called after the current code is finished.
+So `.then/catch/finally` handlers are always called after the current code is finished.
 
 If we need to guarantee that a piece of code is executed after `.then/catch/finally`, we can add it into a chained `.then` call.
 
-In most JavaScript engines, including browsers and Node.js, the concept of microtasks is closely tied with "event loop" and "macrotasks". As these have no direct relation to promises, they are covered in another part of the tutorial, in the chapter <info:event-loop>.
+In most Javascript engines, including browsers and Node.js, the concept of microtasks is closely tied with the "event loop" and "macrotasks". As these have no direct relation to promises, they are covered in another part of the tutorial, in the article <info:event-loop>.
diff --git a/1-js/11-async/08-async-await/01-rewrite-async/solution.md b/1-js/11-async/08-async-await/01-rewrite-async/solution.md
index 6d9b339f6..3337ef3c4 100644
--- a/1-js/11-async/08-async-await/01-rewrite-async/solution.md
+++ b/1-js/11-async/08-async-await/01-rewrite-async/solution.md
@@ -13,7 +13,7 @@ async function loadJson(url) { // (1)
   throw new Error(response.status);
 }
 
-loadJson('no-such-user.json')
+loadJson('https://javascript.info/no-such-user.json')
   .catch(alert); // Error: 404 (4)
 ```
 
diff --git a/1-js/11-async/08-async-await/01-rewrite-async/task.md b/1-js/11-async/08-async-await/01-rewrite-async/task.md
index ad33fdb23..0c31737da 100644
--- a/1-js/11-async/08-async-await/01-rewrite-async/task.md
+++ b/1-js/11-async/08-async-await/01-rewrite-async/task.md
@@ -12,9 +12,9 @@ function loadJson(url) {
       } else {
         throw new Error(response.status);
       }
-    })
+    });
 }
 
-loadJson('no-such-user.json') // (3)
+loadJson('https://javascript.info/no-such-user.json')
   .catch(alert); // Error: 404
 ```
diff --git a/1-js/11-async/08-async-await/02-rewrite-async-2/solution.md b/1-js/11-async/08-async-await/02-rewrite-async-2/solution.md
index 105948833..aa462dbf7 100644
--- a/1-js/11-async/08-async-await/02-rewrite-async-2/solution.md
+++ b/1-js/11-async/08-async-await/02-rewrite-async-2/solution.md
@@ -1,5 +1,5 @@
 
-There are no tricks here. Just replace `.catch` with `try...catch` inside `demoGithubUser` and add `async/await` where needed:
+There are no tricks here. Just replace `.catch` with `try..catch` inside `demoGithubUser` and add `async/await` where needed:
 
 ```js run
 class HttpError extends Error {
diff --git a/1-js/11-async/08-async-await/02-rewrite-async-2/task.md b/1-js/11-async/08-async-await/02-rewrite-async-2/task.md
index a5c1c03a2..13d625d2a 100644
--- a/1-js/11-async/08-async-await/02-rewrite-async-2/task.md
+++ b/1-js/11-async/08-async-await/02-rewrite-async-2/task.md
@@ -1,7 +1,7 @@
 
 # Rewrite "rethrow" with async/await
 
-Below you can find the "rethrow" example from the chapter <info:promise-chaining>. Rewrite it using `async/await` instead of `.then/catch`.
+Below you can find the "rethrow" example. Rewrite it using `async/await` instead of `.then/catch`.
 
 And get rid of the recursion in favour of a loop in `demoGithubUser`: with `async/await` that becomes easy to do.
 
@@ -22,7 +22,7 @@ function loadJson(url) {
       } else {
         throw new HttpError(response);
       }
-    })
+    });
 }
 
 // Ask for a user name until github returns a valid user
diff --git a/1-js/11-async/08-async-await/03-async-from-regular/task.md b/1-js/11-async/08-async-await/03-async-from-regular/task.md
index 18d0e2ce7..ca7c186ff 100644
--- a/1-js/11-async/08-async-await/03-async-from-regular/task.md
+++ b/1-js/11-async/08-async-await/03-async-from-regular/task.md
@@ -1,7 +1,7 @@
 
 # Call async from non-async
 
-We have a "regular" function. How to call `async` from it and use its result?
+We have a "regular" function called `f`. How can you call the `async` function `wait()` and use its result inside of `f`?
 
 ```js
 async function wait() {
@@ -11,7 +11,7 @@ async function wait() {
 }
 
 function f() {
-  // ...what to write here?
+  // ...what should you write here?
   // we need to call async wait() and wait to get 10
   // remember, we can't use "await"
 }
diff --git a/1-js/11-async/08-async-await/article.md b/1-js/11-async/08-async-await/article.md
index e1be919dc..e679b1c4c 100644
--- a/1-js/11-async/08-async-await/article.md
+++ b/1-js/11-async/08-async-await/article.md
@@ -67,12 +67,12 @@ f();
 
 The function execution "pauses" at the line `(*)` and resumes when the promise settles, with `result` becoming its result. So the code above shows "done!" in one second.
 
-Let's emphasize: `await` literally makes JavaScript wait until the promise settles, and then go on with the result. That doesn't cost any CPU resources, because the engine can do other jobs in the meantime: execute other scripts, handle events, etc.
+Let's emphasize: `await` literally suspends the function execution until the promise settles, and then resumes it with the promise result. That doesn't cost any CPU resources, because the JavaScript engine can do other jobs in the meantime: execute other scripts, handle events, etc.
 
-It's just a more elegant syntax of getting the promise result than `promise.then`, easier to read and write.
+It's just a more elegant syntax of getting the promise result than `promise.then`. And, it's easier to read and write.
 
 ````warn header="Can't use `await` in regular functions"
-If we try to use `await` in non-async function, there would be a syntax error:
+If we try to use `await` in a non-async function, there would be a syntax error:
 
 ```js run
 function f() {
@@ -83,7 +83,7 @@ function f() {
 }
 ```
 
-We will get this error if we do not put `async` before a function. As said, `await` only works inside an `async function`.
+We may get this error if we forget to put `async` before a function. As stated earlier, `await` only works inside an `async` function.
 ````
 
 Let's take the `showAvatar()` example from the chapter <info:promise-chaining> and rewrite it using `async/await`:
@@ -121,16 +121,22 @@ showAvatar();
 
 Pretty clean and easy to read, right? Much better than before.
 
-````smart header="`await` won't work in the top-level code"
-People who are just starting to use `await` tend to forget the fact that we can't use `await` in top-level code. For example, this will not work:
+````smart header="Modern browsers allow top-level `await` in modules"
+In modern browsers, `await` on top level works just fine, when we're inside a module. We'll cover modules in article <info:modules-intro>.
 
-```js run
-// syntax error in top-level code
+For instance:
+
+```js run module
+// we assume this code runs at top level, inside a module
 let response = await fetch('/article/promise-chaining/user.json');
 let user = await response.json();
+
+console.log(user);
 ```
 
-But we can wrap it into an anonymous async function, like this:
+If we're not using modules, or [older browsers](https://caniuse.com/mdn-javascript_operators_await_top_level) must be supported, there's a universal recipe: wrapping into an anonymous async function.
+
+Like this:
 
 ```js
 (async () => {
@@ -140,10 +146,10 @@ But we can wrap it into an anonymous async function, like this:
 })();
 ```
 
-
 ````
+
 ````smart header="`await` accepts \"thenables\""
-Like `promise.then`, `await` allows to use thenable objects (those with a callable `then` method). The idea is that a third-party object may not be a promise, but promise-compatible: if it supports `.then`, that's enough to use with `await`.
+Like `promise.then`, `await` allows us to use thenable objects (those with a callable `then` method). The idea is that a third-party object may not be a promise, but promise-compatible: if it supports `.then`, that's enough to use it with `await`.
 
 Here's a demo `Thenable` class; the `await` below accepts its instances:
 
@@ -157,7 +163,7 @@ class Thenable {
     // resolve with this.num*2 after 1000ms
     setTimeout(() => resolve(this.num * 2), 1000); // (*)
   }
-};
+}
 
 async function f() {
   // waits for 1 second, then result becomes 2
@@ -185,7 +191,7 @@ class Waiter {
 
 new Waiter()
   .wait()
-  .then(alert); // 1
+  .then(alert); // 1 (this is the same as (result => alert(result)))
 ```
 The meaning is the same: it ensures that the returned value is a promise and enables `await`.
 
@@ -297,7 +303,7 @@ The `async` keyword before a function has two effects:
 
 The `await` keyword before a promise makes JavaScript wait until that promise settles, and then:
 
-1. If it's an error, the exception is generated — same as if `throw error` were called at that very place.
+1. If it's an error, an exception is generated — same as if `throw error` were called at that very place.
 2. Otherwise, it returns the result.
 
 Together they provide a great framework to write asynchronous code that is easy to both read and write.
diff --git a/1-js/12-generators-iterators/1-generators/01-pseudo-random-generator/solution.md b/1-js/12-generators-iterators/1-generators/01-pseudo-random-generator/solution.md
index af2ad0eed..4355d0cfc 100644
--- a/1-js/12-generators-iterators/1-generators/01-pseudo-random-generator/solution.md
+++ b/1-js/12-generators-iterators/1-generators/01-pseudo-random-generator/solution.md
@@ -3,7 +3,7 @@ function* pseudoRandom(seed) {
   let value = seed;
 
   while(true) {
-    value = value * 16807 % 2147483647
+    value = value * 16807 % 2147483647;
     yield value;
   }
 
diff --git a/1-js/12-generators-iterators/1-generators/article.md b/1-js/12-generators-iterators/1-generators/article.md
index 9be227ad9..55f6bf903 100644
--- a/1-js/12-generators-iterators/1-generators/article.md
+++ b/1-js/12-generators-iterators/1-generators/article.md
@@ -102,7 +102,7 @@ But usually the first syntax is preferred, as the star `*` denotes that it's a g
 
 As you probably already guessed looking at the `next()` method, generators are [iterable](info:iterable).
 
-We can get loop over values by `for..of`:
+We can loop over their values using `for..of`:
 
 ```js run
 function* generateSequence() {
@@ -314,11 +314,11 @@ alert(str); // 0..9A..Za..z
 
 A generator composition is a natural way to insert a flow of one generator into another. It doesn't use extra memory to store intermediate results.
 
-## "yield" is a two-way road
+## "yield" is a two-way street
 
 Until this moment, generators were similar to iterable objects, with a special syntax to generate values. But in fact they are much more powerful and flexible.
 
-That's because `yield` is a two-way road: it not only returns the result outside, but also can pass the value inside the generator.
+That's because `yield` is a two-way street: it not only returns the result to the outside, but also can pass the value inside the generator.
 
 To do so, we should call `generator.next(arg)`, with an argument. That argument becomes the result of `yield`.
 
@@ -347,7 +347,7 @@ generator.next(4); // --> pass the result into the generator
 2. Then, as shown at the picture above, the result of `yield` gets into the `question` variable in the calling code.
 3. On `generator.next(4)`, the generator resumes, and `4` gets in as the result: `let result = 4`.
 
-Please note, the outer code does not have to immediately call`next(4)`. It may take time. That's not a problem: the generator will wait.
+Please note, the outer code does not have to immediately call `next(4)`. It may take time. That's not a problem: the generator will wait.
 
 For instance:
 
@@ -448,6 +448,28 @@ try {
 
 If we don't catch the error there, then, as usual, it falls through to the outer calling code (if any) and, if uncaught, kills the script.
 
+## generator.return
+
+`generator.return(value)` finishes the generator execution and return the given `value`.
+
+```js
+function* gen() {
+  yield 1;
+  yield 2;
+  yield 3;
+}
+
+const g = gen();
+
+g.next();        // { value: 1, done: false }
+g.return('foo'); // { value: "foo", done: true }
+g.next();        // { value: undefined, done: true }
+```
+
+If we again use `generator.return()` in a completed generator, it will return that value again ([MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator/return)).
+
+Often we don't use it, as most of time we want to get all returning values, but it can be useful when we want to stop generator in a specific condition.
+
 ## Summary
 
 - Generators are created by generator functions `function* f(…) {…}`.
diff --git a/1-js/12-generators-iterators/2-async-iterators-generators/article.md b/1-js/12-generators-iterators/2-async-iterators-generators/article.md
index 5edcc6582..d4e9f7861 100644
--- a/1-js/12-generators-iterators/2-async-iterators-generators/article.md
+++ b/1-js/12-generators-iterators/2-async-iterators-generators/article.md
@@ -1,36 +1,48 @@
 
-# Async iterators and generators
+# Async iteration and generators
 
-Asynchronous iterators allow to iterate over data that comes asynchronously, on-demand. For instance, when we download something chunk-by-chunk over a network. Asynchronous generators make it even more convenient.
+Asynchronous iteration allow us to iterate over data that comes asynchronously, on-demand. Like, for instance, when we download something chunk-by-chunk over a network. And asynchronous generators make it even more convenient.
 
 Let's see a simple example first, to grasp the syntax, and then review a real-life use case.
 
-## Async iterators
+## Recall iterables
 
-Asynchronous iterators are similar to regular iterators, with a few syntactic differences.
+Let's recall the topic about iterables. 
 
-A "regular" iterable object, as described in the chapter <info:iterable>, looks like this:
+The idea is that we have an object, such as `range` here:
+```js
+let range = {
+  from: 1,
+  to: 5
+};
+```
+
+...And we'd like to use `for..of` loop on it, such as `for(value of range)`, to get values from `1` to `5`.
+
+In other words, we want to add an *iteration ability* to the object.
+
+That can be implemented using a special method with the name `Symbol.iterator`:
+
+- This method is called in by the `for..of` construct when the loop is started, and it should return an object with the `next` method.
+- For each iteration, the `next()` method is invoked for the next value.
+- The `next()` should return a value in the form `{done: true/false, value:<loop value>}`, where `done:true` means the end of the loop.
+
+Here's an implementation for the iterable `range`:
 
 ```js run
 let range = {
   from: 1,
   to: 5,
 
-  // for..of calls this method once in the very beginning
 *!*
-  [Symbol.iterator]() {
+  [Symbol.iterator]() { // called once, in the beginning of for..of
 */!*
-    // ...it returns the iterator object:
-    // onward, for..of works only with that object,
-    // asking it for next values using next()
     return {
       current: this.from,
       last: this.to,
 
-      // next() is called on each iteration by the for..of loop
 *!*
-      next() { // (2)
-        // it should return the value as an object {done:.., value :...}
+      next() { // called every iteration, to get the next value
 */!*
         if (this.current <= this.last) {
           return { done: false, value: this.current++ };
@@ -47,40 +59,44 @@ for(let value of range) {
 }
 ```
 
-If necessary, please refer to the [chapter about iterables](info:iterable) for details about regular iterators.
+If anything is unclear, please visit the chapter [](info:iterable), it gives all the details about regular iterables.
+
+## Async iterables
+
+Asynchronous iteration is needed when values come asynchronously: after `setTimeout` or another kind of delay. 
+
+The most common case is that the object needs to make a network request to deliver the next value, we'll see a real-life example of it a bit later.
+
+To make an object iterable asynchronously:
+
+1. Use `Symbol.asyncIterator` instead of `Symbol.iterator`.
+2. The `next()` method should return a promise (to be fulfilled with the next value).
+    - The `async` keyword handles it, we can simply make `async next()`.
+3. To iterate over such an object, we should use a `for await (let item of iterable)` loop.
+    - Note the `await` word.
 
-To make the object iterable asynchronously:
-1. We need to use `Symbol.asyncIterator` instead of `Symbol.iterator`.
-2. `next()` should return a promise.
-3. To iterate over such an object, we should use `for await (let item of iterable)` loop.
+As a starting example, let's make an iterable `range` object, similar like the one before, but now it will return values asynchronously, one per second.
 
-Let's make an iterable `range` object, like the one before, but now it will return values asynchronously, one per second:
+All we need to do is to perform a few replacements in the code above:
 
 ```js run
 let range = {
   from: 1,
   to: 5,
 
-  // for await..of calls this method once in the very beginning
 *!*
   [Symbol.asyncIterator]() { // (1)
 */!*
-    // ...it returns the iterator object:
-    // onward, for await..of works only with that object,
-    // asking it for next values using next()
     return {
       current: this.from,
       last: this.to,
 
-      // next() is called on each iteration by the for await..of loop
 *!*
       async next() { // (2)
-        // it should return the value as an object {done:.., value :...}
-        // (automatically wrapped into a promise by async)
 */!*
 
 *!*
-        // can use await inside, do async stuff:
+        // note: we can use "await" inside the async next:
         await new Promise(resolve => setTimeout(resolve, 1000)); // (3)
 */!*
 
@@ -109,10 +125,10 @@ As we can see, the structure is similar to regular iterators:
 
 1. To make an object asynchronously iterable, it must have a method `Symbol.asyncIterator` `(1)`.
 2. This method must return the object with `next()` method returning a promise `(2)`.
-3. The `next()` method doesn't have to be `async`, it may be a regular method returning a promise, but `async` allows to use `await`, so that's convenient. Here we just delay for a second `(3)`.
+3. The `next()` method doesn't have to be `async`, it may be a regular method returning a promise, but `async` allows us to use `await`, so that's convenient. Here we just delay for a second `(3)`.
 4. To iterate, we use `for await(let value of range)` `(4)`, namely add "await" after "for". It calls `range[Symbol.asyncIterator]()` once, and then its `next()` for values.
 
-Here's a small cheatsheet:
+Here's a small table with the differences:
 
 |       | Iterators | Async iterators |
 |-------|-----------|-----------------|
@@ -128,14 +144,20 @@ For instance, a spread syntax won't work:
 alert( [...range] ); // Error, no Symbol.iterator
 ```
 
-That's natural, as it expects to find `Symbol.iterator`, same as `for..of` without `await`. Not `Symbol.asyncIterator`.
+That's natural, as it expects to find `Symbol.iterator`, not `Symbol.asyncIterator`.
+
+It's also the case for `for..of`: the syntax without `await` needs `Symbol.iterator`.
 ````
 
-## Async generators
+## Recall generators
+
+Now let's recall generators, as they allow to make iteration code much shorter. Most of the time, when we'd like to make an iterable, we'll use generators.
+
+For sheer simplicity, omitting some important stuff, they are "functions that generate (yield) values". They are explained in detail in the chapter [](info:generators).
 
-As we already know, JavaScript also supports generators, and they are iterable.
+Generators are labelled with `function*` (note the star) and use `yield` to generate a value, then we can use `for..of` to loop over them.
 
-Let's recall a sequence generator from the chapter [](info:generators). It generates a sequence of values from `start` to `end`:
+This example generates a sequence of values from `start` to `end`:
 
 ```js run
 function* generateSequence(start, end) {
@@ -149,11 +171,54 @@ for(let value of generateSequence(1, 5)) {
 }
 ```
 
-In regular generators we can't use `await`. All values must come synchronously: there's no place for delay in `for..of`, it's a synchronous construct.
+As we already know, to make an object iterable, we should add `Symbol.iterator` to it.
+
+```js
+let range = {
+  from: 1,
+  to: 5,
+*!*
+  [Symbol.iterator]() {
+    return <object with next to make range iterable>
+  }
+*/!*
+}
+```
+
+A common practice for `Symbol.iterator` is to return a generator, it makes the code shorter, as you can see:
+
+```js run
+let range = {
+  from: 1,
+  to: 5,
+
+  *[Symbol.iterator]() { // a shorthand for [Symbol.iterator]: function*()
+    for(let value = this.from; value <= this.to; value++) {
+      yield value;
+    }
+  }
+};
+
+for(let value of range) {
+  alert(value); // 1, then 2, then 3, then 4, then 5
+}
+```
+
+Please see the chapter [](info:generators) if you'd like more details.
 
-But what if we need to use `await` in the generator body? To perform network requests, for instance.
+In regular generators we can't use `await`. All values must come synchronously, as required by the `for..of` construct.
 
-No problem, just prepend it with `async`, like this:
+What if we'd like to generate values asynchronously? From network requests, for instance. 
+
+Let's switch to asynchronous generators to make it possible.
+
+## Async generators (finally)
+
+For most practical applications, when we'd like to make an object that asynchronously generates a sequence of values, we can use an asynchronous generator.
+
+The syntax is simple: prepend `function*` with `async`. That makes the generator asynchronous.
+
+And then use `for await (...)` to iterate over it, like this:
 
 ```js run
 *!*async*/!* function* generateSequence(start, end) {
@@ -161,7 +226,7 @@ No problem, just prepend it with `async`, like this:
   for (let i = start; i <= end; i++) {
 
 *!*
-    // yay, can use await!
+    // Wow, can use await!
     await new Promise(resolve => setTimeout(resolve, 1000));
 */!*
 
@@ -174,72 +239,43 @@ No problem, just prepend it with `async`, like this:
 
   let generator = generateSequence(1, 5);
   for *!*await*/!* (let value of generator) {
-    alert(value); // 1, then 2, then 3, then 4, then 5
+    alert(value); // 1, then 2, then 3, then 4, then 5 (with delay between)
   }
 
 })();
 ```
 
-Now we have the async generator, iterable with `for await...of`.
+As the generator is asynchronous, we can use `await` inside it, rely on promises, perform network requests and so on.
 
-It's indeed very simple. We add the `async` keyword, and the generator now can use `await` inside of it, rely on promises and other async functions.
+````smart header="Under-the-hood difference"
+Technically, if you're an advanced reader who remembers the details about generators, there's an internal difference.
 
-Technically, another difference of an async generator is that its `generator.next()` method is now asynchronous also, it returns promises.
+For async generators, the `generator.next()` method is asynchronous, it returns promises.
 
 In a regular generator we'd use `result = generator.next()` to get values. In an async generator, we should add `await`, like this:
 
 ```js
 result = await generator.next(); // result = {value: ..., done: true/false}
 ```
+That's why async generators work with `for await...of`.
+````
 
-## Async iterables
-
-As we already know, to make an object iterable, we should add `Symbol.iterator` to it.
-
-```js
-let range = {
-  from: 1,
-  to: 5,
-*!*
-  [Symbol.iterator]() {
-    return <object with next to make range iterable>
-  }
-*/!*
-}
-```
-
-A common practice for `Symbol.iterator` is to return a generator, rather than a plain object with `next` as in the example before.
-
-Let's recall an example from the chapter [](info:generators):
-
-```js run
-let range = {
-  from: 1,
-  to: 5,
-
-  *[Symbol.iterator]() { // a shorthand for [Symbol.iterator]: function*()
-    for(let value = this.from; value <= this.to; value++) {
-      yield value;
-    }
-  }
-};
+### Async iterable range
 
-for(let value of range) {
-  alert(value); // 1, then 2, then 3, then 4, then 5
-}
-```
+Regular generators can be used as `Symbol.iterator` to make the iteration code shorter.
 
-Here a custom object `range` is iterable, and the generator `*[Symbol.iterator]` implements the logic for listing values.
+Similar to that, async generators can be used as `Symbol.asyncIterator` to implement the asynchronous iteration.
 
-If we'd like to add async actions into the generator, then we should replace `Symbol.iterator` with async `Symbol.asyncIterator`:
+For instance, we can make the `range` object generate values asynchronously, once per second, by replacing synchronous `Symbol.iterator` with asynchronous `Symbol.asyncIterator`:
 
 ```js run
 let range = {
   from: 1,
   to: 5,
 
+  // this line is same as [Symbol.asyncIterator]: async function*() {
 *!*
-  async *[Symbol.asyncIterator]() { // same as [Symbol.asyncIterator]: async function*()
+  async *[Symbol.asyncIterator]() {
 */!*
     for(let value = this.from; value <= this.to; value++) {
 
@@ -262,31 +298,39 @@ let range = {
 
 Now values come with a delay of 1 second between them.
 
-## Real-life example
+```smart
+Technically, we can add both `Symbol.iterator` and `Symbol.asyncIterator` to the object, so it's both synchronously (`for..of`) and asynchronously (`for await..of`) iterable.
+
+In practice though, that would be a weird thing to do.
+```
+
+## Real-life example: paginated data
 
-So far we've seen simple examples, to gain basic understanding. Now let's review a real-life use case.
+So far we've seen basic examples, to gain understanding. Now let's review a real-life use case.
 
 There are many online services that deliver paginated data. For instance, when we need a list of users, a request returns a pre-defined count (e.g. 100 users) - "one page", and provides a URL to the next page.
 
-This pattern is very common. It's not about users, but just about anything. For instance, GitHub allows to retrieve commits in the same, paginated fashion:
+This pattern is very common. It's not about users, but just about anything. 
 
-- We should make a request to URL in the form `https://api.github.com/repos/<repo>/commits`.
+For instance, GitHub allows us to retrieve commits in the same, paginated fashion:
+
+- We should make a request to `fetch` in the form `https://api.github.com/repos/<repo>/commits`.
 - It responds with a JSON of 30 commits, and also provides a link to the next page in the `Link` header.
 - Then we can use that link for the next request, to get more commits, and so on.
 
-But we'd like to have a simpler API: an iterable object with commits, so that we could go over them like this:
+For our code, we'd like to have a simpler way to get commits.
 
-```js
-let repo = 'javascript-tutorial/en.javascript.info'; // GitHub repository to get commits from
+Let's make a function `fetchCommits(repo)` that gets commits for us, making requests whenever needed. And let it care about all pagination stuff. For us it'll be a simple async iteration `for await..of`.
+
+So the usage will be like this:
 
-for await (let commit of fetchCommits(repo)) {
+```js
+for await (let commit of fetchCommits("username/repository")) {
   // process commit
 }
 ```
 
-We'd like to make a function `fetchCommits(repo)` that gets commits for us, making requests whenever needed. And let it care about all pagination stuff. For us it'll be a simple `for await..of`.
-
-With async generators that's pretty easy to implement:
+Here's such function, implemented as async generator:
 
 ```js
 async function* fetchCommits(repo) {
@@ -294,14 +338,14 @@ async function* fetchCommits(repo) {
 
   while (url) {
     const response = await fetch(url, { // (1)
-      headers: {'User-Agent': 'Our script'}, // github requires user-agent header
+      headers: {'User-Agent': 'Our script'}, // github needs any user-agent header
     });
 
     const body = await response.json(); // (2) response is JSON (array of commits)
 
     // (3) the URL of the next page is in the headers, extract it
     let nextPage = response.headers.get('Link').match(/<(.*?)>; rel="next"/);
-    nextPage = nextPage && nextPage[1];
+    nextPage = nextPage?.[1];
 
     url = nextPage;
 
@@ -312,10 +356,16 @@ async function* fetchCommits(repo) {
 }
 ```
 
-1. We use the browser [fetch](info:fetch) method to download from a remote URL. It allows to supply authorization and other headers if needed, here GitHub requires `User-Agent`.
-2. The fetch result is parsed as JSON, that's again a `fetch`-specific method.
-3. We should get the next page URL from the `Link` header of the response. It has a special format, so we use a regexp for that. The next page URL may look like `https://api.github.com/repositories/93253246/commits?page=2`, it's generated by GitHub itself.
-4. Then we yield all commits received, and when they finish -- the next `while(url)` iteration will trigger, making one more request.
+More explanations about how it works:
+
+1. We use the browser [fetch](info:fetch) method to download the commits.
+
+    - The initial URL is `https://api.github.com/repos/<repo>/commits`, and the next page will be in the `Link` header of the response.
+    - The `fetch` method allows us to supply authorization and other headers if needed -- here GitHub requires `User-Agent`.
+2. The commits are returned in JSON format.
+3. We should get the next page URL from the `Link` header of the response. It has a special format, so we use a regular expression for that (we will learn this feature in [Regular expressions](info:regular-expressions)).
+    - The next page URL may look like `https://api.github.com/repositories/93253246/commits?page=2`. It's generated by GitHub itself.
+4. Then we yield the received commits one by one, and when they finish, the next `while(url)` iteration will trigger, making one more request.
 
 An example of use (shows commit authors in console):
 
@@ -334,9 +384,13 @@ An example of use (shows commit authors in console):
   }
 
 })();
+
+// Note: If you are running this in an external sandbox, you'll need to paste here the function fetchCommits described above 
 ```
 
-That's just what we wanted. The internal mechanics of paginated requests is invisible from the outside. For us it's just an async generator that returns commits.
+That's just what we wanted. 
+
+The internal mechanics of paginated requests is invisible from the outside. For us it's just an async generator that returns commits.
 
 ## Summary
 
@@ -360,4 +414,4 @@ Syntax differences between async and regular generators:
 
 In web-development we often meet streams of data, when it flows chunk-by-chunk. For instance, downloading or uploading a big file.
 
-We can use async generators to process such data. It's also noteworthy that in some environments, such as browsers, there's also another API called Streams, that provides special interfaces to work with such streams, to transform the data and to pass it from one stream to another (e.g. download from one place and immediately send elsewhere).
+We can use async generators to process such data. It's also noteworthy that in some environments, like in browsers, there's also another API called Streams, that provides special interfaces to work with such streams, to transform the data and to pass it from one stream to another (e.g. download from one place and immediately send elsewhere).
diff --git a/1-js/12-generators-iterators/2-async-iterators-generators/head.html b/1-js/12-generators-iterators/2-async-iterators-generators/head.html
index 74d66a8b8..03f21e2bd 100644
--- a/1-js/12-generators-iterators/2-async-iterators-generators/head.html
+++ b/1-js/12-generators-iterators/2-async-iterators-generators/head.html
@@ -11,7 +11,7 @@
 
       // the URL of the next page is in the headers, extract it
       let nextPage = response.headers.get('Link').match(/<(.*?)>; rel="next"/);
-      nextPage = nextPage && nextPage[1];
+      nextPage = nextPage?.[1];
 
       url = nextPage;
 
diff --git a/1-js/13-modules/01-modules-intro/article.md b/1-js/13-modules/01-modules-intro/article.md
index f21367c88..5ad70d151 100644
--- a/1-js/13-modules/01-modules-intro/article.md
+++ b/1-js/13-modules/01-modules-intro/article.md
@@ -1,30 +1,30 @@
 
 # Modules, introduction
 
-As our application grows bigger, we want to split it into multiple files, so called "modules". A module usually contains a class or a library of functions.
+As our application grows bigger, we want to split it into multiple files, so called "modules". A module may contain a class or a library of functions for a specific purpose.
 
 For a long time, JavaScript existed without a language-level module syntax. That wasn't a problem, because initially scripts were small and simple, so there was no need.
 
 But eventually scripts became more and more complex, so the community invented a variety of ways to organize code into modules, special libraries to load modules on demand.
 
-For instance:
+To name some (for historical reasons):
 
-- [AMD](https://en.wikipedia.org/wiki/Asynchronous_module_definition) -- one of the most ancient module systems, initially implemented by the library [require.js](http://requirejs.org/).
-- [CommonJS](http://wiki.commonjs.org/wiki/Modules/1.1) -- the module system created for Node.js server.
+- [AMD](https://en.wikipedia.org/wiki/Asynchronous_module_definition) -- one of the most ancient module systems, initially implemented by the library [require.js](https://requirejs.org/).
+- [CommonJS](https://wiki.commonjs.org/wiki/Modules/1.1) -- the module system created for Node.js server.
 - [UMD](https://github.com/umdjs/umd) -- one more module system, suggested as a universal one, compatible with AMD and CommonJS.
 
-Now all these slowly become a part of history, but we still can find them in old scripts.
+Now these all slowly became a part of history, but we still can find them in old scripts.
 
-The language-level module system appeared in the standard in 2015, gradually evolved since then, and is now supported by all major browsers and in Node.js. So we'll study it from now on.
+The language-level module system appeared in the standard in 2015, gradually evolved since then, and is now supported by all major browsers and in Node.js. So we'll study the modern JavaScript modules from now on.
 
 ## What is a module?
 
-A module is just a file. One script is one module.
+A module is just a file. One script is one module. As simple as that.
 
 Modules can load each other and use special directives `export` and `import` to interchange functionality, call functions of one module from another one:
 
 - `export` keyword labels variables and functions that should be accessible from outside the current module.
-- `import` allows to import functionality from other modules.
+- `import` allows the import of functionality from other modules.
 
 For instance, if we have a file `sayHi.js` exporting a function:
 
@@ -45,7 +45,7 @@ alert(sayHi); // function...
 sayHi('John'); // Hello, John!
 ```
 
-The `import` directive loads the module by path `./sayHi.js` relative the current file and assigns exported function `sayHi` to the corresponding variable.
+The `import` directive loads the module by path `./sayHi.js` relative to the current file, and assigns exported function `sayHi` to the corresponding variable.
 
 Let's run the example in-browser.
 
@@ -57,6 +57,10 @@ Like this:
 
 The browser automatically fetches and evaluates the imported module (and its imports if needed), and then runs the script.
 
+```warn header="Modules work only via HTTP(s), not locally"
+If you try to open a web-page locally, via `file://` protocol, you'll find that `import/export` directives don't work. Use a local web-server, such as [static-server](https://www.npmjs.com/package/static-server#getting-started) or use the "live server" capability of your editor, such as VS Code [Live Server Extension](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer) to test modules.
+```
+
 ## Core module features
 
 What's different in modules, compared to "regular" scripts?
@@ -65,7 +69,7 @@ There are core features, valid both for browser and server-side JavaScript.
 
 ### Always "use strict"
 
-Modules always `use strict`, by default. E.g. assigning to an undeclared variable will give an error.
+Modules always work in strict mode. E.g. assigning to an undeclared variable will give an error.
 
 ```html run
 <script type="module">
@@ -77,19 +81,24 @@ Modules always `use strict`, by default. E.g. assigning to an undeclared variabl
 
 Each module has its own top-level scope. In other words, top-level variables and functions from a module are not seen in other scripts.
 
-In the example below, two scripts are imported, and `hello.js` tries to use `user` variable declared in `user.js`, and fails:
+In the example below, two scripts are imported, and `hello.js` tries to use `user` variable declared in `user.js`. It fails, because it's a separate module (you'll see the error in the console):
 
 [codetabs src="scopes" height="140" current="index.html"]
 
-Modules are expected to `export` what they want to be accessible from outside and `import` what they need.
+Modules should `export` what they want to be accessible from outside and `import` what they need.
 
-So we should import `user.js` into `hello.js` and get the required functionality from it instead of relying on global variables.
+- `user.js` should export the `user` variable.
+- `hello.js` should import it from `user.js` module.
 
-That's the correct variant:
+In other words, with modules we use import/export instead of relying on global variables.
+
+This is the correct variant:
 
 [codetabs src="scopes-working" height="140" current="hello.js"]
 
-In the browser, independent top-level scope also exists for each `<script type="module">`:
+In the browser, if we talk about HTML pages, independent top-level scope also exists for each `<script type="module">`.
+
+Here are two scripts on the same page, both `type="module"`. They don't see each other's top-level variables:
 
 ```html run
 <script type="module">
@@ -104,13 +113,21 @@ In the browser, independent top-level scope also exists for each `<script type="
 </script>
 ```
 
-If we really need to make a window-level global variable, we can explicitly assign it to `window` and access as `window.user`. But that's an exception requiring a good reason.
+```smart
+In the browser, we can make a variable window-level global by explicitly assigning it to a `window` property, e.g. `window.user = "John"`. 
+
+Then all scripts will see it, both with `type="module"` and without it. 
+
+That said, making such global variables is frowned upon. Please try to avoid them.
+```
 
 ### A module code is evaluated only the first time when imported
 
-If the same module is imported into multiple other places, its code is executed only the first time, then exports are given to all importers.
+If the same module is imported into multiple other modules, its code is executed only once, upon the first import. Then its exports are given to all further importers.
 
-That has important consequences. Let's see that on examples.
+The one-time evaluation has important consequences, that we should be aware of. 
+
+Let's see a couple of examples.
 
 First, if executing a module code brings side-effects, like showing a message, then importing it multiple times will trigger it only once -- the first time:
 
@@ -129,9 +146,11 @@ import `./alert.js`; // Module is evaluated!
 import `./alert.js`; // (shows nothing)
 ```
 
-In practice, top-level module code is mostly used for initialization, creation of internal data structures, and if we want something to be reusable -- export it.
+The second import shows nothing, because the module has already been evaluated.
+
+There's a rule: top-level module code should be used for initialization, creation of module-specific internal data structures. If we need to make something callable multiple times - we should export it as a function, like we did with `sayHi` above.
 
-Now, a more advanced example.
+Now, let's consider a deeper example.
 
 Let's say, a module exports an object:
 
@@ -156,54 +175,67 @@ import {admin} from './admin.js';
 alert(admin.name); // Pete
 
 *!*
-// Both 1.js and 2.js imported the same object
+// Both 1.js and 2.js reference the same admin object
 // Changes made in 1.js are visible in 2.js
 */!*
 ```
 
-So, let's reiterate -- the module is executed only once. Exports are generated, and then they are shared between importers, so if something changes the `admin` object, other modules will see that.
+As you can see, when `1.js` changes the `name` property in the imported `admin`, then `2.js` can see the new `admin.name`.
 
-Such behavior allows to *configure* modules on first import. We can setup its properties once, and then in further imports it's ready.
+That's exactly because the module is executed only once. Exports are generated, and then they are shared between importers, so if something changes the `admin` object, other importers will see that.
 
-For instance, the `admin.js` module may provide certain functionality, but expect the credentials to come into the `admin` object from outside:
+**Such behavior is actually very convenient, because it allows us to *configure* modules.**
+
+In other words, a module can provide a generic functionality that needs a setup. E.g. authentication needs credentials. Then it can export a configuration object expecting the outer code to assign to it.
+
+Here's the classical pattern:
+1. A module exports some means of configuration, e.g. a configuration object.
+2. On the first import we initialize it, write to its properties. The top-level application script may do that.
+3. Further imports use the module.
+
+For instance, the `admin.js` module may provide certain functionality (e.g. authentication), but expect the credentials to come into the `config` object from outside:
 
 ```js
 // 📁 admin.js
-export let admin = { };
+export let config = { };
 
 export function sayHi() {
-  alert(`Ready to serve, ${admin.name}!`);
+  alert(`Ready to serve, ${config.user}!`);
 }
 ```
 
-In `init.js`, the first script of our app, we set `admin.name`. Then everyone will see it, including calls made from inside `admin.js` itself:
+Here, `admin.js` exports the `config` object (initially empty, but may have default properties too).
+
+Then in `init.js`, the first script of our app, we import `config` from it and set `config.user`:
 
 ```js
 // 📁 init.js
-import {admin} from './admin.js';
-admin.name = "Pete";
+import {config} from './admin.js';
+config.user = "Pete";
 ```
 
-Another module can also see `admin.name`:
+...Now the module `admin.js` is configured. 
 
-```js
-// 📁 other.js
-import {admin, sayHi} from './admin.js';
+Further importers can call it, and it correctly shows the current user:
 
-alert(admin.name); // *!*Pete*/!*
+```js
+// 📁 another.js
+import {sayHi} from './admin.js';
 
 sayHi(); // Ready to serve, *!*Pete*/!*!
 ```
 
+
 ### import.meta
 
 The object `import.meta` contains the information about the current module.
 
-Its content depends on the environment. In the browser, it contains the url of the script, or a current webpage url if inside HTML:
+Its content depends on the environment. In the browser, it contains the URL of the script, or a current webpage URL if inside HTML:
 
 ```html run height=0
 <script type="module">
-  alert(import.meta.url); // script url (url of the html page for an inline script)
+  alert(import.meta.url); // script URL
+  // for an inline script - the URL of the current HTML-page
 </script>
 ```
 
@@ -229,7 +261,7 @@ Compare it to non-module scripts, where `this` is a global object:
 
 There are also several browser-specific differences of scripts with `type="module"` compared to regular ones.
 
-You may want skip this section for now if you're reading for the first time, or if you don't use JavaScript in a browser.
+You may want to skip this section for now if you're reading for the first time, or if you don't use JavaScript in a browser.
 
 ### Module scripts are deferred
 
@@ -240,7 +272,7 @@ In other words:
 - module scripts wait until the HTML document is fully ready (even if they are tiny and load faster than HTML), and then run.
 - relative order of scripts is maintained: scripts that go first in the document, execute first.
 
-As a side-effect, module scripts always "see" the fully loaded HTML-page, including HTML elements below them.
+As a side effect, module scripts always "see" the fully loaded HTML-page, including HTML elements below them.
 
 For instance:
 
@@ -256,7 +288,7 @@ Compare to regular script below:
 
 <script>
 *!*
-  alert(typeof button); // Error: button is undefined, the script can't see elements below
+  alert(typeof button); // button is undefined, the script can't see elements below
 */!*
   // regular scripts run immediately, before the rest of the page is processed
 </script>
@@ -268,11 +300,11 @@ Please note: the second script actually runs before the first! So we'll see `und
 
 That's because modules are deferred, so we wait for the document to be processed. The regular script runs immediately, so we see its output first.
 
-When using modules, we should be aware that HTML-page shows up as it loads, and JavaScript modules run after that, so the user may see the page before the JavaScript application is ready. Some functionality may not work yet. We should put "loading indicators", or otherwise ensure that the visitor won't be confused by that.
+When using modules, we should be aware that the HTML page shows up as it loads, and JavaScript modules run after that, so the user may see the page before the JavaScript application is ready. Some functionality may not work yet. We should put "loading indicators", or otherwise ensure that the visitor won't be confused by that.
 
 ### Async works on inline scripts
 
-For non-module scripts, `async` attribute only works on external scripts. Async scripts run immediately when ready, independently of other scripts or the HTML document.
+For non-module scripts, the `async` attribute only works on external scripts. Async scripts run immediately when ready, independently of other scripts or the HTML document.
 
 For module scripts, it works on inline scripts as well.
 
diff --git a/1-js/13-modules/02-import-export/article.md b/1-js/13-modules/02-import-export/article.md
index cb45b1fdf..1b5649c69 100644
--- a/1-js/13-modules/02-import-export/article.md
+++ b/1-js/13-modules/02-import-export/article.md
@@ -2,7 +2,7 @@
 
 Export and import directives have several syntax variants.
 
-In the previous chapter we saw a simple use, now let's explore more examples.
+In the previous article we saw a simple use, now let's explore more examples.
 
 ## Export before declarations
 
@@ -46,7 +46,7 @@ Also, we can put `export` separately.
 
 Here we first declare, and then export:
 
-```js  
+```js
 // 📁 say.js
 function sayHi(user) {
   alert(`Hello, ${user}!`);
@@ -93,25 +93,14 @@ At first sight, "import everything" seems such a cool thing, short to write, why
 
 Well, there are few reasons.
 
-1. Modern build tools ([webpack](http://webpack.github.io) and others) bundle modules together and optimize them to speedup loading and remove unused stuff.
-
-    Let's say, we added a 3rd-party library `say.js` to our project with many functions:
-    ```js
-    // 📁 say.js
-    export function sayHi() { ... }
-    export function sayBye() { ... }
-    export function becomeSilent() { ... }
-    ```
+1. Explicitly listing what to import gives shorter names: `sayHi()` instead of `say.sayHi()`.
+2. Explicit list of imports gives better overview of the code structure: what is used and where. It makes code support and refactoring easier.
 
-    Now if we only use one of `say.js` functions in our project:
-    ```js
-    // 📁 main.js
-    import {sayHi} from './say.js';
-    ```
-    ...Then the optimizer will see that and remove the other functions from the bundled code, thus making the build smaller. That is called "tree-shaking".
+```smart header="Don't be afraid to import too much"
+Modern build tools, such as [webpack](https://webpack.js.org/) and others, bundle modules together and optimize them to speedup loading. They also remove unused imports.
 
-2. Explicitly listing what to import gives shorter names: `sayHi()` instead of `say.sayHi()`.
-3. Explicit list of imports gives better overview of the code structure: what is used and where. It makes code support and refactoring easier.
+For instance, if you `import * as library` from a huge code library, and then use only few methods, then unused ones [will not be included](https://github.com/webpack/webpack/tree/main/examples/harmony-unused#examplejs) into the optimized bundle.
+```
 
 ## Import "as"
 
@@ -162,7 +151,7 @@ Mostly, the second approach is preferred, so that every "thing" resides in its o
 
 Naturally, that requires a lot of files, as everything wants its own module, but that's not a problem at all. Actually, code navigation becomes easier if files are well-named and structured into folders.
 
-Modules provide special `export default` ("the default export") syntax to make the "one thing per module" way look better.
+Modules provide a special `export default` ("the default export") syntax to make the "one thing per module" way look better.
 
 Put `export default` before the entity to export:
 
@@ -216,15 +205,15 @@ export default function(user) { // no function name
 export default ['Jan', 'Feb', 'Mar','Apr', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
 ```
 
-Not giving a name is fine, because `export default` is only one per file, so `import` without curly braces knows what to import.
+Not giving a name is fine, because there is only one `export default` per file, so `import` without curly braces knows what to import.
 
-Without `default`, such export would give an error:
+Without `default`, such an export would give an error:
 
 ```js
 export class { // Error! (non-default export needs a name)
   constructor() {}
 }
-```     
+```
 
 ### The "default" name
 
@@ -241,7 +230,7 @@ function sayHi(user) {
 export {sayHi as default};
 ```
 
-Or, another situation, let's say a module `user.js` exports one main "default" thing and a few named ones (rarely the case, but happens):
+Or, another situation, let's say a module `user.js` exports one main "default" thing, and a few named ones (rarely the case, but it happens):
 
 ```js
 // 📁 user.js
@@ -277,9 +266,9 @@ new User('John');
 
 ### A word against default exports
 
-Named exports are explicit. They exactly name what they import, so we have that information from them, that's a good thing.
+Named exports are explicit. They exactly name what they import, so we have that information from them; that's a good thing.
 
-Named exports enforce us to use exactly the right name to import:
+Named exports force us to use exactly the right name to import:
 
 ```js
 import {User} from './user.js';
@@ -321,12 +310,12 @@ export {default as User} from './user.js'; // re-export default
 
 Why would that be needed? Let's see a practical use case.
 
-Imagine, we're writing a "package": a folder with a lot of modules, with some of the functionality exported outside (tools like NPM allow to publish and distribute such packages), and many modules are just "helpers", for the internal use in other package modules.
+Imagine, we're writing a "package": a folder with a lot of modules, with some of the functionality exported outside (tools like NPM allow us to publish and distribute such packages, but we don't have to use them), and many modules are just "helpers", for internal use in other package modules.
 
 The file structure could be like this:
 ```
 auth/
-    index.js  
+    index.js
     user.js
     helpers.js
     tests/
@@ -337,13 +326,19 @@ auth/
         ...
 ```
 
-We'd like to expose the package functionality via a single entry point, the "main file" `auth/index.js`, to be used like this:
+We'd like to expose the package functionality via a single entry point.
+
+In other words, a person who would like to use our package, should import only from the "main file" `auth/index.js`.
+
+Like this:
 
 ```js
 import {login, logout} from 'auth/index.js'
 ```
 
-The idea is that outsiders, developers who use our package, should not meddle with its internal structure, search for files inside our package folder. We export only what's necessary in `auth/index.js` and keep the rest hidden from prying eyes.
+The "main file", `auth/index.js` exports all the functionality that we'd like to provide in our package.
+
+The idea is that outsiders, other programmers who use our package, should not meddle with its internal structure, search for files inside our package folder. We export only what's necessary in `auth/index.js` and keep the rest hidden from prying eyes.
 
 As the actual exported functionality is scattered among the package, we can import it into `auth/index.js` and export from it:
 
@@ -366,19 +361,21 @@ The syntax `export ... from ...` is just a shorter notation for such import-expo
 
 ```js
 // 📁 auth/index.js
-// import login/logout and immediately export them
+// re-export login/logout
 export {login, logout} from './helpers.js';
 
-// import default as User and export it
+// re-export the default export as User
 export {default as User} from './user.js';
 ...
 ```
 
+The notable difference of `export ... from` compared to `import/export` is that re-exported modules aren't available in the current file. So inside the above example of `auth/index.js` we can't use re-exported `login/logout` functions.
+
 ### Re-exporting the default export
 
 The default export needs separate handling when re-exporting.
 
-Let's say we have `user.js`, and we'd like to re-export class `User` from it:
+Let's say we have `user.js` with the `export default class User` and would like to re-export it:
 
 ```js
 // 📁 user.js
@@ -387,23 +384,25 @@ export default class User {
 }
 ```
 
-1. `export User from './user.js'` won't work. What can go wrong?... But that's a syntax error!
+We can come across two problems with it:
+
+1. `export User from './user.js'` won't work. That would lead to a syntax error.
 
-    To re-export the default export, we have to write `export {default as User}`, as in the example above.    
+    To re-export the default export, we have to write `export {default as User}`, as in the example above.
 
 2. `export * from './user.js'` re-exports only named exports, but ignores the default one.
 
-    If we'd like to re-export both named and the default export, then two statements are needed:
+    If we'd like to re-export both named and default exports, then two statements are needed:
     ```js
     export * from './user.js'; // to re-export named exports
     export {default} from './user.js'; // to re-export the default export
     ```
 
-Such oddities of re-exporting the default export are one of the reasons why some developers don't like them.
+Such oddities of re-exporting a default export are one of the reasons why some developers don't like default exports and prefer named ones.
 
 ## Summary
 
-Here are all types of `export` that we covered in this and previous chapters.
+Here are all types of `export` that we covered in this and previous articles.
 
 You can check yourself by reading them and recalling what they mean:
 
@@ -418,14 +417,14 @@ You can check yourself by reading them and recalling what they mean:
 
 Import:
 
-- Named exports from module:
+- Importing named exports:
   - `import {x [as y], ...} from "module"`
-- Default export:  
+- Importing the default export:
   - `import x from "module"`
   - `import {default as x} from "module"`
-- Everything:
+- Import all:
   - `import * as obj from "module"`
-- Import the module (its code runs), but do not assign it to a variable:
+- Import the module (its code runs), but do not assign any of its exports to variables:
   - `import "module"`
 
 We can put `import/export` statements at the top or at the bottom of a script, that doesn't matter.
@@ -439,7 +438,7 @@ sayHi();
 import {sayHi} from './say.js'; // import at the end of the file
 ```
 
-In practice imports are usually at the start of the file, but that's only for better convenience.
+In practice imports are usually at the start of the file, but that's only for more convenience.
 
 **Please note that import/export statements don't work if inside `{...}`.**
 
@@ -452,4 +451,4 @@ if (something) {
 
 ...But what if we really need to import something conditionally? Or at the right time? Like, load a module upon request, when it's really needed?
 
-We'll see dynamic imports in the next chapter.
+We'll see dynamic imports in the next article.
diff --git a/1-js/13-modules/03-modules-dynamic-imports/article.md b/1-js/13-modules/03-modules-dynamic-imports/article.md
index b638fd347..e48144a3e 100644
--- a/1-js/13-modules/03-modules-dynamic-imports/article.md
+++ b/1-js/13-modules/03-modules-dynamic-imports/article.md
@@ -94,5 +94,5 @@ Dynamic imports work in regular scripts, they don't require `script type="module
 ```smart
 Although `import()` looks like a function call, it's a special syntax that just happens to use parentheses (similar to `super()`).
 
-So we can't copy `import` to a variable or use `call/apply` with it. That's not a function.
+So we can't copy `import` to a variable or use `call/apply` with it. It's not a function.
 ```
diff --git a/1-js/99-js-misc/01-proxy/01-error-nonexisting/solution.md b/1-js/99-js-misc/01-proxy/01-error-nonexisting/solution.md
index 357a57313..9db69cb2f 100644
--- a/1-js/99-js-misc/01-proxy/01-error-nonexisting/solution.md
+++ b/1-js/99-js-misc/01-proxy/01-error-nonexisting/solution.md
@@ -19,5 +19,5 @@ function wrap(target) {
 user = wrap(user);
 
 alert(user.name); // John
-alert(user.age); // ReferenceError: Property doesn't exist "age"
+alert(user.age); // ReferenceError: Property doesn't exist: "age"
 ```
diff --git a/1-js/99-js-misc/01-proxy/01-error-nonexisting/task.md b/1-js/99-js-misc/01-proxy/01-error-nonexisting/task.md
index 827cf35e3..47985e1a7 100644
--- a/1-js/99-js-misc/01-proxy/01-error-nonexisting/task.md
+++ b/1-js/99-js-misc/01-proxy/01-error-nonexisting/task.md
@@ -1,8 +1,8 @@
-# Error on reading non-existant property
+# Error on reading non-existent property
 
-Usually, an attempt to read a non-existant property returns `undefined`.
+Usually, an attempt to read a non-existent property returns `undefined`.
 
-Create a proxy that throws an error for an attempt to read of a non-existant property instead.
+Create a proxy that throws an error for an attempt to read of a non-existent property instead.
 
 That can help to detect programming mistakes early.
 
@@ -27,6 +27,6 @@ user = wrap(user);
 
 alert(user.name); // John
 *!*
-alert(user.age); // ReferenceError: Property doesn't exist "age"
+alert(user.age); // ReferenceError: Property doesn't exist: "age"
 */!*
 ```
diff --git a/1-js/99-js-misc/01-proxy/article.md b/1-js/99-js-misc/01-proxy/article.md
index 0ae375f77..1f84912e5 100644
--- a/1-js/99-js-misc/01-proxy/article.md
+++ b/1-js/99-js-misc/01-proxy/article.md
@@ -2,7 +2,9 @@
 
 A `Proxy` object wraps another object and intercepts operations, like reading/writing properties and others, optionally handling them on its own, or transparently allowing the object to handle them.
 
-Proxies are used in many libraries and some browser frameworks. We'll see many practical applications in this chapter.
+Proxies are used in many libraries and some browser frameworks. We'll see many practical applications in this article.
+
+## Proxy
 
 The syntax:
 
@@ -37,7 +39,7 @@ As there are no traps, all operations on `proxy` are forwarded to `target`.
 
 As we can see, without any traps, `proxy` is a transparent wrapper around `target`.
 
-![](proxy.svg)  
+![](proxy.svg)
 
 `Proxy` is a special "exotic object". It doesn't have own properties. With an empty `handler` it transparently forwards operations to `target`.
 
@@ -59,13 +61,13 @@ For every internal method, there's a trap in this table: the name of the method
 | `[[Delete]]` | `deleteProperty` | `delete` operator |
 | `[[Call]]` | `apply` | function call |
 | `[[Construct]]` | `construct` | `new` operator |
-| `[[GetPrototypeOf]]` | `getPrototypeOf` | [Object.getPrototypeOf](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getPrototypeOf) |
-| `[[SetPrototypeOf]]` | `setPrototypeOf` | [Object.setPrototypeOf](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf) |
-| `[[IsExtensible]]` | `isExtensible` | [Object.isExtensible](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible) |
-| `[[PreventExtensions]]` | `preventExtensions` | [Object.preventExtensions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/preventExtensions) |
-| `[[DefineOwnProperty]]` | `defineProperty` | [Object.defineProperty](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty), [Object.defineProperties](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperties) |
-| `[[GetOwnProperty]]` | `getOwnPropertyDescriptor` | [Object.getOwnPropertyDescriptor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor), `for..in`, `Object.keys/values/entries` |
-| `[[OwnPropertyKeys]]` | `ownKeys` | [Object.getOwnPropertyNames](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyNames), [Object.getOwnPropertySymbols](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertySymbols), `for..in`, `Object/keys/values/entries` |
+| `[[GetPrototypeOf]]` | `getPrototypeOf` | [Object.getPrototypeOf](mdn:/JavaScript/Reference/Global_Objects/Object/getPrototypeOf) |
+| `[[SetPrototypeOf]]` | `setPrototypeOf` | [Object.setPrototypeOf](mdn:/JavaScript/Reference/Global_Objects/Object/setPrototypeOf) |
+| `[[IsExtensible]]` | `isExtensible` | [Object.isExtensible](mdn:/JavaScript/Reference/Global_Objects/Object/isExtensible) |
+| `[[PreventExtensions]]` | `preventExtensions` | [Object.preventExtensions](mdn:/JavaScript/Reference/Global_Objects/Object/preventExtensions) |
+| `[[DefineOwnProperty]]` | `defineProperty` | [Object.defineProperty](mdn:/JavaScript/Reference/Global_Objects/Object/defineProperty), [Object.defineProperties](mdn:/JavaScript/Reference/Global_Objects/Object/defineProperties) |
+| `[[GetOwnProperty]]` | `getOwnPropertyDescriptor` | [Object.getOwnPropertyDescriptor](mdn:/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor), `for..in`, `Object.keys/values/entries` |
+| `[[OwnPropertyKeys]]` | `ownKeys` | [Object.getOwnPropertyNames](mdn:/JavaScript/Reference/Global_Objects/Object/getOwnPropertyNames), [Object.getOwnPropertySymbols](mdn:/JavaScript/Reference/Global_Objects/Object/getOwnPropertySymbols), `for..in`, `Object.keys/values/entries` |
 
 ```warn header="Invariants"
 JavaScript enforces some invariants -- conditions that must be fulfilled by internal methods and traps.
@@ -244,7 +246,7 @@ If we forget to do it or return any falsy value, the operation triggers `TypeErr
 Such methods differ in details:
 - `Object.getOwnPropertyNames(obj)` returns non-symbol keys.
 - `Object.getOwnPropertySymbols(obj)` returns symbol keys.
-- `Object.keys/values()` returns non-symbol keys/values with `enumerable` flag (property flags were explained in the chapter <info:property-descriptors>).
+- `Object.keys/values()` returns non-symbol keys/values with `enumerable` flag (property flags were explained in the article <info:property-descriptors>).
 - `for..in` loops over non-symbol keys with `enumerable` flag, and also prototype keys.
 
 ...But all of them start with that list.
@@ -333,7 +335,7 @@ let user = {
   _password: "secret"
 };
 
-alert(user._password); // secret  
+alert(user._password); // secret
 ```
 
 Let's use proxies to prevent any access to properties starting with `_`.
@@ -374,7 +376,7 @@ user = new Proxy(user, {
   },
 *!*
   deleteProperty(target, prop) { // to intercept property deletion
-*/!*  
+*/!*
     if (prop.startsWith('_')) {
       throw new Error("Access denied");
     } else {
@@ -435,7 +437,7 @@ user = {
 ```
 
 
-A call to `user.checkPassword()` call gets proxied `user` as `this` (the object before dot becomes `this`), so when it tries to access `this._password`, the `get` trap activates (it triggers on any property read) and throws an error.
+A call to `user.checkPassword()` gets proxied `user` as `this` (the object before dot becomes `this`), so when it tries to access `this._password`, the `get` trap activates (it triggers on any property read) and throws an error.
 
 So we bind the context of object methods to the original object, `target`, in the line `(*)`. Then their future calls will use `target` as `this`, without any traps.
 
@@ -446,7 +448,7 @@ Besides, an object may be proxied multiple times (multiple proxies may add diffe
 So, such a proxy shouldn't be used everywhere.
 
 ```smart header="Private properties of a class"
-Modern JavaScript engines natively support private properties in classes, prefixed with `#`. They are described in the chapter <info:private-protected-properties-methods>. No proxies required.
+Modern JavaScript engines natively support private properties in classes, prefixed with `#`. They are described in the article <info:private-protected-properties-methods>. No proxies required.
 
 Such properties have their own issues though. In particular, they are not inherited.
 ```
@@ -485,7 +487,7 @@ range = new Proxy(range, {
 *!*
   has(target, prop) {
 */!*
-    return prop >= target.start && prop <= target.end
+    return prop >= target.start && prop <= target.end;
   }
 });
 
@@ -507,9 +509,9 @@ The `apply(target, thisArg, args)` trap handles calling a proxy as function:
 - `thisArg` is the value of `this`.
 - `args` is a list of arguments.
 
-For example, let's recall `delay(f, ms)` decorator, that we did in the chapter <info:call-apply-decorators>.
+For example, let's recall `delay(f, ms)` decorator, that we did in the article <info:call-apply-decorators>.
 
-In that chapter we did it without proxies. A call to `delay(f, ms)` returned a function that forwards all calls to `f` after `ms` milliseconds.
+In that article we did it without proxies. A call to `delay(f, ms)` returned a function that forwards all calls to `f` after `ms` milliseconds.
 
 Here's the previous, function-based implementation:
 
@@ -587,7 +589,7 @@ The result is the same, but now not only calls, but all operations on the proxy
 
 We've got a "richer" wrapper.
 
-Other traps exist: the full list is in the beginning of this chapter. Their usage pattern is similar to the above.
+Other traps exist: the full list is in the beginning of this article. Their usage pattern is similar to the above.
 
 ## Reflect
 
@@ -619,7 +621,7 @@ alert(user.name); // John
 
 In particular, `Reflect` allows us to call operators (`new`, `delete`...) as functions (`Reflect.construct`, `Reflect.deleteProperty`, ...). That's an interesting capability, but here another thing is important.
 
-**For every internal method, trappable by `Proxy`, there's a corresponding method in `Reflect`, with the same name and arguments as `Proxy` trap.**
+**For every internal method, trappable by `Proxy`, there's a corresponding method in `Reflect`, with the same name and arguments as the `Proxy` trap.**
 
 So we can use `Reflect` to forward an operation to the original object.
 
@@ -660,7 +662,7 @@ In most cases we can do the same without `Reflect`, for instance, reading a prop
 
 ### Proxying a getter
 
-Let's see an example that demonstrates why `Reflect.get` is better. And we'll also see why `get/set` have the fourth argument `receiver`, that we didn't use before.
+Let's see an example that demonstrates why `Reflect.get` is better. And we'll also see why `get/set` have the third argument `receiver`, that we didn't use before.
 
 We have an object `user` with `_name` property and a getter for it.
 
@@ -838,7 +840,7 @@ So there's no such problem when proxying an array.
 
 ### Private fields
 
-The similar thing happens with private class fields.
+A similar thing happens with private class fields.
 
 For example, `getName()` method accesses the private `#name` property and breaks after proxying:
 
@@ -961,9 +963,13 @@ revoke();
 alert(proxy.data); // Error
 ```
 
-A call to `revoke()` removes all internal references to the target object from the proxy, so they are no more connected. The target object can be garbage-collected after that.
+A call to `revoke()` removes all internal references to the target object from the proxy, so they are no longer connected. 
+
+Initially, `revoke` is separate from `proxy`, so that we can pass `proxy` around while leaving `revoke` in the current scope.
 
-We can also store `revoke` in a `WeakMap`, to be able to easily find it by a proxy object:
+We can also bind `revoke` method to proxy by setting `proxy.revoke = revoke`.
+
+Another option is to create a `WeakMap` that has `proxy` as the key and the corresponding `revoke` as the value, that allows to easily find `revoke` for a proxy:
 
 ```js run
 *!*
@@ -978,21 +984,19 @@ let {proxy, revoke} = Proxy.revocable(object, {});
 
 revokes.set(proxy, revoke);
 
-// ..later in our code..
+// ..somewhere else in our code..
 revoke = revokes.get(proxy);
 revoke();
 
 alert(proxy.data); // Error (revoked)
 ```
 
-The benefit of such an approach is that we don't have to carry `revoke` around. We can get it from the map by `proxy` when needed.
-
 We use `WeakMap` instead of `Map` here because it won't block garbage collection. If a proxy object becomes "unreachable" (e.g. no variable references it any more), `WeakMap` allows it to be wiped from memory together with its `revoke` that we won't need any more.
 
 ## References
 
 - Specification: [Proxy](https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots).
-- MDN: [Proxy](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy).
+- MDN: [Proxy](mdn:/JavaScript/Reference/Global_Objects/Proxy).
 
 ## Summary
 
@@ -1014,13 +1018,13 @@ We can trap:
 - Reading (`get`), writing (`set`), deleting (`deleteProperty`) a property (even a non-existing one).
 - Calling a function (`apply` trap).
 - The `new` operator (`construct` trap).
-- Many other operations (the full list is at the beginning of the article and in the [docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy)).
+- Many other operations (the full list is at the beginning of the article and in the [docs](mdn:/JavaScript/Reference/Global_Objects/Proxy)).
 
 That allows us to create "virtual" properties and methods, implement default values, observable objects, function decorators and so much more.
 
 We can also wrap an object multiple times in different proxies, decorating it with various aspects of functionality.
 
-The [Reflect](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect) API is designed to complement [Proxy](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy). For any `Proxy` trap, there's a `Reflect` call with same arguments. We should use those to forward calls to target objects.
+The [Reflect](mdn:/JavaScript/Reference/Global_Objects/Reflect) API is designed to complement [Proxy](mdn:/JavaScript/Reference/Global_Objects/Proxy). For any `Proxy` trap, there's a `Reflect` call with same arguments. We should use those to forward calls to target objects.
 
 Proxies have some limitations:
 
diff --git a/1-js/99-js-misc/03-currying-partials/article.md b/1-js/99-js-misc/03-currying-partials/article.md
index 1afe10a83..d71ac23f8 100644
--- a/1-js/99-js-misc/03-currying-partials/article.md
+++ b/1-js/99-js-misc/03-currying-partials/article.md
@@ -39,7 +39,7 @@ alert( curriedSum(1)(2) ); // 3
 As you can see, the implementation is straightforward: it's just two wrappers.
 
 - The result of `curry(func)` is a wrapper `function(a)`.
-- When it is called like `sum(1)`, the argument is saved in the Lexical Environment, and a new wrapper is returned `function(b)`.
+- When it is called like `curriedSum(1)`, the argument is saved in the Lexical Environment, and a new wrapper is returned `function(b)`.
 - Then this wrapper is called with `2` as an argument, and it passes the call to the original `sum`.
 
 More advanced implementations of currying, such as [_.curry](https://lodash.com/docs#curry) from lodash library, return a wrapper that allows a function to be called both normally and partially:
@@ -111,7 +111,7 @@ So:
 
 ## Advanced curry implementation
 
-In case you'd like to get in details, here's the "advanced" curry implementation for multi-argument functions that we could use above.
+In case you'd like to get in to the details, here's the "advanced" curry implementation for multi-argument functions that we could use above.
 
 It's pretty short:
 
@@ -155,7 +155,7 @@ function curried(...args) {
   if (args.length >= func.length) { // (1)
     return func.apply(this, args);
   } else {
-    return function pass(...args2) { // (2)
+    return function(...args2) { // (2)
       return curried.apply(this, args.concat(args2));
     }
   }
@@ -164,18 +164,10 @@ function curried(...args) {
 
 When we run it, there are two `if` execution branches:
 
-1. Call now: if passed `args` count is the same as the original function has in its definition (`func.length`) or longer, then just pass the call to it.
-2. Get a partial: otherwise, `func` is not called yet. Instead, another wrapper `pass` is returned, that will re-apply `curried` providing previous arguments together with the new ones. Then on a new call, again, we'll get either a new partial (if not enough arguments) or, finally, the result.
+1. If passed `args` count is the same or more than the original function has in its definition (`func.length`) , then just pass the call to it using `func.apply`. 
+2. Otherwise, get a partial: we don't call `func` just yet. Instead, another wrapper is returned, that will re-apply `curried` providing previous arguments together with the new ones. 
 
-For instance, let's see what happens in the case of `sum(a, b, c)`. Three arguments, so `sum.length = 3`.
-
-For the call `curried(1)(2)(3)`:
-
-1. The first call `curried(1)` remembers `1` in its Lexical Environment, and returns a wrapper `pass`.
-2. The wrapper `pass` is called with `(2)`: it takes previous args (`1`), concatenates them with what it got `(2)` and calls `curried(1, 2)` with them together. As the argument count is still less than 3, `curry` returns `pass`.
-3. The wrapper `pass` is called again with `(3)`,  for the next call `pass(3)` takes previous args (`1`, `2`) and adds `3` to them, making the call `curried(1, 2, 3)` -- there are `3` arguments at last, they are given to the original function.
-
-If that's still not obvious, just trace the calls sequence in your mind or on the paper.
+Then, if we call it, again, we'll get either a new partial (if not enough arguments) or, finally, the result.
 
 ```smart header="Fixed-length functions only"
 The currying requires the function to have a fixed number of arguments.
@@ -191,6 +183,6 @@ But most implementations of currying in JavaScript are advanced, as described: t
 
 ## Summary
 
-*Currying* is a transform that makes `f(a,b,c)` callable as `f(a)(b)(c)`. JavaScript implementations usually both keep the function callable normally and return the partial if arguments count is not enough.
+*Currying* is a transform that makes `f(a,b,c)` callable as `f(a)(b)(c)`. JavaScript implementations usually both keep the function callable normally and return the partial if the arguments count is not enough.
 
-Currying allows to easily get partials. As we've seen in the logging example: the universal function `log(date, importance, message)` after currying gives us partials when called with one argument like `log(date)` or two arguments `log(date, importance)`.  
+Currying allows us to easily get partials. As we've seen in the logging example, after currying the three argument universal function `log(date, importance, message)` gives us partials when called with one argument (like `log(date)`) or two arguments (like `log(date, importance)`).  
diff --git a/1-js/04-object-basics/04-object-methods/2-check-syntax/solution.md b/1-js/99-js-misc/04-reference-type/2-check-syntax/solution.md
similarity index 74%
rename from 1-js/04-object-basics/04-object-methods/2-check-syntax/solution.md
rename to 1-js/99-js-misc/04-reference-type/2-check-syntax/solution.md
index b07995788..2eeb41f21 100644
--- a/1-js/04-object-basics/04-object-methods/2-check-syntax/solution.md
+++ b/1-js/99-js-misc/04-reference-type/2-check-syntax/solution.md
@@ -33,4 +33,8 @@ let user = {
 (user.go)() // John
 ```
 
+<<<<<<< HEAD:1-js/04-object-basics/04-object-methods/2-check-syntax/solution.md
 Miej na uwadze, że nawiasy wokół `(user.go)` nie mają tu żadnego znaczenia. Zazwyczaj służą do zachowania kolejności wykonywania działań, jednak w tym przypadku kropka `.` i tak ma pierwszeństwo. Jedynie średnik jest tu niezbędny. 
+=======
+Please note that parentheses around `(user.go)` do nothing here. Usually they setup the order of operations, but here the dot `.` works first anyway, so there's no effect. Only the semicolon thing matters.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3:1-js/99-js-misc/04-reference-type/2-check-syntax/solution.md
diff --git a/1-js/04-object-basics/04-object-methods/2-check-syntax/task.md b/1-js/99-js-misc/04-reference-type/2-check-syntax/task.md
similarity index 100%
rename from 1-js/04-object-basics/04-object-methods/2-check-syntax/task.md
rename to 1-js/99-js-misc/04-reference-type/2-check-syntax/task.md
diff --git a/1-js/04-object-basics/04-object-methods/3-why-this/solution.md b/1-js/99-js-misc/04-reference-type/3-why-this/solution.md
similarity index 58%
rename from 1-js/04-object-basics/04-object-methods/3-why-this/solution.md
rename to 1-js/99-js-misc/04-reference-type/3-why-this/solution.md
index 8875bd388..ee3c70e29 100644
--- a/1-js/04-object-basics/04-object-methods/3-why-this/solution.md
+++ b/1-js/99-js-misc/04-reference-type/3-why-this/solution.md
@@ -3,9 +3,15 @@ Oto wyjaśnienie.
 
 1. Jest to zwykłe wywołanie metody obiektu.
 
+<<<<<<< HEAD:1-js/04-object-basics/04-object-methods/3-why-this/solution.md
 2. Tak jak powyżej, nawiasy nie zmieniają tutaj kolejności wykonywania działań, kropka i tak ma pierwszeństwo.
 
 3. Tutaj mamy bardziej złożone wywołanie `(expression).method()`. Wywołanie działa tutaj tak jakby było rozbite na dwie linijki kodu:
+=======
+2. The same, parentheses do not change the order of operations here, the dot is first anyway.
+
+3. Here we have a more complex call `(expression)()`. The call works as if it were split into two lines:
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3:1-js/99-js-misc/04-reference-type/3-why-this/solution.md
 
     ```js no-beautify
     f = obj.go; // przypisanie jako wartość zmiennej
@@ -14,7 +20,11 @@ Oto wyjaśnienie.
 
     `f()` jest tutaj wywoływane jako funkcja, bez `this`.
 
+<<<<<<< HEAD:1-js/04-object-basics/04-object-methods/3-why-this/solution.md
 4. Podobna sytuacja jak w `(3)`, po lewej stronie od kropki `.` mamy wyrażenie.
+=======
+4. The similar thing as `(3)`, to the left of the parentheses `()` we have an expression.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3:1-js/99-js-misc/04-reference-type/3-why-this/solution.md
 
 Żeby wyjaśnić zachowanie `(3)` i `(4)` musimy przypomnieć sobie, że akcesory właściwości (kropki lub nawiasy kwadratowe) zwracają wartość Typu Referencji.
 
diff --git a/1-js/04-object-basics/04-object-methods/3-why-this/task.md b/1-js/99-js-misc/04-reference-type/3-why-this/task.md
similarity index 100%
rename from 1-js/04-object-basics/04-object-methods/3-why-this/task.md
rename to 1-js/99-js-misc/04-reference-type/3-why-this/task.md
diff --git a/1-js/99-js-misc/04-reference-type/article.md b/1-js/99-js-misc/04-reference-type/article.md
new file mode 100644
index 000000000..894db8fc6
--- /dev/null
+++ b/1-js/99-js-misc/04-reference-type/article.md
@@ -0,0 +1,108 @@
+
+# Reference Type
+
+```warn header="In-depth language feature"
+This article covers an advanced topic, to understand certain edge-cases better.
+
+It's not important. Many experienced developers live fine without knowing it. Read on if you want to know how things work under the hood.
+```
+
+A dynamically evaluated method call can lose `this`.
+
+For instance:
+
+```js run
+let user = {
+  name: "John",
+  hi() { alert(this.name); },
+  bye() { alert("Bye"); }
+};
+
+user.hi(); // works
+
+// now let's call user.hi or user.bye depending on the name
+*!*
+(user.name == "John" ? user.hi : user.bye)(); // Error!
+*/!*
+```
+
+On the last line there is a conditional operator that chooses either `user.hi` or `user.bye`. In this case the result is `user.hi`.
+
+Then the method is immediately called with parentheses `()`. But it doesn't work correctly!
+
+As you can see, the call results in an error, because the value of `"this"` inside the call becomes `undefined`.
+
+This works (object dot method):
+```js
+user.hi();
+```
+
+This doesn't (evaluated method):
+```js
+(user.name == "John" ? user.hi : user.bye)(); // Error!
+```
+
+Why? If we want to understand why it happens, let's get under the hood of how `obj.method()` call works.
+
+## Reference type explained
+
+Looking closely, we may notice two operations in `obj.method()` statement:
+
+1. First, the dot `'.'` retrieves the property `obj.method`.
+2. Then parentheses `()` execute it.
+
+So, how does the information about `this` get passed from the first part to the second one?
+
+If we put these operations on separate lines, then `this` will be lost for sure:
+
+```js run
+let user = {
+  name: "John",
+  hi() { alert(this.name); }
+};
+
+*!*
+// split getting and calling the method in two lines
+let hi = user.hi;
+hi(); // Error, because this is undefined
+*/!*
+```
+
+Here `hi = user.hi` puts the function into the variable, and then on the last line it is completely standalone, and so there's no `this`.
+
+**To make `user.hi()` calls work, JavaScript uses a trick -- the dot `'.'` returns not a function, but a value of the special [Reference Type](https://tc39.github.io/ecma262/#sec-reference-specification-type).**
+
+The Reference Type is a "specification type". We can't explicitly use it, but it is used internally by the language.
+
+The value of Reference Type is a three-value combination `(base, name, strict)`, where:
+
+- `base` is the object.
+- `name` is the property name.
+- `strict` is true if `use strict` is in effect.
+
+The result of a property access `user.hi` is not a function, but a value of Reference Type. For `user.hi` in strict mode it is:
+
+```js
+// Reference Type value
+(user, "hi", true)
+```
+
+When parentheses `()` are called on the Reference Type, they receive the full information about the object and its method, and can set the right `this` (`user` in this case).
+
+Reference type is a special "intermediary" internal type, with the purpose to pass information from dot `.` to calling parentheses `()`.
+
+Any other operation like assignment `hi = user.hi` discards the reference type as a whole, takes the value of `user.hi` (a function) and passes it on. So any further operation "loses" `this`.
+
+So, as the result, the value of `this` is only passed the right way if the function is called directly using a dot `obj.method()` or square brackets `obj['method']()` syntax (they do the same here). There are various ways to solve this problem such as [func.bind()](/bind#solution-2-bind).
+
+## Summary
+
+Reference Type is an internal type of the language.
+
+Reading a property, such as with dot `.` in `obj.method()` returns not exactly the property value, but a special "reference type" value that stores both the property value and the object it was taken from.
+
+That's for the subsequent method call `()` to get the object and set `this` to it.
+
+For all other operations, the reference type automatically becomes the property value (a function in our case).
+
+The whole mechanics is hidden from our eyes. It only matters in subtle cases, such as when a method is obtained dynamically from the object, using an expression.
diff --git a/1-js/99-js-misc/05-bigint/article.md b/1-js/99-js-misc/05-bigint/article.md
index 29c5e27da..2a1cfc843 100644
--- a/1-js/99-js-misc/05-bigint/article.md
+++ b/1-js/99-js-misc/05-bigint/article.md
@@ -45,12 +45,12 @@ alert(bigint + BigInt(number)); // 3
 alert(Number(bigint) + number); // 3
 ```
 
-The conversion of bigint to number is always silent, but if the bigint is too huge and won't fit the number type, then extra bits will be cut off, causing a precision loss.
+The conversion operations are always silent, never give errors, but if the bigint is too huge and won't fit the number type, then extra bits will be cut off, so we should be careful doing such conversion.
 
 ````smart header="The unary plus is not supported on bigints"
 The unary plus operator `+value` is a well-known way to convert `value` to a number.
 
-On bigints it's not supported, to avoid confusion:
+In order to avoid confusion, it's not supported on bigints:
 ```js run
 let bigint = 1n;
 
@@ -69,7 +69,7 @@ alert( 2n > 1n ); // true
 alert( 2n > 1 ); // true
 ```
 
-As numbers and bigints belong to different types, they can be equal `==`, but not strictly equal `===`:
+Please note though, as numbers and bigints belong to different types, they can be equal `==`, but not strictly equal `===`:
 
 ```js run
 alert( 1 == 1n ); // true
@@ -101,15 +101,15 @@ alert( 0n || 2 ); // 2 (0n is considered falsy)
 
 Polyfilling bigints is tricky. The reason is that many JavaScript operators, such as `+`, `-` and so on behave differently with bigints compared to regular numbers.
 
-For example, division of bigints always returns an integer.
+For example, division of bigints always returns a bigint (rounded if necessary).
 
-To emulate such behavior, a polyfill would need to replace all such operators with its functions. But doing so is cumbersome and would cost a lot of performance.
+To emulate such behavior, a polyfill would need to analyze the code and replace all such operators with its functions. But doing so is cumbersome and would cost a lot of performance.
 
 So, there's no well-known good polyfill.
 
-Although, the other way around is proposed by the developers of [https://github.com/GoogleChromeLabs/jsbi](JSBI) library.
+Although, the other way around is proposed by the developers of [JSBI](https://github.com/GoogleChromeLabs/jsbi) library.
 
-They suggest to use JSBI library calls instead of native bigints:
+This library implements big numbers using its own methods. We can use them instead of native bigints:
 
 | Operation | native `BigInt` | JSBI |
 |-----------|-----------------|------|
@@ -120,9 +120,11 @@ They suggest to use JSBI library calls instead of native bigints:
 
 ...And then use the polyfill (Babel plugin) to convert JSBI calls to native bigints for those browsers that support them.
 
-In other words, this approach suggests that we write code in JSBI instead of native bigints. But JSBI works with numbers as with bigints internally, closely following the specification, so the code will be "bigint-ready".
+In other words, this approach suggests that we write code in JSBI instead of native bigints. But JSBI works with numbers as with bigints internally, emulates them closely following the specification, so the code will be "bigint-ready".
+
+We can use such JSBI code "as is" for engines that don't support bigints and for those that do support - the polyfill will convert the calls to native bigints.
 
 ## References
 
-- [MDN docs on BigInt](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt).
+- [MDN docs on BigInt](mdn:/JavaScript/Reference/Global_Objects/BigInt).
 - [Specification](https://tc39.es/ecma262/#sec-bigint-objects).
diff --git a/1-js/99-js-misc/06-unicode/article.md b/1-js/99-js-misc/06-unicode/article.md
new file mode 100644
index 000000000..4f144f824
--- /dev/null
+++ b/1-js/99-js-misc/06-unicode/article.md
@@ -0,0 +1,172 @@
+
+# Unicode, String internals
+
+```warn header="Advanced knowledge"
+The section goes deeper into string internals. This knowledge will be useful for you if you plan to deal with emoji, rare mathematical or hieroglyphic characters, or other rare symbols.
+```
+
+As we already know, JavaScript strings are based on [Unicode](https://en.wikipedia.org/wiki/Unicode): each character is represented by a byte sequence of 1-4 bytes.
+
+JavaScript allows us to insert a character into a string by specifying its hexadecimal Unicode code with one of these three notations:
+
+- `\xXX`
+
+    `XX` must be two hexadecimal digits with a value between `00` and `FF`, then `\xXX` is the character whose Unicode code is `XX`.
+
+    Because the `\xXX` notation supports only two hexadecimal digits, it can be used only for the first 256 Unicode characters.
+
+    These first 256 characters include the Latin alphabet, most basic syntax characters, and some others. For example, `"\x7A"` is the same as `"z"` (Unicode `U+007A`).
+
+    ```js run
+    alert( "\x7A" ); // z
+    alert( "\xA9" ); // ©, the copyright symbol
+    ```
+
+- `\uXXXX`
+    `XXXX` must be exactly 4 hex digits with the value between `0000` and `FFFF`, then `\uXXXX` is the character whose Unicode code is `XXXX`.
+
+    Characters with Unicode values greater than `U+FFFF` can also be represented with this notation, but in this case, we will need to use a so called surrogate pair (we will talk about surrogate pairs later in this chapter).
+
+    ```js run
+    alert( "\u00A9" ); // ©, the same as \xA9, using the 4-digit hex notation
+    alert( "\u044F" ); // я, the Cyrillic alphabet letter
+    alert( "\u2191" ); // ↑, the arrow up symbol
+    ```
+
+- `\u{X…XXXXXX}`
+
+    `X…XXXXXX` must be a hexadecimal value of 1 to 6 bytes between `0` and `10FFFF` (the highest code point defined by Unicode). This notation allows us to easily represent all existing Unicode characters.
+
+    ```js run
+    alert( "\u{20331}" ); // 佫, a rare Chinese character (long Unicode)
+    alert( "\u{1F60D}" ); // 😍, a smiling face symbol (another long Unicode)
+    ```
+
+## Surrogate pairs
+
+All frequently used characters have 2-byte codes (4 hex digits). Letters in most European languages, numbers, and the basic unified CJK ideographic sets (CJK -- from Chinese, Japanese, and Korean writing systems), have a 2-byte representation.
+
+Initially, JavaScript was based on UTF-16 encoding that only allowed 2 bytes per character. But 2 bytes only allow 65536 combinations and that's not enough for every possible symbol of Unicode.
+
+So rare symbols that require more than 2 bytes are encoded with a pair of 2-byte characters called "a surrogate pair".
+
+As a side effect, the length of such symbols is `2`:
+
+```js run
+alert( '𝒳'.length ); // 2, MATHEMATICAL SCRIPT CAPITAL X
+alert( '😂'.length ); // 2, FACE WITH TEARS OF JOY
+alert( '𩷶'.length ); // 2, a rare Chinese character
+```
+
+That's because surrogate pairs did not exist at the time when JavaScript was created, and thus are not correctly processed by the language!
+
+We actually have a single symbol in each of the strings above, but the `length` property shows a length of `2`.
+
+Getting a symbol can also be tricky, because most language features treat surrogate pairs as two characters.
+
+For example, here we can see two odd characters in the output:
+
+```js run
+alert( '𝒳'[0] ); // shows strange symbols...
+alert( '𝒳'[1] ); // ...pieces of the surrogate pair
+```
+
+Pieces of a surrogate pair have no meaning without each other. So the alerts in the example above actually display garbage.
+
+Technically, surrogate pairs are also detectable by their codes: if a character has the code in the interval of `0xd800..0xdbff`, then it is the first part of the surrogate pair. The next character (second part) must have the code in interval `0xdc00..0xdfff`. These intervals are reserved exclusively for surrogate pairs by the standard.
+
+So the methods [String.fromCodePoint](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/fromCodePoint) and [str.codePointAt](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/codePointAt) were added in JavaScript to deal with surrogate pairs.
+
+They are essentially the same as [String.fromCharCode](mdn:js/String/fromCharCode) and [str.charCodeAt](mdn:js/String/charCodeAt), but they treat surrogate pairs correctly.
+
+One can see the difference here:
+
+```js run
+// charCodeAt is not surrogate-pair aware, so it gives codes for the 1st part of 𝒳:
+
+alert( '𝒳'.charCodeAt(0).toString(16) ); // d835
+
+// codePointAt is surrogate-pair aware
+alert( '𝒳'.codePointAt(0).toString(16) ); // 1d4b3, reads both parts of the surrogate pair
+```
+
+That said, if we take from position 1 (and that's rather incorrect here), then they both return only the 2nd part of the pair:
+
+```js run
+alert( '𝒳'.charCodeAt(1).toString(16) ); // dcb3
+alert( '𝒳'.codePointAt(1).toString(16) ); // dcb3
+// meaningless 2nd half of the pair
+```
+
+You will find more ways to deal with surrogate pairs later in the chapter <info:iterable>. There are probably special libraries for that too, but nothing famous enough to suggest here.
+
+````warn header="Takeaway: splitting strings at an arbitrary point is dangerous"
+We can't just split a string at an arbitrary position, e.g. take `str.slice(0, 4)` and expect it to be a valid string, e.g.:
+
+```js run
+alert( 'hi 😂'.slice(0, 4) ); //  hi [?]
+```
+
+Here we can see a garbage character (first half of the smile surrogate pair) in the output.
+
+Just be aware of it if you intend to reliably work with surrogate pairs. May not be a big problem, but at least you should understand what happens.
+````
+
+## Diacritical marks and normalization
+
+In many languages, there are symbols that are composed of the base character with a mark above/under it.
+
+For instance, the letter `a` can be the base character for these characters: `àáâäãåā`.
+
+Most common "composite" characters have their own code in the Unicode table. But not all of them, because there are too many possible combinations.
+
+To support arbitrary compositions, the Unicode standard allows us to use several Unicode characters: the base character followed by one or many "mark" characters that "decorate" it.
+
+For instance, if we have `S` followed by the special "dot above" character (code `\u0307`), it is shown as Ṡ.
+
+```js run
+alert( 'S\u0307' ); // Ṡ
+```
+
+If we need an additional mark above the letter (or below it) -- no problem, just add the necessary mark character.
+
+For instance, if we append a character "dot below" (code `\u0323`), then we'll have "S with dots above and below": `Ṩ`.
+
+For example:
+
+```js run
+alert( 'S\u0307\u0323' ); // Ṩ
+```
+
+This provides great flexibility, but also an interesting problem: two characters may visually look the same, but be represented with different Unicode compositions.
+
+For instance:
+
+```js run
+let s1 = 'S\u0307\u0323'; // Ṩ, S + dot above + dot below
+let s2 = 'S\u0323\u0307'; // Ṩ, S + dot below + dot above
+
+alert( `s1: ${s1}, s2: ${s2}` );
+
+alert( s1 == s2 ); // false though the characters look identical (?!)
+```
+
+To solve this, there exists a "Unicode normalization" algorithm that brings each string to the single "normal" form.
+
+It is implemented by [str.normalize()](mdn:js/String/normalize).
+
+```js run
+alert( "S\u0307\u0323".normalize() == "S\u0323\u0307".normalize() ); // true
+```
+
+It's funny that in our situation `normalize()` actually brings together a sequence of 3 characters to one: `\u1e68` (S with two dots).
+
+```js run
+alert( "S\u0307\u0323".normalize().length ); // 1
+
+alert( "S\u0307\u0323".normalize() == "\u1e68" ); // true
+```
+
+In reality, this is not always the case. The reason is that the symbol `Ṩ` is "common enough", so Unicode creators included it in the main table and gave it the code.
+
+If you want to learn more about normalization rules and variants -- they are described in the appendix of the Unicode standard: [Unicode Normalization Forms](https://www.unicode.org/reports/tr15/), but for most practical purposes the information from this section is enough.
diff --git a/1-js/99-js-misc/07-weakref-finalizationregistry/article.md b/1-js/99-js-misc/07-weakref-finalizationregistry/article.md
new file mode 100644
index 000000000..777bf703c
--- /dev/null
+++ b/1-js/99-js-misc/07-weakref-finalizationregistry/article.md
@@ -0,0 +1,483 @@
+
+# WeakRef and FinalizationRegistry
+
+```warn header="\"Hidden\" features of the language"
+This article covers a very narrowly focused topic, that most developers extremely rarely encounter in practice (and may not even be aware of its existence).  
+
+We recommend skipping this chapter if you have just started learning JavaScript.
+```
+
+Recalling the basic concept of the *reachability principle* from the <info:garbage-collection> chapter,
+we can note that the JavaScript engine is guaranteed to keep values in memory that are accessible or in use.
+
+For example:
+
+
+```js
+//  the user variable holds a strong reference to the object
+let user = { name: "John" };
+
+// let's overwrite the value of the user variable
+user = null;
+
+// the reference is lost and the object will be deleted from memory
+
+```
+
+Or a similar, but slightly more complicated code with two strong references:
+
+```js
+//  the user variable holds a strong reference to the object
+let user = { name: "John" };
+
+// copied the strong reference to the object into the admin variable
+*!*
+let admin = user;
+*/!*
+
+// let's overwrite the value of the user variable
+user = null;
+
+// the object is still reachable through the admin variable
+```
+The object `{ name: "John" }` would only be deleted from memory if there were no strong references to it (if we also overwrote the value of the `admin` variable).  
+
+In JavaScript, there is a concept called `WeakRef`, which behaves slightly differently in this case.
+
+
+````smart header="Terms: \"Strong reference\", \"Weak reference\""
+**Strong reference** - is a reference to an object or value, that prevents them from being deleted by the garbage collector. Thereby, keeping the object or value in memory, to which it points.  
+
+This means, that the object or value remains in memory and is not collected by the garbage collector as long, as there are active strong references to it.  
+
+In JavaScript, ordinary references to objects are strong references. For example:
+
+```js
+// the user variable holds a strong reference to this object
+let user = { name: "John" };
+```
+**Weak reference** - is a reference to an object or value, that does *not* prevent them from being deleted by the garbage collector.
+An object or value can be deleted by the garbage collector if, the only remaining references to them are weak references.
+````
+
+## WeakRef
+
+
+````warn header="Note of caution"
+Before we dive into it, it is worth noting that the correct use of the structures discussed in this article requires very careful thought, and they are best avoided if possible. 
+````
+
+`WeakRef` - is an object, that contains a weak reference to another object, called `target` or `referent`. 
+
+The peculiarity of `WeakRef` is that it does not prevent the garbage collector from deleting its referent-object. In other words, a `WeakRef` object does not keep the `referent` object alive.  
+
+Now let's take the `user` variable as the "referent" and create a weak reference from it to the `admin` variable.
+To create a weak reference, you need to use the `WeakRef` constructor, passing in the target object (the object you want a weak reference to).
+
+In our case — this is the `user` variable:
+
+
+```js
+//  the user variable holds a strong reference to the object
+let user = { name: "John" };
+
+//  the admin variable holds a weak reference to the object
+*!*
+let admin = new WeakRef(user);
+*/!*
+
+```
+
+The diagram below depicts two types of references: a strong reference using the `user` variable and a weak reference using the `admin` variable:
+
+![](weakref-finalizationregistry-01.svg)  
+
+Then, at some point, we stop using the `user` variable - it gets overwritten, goes out of scope, etc., while keeping the `WeakRef` instance in the `admin` variable:
+
+```js
+// let's overwrite the value of the user variable
+user = null;
+```
+
+A weak reference to an object is not enough to keep it "alive". When the only remaining references to a referent-object are weak references, the garbage collector is free to destroy this object and use its memory for something else.
+
+However, until the object is actually destroyed, the weak reference may return it, even if there are no more strong references to this object.
+That is, our object becomes a kind of "[Schrödinger's cat](https://en.wikipedia.org/wiki/Schr%C3%B6dinger%27s_cat)" – we cannot know for sure whether it's "alive" or "dead":
+
+![](weakref-finalizationregistry-02.svg)
+
+At this point, to get the object from the `WeakRef` instance, we will use its `deref()` method.  
+
+The `deref()` method returns the referent-object that the `WeakRef` points to, if the object is still in memory. If the object has been deleted by the garbage collector, then the `deref()` method will return `undefined`:
+
+
+```js
+let ref = admin.deref();
+
+if (ref) {
+  // the object is still accessible: we can perform any manipulations with it
+} else {
+  // the object has been collected by the garbage collector
+}
+```
+
+## WeakRef use cases
+
+`WeakRef` is typically used to create caches or [associative arrays](https://en.wikipedia.org/wiki/Associative_array) that store resource-intensive objects.
+This allows one to avoid preventing these objects from being collected by the garbage collector solely based on their presence in the cache or associative array.  
+
+One of the primary examples - is a situation when we have numerous binary image objects (for instance, represented as `ArrayBuffer` or `Blob`), and we want to associate a name or path with each image.
+Existing data structures are not quite suitable for these purposes:
+
+- Using `Map` to create associations between names and images, or vice versa, will keep the image objects in memory since they are present in the `Map` as keys or values.
+- `WeakMap` is ineligible for this goal either: because the objects represented as `WeakMap` keys use weak references, and are not protected from deletion by the garbage collector.
+
+But, in this situation, we need a data structure that would use weak references in its values.
+
+For this purpose, we can use a `Map` collection, whose values are `WeakRef` instances referring to the large objects we need.
+Consequently, we will not keep these large and unnecessary objects in memory longer than they should be.  
+
+Otherwise, this is a way to get the image object from the cache if it is still reachable.
+If it has been garbage collected, we will re-generate or re-download it again.  
+
+This way, less memory is used in some situations.  
+
+## Example №1: using WeakRef for caching
+
+Below is a code snippet that demonstrates the technique of using `WeakRef`.  
+
+In short, we use a `Map` with string keys and `WeakRef` objects as their values.
+If the `WeakRef` object has not been collected by the garbage collector, we get it from the cache.
+Otherwise, we re-download it again and put it in the cache for further possible reuse:  
+
+```js
+function fetchImg() {
+    // abstract function for downloading images...
+}
+
+function weakRefCache(fetchImg) { // (1)
+    const imgCache = new Map(); // (2)
+
+    return (imgName) => { // (3)
+        const cachedImg = imgCache.get(imgName); // (4)
+
+        if (cachedImg?.deref()) { // (5)
+            return cachedImg?.deref();
+        }
+
+        const newImg = fetchImg(imgName); // (6)
+        imgCache.set(imgName, new WeakRef(newImg)); // (7)
+
+        return newImg;
+    };
+}
+
+const getCachedImg = weakRefCache(fetchImg);
+```  
+
+Let's delve into the details of what happened here:
+1. `weakRefCache` - is a higher-order function that takes another function, `fetchImg`, as an argument. In this example, we can neglect a detailed description of the `fetchImg` function, since it can be any logic for downloading images.
+2. `imgCache` - is a cache of images, that stores cached results of the `fetchImg` function, in the form of string keys (image name) and `WeakRef` objects as their values.
+3. Return an anonymous function that takes the image name as an argument. This argument will be used as a key for the cached image.
+4. Trying to get the cached result from the cache, using the provided key (image name).
+5. If the cache contains a value for the specified key, and the `WeakRef` object has not been deleted by the garbage collector, return the cached result.
+6. If there is no entry in the cache with the requested key, or `deref()` method returns `undefined` (meaning that the `WeakRef` object has been garbage collected), the `fetchImg` function downloads the image again.
+7. Put the downloaded image into the cache as a `WeakRef` object.  
+
+Now we have a `Map` collection, where the keys - are image names as strings, and values - are `WeakRef` objects containing the images themselves.
+
+This technique helps to avoid allocating a large amount of memory for resource-intensive objects, that nobody uses anymore.
+It also saves memory and time in case of reusing cached objects.  
+
+Here is a visual representation of what this code looks like:  
+
+![](weakref-finalizationregistry-03.svg) 
+
+But, this implementation has its drawbacks: over time, `Map` will be filled with strings as keys, that point to a `WeakRef`, whose referent-object has already been garbage collected:  
+
+![](weakref-finalizationregistry-04.svg)
+
+One way to handle this problem - is to periodically scavenge the cache and clear out "dead" entries.
+Another way - is to use finalizers, which we will explore next.  
+
+
+## Example №2: Using WeakRef to track DOM objects
+
+Another use case for `WeakRef` - is tracking DOM objects.  
+
+Let's imagine a scenario where some third-party code or library interacts with elements on our page as long as they exist in the DOM.
+For example, it could be an external utility for monitoring and notifying about the system's state (commonly so-called "logger" – a program that sends informational messages called "logs").
+
+Interactive example:  
+
+[codetabs height=420 src="weakref-dom"]  
+
+When the "Start sending messages" button is clicked, in the so-called "logs display window" (an element with the `.window__body` class), messages (logs) start to appear.  
+
+But, as soon as this element is deleted from the DOM, the logger should stop sending messages.
+To reproduce the removal of this element, just click the "Close" button in the top right corner.  
+
+In order not to complicate our work, and not to notify third-party code every time our DOM-element is available, and when it is not, it will be enough to create a weak reference to it using `WeakRef`.    
+
+Once the element is removed from the DOM, the logger will notice it and stop sending messages.  
+
+Now let's take a closer look at the source code (*tab `index.js`*):
+
+1. Get the DOM-element of the "Start sending messages" button.
+2. Get the DOM-element of the "Close" button.
+3. Get the DOM-element of the logs display window using the `new WeakRef()` constructor. This way, the `windowElementRef` variable holds a weak reference to the DOM-element.
+4. Add an event listener on the "Start sending messages" button, responsible for starting the logger when clicked.
+5. Add an event listener on the "Close" button, responsible for closing the logs display window when clicked.
+6. Use `setInterval` to start displaying a new message every second.
+7. If the DOM-element of the logs display window is still accessible and kept in memory, create and send a new message.
+8. If the `deref()` method returns `undefined`, it means that the DOM-element has been deleted from memory. In this case, the logger stops displaying messages and clears the timer.
+9. `alert`, which will be called, after the DOM-element of the logs display window is deleted from memory (i.e. after clicking the "Close" button). **Note, that deletion from memory may not happen immediately, as it depends only on the internal mechanisms of the garbage collector.**
+
+   We cannot control this process directly from the code. However, despite this, we still have the option to force garbage collection from the browser.
+
+   In Google Chrome, for example, to do this, you need to open the developer tools (`key:Ctrl` + `key:Shift` + `key:J` on Windows/Linux or `key:Option` + `key:⌘` + `key:J` on macOS), go to the "Performance" tab, and click on the bin icon button – "Collect garbage":
+
+   ![](google-chrome-developer-tools.png)
+
+    <br>
+    This functionality is supported in most modern browsers. After the actions are taken, the <code>alert</code> will trigger immediately.
+
+## FinalizationRegistry
+
+Now it is time to talk about finalizers. Before we move on, let's clarify the terminology:  
+
+**Cleanup callback (finalizer)** - is a function that is executed, when an object, registered in the `FinalizationRegistry`, is deleted from memory by the garbage collector.  
+
+Its purpose - is to provide the ability to perform additional operations, related to the object, after it has been finally deleted from memory.  
+
+**Registry** (or `FinalizationRegistry`) - is a special object in JavaScript that manages the registration and unregistration of objects and their cleanup callbacks.  
+
+This mechanism allows registering an object to track and associate a cleanup callback with it.
+Essentially it is a structure that stores information about registered objects and their cleanup callbacks, and then automatically invokes those callbacks when the objects are deleted from memory.  
+
+To create an instance of the `FinalizationRegistry`, it needs to call its constructor, which takes a single argument - the cleanup callback (finalizer).  
+
+Syntax:
+
+```js
+function cleanupCallback(heldValue) { 
+  // cleanup callback code 
+}
+
+const registry = new FinalizationRegistry(cleanupCallback);
+```
+
+Here:
+
+- `cleanupCallback` - a cleanup callback that will be automatically called when a registered object is deleted from memory.
+- `heldValue` - the value that is passed as an argument to the cleanup callback. If `heldValue` is an object, the registry keeps a strong reference to it.
+- `registry` - an instance of `FinalizationRegistry`.
+
+`FinalizationRegistry` methods:
+
+- `register(target, heldValue [, unregisterToken])` - used to register objects in the registry.
+
+  `target` - the object being registered for tracking. If the `target` is garbage collected, the cleanup callback will be called with `heldValue` as its argument.
+
+  Optional `unregisterToken` – an unregistration token. It can be passed to unregister an object before the garbage collector deletes it. Typically, the `target` object is used as `unregisterToken`, which is the standard practice.
+- `unregister(unregisterToken)` - the `unregister` method is used to unregister an object from the registry. It takes one argument - `unregisterToken` (the unregister token that was obtained when registering the object).  
+
+Now let's move on to a simple example. Let's use the already-known `user` object and create an instance of `FinalizationRegistry`:  
+
+```js
+let user = { name: "John" };
+
+const registry = new FinalizationRegistry((heldValue) => {
+  console.log(`${heldValue} has been collected by the garbage collector.`);
+});
+```
+
+Then, we will register the object, that requires a cleanup callback by calling the `register` method:
+
+```js
+registry.register(user, user.name);
+```
+
+The registry does not keep a strong reference to the object being registered, as this would defeat its purpose. If the registry kept a strong reference, then the object would never be garbage collected.  
+
+If the object is deleted by the garbage collector, our cleanup callback may be called at some point in the future, with the `heldValue` passed to it:
+
+```js
+// When the user object is deleted by the garbage collector, the following message will be printed in the console:
+"John has been collected by the garbage collector."
+```
+
+There are also situations where, even in implementations that use a cleanup callback, there is a chance that it will not be called.
+
+For example:
+- When the program fully terminates its operation (for example, when closing a tab in a browser).
+- When the `FinalizationRegistry` instance itself is no longer reachable to JavaScript code.
+  If the object that creates the `FinalizationRegistry` instance goes out of scope or is deleted, the cleanup callbacks registered in that registry might also not be invoked.
+
+## Caching with FinalizationRegistry
+
+Returning to our *weak* cache example, we can notice the following:
+- Even though the values wrapped in the `WeakRef` have been collected by the garbage collector, there is still an issue of "memory leakage" in the form of the remaining keys, whose values have been collected by the garbage collector.
+
+Here is an improved caching example using `FinalizationRegistry`:
+
+```js
+function fetchImg() {
+  // abstract function for downloading images...
+}
+
+function weakRefCache(fetchImg) {
+  const imgCache = new Map();
+
+  *!*
+  const registry = new FinalizationRegistry((imgName) => { // (1)
+    const cachedImg = imgCache.get(imgName);
+    if (cachedImg && !cachedImg.deref()) imgCache.delete(imgName);
+  });
+  */!*
+
+  return (imgName) => {
+    const cachedImg = imgCache.get(imgName);
+    
+    if (cachedImg?.deref()) {
+      return cachedImg?.deref();
+    }
+
+    const newImg = fetchImg(imgName);
+    imgCache.set(imgName, new WeakRef(newImg));
+    *!*
+    registry.register(newImg, imgName); // (2)
+    */!*
+
+    return newImg;
+  };
+}
+
+const getCachedImg = weakRefCache(fetchImg);
+```
+
+1. To manage the cleanup of "dead" cache entries, when the associated `WeakRef` objects are collected by the garbage collector, we create a `FinalizationRegistry` cleanup registry.
+
+   The important point here is, that in the cleanup callback, it should be checked, if the entry was deleted by the garbage collector and not re-added, in order not to delete a "live" entry.
+2. Once the new value (image) is downloaded and put into the cache, we register it in the finalizer registry to track the `WeakRef` object.
+
+This implementation contains only actual or "live" key/value pairs.
+In this case, each `WeakRef` object is registered in the `FinalizationRegistry`.
+And after the objects are cleaned up by the garbage collector, the cleanup callback will delete all `undefined` values.
+
+Here is a visual representation of the updated code:  
+
+![](weakref-finalizationregistry-05.svg)
+
+A key aspect of the updated implementation is that finalizers allow parallel processes to be created between the "main" program and cleanup callbacks.
+In the context of JavaScript, the "main" program - is our JavaScript-code, that runs and executes in our application or web page.  
+
+Hence, from the moment an object is marked for deletion by the garbage collector, and to the actual execution of the cleanup callback, there may be a certain time gap.
+It is important to understand that during this time gap, the main program can make any changes to the object or even bring it back to memory.  
+
+That's why, in the cleanup callback, we must check to see if an entry has been added back to the cache by the main program to avoid deleting "live" entries.
+Similarly, when searching for a key in the cache, there is a chance that the value has been deleted by the garbage collector, but the cleanup callback has not been executed yet.  
+
+Such situations require special attention if you are working with `FinalizationRegistry`.
+
+## Using WeakRef and FinalizationRegistry in practice
+
+Moving from theory to practice, imagine a real-life scenario, where a user synchronizes their photos on a mobile device with some cloud service
+(such as [iCloud](https://en.wikipedia.org/wiki/ICloud) or [Google Photos](https://en.wikipedia.org/wiki/Google_Photos)),
+and wants to view them from other devices. In addition to the basic functionality of viewing photos, such services offer a lot of additional features, for example:  
+
+- Photo editing and video effects.
+- Creating "memories" and albums.
+- Video montage from a series of photos.
+- ...and much more.
+
+Here, as an example, we will use a fairly primitive implementation of such a service.
+The main point - is to show a possible scenario of using `WeakRef` and `FinalizationRegistry` together in real life.
+
+Here is what it looks like:
+
+![](weakref-finalizationregistry-demo-01.png)
+
+<br>
+On the left side, there is a cloud library of photos (they are displayed as thumbnails).
+We can select the images we need and create a collage, by clicking the "Create collage" button on the right side of the page.
+Then, the resulting collage can be downloaded as an image.
+</br><br>
+
+To increase page loading speed, it would be reasonable to download and display photo thumbnails in *compressed* quality.
+But, to create a collage from selected photos, download and use them in *full-size* quality.  
+
+Below, we can see, that the intrinsic size of the thumbnails is 240x240 pixels.
+The size was chosen on purpose to increase loading speed.
+Moreover, we do not need full-size photos in preview mode.
+
+![](weakref-finalizationregistry-demo-02.png)
+
+<br>
+Let's assume, that we need to create a collage of 4 photos: we select them, and then click the "Create collage" button.
+At this stage, the already known to us <code>weakRefCache</code> function checks whether the required image is in the cache.
+If not, it downloads it from the cloud and puts it in the cache for further use.
+This happens for each selected image:
+</br><br>
+
+![](weakref-finalizationregistry-demo-03.gif)
+
+</br>
+
+Paying attention to the output in the console, you can see, which of the photos were downloaded from the cloud - this is indicated by <span style="background-color:#133159;color:white;font-weight:500">FETCHED_IMAGE</span>.
+Since this is the first attempt to create a collage, this means, that at this stage the "weak cache" was still empty, and all the photos were downloaded from the cloud and put in it.
+
+But, along with the process of downloading images, there is also a process of memory cleanup by the garbage collector.
+This means, that the object stored in the cache, which we refer to, using a weak reference, is deleted by the garbage collector.
+And our finalizer executes successfully, thereby deleting the key, by which the image was stored in the cache.
+<span style="background-color:#901e30;color:white;font-weight:500;">CLEANED_IMAGE</span> notifies us about it:
+
+![](weakref-finalizationregistry-demo-04.jpg)
+
+<br>
+Next, we realize that we do not like the resulting collage, and decide to change one of the images and create a new one.
+To do this, just deselect the unnecessary image, select another one, and click the "Create collage" button again:
+</br><br>
+
+![](weakref-finalizationregistry-demo-05.gif)
+
+<br>
+But this time not all images were downloaded from the network, and one of them was taken from the weak cache: the <span style="background-color:#385950;color:white;font-weight:500;">CACHED_IMAGE</span> message tells us about it.
+This means that at the time of collage creation, the garbage collector had not yet deleted our image, and we boldly took it from the cache,
+thereby reducing the number of network requests and speeding up the overall time of the collage creation process:
+</br><br>
+
+![](weakref-finalizationregistry-demo-06.jpg)
+
+<br>
+Let's "play around" a little more, by replacing one of the images again and creating a new collage:
+</br><br>
+
+![](weakref-finalizationregistry-demo-07.gif)
+
+<br>
+This time the result is even more impressive. Of the 4 images selected, 3 of them were taken from the weak cache, and only one had to be downloaded from the network.
+The reduction in network load was about 75%. Impressive, isn't it?
+</br><br>
+
+![](weakref-finalizationregistry-demo-08.jpg)
+
+</br>
+
+Of course, it is important to remember, that such behavior is not guaranteed, and depends on the specific implementation and operation of the garbage collector.  
+
+Based on this, a completely logical question immediately arises: why do not we use an ordinary cache, where we can manage its entities ourselves, instead of relying on the garbage collector?
+That's right, in the vast majority of cases there is no need to use `WeakRef` and `FinalizationRegistry`.  
+
+Here, we simply demonstrated an alternative implementation of similar functionality, using a non-trivial approach with interesting language features.
+Still, we cannot rely on this example, if we need a constant and predictable result.
+
+You can [open this example in the sandbox](sandbox:weakref-finalizationregistry).
+
+## Summary
+
+`WeakRef` - designed to create weak references to objects, allowing them to be deleted from memory by the garbage collector if there are no longer strong references to them.
+This is beneficial for addressing excessive memory usage and optimizing the utilization of system resources in applications.
+
+`FinalizationRegistry` - is a tool for registering callbacks, that are executed when objects that are no longer strongly referenced, are destroyed.
+This allows releasing resources associated with the object or performing other necessary operations before deleting the object from memory.
\ No newline at end of file
diff --git a/1-js/99-js-misc/07-weakref-finalizationregistry/google-chrome-developer-tools.png b/1-js/99-js-misc/07-weakref-finalizationregistry/google-chrome-developer-tools.png
new file mode 100644
index 000000000..021637342
Binary files /dev/null and b/1-js/99-js-misc/07-weakref-finalizationregistry/google-chrome-developer-tools.png differ
diff --git a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-dom.view/index.css b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-dom.view/index.css
new file mode 100644
index 000000000..f6df812d0
--- /dev/null
+++ b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-dom.view/index.css
@@ -0,0 +1,49 @@
+.app {
+    display: flex;
+    flex-direction: column;
+    gap: 16px;
+}
+
+.start-messages {
+    width: fit-content;
+}
+
+.window {
+    width: 100%;
+    border: 2px solid #464154;
+    overflow: hidden;
+}
+
+.window__header {
+    position: sticky;
+    padding: 8px;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    background-color: #736e7e;
+}
+
+.window__title {
+    margin: 0;
+    font-size: 24px;
+    font-weight: 700;
+    color: white;
+    letter-spacing: 1px;
+}
+
+.window__button {
+    padding: 4px;
+    background: #4f495c;
+    outline: none;
+    border: 2px solid #464154;
+    color: white;
+    font-size: 16px;
+    cursor: pointer;
+}
+
+.window__body {
+    height: 250px;
+    padding: 16px;
+    overflow: scroll;
+    background-color: #736e7e33;
+}
\ No newline at end of file
diff --git a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-dom.view/index.html b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-dom.view/index.html
new file mode 100644
index 000000000..7f93af4c7
--- /dev/null
+++ b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-dom.view/index.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML>
+<html lang="en">
+
+<head>
+  <meta charset="utf-8">
+  <link rel="stylesheet" href="index.css">
+  <title>WeakRef DOM Logger</title>
+</head>
+
+<body>
+
+<div class="app">
+  <button class="start-messages">Start sending messages</button>
+  <div class="window">
+    <div class="window__header">
+      <p class="window__title">Messages:</p>
+      <button class="window__button">Close</button>
+    </div>
+    <div class="window__body">
+      No messages.
+    </div>
+  </div>
+</div>
+
+
+<script type="module" src="index.js"></script>
+</body>
+</html>
diff --git a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-dom.view/index.js b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-dom.view/index.js
new file mode 100644
index 000000000..ea55b4478
--- /dev/null
+++ b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-dom.view/index.js
@@ -0,0 +1,24 @@
+const startMessagesBtn = document.querySelector('.start-messages'); // (1)
+const closeWindowBtn = document.querySelector('.window__button'); // (2)
+const windowElementRef = new WeakRef(document.querySelector(".window__body")); // (3)
+
+startMessagesBtn.addEventListener('click', () => { // (4)
+    startMessages(windowElementRef);
+    startMessagesBtn.disabled = true;
+});
+
+closeWindowBtn.addEventListener('click', () =>  document.querySelector(".window__body").remove()); // (5)
+
+
+const startMessages = (element) => {
+    const timerId = setInterval(() => { // (6)
+        if (element.deref()) { // (7)
+            const payload = document.createElement("p");
+            payload.textContent = `Message: System status OK: ${new Date().toLocaleTimeString()}`;
+            element.deref().append(payload);
+        } else { // (8)
+            alert("The element has been deleted."); // (9)
+            clearInterval(timerId);
+        }
+    }, 1000);
+};
\ No newline at end of file
diff --git a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-01.svg b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-01.svg
new file mode 100644
index 000000000..2a507dbcd
--- /dev/null
+++ b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-01.svg
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg viewBox="-38.324 -109.673 191.121 281.642" width="191.121px" height="281.642px" xmlns="http://www.w3.org/2000/svg" xmlns:bx="https://boxy-svg.com">
+  <defs>
+    <style bx:fonts="Open Sans">@import url(https://fonts.googleapis.com/css2?family=Open+Sans%3Aital%2Cwght%400%2C300%3B0%2C400%3B0%2C500%3B0%2C600%3B0%2C700%3B0%2C800%3B1%2C300%3B1%2C400%3B1%2C500%3B1%2C600%3B1%2C700%3B1%2C800&amp;display=swap);</style>
+  </defs>
+  <g id="garbage-collection" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1" transform="matrix(1.6492669582366946, 0, 0, 1.6492669582366946, -81.42222595214844, 62.8305015563965)" style="">
+    <g id="memory-user-john-admin.svg" transform="matrix(1, 0, 0, 1, -1.759865, 4.803441)">
+      <text id="user" style="fill: rgb(175, 110, 36); font-family: 'Open Sans'; font-size: 14px; font-weight: 600; white-space: pre;" transform="matrix(0.735667, 0, 0, 0.753868, 7.56361, 10.722544)" x="31.917" y="-40.191">user</text>
+      <path id="Rectangle-4" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M 39.02 4.206 L 125.8 4.206 L 125.8 48.227 L 39.02 48.227 L 39.02 4.206 Z" style=""/>
+      <text id="name:-&quot;John&quot;" style="fill: rgb(175, 110, 36); font-family: 'Open Sans'; font-size: 9px; font-weight: 500; white-space: pre;" x="54.086" y="34.58">name: "John"</text>
+      <text id="Object" style="fill: rgb(175, 110, 36); font-family: 'Open Sans'; font-size: 10.5px; font-weight: 500; white-space: pre;" x="64.679" y="23.487">Object</text>
+      <path id="Rectangle-1" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M 36.398 -102.608 L 129.398 -102.608 L 129.398 -76.608 L 36.398 -76.608 L 36.398 -102.608 Z"/>
+      <text id="&lt;global&gt;" style="fill: rgb(175, 110, 36); font-family: 'Open Sans'; font-size: 10.6px; font-weight: 500; white-space: pre;" x="59.233" y="-86.001"> &lt;global&gt;</text>
+      <path d="M 105.999 1.57 L 113.013 13.895 L 98.985 13.895 L 105.999 1.57 Z" style="fill-rule: nonzero; fill: rgb(172, 67, 67);" transform="matrix(1, 0, 0, -1, 0, 0)" bx:shape="triangle 98.985 1.57 14.028 12.325 0.5 0 1@df7d9fa9"/>
+      <g>
+        <rect x="105.024" y="-69.436" width="1.99" height="5.009" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);"/>
+        <rect x="105.014" y="-59.02" width="1.99" height="5.009" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);"/>
+        <rect x="105.014" y="-48.877" width="1.99" height="5.009" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);"/>
+      </g>
+      <g transform="matrix(1, 0, 0, 1.024052, -0.03572, 31.45084)" style="">
+        <rect x="105.024" y="-69.051" width="1.99" height="5.009" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);"/>
+        <rect x="105.014" y="-59.02" width="1.99" height="5.009" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);"/>
+        <rect x="105.014" y="-48.877" width="1.99" height="5.009" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);"/>
+      </g>
+      <g transform="matrix(1, 0, 0, 1, -9.930843, 12.564639)">
+        <path d="M 66.874 14.118 L 73.888 26.443 L 59.86 26.443 L 66.874 14.118 Z" style="fill-rule: nonzero; fill: rgb(192, 99, 52);" transform="matrix(1, 0, 0, -1, 0, 0)" bx:shape="triangle 59.86 14.118 14.028 12.325 0.5 0 1@9d4d6098"/>
+        <rect x="65.833" y="-81.984" width="2.056" height="55.884" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(192, 99, 52);"/>
+      </g>
+      <text id="text-1" style="fill: rgb(172, 67, 67); font-family: 'Open Sans'; font-size: 14px; font-weight: 600; white-space: pre;" transform="matrix(0.735667, 0, 0, 0.753868, 87.03299, 10.790039)" x="31.917" y="-40.191">admin</text>
+    </g>
+  </g>
+</svg>
\ No newline at end of file
diff --git a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-02.svg b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-02.svg
new file mode 100644
index 000000000..6cc199a12
--- /dev/null
+++ b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-02.svg
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg viewBox="-56.888 -212.944 192.167 294.011" width="178.044px" height="272.403px" xmlns="http://www.w3.org/2000/svg" xmlns:bx="https://boxy-svg.com">
+  <defs>
+    <style bx:fonts="Open Sans">@import url(https://fonts.googleapis.com/css2?family=Open+Sans%3Aital%2Cwght%400%2C300%3B0%2C400%3B0%2C500%3B0%2C600%3B0%2C700%3B0%2C800%3B1%2C300%3B1%2C400%3B1%2C500%3B1%2C600%3B1%2C700%3B1%2C800&amp;display=swap);</style>
+  </defs>
+  <g id="garbage-collection" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1" transform="matrix(1.708757996559143, 0, 0, 1.708757996559143, -109.71231842041016, -35.19435119628906)" style="">
+    <g id="memory-user-john-admin.svg" transform="matrix(1, 0, 0, 1, -1.759865, 4.803441)">
+      <path id="Rectangle-4" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M 39.02 4.206 L 125.8 4.206 L 125.8 48.227 L 39.02 48.227 L 39.02 4.206 Z" style=""/>
+      <path id="Rectangle-1" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M 36.398 -102.608 L 129.398 -102.608 L 129.398 -76.608 L 36.398 -76.608 L 36.398 -102.608 Z"/>
+      <text id="&lt;global&gt;" style="fill: rgb(175, 110, 36); font-family: 'Open Sans'; font-size: 10.8px; font-weight: 500; white-space: pre;" x="57.977" y="-85.926"> &lt;global&gt;</text>
+      <path d="M 105.999 1.57 L 113.013 13.895 L 98.985 13.895 L 105.999 1.57 Z" style="fill-rule: nonzero; fill: rgb(172, 67, 67);" transform="matrix(1, 0, 0, -1, 0, 0)" bx:shape="triangle 98.985 1.57 14.028 12.325 0.5 0 1@df7d9fa9"/>
+      <g style="" transform="matrix(0.7989, 0, 0, 0.7989, 13.076554, 6.083323)">
+        <text id="name:-&quot;John&quot;" style="fill: rgb(175, 110, 36); font-family: 'Open Sans'; font-size: 12px; font-weight: 500; white-space: pre;" x="48.212" y="37.89">name: "John"</text>
+        <text id="Object" style="fill: rgb(175, 110, 36); font-family: 'Open Sans'; font-size: 14px; font-weight: 500; white-space: pre;" x="61.598" y="23.794">Object</text>
+      </g>
+      <g>
+        <rect x="105.024" y="-69.436" width="1.99" height="5.009" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);"/>
+        <rect x="105.014" y="-59.02" width="1.99" height="5.009" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);"/>
+        <rect x="105.014" y="-48.877" width="1.99" height="5.009" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);"/>
+      </g>
+      <g transform="matrix(1, 0, 0, 1.024052, -0.03572, 31.45084)" style="">
+        <rect x="105.024" y="-69.051" width="1.99" height="5.009" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);"/>
+        <rect x="105.014" y="-59.02" width="1.99" height="5.009" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);"/>
+        <rect x="105.014" y="-48.877" width="1.99" height="5.009" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);"/>
+      </g>
+      <text id="text-1" style="fill: rgb(172, 67, 67); font-family: 'Open Sans'; font-size: 14px; font-weight: 600; white-space: pre;" transform="matrix(0.735667, 0, 0, 0.753868, 86.426659, 10.790039)" x="31.917" y="-40.191">admin</text>
+    </g>
+  </g>
+  <g transform="matrix(0.529145, 0, 0, 0.529145, -21.841589, -83.135681)" style="">
+    <path d="M80.179,13.758c-18.342-18.342-48.08-18.342-66.422,0c-18.342,18.341-18.342,48.08,0,66.421 c18.342,18.342,48.08,18.342,66.422,0C98.521,61.837,98.521,32.099,80.179,13.758z M44.144,83.117 c-4.057,0-7.001-3.071-7.001-7.305c0-4.291,2.987-7.404,7.102-7.404c4.123,0,7.001,3.044,7.001,7.404 C51.246,80.113,48.326,83.117,44.144,83.117z M54.73,44.921c-4.15,4.905-5.796,9.117-5.503,14.088l0.097,2.495 c0.011,0.062,0.017,0.125,0.017,0.188c0,0.58-0.47,1.051-1.05,1.051c-0.004-0.001-0.008-0.001-0.012,0h-7.867 c-0.549,0-1.005-0.423-1.047-0.97l-0.202-2.623c-0.676-6.082,1.508-12.218,6.494-18.202c4.319-5.087,6.816-8.865,6.816-13.145 c0-4.829-3.036-7.536-8.548-7.624c-3.403,0-7.242,1.171-9.534,2.913c-0.264,0.201-0.607,0.264-0.925,0.173 s-0.575-0.327-0.693-0.636l-2.42-6.354c-0.169-0.442-0.02-0.943,0.364-1.224c3.538-2.573,9.441-4.235,15.041-4.235 c12.36,0,17.894,7.975,17.894,15.877C63.652,33.765,59.785,38.919,54.73,44.921z" style="fill: rgb(172, 67, 67);"/>
+  </g>
+  <rect x="-52.271" y="-25.92" width="160.339" height="87.431" style="fill: rgba(216, 216, 216, 0); stroke: rgb(172, 67, 67); stroke-width: 3px;"/>
+</svg>
\ No newline at end of file
diff --git a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-03.svg b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-03.svg
new file mode 100644
index 000000000..949a14f9f
--- /dev/null
+++ b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-03.svg
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg viewBox="-46.534 -212.944 529.701 256.516" width="540.055px" height="256.516px" xmlns="http://www.w3.org/2000/svg" xmlns:bx="https://boxy-svg.com">
+  <defs>
+    <style bx:fonts="Open Sans">@import url(https://fonts.googleapis.com/css2?family=Open+Sans%3Aital%2Cwght%400%2C300%3B0%2C400%3B0%2C500%3B0%2C600%3B0%2C700%3B0%2C800%3B1%2C300%3B1%2C400%3B1%2C500%3B1%2C600%3B1%2C700%3B1%2C800&amp;display=swap);</style>
+  </defs>
+  <g id="memory-user-john-admin.svg" transform="matrix(1.7087579965591428, 0, 0, 1.7087579965591428, -443.0394287109375, -47.16891479492199)" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1">
+    <path id="path-1" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M 234.068 -87.403 L 333.494 -87.403 L 333.494 -57.762 L 234.068 -57.762 L 234.068 -87.403 Z" style=""/>
+    <path id="path-2" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M 336.651 -87.403 L 492.549 -87.403 L 492.549 -57.762 L 336.651 -57.762 L 336.651 -87.403 Z" style=""/>
+    <path id="path-3" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M 234.068 -53.711 L 333.494 -53.711 L 333.494 -24.07 L 234.068 -24.07 L 234.068 -53.711 Z" style=""/>
+    <path id="path-4" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M 336.651 -53.711 L 492.783 -53.711 L 492.783 -24.07 L 336.651 -24.07 L 336.651 -53.711 Z" style=""/>
+    <path id="path-5" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M 234.189 -20.462 L 333.615 -20.462 L 333.615 9.179 L 234.189 9.179 L 234.189 -20.462 Z" style=""/>
+    <path id="path-6" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M 336.791 -20.462 L 493.057 -20.462 L 493.057 9.179 L 336.791 9.179 L 336.791 -20.462 Z" style=""/>
+    <path id="path-7" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M 234.068 13.088 L 333.494 13.088 L 333.494 43.59 L 234.068 43.59 L 234.068 13.088 Z" style=""/>
+    <path id="path-8" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M 336.651 13.088 L 493.054 13.088 L 493.054 43.59 L 336.651 43.59 L 336.651 13.088 Z" style=""/>
+    <text id="&lt;global&gt;" style="fill: rgb(175, 110, 36); font-family: 'Open Sans'; font-size: 11.5772px; font-weight: 600; line-height: 19.9484px; white-space: pre;" transform="matrix(1.374145, 0, 0, 1.314286, -102.41082, 25.040792)" x="263.861" y="-70.535">key</text>
+    <text id="text-2" style="fill: rgb(175, 110, 36); font-family: 'Open Sans'; font-size: 11.5772px; font-weight: 600; line-height: 19.9484px; white-space: pre;" transform="matrix(1.374145, 0, 0, 1.314286, 13.577469, 25.203112)" x="263.861" y="-70.535">value</text>
+    <text id="text-3" style="fill: rgb(175, 110, 36); font-family: 'Open Sans'; font-size: 14px; white-space: pre;" transform="matrix(1.071654, 0, 0, 1.142641, -43.57296, 46.390514)" x="263.861" y="-70.535">image-01.jpg</text>
+    <text id="text-4" style="fill: rgb(175, 110, 36); font-family: 'Open Sans'; font-size: 14px; white-space: pre;" transform="matrix(1.054877, 0, 0, 1.142641, -39.02475, 80.086914)" x="263.861" y="-70.535">image-02.jpg</text>
+    <text id="text-5" style="fill: rgb(175, 110, 36); font-family: 'Open Sans'; font-size: 14px; white-space: pre;" transform="matrix(1.054877, 0, 0, 1.142641, -39.468063, 113.637062)" x="263.861" y="-70.535">image-03.jpg</text>
+    <g transform="matrix(0.000041, -1, 1.521843, 0.000133, 289.017426, 2.750529)" style="transform-origin: 105.999px -35.503px;">
+      <path d="M 105.537 7.964 L 110.918 13.895 L 100.155 13.895 L 105.537 7.964 Z" style="fill-rule: nonzero; fill: rgb(172, 67, 67);" transform="matrix(1, 0, 0, -1, 0, 0)" bx:shape="triangle 100.155 7.964 10.763 5.931 0.5 0 1@87a4267a"/>
+      <g>
+        <rect x="105.024" y="-69.436" width="1.99" height="5.009" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);"/>
+        <rect x="105.014" y="-59.02" width="1.99" height="5.009" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);"/>
+        <rect x="105.014" y="-48.877" width="1.99" height="5.009" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);"/>
+      </g>
+      <g transform="matrix(1, 0, 0, 1.024052, -0.03572, 31.45084)" style="">
+        <rect x="105.024" y="-69.051" width="1.99" height="5.009" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);"/>
+        <rect x="105.014" y="-59.02" width="1.99" height="5.009" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);"/>
+        <rect x="105.014" y="-48.877" width="1.99" height="5.009" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);"/>
+      </g>
+    </g>
+    <text id="text-6" style="fill: rgb(172, 67, 67); font-family: 'Open Sans'; font-size: 9.73113px; font-style: italic; white-space: pre;" transform="matrix(1.038937, 0, 0, 1.142641, 69.710487, 42.749538)" x="263.861" y="-70.535">WeakRef object</text>
+    <g transform="matrix(0.441364, 0, 0, 0.412845, 420.761139, -59.372555)" style="">
+      <g>
+        <path d=" M 58.15 23.65 L 58.15 20 54.25 20 Q 50.95 20 49.35 22.2 47.75 24.4 47.75 27.7 L 47.05 41.45 Q 46.8 43.25 46.1 44.6 45.45 46.05 44.35 47.05 43.9 47.55 43.2 47.75 42.8 47.95 41.85 48.15 L 41.85 51.6 Q 42.95 51.8 43.2 51.9 43.9 52.1 44.35 52.45 45.45 53.25 46.05 54.55 47.65 58.15 47.65 61.65 L 47.65 72.1 Q 47.65 75.7 49.45 77.85 51.25 80 54.1 80 L 58.15 80 58.15 76.25 55.25 76.25 Q 54.1 76.25 53.35 75.65 52.55 74.95 52.2 74 L 51.65 71.75 51.5 69.45 51.35 59.8 Q 51.35 57.55 50.8 55.8 50.15 53.65 49.65 52.8 48.8 51.5 47.9 50.8 47.05 50.1 46.1 49.75 47 49.3 47.8 48.7 48.95 47.85 49.6 46.75 50.1 45.8 50.75 43.7 51.35 41.85 51.35 39.45 L 51.55 28.05 52 25.9 Q 52.35 24.85 53.15 24.2 53.9 23.65 55.25 23.65 L 58.15 23.65 Z" style="fill: rgb(175, 110, 36);"/>
+      </g>
+    </g>
+    <g transform="matrix(-0.441364, 0, 0, -0.412845, 414.750092, -88.816727)" style="transform-origin: 50px 50px;">
+      <g>
+        <path d="M 14.392 23.65 L 14.392 20 L 10.492 20 C 8.292 20 6.659 20.733 5.592 22.2 C 4.525 23.667 3.992 25.5 3.992 27.7 L 3.292 41.45 C 3.125 42.65 2.809 43.7 2.342 44.6 C 1.909 45.567 1.325 46.383 0.592 47.05 C 0.292 47.383 -0.091 47.617 -0.558 47.75 C -0.825 47.883 -1.275 48.017 -1.908 48.15 L -1.908 51.6 C -1.175 51.733 -0.725 51.833 -0.558 51.9 C -0.091 52.033 0.292 52.217 0.592 52.45 C 1.325 52.983 1.892 53.683 2.292 54.55 C 3.359 56.95 3.892 59.317 3.892 61.65 L 3.892 72.1 C 3.892 74.5 4.492 76.417 5.692 77.85 C 6.892 79.283 8.442 80 10.342 80 L 14.392 80 L 14.392 76.25 L 11.492 76.25 C 10.725 76.25 10.092 76.05 9.592 75.65 C 9.059 75.183 8.675 74.633 8.442 74 L 7.892 71.75 L 7.742 69.45 L 7.592 59.8 C 7.592 58.3 7.409 56.967 7.042 55.8 C 6.609 54.367 6.225 53.367 5.892 52.8 C 5.325 51.933 4.742 51.267 4.142 50.8 C 3.575 50.333 2.975 49.983 2.342 49.75 C 2.942 49.45 3.509 49.1 4.042 48.7 C 4.809 48.133 5.409 47.483 5.842 46.75 C 6.175 46.117 6.559 45.1 6.992 43.7 C 7.392 42.467 7.592 41.05 7.592 39.45 L 7.792 28.05 L 8.242 25.9 C 8.475 25.2 8.859 24.633 9.392 24.2 C 9.892 23.833 10.592 23.65 11.492 23.65 L 14.392 23.65 Z" style="fill: rgb(175, 110, 36);"/>
+        <path d="M 255.632 27.46 L 268.667 47.91 L 242.597 47.91 L 255.632 27.46 Z" style="fill-rule: nonzero; fill: rgb(172, 67, 67);" transform="matrix(-0.000038, 1, 1, 0.000093, 86.522967, -302.258205)" bx:shape="triangle 242.597 27.46 26.07 20.45 0.5 0 1@97f9cc39"/>
+        <rect x="254.391" y="-239.419" width="4.82" height="17.271" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);" transform="matrix(-0.000038, 1, -1, -0.000093, 86.522728, -302.258331)"/>
+        <rect x="254.367" y="-203.504" width="4.82" height="17.271" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);" transform="matrix(-0.000038, 1, -1, -0.000093, 86.522728, -302.258331)"/>
+        <rect x="254.367" y="-168.53" width="4.82" height="17.271" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);" transform="matrix(-0.000038, 1, -1, -0.000093, 86.522728, -302.258331)"/>
+        <rect x="254.391" y="-243.818" width="4.82" height="17.687" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);" transform="matrix(-0.000038, 1, -1, -0.000093, -21.921179, -302.35498)"/>
+        <rect x="254.367" y="-208.398" width="4.82" height="17.687" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);" transform="matrix(-0.000038, 1, -1, -0.000093, -21.921179, -302.35498)"/>
+        <rect x="254.367" y="-172.584" width="4.82" height="17.687" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);" transform="matrix(-0.000038, 1, -1, -0.000093, -21.921179, -302.35498)"/>
+        <text id="text-7" style="fill: rgb(172, 67, 67); font-family: 'Open Sans'; font-size: 9.73113px; font-style: italic; white-space: pre;" transform="matrix(-2.353923, 0, 0, -2.767724, 945.975708, -228.376572)" x="263.861" y="-70.535">WeakRef object</text>
+        <path d="M 108.749 -57.365 L 108.749 -61.015 L 104.849 -61.015 C 102.649 -61.015 101.015 -60.281 99.949 -58.815 C 98.882 -57.348 98.349 -55.515 98.349 -53.315 L 97.649 -39.565 C 97.482 -38.365 97.165 -37.315 96.699 -36.415 C 96.265 -35.448 95.682 -34.631 94.949 -33.965 C 94.649 -33.631 94.265 -33.398 93.799 -33.265 C 93.532 -33.131 93.082 -32.998 92.449 -32.865 L 92.449 -29.415 C 93.182 -29.281 93.632 -29.181 93.799 -29.115 C 94.265 -28.981 94.649 -28.798 94.949 -28.565 C 95.682 -28.031 96.249 -27.331 96.649 -26.465 C 97.715 -24.065 98.249 -21.698 98.249 -19.365 L 98.249 -8.915 C 98.249 -6.515 98.849 -4.598 100.049 -3.165 C 101.249 -1.731 102.799 -1.015 104.699 -1.015 L 108.749 -1.015 L 108.749 -4.765 L 105.849 -4.765 C 105.082 -4.765 104.449 -4.965 103.949 -5.365 C 103.415 -5.831 103.032 -6.381 102.799 -7.015 L 102.249 -9.265 L 102.099 -11.565 L 101.949 -21.215 C 101.949 -22.715 101.765 -24.048 101.399 -25.215 C 100.965 -26.648 100.582 -27.648 100.249 -28.215 C 99.682 -29.081 99.099 -29.748 98.499 -30.215 C 97.932 -30.681 97.332 -31.031 96.699 -31.265 C 97.299 -31.565 97.865 -31.915 98.399 -32.315 C 99.165 -32.881 99.765 -33.531 100.199 -34.265 C 100.532 -34.898 100.915 -35.915 101.349 -37.315 C 101.749 -38.548 101.949 -39.965 101.949 -41.565 L 102.149 -52.965 L 102.599 -55.115 C 102.832 -55.815 103.215 -56.381 103.749 -56.815 C 104.249 -57.181 104.949 -57.365 105.849 -57.365 L 108.749 -57.365 Z" style="fill: rgb(175, 110, 36); transform-box: fill-box; transform-origin: 50% 50%;" transform="matrix(-1, 0, 0, -1, -0.000004, -0.000028)"/>
+        <path d="M 15.325 -57.155 L 15.325 -60.805 L 11.425 -60.805 C 9.225 -60.805 7.591 -60.072 6.525 -58.605 C 5.458 -57.139 4.925 -55.305 4.925 -53.105 L 4.225 -39.355 C 4.058 -38.155 3.741 -37.105 3.275 -36.205 C 2.841 -35.239 2.258 -34.422 1.525 -33.755 C 1.225 -33.422 0.841 -33.189 0.375 -33.055 C 0.108 -32.922 -0.342 -32.789 -0.975 -32.655 L -0.975 -29.205 C -0.242 -29.072 0.208 -28.972 0.375 -28.905 C 0.841 -28.772 1.225 -28.589 1.525 -28.355 C 2.258 -27.822 2.825 -27.122 3.225 -26.255 C 4.291 -23.855 4.825 -21.489 4.825 -19.155 L 4.825 -8.705 C 4.825 -6.305 5.425 -4.389 6.625 -2.955 C 7.825 -1.522 9.375 -0.805 11.275 -0.805 L 15.325 -0.805 L 15.325 -4.555 L 12.425 -4.555 C 11.658 -4.555 11.025 -4.755 10.525 -5.155 C 9.991 -5.622 9.608 -6.172 9.375 -6.805 L 8.825 -9.055 L 8.675 -11.355 L 8.525 -21.005 C 8.525 -22.505 8.341 -23.839 7.975 -25.005 C 7.541 -26.439 7.158 -27.439 6.825 -28.005 C 6.258 -28.872 5.675 -29.539 5.075 -30.005 C 4.508 -30.472 3.908 -30.822 3.275 -31.055 C 3.875 -31.355 4.441 -31.705 4.975 -32.105 C 5.741 -32.672 6.341 -33.322 6.775 -34.055 C 7.108 -34.689 7.491 -35.705 7.925 -37.105 C 8.325 -38.339 8.525 -39.755 8.525 -41.355 L 8.725 -52.755 L 9.175 -54.905 C 9.408 -55.605 9.791 -56.172 10.325 -56.605 C 10.825 -56.972 11.525 -57.155 12.425 -57.155 L 15.325 -57.155 Z" style="fill: rgb(175, 110, 36);"/>
+      </g>
+    </g>
+  </g>
+  <g transform="matrix(0.3355039954185486, 0, 0, 0.3355039954185486, 67.31304168701172, -387.90008544921875)" style="">
+    <g transform="matrix(0.178489, 0, 0, 0.175502, 747.077209, 776.317017)" style="">
+      <path d="M 267.184 437.8 C 267.184 466.3 290.384 489.4 318.784 489.4 L 704.984 489.4 C 733.484 489.4 756.584 466.2 756.584 437.8 L 756.584 51.6 C 756.584 23.1 733.384 0 704.984 0 L 318.784 0 C 290.284 0 267.184 23.2 267.184 51.6 C 267.184 51.6 267.184 437.8 267.184 437.8 Z M 704.984 464.9 L 318.784 464.9 C 303.884 464.9 291.684 452.7 291.684 437.8 L 291.684 373.3 L 384.484 280.5 L 463.784 359.8 C 468.584 364.6 476.284 364.6 481.084 359.8 L 624.284 216.6 L 732.084 324.4 L 732.084 437.8 C 732.084 452.7 719.884 464.9 704.984 464.9 Z M 318.784 24.5 L 704.984 24.5 C 719.884 24.5 732.084 36.7 732.084 51.6 L 732.084 289.7 L 632.884 190.6 C 628.084 185.8 620.384 185.8 615.584 190.6 L 472.384 333.8 L 393.084 254.5 C 388.284 249.7 380.584 249.7 375.784 254.5 L 291.684 338.6 L 291.684 51.6 C 291.684 36.7 303.884 24.5 318.784 24.5 Z" style="fill: rgb(175, 110, 36);"/>
+      <path d="M 418.884 196.1 C 453.284 196.1 481.184 168.1 481.184 133.8 C 481.184 99.5 453.184 71.5 418.884 71.5 C 384.584 71.5 356.584 99.5 356.584 133.8 C 356.584 168.1 384.484 196.1 418.884 196.1 Z M 418.884 96 C 439.784 96 456.684 113 456.684 133.8 C 456.684 154.6 439.684 171.6 418.884 171.6 C 398.084 171.6 381.084 154.6 381.084 133.8 C 381.084 113 397.984 96 418.884 96 Z" style="fill: rgb(175, 110, 36);"/>
+    </g>
+  </g>
+  <path d="M -161.945 -20.71 L -152.75 -5.287 L -171.141 -5.287 L -161.945 -20.71 Z" style="fill-rule: nonzero; fill: rgb(172, 67, 67);" transform="matrix(0.00004100000296602957, -0.9999999999999999, -0.9999999999999999, -0.00008700000762473792, 281.6644897460937, -149.34440612792974)" bx:shape="triangle -171.141 -20.71 18.391 15.423 0.5 0 1@d86e5ee8"/>
+  <rect x="179.461" y="-180.566" width="3.4" height="13.026" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);" transform="matrix(0.00004100000296602957, -0.9999999999999999, 0.9999999999999999, 0.00008700000762473792, 323.0706176757812, 192.94052124023426)"/>
+  <rect x="179.444" y="-153.479" width="3.4" height="13.026" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);" transform="matrix(0.00004100000296602957, -0.9999999999999999, 0.9999999999999999, 0.00008700000762473792, 323.0706176757812, 192.94052124023426)"/>
+  <rect x="179.444" y="-127.103" width="3.4" height="13.026" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);" transform="matrix(0.00004100000296602957, -0.9999999999999999, 0.9999999999999999, 0.00008700000762473792, 323.0706176757812, 192.94052124023426)"/>
+  <rect x="179.461" y="-183.883" width="3.4" height="13.339" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);" transform="matrix(0.00004100000296602957, -0.9999999999999999, 0.9999999999999999, 0.00008700000762473792, 404.85729980468744, 193.00871276855457)"/>
+  <rect x="179.444" y="-157.171" width="3.4" height="13.339" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);" transform="matrix(0.00004100000296602957, -0.9999999999999999, 0.9999999999999999, 0.00008700000762473792, 404.85729980468744, 193.00871276855457)"/>
+  <rect x="179.444" y="-130.16" width="3.4" height="13.339" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);" transform="matrix(0.00004100000296602957, -0.9999999999999999, 0.9999999999999999, 0.00008700000762473792, 404.85729980468744, 193.00871276855457)"/>
+  <text id="text-8" style="fill: rgb(172, 67, 67); font-family: 'Open Sans'; font-size: 9.73113px; font-style: italic; white-space: pre;" transform="matrix(1.7752919197082517, 0, 0, 1.9524970054626463, -325.1152648925781, 140.82048034667957)" x="263.861" y="-70.535">WeakRef object</text>
+  <path d="M 318.601 -16.998 L 318.601 -19.573 L 315.66 -19.573 C 314.001 -19.573 312.769 -19.055 311.964 -18.021 C 311.16 -16.986 310.758 -15.693 310.758 -14.141 L 310.23 -4.441 C 310.104 -3.594 309.865 -2.853 309.513 -2.218 C 309.186 -1.536 308.746 -0.96 308.193 -0.49 C 307.967 -0.255 307.678 -0.09 307.326 0.004 C 307.125 0.098 306.786 0.192 306.308 0.286 L 306.308 2.72 C 306.861 2.814 307.2 2.884 307.326 2.931 C 307.678 3.025 307.967 3.155 308.193 3.319 C 308.746 3.696 309.174 4.189 309.475 4.801 C 310.28 6.494 310.682 8.163 310.682 9.81 L 310.682 17.181 C 310.682 18.875 311.135 20.227 312.04 21.238 C 312.945 22.249 314.114 22.755 315.547 22.755 L 318.601 22.755 L 318.601 20.109 L 316.414 20.109 C 315.836 20.109 315.358 19.968 314.981 19.686 C 314.579 19.357 314.29 18.969 314.114 18.522 L 313.699 16.935 L 313.586 15.312 L 313.473 8.504 C 313.473 7.446 313.334 6.506 313.058 5.683 C 312.731 4.671 312.442 3.966 312.191 3.566 C 311.763 2.955 311.323 2.485 310.871 2.155 C 310.443 1.826 309.991 1.579 309.513 1.415 C 309.966 1.203 310.393 0.956 310.795 0.674 C 311.373 0.274 311.826 -0.184 312.153 -0.702 C 312.404 -1.148 312.693 -1.866 313.02 -2.853 C 313.322 -3.723 313.473 -4.723 313.473 -5.852 L 313.623 -13.894 L 313.963 -15.41 C 314.139 -15.904 314.428 -16.304 314.83 -16.61 C 315.207 -16.868 315.735 -16.998 316.414 -16.998 L 318.601 -16.998 Z" style="fill: rgb(175, 110, 36);" transform="matrix(0.9999999999999999, 0, 0, 0.9999999999999999, 0, -1.1368683772161603e-13)"/>
+  <path d="M 389.058 -17.145 L 389.058 -19.72 L 386.117 -19.72 C 384.458 -19.72 383.226 -19.203 382.421 -18.168 C 381.617 -17.134 381.215 -15.84 381.215 -14.288 L 380.687 -4.588 C 380.561 -3.742 380.322 -3.001 379.97 -2.366 C 379.644 -1.684 379.204 -1.108 378.651 -0.638 C 378.424 -0.403 378.135 -0.238 377.783 -0.144 C 377.582 -0.05 377.243 0.044 376.765 0.138 L 376.765 2.572 C 377.318 2.666 377.658 2.737 377.783 2.784 C 378.135 2.878 378.424 3.007 378.651 3.172 C 379.204 3.548 379.631 4.042 379.933 4.653 C 380.737 6.346 381.139 8.016 381.139 9.662 L 381.139 17.034 C 381.139 18.727 381.592 20.079 382.497 21.09 C 383.402 22.101 384.571 22.607 386.004 22.607 L 389.058 22.607 L 389.058 19.961 L 386.871 19.961 C 386.293 19.961 385.815 19.82 385.438 19.538 C 385.036 19.209 384.747 18.821 384.571 18.374 L 384.156 16.787 L 384.043 15.164 L 383.93 8.357 C 383.93 7.299 383.792 6.358 383.515 5.535 C 383.188 4.524 382.899 3.818 382.648 3.419 C 382.22 2.807 381.78 2.337 381.328 2.008 C 380.901 1.679 380.448 1.432 379.97 1.267 C 380.423 1.055 380.85 0.808 381.253 0.526 C 381.831 0.127 382.283 -0.332 382.61 -0.849 C 382.861 -1.296 383.151 -2.013 383.477 -3.001 C 383.779 -3.871 383.93 -4.87 383.93 -5.999 L 384.081 -14.041 L 384.42 -15.558 C 384.596 -16.052 384.885 -16.452 385.287 -16.757 C 385.664 -17.016 386.192 -17.145 386.871 -17.145 L 389.058 -17.145 Z" style="fill: rgb(175, 110, 36); transform-origin: 382.912px 1.4435px;" transform="matrix(-1, 0, 0, -1, 0, -0.000015020371)"/>
+  <path d="M 333.236 -45.236 C 333.236 -43.558 334.625 -42.198 336.326 -42.198 L 359.453 -42.198 C 361.16 -42.198 362.543 -43.564 362.543 -45.236 L 362.543 -67.977 C 362.543 -69.655 361.154 -71.015 359.453 -71.015 L 336.326 -71.015 C 334.619 -71.015 333.236 -69.649 333.236 -67.977 C 333.236 -67.977 333.236 -45.236 333.236 -45.236 Z M 359.453 -43.641 L 336.326 -43.641 C 335.434 -43.641 334.703 -44.359 334.703 -45.236 L 334.703 -49.034 L 340.26 -54.499 L 345.009 -49.829 C 345.297 -49.547 345.758 -49.547 346.045 -49.829 L 354.62 -58.261 L 361.076 -51.914 L 361.076 -45.236 C 361.076 -44.359 360.345 -43.641 359.453 -43.641 Z M 336.326 -69.572 L 359.453 -69.572 C 360.345 -69.572 361.076 -68.854 361.076 -67.977 L 361.076 -53.957 L 355.135 -59.792 C 354.848 -60.075 354.387 -60.075 354.099 -59.792 L 345.524 -51.36 L 340.775 -56.029 C 340.488 -56.312 340.027 -56.312 339.739 -56.029 L 334.703 -51.077 L 334.703 -67.977 C 334.703 -68.854 335.434 -69.572 336.326 -69.572 Z" style="fill: rgb(175, 110, 36);" transform="matrix(0.9999999999999999, 0, 0, 0.9999999999999999, 0, -1.1368683772161603e-13)"/>
+  <path d="M 341.32 -59.468 C 343.38 -59.468 345.051 -61.117 345.051 -63.137 C 345.051 -65.156 343.374 -66.805 341.32 -66.805 C 339.266 -66.805 337.59 -65.156 337.59 -63.137 C 337.59 -61.117 339.26 -59.468 341.32 -59.468 Z M 341.32 -65.362 C 342.572 -65.362 343.584 -64.361 343.584 -63.137 C 343.584 -61.912 342.566 -60.911 341.32 -60.911 C 340.075 -60.911 339.057 -61.912 339.057 -63.137 C 339.057 -64.361 340.069 -65.362 341.32 -65.362 Z" style="fill: rgb(175, 110, 36);" transform="matrix(0.9999999999999999, 0, 0, 0.9999999999999999, 0, -1.1368683772161603e-13)"/>
+  <path d="M 333.305 13.146 C 333.305 14.824 334.694 16.184 336.395 16.184 L 359.522 16.184 C 361.229 16.184 362.612 14.818 362.612 13.146 L 362.612 -9.594 C 362.612 -11.272 361.223 -12.633 359.522 -12.633 L 336.395 -12.633 C 334.688 -12.633 333.305 -11.267 333.305 -9.594 C 333.305 -9.594 333.305 13.146 333.305 13.146 Z M 359.522 14.742 L 336.395 14.742 C 335.503 14.742 334.772 14.023 334.772 13.146 L 334.772 9.348 L 340.329 3.884 L 345.078 8.553 C 345.366 8.836 345.827 8.836 346.114 8.553 L 354.69 0.121 L 361.145 6.469 L 361.145 13.146 C 361.145 14.023 360.415 14.742 359.522 14.742 Z M 336.395 -11.19 L 359.522 -11.19 C 360.415 -11.19 361.145 -10.472 361.145 -9.594 L 361.145 4.426 L 355.205 -1.41 C 354.917 -1.692 354.456 -1.692 354.169 -1.41 L 345.593 7.022 L 340.844 2.353 C 340.557 2.07 340.096 2.07 339.809 2.353 L 334.772 7.305 L 334.772 -9.594 C 334.772 -10.472 335.503 -11.19 336.395 -11.19 Z" style="fill: rgb(175, 110, 36);" transform="matrix(0.9999999999999999, 0, 0, 0.9999999999999999, 0, -1.1368683772161603e-13)"/>
+  <path d="M 341.39 -1.086 C 343.45 -1.086 345.12 -2.735 345.12 -4.754 C 345.12 -6.774 343.444 -8.423 341.39 -8.423 C 339.335 -8.423 337.659 -6.774 337.659 -4.754 C 337.659 -2.735 339.329 -1.086 341.39 -1.086 Z M 341.39 -6.98 C 342.641 -6.98 343.653 -5.979 343.653 -4.754 C 343.653 -3.529 342.635 -2.528 341.39 -2.528 C 340.144 -2.528 339.126 -3.529 339.126 -4.754 C 339.126 -5.979 340.138 -6.98 341.39 -6.98 Z" style="fill: rgb(175, 110, 36);" transform="matrix(0.9999999999999999, 0, 0, 0.9999999999999999, 0, -1.1368683772161603e-13)"/>
+</svg>
\ No newline at end of file
diff --git a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-04.svg b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-04.svg
new file mode 100644
index 000000000..1177d6580
--- /dev/null
+++ b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-04.svg
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg viewBox="-44.887 -212.944 528.054 256.516" width="540.055px" height="256.516px" xmlns="http://www.w3.org/2000/svg" xmlns:bx="https://boxy-svg.com">
+  <defs>
+    <style bx:fonts="Open Sans">@import url(https://fonts.googleapis.com/css2?family=Open+Sans%3Aital%2Cwght%400%2C300%3B0%2C400%3B0%2C500%3B0%2C600%3B0%2C700%3B0%2C800%3B1%2C300%3B1%2C400%3B1%2C500%3B1%2C600%3B1%2C700%3B1%2C800&amp;display=swap);</style>
+  </defs>
+  <g id="memory-user-john-admin.svg" transform="matrix(1.708757996559143, 0, 0, 1.708757996559143, -443.0394287109375, -47.168914794921875)" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1">
+    <text id="name:-&quot;John&quot;" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="12" font-weight="normal" style="white-space: pre;" x="19.382" y="-93.28"><tspan x="49.382" y="36.72" style="font-size: 12px; word-spacing: 0px;">name: "John"</tspan></text>
+    <text id="Object" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal" style="white-space: pre;" x="17.598" y="-86.206"><tspan x="61.598" y="23.794" style="font-size: 14px; word-spacing: 0px;">Object</tspan></text>
+    <path id="Rectangle-1" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M 40.047 -102 L 133.047 -102 L 133.047 -76 L 40.047 -76 L 40.047 -102 Z"/>
+    <text id="text-1" style="fill: rgb(172, 67, 67); font-family: PTMono-Regular, 'PT Mono'; font-size: 14px; white-space: pre;" transform="matrix(0.735667, 0, 0, 0.753868, 86.426659, 10.790039)" x="31.917" y="-40.191">admin</text>
+    <path id="path-1" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M 234.068 -87.403 L 333.494 -87.403 L 333.494 -57.762 L 234.068 -57.762 L 234.068 -87.403 Z" style=""/>
+    <path id="path-2" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M 336.651 -87.403 L 492.549 -87.403 L 492.549 -57.762 L 336.651 -57.762 L 336.651 -87.403 Z" style=""/>
+    <path id="path-3" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M 234.068 -53.711 L 333.494 -53.711 L 333.494 -24.07 L 234.068 -24.07 L 234.068 -53.711 Z" style=""/>
+    <path id="path-4" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M 336.651 -53.711 L 492.783 -53.711 L 492.783 -24.07 L 336.651 -24.07 L 336.651 -53.711 Z" style=""/>
+    <path id="path-5" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M 234.189 -20.462 L 333.615 -20.462 L 333.615 9.179 L 234.189 9.179 L 234.189 -20.462 Z" style=""/>
+    <path id="path-6" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M 336.791 -20.462 L 493.057 -20.462 L 493.057 9.179 L 336.791 9.179 L 336.791 -20.462 Z" style=""/>
+    <path id="path-7" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M 234.068 13.088 L 333.494 13.088 L 333.494 43.59 L 234.068 43.59 L 234.068 13.088 Z" style=""/>
+    <path id="path-8" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M 336.651 13.088 L 493.054 13.088 L 493.054 43.59 L 336.651 43.59 L 336.651 13.088 Z" style=""/>
+    <text id="&lt;global&gt;" style="fill: rgb(175, 110, 36); font-family: 'Open Sans'; font-size: 11.5772px; font-weight: 600; line-height: 19.9484px; white-space: pre;" transform="matrix(1.374145, 0, 0, 1.314286, -102.41082, 25.040792)" x="263.861" y="-70.535">key</text>
+    <text id="text-2" style="fill: rgb(175, 110, 36); font-family: 'Open Sans'; font-size: 11.5772px; font-weight: 600; line-height: 19.9484px; white-space: pre;" transform="matrix(1.374145, 0, 0, 1.314286, 13.577469, 25.203112)" x="263.861" y="-70.535">value</text>
+    <text id="text-3" style="fill: rgb(175, 110, 36); font-family: 'Open Sans'; font-size: 14px; white-space: pre;" transform="matrix(1.071654, 0, 0, 1.142641, -43.57296, 46.390514)" x="263.861" y="-70.535">image-01.jpg</text>
+    <text id="text-4" style="fill: rgb(175, 110, 36); font-family: 'Open Sans'; font-size: 14px; white-space: pre;" transform="matrix(1.054877, 0, 0, 1.142641, -39.02475, 80.086914)" x="263.861" y="-70.535">image-02.jpg</text>
+    <text id="text-5" style="fill: rgb(175, 110, 36); font-family: 'Open Sans'; font-size: 14px; white-space: pre;" transform="matrix(1.054877, 0, 0, 1.142641, -39.468063, 113.637062)" x="263.861" y="-70.535">image-03.jpg</text>
+    <g transform="matrix(0.000041, -1, 1.521843, 0.000133, 289.017426, 2.750529)" style="transform-origin: 105.999px -35.503px;">
+      <path d="M 105.537 7.964 L 110.918 13.895 L 100.155 13.895 L 105.537 7.964 Z" style="fill-rule: nonzero; fill: rgb(172, 67, 67);" transform="matrix(1, 0, 0, -1, 0, 0)" bx:shape="triangle 100.155 7.964 10.763 5.931 0.5 0 1@87a4267a"/>
+      <g>
+        <rect x="105.024" y="-69.436" width="1.99" height="5.009" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);"/>
+        <rect x="105.014" y="-59.02" width="1.99" height="5.009" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);"/>
+        <rect x="105.014" y="-48.877" width="1.99" height="5.009" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);"/>
+      </g>
+      <g transform="matrix(1, 0, 0, 1.024052, -0.03572, 31.45084)" style="">
+        <rect x="105.024" y="-69.051" width="1.99" height="5.009" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);"/>
+        <rect x="105.014" y="-59.02" width="1.99" height="5.009" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);"/>
+        <rect x="105.014" y="-48.877" width="1.99" height="5.009" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);"/>
+      </g>
+    </g>
+    <text id="text-6" style="fill: rgb(172, 67, 67); font-family: 'Open Sans'; font-size: 9.73113px; font-style: italic; white-space: pre;" transform="matrix(1.038937, 0, 0, 1.142641, 69.710487, 42.749538)" x="263.861" y="-70.535">WeakRef object</text>
+    <g transform="matrix(0.441364, 0, 0, 0.412845, 420.761139, -59.372555)" style="">
+      <g>
+        <path d=" M 58.15 23.65 L 58.15 20 54.25 20 Q 50.95 20 49.35 22.2 47.75 24.4 47.75 27.7 L 47.05 41.45 Q 46.8 43.25 46.1 44.6 45.45 46.05 44.35 47.05 43.9 47.55 43.2 47.75 42.8 47.95 41.85 48.15 L 41.85 51.6 Q 42.95 51.8 43.2 51.9 43.9 52.1 44.35 52.45 45.45 53.25 46.05 54.55 47.65 58.15 47.65 61.65 L 47.65 72.1 Q 47.65 75.7 49.45 77.85 51.25 80 54.1 80 L 58.15 80 58.15 76.25 55.25 76.25 Q 54.1 76.25 53.35 75.65 52.55 74.95 52.2 74 L 51.65 71.75 51.5 69.45 51.35 59.8 Q 51.35 57.55 50.8 55.8 50.15 53.65 49.65 52.8 48.8 51.5 47.9 50.8 47.05 50.1 46.1 49.75 47 49.3 47.8 48.7 48.95 47.85 49.6 46.75 50.1 45.8 50.75 43.7 51.35 41.85 51.35 39.45 L 51.55 28.05 52 25.9 Q 52.35 24.85 53.15 24.2 53.9 23.65 55.25 23.65 L 58.15 23.65 Z" style="fill: rgb(175, 110, 36);"/>
+      </g>
+    </g>
+    <g transform="matrix(-0.441364, 0, 0, -0.412845, 414.750092, -88.816727)" style="transform-origin: 50px 50px;">
+      <g>
+        <path d="M 14.392 23.65 L 14.392 20 L 10.492 20 C 8.292 20 6.659 20.733 5.592 22.2 C 4.525 23.667 3.992 25.5 3.992 27.7 L 3.292 41.45 C 3.125 42.65 2.809 43.7 2.342 44.6 C 1.909 45.567 1.325 46.383 0.592 47.05 C 0.292 47.383 -0.091 47.617 -0.558 47.75 C -0.825 47.883 -1.275 48.017 -1.908 48.15 L -1.908 51.6 C -1.175 51.733 -0.725 51.833 -0.558 51.9 C -0.091 52.033 0.292 52.217 0.592 52.45 C 1.325 52.983 1.892 53.683 2.292 54.55 C 3.359 56.95 3.892 59.317 3.892 61.65 L 3.892 72.1 C 3.892 74.5 4.492 76.417 5.692 77.85 C 6.892 79.283 8.442 80 10.342 80 L 14.392 80 L 14.392 76.25 L 11.492 76.25 C 10.725 76.25 10.092 76.05 9.592 75.65 C 9.059 75.183 8.675 74.633 8.442 74 L 7.892 71.75 L 7.742 69.45 L 7.592 59.8 C 7.592 58.3 7.409 56.967 7.042 55.8 C 6.609 54.367 6.225 53.367 5.892 52.8 C 5.325 51.933 4.742 51.267 4.142 50.8 C 3.575 50.333 2.975 49.983 2.342 49.75 C 2.942 49.45 3.509 49.1 4.042 48.7 C 4.809 48.133 5.409 47.483 5.842 46.75 C 6.175 46.117 6.559 45.1 6.992 43.7 C 7.392 42.467 7.592 41.05 7.592 39.45 L 7.792 28.05 L 8.242 25.9 C 8.475 25.2 8.859 24.633 9.392 24.2 C 9.892 23.833 10.592 23.65 11.492 23.65 L 14.392 23.65 Z" style="fill: rgb(175, 110, 36);"/>
+        <path d="M 255.632 27.46 L 268.667 47.91 L 242.597 47.91 L 255.632 27.46 Z" style="fill-rule: nonzero; fill: rgb(172, 67, 67);" transform="matrix(-0.000038, 1, 1, 0.000093, 86.522967, -302.258205)" bx:shape="triangle 242.597 27.46 26.07 20.45 0.5 0 1@97f9cc39"/>
+        <rect x="254.391" y="-239.419" width="4.82" height="17.271" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);" transform="matrix(-0.000038, 1, -1, -0.000093, 86.522728, -302.258331)"/>
+        <rect x="254.367" y="-203.504" width="4.82" height="17.271" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);" transform="matrix(-0.000038, 1, -1, -0.000093, 86.522728, -302.258331)"/>
+        <rect x="254.367" y="-168.53" width="4.82" height="17.271" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);" transform="matrix(-0.000038, 1, -1, -0.000093, 86.522728, -302.258331)"/>
+        <rect x="254.391" y="-243.818" width="4.82" height="17.687" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);" transform="matrix(-0.000038, 1, -1, -0.000093, -21.921179, -302.35498)"/>
+        <rect x="254.367" y="-208.398" width="4.82" height="17.687" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);" transform="matrix(-0.000038, 1, -1, -0.000093, -21.921179, -302.35498)"/>
+        <rect x="254.367" y="-172.584" width="4.82" height="17.687" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);" transform="matrix(-0.000038, 1, -1, -0.000093, -21.921179, -302.35498)"/>
+        <text id="text-7" style="fill: rgb(172, 67, 67); font-family: 'Open Sans'; font-size: 9.73113px; font-style: italic; white-space: pre;" transform="matrix(-2.353923, 0, 0, -2.767724, 945.975708, -228.376572)" x="263.861" y="-70.535">WeakRef object</text>
+        <path d="M 108.749 -57.365 L 108.749 -61.015 L 104.849 -61.015 C 102.649 -61.015 101.015 -60.281 99.949 -58.815 C 98.882 -57.348 98.349 -55.515 98.349 -53.315 L 97.649 -39.565 C 97.482 -38.365 97.165 -37.315 96.699 -36.415 C 96.265 -35.448 95.682 -34.631 94.949 -33.965 C 94.649 -33.631 94.265 -33.398 93.799 -33.265 C 93.532 -33.131 93.082 -32.998 92.449 -32.865 L 92.449 -29.415 C 93.182 -29.281 93.632 -29.181 93.799 -29.115 C 94.265 -28.981 94.649 -28.798 94.949 -28.565 C 95.682 -28.031 96.249 -27.331 96.649 -26.465 C 97.715 -24.065 98.249 -21.698 98.249 -19.365 L 98.249 -8.915 C 98.249 -6.515 98.849 -4.598 100.049 -3.165 C 101.249 -1.731 102.799 -1.015 104.699 -1.015 L 108.749 -1.015 L 108.749 -4.765 L 105.849 -4.765 C 105.082 -4.765 104.449 -4.965 103.949 -5.365 C 103.415 -5.831 103.032 -6.381 102.799 -7.015 L 102.249 -9.265 L 102.099 -11.565 L 101.949 -21.215 C 101.949 -22.715 101.765 -24.048 101.399 -25.215 C 100.965 -26.648 100.582 -27.648 100.249 -28.215 C 99.682 -29.081 99.099 -29.748 98.499 -30.215 C 97.932 -30.681 97.332 -31.031 96.699 -31.265 C 97.299 -31.565 97.865 -31.915 98.399 -32.315 C 99.165 -32.881 99.765 -33.531 100.199 -34.265 C 100.532 -34.898 100.915 -35.915 101.349 -37.315 C 101.749 -38.548 101.949 -39.965 101.949 -41.565 L 102.149 -52.965 L 102.599 -55.115 C 102.832 -55.815 103.215 -56.381 103.749 -56.815 C 104.249 -57.181 104.949 -57.365 105.849 -57.365 L 108.749 -57.365 Z" style="fill: rgb(175, 110, 36); transform-box: fill-box; transform-origin: 50% 50%;" transform="matrix(-1, 0, 0, -1, -0.000004, -0.000028)"/>
+        <path d="M 15.325 -57.155 L 15.325 -60.805 L 11.425 -60.805 C 9.225 -60.805 7.591 -60.072 6.525 -58.605 C 5.458 -57.139 4.925 -55.305 4.925 -53.105 L 4.225 -39.355 C 4.058 -38.155 3.741 -37.105 3.275 -36.205 C 2.841 -35.239 2.258 -34.422 1.525 -33.755 C 1.225 -33.422 0.841 -33.189 0.375 -33.055 C 0.108 -32.922 -0.342 -32.789 -0.975 -32.655 L -0.975 -29.205 C -0.242 -29.072 0.208 -28.972 0.375 -28.905 C 0.841 -28.772 1.225 -28.589 1.525 -28.355 C 2.258 -27.822 2.825 -27.122 3.225 -26.255 C 4.291 -23.855 4.825 -21.489 4.825 -19.155 L 4.825 -8.705 C 4.825 -6.305 5.425 -4.389 6.625 -2.955 C 7.825 -1.522 9.375 -0.805 11.275 -0.805 L 15.325 -0.805 L 15.325 -4.555 L 12.425 -4.555 C 11.658 -4.555 11.025 -4.755 10.525 -5.155 C 9.991 -5.622 9.608 -6.172 9.375 -6.805 L 8.825 -9.055 L 8.675 -11.355 L 8.525 -21.005 C 8.525 -22.505 8.341 -23.839 7.975 -25.005 C 7.541 -26.439 7.158 -27.439 6.825 -28.005 C 6.258 -28.872 5.675 -29.539 5.075 -30.005 C 4.508 -30.472 3.908 -30.822 3.275 -31.055 C 3.875 -31.355 4.441 -31.705 4.975 -32.105 C 5.741 -32.672 6.341 -33.322 6.775 -34.055 C 7.108 -34.689 7.491 -35.705 7.925 -37.105 C 8.325 -38.339 8.525 -39.755 8.525 -41.355 L 8.725 -52.755 L 9.175 -54.905 C 9.408 -55.605 9.791 -56.172 10.325 -56.605 C 10.825 -56.972 11.525 -57.155 12.425 -57.155 L 15.325 -57.155 Z" style="fill: rgb(175, 110, 36);"/>
+      </g>
+    </g>
+    <text id="text-9" style="fill: rgb(175, 110, 36); font-family: 'Open Sans'; font-size: 4.89804px; font-weight: 700; line-height: 19.9484px; white-space: pre;" transform="matrix(1.374145, 0, 0, 1.314286, 83.283821, 89.215279)" x="263.861" y="-70.535">undefined</text>
+    <text id="text-10" style="fill: rgb(175, 110, 36); font-family: 'Open Sans'; font-size: 4.89804px; font-weight: 700; line-height: 19.9484px; white-space: pre;" transform="matrix(1.374145, 0, 0, 1.314286, 82.957924, 122.90126)" x="263.861" y="-70.535">undefined</text>
+  </g>
+  <g transform="matrix(0.3355039954185486, 0, 0, 0.3355039954185486, 67.31304168701172, -387.90008544921875)" style="">
+    <g transform="matrix(0.178489, 0, 0, 0.175502, 747.077209, 776.317017)" style="">
+      <path d="M 267.184 437.8 C 267.184 466.3 290.384 489.4 318.784 489.4 L 704.984 489.4 C 733.484 489.4 756.584 466.2 756.584 437.8 L 756.584 51.6 C 756.584 23.1 733.384 0 704.984 0 L 318.784 0 C 290.284 0 267.184 23.2 267.184 51.6 C 267.184 51.6 267.184 437.8 267.184 437.8 Z M 704.984 464.9 L 318.784 464.9 C 303.884 464.9 291.684 452.7 291.684 437.8 L 291.684 373.3 L 384.484 280.5 L 463.784 359.8 C 468.584 364.6 476.284 364.6 481.084 359.8 L 624.284 216.6 L 732.084 324.4 L 732.084 437.8 C 732.084 452.7 719.884 464.9 704.984 464.9 Z M 318.784 24.5 L 704.984 24.5 C 719.884 24.5 732.084 36.7 732.084 51.6 L 732.084 289.7 L 632.884 190.6 C 628.084 185.8 620.384 185.8 615.584 190.6 L 472.384 333.8 L 393.084 254.5 C 388.284 249.7 380.584 249.7 375.784 254.5 L 291.684 338.6 L 291.684 51.6 C 291.684 36.7 303.884 24.5 318.784 24.5 Z" style="fill: rgb(175, 110, 36);"/>
+      <path d="M 418.884 196.1 C 453.284 196.1 481.184 168.1 481.184 133.8 C 481.184 99.5 453.184 71.5 418.884 71.5 C 384.584 71.5 356.584 99.5 356.584 133.8 C 356.584 168.1 384.484 196.1 418.884 196.1 Z M 418.884 96 C 439.784 96 456.684 113 456.684 133.8 C 456.684 154.6 439.684 171.6 418.884 171.6 C 398.084 171.6 381.084 154.6 381.084 133.8 C 381.084 113 397.984 96 418.884 96 Z" style="fill: rgb(175, 110, 36);"/>
+    </g>
+  </g>
+  <path d="M -161.945 -20.71 L -152.75 -5.287 L -171.141 -5.287 L -161.945 -20.71 Z" style="fill-rule: nonzero; fill: rgb(172, 67, 67);" transform="matrix(0.00004100000296602957, -1, -1, -0.00008700000762473792, 281.66448974609375, -149.3444061279297)" bx:shape="triangle -171.141 -20.71 18.391 15.423 0.5 0 1@d86e5ee8"/>
+  <rect x="179.461" y="-180.566" width="3.4" height="13.026" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);" transform="matrix(0.00004100000296602957, -1, 1, 0.00008700000762473792, 323.07061767578125, 192.94052124023438)"/>
+  <rect x="179.444" y="-153.479" width="3.4" height="13.026" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);" transform="matrix(0.00004100000296602957, -1, 1, 0.00008700000762473792, 323.07061767578125, 192.94052124023438)"/>
+  <rect x="179.444" y="-127.103" width="3.4" height="13.026" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);" transform="matrix(0.00004100000296602957, -1, 1, 0.00008700000762473792, 323.07061767578125, 192.94052124023438)"/>
+  <rect x="179.461" y="-183.883" width="3.4" height="13.339" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);" transform="matrix(0.00004100000296602957, -1, 1, 0.00008700000762473792, 404.8572998046875, 193.0087127685547)"/>
+  <rect x="179.444" y="-157.171" width="3.4" height="13.339" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);" transform="matrix(0.00004100000296602957, -1, 1, 0.00008700000762473792, 404.8572998046875, 193.0087127685547)"/>
+  <rect x="179.444" y="-130.16" width="3.4" height="13.339" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);" transform="matrix(0.00004100000296602957, -1, 1, 0.00008700000762473792, 404.8572998046875, 193.0087127685547)"/>
+  <text id="text-8" style="fill: rgb(172, 67, 67); font-family: 'Open Sans'; font-size: 9.73113px; font-style: italic; white-space: pre;" transform="matrix(1.775291919708252, 0, 0, 1.9524970054626465, -325.1152648925781, 140.8204803466797)" x="263.861" y="-70.535">WeakRef object</text>
+  <path d="M 318.601 -16.998 L 318.601 -19.573 L 315.66 -19.573 C 314.001 -19.573 312.769 -19.055 311.964 -18.021 C 311.16 -16.986 310.758 -15.693 310.758 -14.141 L 310.23 -4.441 C 310.104 -3.594 309.865 -2.853 309.513 -2.218 C 309.186 -1.536 308.746 -0.96 308.193 -0.49 C 307.967 -0.255 307.678 -0.09 307.326 0.004 C 307.125 0.098 306.786 0.192 306.308 0.286 L 306.308 2.72 C 306.861 2.814 307.2 2.884 307.326 2.931 C 307.678 3.025 307.967 3.155 308.193 3.319 C 308.746 3.696 309.174 4.189 309.475 4.801 C 310.28 6.494 310.682 8.163 310.682 9.81 L 310.682 17.181 C 310.682 18.875 311.135 20.227 312.04 21.238 C 312.945 22.249 314.114 22.755 315.547 22.755 L 318.601 22.755 L 318.601 20.109 L 316.414 20.109 C 315.836 20.109 315.358 19.968 314.981 19.686 C 314.579 19.357 314.29 18.969 314.114 18.522 L 313.699 16.935 L 313.586 15.312 L 313.473 8.504 C 313.473 7.446 313.334 6.506 313.058 5.683 C 312.731 4.671 312.442 3.966 312.191 3.566 C 311.763 2.955 311.323 2.485 310.871 2.155 C 310.443 1.826 309.991 1.579 309.513 1.415 C 309.966 1.203 310.393 0.956 310.795 0.674 C 311.373 0.274 311.826 -0.184 312.153 -0.702 C 312.404 -1.148 312.693 -1.866 313.02 -2.853 C 313.322 -3.723 313.473 -4.723 313.473 -5.852 L 313.623 -13.894 L 313.963 -15.41 C 314.139 -15.904 314.428 -16.304 314.83 -16.61 C 315.207 -16.868 315.735 -16.998 316.414 -16.998 L 318.601 -16.998 Z" style="fill: rgb(175, 110, 36);"/>
+  <path d="M 389.058 -17.145 L 389.058 -19.72 L 386.117 -19.72 C 384.458 -19.72 383.226 -19.203 382.421 -18.168 C 381.617 -17.134 381.215 -15.84 381.215 -14.288 L 380.687 -4.588 C 380.561 -3.742 380.322 -3.001 379.97 -2.366 C 379.644 -1.684 379.204 -1.108 378.651 -0.638 C 378.424 -0.403 378.135 -0.238 377.783 -0.144 C 377.582 -0.05 377.243 0.044 376.765 0.138 L 376.765 2.572 C 377.318 2.666 377.658 2.737 377.783 2.784 C 378.135 2.878 378.424 3.007 378.651 3.172 C 379.204 3.548 379.631 4.042 379.933 4.653 C 380.737 6.346 381.139 8.016 381.139 9.662 L 381.139 17.034 C 381.139 18.727 381.592 20.079 382.497 21.09 C 383.402 22.101 384.571 22.607 386.004 22.607 L 389.058 22.607 L 389.058 19.961 L 386.871 19.961 C 386.293 19.961 385.815 19.82 385.438 19.538 C 385.036 19.209 384.747 18.821 384.571 18.374 L 384.156 16.787 L 384.043 15.164 L 383.93 8.357 C 383.93 7.299 383.792 6.358 383.515 5.535 C 383.188 4.524 382.899 3.818 382.648 3.419 C 382.22 2.807 381.78 2.337 381.328 2.008 C 380.901 1.679 380.448 1.432 379.97 1.267 C 380.423 1.055 380.85 0.808 381.253 0.526 C 381.831 0.127 382.283 -0.332 382.61 -0.849 C 382.861 -1.296 383.151 -2.013 383.477 -3.001 C 383.779 -3.871 383.93 -4.87 383.93 -5.999 L 384.081 -14.041 L 384.42 -15.558 C 384.596 -16.052 384.885 -16.452 385.287 -16.757 C 385.664 -17.016 386.192 -17.145 386.871 -17.145 L 389.058 -17.145 Z" style="fill: rgb(175, 110, 36); transform-origin: 382.912px 1.4435px;" transform="matrix(-1, 0, 0, -1, 0, -0.000015020371)"/>
+</svg>
\ No newline at end of file
diff --git a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-05.svg b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-05.svg
new file mode 100644
index 000000000..e738f8e7e
--- /dev/null
+++ b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-05.svg
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg viewBox="-56.888 -599965.495 896063.875 604140.645" width="420.466px" height="300.516px" xmlns="http://www.w3.org/2000/svg" xmlns:bx="https://boxy-svg.com">
+  <defs>
+    <style bx:fonts="Open Sans">@import url(https://fonts.googleapis.com/css2?family=Open+Sans%3Aital%2Cwght%400%2C300%3B0%2C400%3B0%2C500%3B0%2C600%3B0%2C700%3B0%2C800%3B1%2C300%3B1%2C400%3B1%2C500%3B1%2C600%3B1%2C700%3B1%2C800&amp;display=swap);</style>
+  </defs>
+  <g id="memory-user-john-admin.svg" transform="matrix(3405.68798828125, 0, 0, 3405.68798828125, -789862.25, -296077.03124999994)" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1" style="">
+    <path id="path-1" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M 234.068 -87.403 L 333.494 -87.403 L 333.494 -57.762 L 234.068 -57.762 L 234.068 -87.403 Z" style=""/>
+    <path id="path-2" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M 336.651 -87.403 L 492.549 -87.403 L 492.549 -57.762 L 336.651 -57.762 L 336.651 -87.403 Z" style=""/>
+    <path id="path-3" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M 234.068 -53.711 L 333.494 -53.711 L 333.494 -24.07 L 234.068 -24.07 L 234.068 -53.711 Z" style=""/>
+    <path id="path-4" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M 336.651 -53.711 L 492.783 -53.711 L 492.783 -24.07 L 336.651 -24.07 L 336.651 -53.711 Z" style=""/>
+    <g transform="matrix(1, 0, 0, 1, 0, 42.135864)">
+      <path id="path-5" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M 234.189 -20.462 L 333.615 -20.462 L 333.615 9.179 L 234.189 9.179 L 234.189 -20.462 Z" style=""/>
+      <path id="path-6" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M 336.791 -20.462 L 493.057 -20.462 L 493.057 9.179 L 336.791 9.179 L 336.791 -20.462 Z" style=""/>
+      <path id="path-7" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M 234.068 13.088 L 333.494 13.088 L 333.494 43.59 L 234.068 43.59 L 234.068 13.088 Z" style=""/>
+      <path id="path-8" fill="#FBF2EC" stroke="#DBAF88" stroke-width="2" d="M 336.651 13.088 L 493.054 13.088 L 493.054 43.59 L 336.651 43.59 L 336.651 13.088 Z" style=""/>
+      <text id="text-4" style="fill: rgb(175, 110, 36); font-family: 'Open Sans'; font-size: 14px; white-space: pre;" transform="matrix(1.054877, 0, 0, 1.142641, -39.02475, 80.086914)" x="263.861" y="-70.535">image-02.jpg</text>
+      <text id="text-5" style="fill: rgb(175, 110, 36); font-family: 'Open Sans'; font-size: 14px; white-space: pre;" transform="matrix(1.054877, 0, 0, 1.142641, -39.468063, 113.637062)" x="263.861" y="-70.535">image-03.jpg</text>
+    </g>
+    <text id="&lt;global&gt;" style="fill: rgb(175, 110, 36); font-family: 'Open Sans'; font-size: 11.5772px; font-weight: 600; line-height: 19.9484px; white-space: pre;" transform="matrix(1.374145, 0, 0, 1.314286, -102.41082, 25.040792)" x="263.861" y="-70.535">key</text>
+    <text id="text-2" style="fill: rgb(175, 110, 36); font-family: 'Open Sans'; font-size: 11.5772px; font-weight: 600; line-height: 19.9484px; white-space: pre;" transform="matrix(1.374145, 0, 0, 1.314286, 13.577469, 25.203112)" x="263.861" y="-70.535">value</text>
+    <text id="text-3" style="fill: rgb(175, 110, 36); font-family: 'Open Sans'; font-size: 14px; white-space: pre;" transform="matrix(1.071654, 0, 0, 1.142641, -43.57296, 46.390514)" x="263.861" y="-70.535">image-01.jpg</text>
+    <g transform="matrix(0.000041, -1, 1.521843, 0.000133, 289.017426, 2.750529)" style="transform-origin: 105.999px -35.503px;">
+      <path d="M 105.537 7.964 L 110.918 13.895 L 100.155 13.895 L 105.537 7.964 Z" style="fill-rule: nonzero; fill: rgb(172, 67, 67);" transform="matrix(1, 0, 0, -1, 0, 0)" bx:shape="triangle 100.155 7.964 10.763 5.931 0.5 0 1@87a4267a"/>
+      <g>
+        <rect x="105.024" y="-69.436" width="1.99" height="5.009" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);"/>
+        <rect x="105.014" y="-59.02" width="1.99" height="5.009" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);"/>
+        <rect x="105.014" y="-48.877" width="1.99" height="5.009" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);"/>
+        <g transform="matrix(1, 0, 0, 1, 10.348016, -60.719521)"/>
+        <g transform="matrix(1, 0, 0, 1, 10.356147, 0.41661)"/>
+        <g transform="matrix(1, 0, 0, 1, 10.161898, 52.045895)"/>
+        <g transform="matrix(1, 0, 0, 1, -23.594774, -60.719116)">
+          <rect x="79.597" y="-80.351" width="1.99" height="5.009" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);"/>
+          <rect x="79.587" y="-69.935" width="1.99" height="5.009" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);"/>
+          <rect x="79.587" y="-59.792" width="1.99" height="5.009" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);"/>
+          <rect x="79.561" y="-50.176" width="1.99" height="5.129" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);"/>
+          <rect x="79.551" y="-39.904" width="1.99" height="5.129" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);"/>
+          <rect x="79.551" y="-29.517" width="1.99" height="5.129" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);"/>
+        </g>
+        <g transform="matrix(1, 0, 0, 1, -23.586773, 0.417928)">
+          <rect x="79.597" y="-80.351" width="1.99" height="5.009" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);"/>
+          <rect x="79.587" y="-69.935" width="1.99" height="5.009" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);"/>
+          <rect x="79.587" y="-59.792" width="1.99" height="5.009" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);"/>
+          <rect x="79.561" y="-50.176" width="1.99" height="5.129" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);"/>
+          <rect x="79.551" y="-39.904" width="1.99" height="5.129" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);"/>
+        </g>
+        <g transform="matrix(1, 0, 0, 1, -23.780775, 52.046886)">
+          <rect x="79.798" y="-80.298" width="1.99" height="5.009" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);"/>
+          <rect x="79.587" y="-69.935" width="1.99" height="5.009" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);"/>
+          <rect x="79.587" y="-59.792" width="1.99" height="5.009" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);"/>
+          <rect x="79.561" y="-50.176" width="1.99" height="5.129" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);"/>
+          <rect x="79.551" y="-39.904" width="1.99" height="5.129" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);"/>
+          <rect x="79.551" y="-29.517" width="1.99" height="5.129" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);"/>
+        </g>
+      </g>
+      <g transform="matrix(1, 0, 0, 1.024052, -0.03572, 31.45084)" style="">
+        <rect x="105.024" y="-69.051" width="1.99" height="5.009" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);"/>
+        <rect x="105.014" y="-59.02" width="1.99" height="5.009" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);"/>
+        <rect x="105.014" y="-48.877" width="1.99" height="5.009" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);"/>
+      </g>
+    </g>
+    <text id="text-6" style="fill: rgb(172, 67, 67); font-family: 'Open Sans'; font-size: 9.73113px; font-style: italic; white-space: pre;" transform="matrix(1.038937, 0, 0, 1.142641, 69.710487, 42.749538)" x="263.861" y="-70.535">WeakRef object</text>
+    <g transform="matrix(0.441364, 0, 0, 0.412845, 420.761139, -59.372555)" style="">
+      <g>
+        <path d=" M 58.15 23.65 L 58.15 20 54.25 20 Q 50.95 20 49.35 22.2 47.75 24.4 47.75 27.7 L 47.05 41.45 Q 46.8 43.25 46.1 44.6 45.45 46.05 44.35 47.05 43.9 47.55 43.2 47.75 42.8 47.95 41.85 48.15 L 41.85 51.6 Q 42.95 51.8 43.2 51.9 43.9 52.1 44.35 52.45 45.45 53.25 46.05 54.55 47.65 58.15 47.65 61.65 L 47.65 72.1 Q 47.65 75.7 49.45 77.85 51.25 80 54.1 80 L 58.15 80 58.15 76.25 55.25 76.25 Q 54.1 76.25 53.35 75.65 52.55 74.95 52.2 74 L 51.65 71.75 51.5 69.45 51.35 59.8 Q 51.35 57.55 50.8 55.8 50.15 53.65 49.65 52.8 48.8 51.5 47.9 50.8 47.05 50.1 46.1 49.75 47 49.3 47.8 48.7 48.95 47.85 49.6 46.75 50.1 45.8 50.75 43.7 51.35 41.85 51.35 39.45 L 51.55 28.05 52 25.9 Q 52.35 24.85 53.15 24.2 53.9 23.65 55.25 23.65 L 58.15 23.65 Z" style="fill: rgb(175, 110, 36);"/>
+      </g>
+    </g>
+    <g transform="matrix(-0.441364, 0, 0, -0.412845, 414.750092, -88.816727)" style="transform-origin: 50px 50px;">
+      <g>
+        <path d="M 14.392 23.65 L 14.392 20 L 10.492 20 C 8.292 20 6.659 20.733 5.592 22.2 C 4.525 23.667 3.992 25.5 3.992 27.7 L 3.292 41.45 C 3.125 42.65 2.809 43.7 2.342 44.6 C 1.909 45.567 1.325 46.383 0.592 47.05 C 0.292 47.383 -0.091 47.617 -0.558 47.75 C -0.825 47.883 -1.275 48.017 -1.908 48.15 L -1.908 51.6 C -1.175 51.733 -0.725 51.833 -0.558 51.9 C -0.091 52.033 0.292 52.217 0.592 52.45 C 1.325 52.983 1.892 53.683 2.292 54.55 C 3.359 56.95 3.892 59.317 3.892 61.65 L 3.892 72.1 C 3.892 74.5 4.492 76.417 5.692 77.85 C 6.892 79.283 8.442 80 10.342 80 L 14.392 80 L 14.392 76.25 L 11.492 76.25 C 10.725 76.25 10.092 76.05 9.592 75.65 C 9.059 75.183 8.675 74.633 8.442 74 L 7.892 71.75 L 7.742 69.45 L 7.592 59.8 C 7.592 58.3 7.409 56.967 7.042 55.8 C 6.609 54.367 6.225 53.367 5.892 52.8 C 5.325 51.933 4.742 51.267 4.142 50.8 C 3.575 50.333 2.975 49.983 2.342 49.75 C 2.942 49.45 3.509 49.1 4.042 48.7 C 4.809 48.133 5.409 47.483 5.842 46.75 C 6.175 46.117 6.559 45.1 6.992 43.7 C 7.392 42.467 7.592 41.05 7.592 39.45 L 7.792 28.05 L 8.242 25.9 C 8.475 25.2 8.859 24.633 9.392 24.2 C 9.892 23.833 10.592 23.65 11.492 23.65 L 14.392 23.65 Z" style="fill: rgb(175, 110, 36);"/>
+        <path d="M 255.632 27.46 L 268.667 47.91 L 242.597 47.91 L 255.632 27.46 Z" style="fill-rule: nonzero; fill: rgb(172, 67, 67);" transform="matrix(-0.000038, 1, 1, 0.000093, 86.522967, -404.320629)" bx:shape="triangle 242.597 27.46 26.07 20.45 0.5 0 1@97f9cc39"/>
+        <rect x="254.391" y="-239.419" width="4.82" height="17.271" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);" transform="matrix(-0.000038, 1, -1, -0.000093, 86.522728, -404.32132)"/>
+        <rect x="254.367" y="-203.504" width="4.82" height="17.271" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);" transform="matrix(-0.000038, 1, -1, -0.000093, 86.522728, -404.32132)"/>
+        <rect x="254.367" y="-168.53" width="4.82" height="17.271" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);" transform="matrix(-0.000038, 1, -1, -0.000093, 86.522728, -404.32132)"/>
+        <rect x="254.391" y="-243.818" width="4.82" height="17.687" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);" transform="matrix(-0.000038, 1, -1, -0.000093, -21.921179, -404.417969)"/>
+        <rect x="254.367" y="-208.398" width="4.82" height="17.687" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);" transform="matrix(-0.000038, 1, -1, -0.000093, -21.921179, -404.417969)"/>
+        <rect x="254.367" y="-172.584" width="4.82" height="17.687" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);" transform="matrix(-0.000038, 1, -1, -0.000093, -21.921179, -404.417969)"/>
+        <text id="text-7" style="fill: rgb(172, 67, 67); font-family: 'Open Sans'; font-size: 9.73113px; font-style: italic; white-space: pre;" transform="matrix(-2.353923, 0, 0, -2.767724, 945.975708, -330.43927)" x="263.861" y="-70.535">WeakRef object</text>
+        <path d="M 108.749 -159.455 L 108.749 -163.105 L 104.849 -163.105 C 102.649 -163.105 101.015 -162.371 99.949 -160.905 C 98.882 -159.438 98.349 -157.605 98.349 -155.405 L 97.649 -141.655 C 97.482 -140.455 97.165 -139.405 96.699 -138.505 C 96.265 -137.538 95.682 -136.721 94.949 -136.055 C 94.649 -135.721 94.265 -135.488 93.799 -135.355 C 93.532 -135.221 93.082 -135.088 92.449 -134.955 L 92.449 -131.505 C 93.182 -131.371 93.632 -131.271 93.799 -131.205 C 94.265 -131.071 94.649 -130.888 94.949 -130.655 C 95.682 -130.121 96.249 -129.421 96.649 -128.555 C 97.715 -126.155 98.249 -123.788 98.249 -121.455 L 98.249 -111.005 C 98.249 -108.605 98.849 -106.688 100.049 -105.255 C 101.249 -103.821 102.799 -103.105 104.699 -103.105 L 108.749 -103.105 L 108.749 -106.855 L 105.849 -106.855 C 105.082 -106.855 104.449 -107.055 103.949 -107.455 C 103.415 -107.921 103.032 -108.471 102.799 -109.105 L 102.249 -111.355 L 102.099 -113.655 L 101.949 -123.305 C 101.949 -124.805 101.765 -126.138 101.399 -127.305 C 100.965 -128.738 100.582 -129.738 100.249 -130.305 C 99.682 -131.171 99.099 -131.838 98.499 -132.305 C 97.932 -132.771 97.332 -133.121 96.699 -133.355 C 97.299 -133.655 97.865 -134.005 98.399 -134.405 C 99.165 -134.971 99.765 -135.621 100.199 -136.355 C 100.532 -136.988 100.915 -138.005 101.349 -139.405 C 101.749 -140.638 101.949 -142.055 101.949 -143.655 L 102.149 -155.055 L 102.599 -157.205 C 102.832 -157.905 103.215 -158.471 103.749 -158.905 C 104.249 -159.271 104.949 -159.455 105.849 -159.455 L 108.749 -159.455 Z" style="fill: rgb(175, 110, 36); transform-box: fill-box; transform-origin: 50% 50%;" transform="matrix(-1, 0, 0, -1, -0.000041, -0.000044)"/>
+        <path d="M 15.325 -159.251 L 15.325 -162.901 L 11.425 -162.901 C 9.225 -162.901 7.591 -162.168 6.525 -160.701 C 5.458 -159.235 4.925 -157.401 4.925 -155.201 L 4.225 -141.451 C 4.058 -140.251 3.741 -139.201 3.275 -138.301 C 2.841 -137.335 2.258 -136.518 1.525 -135.851 C 1.225 -135.518 0.841 -135.285 0.375 -135.151 C 0.108 -135.018 -0.342 -134.885 -0.975 -134.751 L -0.975 -131.301 C -0.242 -131.168 0.208 -131.068 0.375 -131.001 C 0.841 -130.868 1.225 -130.685 1.525 -130.451 C 2.258 -129.918 2.825 -129.218 3.225 -128.351 C 4.291 -125.951 4.825 -123.585 4.825 -121.251 L 4.825 -110.801 C 4.825 -108.401 5.425 -106.485 6.625 -105.051 C 7.825 -103.618 9.375 -102.901 11.275 -102.901 L 15.325 -102.901 L 15.325 -106.651 L 12.425 -106.651 C 11.658 -106.651 11.025 -106.851 10.525 -107.251 C 9.991 -107.718 9.608 -108.268 9.375 -108.901 L 8.825 -111.151 L 8.675 -113.451 L 8.525 -123.101 C 8.525 -124.601 8.341 -125.935 7.975 -127.101 C 7.541 -128.535 7.158 -129.535 6.825 -130.101 C 6.258 -130.968 5.675 -131.635 5.075 -132.101 C 4.508 -132.568 3.908 -132.918 3.275 -133.151 C 3.875 -133.451 4.441 -133.801 4.975 -134.201 C 5.741 -134.768 6.341 -135.418 6.775 -136.151 C 7.108 -136.785 7.491 -137.801 7.925 -139.201 C 8.325 -140.435 8.525 -141.851 8.525 -143.451 L 8.725 -154.851 L 9.175 -157.001 C 9.408 -157.701 9.791 -158.268 10.325 -158.701 C 10.825 -159.068 11.525 -159.251 12.425 -159.251 L 15.325 -159.251 Z" style="fill: rgb(175, 110, 36);"/>
+      </g>
+    </g>
+    <text id="text-9" style="fill: rgb(175, 110, 36); font-family: 'Open Sans'; font-size: 4.89804px; font-weight: 700; line-height: 19.9484px; white-space: pre;" transform="matrix(1.374145, 0, 0, 1.314286, 83.283821, 131.351151)" x="263.861" y="-70.535">undefined</text>
+    <text id="text-10" style="fill: rgb(175, 110, 36); font-family: 'Open Sans'; font-size: 4.89804px; font-weight: 700; line-height: 19.9484px; white-space: pre;" transform="matrix(1.374145, 0, 0, 1.314286, 82.957924, 165.037125)" x="263.861" y="-70.535">undefined</text>
+    <text id="text-11" style="fill: rgb(172, 67, 67); font-family: 'Open Sans'; font-size: 9.73113px; font-style: italic; white-space: pre;" transform="matrix(1.038937, 0, 0, 1.142641, -18.813889, 90.723404)" x="263.861" y="-70.535">Deleted by FinalizationRegistry cleanup callback</text>
+  </g>
+  <g transform="matrix(668.68603515625, 0, 0, 668.68603515625, 227309.90625, -975180.6875)" style="">
+    <g transform="matrix(0.178489, 0, 0, 0.175502, 747.077209, 776.317017)" style="">
+      <path d="M 267.184 437.8 C 267.184 466.3 290.384 489.4 318.784 489.4 L 704.984 489.4 C 733.484 489.4 756.584 466.2 756.584 437.8 L 756.584 51.6 C 756.584 23.1 733.384 0 704.984 0 L 318.784 0 C 290.284 0 267.184 23.2 267.184 51.6 C 267.184 51.6 267.184 437.8 267.184 437.8 Z M 704.984 464.9 L 318.784 464.9 C 303.884 464.9 291.684 452.7 291.684 437.8 L 291.684 373.3 L 384.484 280.5 L 463.784 359.8 C 468.584 364.6 476.284 364.6 481.084 359.8 L 624.284 216.6 L 732.084 324.4 L 732.084 437.8 C 732.084 452.7 719.884 464.9 704.984 464.9 Z M 318.784 24.5 L 704.984 24.5 C 719.884 24.5 732.084 36.7 732.084 51.6 L 732.084 289.7 L 632.884 190.6 C 628.084 185.8 620.384 185.8 615.584 190.6 L 472.384 333.8 L 393.084 254.5 C 388.284 249.7 380.584 249.7 375.784 254.5 L 291.684 338.6 L 291.684 51.6 C 291.684 36.7 303.884 24.5 318.784 24.5 Z" style="fill: rgb(175, 110, 36);"/>
+      <path d="M 418.884 196.1 C 453.284 196.1 481.184 168.1 481.184 133.8 C 481.184 99.5 453.184 71.5 418.884 71.5 C 384.584 71.5 356.584 99.5 356.584 133.8 C 356.584 168.1 384.484 196.1 418.884 196.1 Z M 418.884 96 C 439.784 96 456.684 113 456.684 133.8 C 456.684 154.6 439.684 171.6 418.884 171.6 C 398.084 171.6 381.084 154.6 381.084 133.8 C 381.084 113 397.984 96 418.884 96 Z" style="fill: rgb(175, 110, 36);"/>
+    </g>
+  </g>
+  <path d="M 359424.367 41276.336 L 377751.896 72015.889 L 341096.837 72015.889 L 359424.367 41276.336 Z" style="fill-rule: nonzero; fill: rgb(172, 67, 67);" transform="matrix(0.00004100000296602957, -1, -1, -0.00008700000762473792, 737054.1250000001, 325983.1250000001)" bx:shape="triangle 341096.837 41276.336 36655.059 30739.553 0.5 0 1@d50babe8"/>
+  <rect x="357681.08" y="-359881.579" width="6776.286" height="25963.08" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);" transform="matrix(0.00004100000296602957, -1, 1, 0.00008700000762473792, 737054.6250000001, 325981.3125000001)"/>
+  <rect x="357644.501" y="-305895.331" width="6776.286" height="25963.08" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);" transform="matrix(0.00004100000296602957, -1, 1, 0.00008700000762473792, 737054.6250000001, 325981.3125000001)"/>
+  <rect x="357644.501" y="-253326.04" width="6776.286" height="25963.08" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);" transform="matrix(0.00004100000296602957, -1, 1, 0.00008700000762473792, 737054.6250000001, 325981.3125000001)"/>
+  <rect x="357681.08" y="-366492.978" width="6776.286" height="26586.395" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);" transform="matrix(0.00004100000296602957, -1, 1, 0.00008700000762473792, 900061.8125000001, 326117.2187500001)"/>
+  <rect x="357644.501" y="-313254.567" width="6776.286" height="26586.395" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);" transform="matrix(0.00004100000296602957, -1, 1, 0.00008700000762473792, 900061.8125000001, 326117.2187500001)"/>
+  <rect x="357644.501" y="-259418.129" width="6776.286" height="26586.395" style="paint-order: stroke; stroke: rgb(53, 81, 138); stroke-width: 0px; fill: rgb(172, 67, 67);" transform="matrix(0.00004100000296602957, -1, 1, 0.00008700000762473792, 900061.8125000001, 326117.2187500001)"/>
+  <text id="text-8" style="fill: rgb(172, 67, 67); font-family: 'Open Sans'; font-size: 9.73113px; font-style: italic; white-space: pre;" transform="matrix(3538.295166015625, 0, 0, 3891.478759765625, -554830.25, 222101.96875)" x="263.861" y="-70.535">WeakRef object</text>
+  <path d="M 728146.338 -92443.632 L 728146.338 -97574.712 L 722284.793 -97574.712 C 718978.199 -97574.712 716523.314 -96542.53 714919.193 -94480.927 C 713316.016 -92418.404 712514.341 -89841.53 712514.341 -86748.938 L 711462.052 -67415.4 C 711210.096 -65727.244 710734.892 -64250.108 710033.283 -62985.482 C 709382.304 -61626.233 708504.597 -60478.003 707402.151 -59541.042 C 706951.752 -59072.499 706375.587 -58743.915 705673.655 -58556.036 C 705273.289 -58368.007 704596.909 -58181.644 703645.158 -57993.168 L 703645.158 -53141.856 C 704747.605 -52953.853 705423.812 -52816.007 705673.655 -52721.682 C 706375.587 -52533.653 706951.752 -52275.956 707402.151 -51947.819 C 708504.597 -51196.774 709359.189 -50215.843 709957.252 -48995.062 C 711561.373 -45621.509 712363.794 -42293.888 712363.794 -39012.547 L 712363.794 -24320.941 C 712363.794 -20946.169 713265.063 -18250.364 715069.292 -16236.209 C 716874.118 -14219.916 719201.895 -13211.347 722059.73 -13211.347 L 728146.338 -13211.347 L 728146.338 -18485.095 L 723786.735 -18485.095 C 722635.597 -18485.095 721683.847 -18767.275 720932.205 -19327.881 C 720129.784 -19984.452 719554.812 -20757.843 719201.895 -21648.25 L 718377.253 -24810.511 L 718150.525 -28045.597 L 717925.463 -41615.096 C 717925.463 -43722.656 717648.726 -45597.921 717099.007 -47236.193 C 716447.133 -49254.872 715870.968 -50660.078 715370.511 -51456.161 C 714517.162 -52674.979 713641.12 -53612.089 712740.149 -54268.661 C 711885.582 -54925.978 710986.4 -55416.741 710033.283 -55743.536 C 710935.472 -56166.271 711786.261 -56657.059 712587.937 -57219.753 C 713740.267 -58016.755 714644.122 -58930.278 715294.33 -59961.987 C 715794.787 -60852.37 716371.101 -62282.655 717022.975 -64250.108 C 717625.611 -65984.196 717925.463 -67976.901 717925.463 -70227.453 L 718225.811 -86255.615 L 718902.938 -89277.444 C 719252.823 -90261.705 719829.908 -91059.9 720629.445 -91669.769 C 721380.938 -92183.673 722434.122 -92443.632 723786.735 -92443.632 L 728146.338 -92443.632 Z" style="fill: rgb(175, 110, 36);"/>
+  <path d="M 868579.948 -92734.348 L 868579.948 -97866.322 L 862717.955 -97866.322 C 859411.336 -97866.322 856954.786 -96837.173 855350.69 -94775.421 C 853747.488 -92713.793 852947.926 -90134.359 852947.926 -87041.916 L 851895.661 -67707.906 C 851643.706 -66022.185 851168.054 -64545.67 850465.228 -63278.459 C 849816.809 -61920.428 848939.872 -60773.094 847838.32 -59836.43 C 847385.039 -59366.993 846807.506 -59039.453 846107.264 -58850.977 C 845705.979 -58662.948 845032.333 -58476.734 844077.55 -58288.705 L 844077.55 -53438.165 C 845180.295 -53250.136 845856.974 -53108.363 846107.264 -53014.659 C 846807.506 -52828.296 847385.039 -52570.897 847838.32 -52242.462 C 848939.872 -51491.715 849788.996 -50508.374 850393.421 -49291.196 C 851994.957 -45916.599 852795.738 -42588.531 852795.738 -39308.084 L 852795.738 -24614.217 C 852795.738 -21238.7 853699.12 -18545.753 855503.051 -16529.485 C 857306.038 -14515.33 859635.504 -13506.885 862491.674 -13506.885 L 868579.948 -13506.885 L 868579.948 -18781.23 L 864220.319 -18781.23 C 863067.542 -18781.23 862114.424 -19061.47 861364.149 -19624.164 C 860562.474 -20278.623 859988.421 -21052.486 859635.504 -21943.639 L 858809.496 -25105.899 L 858584.135 -28341.01 L 858357.407 -41908.844 C 858357.407 -44017.15 858082.336 -45890.452 857532.617 -47532.477 C 856880.42 -49546.483 856302.887 -50953.801 855803.201 -51749.114 C 854950.299 -52969.622 854074.73 -53906.708 853171.77 -54561.937 C 852320.832 -55217.589 851420.01 -55710.191 850465.228 -56038.154 C 851368.61 -56462.579 852219.573 -56952.447 853024.106 -57514.843 C 854174.772 -58310.926 855075.594 -59225.667 855727.194 -60256.63 C 856228.546 -61147.784 856806.351 -62576.08 857456.585 -64545.67 C 858057.531 -66279.609 858357.407 -68270.177 858357.407 -70520.281 L 858660.316 -86548.145 L 859335.33 -89573.007 C 859685.662 -90557.094 860263.045 -91354.096 861063.055 -91962.3 C 861814.548 -92479.061 862866.066 -92734.348 864220.319 -92734.348 L 868579.948 -92734.348 Z" style="fill: rgb(175, 110, 36); transform-origin: 856323px -55686.3px;" transform="matrix(-1, 0, 0, -1, 0.87500000055, -0.046875000444)"/>
+  <rect x="3810.427" y="-226324.344" width="889802.927" height="226474.243" style="stroke: rgb(0, 0, 0); stroke-opacity: 0; fill: rgb(172, 67, 67); opacity: 0.76;"/>
+</svg>
\ No newline at end of file
diff --git a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-demo-01.png b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-demo-01.png
new file mode 100644
index 000000000..fc33a023a
Binary files /dev/null and b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-demo-01.png differ
diff --git a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-demo-02.png b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-demo-02.png
new file mode 100644
index 000000000..7d8bb01e8
Binary files /dev/null and b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-demo-02.png differ
diff --git a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-demo-03.gif b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-demo-03.gif
new file mode 100644
index 000000000..b81966dda
Binary files /dev/null and b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-demo-03.gif differ
diff --git a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-demo-04.jpg b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-demo-04.jpg
new file mode 100644
index 000000000..ba60f1e86
Binary files /dev/null and b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-demo-04.jpg differ
diff --git a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-demo-05.gif b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-demo-05.gif
new file mode 100644
index 000000000..d34bda4d7
Binary files /dev/null and b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-demo-05.gif differ
diff --git a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-demo-06.jpg b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-demo-06.jpg
new file mode 100644
index 000000000..b2655540f
Binary files /dev/null and b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-demo-06.jpg differ
diff --git a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-demo-07.gif b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-demo-07.gif
new file mode 100644
index 000000000..51f874518
Binary files /dev/null and b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-demo-07.gif differ
diff --git a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-demo-08.jpg b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-demo-08.jpg
new file mode 100644
index 000000000..5f98aec14
Binary files /dev/null and b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-demo-08.jpg differ
diff --git a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry.view/index.css b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry.view/index.css
new file mode 100644
index 000000000..e6c9e3960
--- /dev/null
+++ b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry.view/index.css
@@ -0,0 +1,285 @@
+:root {
+    --mineralGreen: 60, 98, 85;
+    --viridianGreen: 97, 135, 110;
+    --swampGreen: 166, 187, 141;
+    --fallGreen: 234, 231, 177;
+    --brinkPink: #FA7070;
+    --silverChalice: 178, 178, 178;
+    --white: 255, 255, 255;
+    --black: 0, 0, 0;
+
+    --topBarHeight: 64px;
+    --itemPadding: 32px;
+    --containerGap: 8px;
+}
+
+@keyframes zoom-in {
+    0% {
+        transform: scale(1, 1);
+    }
+
+    100% {
+        transform: scale(1.30, 1.30);
+    }
+}
+
+body, html {
+    margin: 0;
+    padding: 0;
+}
+
+.app {
+    min-height: 100vh;
+    background-color: rgba(var(--viridianGreen), 0.5);
+}
+
+.header {
+    height: var(--topBarHeight);
+    padding: 0 24px;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    background-color: rgba(var(--mineralGreen), 1);
+}
+
+.header-text {
+    color: white;
+}
+
+.container {
+    display: flex;
+    gap: 24px;
+    padding: var(--itemPadding);
+}
+
+.item {
+    width: 50%;
+}
+
+.item--scrollable {
+    overflow-y: scroll;
+    height: calc(100vh - var(--topBarHeight) - (var(--itemPadding) * 2));
+}
+
+.thumbnails-container {
+    display: flex;
+    flex-wrap: wrap;
+    gap: 8px;
+    justify-content: center;
+    align-items: center;
+}
+
+.thumbnail-item {
+    width: calc(25% - var(--containerGap));
+    cursor: pointer;
+    position: relative;
+}
+
+.thumbnail-item:hover {
+    z-index: 1;
+    animation: zoom-in 0.1s forwards;
+}
+
+.thumbnail-item--selected {
+    outline: 3px solid rgba(var(--fallGreen), 1);
+    outline-offset: -3px;
+}
+
+.badge {
+    width: 16px;
+    height: 16px;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    padding: 4px;
+    position: absolute;
+    right: 8px;
+    bottom: 8px;
+    border-radius: 50%;
+    border: 2px solid rgba(var(--fallGreen), 1);
+    background-color: rgba(var(--swampGreen), 1);
+}
+
+.check {
+    display: inline-block;
+    transform: rotate(45deg);
+    border-bottom: 2px solid white;
+    border-right: 2px solid white;
+    width: 6px;
+    height: 12px;
+}
+
+.img {
+    width: 100%;
+    height: 100%;
+    object-fit: cover;
+}
+
+.actions {
+    display: flex;
+    flex-wrap: wrap;
+    justify-content: center;
+    align-content: center;
+    padding: 0 0 16px 0;
+    gap: 8px;
+}
+
+.select {
+    padding: 16px;
+    cursor: pointer;
+    font-weight: 700;
+    color: rgba(var(--black), 1);
+    border: 2px solid rgba(var(--swampGreen), 0.5);
+    background-color: rgba(var(--swampGreen), 1);
+}
+
+.select:disabled {
+    cursor: not-allowed;
+    background-color: rgba(var(--silverChalice), 1);
+    color: rgba(var(--black), 0.5);
+    border: 2px solid rgba(var(--black), 0.25);
+}
+
+.btn {
+    outline: none;
+    padding: 16px;
+    cursor: pointer;
+    font-weight: 700;
+    color: rgba(var(--black), 1);
+    border: 2px solid rgba(var(--black), 0.5);
+}
+
+.btn--primary {
+    background-color: rgba(var(--mineralGreen), 1);
+}
+
+.btn--primary:hover:not([disabled]) {
+    background-color: rgba(var(--mineralGreen), 0.85);
+}
+
+.btn--secondary {
+    background-color: rgba(var(--viridianGreen), 0.5);
+}
+
+.btn--secondary:hover:not([disabled]) {
+    background-color: rgba(var(--swampGreen), 0.25);
+}
+
+.btn--success {
+    background-color: rgba(var(--fallGreen), 1);
+}
+
+.btn--success:hover:not([disabled]) {
+    background-color: rgba(var(--fallGreen), 0.85);
+}
+
+.btn:disabled {
+    cursor: not-allowed;
+    background-color: rgba(var(--silverChalice), 1);
+    color: rgba(var(--black), 0.5);
+    border: 2px solid rgba(var(--black), 0.25);
+}
+
+.previewContainer {
+    margin-bottom: 16px;
+    display: flex;
+    width: 100%;
+    height: 40vh;
+    overflow: scroll;
+    border: 3px solid rgba(var(--black), 1);
+}
+
+.previewContainer--disabled {
+    background-color: rgba(var(--black), 0.1);
+    cursor: not-allowed;
+}
+
+.canvas {
+    margin: auto;
+    display: none;
+}
+
+.canvas--ready {
+    display: block;
+}
+
+.spinnerContainer {
+    display: flex;
+    gap: 8px;
+    flex-direction: column;
+    align-content: center;
+    align-items: center;
+    margin: auto;
+}
+
+.spinnerContainer--hidden {
+    display: none;
+}
+
+.spinnerText {
+    margin: 0;
+    color: rgba(var(--mineralGreen), 1);
+}
+
+.spinner {
+    display: inline-block;
+    width: 50px;
+    height: 50px;
+    margin: auto;
+    border: 3px solid rgba(var(--mineralGreen), 0.3);
+    border-radius: 50%;
+    border-top-color: rgba(var(--mineralGreen), 0.9);
+    animation: spin 1s ease-in-out infinite;
+}
+
+@keyframes spin {
+    to {
+        transform: rotate(360deg);
+    }
+}
+
+.loggerContainer {
+    display: flex;
+    flex-direction: column;
+    gap: 8px;
+    padding: 0 8px 8px 8px;
+    width: 100%;
+    min-height: 30vh;
+    max-height: 30vh;
+    overflow: scroll;
+    border-left: 3px solid rgba(var(--black), 0.25);
+}
+
+.logger-title {
+    display: flex;
+    align-items: center;
+    padding: 8px;
+    position: sticky;
+    height: 40px;
+    min-height: 40px;
+    top: 0;
+    left: 0;
+    background-color: rgba(var(--viridianGreen), 1);
+    font-size: 24px;
+    font-weight: 700;
+    margin: 0;
+}
+
+.logger-item {
+    font-size: 14px;
+    padding: 8px;
+    border: 2px solid #5a5a5a;
+    color: white;
+}
+
+.logger--primary {
+    background-color: #13315a;
+}
+
+.logger--success {
+    background-color: #385a4e;
+}
+
+.logger--error {
+    background-color: #5a1a24;
+}
\ No newline at end of file
diff --git a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry.view/index.html b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry.view/index.html
new file mode 100644
index 000000000..7ce52f927
--- /dev/null
+++ b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry.view/index.html
@@ -0,0 +1,49 @@
+<!DOCTYPE HTML>
+<html lang="en">
+
+<head>
+  <meta charset="utf-8">
+  <link rel="stylesheet" href="index.css">
+  <title>Photo Library Collage</title>
+</head>
+
+<body>
+
+<div class="app">
+  <header class="header">
+    <h1 class="header-text">
+      Photo Library Collage
+    </h1>
+  </header>
+  <div class="container">
+    <div class="item item--scrollable">
+      <!--Thumbnails-->
+      <div class="thumbnails-container"></div>
+    </div>
+    <div class="item">
+      <div>
+        <div class=actions>
+          <select class="select"></select>
+          <button class="btn btn--primary btn-create-collage"> Create collage </button>
+          <button class="btn btn--secondary btn-start-over"> Start over </button>
+          <button class="btn btn--success btn-download" onClick={downloadCollage}> Download </button>
+        </div>
+        <div class="previewContainer">
+          <div class="spinnerContainer spinnerContainer--hidden">
+            <div class="spinner"></div>
+            <p class="spinnerText"></p>
+          </div>
+          <canvas class="canvas"></canvas>
+        </div>
+        <div class="loggerContainer">
+          <p class="logger-title">Logger:</p>
+        </div>
+      </div>
+    </div>
+  </div>
+</div>
+
+
+<script type="module" src="index.js"></script>
+</body>
+</html>
diff --git a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry.view/index.js b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry.view/index.js
new file mode 100644
index 000000000..983b34d9a
--- /dev/null
+++ b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry.view/index.js
@@ -0,0 +1,228 @@
+import {
+    createImageFile,
+    loadImage,
+    weakRefCache,
+    LAYOUTS,
+    images,
+    THUMBNAIL_PARAMS,
+    stateObj,
+} from "./utils.js";
+
+export const state = new Proxy(stateObj, {
+    set(target, property, value) {
+        const previousValue = target[property];
+
+        target[property] = value;
+
+        if (previousValue !== value) {
+            handleStateChange(target);
+        }
+
+        return true;
+    },
+});
+
+// Elements.
+const thumbnailsContainerEl = document.querySelector(".thumbnails-container");
+const selectEl = document.querySelector(".select");
+const previewContainerEl = document.querySelector(".previewContainer");
+const canvasEl = document.querySelector(".canvas");
+const createCollageBtn = document.querySelector(".btn-create-collage");
+const startOverBtn = document.querySelector(".btn-start-over");
+const downloadBtn = document.querySelector(".btn-download");
+const spinnerContainerEl = document.querySelector(".spinnerContainer");
+const spinnerTextEl = document.querySelector(".spinnerText");
+const loggerContainerEl = document.querySelector(".loggerContainer");
+
+// Renders.
+// Render thumbnails previews.
+images.forEach((img) => {
+    const thumbnail = document.createElement("div");
+    thumbnail.classList.add("thumbnail-item");
+
+    thumbnail.innerHTML = `
+        <img src='${img.img}?${THUMBNAIL_PARAMS}' class="img">
+  `;
+
+    thumbnail.addEventListener("click", (e) => handleSelection(e, img));
+
+    thumbnailsContainerEl.appendChild(thumbnail);
+});
+// Render layouts select.
+LAYOUTS.forEach((layout) => {
+    const option = document.createElement("option");
+    option.value = JSON.stringify(layout);
+    option.innerHTML = layout.name;
+    selectEl.appendChild(option);
+});
+
+const handleStateChange = (state) => {
+    if (state.loading) {
+        selectEl.disabled = true;
+        createCollageBtn.disabled = true;
+        startOverBtn.disabled = true;
+        downloadBtn.disabled = true;
+        previewContainerEl.classList.add("previewContainer--disabled");
+        spinnerContainerEl.classList.remove("spinnerContainer--hidden");
+        spinnerTextEl.innerText = "Loading...";
+        canvasEl.classList.remove("canvas--ready");
+    } else if (!state.loading) {
+        selectEl.disabled = false;
+        createCollageBtn.disabled = false;
+        startOverBtn.disabled = false;
+        downloadBtn.disabled = false;
+        previewContainerEl.classList.remove("previewContainer--disabled");
+        spinnerContainerEl.classList.add("spinnerContainer--hidden");
+        canvasEl.classList.add("canvas--ready");
+    }
+
+    if (!state.selectedImages.size) {
+        createCollageBtn.disabled = true;
+        document.querySelectorAll(".badge").forEach((item) => item.remove());
+    } else if (state.selectedImages.size && !state.loading) {
+        createCollageBtn.disabled = false;
+    }
+
+    if (!state.collageRendered) {
+        downloadBtn.disabled = true;
+    } else if (state.collageRendered) {
+        downloadBtn.disabled = false;
+    }
+};
+handleStateChange(state);
+
+const handleSelection = (e, imgName) => {
+    const imgEl = e.currentTarget;
+
+    imgEl.classList.toggle("thumbnail-item--selected");
+
+    if (state.selectedImages.has(imgName)) {
+        state.selectedImages.delete(imgName);
+        state.selectedImages = new Set(state.selectedImages);
+        imgEl.querySelector(".badge")?.remove();
+    } else {
+        state.selectedImages = new Set(state.selectedImages.add(imgName));
+
+        const badge = document.createElement("div");
+        badge.classList.add("badge");
+        badge.innerHTML = `
+            <div class="check" />
+        `;
+        imgEl.prepend(badge);
+    }
+};
+
+// Make a wrapper function.
+let getCachedImage;
+(async () => {
+    getCachedImage = await weakRefCache(loadImage);
+})();
+
+const calculateGridRows = (blobsLength) =>
+    Math.ceil(blobsLength / state.currentLayout.columns);
+
+const drawCollage = (images) => {
+    state.drawing = true;
+
+    let context = canvasEl.getContext("2d");
+
+    /**
+     * Calculate canvas dimensions based on the current layout.
+     * */
+    context.canvas.width =
+        state.currentLayout.itemWidth * state.currentLayout.columns;
+    context.canvas.height =
+        calculateGridRows(images.length) * state.currentLayout.itemHeight;
+
+    let currentRow = 0;
+    let currentCanvasDx = 0;
+    let currentCanvasDy = 0;
+
+    for (let i = 0; i < images.length; i++) {
+        /**
+         * Get current row of the collage.
+         * */
+        if (i % state.currentLayout.columns === 0) {
+            currentRow += 1;
+            currentCanvasDx = 0;
+
+            if (currentRow > 1) {
+                currentCanvasDy += state.currentLayout.itemHeight;
+            }
+        }
+
+        context.drawImage(
+            images[i],
+            0,
+            0,
+            images[i].width,
+            images[i].height,
+            currentCanvasDx,
+            currentCanvasDy,
+            state.currentLayout.itemWidth,
+            state.currentLayout.itemHeight,
+        );
+
+        currentCanvasDx += state.currentLayout.itemWidth;
+    }
+
+    state.drawing = false;
+    state.collageRendered = true;
+};
+
+const createCollage = async () => {
+    state.loading = true;
+
+    const images = [];
+
+    for (const image of state.selectedImages.values()) {
+        const blobImage = await getCachedImage(image.img);
+
+        const url = URL.createObjectURL(blobImage);
+        const img = await createImageFile(url);
+
+        images.push(img);
+        URL.revokeObjectURL(url);
+    }
+
+    state.loading = false;
+
+    drawCollage(images);
+};
+
+/**
+ * Clear all settled data to start over.
+ * */
+const startOver = () => {
+    state.selectedImages = new Set();
+    state.collageRendered = false;
+    const context = canvasEl.getContext("2d");
+    context.clearRect(0, 0, canvasEl.width, canvasEl.height);
+
+    document
+        .querySelectorAll(".thumbnail-item--selected")
+        .forEach((item) => item.classList.remove("thumbnail-item--selected"));
+
+    loggerContainerEl.innerHTML = '<p class="logger-title">Logger:</p>';
+};
+
+const downloadCollage = () => {
+    const date = new Date();
+    const fileName = `Collage-${date.getDay()}-${date.getMonth()}-${date.getFullYear()}.png`;
+    const img = canvasEl.toDataURL("image/png");
+    const link = document.createElement("a");
+    link.download = fileName;
+    link.href = img;
+    link.click();
+    link.remove();
+};
+
+const changeLayout = ({ target }) => {
+    state.currentLayout = JSON.parse(target.value);
+};
+
+// Listeners.
+selectEl.addEventListener("change", changeLayout);
+createCollageBtn.addEventListener("click", createCollage);
+startOverBtn.addEventListener("click", startOver);
+downloadBtn.addEventListener("click", downloadCollage);
diff --git a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry.view/utils.js b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry.view/utils.js
new file mode 100644
index 000000000..f0140c116
--- /dev/null
+++ b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry.view/utils.js
@@ -0,0 +1,321 @@
+const loggerContainerEl = document.querySelector(".loggerContainer");
+
+export const images = [
+    {
+        img: "https://images.unsplash.com/photo-1471357674240-e1a485acb3e1",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1589118949245-7d38baf380d6",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1527631746610-bca00a040d60",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1500835556837-99ac94a94552",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1503220317375-aaad61436b1b",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1501785888041-af3ef285b470",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1528543606781-2f6e6857f318",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1523906834658-6e24ef2386f9",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1539635278303-d4002c07eae3",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1533105079780-92b9be482077",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1516483638261-f4dbaf036963",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1502791451862-7bd8c1df43a7",
+    },
+    {
+        img: "https://plus.unsplash.com/premium_photo-1663047367140-91adf819d007",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1506197603052-3cc9c3a201bd",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1517760444937-f6397edcbbcd",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1518684079-3c830dcef090",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1505832018823-50331d70d237",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1524850011238-e3d235c7d4c9",
+    },
+    {
+        img: "https://plus.unsplash.com/premium_photo-1661277758451-b5053309eea1",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1541410965313-d53b3c16ef17",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1528702748617-c64d49f918af",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1502003148287-a82ef80a6abc",
+    },
+    {
+        img: "https://plus.unsplash.com/premium_photo-1661281272544-5204ea3a481a",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1503457574462-bd27054394c1",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1499363536502-87642509e31b",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1551918120-9739cb430c6d",
+    },
+    {
+        img: "https://plus.unsplash.com/premium_photo-1661382219642-43e54f7e81d7",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1497262693247-aa258f96c4f5",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1525254134158-4fd5fdd45793",
+    },
+    {
+        img: "https://plus.unsplash.com/premium_photo-1661274025419-4c54107d5c48",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1553697388-94e804e2f0f6",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1574260031597-bcd9eb192b4f",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1536323760109-ca8c07450053",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1527824404775-dce343118ebc",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1612278675615-7b093b07772d",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1522010675502-c7b3888985f6",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1501555088652-021faa106b9b",
+    },
+    {
+        img: "https://plus.unsplash.com/premium_photo-1669223469435-27e091439169",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1506012787146-f92b2d7d6d96",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1511739001486-6bfe10ce785f",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1553342385-111fd6bc6ab3",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1516546453174-5e1098a4b4af",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1527142879-95b61a0b8226",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1520466809213-7b9a56adcd45",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1516939884455-1445c8652f83",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1545389336-cf090694435e",
+    },
+    {
+        img: "https://plus.unsplash.com/premium_photo-1669223469455-b7b734c838f4",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1454391304352-2bf4678b1a7a",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1433838552652-f9a46b332c40",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1506125840744-167167210587",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1522199873717-bc67b1a5e32b",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1495904786722-d2b5a19a8535",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1614094082869-cd4e4b2905c7",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1474755032398-4b0ed3b2ae5c",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1501554728187-ce583db33af7",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1515859005217-8a1f08870f59",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1531141445733-14c2eb7d4c1f",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1500259783852-0ca9ce8a64dc",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1510662145379-13537db782dc",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1573790387438-4da905039392",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1512757776214-26d36777b513",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1518855706573-84de4022b69b",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1500049242364-5f500807cdd7",
+    },
+    {
+        img: "https://images.unsplash.com/photo-1528759335187-3b683174c86a",
+    },
+];
+export const THUMBNAIL_PARAMS = "w=240&h=240&fit=crop&auto=format";
+
+// Console styles.
+export const CONSOLE_BASE_STYLES = [
+    "font-size: 12px",
+    "padding: 4px",
+    "border: 2px solid #5a5a5a",
+    "color: white",
+].join(";");
+export const CONSOLE_PRIMARY = [
+    CONSOLE_BASE_STYLES,
+    "background-color: #13315a",
+].join(";");
+export const CONSOLE_SUCCESS = [
+    CONSOLE_BASE_STYLES,
+    "background-color: #385a4e",
+].join(";");
+export const CONSOLE_ERROR = [
+    CONSOLE_BASE_STYLES,
+    "background-color: #5a1a24",
+].join(";");
+
+// Layouts.
+export const LAYOUT_4_COLUMNS = {
+    name: "Layout 4 columns",
+    columns: 4,
+    itemWidth: 240,
+    itemHeight: 240,
+};
+export const LAYOUT_8_COLUMNS = {
+    name: "Layout 8 columns",
+    columns: 8,
+    itemWidth: 240,
+    itemHeight: 240,
+};
+export const LAYOUTS = [LAYOUT_4_COLUMNS, LAYOUT_8_COLUMNS];
+
+export const createImageFile = async (src) =>
+    new Promise((resolve, reject) => {
+        const img = new Image();
+        img.src = src;
+        img.onload = () => resolve(img);
+        img.onerror = () => reject(new Error("Failed to construct image."));
+    });
+
+export const loadImage = async (url) => {
+    try {
+        const response = await fetch(url);
+        if (!response.ok) {
+            throw new Error(String(response.status));
+        }
+
+        return await response.blob();
+    } catch (e) {
+        console.log(`%cFETCHED_FAILED: ${e}`, CONSOLE_ERROR);
+    }
+};
+
+export const weakRefCache = (fetchImg) => {
+    const imgCache = new Map();
+    const registry = new FinalizationRegistry(({ imgName, size, type }) => {
+        const cachedImg = imgCache.get(imgName);
+        if (cachedImg && !cachedImg.deref()) {
+            imgCache.delete(imgName);
+            console.log(
+                `%cCLEANED_IMAGE: Url: ${imgName}, Size: ${size}, Type: ${type}`,
+                CONSOLE_ERROR,
+            );
+
+            const logEl = document.createElement("div");
+            logEl.classList.add("logger-item", "logger--error");
+            logEl.innerHTML = `CLEANED_IMAGE: Url: ${imgName}, Size: ${size}, Type: ${type}`;
+            loggerContainerEl.appendChild(logEl);
+            loggerContainerEl.scrollTop = loggerContainerEl.scrollHeight;
+        }
+    });
+
+    return async (imgName) => {
+        const cachedImg = imgCache.get(imgName);
+
+        if (cachedImg?.deref() !== undefined) {
+            console.log(
+                `%cCACHED_IMAGE: Url: ${imgName}, Size: ${cachedImg.size}, Type: ${cachedImg.type}`,
+                CONSOLE_SUCCESS,
+            );
+
+            const logEl = document.createElement("div");
+            logEl.classList.add("logger-item", "logger--success");
+            logEl.innerHTML = `CACHED_IMAGE: Url: ${imgName}, Size: ${cachedImg.size}, Type: ${cachedImg.type}`;
+            loggerContainerEl.appendChild(logEl);
+            loggerContainerEl.scrollTop = loggerContainerEl.scrollHeight;
+
+            return cachedImg?.deref();
+        }
+
+        const newImg = await fetchImg(imgName);
+        console.log(
+            `%cFETCHED_IMAGE: Url: ${imgName}, Size: ${newImg.size}, Type: ${newImg.type}`,
+            CONSOLE_PRIMARY,
+        );
+
+        const logEl = document.createElement("div");
+        logEl.classList.add("logger-item", "logger--primary");
+        logEl.innerHTML = `FETCHED_IMAGE: Url: ${imgName}, Size: ${newImg.size}, Type: ${newImg.type}`;
+        loggerContainerEl.appendChild(logEl);
+        loggerContainerEl.scrollTop = loggerContainerEl.scrollHeight;
+
+        imgCache.set(imgName, new WeakRef(newImg));
+        registry.register(newImg, {
+            imgName,
+            size: newImg.size,
+            type: newImg.type,
+        });
+
+        return newImg;
+    };
+};
+
+export const stateObj = {
+    loading: false,
+    drawing: true,
+    collageRendered: false,
+    currentLayout: LAYOUTS[0],
+    selectedImages: new Set(),
+};
diff --git a/2-ui/1-document/01-browser-environment/article.md b/2-ui/1-document/01-browser-environment/article.md
index f680554dd..eedc28fb3 100644
--- a/2-ui/1-document/01-browser-environment/article.md
+++ b/2-ui/1-document/01-browser-environment/article.md
@@ -1,12 +1,12 @@
 # Browser environment, specs
 
-The JavaScript language was initially created for web browsers. Since then it has evolved and become a language with many uses and platforms.
+The JavaScript language was initially created for web browsers. Since then, it has evolved into a language with many uses and platforms.
 
-A platform may be a browser, or a web-server or another *host*, even a coffee machine. Each of them provides platform-specific functionality. The JavaScript specification calls that a *host environment*.
+A platform may be a browser, or a web-server or another *host*, or even a "smart" coffee machine if it can run JavaScript. Each of these provides platform-specific functionality. The JavaScript specification calls that a *host environment*.
 
-A host environment provides own objects and functions additional to the language core. Web browsers give a means to control web pages. Node.js provides server-side features, and so on.
+A host environment provides its own objects and functions in addition to the language core. Web browsers give a means to control web pages. Node.js provides server-side features, and so on.
 
-Here's a bird's-eye view of what we have when JavaScript runs in a web-browser:
+Here's a bird's-eye view of what we have when JavaScript runs in a web browser:
 
 ![](windowObjects.svg)
 
@@ -15,9 +15,9 @@ There's a "root" object called `window`. It has two roles:
 1. First, it is a global object for JavaScript code, as described in the chapter <info:global-object>.
 2. Second, it represents the "browser window" and provides methods to control it.
 
-For instance, here we use it as a global object:
+For instance, we can use it as a global object:
 
-```js run
+```js run global
 function sayHi() {
   alert("Hello");
 }
@@ -26,17 +26,17 @@ function sayHi() {
 window.sayHi();
 ```
 
-And here we use it as a browser window, to see the window height:
+And we can use it as a browser window, to show the window height:
 
 ```js run
 alert(window.innerHeight); // inner window height
 ```
 
-There are more window-specific methods and properties, we'll cover them later.
+There are more window-specific methods and properties, which we'll cover later.
 
 ## DOM (Document Object Model)
 
-Document Object Model, or DOM for short, represents all page content as objects that can be modified.
+The Document Object Model, or DOM for short, represents all page content as objects that can be modified.
 
 The `document` object is the main "entry point" to the page. We can change or create anything on the page using it.
 
@@ -49,20 +49,18 @@ document.body.style.background = "red";
 setTimeout(() => document.body.style.background = "", 1000);
 ```
 
-Here we used `document.body.style`, but there's much, much more. Properties and methods are described in the specification:
-
-- **DOM Living Standard** at <https://dom.spec.whatwg.org>
+Here, we used `document.body.style`, but there's much, much more. Properties and methods are described in the specification: [DOM Living Standard](https://dom.spec.whatwg.org).
 
 ```smart header="DOM is not only for browsers"
 The DOM specification explains the structure of a document and provides objects to manipulate it. There are non-browser instruments that use DOM too.
 
-For instance, server-side scripts that download HTML pages and process them can also use DOM. They may support only a part of the specification though.
+For instance, server-side scripts that download HTML pages and process them can also use the DOM. They may support only a part of the specification though.
 ```
 
 ```smart header="CSSOM for styling"
-CSS rules and stylesheets are structured in a different way than HTML. There's a separate specification, [CSS Object Model (CSSOM)](https://www.w3.org/TR/cssom-1/), that explains how they are represented as objects, and how to read and write them.
+There's also a separate specification, [CSS Object Model (CSSOM)](https://www.w3.org/TR/cssom-1/) for CSS rules and stylesheets, that explains how they are represented as objects, and how to read and write them.
 
-CSSOM is used together with DOM when we modify style rules for the document. In practice though, CSSOM is rarely required, because usually CSS rules are static. We rarely need to add/remove CSS rules from JavaScript, but that's also possible.
+The CSSOM is used together with the DOM when we modify style rules for the document. In practice though, the CSSOM is rarely required, because we rarely need to modify CSS rules from JavaScript (usually we just add/remove CSS classes, not modify their CSS rules), but that's also possible.
 ```
 
 ## BOM (Browser Object Model)
@@ -71,7 +69,7 @@ The Browser Object Model (BOM) represents additional objects provided by the bro
 
 For instance:
 
-- The [navigator](mdn:api/Window/navigator) object provides background information about the browser and the operating system. There are many properties, but the two most widely known are: `navigator.userAgent` -- about the current browser, and `navigator.platform` -- about the platform (can help to differ between Windows/Linux/Mac etc).
+- The [navigator](mdn:api/Window/navigator) object provides background information about the browser and the operating system. There are many properties, but the two most widely known are: `navigator.userAgent` -- about the current browser, and `navigator.platform` -- about the platform (can help to differentiate between Windows/Linux/Mac etc).
 - The [location](mdn:api/Window/location) object allows us to read the current URL and can redirect the browser to a new one.
 
 Here's how we can use the `location` object:
@@ -83,12 +81,12 @@ if (confirm("Go to Wikipedia?")) {
 }
 ```
 
-Functions `alert/confirm/prompt` are also a part of BOM: they are directly not related to the document, but represent pure browser methods of communicating with the user.
+The functions `alert/confirm/prompt` are also a part of the BOM: they are not directly related to the document, but represent pure browser methods for communicating with the user.
 
 ```smart header="Specifications"
-BOM is the part of the general [HTML specification](https://html.spec.whatwg.org).
+The BOM is a part of the general [HTML specification](https://html.spec.whatwg.org).
 
-Yes, you heard that right. The HTML spec at <https://html.spec.whatwg.org> is not only about the "HTML language" (tags, attributes), but also covers a bunch of objects, methods and browser-specific DOM extensions. That's "HTML in broad terms". Also, some parts have additional specs listed at <https://spec.whatwg.org>.
+Yes, you heard that right. The HTML spec at <https://html.spec.whatwg.org> is not only about the "HTML language" (tags, attributes), but also covers a bunch of objects, methods, and browser-specific DOM extensions. That's "HTML in broad terms". Also, some parts have additional specs listed at <https://spec.whatwg.org>.
 ```
 
 ## Summary
@@ -96,20 +94,20 @@ Yes, you heard that right. The HTML spec at <https://html.spec.whatwg.org> is no
 Talking about standards, we have:
 
 DOM specification
-: Describes the document structure, manipulations and events, see <https://dom.spec.whatwg.org>.
+: Describes the document structure, manipulations, and events, see <https://dom.spec.whatwg.org>.
 
 CSSOM specification
-: Describes stylesheets and style rules, manipulations with them and their binding to documents, see <https://www.w3.org/TR/cssom-1/>.
+: Describes stylesheets and style rules, manipulations with them, and their binding to documents, see <https://www.w3.org/TR/cssom-1/>.
 
 HTML specification
 : Describes the HTML language (e.g. tags) and also the BOM (browser object model) -- various browser functions: `setTimeout`, `alert`, `location` and so on, see <https://html.spec.whatwg.org>. It takes the DOM specification and extends it with many additional properties and methods.
 
 Additionally, some classes are described separately at <https://spec.whatwg.org/>.
 
-Please note these links, as there's so much stuff to learn it's impossible to cover and remember everything.
+Please note these links, as there's so much to learn that it's impossible to cover everything and remember it all.
 
-When you'd like to read about a property or a method, the Mozilla manual at <https://developer.mozilla.org/en-US/search> is also a nice resource, but the corresponding spec may be better: it's more complex and longer to read, but will make your fundamental knowledge sound and complete.
+When you'd like to read about a property or a method, the Mozilla manual at <https://developer.mozilla.org/en-US/> is also a nice resource, but the corresponding spec may be better: it's more complex and longer to read, but will make your fundamental knowledge sound and complete.
 
 To find something, it's often convenient to use an internet search "WHATWG [term]" or "MDN [term]", e.g <https://google.com?q=whatwg+localstorage>, <https://google.com?q=mdn+localstorage>.
 
-Now we'll get down to learning DOM, because the document plays the central role in the UI.
+Now, we'll get down to learning the DOM, because the document plays the central role in the UI.
diff --git a/2-ui/1-document/02-dom-nodes/article.md b/2-ui/1-document/02-dom-nodes/article.md
index 019398be9..f7f2be91d 100644
--- a/2-ui/1-document/02-dom-nodes/article.md
+++ b/2-ui/1-document/02-dom-nodes/article.md
@@ -51,7 +51,7 @@ The DOM represents HTML as a tree structure of tags. Here's how it looks:
 <div class="domtree"></div>
 
 <script>
-let node1 = {"name":"HTML","nodeType":1,"children":[{"name":"HEAD","nodeType":1,"children":[{"name":"#text","nodeType":3,"content":"\n    "},{"name":"TITLE","nodeType":1,"children":[{"name":"#text","nodeType":3,"content":"About elk"}]},{"name":"#text","nodeType":3,"content":"\n  "}]},{"name":"#text","nodeType":3,"content":"\n  "},{"name":"BODY","nodeType":1,"children":[{"name":"#text","nodeType":3,"content":"\n  The truth about elk."}]}]}
+let node1 = {"name":"HTML","nodeType":1,"children":[{"name":"HEAD","nodeType":1,"children":[{"name":"#text","nodeType":3,"content":"\n  "},{"name":"TITLE","nodeType":1,"children":[{"name":"#text","nodeType":3,"content":"About elk"}]},{"name":"#text","nodeType":3,"content":"\n"}]},{"name":"#text","nodeType":3,"content":"\n"},{"name":"BODY","nodeType":1,"children":[{"name":"#text","nodeType":3,"content":"\n  The truth about elk.\n"}]}]}
 
 drawHtmlTree(node1, 'div.domtree', 690, 320);
 </script>
@@ -143,7 +143,7 @@ drawHtmlTree(node4, 'div.domtree', 690, 360);
 </script>
 
 ````warn header="Tables always have `<tbody>`"
-An interesting "special case" is tables. By the DOM specification they must have `<tbody>`, but HTML text may (officially) omit it. Then the browser creates `<tbody>` in the DOM automatically.
+An interesting "special case" is tables. By DOM specification they must have `<tbody>` tag, but HTML text may omit it. Then the browser creates `<tbody>` in the DOM automatically.
 
 For the HTML:
 
@@ -160,7 +160,7 @@ let node5 = {"name":"TABLE","nodeType":1,"children":[{"name":"TBODY","nodeType":
 drawHtmlTree(node5,  'div.domtree', 600, 200);
 </script>
 
-You see? The `<tbody>` appeared out of nowhere. You should keep this in mind while working with tables to avoid surprises.
+You see? The `<tbody>` appeared out of nowhere. We should keep this in mind while working with tables to avoid surprises.
 ````
 
 ## Other node types
@@ -188,7 +188,7 @@ For example, comments:
 <div class="domtree"></div>
 
 <script>
-let node6 = {"name":"HTML","nodeType":1,"children":[{"name":"HEAD","nodeType":1,"children":[]},{"name":"BODY","nodeType":1,"children":[{"name":"#text","nodeType":3,"content":"\n  The truth about elk.\n    "},{"name":"OL","nodeType":1,"children":[{"name":"#text","nodeType":3,"content":"\n      "},{"name":"LI","nodeType":1,"children":[{"name":"#text","nodeType":3,"content":"An elk is a smart"}]},{"name":"#text","nodeType":3,"content":"\n      "},{"name":"#comment","nodeType":8,"content":"comment"},{"name":"#text","nodeType":3,"content":"\n      "},{"name":"LI","nodeType":1,"children":[{"name":"#text","nodeType":3,"content":"...and cunning animal!"}]},{"name":"#text","nodeType":3,"content":"\n    "}]},{"name":"#text","nodeType":3,"content":"\n  \n"}]}]};
+let node6 = {"name":"HTML","nodeType":1,"children":[{"name":"HEAD","nodeType":1,"children":[]},{"name":"BODY","nodeType":1,"children":[{"name":"#text","nodeType":3,"content":"\n  The truth about elk.\n  "},{"name":"OL","nodeType":1,"children":[{"name":"#text","nodeType":3,"content":"\n    "},{"name":"LI","nodeType":1,"children":[{"name":"#text","nodeType":3,"content":"An elk is a smart"}]},{"name":"#text","nodeType":3,"content":"\n    "},{"name":"#comment","nodeType":8,"content":"comment"},{"name":"#text","nodeType":3,"content":"\n    "},{"name":"LI","nodeType":1,"children":[{"name":"#text","nodeType":3,"content":"...and cunning animal!"}]},{"name":"#text","nodeType":3,"content":"\n  "}]},{"name":"#text","nodeType":3,"content":"\n\n\n"}]}]};
 
 drawHtmlTree(node6, 'div.domtree', 690, 500);
 </script>
@@ -199,7 +199,7 @@ We may think -- why is a comment added to the DOM? It doesn't affect the visual
 
 **Everything in HTML, even comments, becomes a part of the DOM.**
 
-Even the `<!DOCTYPE...>` directive at the very beginning of HTML is also a DOM node. It's in the DOM tree right before `<html>`. We are not going to touch that node, we even don't draw it on diagrams for that reason, but it's there.
+Even the `<!DOCTYPE...>` directive at the very beginning of HTML is also a DOM node. It's in the DOM tree right before `<html>`. Few people know about that. We are not going to touch that node, we even don't draw it on diagrams, but it's there.
 
 The `document` object that represents the whole document is, formally, a DOM node as well.
 
@@ -212,7 +212,7 @@ There are [12 node types](https://dom.spec.whatwg.org/#node). In practice we usu
 
 ## See it for yourself
 
-To see the DOM structure in real-time, try [Live DOM Viewer](http://software.hixie.ch/utilities/js/live-dom-viewer/). Just type in the document, and it will show up as a DOM at an instant.
+To see the DOM structure in real-time, try [Live DOM Viewer](https://software.hixie.ch/utilities/js/live-dom-viewer/). Just type in the document, and it will show up as a DOM at an instant.
 
 Another way to explore the DOM is to use the browser developer tools. Actually, that's what we use when developing.
 
diff --git a/2-ui/1-document/03-dom-navigation/article.md b/2-ui/1-document/03-dom-navigation/article.md
index 332f57827..b5f03098c 100644
--- a/2-ui/1-document/03-dom-navigation/article.md
+++ b/2-ui/1-document/03-dom-navigation/article.md
@@ -201,7 +201,7 @@ The parent is available as `parentNode`.
 
 For example:
 
-```js
+```js run
 // parent of <body> is <html>
 alert( document.body.parentNode === document.documentElement ); // true
 
@@ -214,7 +214,7 @@ alert( document.body.previousSibling ); // HTMLHeadElement
 
 ## Element-only navigation
 
-Navigation properties listed above refer to *all* nodes. For instance, in `childNodes` we can see both text nodes, element nodes, and even comment nodes if there exist.
+Navigation properties listed above refer to *all* nodes. For instance, in `childNodes` we can see both text nodes, element nodes, and even comment nodes if they exist.
 
 But for many tasks we don't want text or comment nodes. We want to manipulate element nodes that represent tags and form the structure of the page.
 
diff --git a/2-ui/1-document/04-searching-elements-dom/article.md b/2-ui/1-document/04-searching-elements-dom/article.md
index cc878009f..405129694 100644
--- a/2-ui/1-document/04-searching-elements-dom/article.md
+++ b/2-ui/1-document/04-searching-elements-dom/article.md
@@ -55,7 +55,7 @@ Also, there's a global variable named by `id` that references the element:
 ```
 
 ```warn header="Please don't use id-named global variables to access elements"
-This behavior is described [in the specification](http://www.whatwg.org/specs/web-apps/current-work/#dom-window-nameditem), so it's kind of standard. But it is supported mainly for compatibility.
+This behavior is described [in the specification](https://html.spec.whatwg.org/multipage/window-object.html#named-access-on-the-window-object), but it is supported mainly for compatibility.
 
 The browser tries to help us by mixing namespaces of JS and DOM. That's fine for simple scripts, inlined into HTML, but generally isn't a good thing. There may be naming conflicts. Also, when one reads JS code and doesn't have HTML in view, it's not obvious where the variable comes from.
 
@@ -71,7 +71,7 @@ If there are multiple elements with the same `id`, then the behavior of methods
 ```
 
 ```warn header="Only `document.getElementById`, not `anyElem.getElementById`"
-The method `getElementById` that can be called only on `document` object. It looks for the given `id` in the whole document.
+The method `getElementById` can be called only on `document` object. It looks for the given `id` in the whole document.
 ```
 
 ## querySelectorAll [#querySelectorAll]
@@ -103,7 +103,7 @@ Here we look for all `<li>` elements that are last children:
 This method is indeed powerful, because any CSS selector can be used.
 
 ```smart header="Can use pseudo-classes as well"
-Pseudo-classes in the CSS selector like `:hover` and `:active` are also supported. For instance, `document.querySelectorAll(':hover')` will return the collection with elements that the pointer is  over now (in nesting order: from the outermost `<html>` to the most nested one).
+Pseudo-classes in the CSS selector like `:hover` and `:active` are also supported. For instance, `document.querySelectorAll(':hover')` will return the collection with elements that the pointer is over now (in nesting order: from the outermost `<html>` to the most nested one).
 ```
 
 ## querySelector [#querySelector]
@@ -116,7 +116,7 @@ In other words, the result is the same as `elem.querySelectorAll(css)[0]`, but t
 
 Previous methods were searching the DOM.
 
-The [elem.matches(css)](http://dom.spec.whatwg.org/#dom-element-matches) does not look for anything, it merely checks if `elem` matches the given CSS-selector. It returns `true` or `false`.
+The [elem.matches(css)](https://dom.spec.whatwg.org/#dom-element-matches) does not look for anything, it merely checks if `elem` matches the given CSS-selector. It returns `true` or `false`.
 
 The method comes in handy when we are iterating over elements (like in an array or something) and trying to filter out those that interest us.
 
@@ -142,7 +142,7 @@ For instance:
 
 *Ancestors* of an element are: parent, the parent of parent, its parent and so on. The ancestors together form the chain of parents from the element to the top.
 
-The method `elem.closest(css)` looks the nearest ancestor that matches the CSS-selector. The `elem` itself is also included in the search.
+The method `elem.closest(css)` looks for the nearest ancestor that matches the CSS-selector. The `elem` itself is also included in the search.
 
 In other words, the method `closest` goes up from the element and checks each of parents. If it matches the selector, then the search stops, and the ancestor is returned.
 
@@ -154,7 +154,7 @@ For instance:
 <div class="contents">
   <ul class="book">
     <li class="chapter">Chapter 1</li>
-    <li class="chapter">Chapter 1</li>
+    <li class="chapter">Chapter 2</li>
   </ul>
 </div>
 
@@ -178,7 +178,7 @@ So here we cover them mainly for completeness, while you can still find them in
 
 - `elem.getElementsByTagName(tag)` looks for elements with the given tag and returns the collection of them. The `tag` parameter can also be a star `"*"` for "any tags".
 - `elem.getElementsByClassName(className)` returns elements that have the given CSS class.
-- `document.getElementsByName(name)` returns elements with the given `name` attribute, document-wide. very rarely used.
+- `document.getElementsByName(name)` returns elements with the given `name` attribute, document-wide. Very rarely used.
 
 For instance:
 ```js
@@ -363,7 +363,7 @@ There are 6 main methods to search for nodes in DOM:
 </tbody>
 </table>
 
-By far the most used are `querySelector` and `querySelectorAll`, but `getElementBy*` can be sporadically helpful or found in the old scripts.
+By far the most used are `querySelector` and `querySelectorAll`, but `getElement(s)By*` can be sporadically helpful or found in the old scripts.
 
 Besides that:
 
diff --git a/2-ui/1-document/05-basic-dom-node-properties/article.md b/2-ui/1-document/05-basic-dom-node-properties/article.md
index 78bc3fd88..99dde5bcd 100644
--- a/2-ui/1-document/05-basic-dom-node-properties/article.md
+++ b/2-ui/1-document/05-basic-dom-node-properties/article.md
@@ -10,7 +10,7 @@ Different DOM nodes may have different properties. For instance, an element node
 
 Each DOM node belongs to the corresponding built-in class.
 
-The root of the hierarchy is [EventTarget](https://dom.spec.whatwg.org/#eventtarget), that is inherited by  [Node](http://dom.spec.whatwg.org/#interface-node), and other DOM nodes inherit from it.
+The root of the hierarchy is [EventTarget](https://dom.spec.whatwg.org/#eventtarget), that is inherited by  [Node](https://dom.spec.whatwg.org/#interface-node), and other DOM nodes inherit from it.
 
 Here's the picture, explanations to follow:
 
@@ -18,16 +18,39 @@ Here's the picture, explanations to follow:
 
 The classes are:
 
-- [EventTarget](https://dom.spec.whatwg.org/#eventtarget) -- is the root "abstract" class. Objects of that class are never created. It serves as a base, so that all DOM nodes support so-called "events", we'll study them later.
-- [Node](http://dom.spec.whatwg.org/#interface-node) -- is also an "abstract" class, serving as a base  for DOM nodes. It provides the core tree functionality: `parentNode`, `nextSibling`, `childNodes` and so on (they are getters). Objects of `Node` class are never created. But there are concrete node classes that inherit from it, namely: `Text` for text nodes, `Element` for element nodes and more exotic ones like `Comment` for comment nodes.
-- [Element](http://dom.spec.whatwg.org/#interface-element) -- is a base class for DOM elements. It provides element-level navigation like `nextElementSibling`, `children` and searching methods like `getElementsByTagName`, `querySelector`. A  browser supports not only HTML, but also XML and SVG. The `Element` class serves as a base for more specific classes: `SVGElement`, `XMLElement` and `HTMLElement`.
-- [HTMLElement](https://html.spec.whatwg.org/multipage/dom.html#htmlelement) -- is finally the basic class for all HTML elements. It is inherited by concrete HTML elements:
+- [EventTarget](https://dom.spec.whatwg.org/#eventtarget) -- is the root "abstract" class for everything.
+
+    Objects of that class are never created. It serves as a base, so that all DOM nodes support so-called "events", we'll study them later.
+
+- [Node](https://dom.spec.whatwg.org/#interface-node) -- is also an "abstract" class, serving as a base  for DOM nodes.
+
+    It provides the core tree functionality: `parentNode`, `nextSibling`, `childNodes` and so on (they are getters). Objects of `Node` class are never created. But there are other classes that inherit from it (and so inherit the `Node` functionality).
+
+- [Document](https://dom.spec.whatwg.org/#interface-document), for historical reasons often inherited by `HTMLDocument` (though the latest spec doesn't dictate it) -- is a document as a whole.
+
+    The `document` global object belongs exactly to this class. It serves as an entry point to the DOM.
+
+- [CharacterData](https://dom.spec.whatwg.org/#interface-characterdata) -- an "abstract" class, inherited by:
+    - [Text](https://dom.spec.whatwg.org/#interface-text) -- the class corresponding to a text inside elements, e.g. `Hello` in `<p>Hello</p>`.
+    - [Comment](https://dom.spec.whatwg.org/#interface-comment) -- the class for comments. They are not shown, but each comment becomes a member of DOM.
+
+- [Element](https://dom.spec.whatwg.org/#interface-element) -- is the base class for DOM elements.
+
+    It provides element-level navigation like `nextElementSibling`, `children` and searching methods like `getElementsByTagName`, `querySelector`.
+
+    A browser supports not only HTML, but also XML and SVG. So the `Element` class serves as a base for more specific classes: `SVGElement`, `XMLElement` (we don't need them here) and `HTMLElement`.
+
+- Finally, [HTMLElement](https://html.spec.whatwg.org/multipage/dom.html#htmlelement) is the basic class for all HTML elements. We'll work with it most of the time.
+
+    It is inherited by concrete HTML elements:
     - [HTMLInputElement](https://html.spec.whatwg.org/multipage/forms.html#htmlinputelement) -- the class for `<input>` elements,
     - [HTMLBodyElement](https://html.spec.whatwg.org/multipage/semantics.html#htmlbodyelement) -- the class for `<body>` elements,
     - [HTMLAnchorElement](https://html.spec.whatwg.org/multipage/semantics.html#htmlanchorelement) -- the class for `<a>` elements,
-    - ...and so on, each tag has its own class that may provide specific properties and methods.
+    - ...and so on.
+
+There are many other tags with their own classes that may have specific properties and methods, while some elements, such as `<span>`, `<section>`, `<article>` do not have any specific properties, so they are instances of `HTMLElement` class.
 
-So, the full set of properties and methods of a given node comes as the result of the inheritance.
+So, the full set of properties and methods of a given node comes as the result of the chain of inheritance.
 
 For example, let's consider the DOM object for an `<input>` element. It belongs to [HTMLInputElement](https://html.spec.whatwg.org/multipage/forms.html#htmlinputelement) class.
 
@@ -36,7 +59,7 @@ It gets properties and methods as a superposition of (listed in inheritance orde
 - `HTMLInputElement` -- this class provides input-specific properties,
 - `HTMLElement` -- it provides common HTML element methods (and getters/setters),
 - `Element` -- provides generic element methods,
-- `Node` -- provides common DOM node properties,.
+- `Node` -- provides common DOM node properties,
 - `EventTarget` -- gives the support for events (to be covered),
 - ...and finally it inherits from `Object`, so "plain object" methods like `hasOwnProperty` are also available.
 
@@ -128,13 +151,13 @@ For instance:
 
 ```html run
 <body>
-  <script>  
+  <script>
   let elem = document.body;
 
-  // let's examine what it is?
+  // let's examine: what type of node is in elem?
   alert(elem.nodeType); // 1 => element
 
-  // and the first child is...
+  // and its first child is...
   alert(elem.firstChild.nodeType); // 3 => text
 
   // for the document object, the type is 9
@@ -198,7 +221,7 @@ In XML mode the case is kept "as is". Nowadays XML mode is rarely used.
 
 ## innerHTML: the contents
 
-The [innerHTML](https://w3c.github.io/DOM-Parsing/#widl-Element-innerHTML) property allows to get the HTML inside the element as a string.
+The [innerHTML](https://w3c.github.io/DOM-Parsing/#the-innerhtml-mixin) property allows to get the HTML inside the element as a string.
 
 We can also modify it. So it's one of the most powerful ways to change the page.
 
@@ -397,7 +420,7 @@ Compare the two:
 <div id="elem2"></div>
 
 <script>
-  let name = prompt("What's your name?", "<b>Winnie-the-pooh!</b>");
+  let name = prompt("What's your name?", "<b>Winnie-the-Pooh!</b>");
 
   elem1.innerHTML = name;
   elem2.textContent = name;
@@ -405,7 +428,7 @@ Compare the two:
 ```
 
 1. The first `<div>` gets the name "as HTML": all tags become tags, so we see the bold name.
-2. The second `<div>` gets the name "as text", so we literally see `<b>Winnie-the-pooh!</b>`.
+2. The second `<div>` gets the name "as text", so we literally see `<b>Winnie-the-Pooh!</b>`.
 
 In most cases, we expect the text from a user, and want to treat it as text. We don't want unexpected HTML in our site. An assignment to `textContent` does exactly that.
 
@@ -413,7 +436,7 @@ In most cases, we expect the text from a user, and want to treat it as text. We
 
 The "hidden" attribute and the DOM property specifies whether the element is visible or not.
 
-We can use it in HTML or assign using JavaScript, like this:
+We can use it in HTML or assign it using JavaScript, like this:
 
 ```html run height="80"
 <div>Both divs below are hidden</div>
diff --git a/2-ui/1-document/06-dom-attributes-and-properties/article.md b/2-ui/1-document/06-dom-attributes-and-properties/article.md
index bcbf074ce..b02f626dc 100644
--- a/2-ui/1-document/06-dom-attributes-and-properties/article.md
+++ b/2-ui/1-document/06-dom-attributes-and-properties/article.md
@@ -162,7 +162,7 @@ In the example below `id` is modified as an attribute, and we can see the proper
 </script>
 ```
 
-But there are exclusions, for instance `input.value` synchronizes only from attribute -> to property, but not back:
+But there are exclusions, for instance `input.value` synchronizes only from attribute -> property, but not back:
 
 ```html run
 <input>
@@ -298,7 +298,7 @@ For instance, here for the order state the attribute `order-state` is used:
 </div>
 ```
 
-Why would using an attribute be preferable to having classes like `.order-state-new`, `.order-state-pending`, `order-state-canceled`?
+Why would using an attribute be preferable to having classes like `.order-state-new`, `.order-state-pending`, `.order-state-canceled`?
 
 Because an attribute is more convenient to manage. The state can be changed as easy as:
 
diff --git a/2-ui/1-document/07-modifying-document/1-createtextnode-vs-innerhtml/task.md b/2-ui/1-document/07-modifying-document/1-createtextnode-vs-innerhtml/task.md
index e127bc0ef..40c75dff3 100644
--- a/2-ui/1-document/07-modifying-document/1-createtextnode-vs-innerhtml/task.md
+++ b/2-ui/1-document/07-modifying-document/1-createtextnode-vs-innerhtml/task.md
@@ -6,7 +6,7 @@ importance: 5
 
 We have an empty DOM element `elem` and a string `text`.
 
-Which of these 3 commands do exactly the same?
+Which of these 3 commands will do exactly the same?
 
 1. `elem.append(document.createTextNode(text))`
 2. `elem.innerHTML = text`
diff --git a/2-ui/1-document/07-modifying-document/10-clock-setinterval/solution.md b/2-ui/1-document/07-modifying-document/10-clock-setinterval/solution.md
index 15238fcf4..1414e90c1 100644
--- a/2-ui/1-document/07-modifying-document/10-clock-setinterval/solution.md
+++ b/2-ui/1-document/07-modifying-document/10-clock-setinterval/solution.md
@@ -39,15 +39,19 @@ The clock-managing functions:
 ```js
 let timerId;
 
-function clockStart() { // run the clock
-  timerId = setInterval(update, 1000);
+function clockStart() { // run the clock  
+  if (!timerId) { // only set a new interval if the clock is not running
+    timerId = setInterval(update, 1000);
+  }
   update(); // (*)
 }
 
 function clockStop() {
   clearInterval(timerId);
-  timerId = null;
+  timerId = null; // (**)
 }
 ```
 
 Please note that the call to `update()` is not only scheduled in `clockStart()`, but immediately run in the line `(*)`. Otherwise the visitor would have to wait till the first execution of `setInterval`. And the clock would be empty till then.
+
+Also it is important to set a new interval in `clockStart()` only when the clock is not running. Otherways clicking the start button several times would set multiple concurrent intervals. Even worse - we would only keep the `timerID` of the last interval, losing references to all others. Then we wouldn't be able to stop the clock ever again! Note that we need to clear the `timerID` when the clock is stopped in the line `(**)`, so that it can be started again by running `clockStart()`.
diff --git a/2-ui/1-document/07-modifying-document/10-clock-setinterval/solution.view/index.html b/2-ui/1-document/07-modifying-document/10-clock-setinterval/solution.view/index.html
index 1bf642b10..84ee26f19 100644
--- a/2-ui/1-document/07-modifying-document/10-clock-setinterval/solution.view/index.html
+++ b/2-ui/1-document/07-modifying-document/10-clock-setinterval/solution.view/index.html
@@ -43,15 +43,19 @@
     }
 
     function clockStart() {
-      timerId = setInterval(update, 1000);
+      // set a new interval only if the clock is stopped
+      // otherwise we would rewrite the timerID reference to the running interval and wouldn't be able to stop the clock ever again
+      if (!timerId) {
+        timerId = setInterval(update, 1000);
+      }
       update(); // <--  start right now, don't wait 1 second till the first setInterval works
     }
 
     function clockStop() {
       clearInterval(timerId);
+      timerId = null; // <-- clear timerID to indicate that the clock has been stopped, so that it is possible to start it again in clockStart()
     }
 
-    clockStart();
   </script>
 
   <!-- click on this button calls clockStart() -->
diff --git a/2-ui/1-document/07-modifying-document/5-why-aaa/solution.md b/2-ui/1-document/07-modifying-document/5-why-aaa/solution.md
index 6b85168b9..3d1f6698f 100644
--- a/2-ui/1-document/07-modifying-document/5-why-aaa/solution.md
+++ b/2-ui/1-document/07-modifying-document/5-why-aaa/solution.md
@@ -1,9 +1,9 @@
 The HTML in the task is incorrect. That's the reason of the odd thing.
 
-The browser has to fix it automatically. But there may be no text inside the `<table>`: according to the spec only table-specific tags are allowed. So the browser adds `"aaa"` *before* the `<table>`.
+The browser has to fix it automatically. But there may be no text inside the `<table>`: according to the spec only table-specific tags are allowed. So the browser shows `"aaa"` *before* the `<table>`.
 
 Now it's obvious that when we remove the table, it remains.
 
-The question can be easily answered by exploring the DOM using the browser tools. It shows `"aaa"` before the `<table>`.
+The question can be easily answered by exploring the DOM using the browser tools. You'll see `"aaa"` before the `<table>`.
 
 The HTML standard specifies in detail how to process bad HTML, and such behavior of the browser is correct.
diff --git a/2-ui/1-document/07-modifying-document/5-why-aaa/task.md b/2-ui/1-document/07-modifying-document/5-why-aaa/task.md
index f87074dba..861f70503 100644
--- a/2-ui/1-document/07-modifying-document/5-why-aaa/task.md
+++ b/2-ui/1-document/07-modifying-document/5-why-aaa/task.md
@@ -22,6 +22,6 @@ Why does that happen?
   alert(table); // the table, as it should be
 
   table.remove();
-  // why there's still aaa in the document?
+  // why there's still "aaa" in the document?
 </script>
 ```
diff --git a/2-ui/1-document/07-modifying-document/6-create-list/task.md b/2-ui/1-document/07-modifying-document/6-create-list/task.md
index 43b0a34a7..a57e7e2d9 100644
--- a/2-ui/1-document/07-modifying-document/6-create-list/task.md
+++ b/2-ui/1-document/07-modifying-document/6-create-list/task.md
@@ -10,7 +10,7 @@ For every list item:
 
 1. Ask a user about its content using `prompt`.
 2. Create the `<li>` with it and add it to `<ul>`.
-3. Continue until the user cancels the input (by pressing `key:Esc` or CANCEL in prompt).
+3. Continue until the user cancels the input (by pressing `key:Esc` or via an empty entry).
 
 All elements should be created dynamically.
 
diff --git a/2-ui/1-document/07-modifying-document/9-calendar-table/solution.md b/2-ui/1-document/07-modifying-document/9-calendar-table/solution.md
index 67bb5e13d..de8be56e9 100644
--- a/2-ui/1-document/07-modifying-document/9-calendar-table/solution.md
+++ b/2-ui/1-document/07-modifying-document/9-calendar-table/solution.md
@@ -3,7 +3,7 @@ We'll create the table as a string: `"<table>...</table>"`, and then assign it t
 The algorithm:
 
 1. Create the table header with `<th>` and weekday names.
-1. Create the date object `d = new Date(year, month-1)`. That's the first day of `month` (taking into account that months in JavaScript start from `0`, not `1`).
-2. First few cells till the first day of the month `d.getDay()` may be empty. Let's fill them in with `<td></td>`.
-3. Increase the day in `d`: `d.setDate(d.getDate()+1)`. If `d.getMonth()` is not yet the next month, then add the new cell `<td>` to the calendar. If that's a Sunday, then add a newline <code>"&lt;/tr&gt;&lt;tr&gt;"</code>.
-4. If the month has finished, but the table row is not yet full, add empty `<td>` into it, to make it square.
+2. Create the date object `d = new Date(year, month-1)`. That's the first day of `month` (taking into account that months in JavaScript start from `0`, not `1`).
+3. First few cells till the first day of the month `d.getDay()` may be empty. Let's fill them in with `<td></td>`.
+4. Increase the day in `d`: `d.setDate(d.getDate()+1)`. If `d.getMonth()` is not yet the next month, then add the new cell `<td>` to the calendar. If that's a Sunday, then add a newline <code>"&lt;/tr&gt;&lt;tr&gt;"</code>.
+5. If the month has finished, but the table row is not yet full, add empty `<td>` into it, to make it square.
diff --git a/2-ui/1-document/07-modifying-document/article.md b/2-ui/1-document/07-modifying-document/article.md
index c4796a1d4..75ce1fbb0 100644
--- a/2-ui/1-document/07-modifying-document/article.md
+++ b/2-ui/1-document/07-modifying-document/article.md
@@ -28,7 +28,7 @@ Here's how it will look:
 */!*
 ```
 
-That was an HTML example. Now let's create the same `div` with JavaScript (assuming that the styles are in the HTML or an external CSS file).
+That was the HTML example. Now let's create the same `div` with JavaScript (assuming that the styles are in the HTML/CSS already).
 
 ## Creating an element
 
@@ -48,21 +48,28 @@ To create DOM nodes, there are two methods:
     let textNode = document.createTextNode('Here I am');
     ```
 
+Most of the time we need to create element nodes, such as the `div` for the message.
+
 ### Creating the message
 
-In our case the message is a `div` with `alert` class and the HTML in it:
+Creating the message div takes 3 steps:
 
 ```js
+// 1. Create <div> element
 let div = document.createElement('div');
+
+// 2. Set its class to "alert"
 div.className = "alert";
+
+// 3. Fill it with the content
 div.innerHTML = "<strong>Hi there!</strong> You've read an important message.";
 ```
 
-We created the element, but as of now it's only in a variable. We can't see the element on the page, as it's not yet a part of the document.
+We've created the element. But as of now it's only in a variable named `div`, not in the page yet. So we can't see it.
 
 ## Insertion methods
 
-To make the `div` show up, we need to insert it somewhere into `document`. For instance, in `document.body`.
+To make the `div` show up, we need to insert it somewhere into `document`. For instance, into `<body>` element, referenced by `document.body`.
 
 There's a special method `append` for that: `document.body.append(div)`.
 
@@ -90,14 +97,20 @@ Here's the full code:
 </script>
 ```
 
-This set of methods provides more ways to insert:
+Here we called `append` on `document.body`, but we can call `append` method on any other element, to put another element into it. For instance, we can append something to `<div>` by calling `div.append(anotherElement)`.
 
-- `node.append(...nodes or strings)` -- append nodes or strings at the end of `node`,
-- `node.prepend(...nodes or strings)` -- insert nodes or strings at the beginning of `node`,
-- `node.before(...nodes or strings)` –- insert nodes or strings before `node`,
-- `node.after(...nodes or strings)` –- insert nodes or strings after `node`,
+Here are more insertion methods, they specify different places where to insert:
+
+- `node.append(...nodes or strings)` -- append nodes or strings *at the end* of `node`,
+- `node.prepend(...nodes or strings)` -- insert nodes or strings *at the beginning* of `node`,
+- `node.before(...nodes or strings)` –- insert nodes or strings *before* `node`,
+- `node.after(...nodes or strings)` –- insert nodes or strings *after* `node`,
 - `node.replaceWith(...nodes or strings)` –- replaces `node` with the given nodes or strings.
 
+Arguments of these methods are an arbitrary list of DOM nodes to insert, or text strings (that become text nodes automatically).
+
+Let's see them in action.
+
 Here's an example of using these methods to add items to a list and the text before/after it:
 
 ```html autorun
@@ -121,7 +134,7 @@ Here's an example of using these methods to add items to a list and the text bef
 </script>
 ```
 
-Here's a visual picture what methods do:
+Here's a visual picture of what the methods do:
 
 ![](before-prepend-append-after.svg)
 
@@ -139,7 +152,7 @@ before
 after
 ```
 
-These methods can insert multiple lists of nodes and text pieces in a single call.
+As said, these methods can insert multiple nodes and text pieces in a single call.
 
 For instance, here a string and an element are inserted:
 
@@ -150,7 +163,7 @@ For instance, here a string and an element are inserted:
 </script>
 ```
 
-All text is inserted *as text*.
+Please note: the text is inserted "as text", not "as HTML", with proper escaping of characters such as `<`, `>`.
 
 So the final HTML is:
 
@@ -166,7 +179,7 @@ In other words, strings are inserted in a safe way, like `elem.textContent` does
 
 So, these methods can only be used to insert DOM nodes or text pieces.
 
-But what if we want to insert HTML "as html", with all tags and stuff working, like `elem.innerHTML`?
+But what if we'd like to insert an HTML string "as html", with all tags and stuff working, in the same manner as `elem.innerHTML` does it?
 
 ## insertAdjacentHTML/Text/Element
 
diff --git a/2-ui/1-document/08-styles-and-classes/article.md b/2-ui/1-document/08-styles-and-classes/article.md
index 34d441ae5..46aaa3b00 100644
--- a/2-ui/1-document/08-styles-and-classes/article.md
+++ b/2-ui/1-document/08-styles-and-classes/article.md
@@ -128,6 +128,14 @@ setTimeout(() => document.body.style.display = "", 1000); // back to normal
 
 If we set `style.display` to an empty string, then the browser applies CSS classes and its built-in styles normally, as if there were no such `style.display` property at all.
 
+Also there is a special method for that, `elem.style.removeProperty('style property')`. So, We can remove a property like this:
+
+```js run
+document.body.style.background = 'red'; //set background to red
+
+setTimeout(() => document.body.style.removeProperty('background'), 1000); // remove background after 1 second
+```
+
 ````smart header="Full rewrite with `style.cssText`"
 Normally, we use `style.*` to assign individual style properties. We can't set the full style like `div.style="color: red; width: 100px"`, because `div.style` is an object, and it's read-only.
 
@@ -249,7 +257,7 @@ For instance:
 ```smart header="Computed and resolved values"
 There are two concepts in [CSS](https://drafts.csswg.org/cssom/#resolved-values):
 
-1. A *computed* style value is the value after all CSS rules and CSS inheritance is applied, as the  result of the CSS cascade. It can look like `height:1em` or `font-size:125%`.
+1. A *computed* style value is the value after all CSS rules and CSS inheritance is applied, as the result of the CSS cascade. It can look like `height:1em` or `font-size:125%`.
 2. A *resolved* style value is the one finally applied to the element. Values like `1em` or `125%` are relative. The browser takes the computed value and makes all units fixed and absolute, for instance: `height:20px` or `font-size:16px`. For geometry properties resolved values may have a floating point, like `width:50.5px`.
 
 A long time ago `getComputedStyle` was created to get computed values, but it turned out that resolved values are much more convenient, and the standard changed.
@@ -261,20 +269,6 @@ So nowadays `getComputedStyle` actually returns the resolved value of the proper
 We should always ask for the exact property that we want, like `paddingLeft` or `marginTop` or `borderTopWidth`. Otherwise the correct result is not guaranteed.
 
 For instance, if there are properties `paddingLeft/paddingTop`, then what should we get for `getComputedStyle(elem).padding`? Nothing, or maybe a "generated" value from known paddings? There's no standard rule here.
-
-There are other inconsistencies. As an example, some browsers (Chrome) show `10px` in the document below, and some of them (Firefox) --  do not:
-
-```html run
-<style>
-  body {
-    margin: 10px;
-  }
-</style>
-<script>
-  let style = getComputedStyle(document.body);
-  alert(style.margin); // empty string in Firefox
-</script>
-```
 ````
 
 ```smart header="Styles applied to `:visited` links are hidden!"
diff --git a/2-ui/1-document/09-size-and-scroll/4-put-ball-in-center/ball-half/index.html b/2-ui/1-document/09-size-and-scroll/4-put-ball-in-center/ball-half/index.html
index ca9c4d579..8f855ecfa 100755
--- a/2-ui/1-document/09-size-and-scroll/4-put-ball-in-center/ball-half/index.html
+++ b/2-ui/1-document/09-size-and-scroll/4-put-ball-in-center/ball-half/index.html
@@ -9,7 +9,7 @@
       background-color: #00FF00;
       position: relative;
     }
-    
+
     #ball {
       position: absolute;
     }
@@ -20,7 +20,7 @@
 
 
   <div id="field">
-    <img src="https://js.cx/clipart/ball.svg" id="ball"> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+    <img src="https://js.cx/clipart/ball.svg" height="40" width="40" id="ball"> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
     . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
   </div>
 
@@ -38,4 +38,4 @@
 
 </body>
 
-</html>
\ No newline at end of file
+</html>
diff --git a/2-ui/1-document/09-size-and-scroll/4-put-ball-in-center/solution.md b/2-ui/1-document/09-size-and-scroll/4-put-ball-in-center/solution.md
index c6fe6c3bb..afa1d8f50 100644
--- a/2-ui/1-document/09-size-and-scroll/4-put-ball-in-center/solution.md
+++ b/2-ui/1-document/09-size-and-scroll/4-put-ball-in-center/solution.md
@@ -24,17 +24,22 @@ ball.style.left = Math.round(field.clientWidth / 2 - ball.offsetWidth / 2) + 'px
 ball.style.top = Math.round(field.clientHeight / 2 - ball.offsetHeight / 2) + 'px';
 ```
 
-**Attention: the pitfall!**
+Now the ball is finally centered.
+
+````warn header="Attention: the pitfall!"
 
 The code won't work reliably while `<img>` has no width/height:
 
 ```html
 <img src="ball.png" id="ball">
 ```
+````
 
 When the browser does not know the width/height of an image (from tag attributes or CSS), then it assumes them to equal `0` until the image finishes loading.
 
-After the first load browser usually caches the image, and on next loads it will have the size immediately. But on the first load the value of `ball.offsetWidth` is `0`. That leads to wrong coordinates.
+So the value of `ball.offsetWidth` will be `0` until the image loads. That leads to wrong coordinates in the code above.
+
+After the first load, the browser usually caches the image, and on reloads it will have the size immediately. But on the first load the value of `ball.offsetWidth` is `0`.
 
 We should fix that by adding `width/height` to `<img>`:
 
diff --git a/2-ui/1-document/09-size-and-scroll/4-put-ball-in-center/solution.view/index.html b/2-ui/1-document/09-size-and-scroll/4-put-ball-in-center/solution.view/index.html
index 9ebe6001e..9f21e5421 100755
--- a/2-ui/1-document/09-size-and-scroll/4-put-ball-in-center/solution.view/index.html
+++ b/2-ui/1-document/09-size-and-scroll/4-put-ball-in-center/solution.view/index.html
@@ -26,7 +26,7 @@
 
 
   <script>
-    // ball.offsetWidth=0 before image loaded! 
+    // ball.offsetWidth=0 before image loaded!
     // to fix: set width
     ball.style.left = Math.round(field.clientWidth / 2 - ball.offsetWidth / 2) + 'px'
     ball.style.top = Math.round(field.clientHeight / 2 - ball.offsetHeight / 2) + 'px'
diff --git a/2-ui/1-document/09-size-and-scroll/4-put-ball-in-center/task.md b/2-ui/1-document/09-size-and-scroll/4-put-ball-in-center/task.md
index 57746d921..f56e0858b 100644
--- a/2-ui/1-document/09-size-and-scroll/4-put-ball-in-center/task.md
+++ b/2-ui/1-document/09-size-and-scroll/4-put-ball-in-center/task.md
@@ -10,7 +10,7 @@ Here's how the source document looks:
 
 What are coordinates of the field center?
 
-Calculate them and use to place the ball into the center of the field:
+Calculate them and use to place the ball into the center of the green field:
 
 [iframe src="solution" height=180]
 
diff --git a/2-ui/1-document/09-size-and-scroll/article.md b/2-ui/1-document/09-size-and-scroll/article.md
index 024e9a4d9..66f28115f 100644
--- a/2-ui/1-document/09-size-and-scroll/article.md
+++ b/2-ui/1-document/09-size-and-scroll/article.md
@@ -17,8 +17,8 @@ As a sample element to demonstrate properties we'll use the one given below:
     width: 300px;
     height: 200px;
     border: 25px solid #E8C48F;
-    padding: 20px;              
-    overflow: auto;             
+    padding: 20px;
+    overflow: auto;
   }
 </style>
 ```
@@ -106,7 +106,7 @@ Geometry properties are calculated only for displayed elements.
 
 If an element (or any of its ancestors) has `display:none` or is not in the document, then all geometry properties are zero (or `null` for `offsetParent`).
 
-For example, `offsetParent` is `null`, and `offsetWidth`, `offsetHeight` are `0` when we created an element, but haven't inserted it into the document yet, or it (or it's ancestor) has `display:none`.
+For example, `offsetParent` is `null`, and `offsetWidth`, `offsetHeight` are `0` when we created an element, but haven't inserted it into the document yet, or it (or its ancestor) has `display:none`.
 
 We can use this to check if an element is hidden, like this:
 
@@ -116,7 +116,7 @@ function isHidden(elem) {
 }
 ```
 
-Please note that such `isHidden` returns `true` for elements that are on-screen, but have zero sizes (like an empty `<div>`).
+Please note that such `isHidden` returns `true` for elements that are on-screen, but have zero sizes.
 ````
 
 ## clientTop/Left
@@ -211,7 +211,7 @@ If you click the element below, the code `elem.scrollTop += 10` executes. That m
 <div onclick="this.scrollTop+=10" style="cursor:pointer;border:1px solid black;width:100px;height:80px;overflow:auto">Click<br>Me<br>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9</div>
 ```
 
-Setting `scrollTop` to `0` or `Infinity` will make the element scroll to the very top/bottom respectively.
+Setting `scrollTop` to `0` or a big value, such as `1e9` will make the element scroll to the very top/bottom respectively.
 ````
 
 ## Don't take width/height from CSS
diff --git a/2-ui/1-document/10-size-and-scroll-window/article.md b/2-ui/1-document/10-size-and-scroll-window/article.md
index 10898dbf7..08a2f6576 100644
--- a/2-ui/1-document/10-size-and-scroll-window/article.md
+++ b/2-ui/1-document/10-size-and-scroll-window/article.md
@@ -2,11 +2,11 @@
 
 How do we find the width and height of the browser window? How do we get the full width and height of the document, including the scrolled out part? How do we scroll the page using JavaScript?
 
-For most such requests, we can use the root document element `document.documentElement`, that corresponds to the `<html>` tag. But there are additional methods and peculiarities important enough to consider.
+For this type of information, we can use the root document element `document.documentElement`, that corresponds to the `<html>` tag. But there are additional methods and peculiarities to consider.
 
 ## Width/height of the window
 
-To get window width and height we can use `clientWidth/clientHeight` of `document.documentElement`:
+To get window width and height, we can use the `clientWidth/clientHeight` of `document.documentElement`:
 
 ![](document-client-width-height.svg)
 
@@ -16,12 +16,12 @@ For instance, this button shows the height of your window:
 <button onclick="alert(document.documentElement.clientHeight)">alert(document.documentElement.clientHeight)</button>
 ```
 
-````warn header="Not `window.innerWidth/Height`"
-Browsers also support properties `window.innerWidth/innerHeight`. They look like what we want. So why not to use them instead?
+````warn header="Not `window.innerWidth/innerHeight`"
+Browsers also support properties like `window.innerWidth/innerHeight`. They look like what we want, so why not to use them instead?
 
-If there exists a scrollbar, and it occupies some space, `clientWidth/clientHeight` provide the width/height without it (subtract it). In other words, they return width/height of the visible part of the document, available for the content.
+If there exists a scrollbar, and it occupies some space, `clientWidth/clientHeight` provide the width/height without it (subtract it). In other words, they return the width/height of the visible part of the document, available for the content.
 
-...And `window.innerWidth/innerHeight` include the scrollbar.
+`window.innerWidth/innerHeight` includes the scrollbar.
 
 If there's a scrollbar, and it occupies some space, then these two lines show different values:
 ```js run
@@ -29,7 +29,7 @@ alert( window.innerWidth ); // full window width
 alert( document.documentElement.clientWidth ); // window width minus the scrollbar
 ```
 
-In most cases we need the *available* window width: to draw or position something. That is: inside scrollbars if there are any. So we should use `documentElement.clientHeight/Width`.
+In most cases, we need the *available* window width in order to draw or position something within scrollbars (if there are any), so we should use `documentElement.clientHeight/clientWidth`.
 ````
 
 ```warn header="`DOCTYPE` is important"
@@ -40,9 +40,9 @@ In modern HTML we should always write `DOCTYPE`.
 
 ## Width/height of the document
 
-Theoretically, as the root document element is `document.documentElement`, and it encloses all the content, we could measure document full size as `document.documentElement.scrollWidth/scrollHeight`.
+Theoretically, as the root document element is `document.documentElement`, and it encloses all the content, we could measure the document's full size as `document.documentElement.scrollWidth/scrollHeight`.
 
-But on that element, for the whole page, these properties do not work as intended. In Chrome/Safari/Opera if there's no scroll, then `documentElement.scrollHeight` may be even less than  `documentElement.clientHeight`! Sounds like a nonsense, weird, right?
+But on that element, for the whole page, these properties do not work as intended. In Chrome/Safari/Opera, if there's no scroll, then `documentElement.scrollHeight` may be even less than `documentElement.clientHeight`! Weird, right?
 
 To reliably obtain the full document height, we should take the maximum of these properties:
 
@@ -60,11 +60,11 @@ Why so? Better don't ask. These inconsistencies come from ancient times, not a "
 
 ## Get the current scroll [#page-scroll]
 
-DOM elements have their current scroll state in `elem.scrollLeft/scrollTop`.
+DOM elements have their current scroll state in their `scrollLeft/scrollTop` properties.
 
-For document scroll `document.documentElement.scrollLeft/Top` works in most browsers, except older WebKit-based ones, like Safari (bug [5991](https://bugs.webkit.org/show_bug.cgi?id=5991)), where we should use `document.body` instead of `document.documentElement`.
+For document scroll, `document.documentElement.scrollLeft/scrollTop` works in most browsers, except older WebKit-based ones, like Safari (bug [5991](https://bugs.webkit.org/show_bug.cgi?id=5991)), where we should use `document.body` instead of `document.documentElement`.
 
-Luckily, we don't have to remember these peculiarities at all, because the scroll is available in the special properties `window.pageXOffset/pageYOffset`:
+Luckily, we don't have to remember these peculiarities at all, because the scroll is available in the special properties, `window.pageXOffset/pageYOffset`:
 
 ```js run
 alert('Current scroll from the top: ' + window.pageYOffset);
@@ -73,19 +73,25 @@ alert('Current scroll from the left: ' + window.pageXOffset);
 
 These properties are read-only.
 
+```smart header="Also available as `window` properties `scrollX` and `scrollY`"
+For historical reasons, both properties exist, but they are the same:
+- `window.pageXOffset` is an alias of `window.scrollX`.
+- `window.pageYOffset` is an alias of `window.scrollY`.
+```
+
 ## Scrolling: scrollTo, scrollBy, scrollIntoView [#window-scroll]
 
 ```warn
-To scroll the page from JavaScript, its DOM must be fully built.
+To scroll the page with JavaScript, its DOM must be fully built.
 
-For instance, if we try to scroll the page from the script in `<head>`, it won't work.
+For instance, if we try to scroll the page with a script in `<head>`, it won't work.
 ```
 
 Regular elements can be scrolled by changing `scrollTop/scrollLeft`.
 
-We can do the same for the page using `document.documentElement.scrollTop/Left` (except Safari, where `document.body.scrollTop/Left` should be used instead).
+We can do the same for the page using `document.documentElement.scrollTop/scrollLeft` (except Safari, where `document.body.scrollTop/Left` should be used instead).
 
-Alternatively, there's a simpler, universal solution: special methods  [window.scrollBy(x,y)](mdn:api/Window/scrollBy) and [window.scrollTo(pageX,pageY)](mdn:api/Window/scrollTo).
+Alternatively, there's a simpler, universal solution: special methods [window.scrollBy(x,y)](mdn:api/Window/scrollBy) and [window.scrollTo(pageX,pageY)](mdn:api/Window/scrollTo).
 
 - The method `scrollBy(x,y)` scrolls the page *relative to its current position*. For instance, `scrollBy(0,10)` scrolls the page `10px` down.
 
@@ -106,28 +112,28 @@ These methods work for all browsers the same way.
 
 ## scrollIntoView
 
-For completeness, let's cover one more method:  [elem.scrollIntoView(top)](mdn:api/Element/scrollIntoView).
+For completeness, let's cover one more method: [elem.scrollIntoView(top)](mdn:api/Element/scrollIntoView).
 
 The call to `elem.scrollIntoView(top)` scrolls the page to make `elem` visible. It has one argument:
 
-- if `top=true` (that's the default), then the page will be scrolled to make `elem` appear on the top of the window. The upper edge of the element is aligned with the window top.
-- if `top=false`, then the page scrolls to make `elem` appear at the bottom. The bottom edge of the element is aligned with the window bottom.
+- If `top=true` (that's the default), then the page will be scrolled to make `elem` appear on the top of the window. The upper edge of the element will be aligned with the window top.
+- If `top=false`, then the page scrolls to make `elem` appear at the bottom. The bottom edge of the element will be aligned with the window bottom.
 
 ```online
-The button below scrolls the page to make itself show at the window top:
+The button below scrolls the page to position itself at the window top:
 
 <button onclick="this.scrollIntoView()">this.scrollIntoView()</button>
 
-And this button scrolls the page to show it at the bottom:
+And this button scrolls the page to position itself at the bottom:
 
 <button onclick="this.scrollIntoView(false)">this.scrollIntoView(false)</button>
 ```
 
 ## Forbid the scrolling
 
-Sometimes we need to make the document "unscrollable". For instance, when we need to cover it with a large message requiring immediate attention, and we want the visitor to interact with that message, not with the document.
+Sometimes we need to make the document "unscrollable". For instance, when we need to cover the page with a large message requiring immediate attention, and we want the visitor to interact with that message, not with the document.
 
-To make the document unscrollable, it's enough to set `document.body.style.overflow = "hidden"`. The page will freeze on its current scroll.
+To make the document unscrollable, it's enough to set `document.body.style.overflow = "hidden"`. The page will "freeze" at its current scroll position.
 
 ```online
 Try it:
@@ -136,20 +142,20 @@ Try it:
 
 <button onclick="document.body.style.overflow = ''">document.body.style.overflow = ''</button>
 
-The first button freezes the scroll, the second one resumes it.
+The first button freezes the scroll, while the second one releases it.
 ```
 
-We can use the same technique to "freeze" the scroll for other elements, not just for `document.body`.
+We can use the same technique to freeze the scroll for other elements, not just for `document.body`.
 
-The drawback of the method is that the scrollbar disappears. If it occupied some space, then that space is now free, and the content "jumps" to fill it.
+The drawback of the method is that the scrollbar disappears. If it occupied some space, then that space is now free and the content "jumps" to fill it.
 
-That looks a bit odd, but can be worked around if we compare `clientWidth` before and after the freeze, and if it increased (the scrollbar disappeared) then add `padding` to `document.body` in place of the scrollbar, to keep the content width the same.
+That looks a bit odd, but can be worked around if we compare `clientWidth` before and after the freeze. If it increased (the scrollbar disappeared), then add `padding` to `document.body` in place of the scrollbar to keep the content width the same.
 
 ## Summary
 
 Geometry:
 
-- Width/height of the visible part of the document (content area width/height): `document.documentElement.clientWidth/Height`
+- Width/height of the visible part of the document (content area width/height): `document.documentElement.clientWidth/clientHeight`
 - Width/height of the whole document, with the scrolled out part:
 
     ```js
diff --git a/2-ui/1-document/11-coordinates/1-find-point-coordinates/solution.md b/2-ui/1-document/11-coordinates/1-find-point-coordinates/solution.md
index f3547096f..4101d4915 100644
--- a/2-ui/1-document/11-coordinates/1-find-point-coordinates/solution.md
+++ b/2-ui/1-document/11-coordinates/1-find-point-coordinates/solution.md
@@ -1,6 +1,6 @@
 # Outer corners
 
-Outer corners are basically what we get from  [elem.getBoundingClientRect()](https://developer.mozilla.org/en-US/docs/DOM/element.getBoundingClientRect).
+Outer corners are basically what we get from [elem.getBoundingClientRect()](https://developer.mozilla.org/en-US/docs/DOM/element.getBoundingClientRect).
 
 Coordinates of the upper-left corner `answer1` and the bottom-right corner `answer2`:
 
diff --git a/2-ui/1-document/11-coordinates/article.md b/2-ui/1-document/11-coordinates/article.md
index 18d56cd27..fc605c414 100644
--- a/2-ui/1-document/11-coordinates/article.md
+++ b/2-ui/1-document/11-coordinates/article.md
@@ -36,7 +36,7 @@ Additionally, there are derived properties:
 ```online
 For instance click this button to see its window coordinates:
 
-<p><input id="brTest" type="button" value="Get coordinates using button.getBoundingClientRect() for this button" onclick='showRect(this)'/></p>
+<p><input id="brTest" type="button" style="max-width: 90vw;" value="Get coordinates using button.getBoundingClientRect() for this button" onclick='showRect(this)'/></p>
 
 <script>
 function showRect(elem) {
@@ -88,10 +88,10 @@ As you can see, `left/top` do not equal `x/y` in such case.
 In practice though, `elem.getBoundingClientRect()` always returns positive width/height, here we mention negative `width/height` only for you to understand why these seemingly duplicate properties are not actually duplicates.
 ```
 
-```warn header="Internet Explorer and Edge: no support for `x/y`"
-Internet Explorer and Edge don't support `x/y` properties for historical reasons.
+```warn header="Internet Explorer: no support for `x/y`"
+Internet Explorer doesn't support `x/y` properties for historical reasons.
 
-So we can either make a polywill (add getters in `DomRect.prototype`) or just use `top/left`, as they are always the same as `x/y` for positive `width/height`, in particular in the result of `elem.getBoundingClientRect()`.
+So we can either make a polyfill (add getters in `DomRect.prototype`) or just use `top/left`, as they are always the same as `x/y` for positive `width/height`, in particular in the result of `elem.getBoundingClientRect()`.
 ```
 
 ```warn header="Coordinates right/bottom are different from CSS position properties"
@@ -216,6 +216,8 @@ function getCoords(elem) {
 
   return {
     top: box.top + window.pageYOffset,
+    right: box.right + window.pageXOffset,
+    bottom: box.bottom + window.pageYOffset,
     left: box.left + window.pageXOffset
   };
 }
diff --git a/2-ui/2-events/01-introduction-browser-events/07-carousel/solution.view/index.html b/2-ui/2-events/01-introduction-browser-events/07-carousel/solution.view/index.html
index 2c6073316..baf867664 100644
--- a/2-ui/2-events/01-introduction-browser-events/07-carousel/solution.view/index.html
+++ b/2-ui/2-events/01-introduction-browser-events/07-carousel/solution.view/index.html
@@ -10,7 +10,7 @@
   <div id="carousel" class="carousel">
     <button class="arrow prev">⇦</button>
     <div class="gallery">
-      <ul class="images">
+      <ul>
         <li><img src="https://en.js.cx/carousel/1.png"></li>
         <li><img src="https://en.js.cx/carousel/2.png"></li>
         <li><img src="https://en.js.cx/carousel/3.png"></li>
diff --git a/2-ui/2-events/01-introduction-browser-events/article.md b/2-ui/2-events/01-introduction-browser-events/article.md
index 7f160154e..4eca222aa 100644
--- a/2-ui/2-events/01-introduction-browser-events/article.md
+++ b/2-ui/2-events/01-introduction-browser-events/article.md
@@ -11,20 +11,20 @@ Here's a list of the most useful DOM events, just to take a look at:
 - `mousedown` / `mouseup` -- when the mouse button is pressed / released over an element.
 - `mousemove` -- when the mouse is moved.
 
+**Keyboard events:**
+- `keydown` and `keyup` -- when a keyboard key is pressed and released.
+
 **Form element events:**
 - `submit` -- when the visitor submits a `<form>`.
 - `focus` --  when the visitor focuses on an element, e.g. on an `<input>`.
 
-**Keyboard events:**
-- `keydown` and `keyup` -- when the visitor presses and then releases the button.
-
 **Document events:**
 - `DOMContentLoaded` -- when the HTML is loaded and processed, DOM is fully built.
 
 **CSS events:**
 - `transitionend` -- when a CSS-animation finishes.
 
-There are many other events. We'll get into more details of particular events in next chapters.
+There are many other events. We'll get into more details of particular events in upcoming chapters.
 
 ## Event handlers
 
@@ -87,8 +87,6 @@ If the handler is assigned using an HTML-attribute then the browser reads it, cr
 
 So this way is actually the same as the previous one.
 
-**The handler is always in the DOM property: the HTML-attribute is just one of the ways to initialize it.**
-
 These two code pieces work the same:
 
 1. Only HTML:
@@ -109,6 +107,8 @@ These two code pieces work the same:
     </script>
     ```
 
+In the first example, the HTML attribute is used to initialize the `button.onclick`, while in the second example -- the script, that's all the difference.
+
 **As there's only one `onclick` property, we can't assign more than one event handler.**
 
 In the example below adding a handler with JavaScript overwrites the existing handler:
@@ -124,16 +124,6 @@ In the example below adding a handler with JavaScript overwrites the existing ha
 </script>
 ```
 
-By the way, we can assign an existing function as a handler directly:
-
-```js
-function sayThanks() {
-  alert('Thanks!');
-}
-
-elem.onclick = sayThanks;
-```
-
 To remove a handler -- assign `elem.onclick = null`.
 
 ## Accessing the element: this
@@ -150,7 +140,17 @@ In the code below `button` shows its contents using `this.innerHTML`:
 
 If you're starting to work with events -- please note some subtleties.
 
-**The function should be assigned as `sayThanks`, not `sayThanks()`.**
+We can set an existing function as a handler:
+
+```js
+function sayThanks() {
+  alert('Thanks!');
+}
+
+elem.onclick = sayThanks;
+```
+
+But be careful: the function should be assigned as `sayThanks`, not `sayThanks()`.
 
 ```js
 // right
@@ -160,7 +160,7 @@ button.onclick = sayThanks;
 button.onclick = sayThanks();
 ```
 
-If we add parentheses, `sayThanks()` --  is a function call. So the last line actually takes the *result* of the function execution, that is `undefined` (as the function returns nothing), and assigns it to `onclick`. That doesn't work.
+If we add parentheses, then `sayThanks()` becomes a function call. So the last line actually takes the *result* of the function execution, that is `undefined` (as the function returns nothing), and assigns it to `onclick`. That doesn't work.
 
 ...On the other hand, in the markup we do need the parentheses:
 
@@ -168,21 +168,17 @@ If we add parentheses, `sayThanks()` --  is a function call. So the last line ac
 <input type="button" id="button" onclick="sayThanks()">
 ```
 
-The difference is easy to explain. When the browser reads the attribute, it creates a handler function with *body from its content*: `sayThanks()`.
+The difference is easy to explain. When the browser reads the attribute, it creates a handler function with body from the attribute content.
 
 So the markup generates this property:
 ```js
 button.onclick = function() {
 *!*
-  sayThanks(); // the attribute content
+  sayThanks(); // <-- the attribute content goes here
 */!*
 };
 ```
 
-**Use functions, not strings.**
-
-The assignment `elem.onclick = "alert(1)"` would work too. It works for compatibility reasons, but is strongly not recommended.
-
 **Don't use `setAttribute` for handlers.**
 
 Such a call won't work:
@@ -199,9 +195,9 @@ Assign a handler to `elem.onclick`, not `elem.ONCLICK`, because DOM properties a
 
 ## addEventListener
 
-The fundamental problem of the aforementioned ways to assign handlers -- we can't assign multiple handlers to one event.
+The fundamental problem of the aforementioned ways to assign handlers is that we *can't assign multiple handlers to one event*.
 
-For instance, one part of our code wants to highlight a button on click, and another one wants to show a message.
+Let's say, one part of our code wants to highlight a button on click, and another one wants to show a message on the same click.
 
 We'd like to assign two event handlers for that. But a new DOM property will overwrite the existing one:
 
@@ -211,12 +207,12 @@ input.onclick = function() { alert(1); }
 input.onclick = function() { alert(2); } // replaces the previous handler
 ```
 
-Web-standard developers understood that long ago and suggested an alternative way of managing handlers using special methods `addEventListener` and `removeEventListener`. They are free of such a problem.
+Developers of web standards understood that long ago and suggested an alternative way of managing handlers using the special methods `addEventListener` and `removeEventListener` which aren't bound by such constraint.
 
 The syntax to add a handler:
 
 ```js
-element.addEventListener(event, handler[, options]);
+element.addEventListener(event, handler, [options]);
 ```
 
 `event`
@@ -229,19 +225,18 @@ element.addEventListener(event, handler[, options]);
 : An additional optional object with properties:
     - `once`: if `true`, then the listener is automatically removed after it triggers.
     - `capture`: the phase where to handle the event, to be covered later in the chapter <info:bubbling-and-capturing>. For historical reasons, `options` can also be `false/true`, that's the same as `{capture: false/true}`.
-    - `passive`: if `true`, then the handler will not `preventDefault()`, we'll cover that later in <info:default-browser-action>.
-
+    - `passive`: if `true`, then the handler will not call `preventDefault()`, we'll explain that later in <info:default-browser-action>.
 
 To remove the handler, use `removeEventListener`:
 
 ```js
-element.removeEventListener(event, handler[, options]);
+element.removeEventListener(event, handler, [options]);
 ```
 
 ````warn header="Removal requires the same function"
 To remove a handler we should pass exactly the same function as was assigned.
 
-That doesn't work:
+This doesn't work:
 
 ```js no-beautify
 elem.addEventListener( "click" , () => alert('Thanks!'));
@@ -249,7 +244,7 @@ elem.addEventListener( "click" , () => alert('Thanks!'));
 elem.removeEventListener( "click", () => alert('Thanks!'));
 ```
 
-The handler won't be removed, because `removeEventListener` gets another function -- with the same code, but that doesn't matter.
+The handler won't be removed, because `removeEventListener` gets another function -- with the same code, but that doesn't matter, as it's a different function object.
 
 Here's the right way:
 
@@ -266,7 +261,7 @@ input.removeEventListener("click", handler);
 Please note -- if we don't store the function in a variable, then we can't remove it. There's no way to "read back" handlers assigned by `addEventListener`.
 ````
 
-Multiple calls to `addEventListener` allow to add multiple handlers, like this:
+Multiple calls to `addEventListener` allow it to add multiple handlers, like this:
 
 ```html run no-beautify
 <input id="elem" type="button" value="Click me"/>
@@ -291,47 +286,33 @@ Multiple calls to `addEventListener` allow to add multiple handlers, like this:
 As we can see in the example above, we can set handlers *both* using a DOM-property and `addEventListener`. But generally we use only one of these ways.
 
 ````warn header="For some events, handlers only work with `addEventListener`"
-There exist events that can't be assigned via a DOM-property. Must use `addEventListener`.
-
-For instance, the event `transitionend` (CSS animation finished) is like that.
-
-Try the code below. In most browsers only the second handler works, not the first one.
+There exist events that can't be assigned via a DOM-property. Only with `addEventListener`.
 
-```html run
-<style>
-  input {
-    transition: width 1s;
-    width: 100px;
-  }
-
-  .wide {
-    width: 300px;
-  }
-</style>
-
-<input type="button" id="elem" onclick="this.classList.toggle('wide')" value="Click me">
+For instance, the `DOMContentLoaded` event, that triggers when the document is loaded and the DOM has been built.
 
-<script>
-  elem.ontransitionend = function() {
-    alert("DOM property"); // doesn't work
-  };
+```js
+// will never run
+document.onDOMContentLoaded = function() {
+  alert("DOM built");
+};
+```
 
-*!*
-  elem.addEventListener("transitionend", function() {
-    alert("addEventListener"); // shows up when the animation finishes
-  });
-*/!*
-</script>
+```js
+// this way it works
+document.addEventListener("DOMContentLoaded", function() {
+  alert("DOM built");
+});
 ```
+So `addEventListener` is more universal. Although, such events are an exception rather than the rule.
 ````
 
 ## Event object
 
-To properly handle an event we'd want to know more about what's happened. Not just a "click" or a "keypress", but what were the pointer coordinates? Which key was pressed? And so on.
+To properly handle an event we'd want to know more about what's happened. Not just a "click" or a "keydown", but what were the pointer coordinates? Which key was pressed? And so on.
 
 When an event happens, the browser creates an *event object*, puts details into it and passes it as an argument to the handler.
 
-Here's an example of getting mouse coordinates from the event object:
+Here's an example of getting pointer coordinates from the event object:
 
 ```html run
 <input type="button" value="Click me" id="elem">
@@ -353,12 +334,12 @@ Some properties of `event` object:
 `event.currentTarget`
 : Element that handled the event. That's exactly the same as `this`, unless the handler is an arrow function, or its `this` is bound to something else, then we can get the element from  `event.currentTarget`.
 
-`event.clientX / event.clientY`
-: Window-relative coordinates of the cursor, for mouse events.
+`event.clientX` / `event.clientY`
+: Window-relative coordinates of the cursor, for pointer events.
 
-There are more properties. They depend on the event type, so we'll study them later when we come to different events in details.
+There are more properties. Many of them depend on the event type: keyboard events have one set of properties, pointer events - another one, we'll study them later when as we move on to the details of different events.
 
-````smart header="The event object is also accessible from HTML"
+````smart header="The event object is also available in HTML handlers"
 If we assign a handler in HTML, we can also use the `event` object, like this:
 
 ```html autorun height=60
@@ -380,17 +361,19 @@ For instance:
 <button id="elem">Click me</button>
 
 <script>
-  elem.addEventListener('click', {
+  let obj = {
     handleEvent(event) {
       alert(event.type + " at " + event.currentTarget);
     }
-  });
+  };
+
+  elem.addEventListener('click', obj);
 </script>
 ```
 
-As we can see, when `addEventListener` receives an object as the handler, it calls `object.handleEvent(event)` in case of an event.
+As we can see, when `addEventListener` receives an object as the handler, it calls `obj.handleEvent(event)` in case of an event.
 
-We could also use a class for that:
+We could also use objects of a custom class, like this:
 
 
 ```html run
@@ -412,6 +395,7 @@ We could also use a class for that:
 
 *!*
   let menu = new Menu();
+
   elem.addEventListener('mousedown', menu);
   elem.addEventListener('mouseup', menu);
 */!*
@@ -462,7 +446,7 @@ HTML attributes are used sparingly, because JavaScript in the middle of an HTML
 
 DOM properties are ok to use, but we can't assign more than one handler of the particular event. In many cases that limitation is not pressing.
 
-The last way is the most flexible, but it is also the longest to write. There are few events that only work with it, for instance `transtionend` and `DOMContentLoaded` (to be covered). Also `addEventListener` supports objects as event handlers. In that case the method `handleEvent` is called in case of the event.
+The last way is the most flexible, but it is also the longest to write. There are few events that only work with it, for instance `transitionend` and `DOMContentLoaded` (to be covered). Also `addEventListener` supports objects as event handlers. In that case the method `handleEvent` is called in case of the event.
 
 No matter how you assign the handler -- it gets an event object as the first argument. That object contains the details about what's happened.
 
diff --git a/2-ui/2-events/02-bubbling-and-capturing/article.md b/2-ui/2-events/02-bubbling-and-capturing/article.md
index 1ac989c79..2448cfa5b 100644
--- a/2-ui/2-events/02-bubbling-and-capturing/article.md
+++ b/2-ui/2-events/02-bubbling-and-capturing/article.md
@@ -120,26 +120,27 @@ There's usually no real need to prevent the bubbling. A task that seemingly requ
 
 There's another phase of event processing called "capturing". It is rarely used in real code, but sometimes can be useful.
 
-The standard [DOM Events](http://www.w3.org/TR/DOM-Level-3-Events/) describes 3 phases of event propagation:
+The standard [DOM Events](https://www.w3.org/TR/DOM-Level-3-Events/) describes 3 phases of event propagation:
 
 1. Capturing phase -- the event goes down to the element.
 2. Target phase -- the event reached the target element.
 3. Bubbling phase -- the event bubbles up from the element.
 
-Here's the picture of a click on `<td>` inside a table, taken from the specification:
+Here's the picture, taken from the specification, of the capturing `(1)`, target `(2)` and bubbling `(3)` phases for a click event on a `<td>` inside a table:
 
 ![](eventflow.svg)
 
 That is: for a click on `<td>` the event first goes through the ancestors chain down to the element (capturing phase), then it reaches the target and triggers there (target phase), and then it goes up (bubbling phase), calling handlers on its way.
 
-**Before we only talked about bubbling, because the capturing phase is rarely used. Normally it is invisible to us.**
+Until now, we only talked about bubbling, because the capturing phase is rarely used.
 
-Handlers added using `on<event>`-property or using HTML attributes or using two-argument `addEventListener(event, handler)` don't know anything about capturing, they only run on the 2nd and 3rd phases.
+In fact, the capturing phase was invisible for us, because handlers added using `on<event>`-property or using HTML attributes or using two-argument `addEventListener(event, handler)` don't know anything about capturing, they only run on the 2nd and 3rd phases.
 
 To catch an event on the capturing phase, we need to set the handler `capture` option to `true`:
 
 ```js
 elem.addEventListener(..., {capture: true})
+
 // or, just "true" is an alias to {capture: true}
 elem.addEventListener(..., true)
 ```
@@ -180,9 +181,10 @@ The code sets click handlers on *every* element in the document to see which one
 
 If you click on `<p>`, then the sequence is:
 
-1. `HTML` -> `BODY` -> `FORM` -> `DIV` (capturing phase, the first listener):
-2. `P` (target phrase, triggers two times, as we've set two listeners: capturing and bubbling)
-3. `DIV` -> `FORM` -> `BODY` -> `HTML` (bubbling phase, the second listener).
+1. `HTML` -> `BODY` -> `FORM` -> `DIV -> P` (capturing phase, the first listener):
+2. `P` -> `DIV` -> `FORM` -> `BODY` -> `HTML` (bubbling phase, the second listener).
+
+Please note, the `P` shows up twice, because we've set two listeners: capturing and bubbling. The target triggers at the end of the first and at the beginning of the second phase.
 
 There's a property `event.eventPhase` that tells us the number of the phase on which the event was caught. But it's rarely used, because we usually know it in the handler.
 
@@ -190,7 +192,7 @@ There's a property `event.eventPhase` that tells us the number of the phase on w
 If we `addEventListener(..., true)`, then we should mention the same phase in `removeEventListener(..., true)` to correctly remove the handler.
 ```
 
-````smart header="Listeners on same element and same phase run in their set order"
+````smart header="Listeners on the same element and same phase run in their set order"
 If we have multiple event handlers on the same phase, assigned to the same element with `addEventListener`, they run in the same order as they are created:
 
 ```js
@@ -199,14 +201,20 @@ elem.addEventListener("click", e => alert(2));
 ```
 ````
 
+```smart header="The `event.stopPropagation()` during the capturing also prevents the bubbling"
+The `event.stopPropagation()` method and its sibling `event.stopImmediatePropagation()` can also be called on the capturing phase. Then not only the futher capturing is stopped, but the bubbling as well.
+
+In other words, normally the event goes first down ("capturing") and then up ("bubbling"). But if `event.stopPropagation()` is called during the capturing phase, then the event travel stops, no bubbling will occur.
+```
+
 
 ## Summary
 
 When an event happens -- the most nested element where it happens gets labeled as the "target element" (`event.target`).
 
-- Then the event moves down from the document root to `event.target`, calling handlers assigned with `addEventListener(...., true)` on the way (`true` is a shorthand for `{capture: true}`).
+- Then the event moves down from the document root to `event.target`, calling handlers assigned with `addEventListener(..., true)` on the way (`true` is a shorthand for `{capture: true}`).
 - Then handlers are called on the target element itself.
-- Then the event bubbles up from `event.target` up to the root, calling handlers assigned using `on<event>` and `addEventListener` without the 3rd argument or with the 3rd argument `false/{capture:false}`.
+- Then the event bubbles up from `event.target` to the root, calling handlers assigned using `on<event>`, HTML attributes and `addEventListener` without the 3rd argument or with the 3rd argument `false/{capture:false}`.
 
 Each handler can access `event` object properties:
 
@@ -216,10 +224,10 @@ Each handler can access `event` object properties:
 
 Any event handler can stop the event by calling `event.stopPropagation()`, but that's not recommended, because we can't really be sure we won't need it above, maybe for completely different things.
 
-The capturing phase is used very rarely, usually we handle events on bubbling. And there's a logic behind that.
+The capturing phase is used very rarely, usually we handle events on bubbling. And there's a logical explanation for that.
 
 In real world, when an accident happens, local authorities react first. They know best the area where it happened. Then higher-level authorities if needed.
 
-The same for event handlers. The code that set the handler on a particular element knows maximum  details about the element and what it does. A handler on a particular `<td>` may be suited for that exactly `<td>`, it knows everything about it, so it should get the chance first. Then its immediate parent also knows about the context, but a little bit less, and so on till the very top element that handles general concepts and runs the last.
+The same for event handlers. The code that set the handler on a particular element knows maximum details about the element and what it does. A handler on a particular `<td>` may be suited for that exactly `<td>`, it knows everything about it, so it should get the chance first. Then its immediate parent also knows about the context, but a little bit less, and so on till the very top element that handles general concepts and runs the last one.
 
 Bubbling and capturing lay the foundation for "event delegation" -- an extremely powerful event handling pattern that we study in the next chapter.
diff --git a/2-ui/2-events/03-event-delegation/article.md b/2-ui/2-events/03-event-delegation/article.md
index 3d8beda0f..881183740 100644
--- a/2-ui/2-events/03-event-delegation/article.md
+++ b/2-ui/2-events/03-event-delegation/article.md
@@ -1,11 +1,11 @@
 
 # Event delegation
 
-Capturing and bubbling allow us to implement one of most powerful event handling patterns called *event delegation*.
+Capturing and bubbling allow us to implement one of the most powerful event handling patterns called *event delegation*.
 
 The idea is that if we have a lot of elements handled in a similar way, then instead of assigning a handler to each of them -- we put a single handler on their common ancestor.
 
-In the handler we get `event.target`, see where the event actually happened and handle it.
+In the handler we get `event.target` to see where the event actually happened and handle it.
 
 Let's see an example -- the [Ba-Gua diagram](http://en.wikipedia.org/wiki/Ba_gua) reflecting the ancient Chinese philosophy.
 
@@ -101,8 +101,8 @@ table.onclick = function(event) {
 
 Explanations:
 1. The method `elem.closest(selector)` returns the nearest ancestor that matches the selector. In our case we look for `<td>` on the way up from the source element.
-2. If `event.target` is not inside any `<td>`, then the call returns `null`, and we don't have to do anything.
-3. In case of nested tables, `event.target` may be a `<td>` lying outside of the current table. So we check if that's actually *our table's* `<td>`.
+2. If `event.target` is not inside any `<td>`, then the call returns immediately, as there's nothing to do.
+3. In case of nested tables, `event.target` may be a `<td>`, but lying outside of the current table. So we check if that's actually *our table's* `<td>`.
 4. And, if it's so, then highlight it.
 
 As the result, we have a fast, efficient highlighting code, that doesn't care about the total number of `<td>` in the table.
@@ -121,7 +121,7 @@ The first idea may be to assign a separate handler to each button. But there's a
 
 The handler reads the attribute and executes the method. Take a look at the working example:
 
-```html autorun height=60 run
+```html autorun height=60 run untrusted
 <div id="menu">
   <button data-action="save">Save</button>
   <button data-action="load">Load</button>
diff --git a/2-ui/2-events/04-default-browser-action/3-image-gallery/solution.view/gallery.css b/2-ui/2-events/04-default-browser-action/3-image-gallery/solution.view/gallery.css
index 4522006ae..8d6472ee6 100644
--- a/2-ui/2-events/04-default-browser-action/3-image-gallery/solution.view/gallery.css
+++ b/2-ui/2-events/04-default-browser-action/3-image-gallery/solution.view/gallery.css
@@ -4,16 +4,6 @@ body {
   font: 75%/120% sans-serif;
 }
 
-h2 {
-  font: bold 190%/100% sans-serif;
-  margin: 0 0 .2em;
-}
-
-h2 em {
-  font: normal 80%/100% sans-serif;
-  color: #999999;
-}
-
 #largeImg {
   border: solid 1px #ccc;
   width: 550px;
diff --git a/2-ui/2-events/04-default-browser-action/3-image-gallery/source.view/gallery.css b/2-ui/2-events/04-default-browser-action/3-image-gallery/source.view/gallery.css
index b6e523014..8d6472ee6 100644
--- a/2-ui/2-events/04-default-browser-action/3-image-gallery/source.view/gallery.css
+++ b/2-ui/2-events/04-default-browser-action/3-image-gallery/source.view/gallery.css
@@ -4,16 +4,6 @@ body {
   font: 75%/120% sans-serif;
 }
 
-h2 {
-  font: bold 190%/100% sans-serif;
-  margin: 0 0 .2em;
-}
-
-h2 em {
-  font: normal 80%/100% sans-serif;
-  color: #999999;
-}
-
 #largeImg {
   border: solid 1px #ccc;
   width: 550px;
@@ -32,4 +22,13 @@ h2 em {
 
 #thumbs a:hover {
   border-color: #FF9900;
+}
+
+#thumbs li {
+  list-style: none;
+}
+
+#thumbs {
+  margin: 0;
+  padding: 0;
 }
\ No newline at end of file
diff --git a/2-ui/2-events/04-default-browser-action/article.md b/2-ui/2-events/04-default-browser-action/article.md
index 8bb2ffc6a..cd815654f 100644
--- a/2-ui/2-events/04-default-browser-action/article.md
+++ b/2-ui/2-events/04-default-browser-action/article.md
@@ -17,7 +17,7 @@ There are two ways to tell the browser we don't want it to act:
 - The main way is to use the `event` object. There's a method `event.preventDefault()`.
 - If the handler is assigned using `on<event>` (not by `addEventListener`), then returning `false` also works the same.
 
-In this HTML a click on a link doesn't lead to navigation, browser doesn't do anything:
+In this HTML, a click on a link doesn't lead to navigation; the browser doesn't do anything:
 
 ```html autorun height=60 no-beautify
 <a href="/" onclick="return false">Click here</a>
@@ -96,7 +96,7 @@ That's because the browser action is canceled on `mousedown`. The focusing is st
 
 The optional `passive: true` option of `addEventListener` signals the browser that the handler is not going to call `preventDefault()`.
 
-Why that may be needed?
+Why might that be needed?
 
 There are some events like `touchmove` on mobile devices (when the user moves their finger across the screen), that cause scrolling by default, but that scrolling can be prevented using `preventDefault()` in the handler.
 
@@ -113,7 +113,7 @@ The property `event.defaultPrevented` is `true` if the default action was preven
 
 There's an interesting use case for it.
 
-You remember in the chapter <info:bubbling-and-capturing> we talked about `event.stopPropagation()`  and why stopping bubbling is bad?
+You remember in the chapter <info:bubbling-and-capturing> we talked about `event.stopPropagation()` and why stopping bubbling is bad?
 
 Sometimes we can use `event.defaultPrevented` instead, to signal other event handlers that the event was handled.
 
diff --git a/2-ui/2-events/05-dispatch-events/article.md b/2-ui/2-events/05-dispatch-events/article.md
index ad9092fd8..047413fd3 100644
--- a/2-ui/2-events/05-dispatch-events/article.md
+++ b/2-ui/2-events/05-dispatch-events/article.md
@@ -8,7 +8,7 @@ We can generate not only completely new events, that we invent for our own purpo
 
 ## Event constructor
 
-Build-in event classes form a hierarchy, similar to DOM element classes. The root is the built-in [Event](http://www.w3.org/TR/dom/#event) class.
+Built-in event classes form a hierarchy, similar to DOM element classes. The root is the built-in [Event](https://dom.spec.whatwg.org/#events) class.
 
 We can create `Event` objects like this:
 
@@ -162,7 +162,7 @@ Besides, the event class describes "what kind of event" it is, and if the event
 
 ## event.preventDefault()
 
-Many browser events have a "default action", such as nagivating to a link, starting a selection, and so on.
+Many browser events have a "default action", such as navigating to a link, starting a selection, and so on.
 
 For new, custom events, there are definitely no default browser actions, but a code that dispatches such event may have its own plans what to do after triggering the event.
 
@@ -187,7 +187,6 @@ Any handler can listen for that event with `rabbit.addEventListener('hide',...)`
 <button onclick="hide()">Hide()</button>
 
 <script>
-  // hide() will be called automatically in 2 seconds
   function hide() {
     let event = new CustomEvent("hide", {
       cancelable: true // without that flag preventDefault doesn't work
@@ -211,13 +210,14 @@ Please note: the event must have the flag `cancelable: true`, otherwise the call
 
 ## Events-in-events are synchronous
 
-Usually events are processed asynchronously. That is: if the browser is processing `onclick` and in the process a new event occurs, then it waits until the `onclick` processing is finished.
+Usually events are processed in a queue. That is: if the browser is processing `onclick` and a new event occurs, e.g. mouse moved, then its handling is queued up, corresponding `mousemove` handlers will be called after `onclick` processing is finished.
 
-The exception is when one event is initiated from within another one.
+The notable exception is when one event is initiated from within another one, e.g. using `dispatchEvent`. Such events are processed immediately: the new event handlers are called, and then the current event handling is resumed.
 
-Then the control jumps to the nested event handler, and after it goes back.
+For instance, in the code below the `menu-open` event is triggered during the `onclick`.
+
+It's processed immediately, without waiting for `onclick` handler to end:
 
-For instance, here the nested `menu-open` event is processed synchronously, during the `onclick`:
 
 ```html run autorun
 <button id="menu">Menu (click me)</button>
@@ -226,7 +226,6 @@ For instance, here the nested `menu-open` event is processed synchronously, duri
   menu.onclick = function() {
     alert(1);
 
-    // alert("nested")
     menu.dispatchEvent(new CustomEvent("menu-open", {
       bubbles: true
     }));
@@ -234,17 +233,20 @@ For instance, here the nested `menu-open` event is processed synchronously, duri
     alert(2);
   };
 
+  // triggers between 1 and 2
   document.addEventListener('menu-open', () => alert('nested'));
 </script>
-```    
+```
 
 The output order is: 1 -> nested -> 2.
 
-Please note that the nested event `menu-open` fully bubbles up and is handled on the `document`. The propagation and handling of the nested event must be fully finished before the processing gets back to the outer code (`onclick`).
+Please note that the nested event `menu-open` is caught on the `document`. The propagation and handling of the nested event is finished before the processing gets back to the outer code (`onclick`).
 
-That's not only about `dispatchEvent`, there are other cases. JavaScript in an event handler can call methods that lead to other events -- they are too processed synchronously.
+That's not only about `dispatchEvent`, there are other cases. If an event handler calls methods that trigger other events -- they are processed synchronously too, in a nested fashion.
 
-If we don't like it, we can either put the `dispatchEvent` (or other event-triggering call) at the end of `onclick` or, maybe better, wrap it in zero-delay `setTimeout`:
+Let's say we don't like it. We'd want `onclick` to be fully processed first, independently from `menu-open` or any other nested events.
+
+Then we can either put the `dispatchEvent` (or another event-triggering call) at the end of `onclick` or, maybe better, wrap it in the zero-delay `setTimeout`:
 
 ```html run
 <button id="menu">Menu (click me)</button>
@@ -253,7 +255,6 @@ If we don't like it, we can either put the `dispatchEvent` (or other event-trigg
   menu.onclick = function() {
     alert(1);
 
-    // alert(2)
     setTimeout(() => menu.dispatchEvent(new CustomEvent("menu-open", {
       bubbles: true
     })));
@@ -263,9 +264,9 @@ If we don't like it, we can either put the `dispatchEvent` (or other event-trigg
 
   document.addEventListener('menu-open', () => alert('nested'));
 </script>
-```    
+```
 
-Now `dispatchEvent` runs asynchronously after the current code execution is finished, including `mouse.onclick`, so event handlers are totally separate.
+Now `dispatchEvent` runs asynchronously after the current code execution is finished, including `menu.onclick`, so event handlers are totally separate.
 
 The output order becomes: 1 -> 2 -> nested.
 
@@ -281,9 +282,9 @@ Other constructors of native events like `MouseEvent`, `KeyboardEvent` and so on
 
 For custom events we should use `CustomEvent` constructor. It has an additional option named `detail`, we should assign the event-specific data to it. Then all handlers can access it as `event.detail`.
 
-Despite the technical possibility to generate browser events like `click` or `keydown`, we should use with the great care.
+Despite the technical possibility of generating browser events like `click` or `keydown`, we should use them with great care.
 
-We shouldn't generate browser events as it's a hacky way to run handlers. That's a bad architecture most of the time.
+We shouldn't generate browser events as it's a hacky way to run handlers. That's bad architecture most of the time.
 
 Native events might be generated:
 
diff --git a/2-ui/3-event-details/1-mouse-events-basics/article.md b/2-ui/3-event-details/1-mouse-events-basics/article.md
index 42f4b6f50..9574b0c83 100644
--- a/2-ui/3-event-details/1-mouse-events-basics/article.md
+++ b/2-ui/3-event-details/1-mouse-events-basics/article.md
@@ -1,4 +1,5 @@
-# Mouse events basics
+
+# Mouse events
 
 In this chapter we'll get into more details about mouse events and their properties.
 
@@ -6,11 +7,7 @@ Please note: such events may come not only from "mouse devices", but are also fr
 
 ## Mouse event types
 
-We can split mouse events into two categories: "simple" and "complex"
-
-### Simple events
-
-The most used simple events are:
+We've already seen some of these events:
 
 `mousedown/mouseup`
 : Mouse button is clicked/released over an element.
@@ -21,54 +18,66 @@ The most used simple events are:
 `mousemove`
 : Every mouse move over an element triggers that event.
 
-`contextmenu`
-: Triggers when opening a context menu is attempted. In the most common case, that happens when the right mouse button is pressed. Although, there are other ways to open a context menu, e.g. using a special keyboard key, so it's not exactly the mouse event.
-
-...There are several other event types too, we'll cover them later.
-
-### Complex events
-
 `click`
 : Triggers after `mousedown` and then `mouseup` over the same element if the left mouse button was used.
 
 `dblclick`
-: Triggers after a double click over an element.
+: Triggers after two clicks on the same element within a short timeframe. Rarely used nowadays.
 
-Complex events are made of simple ones, so in theory we could live without them. But they exist, and that's good, because they are convenient.
+`contextmenu`
+: Triggers when the right mouse button is pressed. There are other ways to open a context menu, e.g. using a special keyboard key, it triggers in that case also, so it's not exactly the mouse event.
 
-### Events order
+...There are several other events too, we'll cover them later.
 
-An action may trigger multiple events.
+## Events order
 
-For instance, a click first triggers `mousedown`, when the button is pressed, then `mouseup` and `click` when it's released.
+As you can see from the list above, a user action may trigger multiple events.
+
+For instance, a left-button click first triggers `mousedown`, when the button is pressed, then `mouseup` and `click` when it's released.
 
 In cases when a single action initiates multiple events, their order is fixed. That is, the handlers are called in the order `mousedown` -> `mouseup` -> `click`.
 
 ```online
 Click the button below and you'll see the events. Try double-click too.
 
-On the teststand below all mouse events are logged, and if there is more than a 1 second delay between them they are separated by a horizontal ruler.
+On the teststand below, all mouse events are logged, and if there is more than a 1 second delay between them, they are separated by a horizontal rule.
 
-Also we can see the `which` property that allows to detect the mouse button.
+Also, we can see the `button` property that allows us to detect the mouse button; it's explained below.
 
 <input onmousedown="return logMouse(event)" onmouseup="return logMouse(event)" onclick="return logMouse(event)" oncontextmenu="return logMouse(event)" ondblclick="return logMouse(event)" value="Click me with the right or the left mouse button" type="button"> <input onclick="logClear('test')" value="Clear" type="button"> <form id="testform" name="testform"> <textarea style="font-size:12px;height:150px;width:360px;"></textarea></form>
 ```
 
-## Getting the button: which
+## Mouse button
+
+Click-related events always have the `button` property, which allows to get the exact mouse button.
 
-Click-related events always have the `which` property, which allows to get the exact mouse button.
+We usually don't use it for `click` and `contextmenu` events, because the former happens only on left-click, and the latter -- only on right-click.
 
-It is not used for `click` and `contextmenu` events, because the former happens only on left-click, and the latter -- only on right-click.
+On the other hand, `mousedown` and `mouseup` handlers may need `event.button`, because these events trigger on any button, so `button` allows to distinguish between "right-mousedown" and "left-mousedown".
 
-But if we track `mousedown` and `mouseup`, then we need it, because these events trigger on any button, so `which` allows to distinguish between "right-mousedown" and "left-mousedown".
+The possible values of `event.button` are:
 
-There are the three possible values:
+| Button state | `event.button` |
+|--------------|----------------|
+| Left button (primary) | 0 |
+| Middle button (auxiliary) | 1 |
+| Right button (secondary) | 2 |
+| X1 button (back) | 3 |
+| X2 button (forward) | 4 |
 
-- `event.which == 1` -- the left button
-- `event.which == 2` - the middle button
-- `event.which == 3` - the right button
+Most mouse devices only have the left and right buttons, so possible values are `0` or `2`. Touch devices also generate similar events when one taps on them.
 
-The middle button is somewhat exotic right now and is very rarely used.
+Also there's `event.buttons` property that has all currently pressed buttons as an integer, one bit per button. In practice this property is very rarely used, you can find details at [MDN](mdn:/api/MouseEvent/buttons) if you ever need it.
+
+```warn header="The outdated `event.which`"
+Old code may use `event.which` property that's an old non-standard way of getting a button, with possible values:
+
+- `event.which == 1` – left button,
+- `event.which == 2` – middle button,
+- `event.which == 3` – right button.
+
+As of now, `event.which` is deprecated, we shouldn't use it.
+```
 
 ## Modifiers: shift, alt, ctrl and meta
 
@@ -116,18 +125,25 @@ For JS-code it means that we should check `if (event.ctrlKey || event.metaKey)`.
 ```
 
 ```warn header="There are also mobile devices"
-Keyboard combinations are good as an addition to the workflow. So that if the visitor has a
- keyboard -- it works. And if their device doesn't have it -- then there should be another way to do the same.
+Keyboard combinations are good as an addition to the workflow. So that if the visitor uses a keyboard -- they work. 
+
+But if their device doesn't have it -- then there should be a way to live without modifier keys.
 ```
 
 ## Coordinates: clientX/Y, pageX/Y
 
-All mouse events have coordinates in two flavours:
+All mouse events provide coordinates in two flavours:
 
 1. Window-relative: `clientX` and `clientY`.
 2. Document-relative: `pageX` and `pageY`.
 
-For instance, if we have a window of the size 500x500, and the mouse is in the left-upper corner, then `clientX` and `clientY` are `0`. And if the mouse is in the center, then `clientX` and `clientY` are `250`, no matter what place in the document it is, how far the document was scrolled. They are similar to `position:fixed`.
+We already covered the difference between them in the chapter <info:coordinates>.
+
+In short, document-relative coordinates `pageX/Y` are counted from the left-upper corner of the document, and do not change when the page is scrolled, while `clientX/Y` are counted from the current window left-upper corner. When the page is scrolled, they change.
+
+For instance, if we have a window of the size 500x500, and the mouse is in the left-upper corner, then `clientX` and `clientY` are `0`, no matter how the page is scrolled. 
+
+And if the mouse is in the center, then `clientX` and `clientY` are `250`, no matter what place in the document it is. They are similar to `position:fixed` in that aspect.
 
 ````online
 Move the mouse over the input field to see `clientX/clientY` (the example is in the `iframe`, so coordinates are relative to that `iframe`):
@@ -137,13 +153,11 @@ Move the mouse over the input field to see `clientX/clientY` (the example is in
 ```
 ````
 
-Document-relative coordinates `pageX`, `pageY` are counted from the left-upper corner of the document, not the window. You can read more about coordinates in the chapter <info:coordinates>.
-
-## Disabling selection
+## Preventing selection on mousedown
 
-Double mouse click has a side-effect that may be disturbing in some interfaces: it selects the text.
+Double mouse click has a side effect that may be disturbing in some interfaces: it selects text.
 
-For instance, a double-click on the text below selects it in addition to our handler:
+For instance, double-clicking on the text below selects it in addition to our handler:
 
 ```html autorun height=50
 <span ondblclick="alert('dblclick')">Double-click me</span>
@@ -186,7 +200,7 @@ Surely the user has access to HTML-source of the page, and can take the content
 
 Mouse events have the following properties:
 
-- Button: `which`.
+- Button: `button`.
 - Modifier keys (`true` if pressed): `altKey`, `ctrlKey`, `shiftKey` and `metaKey` (Mac).
   - If you want to handle `key:Ctrl`, then don't forget Mac users, they usually use `key:Cmd`, so it's better to check `if (e.metaKey || e.ctrlKey)`.
 
diff --git a/2-ui/3-event-details/1-mouse-events-basics/head.html b/2-ui/3-event-details/1-mouse-events-basics/head.html
index f578fb7db..1b9a73fca 100644
--- a/2-ui/3-event-details/1-mouse-events-basics/head.html
+++ b/2-ui/3-event-details/1-mouse-events-basics/head.html
@@ -25,7 +25,7 @@
   function logMouse(e) {
      let evt = e.type;
      while (evt.length < 11) evt += ' ';
-     showmesg(evt + " which=" + e.which, 'test')
+     showmesg(evt + " button=" + e.button, 'test')
      return false;
   }
 
diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/1-behavior-nested-tooltip/solution.view/index.html b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/1-behavior-nested-tooltip/solution.view/index.html
index e998165fd..84d52b18c 100644
--- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/1-behavior-nested-tooltip/solution.view/index.html
+++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/1-behavior-nested-tooltip/solution.view/index.html
@@ -54,7 +54,7 @@
 
     <p>Once upon a time there was a mother pig who had three little pigs.</p>
 
-    <p>The three little pigs grew so big that their mother said to them, "You are too big to live here any longer. You must go and build houses for yourselves. But take care that the wolf does not catch you."
+    <p>The three little pigs grew so big that their mother said to them, "You are too big to live here any longer. You must go and build houses for yourselves. But take care that the wolf does not catch you."</p>
 
     <p>The three little pigs set off. "We will take care that the wolf does not catch us," they said.</p>
 
diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/1-behavior-nested-tooltip/source.view/index.html b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/1-behavior-nested-tooltip/source.view/index.html
index 2dc4394e7..774e24a21 100644
--- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/1-behavior-nested-tooltip/source.view/index.html
+++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/1-behavior-nested-tooltip/source.view/index.html
@@ -54,7 +54,7 @@
 
     <p>Once upon a time there was a mother pig who had three little pigs.</p>
 
-    <p>The three little pigs grew so big that their mother said to them, "You are too big to live here any longer. You must go and build houses for yourselves. But take care that the wolf does not catch you."
+    <p>The three little pigs grew so big that their mother said to them, "You are too big to live here any longer. You must go and build houses for yourselves. But take care that the wolf does not catch you."</p>
 
     <p>The three little pigs set off. "We will take care that the wolf does not catch us," they said.</p>
 
diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/solution.view/hoverIntent.js b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/solution.view/hoverIntent.js
index 4e6e2a3e9..7503ca9c2 100644
--- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/solution.view/hoverIntent.js
+++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/2-hoverintent/solution.view/hoverIntent.js
@@ -88,7 +88,7 @@ class HoverIntent {
     if (speed < this.sensitivity) {
       clearInterval(this.checkSpeedInterval);
       this.isHover = true;
-      this.over.call(this.elem, event);
+      this.over.call(this.elem);
     } else {
       // speed fast, remember new coordinates as the previous ones
       this.prevX = this.lastX;
diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/article.md b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/article.md
index c7ac0d4db..d409c3f12 100644
--- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/article.md
+++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/article.md
@@ -80,7 +80,7 @@ An important feature of `mouseout` -- it triggers, when the pointer moves from a
 </div>
 ```
 
-If we're on `#parent` and then move the pointer deeper into `#child`, but we get `mouseout` on `#parent`!
+If we're on `#parent` and then move the pointer deeper into `#child`, we get `mouseout` on `#parent`!
 
 ![](mouseover-to-child.svg)
 
diff --git a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseoverout-fast.view/script.js b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseoverout-fast.view/script.js
index 6d87199c2..5752e83ae 100755
--- a/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseoverout-fast.view/script.js
+++ b/2-ui/3-event-details/3-mousemove-mouseover-mouseout-mouseenter-mouseleave/mouseoverout-fast.view/script.js
@@ -3,7 +3,7 @@ parent.onmouseover = parent.onmouseout = parent.onmousemove = handler;
 
 function handler(event) {
   let type = event.type;
-  while (type < 11) type += ' ';
+  while (type.length < 11) type += ' ';
 
   log(type + " target=" + event.target.id)
   return false;
diff --git a/2-ui/3-event-details/4-mouse-drag-and-drop/article.md b/2-ui/3-event-details/4-mouse-drag-and-drop/article.md
index b74c13f1e..4c928eef1 100644
--- a/2-ui/3-event-details/4-mouse-drag-and-drop/article.md
+++ b/2-ui/3-event-details/4-mouse-drag-and-drop/article.md
@@ -4,9 +4,9 @@ Drag'n'Drop is a great interface solution. Taking something and dragging and dro
 
 In the modern HTML standard there's a [section about Drag and Drop](https://html.spec.whatwg.org/multipage/interaction.html#dnd) with special events such as `dragstart`, `dragend`, and so on.
 
-These events are useful in that they allow us to solve simple tasks easily. For instance, they allow us to handle the drag'n'drop of "external" files into the browser, so we can take a file in the OS file-manager and drop it into the browser window, thereby giving JavaScript access to its contents.
+These events allow us to support special kinds of drag'n'drop, such as handling dragging a file from OS file-manager and dropping it into the browser window. Then JavaScript can access the contents of such files.
 
-But native Drag Events also have limitations. For instance, we can't limit dragging by a certain area. Also we can't make it "horizontal" or "vertical" only. And there are other drag'n'drop tasks that can't be done using that API. Also, mobile device support for such events is almost non-existant.
+But native Drag Events also have limitations. For instance, we can't prevent dragging from a certain area. Also we can't make the dragging "horizontal" or "vertical" only. And there are many other drag'n'drop tasks that can't be done using them. Also, mobile device support for such events is very weak.
 
 So here we'll see how to implement Drag'n'Drop using mouse events.
 
@@ -14,26 +14,23 @@ So here we'll see how to implement Drag'n'Drop using mouse events.
 
 The basic Drag'n'Drop algorithm looks like this:
 
-1. On `mousedown` - prepare the element for moving, if needed (maybe create a copy of it).
-2. Then on `mousemove` move it by changing `left/top` and `position:absolute`.
-3. On `mouseup` - perform all actions related to a finished Drag'n'Drop.
+1. On `mousedown` - prepare the element for moving, if needed (maybe create a clone of it, add a class to it or whatever).
+2. Then on `mousemove` move it by changing `left/top` with `position:absolute`.
+3. On `mouseup` - perform all actions related to finishing the drag'n'drop.
 
-These are the basics. Later we can extend it, for instance, by highlighting droppable (available for the drop) elements when hovering over them.
+These are the basics. Later we'll see how to add other features, such as highlighting current underlying elements while we drag over them.
 
-Here's the algorithm for drag'n'drop of a ball:
+Here's the implementation of dragging a ball:
 
 ```js
-ball.onmousedown = function(event) { // (1) start the process
-
-  // (2) prepare to moving: make absolute and on top by z-index
+ball.onmousedown = function(event) {
+  // (1) prepare to moving: make absolute and on top by z-index
   ball.style.position = 'absolute';
   ball.style.zIndex = 1000;
+
   // move it out of any current parents directly into body
   // to make it positioned relative to the body
-  document.body.append(ball);  
-  // ...and put that absolutely positioned ball under the pointer
-
-  moveAt(event.pageX, event.pageY);
+  document.body.append(ball);
 
   // centers the ball at (pageX, pageY) coordinates
   function moveAt(pageX, pageY) {
@@ -41,14 +38,17 @@ ball.onmousedown = function(event) { // (1) start the process
     ball.style.top = pageY - ball.offsetHeight / 2 + 'px';
   }
 
+  // move our absolutely positioned ball under the pointer
+  moveAt(event.pageX, event.pageY);
+
   function onMouseMove(event) {
     moveAt(event.pageX, event.pageY);
   }
 
-  // (3) move the ball on mousemove
+  // (2) move the ball on mousemove
   document.addEventListener('mousemove', onMouseMove);
 
-  // (4) drop the ball, remove unneeded handlers
+  // (3) drop the ball, remove unneeded handlers
   ball.onmouseup = function() {
     document.removeEventListener('mousemove', onMouseMove);
     ball.onmouseup = null;
@@ -64,10 +64,10 @@ Here's an example in action:
 
 [iframe src="ball" height=230]
 
-Try to drag'n'drop the mouse and you'll see such behavior.
+Try to drag'n'drop with the mouse and you'll see such behavior.
 ```
 
-That's because the browser has its own Drag'n'Drop for images and some other elements that runs automatically and conflicts with ours.
+That's because the browser has its own drag'n'drop support for images and some other elements. It runs automatically and conflicts with ours.
 
 To disable it:
 
@@ -93,14 +93,14 @@ So we should listen on `document` to catch it.
 
 ## Correct positioning
 
-In the examples above the ball is always moved so, that it's center is under the pointer:
+In the examples above the ball is always moved so that its center is under the pointer:
 
 ```js
 ball.style.left = pageX - ball.offsetWidth / 2 + 'px';
 ball.style.top = pageY - ball.offsetHeight / 2 + 'px';
 ```
 
-Not bad, but there's a side-effect. To initiate the drag'n'drop, we can `mousedown` anywhere on the ball. But if "take" it from its edge, then the ball suddenly "jumps" to become centered under the mouse pointer.
+Not bad, but there's a side effect. To initiate the drag'n'drop, we can `mousedown` anywhere on the ball. But if "take" it from its edge, then the ball suddenly "jumps" to become centered under the mouse pointer.
 
 It would be better if we keep the initial shift of the element relative to the pointer.
 
@@ -124,7 +124,7 @@ Let's update our algorithm:
 
     ```js
     // onmousemove
-    // ball has position:absoute
+    // ball has position:absolute
     ball.style.left = event.pageX - *!*shiftX*/!* + 'px';
     ball.style.top = event.pageY - *!*shiftY*/!* + 'px';
     ```
@@ -219,7 +219,7 @@ That's why the initial idea to put handlers on potential droppables doesn't work
 
 So, what to do?
 
-There's a method called `document.elementFromPoint(clientX, clientY)`. It returns the most nested element on given window-relative coordinates (or `null` if given coordinates are out of the window).
+There's a method called `document.elementFromPoint(clientX, clientY)`. It returns the most nested element on given window-relative coordinates (or `null` if given coordinates are out of the window). If there are multiple overlapping elements on the same coordinates, then the topmost one is returned.
 
 We can use it in any of our mouse event handlers to detect the potential droppable under the pointer, like this:
 
@@ -276,7 +276,7 @@ function onMouseMove(event) {
 }
 ```
 
-In the example below when the ball is dragged over the soccer gate, the gate is highlighted.
+In the example below when the ball is dragged over the soccer goal, the goal is highlighted.
 
 [codetabs height=250 src="ball4"]
 
@@ -300,4 +300,4 @@ We can lay a lot on this foundation.
 - We can use event delegation for `mousedown/up`. A large-area event handler that checks  `event.target` can manage Drag'n'Drop for hundreds of elements.
 - And so on.
 
-There are frameworks that build architecture over it: `DragZone`, `Droppable`, `Draggable` and other classes. Most of them do the similar stuff to described above, so it should be easy to understand them now. Or roll our own, as you can see that's easy enough to do, sometimes easier than adapting a third-part solution.
+There are frameworks that build architecture over it: `DragZone`, `Droppable`, `Draggable` and other classes. Most of them do the similar stuff to what's described above, so it should be easy to understand them now. Or roll your own, as you can see that that's easy enough to do, sometimes easier than adapting a third-party solution.
diff --git a/2-ui/3-event-details/4-mouse-drag-and-drop/ball.view/index.html b/2-ui/3-event-details/4-mouse-drag-and-drop/ball.view/index.html
index 3fdd7fe76..8751c70ad 100644
--- a/2-ui/3-event-details/4-mouse-drag-and-drop/ball.view/index.html
+++ b/2-ui/3-event-details/4-mouse-drag-and-drop/ball.view/index.html
@@ -13,16 +13,13 @@
 
 
   <script>
-    ball.onmousedown = function(event) { // (1) start the process
-
-      // (2) prepare to moving: make absolute and top by z-index
+    ball.onmousedown = function(event) {
       ball.style.position = 'absolute';
       ball.style.zIndex = 1000;
       document.body.appendChild(ball);
-      // ...and put that absolutely positioned ball under the cursor
+
       moveAt(event.pageX, event.pageY);
 
-      // centers the ball at (pageX, pageY) coordinates
       function moveAt(pageX, pageY) {
         ball.style.left = pageX - ball.offsetWidth / 2 + 'px';
         ball.style.top = pageY - ball.offsetHeight / 2 + 'px';
@@ -32,10 +29,8 @@
         moveAt(event.pageX, event.pageY);
       }
 
-      // (3) move the ball on mousemove
       document.addEventListener('mousemove', onMouseMove);
 
-      // (4) drop the ball, remove unneeded handlers
       ball.onmouseup = function() {
         document.removeEventListener('mousemove', onMouseMove);
         ball.onmouseup = null;
diff --git a/2-ui/3-event-details/4-mouse-drag-and-drop/ball2.view/index.html b/2-ui/3-event-details/4-mouse-drag-and-drop/ball2.view/index.html
index 3843aa789..195107e56 100644
--- a/2-ui/3-event-details/4-mouse-drag-and-drop/ball2.view/index.html
+++ b/2-ui/3-event-details/4-mouse-drag-and-drop/ball2.view/index.html
@@ -13,16 +13,13 @@
 
 
   <script>
-    ball.onmousedown = function(event) { // (1) start the process
-
-      // (2) prepare to moving: make absolute and top by z-index
+    ball.onmousedown = function(event) {
       ball.style.position = 'absolute';
       ball.style.zIndex = 1000;
       document.body.appendChild(ball);
-      // ...and put that absolutely positioned ball under the cursor
+
       moveAt(event.pageX, event.pageY);
 
-      // centers the ball at (pageX, pageY) coordinates
       function moveAt(pageX, pageY) {
         ball.style.left = pageX - ball.offsetWidth / 2 + 'px';
         ball.style.top = pageY - ball.offsetHeight / 2 + 'px';
@@ -32,10 +29,8 @@
         moveAt(event.pageX, event.pageY);
       }
 
-      // (3) move the ball on mousemove
       document.addEventListener('mousemove', onMouseMove);
 
-      // (4) drop the ball, remove unneeded handlers
       ball.onmouseup = function() {
         document.removeEventListener('mousemove', onMouseMove);
         ball.onmouseup = null;
diff --git a/2-ui/3-event-details/5-keyboard-events/german-layout.svg b/2-ui/3-event-details/5-keyboard-events/german-layout.svg
deleted file mode 100644
index 8a880e8e0..000000000
--- a/2-ui/3-event-details/5-keyboard-events/german-layout.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="600" height="200" viewBox="0 0 600 200"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:&apos;PT Mono&apos;;font-weight:700;font-style:normal;src:local(&apos;PT MonoBold&apos;),url(/font/PTMonoBold.woff2) format(&apos;woff2&apos;),url(/font/PTMonoBold.woff) format(&apos;woff&apos;),url(/font/PTMonoBold.ttf) format(&apos;truetype&apos;)}</style></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="german-layout.svg"><g id="KB_Germany" transform="translate(.918 .953)"><g id="Group"><path id="rect2186" fill="#FFF" stroke="#000" d="M.08.083h39.933V39.46H.08z"/><path id="rect2218" fill="#FFF" stroke="#000" d="M40.013.083h39.934V39.46H40.013z"/><path id="rect2222" fill="#FFF" stroke="#000" d="M79.947.083h39.933V39.46H79.947z"/><path id="rect2228" fill="#FFF" stroke="#000" d="M118.882.083h39.933V39.46h-39.933z"/><path id="rect2230" fill="#FFF" stroke="#000" d="M158.815.083h39.934V39.46h-39.934z"/><path id="rect2232" fill="#FFF" stroke="#000" d="M198.749.083h39.933V39.46H198.75z"/><path id="rect2234" fill="#FFF" stroke="#000" d="M239.68.083h39.934V39.46h-39.933z"/><path id="rect2236" fill="#FFF" stroke="#000" d="M279.614.083h39.933V39.46h-39.933z"/><path id="rect2238" fill="#FFF" stroke="#000" d="M318.55.083h39.933V39.46h-39.934z"/><path id="rect2240" fill="#FFF" stroke="#000" d="M358.483.083h39.933V39.46h-39.933z"/><path id="rect2242" fill="#FFF" stroke="#000" d="M398.416.083h39.933V39.46h-39.933z"/><path id="rect2244" fill="#FFF" stroke="#000" d="M438.35.083h39.933V39.46h-39.934z"/><path id="rect2246" fill="#FFF" stroke="#000" d="M478.283.083h39.933V39.46h-39.933z"/><path id="rect2248" fill="#DFDFDF" stroke="#000" d="M517.218.083h81.864V39.46h-81.864z"/><path id="rect2250" fill="#DFDFDF" stroke="#000" d="M.08 39.461h59.9V78.84H.08z"/><path id="rect2252" fill="#FFF" stroke="#000" d="M59.98 39.461h39.933V78.84H59.98z"/><path id="rect2254" fill="#FFF" stroke="#000" d="M98.915 39.461h39.934V78.84H98.915z"/><path id="rect2256" fill="#FFF" stroke="#000" d="M138.849 39.461h39.933V78.84h-39.933z"/><path id="rect2258" fill="#FFF" stroke="#000" d="M178.782 39.461h39.933V78.84h-39.933z"/><path id="rect2262" fill="#FFF" stroke="#000" d="M219.714 39.461h39.933V78.84h-39.933z"/><path id="rect2264" fill="#FFF" stroke="#000" d="M259.647 39.461h39.934V78.84h-39.934z"/><path id="rect2266" fill="#FFF" stroke="#000" d="M298.582 39.461h39.934V78.84h-39.934z"/><path id="rect2270" fill="#FFF" stroke="#000" d="M338.516 39.461h39.933V78.84h-39.933z"/><path id="rect2272" fill="#FFF" stroke="#000" d="M378.45 39.461h39.933V78.84h-39.934z"/><path id="rect2274" fill="#FFF" stroke="#000" d="M418.383 39.461h39.933V78.84h-39.933z"/><path id="rect2278" fill="#FFF" stroke="#000" d="M458.316 39.461h39.934V78.84h-39.934z"/><path id="rect2280" fill="#FFF" stroke="#000" d="M497.251 39.461h39.934V78.84H497.25z"/><path id="rect2286" fill="#DFDFDF" stroke="#000" d="M.08 79.876h69.883v39.378H.08z"/><path id="rect2292" fill="#FFF" stroke="#000" d="M69.963 79.876h39.934v39.378H69.963z"/><path id="rect2296" fill="#FFF" stroke="#000" d="M109.897 79.876h39.933v39.378h-39.933z"/><path id="rect2298" fill="#FFF" stroke="#000" d="M149.83 79.876h39.934v39.378H149.83z"/><path id="rect2300" fill="#FFF" stroke="#000" d="M188.765 79.876H228.7v39.378h-39.934z"/><path id="rect2302" fill="#FFF" stroke="#000" d="M228.699 79.876h39.933v39.378H228.7z"/><path id="rect2306" fill="#FFF" stroke="#000" d="M268.632 79.876h39.934v39.378h-39.934z"/><path id="rect2308" fill="#FFF" stroke="#000" d="M308.566 79.876h39.933v39.378h-39.933z"/><path id="rect2312" fill="#FFF" stroke="#000" d="M348.5 79.876h39.933v39.378h-39.934z"/><path id="rect2314" fill="#FFF" stroke="#000" d="M388.433 79.876h39.933v39.378h-39.933z"/><path id="rect2316" fill="#FFF" stroke="#000" d="M428.366 79.876H468.3v39.378h-39.934z"/><path id="rect2318" fill="#FFF" stroke="#000" d="M468.3 79.876h39.933v39.378H468.3z"/><path id="rect2320" fill="#DFDFDF" stroke="#000" stroke-width="1" d="M547.5 79.358h-10.315V39.46h61.896v79.793h-51.656z"/><path id="rect2322" fill="#DFDFDF" stroke="#000" stroke-width="1" d="M.08 119.254h49.917v39.378H.08z"/><path id="rect2324" fill="#FFF" stroke="#000" d="M89.93 119.254h39.934v39.378H89.93z"/><path id="rect2326" fill="#FFF" stroke="#000" d="M129.864 119.254h39.933v39.378h-39.933z"/><path id="rect2330" fill="#FFF" stroke="#000" d="M169.797 119.254h39.933v39.378h-39.933z"/><path id="rect2334" fill="#FFF" stroke="#000" d="M208.732 119.254h39.934v39.378h-39.934z"/><path id="rect2336" fill="#FFF" stroke="#000" d="M248.666 119.254h39.933v39.378h-39.933z"/><path id="rect2338" fill="#FFF" stroke="#000" d="M288.599 119.254h39.933v39.378H288.6z"/><path id="rect2340" fill="#FFF" stroke="#000" d="M328.532 119.254h39.934v39.378h-39.934z"/><path id="rect2342" fill="#FFF" stroke="#000" d="M368.466 119.254h39.933v39.378h-39.933z"/><path id="rect2344" fill="#FFF" stroke="#000" d="M408.4 119.254h39.933v39.378h-39.934z"/><path id="rect2346" fill="#FFF" stroke="#000" d="M448.333 119.254h39.933v39.378h-39.933z"/><path id="rect2348" fill="#DFDFDF" stroke="#000" d="M488.266 119.254h110.816v39.378H488.266z"/><path id="rect2350" fill="#DFDFDF" stroke="#000" d="M.08 158.632h59.9v39.378H.08z"/><path id="rect2352" fill="#DFDFDF" stroke="#000" d="M537.185 158.632h61.897v39.378h-61.897z"/><path id="rect2354" fill="#DFDFDF" stroke="#000" d="M98.915 158.632h59.9v39.378h-59.9z"/><path id="rect2360" fill="#DFDFDF" stroke="#000" d="M398.416 158.632h59.9v39.378h-59.9z"/><path id="rect2362" fill="#FFF" stroke="#000" d="M158.815 158.632h239.601v39.378h-239.6z"/><path id="rect2364" fill="#EFEFEF" stroke="#000" d="M59.98 158.632h39.933v39.378H59.98z"/><path id="rect2366" fill="#EFEFEF" stroke="#000" d="M458.316 158.632h39.934v39.378h-39.934z"/><path id="rect2368" fill="#EFEFEF" stroke="#000" d="M497.251 158.632h39.934v39.378H497.25z"/><path id="text5091" fill="#000" fill-rule="nonzero" d="M49.737 12.695l-.623-5.28V4.227h2.463v3.186l-.624 5.281h-1.216m-.591 3.266v-2.35h2.375v2.35h-2.375m.591 20.391v-7.798h-2.735v-1.6h.176c.997 0 1.722-.155 2.176-.463.458-.308.727-.823.807-1.545h1.832v11.406h-2.256"/><path id="text5127" fill="#000" fill-rule="nonzero" d="M89.635 5.264h1.507v4.347h-1.507V5.264m-2.56 0h1.507v4.347h-1.507V5.264m-2.137 31.088c.01-.995.226-1.837.644-2.527.42-.694 1.163-1.397 2.23-2.107.163-.109.399-.26.707-.451 1.414-.897 2.12-1.76 2.12-2.59 0-.492-.148-.88-.447-1.166-.298-.285-.707-.428-1.225-.428-.565 0-1.002.177-1.311.53-.304.347-.456.844-.456 1.492v.093h-2.073c0-1.275.345-2.257 1.037-2.947.69-.689 1.675-1.034 2.952-1.034 1.157 0 2.081.314 2.773.941.69.622 1.036 1.452 1.036 2.488 0 .742-.18 1.385-.542 1.929-.361.544-1.06 1.164-2.097 1.858-.22.15-.523.348-.91.591-.985.628-1.54 1.104-1.665 1.431h5.104v1.897h-7.877"/><path id="text5139" fill="#000" fill-rule="nonzero" d="M126.869 31.62h2.136c.005.62.155 1.087.45 1.402.296.31.734.465 1.314.465.559 0 .989-.144 1.29-.434.305-.294.458-.715.458-1.263 0-.547-.179-.96-.536-1.24-.353-.284-.878-.426-1.577-.426-.037 0-.094.003-.171.008a2.506 2.506 0 01-.164.008v-1.535h.241c.643 0 1.116-.124 1.422-.372.31-.253.466-.638.466-1.154 0-.429-.132-.767-.396-1.015-.259-.254-.614-.38-1.064-.38-.492 0-.873.145-1.142.434-.27.29-.404.7-.404 1.232v.093h-2.098c.026-1.137.36-2.007 1.002-2.612.648-.61 1.56-.914 2.735-.914 1.113 0 1.996.271 2.65.814.652.542.978 1.273.978 2.193 0 .485-.111.912-.334 1.278-.223.367-.557.67-1.002.907.57.248 1 .592 1.29 1.03.295.435.442.954.442 1.558 0 1.11-.365 1.992-1.095 2.643-.73.65-1.728.976-2.991.976-1.249 0-2.212-.315-2.89-.945-.674-.636-1.01-1.537-1.01-2.705v-.046"/><path id="text5145" fill="#000" fill-rule="nonzero" d="M168.895 14.91c.468-.057.825-.21 1.07-.46.246-.25.369-.584.369-1 0-.37-.117-.674-.351-.914-.229-.244-.591-.434-1.088-.57v2.944m-1.02-5.341V6.914c-.445.052-.785.193-1.019.422-.234.224-.35.526-.35.906 0 .317.108.583.325.796.222.213.57.39 1.045.531m0 8.55V16.62c-1.291-.073-2.256-.414-2.896-1.023-.64-.609-.959-1.489-.959-2.64h2.296c.028.563.17 1.008.428 1.336.263.323.64.529 1.13.617v-3.233c-1.324-.307-2.266-.708-2.826-1.202-.56-.495-.84-1.171-.84-2.03 0-.953.332-1.72.994-2.304.668-.583 1.559-.887 2.673-.914v-.999h1.019v1c1.113.052 1.981.359 2.604.92.622.558.965 1.344 1.027 2.36h-2.33c-.04-.485-.168-.855-.385-1.11-.211-.26-.517-.406-.916-.437v2.842c1.41.401 2.404.86 2.98 1.375.577.515.866 1.194.866 2.038 0 .994-.337 1.788-1.011 2.381-.668.594-1.613.94-2.835 1.039v1.483h-1.02m1.157 14.095v-4.787l-3.332 4.787h3.332m-.052 4.138V33.94h-5.173v-1.967l4.522-6.481h3.041v6.668h1.422v1.78h-1.422v2.413h-2.39"/><path id="text5151" fill="#000" fill-rule="nonzero" d="M212.846 12.99c0 .356.11.656.33.9.22.239.493.358.816.358.314 0 .583-.122.809-.366.225-.25.338-.547.338-.892 0-.34-.113-.63-.338-.868a1.048 1.048 0 00-.809-.367c-.323 0-.595.12-.816.359-.22.233-.33.525-.33.876m-1.595 0c0-.829.264-1.527.793-2.095a2.558 2.558 0 011.948-.852c.755 0 1.396.29 1.926.868.534.573.8 1.266.8 2.079 0 .818-.266 1.519-.8 2.103-.534.579-1.176.868-1.926.868-.77 0-1.418-.287-1.948-.86-.529-.574-.793-1.277-.793-2.111m-4.27 2.971l6.276-11.733h1.183l-6.276 11.733h-1.184m-.646-8.762c0 .35.107.645.323.884.22.24.492.359.816.359.318 0 .588-.12.808-.359.226-.244.338-.539.338-.884 0-.34-.112-.63-.338-.868a1.048 1.048 0 00-.808-.367c-.324 0-.595.12-.816.359a1.243 1.243 0 00-.323.876m-1.595 0c0-.828.264-1.53.794-2.103.529-.579 1.175-.868 1.94-.868.754 0 1.396.292 1.925.876.535.579.802 1.277.802 2.095 0 .818-.267 1.516-.802 2.095-.529.573-1.17.86-1.925.86-.77 0-1.419-.284-1.948-.852-.524-.568-.786-1.27-.786-2.103m2.102 25.76h2.058c.034.5.188.887.463 1.163.274.27.642.406 1.102.406.569 0 1.002-.18 1.301-.541.304-.361.456-.88.456-1.554 0-.632-.155-1.128-.463-1.49-.309-.366-.735-.549-1.28-.549-.303 0-.57.067-.8.2-.23.132-.427.329-.588.589l-1.896-.12.683-6.117h6.049v1.928h-4.564l-.272 2.286c.23-.197.495-.343.794-.438.298-.101.632-.152 1-.152 1.048 0 1.893.345 2.535 1.036.647.69.97 1.595.97 2.716 0 1.227-.355 2.206-1.066 2.94-.71.727-1.663 1.09-2.859 1.09-1.088 0-1.955-.3-2.602-.9-.641-.605-.982-1.436-1.021-2.493"/><path id="path3073" fill="#000" fill-rule="nonzero" d="M248.136 10.477l-.576.414c-.232.16-.406.354-.523.58-.116.226-.174.48-.174.76 0 .427.146.786.44 1.077.293.291.66.437 1.099.437.323 0 .631-.066.925-.196.298-.136.573-.331.826-.587l-2.017-2.485m.607-2.372l.265-.188c.243-.165.422-.351.538-.557.117-.206.175-.442.175-.708 0-.256-.081-.459-.243-.61-.156-.15-.371-.225-.644-.225-.278 0-.498.077-.66.233-.161.15-.242.356-.242.617 0 .14.038.294.113.46.081.165.195.341.342.527l.356.451m-1.706 1.002l-.44-.572a3.576 3.576 0 01-.492-.844 2.442 2.442 0 01-.144-.835c0-.803.258-1.44.773-1.913.52-.477 1.226-.715 2.115-.715.854 0 1.529.218 2.024.655.495.437.743 1.026.743 1.77 0 .562-.147 1.066-.44 1.513-.288.441-.743.858-1.364 1.25l1.6 1.957c.15-.246.27-.522.355-.828.091-.306.155-.648.19-1.024h1.97a6.483 6.483 0 01-.408 1.814 5.604 5.604 0 01-.895 1.529l2.032 2.454h-2.578l-.758-.926a4.741 4.741 0 01-1.47.926 4.572 4.572 0 01-1.668.309c-1.031 0-1.875-.304-2.532-.911-.652-.607-.978-1.383-.978-2.327 0-.702.182-1.307.546-1.814.364-.507.97-.996 1.82-1.468"/><path id="text5163" fill="#000" fill-rule="nonzero" d="M288.564 36.352h-2.353c.084-1.6.454-3.187 1.11-4.76.66-1.574 1.602-3.12 2.824-4.64h-5.54v-1.999h7.987v1.762c-1.238 1.42-2.19 2.923-2.856 4.507-.661 1.585-1.052 3.295-1.172 5.13"/><path id="path3094" fill="#000" fill-rule="nonzero" d="M506.735 48.674l-1.417 2.151-1.368-1.032 1.546-2.091-2.255-.677.524-1.761 2.165.832v-2.49h1.594v2.49l2.166-.815.54 1.761-2.255.66 1.53 2.073-1.4 1.085-1.37-2.186"/><path id="path3092" fill="#000" fill-rule="nonzero" d="M325.79 31.784c0 .541.15.959.45 1.252.304.294.738.44 1.302.44.537 0 .959-.149 1.264-.447.31-.3.465-.714.465-1.245 0-.51-.158-.92-.473-1.228-.315-.31-.734-.464-1.256-.464s-.946.157-1.272.471c-.32.315-.48.722-.48 1.221m.178-4.745c0 .428.134.758.403.99.269.226.654.34 1.155.34.502 0 .887-.116 1.156-.348.274-.232.41-.56.41-.982 0-.412-.139-.736-.418-.973-.28-.237-.662-.356-1.148-.356-.475 0-.855.121-1.14.363-.279.242-.418.564-.418.966m-.799 2.149c-.465-.258-.801-.56-1.008-.905-.207-.345-.31-.785-.31-1.321 0-.948.326-1.692.977-2.233.651-.541 1.55-.812 2.698-.812 1.158 0 2.063.27 2.714.812.657.535.985 1.28.985 2.233 0 .51-.111.953-.333 1.33-.223.37-.556.669-1 .896.542.252.95.602 1.224 1.05.274.444.411.985.411 1.624 0 1.076-.356 1.921-1.07 2.534-.708.614-1.685.92-2.93.92-1.262 0-2.242-.304-2.94-.912-.697-.608-1.046-1.455-1.046-2.542 0-.634.129-1.165.387-1.592.264-.433.678-.794 1.241-1.082"/><path id="path3112" fill="#000" fill-rule="nonzero" d="M330.53 5.264c-.81 1.15-1.412 2.32-1.806 3.51a11.87 11.87 0 00-.59 3.748c0 1.302.197 2.549.59 3.74.394 1.19.995 2.36 1.805 3.51h-1.857c-1.028-1.216-1.808-2.437-2.342-3.663-.528-1.231-.793-2.427-.793-3.587 0-1.16.265-2.356.793-3.587.534-1.231 1.314-2.455 2.342-3.67h1.857"/><path id="path3110" fill="#000" fill-rule="nonzero" d="M369.808 27.766c0-.634-.18-1.134-.537-1.5-.353-.37-.835-.556-1.447-.556-.578 0-1.028.178-1.352.533-.318.356-.476.853-.476 1.492 0 .597.167 1.064.502 1.399.335.334.806.502 1.412.502.595 0 1.06-.165 1.395-.495.335-.33.503-.788.503-1.375m.043 2.882c-.289.258-.63.451-1.022.58a4.243 4.243 0 01-1.326.193c-1.219 0-2.195-.327-2.928-.981-.734-.655-1.1-1.53-1.1-2.628 0-1.164.398-2.105 1.195-2.82.797-.717 1.848-1.075 3.154-1.075 1.513 0 2.663.466 3.448 1.399.792.927 1.187 2.282 1.187 4.065 0 1.916-.421 3.385-1.265 4.405-.843 1.02-2.056 1.53-3.639 1.53-1.092 0-1.972-.252-2.642-.757-.67-.51-1.037-1.203-1.1-2.08l2.503.009c.058.355.214.62.468.796.254.175.612.262 1.074.262.624 0 1.1-.242 1.43-.726.33-.484.517-1.208.563-2.172"/><path id="path3121" fill="#000" fill-rule="nonzero" d="M364.473 5.264h1.875c1.02 1.211 1.796 2.432 2.324 3.663.528 1.227.792 2.425.792 3.595 0 1.165-.264 2.363-.792 3.594-.528 1.232-1.303 2.45-2.324 3.656h-1.875c.815-1.155 1.42-2.328 1.813-3.518.4-1.196.599-2.44.599-3.732 0-1.297-.2-2.541-.599-3.732-.393-1.19-.998-2.366-1.813-3.526"/><path id="path3119" fill="#000" fill-rule="nonzero" d="M405.986 29.62c0 1.349.15 2.328.451 2.937.307.61.793.915 1.459.915.665 0 1.152-.308 1.458-.922.307-.615.46-1.592.46-2.93 0-1.343-.153-2.32-.46-2.929-.306-.61-.793-.914-1.458-.914-.666 0-1.152.305-1.459.914-.3.605-.451 1.581-.451 2.93m-2.578 0c0-1.907.37-3.333 1.11-4.278.747-.95 1.873-1.426 3.378-1.426 1.499 0 2.622.478 3.368 1.434.752.95 1.129 2.379 1.129 4.285 0 1.906-.374 3.33-1.12 4.27-.741.94-1.867 1.41-3.377 1.41-1.505 0-2.63-.473-3.377-1.418-.74-.945-1.111-2.371-1.111-4.278"/><path id="text5187" fill="#000" fill-rule="nonzero" d="M453.324 136.87h7.987v1.58h-7.987v-1.58m1.802 14.508v-2.122h4.383v2.122h-4.383"/><path id="path2908" fill="#000" fill-rule="nonzero" d="M506.976 65.368h1.515v4.328h3.735v1.69h-3.735v4.345h-1.515v-4.346h-3.735v-1.689h3.735v-4.328"/><path id="path2906" fill="#000" fill-rule="nonzero" d="M403.408 12.951h8.985v1.64h-8.985v-1.64m0-3.542h8.985v1.64h-8.985v-1.64"/><g id="g3468" transform="translate(522.21 13.554)"><path id="path5439" stroke="#000" stroke-width="3" d="M34.942 5.448H6.61"/><path id="path5441" fill="#000" d="M10.219 10.79V.105L.329 5.448z"/></g><g id="g5459" transform="translate(10.063 48.788)"><path id="path5453" stroke="#000" stroke-width="3" d="M25.624 5.699H6.669"/><path id="path5455" fill="#000" d="M10.649 11.043V.356L.666 5.7z"/><path id="path5457" stroke="#000" stroke-width="3" d="M.666.356v10.687"/></g><g id="g5464" transform="rotate(-180 18.01 35.275)"><path id="path5466" stroke="#000" stroke-width="3" d="M25.624 5.699H6.669"/><path id="path5468" fill="#000" d="M10.649 11.043V.356L.666 5.7z"/><path id="path5470" stroke="#000" stroke-width="3" d="M.666.356v10.687"/></g><path id="text5474" fill="#000" fill-rule="nonzero" d="M71.803 52.199l-1.188-1.172 1.264-1.326 1.219 1.203c.162-.309.286-.66.373-1.056a6.08 6.08 0 00.13-1.296c0-1.248-.278-2.217-.83-2.906-.554-.694-1.329-1.04-2.324-1.04-.985 0-1.751.344-2.3 1.032-.548.689-.822 1.66-.822 2.914 0 1.25.274 2.22.822 2.915.549.688 1.315 1.033 2.3 1.033.254 0 .493-.026.716-.077a2.86 2.86 0 00.64-.224m1.622 1.55c-.38.257-.825.452-1.333.585a6.39 6.39 0 01-1.645.2c-1.675 0-3.008-.539-3.998-1.618-.985-1.08-1.477-2.534-1.477-4.364 0-1.834.492-3.289 1.477-4.363.99-1.08 2.323-1.62 3.998-1.62 1.676 0 3.008.54 3.999 1.62.995 1.08 1.492 2.534 1.492 4.363 0 .802-.101 1.537-.304 2.205a5.234 5.234 0 01-.9 1.743l1.22 1.18-1.25 1.325-1.279-1.256"/><path id="text5482" fill="#000" fill-rule="nonzero" d="M105.05 55.005l-3.14-11.399h2.337l1.876 8.04 1.585-8.04h2.404l1.585 8.04 1.875-8.04h2.315l-3.133 11.4h-2.151l-1.697-8.73-1.704 8.73h-2.151"/><path id="text5492" fill="#000" fill-rule="nonzero" d="M144.839 55.005V43.606h8.692v1.981h-6.261v2.43h5.724v1.95h-5.724V52.9h6.554v2.105h-8.985"/><path id="text5500" fill="#000" fill-rule="nonzero" d="M187.015 48.59h2.634c.573 0 .992-.121 1.259-.364.271-.242.407-.624.407-1.145 0-.495-.131-.87-.393-1.122-.261-.258-.65-.387-1.169-.387h-2.738v3.018m-2.243 6.415V43.606h5.284c1.19 0 2.07.266 2.643.797.572.532.858 1.344.858 2.438 0 .696-.14 1.277-.422 1.741a2.108 2.108 0 01-1.199.952c.474.175.81.444 1.007.805.202.36.318.923.348 1.687l.044 1.346v.047c.015.68.156 1.093.422 1.238v.348H191.3a2.318 2.318 0 01-.185-.588 6.4 6.4 0 01-.074-.843l-.03-1.2c-.024-.707-.153-1.184-.385-1.432-.227-.247-.639-.371-1.236-.371h-2.375v4.434h-2.243"/><path id="text5504" fill="#000" fill-rule="nonzero" d="M228.05 55.005v-9.364h-3.345v-2.035h8.986v2.035h-3.322v9.364h-2.319"/><path id="text5518" fill="#000" fill-rule="nonzero" d="M101.245 134.798H98.96v-4.249l-4.037-7.15h2.8l2.376 4.914 2.196-4.914h2.611l-3.66 7.15v4.249"/><path id="text5522" fill="#000" fill-rule="nonzero" d="M304.572 43.606h2.33v6.939c0 .856.173 1.482.518 1.877.345.39.894.586 1.645.586.761 0 1.315-.196 1.66-.586.35-.39.525-1.016.525-1.877v-6.939h2.307v7.187c0 1.356-.385 2.397-1.157 3.123-.767.726-1.873 1.09-3.32 1.09-1.457 0-2.574-.361-3.35-1.082-.772-.726-1.158-1.77-1.158-3.131v-7.187"/><path id="text5526" fill="#000" fill-rule="nonzero" d="M347.5 55.005V43.606h1.998v11.4H347.5"/><path id="text5530" fill="#000" fill-rule="nonzero" d="M384.8 48.788c0 1.298.274 2.307.823 3.028.549.716 1.316 1.074 2.303 1.074.996 0 1.772-.358 2.326-1.074.554-.72.831-1.73.831-3.028s-.277-2.305-.831-3.021c-.554-.721-1.33-1.082-2.326-1.082-.987 0-1.754.358-2.303 1.074-.55.716-.824 1.725-.824 3.029m-2.356 0c0-1.907.493-3.419 1.48-4.535.99-1.122 2.325-1.683 4.003-1.683s3.012.56 4.004 1.683c.996 1.121 1.494 2.633 1.494 4.535 0 1.901-.498 3.413-1.494 4.535-.992 1.121-2.326 1.682-4.004 1.682-1.678 0-3.013-.56-4.004-1.682-.986-1.122-1.48-2.634-1.48-4.535"/><path id="text5534" fill="#000" fill-rule="nonzero" d="M425.808 48.884h2.338c.633 0 1.093-.129 1.38-.387.288-.263.432-.684.432-1.261 0-.542-.141-.952-.423-1.23-.282-.28-.703-.419-1.261-.419h-2.466v3.297m-.016 2.066v4.055h-2.418V43.606h5.227c1.234 0 2.168.312 2.8.937.64.619.958 1.53.958 2.731 0 1.177-.31 2.085-.933 2.724-.623.635-1.511.952-2.665.952h-2.969"/><path id="path3102" fill="#00F" fill-rule="nonzero" d="M311.56 21.86v1.6c-.049 0-.118-.003-.206-.008a3.788 3.788 0 00-.182-.007c-.556 0-.933.1-1.131.298-.193.194-.29.608-.29 1.24v1.838c0 .755-.124 1.291-.371 1.608-.248.316-.694.543-1.339.68.645.139 1.09.363 1.339.675.247.311.371.844.371 1.6v1.845c0 .628.097 1.038.29 1.232.192.194.57.291 1.131.291.033 0 .094-.002.182-.007s.157-.008.207-.008v1.6c-.077 0-.185.003-.322.008-.138.005-.24.007-.306.007-.551 0-1.01-.03-1.38-.092a3.388 3.388 0 01-.942-.283 1.495 1.495 0 01-.67-.704c-.126-.291-.19-.799-.19-1.524V31.82c0-.7-.14-1.194-.42-1.485-.281-.296-.755-.444-1.422-.444-.033 0-.088.002-.165.007a2.87 2.87 0 01-.173.008v-1.6c.038 0 .096.003.173.008.077.005.132.007.165.007.661 0 1.132-.148 1.413-.444.287-.296.43-.796.43-1.5v-1.914c0-.73.063-1.243.19-1.539.132-.296.355-.53.67-.704.258-.128.572-.222.941-.284a8.644 8.644 0 011.686-.084c.137.005.245.008.322.008"/><path id="text5546" fill="#00F" fill-rule="nonzero" d="M347.5 22.88h3.994v1.62h-1.858v11.27h1.858v1.619h-3.993V22.88"/><path id="path3106" fill="#00F" fill-rule="nonzero" d="M425.371 21.845h.562c.606 0 1.093.03 1.462.092.37.06.678.158.926.29.314.164.534.4.66.706.133.301.199.807.199 1.517v1.932c0 .7.14 1.198.421 1.494.281.291.755.437 1.421.437.033 0 .088-.003.166-.008a2.88 2.88 0 01.173-.007v1.601h-.306c-.688 0-1.173.143-1.454.43-.28.286-.421.781-.421 1.486v1.932c0 .73-.066 1.244-.198 1.54a1.381 1.381 0 01-.661.69 3.386 3.386 0 01-.942.283 8.634 8.634 0 01-1.686.085 9.241 9.241 0 00-.322-.008v-1.602c.05 0 .118.003.207.008.088.005.148.008.181.008.557 0 .931-.1 1.124-.3.198-.193.297-.602.297-1.226v-1.831c0-.767.124-1.306.372-1.617.248-.317.694-.542 1.339-.675-.645-.138-1.09-.365-1.339-.682-.248-.317-.372-.853-.372-1.61v-1.854c0-.623-.099-1.032-.297-1.226-.193-.2-.567-.299-1.124-.299-.033 0-.093.003-.181.008a3.778 3.778 0 01-.207.007v-1.601"/><path id="text5554" fill="#00F" fill-rule="nonzero" d="M390.43 22.88V37.39h-3.994v-1.62h1.862V24.5h-1.862v-1.618h3.993"/><path id="text5641" fill="#000" fill-rule="nonzero" d="M79.428 86.304l-1.594 4.852h3.196l-1.602-4.852m-1.376-2.283h2.736l4.15 11.399h-2.485l-.782-2.345h-4.463l-.758 2.345h-2.493l4.095-11.4"/><path id="text5645" fill="#000" fill-rule="nonzero" d="M114.889 92.487h2.242c.085.645.333 1.126.743 1.44.41.31 1.002.464 1.777.464.66 0 1.158-.125 1.493-.376.335-.25.502-.621.502-1.112 0-.715-.962-1.307-2.887-1.776a6.848 6.848 0 01-.3-.072c-1.03-.24-1.765-.51-2.205-.809a2.56 2.56 0 01-.893-1.072c-.205-.453-.307-.987-.307-1.6 0-1.147.365-2.025 1.095-2.633.73-.614 1.785-.92 3.165-.92 1.29 0 2.297.325 3.022.976.73.65 1.115 1.568 1.155 2.753h-2.182c-.04-.571-.245-1.006-.615-1.305-.37-.298-.898-.448-1.583-.448-.595 0-1.055.126-1.38.376-.32.246-.48.598-.48 1.057 0 .624.628 1.09 1.883 1.4l.795.2c.805.219 1.375.39 1.71.512.34.123.635.259.885.408.45.267.787.622 1.012 1.065.225.437.338.962.338 1.576 0 1.227-.388 2.18-1.163 2.857-.775.672-1.867 1.008-3.277 1.008-1.39 0-2.48-.344-3.27-1.032-.79-.688-1.215-1.667-1.275-2.937"/><path id="text5649" fill="#000" fill-rule="nonzero" d="M156.959 93.361h1.748c1.012 0 1.743-.284 2.194-.851.455-.573.683-1.499.683-2.778 0-1.274-.21-2.21-.633-2.81-.422-.598-1.081-.897-1.978-.897h-2.014v7.336m-2.137 2.059v-11.4h4.15c1.627 0 2.838.473 3.634 1.417.8.944 1.201 2.376 1.201 4.295 0 1.042-.149 1.96-.446 2.755-.293.794-.72 1.434-1.28 1.919a3.9 3.9 0 01-1.44.782c-.536.154-1.29.232-2.258.232h-3.561"/><path id="text5653" fill="#000" fill-rule="nonzero" d="M194.755 95.42v-11.4h7.987v1.982h-5.664v2.584h4.965v1.982h-4.965v4.852h-2.323"/><path id="text5657" fill="#000" fill-rule="nonzero" d="M241.917 94.733c-.4.593-.856 1.029-1.368 1.306-.508.278-1.106.417-1.794.417-1.507 0-2.73-.572-3.667-1.715-.931-1.148-1.397-2.654-1.397-4.519 0-1.88.466-3.384 1.397-4.51.932-1.128 2.174-1.691 3.726-1.691 1.352 0 2.454.355 3.308 1.065.854.705 1.362 1.678 1.523 2.917h-2.262c-.137-.614-.417-1.082-.842-1.402-.42-.32-.968-.481-1.647-.481-.902 0-1.612.363-2.13 1.09-.512.72-.768 1.72-.768 2.996 0 1.282.268 2.286.805 3.013.537.726 1.274 1.09 2.21 1.09.703 0 1.291-.227 1.764-.681.474-.454.767-1.077.879-1.867h-2.445v-2.02h4.465v6.386h-1.486l-.27-1.394"/><path id="text5661" fill="#000" fill-rule="nonzero" d="M274.622 95.42v-11.4h2.25v4.25h4.485v-4.25h2.25v11.4h-2.25v-5.054h-4.485v5.054h-2.25"/><path id="text5665" fill="#000" fill-rule="nonzero" d="M314.556 90.978h2.484v1.34c0 .386.13.682.39.888.26.2.633.301 1.12.301.53 0 .9-.123 1.11-.369.209-.246.313-.707.313-1.385v-7.732h2.57v7.837c0 .703-.049 1.22-.145 1.551a2.23 2.23 0 01-.458.866c-.327.372-.777.655-1.348.851-.57.196-1.24.294-2.009.294-.707 0-1.331-.086-1.874-.256-.542-.171-.995-.424-1.356-.76a2.392 2.392 0 01-.62-.904c-.118-.337-.177-.889-.177-1.657v-.865"/><path id="text5669" fill="#000" fill-rule="nonzero" d="M353.49 95.42v-11.4h2.31v4.683l4.382-4.682h2.888l-4.48 4.612 4.884 6.787h-2.82l-3.658-5.216-1.196 1.207v4.009h-2.31"/><path id="text5673" fill="#000" fill-rule="nonzero" d="M394.423 95.42v-11.4h2.368v9.295h5.618v2.105h-7.986"/><path id="text5679" fill="#000" fill-rule="nonzero" d="M264.639 55.005v-1.98l6.156-7.353h-6.033v-2.066h8.862v1.981l-6.172 7.36h6.034v2.058h-8.847"/><path id="text5683" fill="#000" fill-rule="nonzero" d="M134.855 134.798l3.55-5.82-3.55-5.579h2.684l2.308 3.985 2.293-3.985h2.699l-3.55 5.564 3.55 5.835h-2.684l-2.308-3.947-2.308 3.947h-2.684"/><path id="text5687" fill="#000" fill-rule="nonzero" d="M184.772 131.451c-.084 1.341-.564 2.407-1.441 3.197-.872.79-2.01 1.186-3.417 1.186-1.62 0-2.88-.545-3.78-1.634-.897-1.09-1.345-2.618-1.345-4.583 0-2.009.458-3.547 1.374-4.616.916-1.068 2.233-1.602 3.952-1.602 1.396 0 2.498.369 3.305 1.106.812.731 1.258 1.768 1.337 3.108h-2.22c-.095-.667-.347-1.175-.758-1.522-.412-.352-.966-.529-1.664-.529-.99 0-1.743.345-2.259 1.034-.515.689-.772 1.696-.772 3.02 0 1.283.255 2.273.765 2.973.515.7 1.246 1.05 2.191 1.05.684 0 1.243-.187 1.68-.561.435-.38.717-.921.846-1.627h2.206"/><path id="text5691" fill="#000" fill-rule="nonzero" d="M217.625 134.798l-3.901-11.399h2.58l2.404 8.528 2.45-8.528h2.55l-3.856 11.399h-2.227"/><path id="text5695" fill="#000" fill-rule="nonzero" d="M256.813 132.74h2.67c.63 0 1.088-.12 1.376-.357.287-.237.431-.61.431-1.122 0-.531-.141-.913-.424-1.145-.282-.237-.749-.356-1.398-.356h-2.655v2.98m0-4.93h2.573c.555 0 .962-.098 1.22-.294.258-.201.387-.516.387-.944 0-.418-.127-.72-.38-.906-.248-.19-.662-.286-1.242-.286h-2.558v2.43m-2.157 6.988v-11.399h5.161c1.121 0 1.974.248 2.56.743.59.49.884 1.205.884 2.143 0 .578-.109 1.06-.327 1.448a2.183 2.183 0 01-.982.897c.565.238.987.58 1.265 1.03.282.443.424.998.424 1.663 0 1.11-.348 1.966-1.042 2.57-.694.603-1.678.905-2.953.905h-4.99"/><path id="text5699" fill="#000" fill-rule="nonzero" d="M294.589 134.798v-11.399h2.346l4.426 7.831V123.4h2.213v11.399h-2.317l-4.455-7.832v7.832h-2.213"/><path id="text5703" fill="#000" fill-rule="nonzero" d="M333.524 134.798v-11.399h3.324l2.174 8.675 2.145-8.675h3.339v11.399h-2.107v-9.194l-2.22 9.194h-2.3l-2.248-9.194v9.194h-2.107"/><g id="g3476" transform="translate(561.145 70.55)"><path id="path5745" fill="#000" d="M10.246 14.192V4.731L0 9.46z"/><path id="path5747" stroke="#000" stroke-width="3" d="M25.615 0v9.462H5.123"/></g><path id="path5757" stroke="#000" stroke-width="2" d="M18.55 130.653l-7.488 9.672h4.991v4.836h4.992v-4.836h4.992z"/><path id="path5801" stroke="#000" stroke-width="2" d="M501.744 130.653l-7.488 9.672h4.992v4.836h4.992v-4.836h4.991z"/><path id="path3083" fill="#000" fill-rule="nonzero" d="M447.271 12.398c0-.055-.002-.128-.008-.219a4.189 4.189 0 01-.008-.21c0-.443.051-.81.153-1.102.101-.297.264-.574.488-.83.171-.191.425-.41.761-.656.342-.247.564-.425.665-.536.214-.226.36-.43.44-.611.08-.181.12-.38.12-.596 0-.478-.14-.85-.424-1.117-.283-.266-.678-.4-1.185-.4-.508 0-.908.161-1.202.483-.288.317-.446.765-.473 1.343h-2.259v-.234c0-1.06.356-1.906 1.066-2.534.715-.634 1.677-.951 2.884-.951 1.233 0 2.213.3 2.94.898.731.593 1.097 1.39 1.097 2.391 0 .352-.043.67-.128.95-.08.277-.206.531-.377.763-.219.291-.558.608-1.017.95-.454.337-.729.546-.825.626-.203.186-.35.383-.44.589a1.927 1.927 0 00-.12.867c.005.06.007.106.007.136h-2.155m-.112 3.229v-2.21h2.363v2.21h-2.363"/><path id="text5819" fill="#000" fill-rule="nonzero" d="M286.602 17.7l3.912-13.472h1.08l-3.927 13.471h-1.065"/><path id="text5928" fill="#00F" fill-rule="nonzero" d="M173.79 71.348c-.084 1.34-.564 2.406-1.44 3.197-.872.79-2.011 1.186-3.418 1.186-1.619 0-2.88-.545-3.78-1.635-.897-1.09-1.345-2.617-1.345-4.583 0-2.008.458-3.547 1.374-4.615.916-1.068 2.234-1.603 3.952-1.603 1.396 0 2.498.369 3.305 1.106.813.732 1.258 1.768 1.337 3.109h-2.22c-.095-.668-.347-1.175-.758-1.522-.411-.353-.966-.53-1.664-.53-.99 0-1.743.345-2.258 1.034-.515.69-.773 1.696-.773 3.021 0 1.282.255 2.273.765 2.973.515.7 1.246 1.05 2.192 1.05.683 0 1.243-.188 1.678-.562.436-.379.718-.921.847-1.626h2.206"/><path id="text5956" fill="#00F" fill-rule="nonzero" d="M161.288 70.602h7.481l-.475.983h-7.482l.476-.983m1.027-2.125h7.482l-.476.983h-7.481l.475-.983"/><path id="path3060" fill="#000" fill-rule="nonzero" d="M246.307 31.467c0 .634.177 1.136.53 1.507.36.371.846.557 1.46.557.573 0 1.022-.18 1.347-.541.324-.36.486-.863.486-1.507 0-.593-.168-1.054-.504-1.383-.336-.33-.808-.495-1.416-.495-.597 0-1.063.165-1.4.495-.335.33-.503.785-.503 1.367m-.035-2.89c.284-.257.626-.45 1.025-.58.4-.133.846-.2 1.339-.2 1.216 0 2.19.33 2.92.989.735.66 1.103 1.538 1.103 2.635 0 1.164-.4 2.105-1.2 2.82-.799.717-1.853 1.075-3.162 1.075-1.512 0-2.662-.464-3.45-1.391-.782-.927-1.173-2.285-1.173-4.073 0-1.921.42-3.39 1.26-4.405.84-1.02 2.05-1.53 3.632-1.53 1.1 0 1.987.255 2.66.765.677.51 1.048 1.2 1.111 2.071h-2.52c-.058-.355-.214-.623-.469-.803-.255-.18-.611-.27-1.069-.27-.625 0-1.106.241-1.442.726-.336.479-.524 1.203-.565 2.171"/><path id="rect10188" fill="#FFF" stroke="#000" d="M508.233 79.876h39.933v39.378h-39.933z"/><path id="path2917" fill="#00F" fill-rule="nonzero" d="M532.193 69.513v1.784c-.512.383-.997.665-1.455.848a3.66 3.66 0 01-1.344.267c-.226 0-.452-.022-.679-.065a4.552 4.552 0 01-.68-.186 22.53 22.53 0 01-.524-.201c-1.078-.404-1.897-.606-2.458-.606-.419 0-.857.102-1.315.307-.453.199-.962.52-1.528.96v-1.784c.526-.387 1.029-.675 1.506-.864.478-.194.928-.29 1.351-.29.576 0 1.293.156 2.15.468a.111.111 0 00.029.008c.088.032.224.083.406.153.763.296 1.354.444 1.772.444.418 0 .85-.1 1.292-.298.443-.2.935-.514 1.477-.945"/><path id="path2915" fill="#000" fill-rule="nonzero" d="M517.137 108.474l-.651 1.887h1.856l.636-1.887h-1.841m0-4.764h1.634l-1.08 3.21h1.79l1.094-3.21h1.635l-1.095 3.21h2.093l-.547 1.554h-2.07l-.622 1.871h2.145l-.526 1.547h-2.152l-1.094 3.217h-1.634l1.094-3.217h-1.804l-1.102 3.217h-1.627l1.08-3.217h-2.123l.562-1.547h2.086l.636-1.871h-2.211l.547-1.555h2.196l1.095-3.21"/><path id="rect10196" fill="#FFF" stroke="#000" d="M49.997 119.254H89.93v39.378H49.997z"/><path id="text5910" fill="#00F" fill-rule="nonzero" d="M106.902 31.171c.018-.655.181-1.209.49-1.661.316-.452.87-.91 1.661-1.373l.473-.262c1.101-.594 1.652-1.167 1.652-1.72 0-.323-.11-.577-.33-.763-.22-.187-.524-.28-.911-.28-.428 0-.759.116-.99.347-.233.226-.349.551-.349.975v.068h-1.553c0-.83.259-1.47.776-1.915.518-.447 1.259-.67 2.223-.67.869 0 1.56.203 2.071.61.518.401.777.938.777 1.61 0 .486-.134.904-.402 1.255-.268.35-.791.754-1.571 1.211-.173.108-.417.249-.732.424-.714.395-1.116.706-1.205.932h3.838v1.212h-5.918"/><path id="text5922" fill="#00F" fill-rule="nonzero" d="M146.835 29.844h1.603c.012.4.127.7.344.898.217.197.543.296.978.296.417 0 .74-.093.969-.28.229-.187.343-.453.343-.799 0-.35-.132-.614-.396-.79-.264-.181-.66-.272-1.19-.272h-.255v-.98h.185c.488 0 .846-.076 1.075-.23.235-.16.352-.4.352-.725 0-.274-.1-.49-.3-.65-.199-.165-.466-.247-.8-.247-.37 0-.656.093-.855.28-.2.181-.3.442-.3.782v.05h-1.568c.018-.72.265-1.269.74-1.647.482-.385 1.166-.577 2.053-.577.834 0 1.491.17 1.973.51.487.341.731.805.731 1.392 0 .308-.085.58-.255.815-.165.231-.412.42-.74.569.428.159.751.381.969.667.223.28.334.609.334.988 0 .713-.276 1.279-.828 1.696-.546.411-1.292.617-2.237.617-.934 0-1.656-.203-2.167-.609-.505-.406-.758-.98-.758-1.72v-.034"/><path id="path3131" fill="#000" fill-rule="nonzero" d="M131.142 12.276c.232-.12.406-.254.522-.4a.747.747 0 00.174-.472.728.728 0 00-.2-.519c-.133-.147-.409-.317-.826-.51l-2.306-1.078c-.226.121-.4.257-.522.41a.789.789 0 00-.174.486c0 .205.084.386.253.543.174.152.554.364 1.14.636l1.94.904m-4.733 2.57h2.149c.046.41.18.713.4.912.226.2.545.299.957.299.383 0 .687-.081.913-.244a.799.799 0 00.34-.676c0-.23-.085-.43-.253-.597-.168-.173-.501-.37-1-.59l-2.08-.95c-.66-.3-1.154-.642-1.479-1.03a1.98 1.98 0 01-.487-1.305c0-.466.125-.875.374-1.226.256-.356.63-.652 1.123-.888a2.377 2.377 0 01-.644-.77 2.09 2.09 0 01-.209-.936c0-.786.299-1.417.896-1.894.598-.482 1.392-.723 2.384-.723 1.02 0 1.821.236 2.401.707.58.472.879 1.124.896 1.957h-2.053c-.012-.35-.128-.618-.348-.801-.215-.184-.525-.275-.93-.275-.36 0-.639.07-.836.212a.7.7 0 00-.287.597c0 .21.113.406.34.59.231.178.646.393 1.243.644l1.462.613c.742.32 1.29.676 1.644 1.07.354.387.53.835.53 1.343 0 .477-.133.894-.4 1.25-.26.35-.637.623-1.13.817.336.267.588.564.757.888.168.325.252.682.252 1.07 0 .806-.32 1.472-.957 1.996-.638.529-1.459.793-2.462.793-1.102 0-1.95-.24-2.54-.723-.592-.482-.914-1.192-.966-2.13"/><path id="text6073" fill="#000" fill-rule="nonzero" d="M444.34 35.039v-8.34c0-.83.334-1.5 1.002-2.01.668-.514 1.559-.772 2.672-.772 1.135 0 2.023.25 2.665.75.642.5.963 1.187.963 2.062 0 .54-.095.983-.287 1.328-.186.345-.477.61-.87.795.611.235 1.07.58 1.375 1.035.31.455.466 1.014.466 1.68 0 1.12-.334 2.024-1.002 2.714-.668.69-1.544 1.035-2.626 1.035-.15 0-.319-.007-.505-.022a10.34 10.34 0 01-.59-.068v-1.755a2.769 2.769 0 00.52.03c.611 0 1.083-.162 1.414-.487.331-.33.497-.798.497-1.403 0-.585-.181-1.03-.544-1.334-.357-.305-.88-.458-1.569-.458h-.21l.008-1.537.101.015h.163c.461 0 .81-.11 1.049-.33.243-.225.365-.55.365-.975 0-.425-.127-.748-.38-.968-.25-.225-.614-.337-1.096-.337-.445 0-.785.125-1.018.375-.233.245-.35.605-.35 1.08v7.897h-2.214"/><path id="path2750" fill="#000" fill-rule="nonzero" d="M417.384 129.151v-2.643h1.997v2.643h-1.997m0 6.683v-2.626h1.997v2.626h-1.997"/><path id="path2746" fill="#000" fill-rule="nonzero" d="M377.464 128.949v-2.441h1.984v2.44h-1.984m0 8.959v-.943c.37-.129.641-.327.817-.596.176-.268.264-.618.264-1.047v-.202h-1.094v-2.424h1.997v2.328c0 .805-.167 1.45-.501 1.933-.334.489-.828.806-1.483.95"/><path id="text5803" fill="#000" fill-rule="nonzero" d="M377.45 157.596v-.937c.37-.128.642-.326.818-.593.176-.267.264-.614.264-1.04v-.201h-1.081v-2.41h1.997v2.314c0 .795-.17 1.436-.508 1.922-.334.486-.83.8-1.49.945"/><path id="text5813" fill="#000" fill-rule="nonzero" d="M417.384 154.487v-2.072h1.997v2.072h-1.997"/><path id="path2737" fill="#000" fill-rule="nonzero" d="M63.973 145.16v1.75l-6.81 2.918 6.81 2.909v1.75l-8.985-3.876v-1.59l8.985-3.86"/><path id="path2742" fill="#000" fill-rule="nonzero" d="M54.988 125.472l8.985 3.86v1.59l-8.985 3.876v-1.75l6.827-2.91-6.827-2.916v-1.75"/><path id="text6003" fill="#000" fill-rule="nonzero" d="M477.764 86.458l-1.594 4.77h3.196l-1.602-4.77m-1.375-2.244h2.735l4.15 11.206h-2.485l-.782-2.305h-4.463l-.758 2.305h-2.493l4.096-11.206m1.868-1.43v-1.872h1.766v1.871h-1.766m-2.72 0v-1.871h1.766v1.871h-1.766"/><path id="text6023" fill="#000" fill-rule="nonzero" d="M464.306 43.7h2.33v6.881c0 .85.173 1.47.518 1.862.345.388.893.581 1.645.581.761 0 1.314-.193 1.66-.58.35-.388.525-1.009.525-1.863V43.7h2.307v7.127c0 1.346-.386 2.378-1.157 3.098-.767.72-1.873 1.08-3.32 1.08-1.457 0-2.574-.357-3.35-1.072-.772-.72-1.158-1.755-1.158-3.106V43.7m4.972-1.37v-1.833H471v1.833h-1.72m-2.65 0v-1.833h1.72v1.833h-1.72"/><path id="text6041" fill="#000" fill-rule="nonzero" d="M434.716 89.64c0 1.207.274 2.145.824 2.816.549.665 1.316.998 2.303.998.996 0 1.771-.333 2.326-.998.554-.67.83-1.61.83-2.816 0-1.206-.276-2.142-.83-2.807-.555-.67-1.33-1.006-2.326-1.006-.987 0-1.754.333-2.303.998-.55.666-.824 1.604-.824 2.815m-2.357 0c0-1.772.494-3.177 1.48-4.215.991-1.043 2.326-1.564 4.004-1.564 1.677 0 3.012.521 4.003 1.564.997 1.043 1.495 2.448 1.495 4.215 0 1.768-.498 3.173-1.495 4.216-.991 1.042-2.326 1.564-4.003 1.564-1.678 0-3.013-.522-4.004-1.564-.986-1.043-1.48-2.448-1.48-4.216m5.964-6.896v-1.832h1.724v1.832h-1.724m-2.654 0v-1.832h1.724v1.832h-1.724"/><path id="path2893" fill="#00F" fill-rule="nonzero" d="M90.991 73.43c-.274.422-.59.733-.949.934-.359.195-.782.293-1.27.293-.788 0-1.388-.215-1.802-.647-.408-.431-.613-1.069-.613-1.912 0-1.199.347-2.205 1.04-3.018.697-.812 1.554-1.219 2.57-1.219.4 0 .745.083 1.04.249.293.165.535.411.724.737l.397-.737h1.33l-1.099 4.5a1.757 1.757 0 00-.052.309c0 .175.06.308.18.399.119.085.296.128.53.128.194 0 .396-.05.605-.151.215-.1.414-.24.598-.421a3.96 3.96 0 00.972-1.408 4.545 4.545 0 00.336-1.768c0-1.205-.463-2.193-1.39-2.966-.922-.777-2.113-1.166-3.573-1.166a7.25 7.25 0 00-1.965.256 5.609 5.609 0 00-1.645.76 5.949 5.949 0 00-1.958 2.145 5.946 5.946 0 00-.68 2.822c0 1.54.516 2.772 1.547 3.695 1.032.918 2.41 1.378 4.133 1.378.808 0 1.595-.123 2.362-.37a7.857 7.857 0 002.153-1.068l.613.88a8.585 8.585 0 01-2.43 1.303 8.199 8.199 0 01-2.668.436c-.956 0-1.836-.123-2.638-.369a6.607 6.607 0 01-2.138-1.076c-.772-.607-1.35-1.307-1.734-2.1-.383-.792-.575-1.69-.575-2.694 0-.838.13-1.636.388-2.393a6.747 6.747 0 011.159-2.077 7.198 7.198 0 012.66-2.062c1.037-.467 2.19-.7 3.461-.7.842 0 1.632.115 2.37.346a6.101 6.101 0 011.935.963c.673.527 1.174 1.129 1.503 1.806.334.673.5 1.433.5 2.28 0 .829-.164 1.594-.493 2.296a4.984 4.984 0 01-1.405 1.791c-.349.281-.73.497-1.144.648a3.781 3.781 0 01-1.278.218c-.528 0-.926-.106-1.195-.316-.265-.211-.402-.522-.412-.933m.374-3.222c-.065-.406-.21-.715-.433-.925-.22-.216-.511-.324-.875-.324-.568 0-1.061.311-1.48.933-.418.622-.628 1.37-.628 2.243 0 .462.1.813.3 1.054.204.24.498.36.881.36.414 0 .79-.157 1.129-.473.344-.316.578-.728.703-1.234l.403-1.634"/><path id="path2898" fill="#00F" fill-rule="nonzero" d="M469.216 37.389l-3.912-13.472h1.065l3.927 13.472h-1.08"/><path id="path2919" fill="#000" fill-rule="nonzero" d="M516.22 82.984h1.996v5.182h-1.996v-5.182"/><path id="text6099" fill="red" fill-rule="nonzero" d="M490.263 22.88l-2.747 3.11h-1.246l1.729-3.11h2.264"/><path id="text5103" fill="red" fill-rule="nonzero" d="M485.271 3.192h2.265l1.729 3.109h-1.247l-2.747-3.11"/><path id="text6117" fill="#00F" fill-rule="nonzero" d="M356.42 146.197h2.083l-.548 3.24c-.072.398-.127.776-.166 1.133a8.3 8.3 0 00-.057.864c0 .462.1.808.302 1.036.202.224.51.335.922.335.48 0 .853-.203 1.117-.61.27-.408.493-1.13.67-2.169l.649-3.83h2.082l-1.39 8.137h-1.931l.13-.872c-.202.387-.428.67-.678.85a1.439 1.439 0 01-.872.267c-.322 0-.608-.074-.857-.223-.25-.144-.476-.37-.678-.678l-.648 3.919h-2.06l1.93-11.4"/><path id="path3396" fill="#00F" fill-rule="nonzero" d="M78.948 141.016h1.997v15.544h-1.997v-15.544"/><path id="path3403" fill="#000" fill-rule="nonzero" d="M9.564 5.327c-.4 0-.744.145-1.03.435-.28.29-.42.64-.42 1.048 0 .42.14.776.42 1.065.28.29.624.435 1.03.435.395 0 .733-.148 1.013-.443.28-.296.42-.648.42-1.057 0-.409-.14-.758-.42-1.048a1.358 1.358 0 00-1.013-.435m0-1.099c.692 0 1.28.256 1.763.767a2.54 2.54 0 01.733 1.832 2.53 2.53 0 01-.733 1.824 2.382 2.382 0 01-1.78.758 2.36 2.36 0 01-1.762-.75c-.478-.5-.717-1.11-.717-1.832 0-.721.242-1.335.725-1.84a2.373 2.373 0 011.771-.759"/><path id="text6091" fill="red" fill-rule="nonzero" d="M8.632 23.917h1.865l3.56 5.181h-1.74l-2.746-3.426-2.76 3.426H5.07l3.56-5.18"/><path id="path2585" stroke="#000" stroke-width="2" d="M18.55 109.927l7.487-9.671h-4.992V95.42h-4.992v4.836h-4.991z"/><text id="Strg" fill="#000" font-family="OpenSans-Regular, Open Sans" font-size="16" font-weight="normal"><tspan x="10.982" y="185.293">Strg</tspan></text><text id="tspan3451" fill="#000" font-family="OpenSans-Regular, Open Sans" font-size="16" font-weight="normal"><tspan x="553.078" y="185.293">Strg</tspan></text><g id="text3456" fill="#000" font-family="OpenSans-Regular, Open Sans" font-size="16" font-weight="normal" transform="translate(116.805 167.948)"><text id="tspan3460"><tspan x="0" y="17.345">Al</tspan> <tspan x="0" y="39.345">t</tspan></text></g><text id="tspan3466" fill="#00F" font-family="OpenSans-Regular, Open Sans" font-size="16" font-weight="normal"><tspan x="405.324" y="185.293">Alt Gr</tspan></text><text id="Win" fill="#000" font-family="OpenSans-Regular, Open Sans" font-size="16" font-weight="normal"><tspan x="64.892" y="185.293">Win</tspan></text><text id="Win" fill="#000" font-family="OpenSans-Regular, Open Sans" font-size="16" font-weight="normal"><tspan x="464.226" y="185.293">Win</tspan></text><text id="Menu" fill="#000" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal"><tspan x="499.171" y="185.293">Menu</tspan></text><circle id="Oval" cx="109.94" cy="138" r="26" stroke="#EE714E" stroke-width="5"/></g></g></g></g></svg>
\ No newline at end of file
diff --git a/2-ui/3-event-details/5-keyboard-events/us-layout.svg b/2-ui/3-event-details/5-keyboard-events/us-layout.svg
deleted file mode 100644
index 699277e02..000000000
--- a/2-ui/3-event-details/5-keyboard-events/us-layout.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="602" height="202" viewBox="0 0 602 202"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:&apos;PT Mono&apos;;font-weight:700;font-style:normal;src:local(&apos;PT MonoBold&apos;),url(/font/PTMonoBold.woff2) format(&apos;woff2&apos;),url(/font/PTMonoBold.woff) format(&apos;woff&apos;),url(/font/PTMonoBold.ttf) format(&apos;truetype&apos;)}</style></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="us-layout.svg"><g id="KB_United_States-NoAltGr" transform="translate(1 1)"><path id="rect2186" fill="#FFF" stroke="#000" d="M0 0h39.604v40H0z"/><path id="rect2218" fill="#FFF" stroke="#000" d="M40.594 0h39.604v40H40.594z"/><path id="rect2222" fill="#FFF" stroke="#000" d="M80.198 0h39.604v40H80.198z"/><path id="rect2228" fill="#FFF" stroke="#000" d="M119.802 0h39.604v40h-39.604z"/><path id="rect2230" fill="#FFF" stroke="#000" d="M160.396 0H200v40h-39.604z"/><path id="rect2232" fill="#FFF" stroke="#000" d="M200 0h39.604v40H200z"/><path id="rect2234" fill="#FFF" stroke="#000" d="M240.594 0h39.604v40h-39.604z"/><path id="rect2236" fill="#FFF" stroke="#000" d="M280.198 0h39.604v40h-39.604z"/><path id="rect2238" fill="#FFF" stroke="#000" d="M319.802 0h39.604v40h-39.604z"/><path id="rect2240" fill="#FFF" stroke="#000" d="M360.396 0H400v40h-39.604z"/><path id="rect2242" fill="#FFF" stroke="#000" d="M400 0h39.604v40H400z"/><path id="rect2244" fill="#FFF" stroke="#000" d="M440.594 0h39.604v40h-39.604z"/><path id="rect2246" fill="#FFF" stroke="#000" d="M480.198 0h39.604v40h-39.604z"/><path id="rect2248" fill="#DFDFDF" stroke="#000" d="M519.802 0H600v40h-80.198z"/><path id="rect2250" fill="#DFDFDF" stroke="#000" d="M0 40h60.396v40H0z"/><path id="rect2252" fill="#FFF" stroke="#000" d="M60.396 40H100v40H60.396z"/><path id="rect2254" fill="#FFF" stroke="#000" d="M100 40h39.604v40H100z"/><path id="rect2256" fill="#FFF" stroke="#000" d="M140.594 40h39.604v40h-39.604z"/><path id="rect2258" fill="#FFF" stroke="#000" d="M180.198 40h39.604v40h-39.604z"/><path id="rect2262" fill="#FFF" stroke="#000" d="M219.802 40h39.604v40h-39.604z"/><path id="rect2264" fill="#FFF" stroke="#000" d="M260.396 40H300v40h-39.604z"/><path id="rect2266" fill="#FFF" stroke="#000" d="M300 40h39.604v40H300z"/><path id="rect2270" fill="#FFF" stroke="#000" d="M340.594 40h39.604v40h-39.604z"/><path id="rect2272" fill="#FFF" stroke="#000" d="M380.198 40h39.604v40h-39.604z"/><path id="rect2274" fill="#FFF" stroke="#000" d="M419.802 40h39.604v40h-39.604z"/><path id="rect2278" fill="#FFF" stroke="#000" d="M460.396 40H500v40h-39.604z"/><path id="rect2280" fill="#FFF" stroke="#000" d="M500 40h39.604v40H500z"/><path id="rect2284" fill="#FFF" stroke="#000" d="M539.604 40H600v40h-60.396z"/><path id="rect2286" fill="#DFDFDF" stroke="#000" d="M0 80h70.297v40H0z"/><path id="rect2292" fill="#FFF" stroke="#000" d="M70.297 80h39.604v40H70.297z"/><path id="rect2296" fill="#FFF" stroke="#000" d="M109.901 80h39.604v40h-39.604z"/><path id="rect2298" fill="#FFF" stroke="#000" d="M150.495 80h39.604v40h-39.604z"/><path id="rect2300" fill="#FFF" stroke="#000" d="M190.099 80h39.604v40h-39.604z"/><path id="rect2302" fill="#FFF" stroke="#000" d="M230.693 80h39.604v40h-39.604z"/><path id="rect2306" fill="#FFF" stroke="#000" d="M270.297 80h39.604v40h-39.604z"/><path id="rect2308" fill="#FFF" stroke="#000" d="M309.901 80h39.604v40h-39.604z"/><path id="rect2312" fill="#FFF" stroke="#000" d="M350.495 80h39.604v40h-39.604z"/><path id="rect2314" fill="#FFF" stroke="#000" d="M390.099 80h39.604v40h-39.604z"/><path id="rect2316" fill="#FFF" stroke="#000" d="M430.693 80h39.604v40h-39.604z"/><path id="rect2318" fill="#FFF" stroke="#000" d="M470.297 80h39.604v40h-39.604z"/><path id="rect2320" fill="#DFDFDF" stroke="#000" d="M509.901 80H600v40h-90.099z"/><path id="rect2322" fill="#DFDFDF" stroke="#000" d="M0 120h90.099v40H0z"/><path id="rect2324" fill="#FFF" stroke="#000" d="M90.099 120h39.604v40H90.099z"/><path id="rect2326" fill="#FFF" stroke="#000" d="M130.693 120h39.604v40h-39.604z"/><path id="rect2330" fill="#FFF" stroke="#000" d="M170.297 120h39.604v40h-39.604z"/><path id="rect2334" fill="#FFF" stroke="#000" d="M209.901 120h39.604v40h-39.604z"/><path id="rect2336" fill="#FFF" stroke="#000" d="M250.495 120h39.604v40h-39.604z"/><path id="rect2338" fill="#FFF" stroke="#000" d="M290.099 120h39.604v40h-39.604z"/><path id="rect2340" fill="#FFF" stroke="#000" d="M330.693 120h39.604v40h-39.604z"/><path id="rect2342" fill="#FFF" stroke="#000" d="M370.297 120h39.604v40h-39.604z"/><path id="rect2344" fill="#FFF" stroke="#000" d="M409.901 120h39.604v40h-39.604z"/><path id="rect2346" fill="#FFF" stroke="#000" d="M450.495 120h39.604v40h-39.604z"/><path id="rect2348" fill="#DFDFDF" stroke="#000" d="M490.099 120H600v40H490.099z"/><path id="rect2350" fill="#DFDFDF" stroke="#000" d="M0 160h60.396v40H0z"/><path id="rect2352" fill="#DFDFDF" stroke="#000" d="M539.604 160H600v40h-60.396z"/><path id="rect2354" fill="#DFDFDF" stroke="#000" d="M100 160h60.396v40H100z"/><path id="rect2360" fill="#DFDFDF" stroke="#000" d="M400 160h60.396v40H400z"/><path id="rect2362" fill="#FFF" stroke="#000" d="M160.396 160H400v40H160.396z"/><path id="rect2364" fill="#EFEFEF" stroke="#000" d="M60.396 160H100v40H60.396z"/><path id="rect2366" fill="#EFEFEF" stroke="#000" d="M460.396 160H500v40h-39.604z"/><path id="rect2368" fill="#EFEFEF" stroke="#000" d="M500 160h39.604v40H500z"/><path id="text5091" fill="#000" fill-rule="nonzero" d="M50.238 12.434l-.619-5.26V4h2.444v3.174l-.62 5.26h-1.205m-.587 3.254v-2.341h2.356v2.34h-2.356M50.238 36v-7.768h-2.713v-1.595h.174c.99 0 1.709-.153 2.158-.46.455-.307.722-.82.801-1.54h1.817V36h-2.237"/><path id="text5103" fill="#000" fill-rule="nonzero" d="M15.842 9v1.75c-.559.376-1.088.653-1.587.832a4.387 4.387 0 01-1.466.262c-.248 0-.495-.021-.742-.063a5.413 5.413 0 01-.74-.183c-.13-.042-.32-.108-.573-.198-1.176-.396-2.07-.594-2.682-.594-.457 0-.935.1-1.434.301-.494.196-1.05.51-1.668.943V10.3a7.651 7.651 0 011.644-.848 4.307 4.307 0 011.474-.286c.628 0 1.41.154 2.344.46a.133.133 0 00.032.008c.097.031.245.082.443.15.833.29 1.477.436 1.934.436.456 0 .926-.098 1.41-.293.483-.196 1.02-.505 1.61-.927M8.037 23.069h2.078L11.701 26h-1.144l-2.521-2.931"/><path id="text5127" fill="#000" fill-rule="nonzero" d="M90.732 13.574c-.291.443-.628.77-1.009.982-.381.206-.831.309-1.35.309-.837 0-1.475-.227-1.914-.681-.434-.454-.651-1.125-.651-2.012 0-1.261.368-2.32 1.104-3.175.74-.855 1.652-1.283 2.732-1.283.423 0 .791.087 1.104.261.312.174.569.433.77.776l.42-.776h1.415l-1.168 4.736a1.833 1.833 0 00-.055.324c0 .185.063.325.19.42.127.09.315.135.564.135.206 0 .42-.053.643-.159.228-.105.44-.253.636-.443.455-.422.8-.916 1.032-1.48a4.741 4.741 0 00.358-1.862c0-1.267-.493-2.307-1.478-3.12-.98-.818-2.245-1.227-3.796-1.227-.747 0-1.443.09-2.089.269-.64.18-1.223.446-1.747.8-.9.602-1.594 1.354-2.08 2.257a6.207 6.207 0 00-.723 2.97c0 1.62.548 2.916 1.644 3.887 1.096.966 2.56 1.45 4.391 1.45a8.25 8.25 0 002.51-.389 8.382 8.382 0 002.287-1.124l.652.926a9.152 9.152 0 01-2.582 1.37 8.79 8.79 0 01-2.835.46c-1.016 0-1.95-.13-2.803-.388a7.047 7.047 0 01-2.272-1.133c-.82-.638-1.435-1.375-1.842-2.21-.408-.833-.612-1.778-.612-2.834 0-.882.138-1.721.413-2.518a7.08 7.08 0 011.231-2.186 7.64 7.64 0 012.828-2.17c1.1-.49 2.327-.736 3.677-.736.894 0 1.734.121 2.517.364.79.238 1.475.576 2.057 1.014.715.554 1.247 1.188 1.597 1.9.354.708.532 1.508.532 2.4 0 .87-.175 1.676-.524 2.415a5.252 5.252 0 01-1.494 1.885 4.054 4.054 0 01-2.573.91c-.561 0-.985-.11-1.27-.332-.281-.222-.427-.55-.437-.982m.397-3.39c-.069-.427-.223-.752-.46-.973-.234-.227-.544-.34-.93-.34-.604 0-1.128.326-1.573.981-.444.655-.667 1.441-.667 2.36 0 .486.106.855.318 1.108.217.254.53.38.937.38.44 0 .84-.166 1.2-.498.365-.333.614-.766.746-1.299l.429-1.718M85.37 36c.01-1.014.228-1.871.651-2.574.424-.707 1.176-1.422 2.256-2.146.164-.11.402-.264.714-.459 1.43-.913 2.145-1.792 2.145-2.637 0-.501-.151-.897-.453-1.188-.302-.29-.715-.435-1.239-.435-.572 0-1.014.18-1.326.538-.307.354-.46.86-.46 1.52v.096H85.56c0-1.299.35-2.3 1.049-3.002s1.694-1.053 2.986-1.053c1.17 0 2.105.32 2.804.958.698.634 1.048 1.479 1.048 2.534 0 .755-.183 1.41-.548 1.964-.365.555-1.072 1.185-2.12 1.893-.223.153-.53.354-.922.602-.995.639-1.557 1.124-1.684 1.457h5.163V36H85.37"/><path id="text5139" fill="#000" fill-rule="nonzero" d="M130.065 8.85l-.704 1.92h2.008l.688-1.92h-1.992m0-4.85h1.768l-1.168 3.267h1.936L133.785 4h1.769l-1.185 3.267h2.265l-.592 1.582h-2.24l-.673 1.905h2.32l-.568 1.575h-2.328l-1.184 3.274h-1.768l1.184-3.274h-1.952l-1.192 3.274h-1.76l1.168-3.274h-2.297l.609-1.575h2.256l.688-1.905h-2.392l.592-1.582h2.376L130.065 4m-3.552 28.245h2.2c.005.63.16 1.105.464 1.425.304.315.755.472 1.352.472.576 0 1.019-.147 1.328-.44.315-.3.472-.727.472-1.284 0-.556-.184-.976-.552-1.26-.363-.288-.904-.432-1.624-.432-.037 0-.096.002-.176.008-.075.005-.13.007-.168.007v-1.558h.248c.661 0 1.15-.126 1.464-.378.32-.257.48-.648.48-1.173 0-.436-.136-.78-.408-1.031-.267-.257-.632-.386-1.096-.386-.507 0-.899.147-1.176.44-.277.295-.416.712-.416 1.253v.094h-2.16c.026-1.155.37-2.039 1.032-2.653.667-.62 1.605-.929 2.816-.929 1.147 0 2.056.276 2.728.827.672.55 1.008 1.293 1.008 2.228 0 .493-.114.926-.344 1.298-.229.373-.573.68-1.032.921.587.252 1.03.601 1.328 1.047.304.441.456.969.456 1.583 0 1.128-.376 2.023-1.128 2.684-.752.661-1.778.992-3.08.992-1.285 0-2.278-.32-2.976-.96-.694-.646-1.04-1.562-1.04-2.748v-.047"/><path id="text5145" fill="#000" fill-rule="nonzero" d="M169.832 14.64c.412-.056.727-.21.944-.458.216-.25.324-.581.324-.996 0-.368-.103-.671-.31-.91-.2-.244-.52-.433-.958-.568v2.933m-.899-5.32V6.675c-.392.052-.692.192-.898.42-.207.223-.31.524-.31.902 0 .316.096.58.287.793.196.213.503.39.921.53m0 8.517v-1.494c-1.137-.072-1.988-.412-2.552-1.019-.564-.606-.846-1.483-.846-2.629h2.024c.025.56.15 1.004.377 1.33.232.322.564.527.997.615v-3.22c-1.168-.306-1.998-.706-2.492-1.198-.493-.493-.74-1.167-.74-2.023 0-.949.292-1.714.876-2.294.59-.581 1.375-.884 2.356-.91V4h.899v.996c.981.051 1.746.357 2.295.917.549.555.85 1.338.906 2.35h-2.054c-.035-.483-.148-.85-.34-1.105-.186-.26-.455-.404-.807-.436v2.832c1.243.399 2.119.855 2.627 1.369.509.513.763 1.19.763 2.03 0 .99-.297 1.781-.891 2.372-.589.591-1.422.936-2.5 1.035v1.478h-.898m1.02 14.04v-4.769l-2.938 4.768h2.938M169.907 36v-2.403h-4.56v-1.96l3.986-6.457h2.68v6.643h1.254v1.774h-1.253V36h-2.107"/><path id="text5151" fill="#000" fill-rule="nonzero" d="M213.66 12.728c0 .354.119.653.356.897.237.238.529.357.876.357.337 0 .627-.122.869-.365a1.23 1.23 0 00.363-.889c0-.339-.121-.627-.363-.865a1.166 1.166 0 00-.869-.365c-.347 0-.64.12-.876.357a1.173 1.173 0 00-.356.873m-1.713 0c0-.825.284-1.52.853-2.087.568-.566 1.266-.849 2.092-.849.81 0 1.5.289 2.07.865.573.571.86 1.262.86 2.071 0 .815-.287 1.513-.86 2.095a2.814 2.814 0 01-2.07.865c-.826 0-1.524-.286-2.092-.857-.569-.572-.853-1.273-.853-2.103m-4.588 2.96L214.103 4h1.27l-6.743 11.688h-1.271m-.695-8.728c0 .349.116.642.347.88.237.238.53.357.877.357.342 0 .632-.119.869-.357.242-.243.363-.537.363-.88 0-.339-.121-.627-.363-.865a1.166 1.166 0 00-.869-.365c-.347 0-.64.119-.877.357a1.187 1.187 0 00-.347.873m-1.714 0c0-.826.285-1.524.853-2.095.569-.577 1.264-.865 2.085-.865.81 0 1.5.29 2.069.873a2.85 2.85 0 01.86 2.087 2.85 2.85 0 01-.86 2.086 2.81 2.81 0 01-2.069.857c-.827 0-1.524-.283-2.093-.849-.563-.566-.845-1.264-.845-2.094m2.259 25.66h2.21c.038.497.204.883.498 1.158.295.27.69.405 1.185.405.61 0 1.076-.18 1.398-.54.326-.36.49-.875.49-1.547 0-.63-.167-1.124-.498-1.484-.332-.365-.79-.547-1.374-.547-.327 0-.614.066-.861.198a1.757 1.757 0 00-.632.587l-2.037-.119.734-6.093h6.5v1.92h-4.905l-.292 2.277c.248-.196.532-.341.853-.436.321-.1.68-.151 1.074-.151 1.127 0 2.035.344 2.724 1.031.695.688 1.043 1.59 1.043 2.706 0 1.222-.382 2.198-1.145 2.928-.764.725-1.788 1.087-3.072 1.087-1.169 0-2.1-.299-2.795-.897-.69-.603-1.056-1.43-1.098-2.483"/><path id="text5157" fill="#000" fill-rule="nonzero" d="M248.477 4h2.056l3.922 4.418h-1.916l-3.026-2.922-3.042 2.922h-1.917L248.477 4m-.685 28.078c0 .646.166 1.158.498 1.536.337.378.794.567 1.37.567.538 0 .96-.184 1.264-.552.305-.367.457-.88.457-1.535 0-.604-.158-1.074-.473-1.41-.316-.336-.759-.504-1.33-.504-.56 0-.997.168-1.313.504-.315.336-.473.8-.473 1.394m-.032-2.946a2.55 2.55 0 01.962-.59 3.652 3.652 0 011.256-.205c1.142 0 2.055.336 2.74 1.008.69.672 1.036 1.567 1.036 2.686 0 1.186-.375 2.144-1.125 2.874S250.889 36 249.659 36c-1.418 0-2.497-.473-3.237-1.418-.734-.945-1.1-2.328-1.1-4.15 0-1.959.393-3.455 1.182-4.49.788-1.04 1.924-1.559 3.409-1.559 1.033 0 1.865.26 2.495.78.637.52.984 1.223 1.044 2.11h-2.365c-.054-.362-.201-.635-.44-.819-.24-.183-.574-.275-1.003-.275-.588 0-1.039.246-1.354.74-.316.488-.492 1.226-.53 2.213"/><path id="text5163" fill="#000" fill-rule="nonzero" d="M288.584 10.586l-.571.436c-.23.17-.404.373-.519.611a1.815 1.815 0 00-.173.801c0 .45.146.828.436 1.135.29.307.654.46 1.09.46.321 0 .627-.069.917-.206.296-.143.57-.35.82-.619l-2-2.618m.602-2.5l.263-.198c.24-.175.418-.37.533-.587.116-.217.173-.466.173-.746 0-.27-.08-.484-.24-.643-.156-.158-.369-.238-.64-.238-.275 0-.493.082-.653.246-.16.159-.24.376-.24.65 0 .149.037.31.112.485.08.174.193.36.338.555l.354.476m-1.692 1.056l-.436-.603a3.832 3.832 0 01-.489-.89 2.72 2.72 0 01-.142-.88c0-.846.255-1.518.766-2.015.517-.503 1.216-.754 2.098-.754.847 0 1.516.23 2.007.69.491.46.737 1.082.737 1.865 0 .592-.145 1.124-.436 1.595-.286.465-.737.904-1.353 1.317l1.586 2.063c.15-.26.268-.55.353-.873a5.97 5.97 0 00.188-1.079h1.955a7.196 7.196 0 01-.406 1.912 6 6 0 01-.887 1.61l2.015 2.588h-2.557l-.751-.976a4.672 4.672 0 01-1.459.976 4.299 4.299 0 01-1.654.325c-1.022 0-1.86-.32-2.51-.96-.647-.64-.97-1.457-.97-2.452 0-.74.18-1.378.54-1.912.362-.534.963-1.05 1.805-1.547M289.742 36h-2.248c.08-1.55.434-3.087 1.06-4.61.632-1.523 1.531-3.02 2.699-4.49h-5.293v-1.937h7.631v1.706c-1.183 1.375-2.092 2.83-2.729 4.364-.631 1.534-1.005 3.19-1.12 4.967"/><path id="text5169" fill="#000" fill-rule="nonzero" d="M328.705 8.587l-1.353 1.948-1.308-.935 1.477-1.893-2.153-.612.5-1.595 2.068.754V4h1.523v2.254l2.068-.738.516 1.594-2.154.597 1.462 1.878-1.339.982-1.307-1.98m-1.722 23.823c0 .55.148.974.446 1.273.302.298.733.448 1.292.448.533 0 .95-.152 1.253-.456.308-.304.461-.725.461-1.265 0-.518-.156-.934-.469-1.248-.312-.315-.728-.472-1.245-.472-.518 0-.939.16-1.262.48-.317.319-.476.732-.476 1.24m.176-4.822c0 .434.134.77.4 1.005.267.23.649.346 1.146.346.497 0 .88-.118 1.146-.354.272-.235.408-.568.408-.997 0-.42-.139-.75-.416-.99-.277-.24-.656-.361-1.138-.361-.471 0-.848.123-1.13.369-.277.246-.416.573-.416.982m-.792 2.183c-.461-.262-.794-.568-1-.919-.204-.35-.307-.798-.307-1.343 0-.963.323-1.72.969-2.27.646-.55 1.538-.825 2.676-.825 1.149 0 2.046.275 2.692.825.65.545.976 1.301.976 2.27 0 .518-.11.969-.33 1.351-.22.377-.551.68-.992.911.538.257.943.613 1.215 1.068.271.45.407 1 .407 1.65 0 1.094-.353 1.953-1.061 2.576-.702.623-1.671.935-2.907.935-1.25 0-2.222-.309-2.914-.927-.692-.618-1.039-1.48-1.039-2.584 0-.644.129-1.183.385-1.618.261-.44.672-.807 1.23-1.1"/><path id="text5175" fill="#000" fill-rule="nonzero" d="M372.099 4a14.885 14.885 0 00-1.566 3.611 14.3 14.3 0 00-.512 3.855c0 1.34.17 2.622.512 3.847a14.884 14.884 0 001.566 3.611h-1.612c-.891-1.25-1.568-2.507-2.032-3.768-.458-1.267-.687-2.497-.687-3.69s.229-2.423.687-3.69c.464-1.266 1.14-2.525 2.032-3.776h1.612m-1.169 24.33c0-.644-.158-1.152-.474-1.523-.31-.377-.735-.566-1.275-.566-.51 0-.907.181-1.192.542-.28.361-.42.866-.42 1.515 0 .607.148 1.081.443 1.421.296.34.71.51 1.245.51.525 0 .935-.167 1.23-.502.295-.335.443-.8.443-1.397m.038 2.928a2.45 2.45 0 01-.901.589c-.346.13-.736.196-1.169.196-1.074 0-1.935-.332-2.581-.997-.647-.665-.97-1.554-.97-2.67 0-1.182.35-2.137 1.054-2.865.702-.727 1.63-1.091 2.78-1.091 1.334 0 2.347.474 3.04 1.421.698.942 1.046 2.319 1.046 4.13 0 1.947-.371 3.438-1.115 4.475-.743 1.036-1.813 1.554-3.208 1.554-.962 0-1.739-.256-2.33-.77-.59-.518-.914-1.221-.97-2.111l2.208.008c.05.36.188.63.412.808.224.178.54.267.947.267.55 0 .97-.246 1.26-.738.291-.492.456-1.227.497-2.206"/><path id="text5181" fill="#000" fill-rule="nonzero" d="M406.175 4h1.63c.888 1.247 1.561 2.504 2.02 3.772.46 1.263.69 2.497.69 3.701 0 1.2-.23 2.434-.69 3.702-.459 1.268-1.132 2.522-2.02 3.764h-1.63a14.864 14.864 0 001.576-3.623c.347-1.23.52-2.512.52-3.843 0-1.335-.173-2.616-.52-3.842A15.002 15.002 0 00406.175 4m1.048 26.224c0 1.367.133 2.36.398 2.978.27.619.7.928 1.286.928.587 0 1.015-.312 1.286-.936.27-.623.405-1.613.405-2.97 0-1.362-.135-2.352-.405-2.97-.27-.619-.7-.928-1.286-.928-.587 0-1.015.31-1.286.927-.265.613-.398 1.604-.398 2.971m-2.273 0c0-1.933.327-3.38.98-4.338.658-.964 1.65-1.446 2.977-1.446 1.321 0 2.311.485 2.97 1.454.663.964.994 2.412.994 4.346 0 1.933-.329 3.376-.987 4.33-.653.953-1.645 1.43-2.977 1.43-1.326 0-2.319-.48-2.977-1.438-.653-.959-.98-2.405-.98-4.338"/><path id="text5187" fill="#000" fill-rule="nonzero" d="M444.554 18h7.921v1.634h-7.92V18m1.786 15v-2.194h4.347V33h-4.347"/><path id="text5201" fill="#000" fill-rule="nonzero" d="M488.853 6h1.502v3.952h3.704v1.543h-3.704v3.967h-1.502v-3.967h-3.704V9.952h3.704V6m-3.704 25.458h8.91V33h-8.91v-1.542m0-3.333h8.91v1.543h-8.91v-1.543"/><path id="text5427" fill="#000" fill-rule="nonzero" d="M7.278 63.794v-6.402H4.95V56h6.253v1.392H8.892v6.402H7.278m8.037-.715c-.195.3-.45.53-.767.688a2.472 2.472 0 01-1.102.233c-.561 0-.995-.159-1.3-.476-.302-.318-.453-.77-.453-1.355 0-.543.151-.957.453-1.243.305-.286.808-.482 1.507-.587.16-.025.37-.053.629-.085.657-.085.985-.273.985-.566 0-.233-.073-.399-.218-.498-.146-.102-.389-.153-.73-.153-.312 0-.552.062-.719.185a.619.619 0 00-.25.53v.084H11.9v-.106c0-.589.21-1.051.629-1.386.419-.339.997-.508 1.736-.508.81 0 1.43.14 1.859.418.433.279.65.68.65 1.206v3.27c0 .24.024.42.074.54a.52.52 0 00.25.264v.26h-1.613a1.337 1.337 0 01-.123-.328 1.884 1.884 0 01-.048-.387m-.026-2.116c-.253.116-.544.21-.874.28-.327.07-.495.108-.506.111-.273.078-.465.175-.575.292-.107.116-.16.276-.16.481 0 .212.07.38.208.508.138.123.325.185.559.185.419 0 .747-.116.985-.35.242-.235.363-.556.363-.962v-.545M18.165 56h1.507v2.757c.192-.3.431-.526.719-.678.291-.155.621-.232.99-.232.7 0 1.272.287 1.716.862.443.571.665 1.316.665 2.233 0 .91-.222 1.645-.665 2.206-.444.561-1.023.841-1.737.841-.373 0-.697-.077-.974-.232-.274-.156-.522-.403-.746-.741v.778h-1.475V56m4.058 4.878c0-.529-.112-.943-.335-1.243a1.082 1.082 0 00-.922-.455c-.412 0-.731.148-.959.444-.223.293-.335.711-.335 1.254 0 .586.106 1.03.32 1.334.216.303.53.455.942.455.42 0 .739-.152.959-.455.22-.307.33-.752.33-1.334"/><path id="text5207" fill="#000" fill-rule="nonzero" d="M526.261 29.323h1.868c.44 0 .762-.08.963-.241.201-.16.302-.414.302-.76 0-.36-.1-.618-.297-.775-.198-.16-.524-.241-.978-.241h-1.858v2.017m0-3.337h1.8c.39 0 .674-.066.854-.2.18-.135.27-.348.27-.638 0-.283-.088-.487-.265-.613-.173-.13-.463-.194-.869-.194h-1.79v1.645m-1.509 4.73V23h3.611c.784 0 1.381.168 1.79.503.413.332.62.815.62 1.45 0 .392-.077.719-.23.98a1.51 1.51 0 01-.686.608c.395.16.69.393.884.697.198.3.297.676.297 1.126 0 .75-.243 1.33-.729 1.74-.485.408-1.174.612-2.065.612h-3.492m10.625-.707c-.19.297-.44.524-.75.68-.308.155-.667.231-1.076.231-.548 0-.971-.157-1.27-.471-.295-.314-.442-.761-.442-1.341 0-.538.147-.948.442-1.231.299-.283.79-.477 1.473-.582.156-.024.36-.052.614-.083.641-.084.962-.271.962-.56 0-.231-.07-.395-.213-.493-.142-.102-.38-.152-.713-.152-.305 0-.54.06-.702.183-.163.122-.245.297-.245.524v.084h-1.415v-.105c0-.583.205-1.04.614-1.372.41-.336.975-.503 1.696-.503.791 0 1.396.138 1.816.414.423.275.635.674.635 1.194v3.237c0 .238.024.416.073.534.048.116.13.203.244.262v.257h-1.576a1.334 1.334 0 01-.12-.325 1.89 1.89 0 01-.047-.382m-.026-2.095c-.246.115-.53.207-.853.277-.32.07-.484.107-.494.11-.268.077-.455.173-.562.288-.104.116-.156.274-.156.477 0 .21.067.377.202.503.136.122.318.183.547.183.41 0 .73-.115.962-.346.236-.233.354-.551.354-.953v-.54m6.197.655h1.493c-.062.723-.324 1.294-.785 1.713-.462.42-1.055.629-1.78.629-.822 0-1.467-.269-1.935-.807-.465-.541-.698-1.288-.698-2.242 0-.95.238-1.694.713-2.231.479-.542 1.136-.812 1.972-.812.732 0 1.318.195 1.759.586.444.392.692.936.744 1.635h-1.504c-.041-.304-.147-.536-.317-.697-.17-.16-.394-.24-.671-.24-.375 0-.656.148-.843.444-.184.297-.276.742-.276 1.336 0 .548.095.971.286 1.268a.94.94 0 00.833.44c.28 0 .506-.086.676-.257.17-.171.281-.426.333-.765m2.482 2.148V23h1.472v4.05l1.8-2.028h1.822l-1.972 2.111 2.091 3.583h-1.815l-1.353-2.425-.573.623v1.802h-1.472m5.562-1.854h1.509c.014.29.118.506.312.65.194.139.486.209.874.209.295 0 .522-.05.682-.147a.475.475 0 00.244-.424c0-.259-.301-.452-.905-.582a13.134 13.134 0 01-.588-.136c-.735-.188-1.247-.412-1.535-.67-.284-.259-.427-.608-.427-1.048 0-.583.209-1.044.625-1.383.42-.342.987-.513 1.701-.513.756 0 1.35.17 1.78.508.433.339.664.815.692 1.43h-1.473a.706.706 0 00-.276-.56c-.17-.133-.407-.2-.712-.2-.288 0-.503.044-.646.131a.434.434 0 00-.208.393c0 .227.377.428 1.13.603.173.038.31.07.41.094.753.178 1.267.393 1.54.644.278.252.417.606.417 1.064 0 .646-.227 1.138-.682 1.477-.45.339-1.108.508-1.972.508-.78 0-1.39-.176-1.831-.53-.44-.352-.661-.837-.661-1.455v-.063m10.14-.959c0-.573-.107-1.01-.322-1.31-.215-.303-.527-.455-.936-.455-.403 0-.71.15-.921.45-.208.3-.312.739-.312 1.315 0 .538.109.953.327 1.247.222.293.534.44.937.44.381 0 .681-.15.9-.45.219-.301.328-.713.328-1.237M555.768 33v-7.978h1.441v.77c.219-.335.462-.58.729-.733.27-.154.588-.23.952-.23.697 0 1.262.277 1.696.832.434.552.65 1.278.65 2.18 0 .91-.216 1.651-.65 2.22-.434.566-.992.849-1.675.849-.361 0-.684-.077-.968-.23a1.927 1.927 0 01-.702-.671V33h-1.473m9.745-2.991c-.19.297-.44.524-.749.68-.309.155-.668.231-1.077.231-.548 0-.971-.157-1.27-.471-.294-.314-.442-.761-.442-1.341 0-.538.148-.948.443-1.231.298-.283.789-.477 1.472-.582.156-.024.36-.052.614-.083.642-.084.963-.271.963-.56 0-.231-.072-.395-.214-.493-.142-.102-.38-.152-.713-.152-.305 0-.539.06-.702.183-.163.122-.245.297-.245.524v.084h-1.415v-.105c0-.583.205-1.04.614-1.372.41-.336.975-.503 1.696-.503.791 0 1.397.138 1.816.414.423.275.635.674.635 1.194v3.237c0 .238.024.416.073.534.048.116.13.203.244.262v.257h-1.576a1.334 1.334 0 01-.12-.325 1.89 1.89 0 01-.047-.382m-.026-2.095c-.246.115-.53.207-.853.277-.319.07-.484.107-.494.11-.267.077-.455.173-.562.288-.104.116-.156.274-.156.477 0 .21.067.377.203.503.135.122.317.183.546.183.41 0 .73-.115.963-.346.235-.233.353-.551.353-.953v-.54m6.197.655h1.494c-.063.723-.325 1.294-.786 1.713-.461.42-1.055.629-1.78.629-.822 0-1.467-.269-1.935-.807-.465-.541-.697-1.288-.697-2.242 0-.95.237-1.694.712-2.231.48-.542 1.136-.812 1.972-.812.732 0 1.319.195 1.76.586.443.392.691.936.743 1.635h-1.504c-.041-.304-.147-.536-.317-.697-.17-.16-.394-.24-.671-.24-.375 0-.656.148-.843.444-.184.297-.276.742-.276 1.336 0 .548.096.971.286 1.268a.94.94 0 00.833.44c.28 0 .506-.086.676-.257.17-.171.281-.426.333-.765m5.937.42h1.509c-.153.6-.461 1.072-.926 1.414-.462.339-1.025.508-1.691.508-.819 0-1.468-.276-1.946-.828-.479-.555-.718-1.306-.718-2.252 0-.933.236-1.668.707-2.206.472-.537 1.117-.806 1.936-.806.867 0 1.537.265 2.008.796.472.527.708 1.28.708 2.258a4.312 4.312 0 01-.016.398h-3.777c.02.447.128.784.322 1.01.198.228.48.341.849.341.26 0 .473-.05.64-.152.166-.104.298-.265.395-.482m-2.206-1.718h2.227c-.014-.384-.116-.675-.307-.875-.188-.202-.458-.303-.812-.303-.33 0-.59.1-.78.303-.188.203-.297.495-.328.875"/><path id="path5439" stroke="#000" stroke-width="3" d="M560.396 11.5h-28.713"/><path id="path5441" fill="#000" d="M534.653 17V7l-9.9 5z"/><g id="g5459" transform="translate(29.703 50)"><path id="path5453" stroke="#000" stroke-width="3" d="M25.401 5.5H6.611"/><path id="path5455" fill="#000" d="M10.556 10.656V.344L.66 5.5z"/><path id="path5457" stroke="#000" stroke-width="3" d="M.66.344v10.312"/></g><g id="g5464" transform="rotate(180 27.723 35.5)"><path id="path5466" stroke="#000" stroke-width="3" d="M25.401 5.5H6.611"/><path id="path5468" fill="#000" d="M10.556 10.656V.344L.66 5.5z"/><path id="path5470" stroke="#000" stroke-width="3" d="M.66.344v10.312"/></g><path id="text5474" fill="#000" fill-rule="nonzero" d="M71.131 54.066l-1.178-1.225 1.254-1.386 1.208 1.257c.161-.322.285-.69.37-1.104.086-.414.129-.865.129-1.354 0-1.305-.275-2.318-.824-3.038-.548-.726-1.316-1.088-2.303-1.088-.977 0-1.737.36-2.281 1.08-.544.72-.816 1.735-.816 3.046 0 1.306.272 2.321.816 3.047.544.72 1.304 1.08 2.28 1.08.253 0 .49-.027.71-.08a2.74 2.74 0 00.635-.235m1.609 1.62a4.191 4.191 0 01-1.322.613 6.03 6.03 0 01-1.631.21c-1.662 0-2.983-.565-3.965-1.693-.977-1.128-1.466-2.649-1.466-4.562 0-1.918.489-3.439 1.466-4.562.982-1.128 2.303-1.692 3.965-1.692 1.661 0 2.983.564 3.965 1.692.987 1.129 1.48 2.65 1.48 4.562a8.3 8.3 0 01-.302 2.305 5.583 5.583 0 01-.89 1.822l1.208 1.233L74.008 57l-1.268-1.314"/><path id="text5482" fill="#000" fill-rule="nonzero" d="M106.308 56l-3.338-12h2.483l1.993 8.464L109.131 44h2.554l1.684 8.464L115.362 44h2.46l-3.33 12h-2.285l-1.803-9.19-1.811 9.19h-2.285"/><path id="text5492" fill="#000" fill-rule="nonzero" d="M145.545 56V44h8.62v2.086h-6.21v2.558h5.678v2.053h-5.677v3.087h6.5V56h-8.911"/><path id="text5500" fill="#000" fill-rule="nonzero" d="M187.62 49.246h2.903c.63 0 1.093-.127 1.387-.382.299-.256.448-.658.448-1.206 0-.522-.144-.915-.432-1.181-.288-.272-.718-.408-1.289-.408h-3.017v3.177M185.149 56V44h5.823c1.31 0 2.28.28 2.911.84.63.559.946 1.414.946 2.565 0 .734-.155 1.344-.465 1.833a2.307 2.307 0 01-1.32 1.002c.521.185.89.467 1.108.848.223.38.351.972.384 1.776l.049 1.417v.049c.016.717.17 1.151.465 1.303V56h-2.708a2.362 2.362 0 01-.204-.62 6.444 6.444 0 01-.082-.887l-.032-1.263c-.027-.744-.169-1.246-.424-1.507-.25-.26-.704-.391-1.362-.391h-2.618V56h-2.471"/><path id="text5504" fill="#000" fill-rule="nonzero" d="M229.06 56v-9.857h-3.317V44h8.91v2.143h-3.294V56h-2.3"/><path id="text5518" fill="#000" fill-rule="nonzero" d="M271.618 56h-2.268v-4.473L265.347 44h2.776l2.357 5.173L272.658 44h2.59l-3.63 7.527V56"/><path id="text5522" fill="#000" fill-rule="nonzero" d="M305.94 44h2.311v7.304c0 .902.172 1.56.514 1.977.342.41.886.616 1.631.616.755 0 1.304-.205 1.646-.616.348-.411.521-1.07.521-1.977V44h2.288v7.565c0 1.428-.382 2.525-1.147 3.289-.76.764-1.858 1.146-3.293 1.146-1.445 0-2.552-.38-3.323-1.138-.765-.765-1.147-1.863-1.147-3.297V44"/><path id="text5526" fill="#000" fill-rule="nonzero" d="M349.505 56V44h1.98v12h-1.98"/><path id="text5530" fill="#000" fill-rule="nonzero" d="M386.495 50c0 1.253.273 2.227.817 2.923.545.69 1.306 1.036 2.284 1.036.989 0 1.758-.346 2.307-1.036.55-.696.825-1.67.825-2.923 0-1.253-.275-2.224-.825-2.915-.55-.696-1.318-1.044-2.307-1.044-.978 0-1.74.346-2.284 1.036-.544.691-.817 1.665-.817 2.923m-2.337 0c0-1.84.49-3.299 1.468-4.376.983-1.083 2.306-1.624 3.97-1.624 1.664 0 2.988.541 3.971 1.624.988 1.082 1.483 2.541 1.483 4.376 0 1.835-.495 3.294-1.483 4.376-.983 1.083-2.307 1.624-3.97 1.624-1.665 0-2.988-.541-3.971-1.624-.978-1.082-1.468-2.54-1.468-4.376"/><path id="text5534" fill="#000" fill-rule="nonzero" d="M428.156 49.556h2.319c.628 0 1.084-.136 1.37-.407.284-.277.426-.72.426-1.328 0-.57-.14-1.002-.419-1.296-.28-.293-.696-.44-1.25-.44h-2.446v3.471m-.016 2.175V56h-2.397V44h5.183c1.224 0 2.15.329 2.778.986.633.651.95 1.61.95 2.876 0 1.238-.31 2.194-.926 2.867-.618.668-1.499 1.002-2.644 1.002h-2.944"/><path id="text5546" fill="#000" fill-rule="nonzero" d="M473.267 43.016v1.634c-.049 0-.117-.002-.205-.008a3.648 3.648 0 00-.18-.007c-.552 0-.926.101-1.122.305-.192.198-.287.62-.287 1.267v1.877c0 .771-.123 1.319-.369 1.642-.246.324-.688.556-1.327.696.639.141 1.081.37 1.327.689.246.318.369.863.369 1.634v1.885c0 .642.095 1.061.287 1.26.19.198.565.297 1.122.297.033 0 .093-.003.18-.008.088-.005.156-.008.205-.008v1.635c-.076 0-.183.002-.32.007a8.326 8.326 0 01-1.672-.086 3.288 3.288 0 01-.933-.289 1.51 1.51 0 01-.664-.72c-.125-.297-.188-.816-.188-1.556v-1.97c0-.715-.14-1.221-.418-1.518-.279-.303-.748-.454-1.41-.454-.032 0-.087.003-.163.008a2.764 2.764 0 01-.172.008V49.6c.038 0 .095.003.172.008.076.005.13.008.164.008.655 0 1.122-.151 1.4-.454.285-.302.427-.813.427-1.533v-1.955c0-.746.063-1.27.188-1.572a1.51 1.51 0 01.664-.72c.257-.13.568-.227.934-.29a8.326 8.326 0 011.672-.085c.136.005.243.008.32.008m-4.302 20.053h4.137v1.666h-1.925v11.6h1.925V78h-4.137V63.07"/><path id="text5554" fill="#000" fill-rule="nonzero" d="M506.93 43h.558c.6 0 1.084.031 1.45.094.366.063.672.162.918.297.311.167.53.407.655.72.132.308.197.824.197 1.55v1.971c0 .715.14 1.224.418 1.526.279.297.748.446 1.41.446.032 0 .087-.003.163-.008.077-.005.134-.008.172-.008v1.636h-.303c-.683 0-1.163.146-1.442.438-.279.292-.418.798-.418 1.518v1.972c0 .746-.065 1.27-.197 1.573a1.393 1.393 0 01-.655.704c-.257.13-.568.227-.934.29a8.322 8.322 0 01-1.672.085 8.903 8.903 0 00-.32-.007V56.16c.05 0 .118.003.206.008.087.005.147.008.18.008.552 0 .923-.102 1.114-.305.197-.199.295-.616.295-1.252v-1.87c0-.783.123-1.333.369-1.651.246-.324.688-.553 1.327-.689-.639-.14-1.081-.373-1.327-.696-.246-.324-.369-.872-.369-1.644v-1.893c0-.637-.098-1.054-.295-1.252-.191-.204-.562-.305-1.114-.305-.033 0-.093.002-.18.008a3.64 3.64 0 01-.205.007V43m4.375 20.063V78h-4.146v-1.667h1.934V64.73h-1.934v-1.666h4.146"/><path id="text5564" fill="#000" fill-rule="nonzero" d="M549.198 42h1.611v16.137h-1.61V42m2.205 34l-3.88-13.403h1.057L552.475 76h-1.071"/><g id="g5770" fill="#000" font-family="OpenSans-Regular, Open Sans" font-size="13" font-weight="normal" transform="translate(2.97 83)"><g id="text5570" transform="translate(0 .166)"><text id="tspan5572"><tspan x=".102" y="14.34">Caps Lock</tspan></text></g></g><path id="text5641" fill="#000" fill-rule="nonzero" d="M79.684 86.403l-1.582 5.108h3.17l-1.588-5.108M78.319 84h2.713l4.117 12h-2.466l-.775-2.468h-4.426L76.73 96h-2.473l4.062-12"/><path id="text5645" fill="#000" fill-rule="nonzero" d="M115.842 92.17h2.224c.084.623.33 1.086.736 1.39.407.298.994.448 1.763.448.654 0 1.148-.121 1.48-.363.332-.242.498-.6.498-1.074 0-.69-.954-1.26-2.863-1.714a6.949 6.949 0 01-.298-.07c-1.021-.231-1.75-.491-2.187-.78a2.488 2.488 0 01-.885-1.034c-.203-.438-.305-.952-.305-1.544 0-1.107.362-1.954 1.086-2.541.724-.592 1.77-.888 3.14-.888 1.278 0 2.278.314 2.997.942.724.628 1.105 1.514 1.145 2.656h-2.164c-.04-.55-.243-.97-.61-1.258-.367-.289-.89-.433-1.57-.433-.59 0-1.046.121-1.368.363-.318.237-.476.577-.476 1.02 0 .602.622 1.052 1.867 1.35l.788.194c.798.211 1.364.376 1.696.494.337.119.63.25.878.394.446.257.78.6 1.004 1.027.223.422.334.93.334 1.521 0 1.184-.384 2.103-1.152 2.757-.769.649-1.853.973-3.25.973-1.38 0-2.46-.332-3.244-.996-.783-.664-1.205-1.609-1.264-2.834"/><path id="text5649" fill="#000" fill-rule="nonzero" d="M157.8 93.833h1.926c1.115 0 1.921-.299 2.418-.896.502-.603.753-1.578.753-2.925 0-1.341-.232-2.327-.698-2.957-.465-.63-1.191-.945-2.18-.945h-2.22v7.723M155.447 96V84h4.574c1.791 0 3.125.497 4.003 1.49.882.995 1.324 2.502 1.324 4.522 0 1.097-.164 2.064-.492 2.9-.322.837-.793 1.51-1.411 2.02-.465.381-.994.655-1.585.824-.592.163-1.422.244-2.49.244h-3.923"/><path id="text5653" fill="#000" fill-rule="nonzero" d="M196.04 96V84h7.92v2.086h-5.617v2.72h4.924v2.086h-4.924V96h-2.303"/><path id="text5657" fill="#000" fill-rule="nonzero" d="M243.628 94.338c-.436.572-.934.992-1.493 1.26-.554.268-1.206.402-1.956.402-1.645 0-2.978-.552-4-1.655-1.017-1.108-1.526-2.561-1.526-4.36 0-1.815.509-3.266 1.526-4.354 1.016-1.087 2.371-1.631 4.064-1.631 1.474 0 2.677.343 3.609 1.028.931.68 1.485 1.619 1.66 2.815h-2.467c-.149-.593-.455-1.044-.918-1.353-.458-.31-1.057-.464-1.796-.464-.985 0-1.76.35-2.324 1.051-.559.696-.838 1.66-.838 2.892 0 1.237.292 2.206.878 2.907.585.701 1.39 1.052 2.411 1.052.767 0 1.408-.22 1.925-.657.516-.439.835-1.039.958-1.802h-2.667v-1.948h4.87v6.162h-1.62l-.296-1.345"/><path id="text5661" fill="#000" fill-rule="nonzero" d="M275.248 96V84h2.479v4.473h4.942V84h2.48v12h-2.48v-5.32h-4.942V96h-2.48"/><path id="text5665" fill="#000" fill-rule="nonzero" d="M316.832 91.324h2.155v1.41c0 .407.113.72.339.936.225.211.55.317.971.317.461 0 .782-.13.964-.389.181-.259.272-.745.272-1.458V84h2.23v8.251c0 .74-.042 1.284-.126 1.633-.078.343-.21.647-.397.911-.284.391-.674.69-1.17.896-.495.206-1.076.309-1.744.309-.613 0-1.155-.09-1.626-.27a2.949 2.949 0 01-1.177-.8 2.594 2.594 0 01-.537-.951c-.103-.354-.154-.935-.154-1.744v-.911"/><path id="text5669" fill="#000" fill-rule="nonzero" d="M355.446 96V84h2.29v4.929L362.08 84h2.865l-4.444 4.855L365.347 96h-2.797l-3.628-5.49-1.186 1.27V96h-2.29"/><path id="text5673" fill="#000" fill-rule="nonzero" d="M396.04 96V84h2.348v9.784h5.572V96h-7.92"/><path id="text5679" fill="#000" fill-rule="nonzero" d="M96.04 136v-2.086l6.105-7.739h-5.983V124h8.788v2.086l-6.12 7.747h5.983V136H96.04"/><path id="text5683" fill="#000" fill-rule="nonzero" d="M134.653 136l3.521-6.126-3.52-5.874h2.661l2.289 4.196 2.274-4.196h2.676l-3.52 5.857 3.52 6.143h-2.661l-2.289-4.155-2.289 4.155h-2.662"/><path id="text5687" fill="#000" fill-rule="nonzero" d="M185.149 131.77c-.092 1.294-.616 2.323-1.573 3.086-.95.763-2.193 1.144-3.727 1.144-1.767 0-3.142-.526-4.125-1.577-.978-1.052-1.467-2.526-1.467-4.423 0-1.938.5-3.423 1.5-4.454.999-1.03 2.436-1.546 4.31-1.546 1.524 0 2.726.356 3.607 1.067.886.706 1.372 1.706 1.458 3h-2.423c-.102-.644-.378-1.134-.826-1.47-.449-.34-1.054-.51-1.815-.51-1.08 0-1.902.333-2.464.998s-.843 1.637-.843 2.915c0 1.237.279 2.193.835 2.869.562.675 1.359 1.012 2.39 1.012.746 0 1.357-.18 1.832-.54.475-.367.783-.89.924-1.57h2.407"/><path id="text5691" fill="#000" fill-rule="nonzero" d="M218.72 136l-3.869-12h2.56l2.383 8.978 2.43-8.978h2.528l-3.823 12h-2.209"/><path id="text5695" fill="#000" fill-rule="nonzero" d="M257.822 133.833h2.943c.694 0 1.2-.125 1.516-.375.317-.25.476-.643.476-1.181 0-.56-.156-.961-.468-1.206-.311-.25-.825-.374-1.54-.374h-2.927v3.136m0-5.19h2.836c.612 0 1.06-.103 1.344-.309.285-.212.427-.543.427-.994 0-.44-.14-.758-.418-.953-.274-.201-.73-.301-1.37-.301h-2.819v2.558M255.446 136v-12h5.688c1.235 0 2.174.26 2.82.782.65.516.975 1.268.975 2.257 0 .608-.12 1.116-.361 1.523-.24.407-.601.722-1.082.945.623.25 1.087.611 1.393 1.084.312.467.468 1.05.468 1.751 0 1.168-.383 2.07-1.148 2.705-.765.635-1.85.953-3.254.953h-5.5"/><path id="text5699" fill="#000" fill-rule="nonzero" d="M295.05 136v-12h2.585l4.877 8.244V124h2.438v12h-2.552l-4.91-8.244V136h-2.438"/><path id="text5703" fill="#000" fill-rule="nonzero" d="M333.663 136v-12h3.597l2.352 9.132 2.32-9.132h3.613v12h-2.28v-9.678l-2.4 9.678h-2.49l-2.432-9.678V136h-2.28"/><path id="text5725" fill="#000" fill-rule="nonzero" d="M438.614 89.363V87h1.98v2.363h-1.98m0 5.974v-2.348h1.98v2.348h-1.98m.013 13.99v-2.362h1.967v2.363h-1.967m0 8.672v-.912c.366-.125.636-.318.81-.578.175-.26.262-.597.262-1.013v-.195h-1.085v-2.348h1.98v2.254c0 .78-.166 1.404-.497 1.872-.33.473-.82.78-1.47.92"/><path id="text5731" fill="#000" fill-rule="nonzero" d="M480.71 85h1.468v4.301h-1.468V85m-2.492 0h1.468v4.301h-1.468V85m1.254 19.699h1.468V109h-1.468v-4.301"/><path id="text5737" fill="#000" fill-rule="nonzero" d="M514.851 93.804V86h5.524v1.356h-3.979v1.664h3.638v1.335h-3.638v2.008h4.165v1.441h-5.71m6.775 0v-5.759h1.472v.683c.21-.279.458-.487.744-.625.286-.141.605-.212.956-.212.62 0 1.084.166 1.39.498.31.329.465.825.465 1.49v3.925h-1.503v-3.48c0-.414-.07-.709-.207-.886-.134-.176-.355-.264-.662-.264-.354 0-.635.109-.842.328-.206.215-.31.51-.31.885v3.417h-1.503m8.82.042l-.496.016c-.19.01-.31.016-.362.016-.575 0-.97-.11-1.183-.328-.21-.223-.315-.66-.315-1.309v-3.115h-.744v-1.081h.744v-1.573h1.488v1.573h.868v1.08h-.868v3.19c0 .152.032.253.098.302.065.046.2.07.403.07h.367v1.16m4.335-1.791h1.499c-.152.607-.459 1.084-.92 1.43-.458.343-1.018.514-1.68.514-.813 0-1.457-.279-1.932-.837-.475-.562-.713-1.321-.713-2.278 0-.943.234-1.687.703-2.23.468-.545 1.109-.817 1.922-.817.861 0 1.526.269 1.994.806.469.533.703 1.294.703 2.283a4.44 4.44 0 01-.015.403h-3.752c.02.452.128.793.32 1.022.197.23.478.345.843.345.258 0 .47-.052.635-.154.166-.106.297-.268.393-.487m-2.19-1.738h2.21c-.013-.389-.115-.684-.304-.885-.186-.205-.455-.307-.806-.307-.327 0-.586.102-.775.307-.186.205-.295.5-.326.885m4.764 3.486v-5.759h1.395v.985c.197-.395.426-.685.688-.868.261-.188.573-.281.935-.281.058 0 .103.002.134.005.035 0 .062.002.083.005l.005 1.563h-.501c-.41 0-.718.11-.925.329-.207.219-.31.544-.31.975v3.046h-1.504"/><path id="path5745" fill="#000" d="M524.752 115v-10l-9.9 5z"/><path id="path5747" stroke="#000" stroke-width="3" d="M539.604 100v10h-19.802"/><g id="g5790" transform="translate(6.901 120)"><text id="tspan5755" fill="#000" font-family="OpenSans-Regular, Open Sans" font-size="16" font-weight="normal"><tspan x=".208" y="17.237">Shift</tspan></text><path id="path5757" stroke="#000" stroke-width="2" d="M8.16 19.535l-7.494 10h4.996v5h4.996v-5h4.996z"/></g><g id="g5795" transform="translate(495.05 127)"><g id="text5797" fill="#000" font-family="OpenSans-Regular, Open Sans" font-size="16" font-weight="normal" transform="translate(30.402)"><text id="tspan5799"><tspan x=".537" y="17.955">Shift</tspan></text></g><path id="path5801" stroke="#000" stroke-width="2" d="M7.55 10.628L0 20.58h5.033v4.976h5.034V20.58H15.1z"/></g><path id="text5803" fill="#000" fill-rule="nonzero" d="M384.158 126v1.71l-6.755 2.848 6.755 2.841v1.71l-8.91-3.786v-1.553l8.91-3.77m-5.605 32v-.913c.424-.125.736-.318.938-.578.202-.26.303-.598.303-1.014v-.195h-1.24v-2.35h2.291v2.256c0 .775-.194 1.4-.582 1.873-.384.474-.953.78-1.71.921"/><path id="text5813" fill="#000" fill-rule="nonzero" d="M415.842 127l8.91 3.731v1.538l-8.91 3.746v-1.692l6.77-2.812-6.77-2.82V127m3.305 29v-2.325h2.277V156h-2.277"/><path id="text5819" fill="#000" fill-rule="nonzero" d="M459.343 132.387c0-.056-.002-.131-.008-.224a4.45 4.45 0 01-.008-.217c0-.454.05-.831.151-1.13.101-.305.263-.59.485-.853.17-.196.421-.42.755-.673.339-.253.559-.437.66-.55.211-.233.357-.442.436-.628.08-.185.12-.39.12-.611 0-.49-.141-.873-.422-1.147-.28-.273-.672-.41-1.176-.41-.503 0-.9.165-1.191.496-.286.325-.442.784-.469 1.378h-2.24v-.24c0-1.09.352-1.957 1.056-2.602.71-.65 1.663-.976 2.86-.976 1.224 0 2.196.307 2.916.922.726.609 1.088 1.427 1.088 2.455 0 .361-.042.686-.127.976-.08.283-.204.544-.373.782-.217.3-.554.624-1.009.976-.45.345-.723.56-.818.642a1.828 1.828 0 00-.437.604 2.04 2.04 0 00-.12.891 1.8 1.8 0 01.008.14h-2.137m-.11 3.314v-2.269h2.343v2.27h-2.344M457.897 157l3.941-13.174h1.088L458.97 157h-1.073"/><path id="text5827" fill="#000" fill-rule="nonzero" d="M11.801 181.18c-.057.863-.387 1.549-.988 2.057-.599.509-1.38.763-2.345.763-1.112 0-1.976-.35-2.595-1.052-.615-.7-.923-1.683-.923-2.948 0-1.292.315-2.282.944-2.97.628-.686 1.532-1.03 2.711-1.03.959 0 1.715.237 2.269.711.557.471.863 1.138.917 2h-1.524c-.064-.43-.238-.756-.52-.979-.282-.227-.663-.34-1.142-.34-.68 0-1.196.221-1.55.665-.353.443-.53 1.09-.53 1.943 0 .825.176 1.462.526 1.912.353.45.854.676 1.503.676.47 0 .853-.12 1.152-.361.3-.244.493-.593.581-1.047h1.514m3.569 2.65c-.136.003-.3.008-.49.015-.187.01-.306.016-.357.016-.567 0-.956-.107-1.167-.32-.207-.216-.31-.64-.31-1.273v-3.03h-.735v-1.052h.734v-1.531h1.468v1.53h.857v1.052h-.857v3.103c0 .148.033.246.097.294.065.045.197.067.398.067h.362v1.129m.861-.041v-5.603h1.376v.958c.194-.385.42-.666.678-.845a1.56 1.56 0 01.923-.273c.058 0 .102.001.133.005.033 0 .06.002.081.005l.005 1.52h-.494c-.405 0-.709.107-.913.32-.204.213-.306.53-.306.949v2.964h-1.483m4.068 0v-7.593h1.483v7.593H20.3"/><path id="text5831" fill="#000" fill-rule="nonzero" d="M108.714 177.587l-1.097 3.373h2.2l-1.103-3.373m-.946-1.587h1.882l2.855 7.925h-1.71l-.538-1.63h-3.07l-.521 1.63h-1.716l2.818-7.925m5.468 7.925V176h1.565v7.925h-1.565m5.576.043a49.21 49.21 0 00-.516.016c-.197.01-.323.016-.377.016-.598 0-1.009-.111-1.231-.334-.219-.226-.328-.668-.328-1.328v-3.164h-.774v-1.097h.774v-1.598h1.549v1.598h.903v1.097h-.903v3.239c0 .154.034.256.102.307.068.046.208.07.42.07h.38v1.178"/><path id="text5835" fill="#000" fill-rule="nonzero" d="M408.714 177.587l-1.097 3.373h2.2l-1.103-3.373m-.946-1.587h1.882l2.855 7.925h-1.71l-.538-1.63h-3.07l-.521 1.63h-1.716l2.818-7.925m5.468 7.925V176h1.565v7.925h-1.565m5.576.043a49.21 49.21 0 00-.516.016c-.197.01-.323.016-.377.016-.598 0-1.009-.111-1.231-.334-.219-.226-.328-.668-.328-1.328v-3.164h-.774v-1.097h.774v-1.598h1.549v1.598h.903v1.097h-.903v3.239c0 .154.034.256.102.307.068.046.208.07.42.07h.38v1.178"/><path id="text5839" fill="#000" fill-rule="nonzero" d="M552.395 181.18c-.057.863-.387 1.549-.988 2.057-.599.509-1.38.763-2.345.763-1.111 0-1.976-.35-2.595-1.052-.615-.7-.922-1.683-.922-2.948 0-1.292.314-2.282.943-2.97.628-.686 1.532-1.03 2.711-1.03.959 0 1.715.237 2.269.711.557.471.863 1.138.917 2h-1.524c-.064-.43-.238-.756-.52-.979-.282-.227-.662-.34-1.142-.34-.68 0-1.196.221-1.55.665-.353.443-.53 1.09-.53 1.943 0 .825.176 1.462.526 1.912.353.45.854.676 1.503.676.47 0 .853-.12 1.152-.361.3-.244.493-.593.582-1.047h1.513m3.569 2.65c-.136.003-.3.008-.49.015-.187.01-.306.016-.356.016-.568 0-.957-.107-1.168-.32-.207-.216-.31-.64-.31-1.273v-3.03h-.735v-1.052h.734v-1.531h1.468v1.53h.857v1.052h-.857v3.103c0 .148.033.246.097.294.065.045.197.067.398.067h.362v1.129m.861-.041v-5.603h1.376v.958c.194-.385.42-.666.678-.845a1.56 1.56 0 01.923-.273c.058 0 .102.001.133.005.034 0 .06.002.081.005l.005 1.52h-.494c-.405 0-.709.107-.913.32-.204.213-.306.53-.306.949v2.964h-1.483m4.068 0v-7.593h1.483v7.593h-1.483"/><path id="text5872" fill="#000" fill-rule="nonzero" d="M72.458 176.567L70.297 169h1.608l1.29 5.338 1.09-5.338h1.655l1.09 5.338L78.32 169h1.593l-2.156 7.567h-1.48l-1.167-5.795-1.172 5.795h-1.48m8.228-6.206V169h1.49v1.361h-1.49m0 6.206v-5.584h1.49v5.584h-1.49m2.816 0v-5.584h1.46v.663c.208-.27.453-.473.737-.606.283-.137.599-.206.947-.206.614 0 1.074.161 1.377.483.308.318.461.8.461 1.444v3.806h-1.49v-3.375c0-.4-.068-.687-.205-.858-.133-.171-.351-.257-.655-.257-.352 0-.63.106-.835.319-.204.209-.307.495-.307.858v3.313h-1.49m-12.55 13.152v-7.567h1.552v3.108l2.944-3.108h1.94l-3.01 3.062 3.282 4.505h-1.895l-2.457-3.463-.804.802v2.661h-1.552m10.676-1.695h1.485c-.15.589-.454 1.051-.911 1.387-.454.332-1.009.498-1.664.498-.806 0-1.444-.27-1.915-.812-.471-.544-.707-1.28-.707-2.209 0-.914.232-1.635.696-2.163.465-.527 1.1-.79 1.905-.79.853 0 1.512.26 1.977.78.464.517.696 1.255.696 2.214a4.215 4.215 0 01-.015.39h-3.718c.02.44.126.77.318.992.194.223.472.334.834.334.256 0 .466-.05.63-.149.164-.102.294-.26.39-.472m-2.172-1.685h2.192c-.014-.377-.115-.663-.302-.858-.185-.199-.451-.298-.8-.298-.323 0-.58.099-.767.298-.185.198-.292.484-.323.858m4.941 5.62v-1.207a1.976 1.976 0 00.348.02c.294 0 .514-.07.661-.21.147-.137.22-.345.22-.622a.799.799 0 00-.03-.154l-2.008-5.651h1.639l1.172 4.027 1.142-4.027h1.567l-2.289 6.586c-.17.493-.384.829-.64 1.007-.256.181-.64.272-1.152.272-.092 0-.191-.003-.297-.01a6.338 6.338 0 01-.333-.031"/><path id="text5878" fill="#000" fill-rule="nonzero" d="M472.458 176.567L470.297 169h1.608l1.29 5.338 1.09-5.338h1.655l1.09 5.338 1.29-5.338h1.593l-2.156 7.567h-1.48l-1.167-5.795-1.172 5.795h-1.48m8.228-6.206V169h1.49v1.361h-1.49m0 6.206v-5.584h1.49v5.584h-1.49m2.816 0v-5.584h1.46v.663c.208-.27.453-.473.737-.606.283-.137.599-.206.947-.206.614 0 1.074.161 1.377.483.308.318.461.8.461 1.444v3.806h-1.49v-3.375c0-.4-.068-.687-.205-.858-.133-.171-.351-.257-.655-.257-.352 0-.63.106-.835.319-.204.209-.307.495-.307.858v3.313h-1.49m-12.55 13.152v-7.567h1.552v3.108l2.944-3.108h1.94l-3.01 3.062 3.282 4.505h-1.895l-2.457-3.463-.804.802v2.661h-1.552m10.676-1.695h1.485c-.15.589-.454 1.051-.911 1.387-.454.332-1.009.498-1.664.498-.806 0-1.444-.27-1.915-.812-.471-.544-.707-1.28-.707-2.209 0-.914.232-1.635.696-2.163.465-.527 1.1-.79 1.905-.79.853 0 1.512.26 1.977.78.464.517.696 1.255.696 2.214a4.215 4.215 0 01-.015.39h-3.718c.02.44.126.77.318.992.194.223.472.334.834.334.256 0 .466-.05.63-.149.164-.102.294-.26.39-.472m-2.172-1.685h2.192c-.014-.377-.115-.663-.302-.858-.185-.199-.451-.298-.8-.298-.323 0-.58.099-.767.298-.185.198-.292.484-.323.858m4.941 5.62v-1.207a1.976 1.976 0 00.348.02c.294 0 .514-.07.661-.21.147-.137.22-.345.22-.622a.8.8 0 00-.03-.154l-2.008-5.651h1.639l1.172 4.027 1.142-4.027h1.567l-2.289 6.586c-.17.493-.384.829-.64 1.007-.256.181-.64.272-1.152.272-.092 0-.191-.003-.297-.01a6.338 6.338 0 01-.333-.031"/><path id="text5884" fill="#000" fill-rule="nonzero" d="M506.93 183.804V176h2.338l1.529 5.94 1.507-5.94h2.348v7.804h-1.482v-6.294l-1.56 6.294h-1.617l-1.58-6.294v6.294h-1.482m12.693-1.748h1.513c-.153.607-.463 1.084-.929 1.43-.462.343-1.027.514-1.695.514-.821 0-1.471-.279-1.951-.837-.48-.562-.72-1.321-.72-2.278 0-.943.236-1.687.71-2.23.472-.545 1.12-.817 1.94-.817.87 0 1.54.269 2.014.806.473.533.71 1.294.71 2.283a4.4 4.4 0 01-.016.403h-3.788c.02.452.129.793.323 1.022.199.23.482.345.85.345.262 0 .476-.052.643-.154.166-.106.299-.268.396-.487m-2.212-1.738h2.233c-.014-.389-.117-.684-.308-.885-.188-.205-.459-.307-.814-.307-.33 0-.591.102-.782.307-.188.205-.298.5-.33.885m4.811 3.486v-5.759h1.487v.683a2.05 2.05 0 01.751-.625c.289-.141.61-.212.965-.212.627 0 1.094.166 1.404.498.313.329.47.825.47 1.49v3.925h-1.519v-3.48c0-.414-.07-.709-.208-.886-.136-.176-.359-.264-.668-.264-.358 0-.642.109-.85.328-.21.215-.314.51-.314.885v3.417h-1.518m11.441-5.759v5.759h-1.487v-.683c-.215.279-.467.489-.756.63a2.191 2.191 0 01-.965.207c-.623 0-1.09-.166-1.404-.498-.31-.332-.464-.829-.464-1.49v-3.925h1.518v3.48c0 .41.068.704.204.88.135.173.36.26.673.26.355 0 .636-.108.845-.323.212-.22.318-.516.318-.89v-3.407h1.518"/><circle id="Oval" cx="109.168" cy="139" r="26" stroke="#EE714E" stroke-width="5"/></g></g></g></svg>
\ No newline at end of file
diff --git a/2-ui/3-event-details/6-pointer-events/article.md b/2-ui/3-event-details/6-pointer-events/article.md
new file mode 100644
index 000000000..ecc144712
--- /dev/null
+++ b/2-ui/3-event-details/6-pointer-events/article.md
@@ -0,0 +1,282 @@
+# Pointer events
+
+Pointer events are a modern way to handle input from a variety of pointing devices, such as a mouse, a pen/stylus, a touchscreen, and so on.
+
+## The brief history
+
+Let's make a small overview, so that you understand the general picture and the place of Pointer Events among other event types.
+
+- Long ago, in the past, there were only mouse events.
+
+    Then touch devices became widespread, phones and tablets in particular. For the existing scripts to work, they generated (and still generate) mouse events. For instance, tapping a touchscreen generates `mousedown`. So touch devices worked well with web pages.
+
+    But touch devices have more capabilities than a mouse. For example, it's possible to touch multiple points at once ("multi-touch"). Although, mouse events don't have necessary properties to handle such multi-touches.
+
+- So touch events were introduced, such as `touchstart`, `touchend`, `touchmove`, that have touch-specific properties (we don't cover them in detail here, because pointer events are even better).
+
+    Still, it wasn't enough, as there are many other devices, such as pens, that have their own features. Also, writing code that listens for both touch and mouse events was cumbersome.
+
+- To solve these issues, the new standard Pointer Events was introduced. It provides a single set of events for all kinds of pointing devices.
+
+As of now, [Pointer Events Level 2](https://www.w3.org/TR/pointerevents2/) specification is supported in all major browsers, while the newer [Pointer Events Level 3](https://w3c.github.io/pointerevents/) is in the works and is mostly compatible with Pointer Events level 2.
+
+Unless you develop for old browsers, such as Internet Explorer 10, or for Safari 12 or below, there's no point in using mouse or touch events any more -- we can switch to pointer events.
+
+Then your code will work well with both touch and mouse devices.
+
+That said, there are some important peculiarities that one should know in order to use Pointer Events correctly and avoid surprises. We'll make note of them in this article.
+
+## Pointer event types
+
+Pointer events are named similarly to mouse events:
+
+| Pointer event | Similar mouse event |
+|---------------|-------------|
+| `pointerdown` | `mousedown` |
+| `pointerup` | `mouseup` |
+| `pointermove` | `mousemove` |
+| `pointerover` | `mouseover` |
+| `pointerout` | `mouseout` |
+| `pointerenter` | `mouseenter` |
+| `pointerleave` | `mouseleave` |
+| `pointercancel` | - |
+| `gotpointercapture` | - |
+| `lostpointercapture` | - |
+
+As we can see, for every `mouse<event>`, there's a `pointer<event>` that plays a similar role. Also there are 3 additional pointer events that don't have a corresponding `mouse...` counterpart, we'll explain them soon.
+
+```smart header="Replacing `mouse<event>` with `pointer<event>` in our code"
+We can replace `mouse<event>` events with `pointer<event>` in our code and expect things to continue working fine with mouse.
+
+The support for touch devices will also "magically" improve. Although, we may need to add `touch-action: none` in some places in CSS. We'll cover it below in the section about `pointercancel`.
+```
+
+## Pointer event properties
+
+Pointer events have the same properties as mouse events, such as `clientX/Y`, `target`, etc., plus some others:
+
+- `pointerId` - the unique identifier of the pointer causing the event.
+
+    Browser-generated. Allows us to handle multiple pointers, such as a touchscreen with stylus and multi-touch (examples will follow).
+- `pointerType` - the pointing device type. Must be a string, one of: "mouse", "pen" or "touch".
+
+    We can use this property to react differently on various pointer types.
+- `isPrimary` - is `true` for the primary pointer (the first finger in multi-touch).
+
+Some pointer devices measure contact area and pressure, e.g. for a finger on the touchscreen, there are additional properties for that:
+
+- `width` - the width of the area where the pointer (e.g. a finger) touches the device. Where unsupported, e.g. for a mouse, it's always `1`.
+- `height` - the height of the area where the pointer touches the device. Where unsupported, it's always `1`.
+- `pressure` - the pressure of the pointer tip, in range from 0 to 1. For devices that don't support pressure must be either `0.5` (pressed) or `0`.
+- `tangentialPressure` - the normalized tangential pressure.
+- `tiltX`, `tiltY`, `twist` - pen-specific properties that describe how the pen is positioned relative to the surface.
+
+These properties aren't supported by most devices, so they are rarely used. You can find the details about them in the [specification](https://w3c.github.io/pointerevents/#pointerevent-interface) if needed.
+
+## Multi-touch
+
+One of the things that mouse events totally don't support is multi-touch: a user can touch in several places at once on their phone or tablet, or perform special gestures.
+
+Pointer Events allow handling multi-touch with the help of the `pointerId` and `isPrimary` properties.
+
+Here's what happens when a user touches a touchscreen in one place, then puts another finger somewhere else on it:
+
+1. At the first finger touch:
+    - `pointerdown` with `isPrimary=true` and some `pointerId`.
+2. For the second finger and more fingers (assuming the first one is still touching):
+    - `pointerdown` with `isPrimary=false` and a different `pointerId` for every finger.
+
+Please note: the `pointerId` is assigned not to the whole device, but for each touching finger. If we use 5 fingers to simultaneously touch the screen, we have 5 `pointerdown` events, each with their respective coordinates and a different `pointerId`.
+
+The events associated with the first finger always have `isPrimary=true`.
+
+We can track multiple touching fingers using their `pointerId`. When the user moves and then removes a finger, we get `pointermove` and `pointerup` events with the same `pointerId` as we had in `pointerdown`.
+
+```online
+Here's the demo that logs `pointerdown` and `pointerup` events:
+
+[iframe src="multitouch" edit height=200]
+
+Please note: you must be using a touchscreen device, such as a phone or a tablet, to actually see the difference in `pointerId/isPrimary`. For single-touch devices, such as a mouse, there'll be always same `pointerId` with `isPrimary=true`, for all pointer events.
+```
+
+## Event: pointercancel
+
+The `pointercancel` event fires when there's an ongoing pointer interaction, and then something happens that causes it to be aborted, so that no more pointer events are generated.
+
+Such causes are:
+- The pointer device hardware was physically disabled.
+- The device orientation changed (tablet rotated).
+- The browser decided to handle the interaction on its own, considering it a mouse gesture or zoom-and-pan action or something else.
+
+We'll demonstrate `pointercancel` on a practical example to see how it affects us.
+
+Let's say we're implementing drag'n'drop for a ball, just as in the beginning of the article <info:mouse-drag-and-drop>.
+
+Here is the flow of user actions and the corresponding events:
+
+1) The user presses on an image, to start dragging
+    - `pointerdown` event fires
+2) Then they start moving the pointer (thus dragging the image)
+    - `pointermove` fires, maybe several times
+3) And then the surprise happens! The browser has native drag'n'drop support for images, that kicks in and takes over the drag'n'drop process, thus generating `pointercancel` event.
+    - The browser now handles drag'n'drop of the image on its own. The user may even drag the ball image out of the browser, into their Mail program or a File Manager.
+    - No more `pointermove` events for us.
+
+So the issue is that the browser "hijacks" the interaction: `pointercancel` fires in the beginning of the "drag-and-drop" process, and no more `pointermove` events are generated.
+
+```online
+Here's the drag'n'drop demo with logging of pointer events (only `up/down`, `move` and `cancel`) in the `textarea`:
+
+[iframe src="ball" height=240 edit]
+```
+
+We'd like to implement the drag'n'drop on our own, so let's tell the browser not to take it over.
+
+**Prevent the default browser action to avoid `pointercancel`.**
+
+We need to do two things:
+
+1. Prevent native drag'n'drop from happening:
+    - We can do this by setting `ball.ondragstart = () => false`, just as described in the article <info:mouse-drag-and-drop>.
+    - That works well for mouse events.
+2. For touch devices, there are other touch-related browser actions (besides drag'n'drop). To avoid problems with them too:
+    - Prevent them by setting `#ball { touch-action: none }` in CSS.
+    - Then our code will start working on touch devices.
+
+After we do that, the events will work as intended, the browser won't hijack the process and doesn't emit `pointercancel`.
+
+```online
+This demo adds these lines:
+
+[iframe src="ball-2" height=240 edit]
+
+As you can see, there's no `pointercancel` any more.
+```
+
+Now we can add the code to actually move the ball, and our drag'n'drop will work for mouse devices and touch devices.
+
+## Pointer capturing
+
+Pointer capturing is a special feature of pointer events.
+
+The idea is very simple, but may seem quite odd at first, as nothing like that exists for any other event type.
+
+The main method is:
+- `elem.setPointerCapture(pointerId)` -- binds events with the given `pointerId` to `elem`. After the call all pointer events with the same `pointerId` will have `elem` as the target (as if happened on `elem`), no matter where in document they really happened.
+
+In other words, `elem.setPointerCapture(pointerId)` retargets all subsequent events with the given `pointerId` to `elem`.
+
+The binding is removed:
+- automatically when `pointerup` or `pointercancel` events occur,
+- automatically when `elem` is removed from the document,
+- when `elem.releasePointerCapture(pointerId)` is called.
+
+Now what is it good for? It's time to see a real-life example.
+
+**Pointer capturing can be used to simplify drag'n'drop kind of interactions.**
+
+Let's recall how one can implement a custom slider, described in the <info:mouse-drag-and-drop>.
+
+We can make a `slider` element to represent the strip and the "runner" (`thumb`) inside it:
+
+```html
+<div class="slider">
+  <div class="thumb"></div>
+</div>
+```
+
+With styles, it looks like this:
+
+[iframe src="slider-html" height=40 edit]
+
+<p></p>
+
+And here's the working logic, as it was described, after replacing mouse events with similar pointer events:
+
+1. The user presses on the slider `thumb` -- `pointerdown` triggers.
+2. Then they move the pointer -- `pointermove` triggers, and our code moves the `thumb` element along.
+    - ...As the pointer moves, it may leave the slider `thumb` element, go above or below it. The `thumb` should move strictly horizontally, remaining aligned with the pointer.
+
+In the mouse event based solution, to track all pointer movements, including when it goes above/below the `thumb`, we had to assign `mousemove` event handler on the whole `document`.
+
+That's not a cleanest solution, though. One of the problems is that when a user moves the pointer around the document, it may trigger event handlers (such as  `mouseover`) on some other elements, invoke totally unrelated UI functionality, and we don't want that.
+
+This is the place where `setPointerCapture` comes into play.
+
+- We can call `thumb.setPointerCapture(event.pointerId)` in `pointerdown` handler,
+- Then future pointer events until `pointerup/cancel` will be retargeted to `thumb`.
+- When `pointerup` happens (dragging complete), the binding is removed automatically, we don't need to care about it.
+
+So, even if the user moves the pointer around the whole document, events handlers will be called on `thumb`. Nevertheless, coordinate properties of the event objects, such as `clientX/clientY` will still be correct - the capturing only affects `target/currentTarget`.
+
+Here's the essential code:
+
+```js
+thumb.onpointerdown = function(event) {
+  // retarget all pointer events (until pointerup) to thumb
+  thumb.setPointerCapture(event.pointerId);
+
+  // start tracking pointer moves
+  thumb.onpointermove = function(event) {
+    // moving the slider: listen on the thumb, as all pointer events are retargeted to it
+    let newLeft = event.clientX - slider.getBoundingClientRect().left;
+    thumb.style.left = newLeft + 'px';
+  };
+
+  // on pointer up finish tracking pointer moves
+  thumb.onpointerup = function(event) {
+    thumb.onpointermove = null;
+    thumb.onpointerup = null;
+    // ...also process the "drag end" if needed
+  };
+};
+
+// note: no need to call thumb.releasePointerCapture,
+// it happens on pointerup automatically
+```
+
+```online
+The full demo:
+
+[iframe src="slider" height=100 edit]
+
+<p></p>
+
+In the demo, there's also an additional element with `onmouseover` handler showing the current date.
+
+Please note: while you're dragging the thumb, you may hover over this element, and its handler *does not* trigger.
+
+So the dragging is now free of side effects, thanks to `setPointerCapture`.
+```
+
+
+
+At the end, pointer capturing gives us two benefits:
+1. The code becomes cleaner as we don't need to add/remove handlers on the whole `document` any more. The binding is released automatically.
+2. If there are other pointer event handlers in the document, they won't be accidentally triggered by the pointer while the user is dragging the slider.
+
+### Pointer capturing events
+
+There's one more thing to mention here, for the sake of completeness.
+
+There are two events associated with pointer capturing:
+
+- `gotpointercapture` fires when an element uses `setPointerCapture` to enable capturing.
+- `lostpointercapture` fires when the capture is released: either explicitly with `releasePointerCapture` call, or automatically on `pointerup`/`pointercancel`.
+
+## Summary
+
+Pointer events allow handling mouse, touch and pen events simultaneously, with a single piece of code.
+
+Pointer events extend mouse events. We can replace `mouse` with `pointer` in event names and expect our code to continue working for mouse, with better support for other device types.
+
+For drag'n'drops and complex touch interactions that the browser may decide to hijack and handle on its own - remember to cancel the default action on events and set `touch-action: none` in CSS for elements that we engage.
+
+Additional abilities of pointer events are:
+
+- Multi-touch support using `pointerId` and `isPrimary`.
+- Device-specific properties, such as `pressure`, `width/height`, and others.
+- Pointer capturing: we can retarget all pointer events to a specific element until `pointerup`/`pointercancel`.
+
+As of now, pointer events are supported in all major browsers, so we can safely switch to them, especially if IE10- and Safari 12- are not needed. And even with those browsers, there are polyfills that enable the support of pointer events.
diff --git a/2-ui/3-event-details/6-pointer-events/ball-2.view/index.html b/2-ui/3-event-details/6-pointer-events/ball-2.view/index.html
new file mode 100644
index 000000000..5f3abbcb0
--- /dev/null
+++ b/2-ui/3-event-details/6-pointer-events/ball-2.view/index.html
@@ -0,0 +1,38 @@
+<!doctype html>
+<body style="height: 200px">
+  <style>
+    #ball {
+      touch-action: none;
+    }
+  </style>
+
+  <p>Drag the ball.</p>
+
+  <img src="https://js.cx/clipart/ball.svg" style="cursor:pointer" width="40" height="40" id="ball">
+
+  <script>
+
+    ball.onpointerdown = log;
+    ball.onpointerup = log;
+    ball.onpointermove = log;
+    ball.onpointercancel = log;
+
+    ball.ondragstart = () => false;
+
+    let lastEventType;
+    let n = 1;
+    function log(event) {
+      if (lastEventType == event.type) {
+        n++;
+        text.value = text.value.replace(/.*\n$/, `${event.type} * ${n}\n`);
+        return;
+      }
+      lastEventType = event.type;
+      n = 1;
+      text.value += event.type + '\n';
+      text.scrollTop = 1e9;
+    }
+  </script>
+
+  <textarea id="text" style="display:block;width:300px;height:100px"></textarea>
+</body>
diff --git a/2-ui/3-event-details/6-pointer-events/ball.view/index.html b/2-ui/3-event-details/6-pointer-events/ball.view/index.html
new file mode 100644
index 000000000..8bbef8f63
--- /dev/null
+++ b/2-ui/3-event-details/6-pointer-events/ball.view/index.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<body style="height: 200px">
+  <p>Drag the ball.</p>
+
+  <img src="https://js.cx/clipart/ball.svg" style="cursor:pointer" width="40" height="40" id="ball">
+
+  <script>
+
+    ball.onpointerdown = log;
+    ball.onpointerup = log;
+    ball.onpointermove = log;
+    ball.onpointercancel = log;
+
+    let lastEventType;
+    let n = 1;
+    function log(event) {
+      if (lastEventType == event.type) {
+        n++;
+        text.value = text.value.replace(/.*\n$/, `${event.type} * ${n}\n`);
+        return;
+      }
+      lastEventType = event.type;
+      n = 1;
+      text.value += event.type + '\n';
+      text.scrollTop = 1e9;
+    }
+  </script>
+
+  <textarea id="text" style="display:block;width:300px;height:100px"></textarea>
+</body>
diff --git a/2-ui/3-event-details/6-pointer-events/multitouch.view/index.html b/2-ui/3-event-details/6-pointer-events/multitouch.view/index.html
new file mode 100644
index 000000000..d46e1bc16
--- /dev/null
+++ b/2-ui/3-event-details/6-pointer-events/multitouch.view/index.html
@@ -0,0 +1,28 @@
+<!doctype html>
+<body>
+  <style>
+    #area {
+      border: 1px solid black; 
+      width: 90%; 
+      height: 180px; 
+      cursor: pointer;
+      overflow: scroll;
+      user-select: none;
+    }
+  </style>
+  
+  <div id="area">
+  Multi-touch here
+  </div>
+  <script>
+    document.onpointerdown = document.onpointerup = log;
+
+    function log(event) {
+      area.insertAdjacentHTML("beforeend", `
+        <div>${event.type} isPrimary=${event.isPrimary} pointerId=${event.pointerId}</div>
+      `)
+     area.scrollTop = 1e9;
+    }
+  </script>
+
+</body>
diff --git a/2-ui/3-event-details/6-pointer-events/slider-html.view/index.html b/2-ui/3-event-details/6-pointer-events/slider-html.view/index.html
new file mode 100644
index 000000000..781016f52
--- /dev/null
+++ b/2-ui/3-event-details/6-pointer-events/slider-html.view/index.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<link rel="stylesheet" href="style.css">
+
+<div id="slider" class="slider">
+  <div class="thumb"></div>
+</div>
diff --git a/2-ui/3-event-details/6-pointer-events/slider-html.view/style.css b/2-ui/3-event-details/6-pointer-events/slider-html.view/style.css
new file mode 100644
index 000000000..9b3d3b82d
--- /dev/null
+++ b/2-ui/3-event-details/6-pointer-events/slider-html.view/style.css
@@ -0,0 +1,19 @@
+.slider {
+  border-radius: 5px;
+  background: #E0E0E0;
+  background: linear-gradient(left top, #E0E0E0, #EEEEEE);
+  width: 310px;
+  height: 15px;
+  margin: 5px;
+}
+
+.thumb {
+  width: 10px;
+  height: 25px;
+  border-radius: 3px;
+  position: relative;
+  left: 10px;
+  top: -5px;
+  background: blue;
+  cursor: pointer;
+}
diff --git a/2-ui/3-event-details/6-pointer-events/slider.view/index.html b/2-ui/3-event-details/6-pointer-events/slider.view/index.html
new file mode 100644
index 000000000..b29e646a1
--- /dev/null
+++ b/2-ui/3-event-details/6-pointer-events/slider.view/index.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<link rel="stylesheet" href="style.css">
+
+<div id="slider" class="slider">
+  <div class="thumb"></div>
+</div>
+
+<p style="border:1px solid gray" onmousemove="this.textContent = new Date()">Mouse over here to see the date</p>
+
+<script>
+  let thumb = slider.querySelector('.thumb');
+  let shiftX;
+
+  function onThumbDown(event) {
+    event.preventDefault(); // prevent selection start (browser action)
+
+    shiftX = event.clientX - thumb.getBoundingClientRect().left;
+
+    thumb.setPointerCapture(event.pointerId);
+
+    thumb.onpointermove = onThumbMove;
+
+    thumb.onpointerup = event => {
+      // dragging finished, no need to track pointer any more
+      // ...any other "drag end" logic here...
+      thumb.onpointermove = null;
+      thumb.onpointerup = null;
+    }
+  };
+
+  function onThumbMove(event) {
+    let newLeft = event.clientX - shiftX - slider.getBoundingClientRect().left;
+
+    // if the pointer is out of slider => adjust left to be within the boundaries
+    if (newLeft < 0) {
+      newLeft = 0;
+    }
+    let rightEdge = slider.offsetWidth - thumb.offsetWidth;
+    if (newLeft > rightEdge) {
+      newLeft = rightEdge;
+    }
+
+    thumb.style.left = newLeft + 'px';
+  };
+
+  thumb.onpointerdown = onThumbDown;
+
+  thumb.ondragstart = () => false;
+
+</script>
diff --git a/2-ui/3-event-details/6-pointer-events/slider.view/style.css b/2-ui/3-event-details/6-pointer-events/slider.view/style.css
new file mode 100644
index 000000000..a84cd5e7e
--- /dev/null
+++ b/2-ui/3-event-details/6-pointer-events/slider.view/style.css
@@ -0,0 +1,20 @@
+.slider {
+  border-radius: 5px;
+  background: #E0E0E0;
+  background: linear-gradient(left top, #E0E0E0, #EEEEEE);
+  width: 310px;
+  height: 15px;
+  margin: 5px;
+}
+
+.thumb {
+  touch-action: none;
+  width: 10px;
+  height: 25px;
+  border-radius: 3px;
+  position: relative;
+  left: 10px;
+  top: -5px;
+  background: blue;
+  cursor: pointer;
+}
diff --git a/2-ui/3-event-details/5-keyboard-events/2-check-sync-keydown/solution.md b/2-ui/3-event-details/7-keyboard-events/2-check-sync-keydown/solution.md
similarity index 100%
rename from 2-ui/3-event-details/5-keyboard-events/2-check-sync-keydown/solution.md
rename to 2-ui/3-event-details/7-keyboard-events/2-check-sync-keydown/solution.md
diff --git a/2-ui/3-event-details/5-keyboard-events/2-check-sync-keydown/solution.view/index.html b/2-ui/3-event-details/7-keyboard-events/2-check-sync-keydown/solution.view/index.html
similarity index 100%
rename from 2-ui/3-event-details/5-keyboard-events/2-check-sync-keydown/solution.view/index.html
rename to 2-ui/3-event-details/7-keyboard-events/2-check-sync-keydown/solution.view/index.html
diff --git a/2-ui/3-event-details/5-keyboard-events/2-check-sync-keydown/task.md b/2-ui/3-event-details/7-keyboard-events/2-check-sync-keydown/task.md
similarity index 100%
rename from 2-ui/3-event-details/5-keyboard-events/2-check-sync-keydown/task.md
rename to 2-ui/3-event-details/7-keyboard-events/2-check-sync-keydown/task.md
diff --git a/2-ui/3-event-details/5-keyboard-events/article.md b/2-ui/3-event-details/7-keyboard-events/article.md
similarity index 81%
rename from 2-ui/3-event-details/5-keyboard-events/article.md
rename to 2-ui/3-event-details/7-keyboard-events/article.md
index 617852ccf..12fe63201 100644
--- a/2-ui/3-event-details/5-keyboard-events/article.md
+++ b/2-ui/3-event-details/7-keyboard-events/article.md
@@ -107,7 +107,7 @@ So, `event.code` may match a wrong character for unexpected layout. Same letters
 
 To reliably track layout-dependent characters, `event.key` may be a better way.
 
-On the other hand, `event.code` has the benefit of staying always the same, bound to the physical key location, even if the visitor changes languages. So hotkeys that rely on it work well even in case of a language switch.
+On the other hand, `event.code` has the benefit of staying always the same, bound to the physical key location. So hotkeys that rely on it work well even in case of a language switch.
 
 Do we want to handle layout-dependant keys? Then `event.key` is the way to go.
 
@@ -139,22 +139,25 @@ For instance, the `<input>` below expects a phone number, so it does not accept
 ```html autorun height=60 run
 <script>
 function checkPhoneKey(key) {
-  return (key >= '0' && key <= '9') || key == '+' || key == '(' || key == ')' || key == '-';
+  return (key >= '0' && key <= '9') || ['+','(',')','-'].includes(key);
 }
 </script>
 <input *!*onkeydown="return checkPhoneKey(event.key)"*/!* placeholder="Phone, please" type="tel">
 ```
 
-Please note that special keys, such as `key:Backspace`, `key:Left`, `key:Right`, `key:Ctrl+V`, do not work in the input. That's a side-effect of the strict filter `checkPhoneKey`.
+The `onkeydown` handler here uses `checkPhoneKey` to check for the key pressed. If it's valid (from `0..9` or one of `+-()`), then it returns `true`, otherwise `false`.
 
-Let's relax it a little bit:
+As we know, the `false` value returned from the event handler, assigned using a DOM property or an attribute, such as above, prevents the default action, so nothing appears in the `<input>` for keys that don't pass the test. (The `true` value returned doesn't affect anything, only returning `false` matters)
 
+Please note that special keys, such as `key:Backspace`, `key:Left`, `key:Right`, do not work in the input. That's a side effect of the strict filter `checkPhoneKey`. These keys make it return `false`.
+
+Let's relax the filter a little bit by allowing arrow keys `key:Left`, `key:Right` and `key:Delete`, `key:Backspace`:
 
 ```html autorun height=60 run
 <script>
 function checkPhoneKey(key) {
-  return (key >= '0' && key <= '9') || key == '+' || key == '(' || key == ')' || key == '-' ||
-    key == 'ArrowLeft' || key == 'ArrowRight' || key == 'Delete' || key == 'Backspace';
+  return (key >= '0' && key <= '9') ||
+    ['+','(',')','-',*!*'ArrowLeft','ArrowRight','Delete','Backspace'*/!*].includes(key);
 }
 </script>
 <input onkeydown="return checkPhoneKey(event.key)" placeholder="Phone, please" type="tel">
@@ -162,7 +165,9 @@ function checkPhoneKey(key) {
 
 Now arrows and deletion works well.
 
-...But we still can enter anything by using a mouse and right-click + Paste. So the filter is not 100% reliable. We can just let it be like that, because most of time it works. Or an alternative approach would be to track the `input` event -- it triggers after any modification. There we can check the new value and highlight/modify it when it's invalid.
+Even though we have the key filter, one still can enter anything using a mouse and right-click + Paste. Mobile devices provide other means to enter values. So the filter is not 100% reliable.
+
+The alternative approach would be to track the `oninput` event -- it triggers *after* any modification. There we can check the new `input.value` and modify it/highlight the `<input>` when it's invalid. Or we can use both event handlers together.
 
 ## Legacy
 
@@ -170,6 +175,12 @@ In the past, there was a `keypress` event, and also `keyCode`, `charCode`, `whic
 
 There were so many browser incompatibilities while working with them, that developers of the specification had no way, other than deprecating all of them and creating new, modern events (described above in this chapter). The old code still works, as browsers keep supporting them, but there's totally no need to use those any more.
 
+## Mobile Keyboards
+
+When using virtual/mobile keyboards, formally known as IME (Input-Method Editor), the W3C standard states that a KeyboardEvent's [`e.keyCode` should be `229`](https://www.w3.org/TR/uievents/#determine-keydown-keyup-keyCode) and [`e.key` should be `"Unidentified"`](https://www.w3.org/TR/uievents-key/#key-attr-values).
+
+While some of these keyboards might still use the right values for `e.key`, `e.code`, `e.keyCode`... when pressing certain keys such as arrows or backspace, there's no guarantee, so your keyboard logic might not always work on mobile devices.
+
 ## Summary
 
 Pressing a key always generates a keyboard event, be it symbol keys or special keys like `key:Shift` or `key:Ctrl` and so on. The only exception is `key:Fn` key that sometimes presents on a laptop keyboard. There's no keyboard event for it, because it's often implemented on lower level than OS.
diff --git a/2-ui/3-event-details/7-keyboard-events/german-layout.svg b/2-ui/3-event-details/7-keyboard-events/german-layout.svg
new file mode 100644
index 000000000..7ac9a4008
--- /dev/null
+++ b/2-ui/3-event-details/7-keyboard-events/german-layout.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="600" height="200" viewBox="0 0 600 200"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:&apos;PT Mono&apos;;font-weight:700;font-style:normal;src:local(&apos;PT MonoBold&apos;),url(/font/PTMonoBold.woff2) format(&apos;woff2&apos;),url(/font/PTMonoBold.woff) format(&apos;woff&apos;),url(/font/PTMonoBold.ttf) format(&apos;truetype&apos;)}</style></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="Group" transform="translate(.918 .953)"><path id="rect2186" fill="#FFF" stroke="#181717" d="M.08.083h39.933V39.46H.08z"/><path id="rect2218" fill="#FFF" stroke="#181717" d="M40.013.083h39.934V39.46H40.013z"/><path id="rect2222" fill="#FFF" stroke="#181717" d="M79.947.083h39.933V39.46H79.947z"/><path id="rect2228" fill="#FFF" stroke="#181717" d="M118.882.083h39.933V39.46h-39.933z"/><path id="rect2230" fill="#FFF" stroke="#181717" d="M158.815.083h39.934V39.46h-39.934z"/><path id="rect2232" fill="#FFF" stroke="#181717" d="M198.749.083h39.933V39.46H198.75z"/><path id="rect2234" fill="#FFF" stroke="#181717" d="M239.68.083h39.934V39.46h-39.933z"/><path id="rect2236" fill="#FFF" stroke="#181717" d="M279.614.083h39.933V39.46h-39.933z"/><path id="rect2238" fill="#FFF" stroke="#181717" d="M318.55.083h39.933V39.46h-39.934z"/><path id="rect2240" fill="#FFF" stroke="#181717" d="M358.483.083h39.933V39.46h-39.933z"/><path id="rect2242" fill="#FFF" stroke="#181717" d="M398.416.083h39.933V39.46h-39.933z"/><path id="rect2244" fill="#FFF" stroke="#181717" d="M438.35.083h39.933V39.46h-39.934z"/><path id="rect2246" fill="#FFF" stroke="#181717" d="M478.283.083h39.933V39.46h-39.933z"/><path id="rect2248" fill="#D1CFCD" stroke="#181717" d="M517.218.083h81.864V39.46h-81.864z"/><path id="rect2250" fill="#D1CFCD" stroke="#181717" d="M.08 39.461h59.9V78.84H.08z"/><path id="rect2252" fill="#FFF" stroke="#181717" d="M59.98 39.461h39.933V78.84H59.98z"/><path id="rect2254" fill="#FFF" stroke="#181717" d="M98.915 39.461h39.934V78.84H98.915z"/><path id="rect2256" fill="#FFF" stroke="#181717" d="M138.849 39.461h39.933V78.84h-39.933z"/><path id="rect2258" fill="#FFF" stroke="#181717" d="M178.782 39.461h39.933V78.84h-39.933z"/><path id="rect2262" fill="#FFF" stroke="#181717" d="M219.714 39.461h39.933V78.84h-39.933z"/><path id="rect2264" fill="#FFF" stroke="#181717" d="M259.647 39.461h39.934V78.84h-39.934z"/><path id="rect2266" fill="#FFF" stroke="#181717" d="M298.582 39.461h39.934V78.84h-39.934z"/><path id="rect2270" fill="#FFF" stroke="#181717" d="M338.516 39.461h39.933V78.84h-39.933z"/><path id="rect2272" fill="#FFF" stroke="#181717" d="M378.45 39.461h39.933V78.84h-39.934z"/><path id="rect2274" fill="#FFF" stroke="#181717" d="M418.383 39.461h39.933V78.84h-39.933z"/><path id="rect2278" fill="#FFF" stroke="#181717" d="M458.316 39.461h39.934V78.84h-39.934z"/><path id="rect2280" fill="#FFF" stroke="#181717" d="M497.251 39.461h39.934V78.84H497.25z"/><path id="rect2286" fill="#D1CFCD" stroke="#181717" d="M.08 79.876h69.883v39.378H.08z"/><path id="rect2292" fill="#FFF" stroke="#181717" d="M69.963 79.876h39.934v39.378H69.963z"/><path id="rect2296" fill="#FFF" stroke="#181717" d="M109.897 79.876h39.933v39.378h-39.933z"/><path id="rect2298" fill="#FFF" stroke="#181717" d="M149.83 79.876h39.934v39.378H149.83z"/><path id="rect2300" fill="#FFF" stroke="#181717" d="M188.765 79.876H228.7v39.378h-39.934z"/><path id="rect2302" fill="#FFF" stroke="#181717" d="M228.699 79.876h39.933v39.378H228.7z"/><path id="rect2306" fill="#FFF" stroke="#181717" d="M268.632 79.876h39.934v39.378h-39.934z"/><path id="rect2308" fill="#FFF" stroke="#181717" d="M308.566 79.876h39.933v39.378h-39.933z"/><path id="rect2312" fill="#FFF" stroke="#181717" d="M348.5 79.876h39.933v39.378h-39.934z"/><path id="rect2314" fill="#FFF" stroke="#181717" d="M388.433 79.876h39.933v39.378h-39.933z"/><path id="rect2316" fill="#FFF" stroke="#181717" d="M428.366 79.876H468.3v39.378h-39.934z"/><path id="rect2318" fill="#FFF" stroke="#181717" d="M468.3 79.876h39.933v39.378H468.3z"/><path id="rect2320" fill="#D1CFCD" stroke="#181717" stroke-width="1" d="M547.5 79.358h-10.315V39.46h61.896v79.793h-51.656z"/><path id="rect2322" fill="#D1CFCD" stroke="#181717" stroke-width="1" d="M.08 119.254h49.917v39.378H.08z"/><path id="rect2324" fill="#FFF" stroke="#181717" d="M89.93 119.254h39.934v39.378H89.93z"/><path id="rect2326" fill="#FFF" stroke="#181717" d="M129.864 119.254h39.933v39.378h-39.933z"/><path id="rect2330" fill="#FFF" stroke="#181717" d="M169.797 119.254h39.933v39.378h-39.933z"/><path id="rect2334" fill="#FFF" stroke="#181717" d="M208.732 119.254h39.934v39.378h-39.934z"/><path id="rect2336" fill="#FFF" stroke="#181717" d="M248.666 119.254h39.933v39.378h-39.933z"/><path id="rect2338" fill="#FFF" stroke="#181717" d="M288.599 119.254h39.933v39.378H288.6z"/><path id="rect2340" fill="#FFF" stroke="#181717" d="M328.532 119.254h39.934v39.378h-39.934z"/><path id="rect2342" fill="#FFF" stroke="#181717" d="M368.466 119.254h39.933v39.378h-39.933z"/><path id="rect2344" fill="#FFF" stroke="#181717" d="M408.4 119.254h39.933v39.378h-39.934z"/><path id="rect2346" fill="#FFF" stroke="#181717" d="M448.333 119.254h39.933v39.378h-39.933z"/><path id="rect2348" fill="#D1CFCD" stroke="#181717" d="M488.266 119.254h110.816v39.378H488.266z"/><path id="rect2350" fill="#D1CFCD" stroke="#181717" d="M.08 158.632h59.9v39.378H.08z"/><path id="rect2352" fill="#D1CFCD" stroke="#181717" d="M537.185 158.632h61.897v39.378h-61.897z"/><path id="rect2354" fill="#D1CFCD" stroke="#181717" d="M98.915 158.632h59.9v39.378h-59.9z"/><path id="rect2360" fill="#D1CFCD" stroke="#181717" d="M398.416 158.632h59.9v39.378h-59.9z"/><path id="rect2362" fill="#FFF" stroke="#181717" d="M158.815 158.632h239.601v39.378h-239.6z"/><path id="rect2364" fill="#F6F3F1" stroke="#181717" d="M59.98 158.632h39.933v39.378H59.98z"/><path id="rect2366" fill="#F6F3F1" stroke="#181717" d="M458.316 158.632h39.934v39.378h-39.934z"/><path id="rect2368" fill="#F6F3F1" stroke="#181717" d="M497.251 158.632h39.934v39.378H497.25z"/><path id="text5091" fill="#181717" fill-rule="nonzero" d="M49.737 12.695l-.623-5.28V4.227h2.463v3.186l-.624 5.281h-1.216m-.591 3.266v-2.35h2.375v2.35h-2.375m.591 20.391v-7.798h-2.735v-1.6h.176c.997 0 1.722-.155 2.176-.463.458-.308.727-.823.807-1.545h1.832v11.406h-2.256"/><path id="text5127" fill="#181717" fill-rule="nonzero" d="M89.635 5.264h1.507v4.347h-1.507V5.264m-2.56 0h1.507v4.347h-1.507V5.264m-2.137 31.088c.01-.995.226-1.837.644-2.527.42-.694 1.163-1.397 2.23-2.107.163-.109.399-.26.707-.451 1.414-.897 2.12-1.76 2.12-2.59 0-.492-.148-.88-.447-1.166-.298-.285-.707-.428-1.225-.428-.565 0-1.002.177-1.311.53-.304.347-.456.844-.456 1.492v.093h-2.073c0-1.275.345-2.257 1.037-2.947.69-.689 1.675-1.034 2.952-1.034 1.157 0 2.081.314 2.773.941.69.622 1.036 1.452 1.036 2.488 0 .742-.18 1.385-.542 1.929-.361.544-1.06 1.164-2.097 1.858-.22.15-.523.348-.91.591-.985.628-1.54 1.104-1.665 1.431h5.104v1.897h-7.877"/><path id="text5139" fill="#181717" fill-rule="nonzero" d="M126.869 31.62h2.136c.005.62.155 1.087.45 1.402.296.31.734.465 1.314.465.559 0 .989-.144 1.29-.434.305-.294.458-.715.458-1.263 0-.547-.179-.96-.536-1.24-.353-.284-.878-.426-1.577-.426-.037 0-.094.003-.171.008a2.506 2.506 0 01-.164.008v-1.535h.241c.643 0 1.116-.124 1.422-.372.31-.253.466-.638.466-1.154 0-.429-.132-.767-.396-1.015-.259-.254-.614-.38-1.064-.38-.492 0-.873.145-1.142.434-.27.29-.404.7-.404 1.232v.093h-2.098c.026-1.137.36-2.007 1.002-2.612.648-.61 1.56-.914 2.735-.914 1.113 0 1.996.271 2.65.814.652.542.978 1.273.978 2.193 0 .485-.111.912-.334 1.278-.223.367-.557.67-1.002.907.57.248 1 .592 1.29 1.03.295.435.442.954.442 1.558 0 1.11-.365 1.992-1.095 2.643-.73.65-1.728.976-2.991.976-1.249 0-2.212-.315-2.89-.945-.674-.636-1.01-1.537-1.01-2.705v-.046"/><path id="text5145" fill="#181717" fill-rule="nonzero" d="M168.895 14.91c.468-.057.825-.21 1.07-.46.246-.25.369-.584.369-1 0-.37-.117-.674-.351-.914-.229-.244-.591-.434-1.088-.57v2.944m-1.02-5.341V6.914c-.445.052-.785.193-1.019.422-.234.224-.35.526-.35.906 0 .317.108.583.325.796.222.213.57.39 1.045.531m0 8.55V16.62c-1.291-.073-2.256-.414-2.896-1.023-.64-.609-.959-1.489-.959-2.64h2.296c.028.563.17 1.008.428 1.336.263.323.64.529 1.13.617v-3.233c-1.324-.307-2.266-.708-2.826-1.202-.56-.495-.84-1.171-.84-2.03 0-.953.332-1.72.994-2.304.668-.583 1.559-.887 2.673-.914v-.999h1.019v1c1.113.052 1.981.359 2.604.92.622.558.965 1.344 1.027 2.36h-2.33c-.04-.485-.168-.855-.385-1.11-.211-.26-.517-.406-.916-.437v2.842c1.41.401 2.404.86 2.98 1.375.577.515.866 1.194.866 2.038 0 .994-.337 1.788-1.011 2.381-.668.594-1.613.94-2.835 1.039v1.483h-1.02m1.157 14.095v-4.787l-3.332 4.787h3.332m-.052 4.138V33.94h-5.173v-1.967l4.522-6.481h3.041v6.668h1.422v1.78h-1.422v2.413h-2.39"/><path id="text5151" fill="#181717" fill-rule="nonzero" d="M212.846 12.99c0 .356.11.656.33.9.22.239.493.358.816.358.314 0 .583-.122.809-.366.225-.25.338-.547.338-.892 0-.34-.113-.63-.338-.868a1.048 1.048 0 00-.809-.367c-.323 0-.595.12-.816.359-.22.233-.33.525-.33.876m-1.595 0c0-.829.264-1.527.793-2.095a2.558 2.558 0 011.948-.852c.755 0 1.396.29 1.926.868.534.573.8 1.266.8 2.079 0 .818-.266 1.519-.8 2.103-.534.579-1.176.868-1.926.868-.77 0-1.418-.287-1.948-.86-.529-.574-.793-1.277-.793-2.111m-4.27 2.971l6.276-11.733h1.183l-6.276 11.733h-1.184m-.646-8.762c0 .35.107.645.323.884.22.24.492.359.816.359.318 0 .588-.12.808-.359.226-.244.338-.539.338-.884 0-.34-.112-.63-.338-.868a1.048 1.048 0 00-.808-.367c-.324 0-.595.12-.816.359a1.243 1.243 0 00-.323.876m-1.595 0c0-.828.264-1.53.794-2.103.529-.579 1.175-.868 1.94-.868.754 0 1.396.292 1.925.876.535.579.802 1.277.802 2.095 0 .818-.267 1.516-.802 2.095-.529.573-1.17.86-1.925.86-.77 0-1.419-.284-1.948-.852-.524-.568-.786-1.27-.786-2.103m2.102 25.76h2.058c.034.5.188.887.463 1.163.274.27.642.406 1.102.406.569 0 1.002-.18 1.301-.541.304-.361.456-.88.456-1.554 0-.632-.155-1.128-.463-1.49-.309-.366-.735-.549-1.28-.549-.303 0-.57.067-.8.2-.23.132-.427.329-.588.589l-1.896-.12.683-6.117h6.049v1.928h-4.564l-.272 2.286c.23-.197.495-.343.794-.438.298-.101.632-.152 1-.152 1.048 0 1.893.345 2.535 1.036.647.69.97 1.595.97 2.716 0 1.227-.355 2.206-1.066 2.94-.71.727-1.663 1.09-2.859 1.09-1.088 0-1.955-.3-2.602-.9-.641-.605-.982-1.436-1.021-2.493"/><path id="path3073" fill="#181717" fill-rule="nonzero" d="M248.136 10.477l-.576.414c-.232.16-.406.354-.523.58-.116.226-.174.48-.174.76 0 .427.146.786.44 1.077.293.291.66.437 1.099.437.323 0 .631-.066.925-.196.298-.136.573-.331.826-.587l-2.017-2.485m.607-2.372l.265-.188c.243-.165.422-.351.538-.557.117-.206.175-.442.175-.708 0-.256-.081-.459-.243-.61-.156-.15-.371-.225-.644-.225-.278 0-.498.077-.66.233-.161.15-.242.356-.242.617 0 .14.038.294.113.46.081.165.195.341.342.527l.356.451m-1.706 1.002l-.44-.572a3.576 3.576 0 01-.492-.844 2.442 2.442 0 01-.144-.835c0-.803.258-1.44.773-1.913.52-.477 1.226-.715 2.115-.715.854 0 1.529.218 2.024.655.495.437.743 1.026.743 1.77 0 .562-.147 1.066-.44 1.513-.288.441-.743.858-1.364 1.25l1.6 1.957c.15-.246.27-.522.355-.828.091-.306.155-.648.19-1.024h1.97a6.483 6.483 0 01-.408 1.814 5.604 5.604 0 01-.895 1.529l2.032 2.454h-2.578l-.758-.926a4.741 4.741 0 01-1.47.926 4.572 4.572 0 01-1.668.309c-1.031 0-1.875-.304-2.532-.911-.652-.607-.978-1.383-.978-2.327 0-.702.182-1.307.546-1.814.364-.507.97-.996 1.82-1.468"/><path id="text5163" fill="#181717" fill-rule="nonzero" d="M288.564 36.352h-2.353c.084-1.6.454-3.187 1.11-4.76.66-1.574 1.602-3.12 2.824-4.64h-5.54v-1.999h7.987v1.762c-1.238 1.42-2.19 2.923-2.856 4.507-.661 1.585-1.052 3.295-1.172 5.13"/><path id="path3094" fill="#181717" fill-rule="nonzero" d="M506.735 48.674l-1.417 2.151-1.368-1.032 1.546-2.091-2.255-.677.524-1.761 2.165.832v-2.49h1.594v2.49l2.166-.815.54 1.761-2.255.66 1.53 2.073-1.4 1.085-1.37-2.186"/><path id="path3092" fill="#181717" fill-rule="nonzero" d="M325.79 31.784c0 .541.15.959.45 1.252.304.294.738.44 1.302.44.537 0 .959-.149 1.264-.447.31-.3.465-.714.465-1.245 0-.51-.158-.92-.473-1.228-.315-.31-.734-.464-1.256-.464s-.946.157-1.272.471c-.32.315-.48.722-.48 1.221m.178-4.745c0 .428.134.758.403.99.269.226.654.34 1.155.34.502 0 .887-.116 1.156-.348.274-.232.41-.56.41-.982 0-.412-.139-.736-.418-.973-.28-.237-.662-.356-1.148-.356-.475 0-.855.121-1.14.363-.279.242-.418.564-.418.966m-.799 2.149c-.465-.258-.801-.56-1.008-.905-.207-.345-.31-.785-.31-1.321 0-.948.326-1.692.977-2.233.651-.541 1.55-.812 2.698-.812 1.158 0 2.063.27 2.714.812.657.535.985 1.28.985 2.233 0 .51-.111.953-.333 1.33-.223.37-.556.669-1 .896.542.252.95.602 1.224 1.05.274.444.411.985.411 1.624 0 1.076-.356 1.921-1.07 2.534-.708.614-1.685.92-2.93.92-1.262 0-2.242-.304-2.94-.912-.697-.608-1.046-1.455-1.046-2.542 0-.634.129-1.165.387-1.592.264-.433.678-.794 1.241-1.082"/><path id="path3112" fill="#181717" fill-rule="nonzero" d="M330.53 5.264c-.81 1.15-1.412 2.32-1.806 3.51a11.87 11.87 0 00-.59 3.748c0 1.302.197 2.549.59 3.74.394 1.19.995 2.36 1.805 3.51h-1.857c-1.028-1.216-1.808-2.437-2.342-3.663-.528-1.231-.793-2.427-.793-3.587 0-1.16.265-2.356.793-3.587.534-1.231 1.314-2.455 2.342-3.67h1.857"/><path id="path3110" fill="#181717" fill-rule="nonzero" d="M369.808 27.766c0-.634-.18-1.134-.537-1.5-.353-.37-.835-.556-1.447-.556-.578 0-1.028.178-1.352.533-.318.356-.476.853-.476 1.492 0 .597.167 1.064.502 1.399.335.334.806.502 1.412.502.595 0 1.06-.165 1.395-.495.335-.33.503-.788.503-1.375m.043 2.882c-.289.258-.63.451-1.022.58a4.243 4.243 0 01-1.326.193c-1.219 0-2.195-.327-2.928-.981-.734-.655-1.1-1.53-1.1-2.628 0-1.164.398-2.105 1.195-2.82.797-.717 1.848-1.075 3.154-1.075 1.513 0 2.663.466 3.448 1.399.792.927 1.187 2.282 1.187 4.065 0 1.916-.421 3.385-1.265 4.405-.843 1.02-2.056 1.53-3.639 1.53-1.092 0-1.972-.252-2.642-.757-.67-.51-1.037-1.203-1.1-2.08l2.503.009c.058.355.214.62.468.796.254.175.612.262 1.074.262.624 0 1.1-.242 1.43-.726.33-.484.517-1.208.563-2.172"/><path id="path3121" fill="#181717" fill-rule="nonzero" d="M364.473 5.264h1.875c1.02 1.211 1.796 2.432 2.324 3.663.528 1.227.792 2.425.792 3.595 0 1.165-.264 2.363-.792 3.594-.528 1.232-1.303 2.45-2.324 3.656h-1.875c.815-1.155 1.42-2.328 1.813-3.518.4-1.196.599-2.44.599-3.732 0-1.297-.2-2.541-.599-3.732-.393-1.19-.998-2.366-1.813-3.526"/><path id="path3119" fill="#181717" fill-rule="nonzero" d="M405.986 29.62c0 1.349.15 2.328.451 2.937.307.61.793.915 1.459.915.665 0 1.152-.308 1.458-.922.307-.615.46-1.592.46-2.93 0-1.343-.153-2.32-.46-2.929-.306-.61-.793-.914-1.458-.914-.666 0-1.152.305-1.459.914-.3.605-.451 1.581-.451 2.93m-2.578 0c0-1.907.37-3.333 1.11-4.278.747-.95 1.873-1.426 3.378-1.426 1.499 0 2.622.478 3.368 1.434.752.95 1.129 2.379 1.129 4.285 0 1.906-.374 3.33-1.12 4.27-.741.94-1.867 1.41-3.377 1.41-1.505 0-2.63-.473-3.377-1.418-.74-.945-1.111-2.371-1.111-4.278"/><path id="text5187" fill="#181717" fill-rule="nonzero" d="M453.324 136.87h7.987v1.58h-7.987v-1.58m1.802 14.508v-2.122h4.383v2.122h-4.383"/><path id="path2908" fill="#181717" fill-rule="nonzero" d="M506.976 65.368h1.515v4.328h3.735v1.69h-3.735v4.345h-1.515v-4.346h-3.735v-1.689h3.735v-4.328"/><path id="path2906" fill="#181717" fill-rule="nonzero" d="M403.408 12.951h8.985v1.64h-8.985v-1.64m0-3.542h8.985v1.64h-8.985v-1.64"/><g id="g3468" transform="translate(522.21 13.554)"><path id="path5439" stroke="#181717" stroke-width="3" d="M34.942 5.448H6.61"/><path id="path5441" fill="#181717" d="M10.219 10.79V.105L.329 5.448z"/></g><g id="g5459" transform="translate(10.063 48.788)"><path id="path5453" stroke="#181717" stroke-width="3" d="M25.624 5.699H6.669"/><path id="path5455" fill="#181717" d="M10.649 11.043V.356L.666 5.7z"/><path id="path5457" stroke="#181717" stroke-width="3" d="M.666.356v10.687"/></g><g id="g5464" transform="rotate(-180 18.01 35.275)"><path id="path5466" stroke="#181717" stroke-width="3" d="M25.624 5.699H6.669"/><path id="path5468" fill="#181717" d="M10.649 11.043V.356L.666 5.7z"/><path id="path5470" stroke="#181717" stroke-width="3" d="M.666.356v10.687"/></g><path id="text5474" fill="#181717" fill-rule="nonzero" d="M71.803 52.199l-1.188-1.172 1.264-1.326 1.219 1.203c.162-.309.286-.66.373-1.056a6.08 6.08 0 00.13-1.296c0-1.248-.278-2.217-.83-2.906-.554-.694-1.329-1.04-2.324-1.04-.985 0-1.751.344-2.3 1.032-.548.689-.822 1.66-.822 2.914 0 1.25.274 2.22.822 2.915.549.688 1.315 1.033 2.3 1.033.254 0 .493-.026.716-.077a2.86 2.86 0 00.64-.224m1.622 1.55c-.38.257-.825.452-1.333.585a6.39 6.39 0 01-1.645.2c-1.675 0-3.008-.539-3.998-1.618-.985-1.08-1.477-2.534-1.477-4.364 0-1.834.492-3.289 1.477-4.363.99-1.08 2.323-1.62 3.998-1.62 1.676 0 3.008.54 3.999 1.62.995 1.08 1.492 2.534 1.492 4.363 0 .802-.101 1.537-.304 2.205a5.234 5.234 0 01-.9 1.743l1.22 1.18-1.25 1.325-1.279-1.256"/><path id="text5482" fill="#181717" fill-rule="nonzero" d="M105.05 55.005l-3.14-11.399h2.337l1.876 8.04 1.585-8.04h2.404l1.585 8.04 1.875-8.04h2.315l-3.133 11.4h-2.151l-1.697-8.73-1.704 8.73h-2.151"/><path id="text5492" fill="#181717" fill-rule="nonzero" d="M144.839 55.005V43.606h8.692v1.981h-6.261v2.43h5.724v1.95h-5.724V52.9h6.554v2.105h-8.985"/><path id="text5500" fill="#181717" fill-rule="nonzero" d="M187.015 48.59h2.634c.573 0 .992-.121 1.259-.364.271-.242.407-.624.407-1.145 0-.495-.131-.87-.393-1.122-.261-.258-.65-.387-1.169-.387h-2.738v3.018m-2.243 6.415V43.606h5.284c1.19 0 2.07.266 2.643.797.572.532.858 1.344.858 2.438 0 .696-.14 1.277-.422 1.741a2.108 2.108 0 01-1.199.952c.474.175.81.444 1.007.805.202.36.318.923.348 1.687l.044 1.346v.047c.015.68.156 1.093.422 1.238v.348H191.3a2.318 2.318 0 01-.185-.588 6.4 6.4 0 01-.074-.843l-.03-1.2c-.024-.707-.153-1.184-.385-1.432-.227-.247-.639-.371-1.236-.371h-2.375v4.434h-2.243"/><path id="text5504" fill="#181717" fill-rule="nonzero" d="M228.05 55.005v-9.364h-3.345v-2.035h8.986v2.035h-3.322v9.364h-2.319"/><path id="text5518" fill="#181717" fill-rule="nonzero" d="M101.245 134.798H98.96v-4.249l-4.037-7.15h2.8l2.376 4.914 2.196-4.914h2.611l-3.66 7.15v4.249"/><path id="text5522" fill="#181717" fill-rule="nonzero" d="M304.572 43.606h2.33v6.939c0 .856.173 1.482.518 1.877.345.39.894.586 1.645.586.761 0 1.315-.196 1.66-.586.35-.39.525-1.016.525-1.877v-6.939h2.307v7.187c0 1.356-.385 2.397-1.157 3.123-.767.726-1.873 1.09-3.32 1.09-1.457 0-2.574-.361-3.35-1.082-.772-.726-1.158-1.77-1.158-3.131v-7.187"/><path id="text5526" fill="#181717" fill-rule="nonzero" d="M347.5 55.005V43.606h1.998v11.4H347.5"/><path id="text5530" fill="#181717" fill-rule="nonzero" d="M384.8 48.788c0 1.298.274 2.307.823 3.028.549.716 1.316 1.074 2.303 1.074.996 0 1.772-.358 2.326-1.074.554-.72.831-1.73.831-3.028s-.277-2.305-.831-3.021c-.554-.721-1.33-1.082-2.326-1.082-.987 0-1.754.358-2.303 1.074-.55.716-.824 1.725-.824 3.029m-2.356 0c0-1.907.493-3.419 1.48-4.535.99-1.122 2.325-1.683 4.003-1.683s3.012.56 4.004 1.683c.996 1.121 1.494 2.633 1.494 4.535 0 1.901-.498 3.413-1.494 4.535-.992 1.121-2.326 1.682-4.004 1.682-1.678 0-3.013-.56-4.004-1.682-.986-1.122-1.48-2.634-1.48-4.535"/><path id="text5534" fill="#181717" fill-rule="nonzero" d="M425.808 48.884h2.338c.633 0 1.093-.129 1.38-.387.288-.263.432-.684.432-1.261 0-.542-.141-.952-.423-1.23-.282-.28-.703-.419-1.261-.419h-2.466v3.297m-.016 2.066v4.055h-2.418V43.606h5.227c1.234 0 2.168.312 2.8.937.64.619.958 1.53.958 2.731 0 1.177-.31 2.085-.933 2.724-.623.635-1.511.952-2.665.952h-2.969"/><path id="path3102" fill="#C9DCEA" fill-rule="nonzero" d="M311.56 21.86v1.6c-.049 0-.118-.003-.206-.008a3.788 3.788 0 00-.182-.007c-.556 0-.933.1-1.131.298-.193.194-.29.608-.29 1.24v1.838c0 .755-.124 1.291-.371 1.608-.248.316-.694.543-1.339.68.645.139 1.09.363 1.339.675.247.311.371.844.371 1.6v1.845c0 .628.097 1.038.29 1.232.192.194.57.291 1.131.291.033 0 .094-.002.182-.007s.157-.008.207-.008v1.6c-.077 0-.185.003-.322.008-.138.005-.24.007-.306.007-.551 0-1.01-.03-1.38-.092a3.388 3.388 0 01-.942-.283 1.495 1.495 0 01-.67-.704c-.126-.291-.19-.799-.19-1.524V31.82c0-.7-.14-1.194-.42-1.485-.281-.296-.755-.444-1.422-.444-.033 0-.088.002-.165.007a2.87 2.87 0 01-.173.008v-1.6c.038 0 .096.003.173.008.077.005.132.007.165.007.661 0 1.132-.148 1.413-.444.287-.296.43-.796.43-1.5v-1.914c0-.73.063-1.243.19-1.539.132-.296.355-.53.67-.704.258-.128.572-.222.941-.284a8.644 8.644 0 011.686-.084c.137.005.245.008.322.008"/><path id="text5546" fill="#C9DCEA" fill-rule="nonzero" d="M347.5 22.88h3.994v1.62h-1.858v11.27h1.858v1.619h-3.993V22.88"/><path id="path3106" fill="#C9DCEA" fill-rule="nonzero" d="M425.371 21.845h.562c.606 0 1.093.03 1.462.092.37.06.678.158.926.29.314.164.534.4.66.706.133.301.199.807.199 1.517v1.932c0 .7.14 1.198.421 1.494.281.291.755.437 1.421.437.033 0 .088-.003.166-.008a2.88 2.88 0 01.173-.007v1.601h-.306c-.688 0-1.173.143-1.454.43-.28.286-.421.781-.421 1.486v1.932c0 .73-.066 1.244-.198 1.54a1.381 1.381 0 01-.661.69 3.386 3.386 0 01-.942.283 8.634 8.634 0 01-1.686.085 9.241 9.241 0 00-.322-.008v-1.602c.05 0 .118.003.207.008.088.005.148.008.181.008.557 0 .931-.1 1.124-.3.198-.193.297-.602.297-1.226v-1.831c0-.767.124-1.306.372-1.617.248-.317.694-.542 1.339-.675-.645-.138-1.09-.365-1.339-.682-.248-.317-.372-.853-.372-1.61v-1.854c0-.623-.099-1.032-.297-1.226-.193-.2-.567-.299-1.124-.299-.033 0-.093.003-.181.008a3.778 3.778 0 01-.207.007v-1.601"/><path id="text5554" fill="#C9DCEA" fill-rule="nonzero" d="M390.43 22.88V37.39h-3.994v-1.62h1.862V24.5h-1.862v-1.618h3.993"/><path id="text5641" fill="#181717" fill-rule="nonzero" d="M79.428 86.304l-1.594 4.852h3.196l-1.602-4.852m-1.376-2.283h2.736l4.15 11.399h-2.485l-.782-2.345h-4.463l-.758 2.345h-2.493l4.095-11.4"/><path id="text5645" fill="#181717" fill-rule="nonzero" d="M114.889 92.487h2.242c.085.645.333 1.126.743 1.44.41.31 1.002.464 1.777.464.66 0 1.158-.125 1.493-.376.335-.25.502-.621.502-1.112 0-.715-.962-1.307-2.887-1.776a6.848 6.848 0 01-.3-.072c-1.03-.24-1.765-.51-2.205-.809a2.56 2.56 0 01-.893-1.072c-.205-.453-.307-.987-.307-1.6 0-1.147.365-2.025 1.095-2.633.73-.614 1.785-.92 3.165-.92 1.29 0 2.297.325 3.022.976.73.65 1.115 1.568 1.155 2.753h-2.182c-.04-.571-.245-1.006-.615-1.305-.37-.298-.898-.448-1.583-.448-.595 0-1.055.126-1.38.376-.32.246-.48.598-.48 1.057 0 .624.628 1.09 1.883 1.4l.795.2c.805.219 1.375.39 1.71.512.34.123.635.259.885.408.45.267.787.622 1.012 1.065.225.437.338.962.338 1.576 0 1.227-.388 2.18-1.163 2.857-.775.672-1.867 1.008-3.277 1.008-1.39 0-2.48-.344-3.27-1.032-.79-.688-1.215-1.667-1.275-2.937"/><path id="text5649" fill="#181717" fill-rule="nonzero" d="M156.959 93.361h1.748c1.012 0 1.743-.284 2.194-.851.455-.573.683-1.499.683-2.778 0-1.274-.21-2.21-.633-2.81-.422-.598-1.081-.897-1.978-.897h-2.014v7.336m-2.137 2.059v-11.4h4.15c1.627 0 2.838.473 3.634 1.417.8.944 1.201 2.376 1.201 4.295 0 1.042-.149 1.96-.446 2.755-.293.794-.72 1.434-1.28 1.919a3.9 3.9 0 01-1.44.782c-.536.154-1.29.232-2.258.232h-3.561"/><path id="text5653" fill="#181717" fill-rule="nonzero" d="M194.755 95.42v-11.4h7.987v1.982h-5.664v2.584h4.965v1.982h-4.965v4.852h-2.323"/><path id="text5657" fill="#181717" fill-rule="nonzero" d="M241.917 94.733c-.4.593-.856 1.029-1.368 1.306-.508.278-1.106.417-1.794.417-1.507 0-2.73-.572-3.667-1.715-.931-1.148-1.397-2.654-1.397-4.519 0-1.88.466-3.384 1.397-4.51.932-1.128 2.174-1.691 3.726-1.691 1.352 0 2.454.355 3.308 1.065.854.705 1.362 1.678 1.523 2.917h-2.262c-.137-.614-.417-1.082-.842-1.402-.42-.32-.968-.481-1.647-.481-.902 0-1.612.363-2.13 1.09-.512.72-.768 1.72-.768 2.996 0 1.282.268 2.286.805 3.013.537.726 1.274 1.09 2.21 1.09.703 0 1.291-.227 1.764-.681.474-.454.767-1.077.879-1.867h-2.445v-2.02h4.465v6.386h-1.486l-.27-1.394"/><path id="text5661" fill="#181717" fill-rule="nonzero" d="M274.622 95.42v-11.4h2.25v4.25h4.485v-4.25h2.25v11.4h-2.25v-5.054h-4.485v5.054h-2.25"/><path id="text5665" fill="#181717" fill-rule="nonzero" d="M314.556 90.978h2.484v1.34c0 .386.13.682.39.888.26.2.633.301 1.12.301.53 0 .9-.123 1.11-.369.209-.246.313-.707.313-1.385v-7.732h2.57v7.837c0 .703-.049 1.22-.145 1.551a2.23 2.23 0 01-.458.866c-.327.372-.777.655-1.348.851-.57.196-1.24.294-2.009.294-.707 0-1.331-.086-1.874-.256-.542-.171-.995-.424-1.356-.76a2.392 2.392 0 01-.62-.904c-.118-.337-.177-.889-.177-1.657v-.865"/><path id="text5669" fill="#181717" fill-rule="nonzero" d="M353.49 95.42v-11.4h2.31v4.683l4.382-4.682h2.888l-4.48 4.612 4.884 6.787h-2.82l-3.658-5.216-1.196 1.207v4.009h-2.31"/><path id="text5673" fill="#181717" fill-rule="nonzero" d="M394.423 95.42v-11.4h2.368v9.295h5.618v2.105h-7.986"/><path id="text5679" fill="#181717" fill-rule="nonzero" d="M264.639 55.005v-1.98l6.156-7.353h-6.033v-2.066h8.862v1.981l-6.172 7.36h6.034v2.058h-8.847"/><path id="text5683" fill="#181717" fill-rule="nonzero" d="M134.855 134.798l3.55-5.82-3.55-5.579h2.684l2.308 3.985 2.293-3.985h2.699l-3.55 5.564 3.55 5.835h-2.684l-2.308-3.947-2.308 3.947h-2.684"/><path id="text5687" fill="#181717" fill-rule="nonzero" d="M184.772 131.451c-.084 1.341-.564 2.407-1.441 3.197-.872.79-2.01 1.186-3.417 1.186-1.62 0-2.88-.545-3.78-1.634-.897-1.09-1.345-2.618-1.345-4.583 0-2.009.458-3.547 1.374-4.616.916-1.068 2.233-1.602 3.952-1.602 1.396 0 2.498.369 3.305 1.106.812.731 1.258 1.768 1.337 3.108h-2.22c-.095-.667-.347-1.175-.758-1.522-.412-.352-.966-.529-1.664-.529-.99 0-1.743.345-2.259 1.034-.515.689-.772 1.696-.772 3.02 0 1.283.255 2.273.765 2.973.515.7 1.246 1.05 2.191 1.05.684 0 1.243-.187 1.68-.561.435-.38.717-.921.846-1.627h2.206"/><path id="text5691" fill="#181717" fill-rule="nonzero" d="M217.625 134.798l-3.901-11.399h2.58l2.404 8.528 2.45-8.528h2.55l-3.856 11.399h-2.227"/><path id="text5695" fill="#181717" fill-rule="nonzero" d="M256.813 132.74h2.67c.63 0 1.088-.12 1.376-.357.287-.237.431-.61.431-1.122 0-.531-.141-.913-.424-1.145-.282-.237-.749-.356-1.398-.356h-2.655v2.98m0-4.93h2.573c.555 0 .962-.098 1.22-.294.258-.201.387-.516.387-.944 0-.418-.127-.72-.38-.906-.248-.19-.662-.286-1.242-.286h-2.558v2.43m-2.157 6.988v-11.399h5.161c1.121 0 1.974.248 2.56.743.59.49.884 1.205.884 2.143 0 .578-.109 1.06-.327 1.448a2.183 2.183 0 01-.982.897c.565.238.987.58 1.265 1.03.282.443.424.998.424 1.663 0 1.11-.348 1.966-1.042 2.57-.694.603-1.678.905-2.953.905h-4.99"/><path id="text5699" fill="#181717" fill-rule="nonzero" d="M294.589 134.798v-11.399h2.346l4.426 7.831V123.4h2.213v11.399h-2.317l-4.455-7.832v7.832h-2.213"/><path id="text5703" fill="#181717" fill-rule="nonzero" d="M333.524 134.798v-11.399h3.324l2.174 8.675 2.145-8.675h3.339v11.399h-2.107v-9.194l-2.22 9.194h-2.3l-2.248-9.194v9.194h-2.107"/><g id="g3476" transform="translate(561.145 70.55)"><path id="path5745" fill="#181717" d="M10.246 14.192V4.731L0 9.46z"/><path id="path5747" stroke="#181717" stroke-width="3" d="M25.615 0v9.462H5.123"/></g><path id="path5757" stroke="#181717" stroke-width="2" d="M18.55 130.653l-7.488 9.672h4.991v4.836h4.992v-4.836h4.992z"/><path id="path5801" stroke="#181717" stroke-width="2" d="M501.744 130.653l-7.488 9.672h4.992v4.836h4.992v-4.836h4.991z"/><path id="path3083" fill="#181717" fill-rule="nonzero" d="M447.271 12.398c0-.055-.002-.128-.008-.219a4.189 4.189 0 01-.008-.21c0-.443.051-.81.153-1.102.101-.297.264-.574.488-.83.171-.191.425-.41.761-.656.342-.247.564-.425.665-.536.214-.226.36-.43.44-.611.08-.181.12-.38.12-.596 0-.478-.14-.85-.424-1.117-.283-.266-.678-.4-1.185-.4-.508 0-.908.161-1.202.483-.288.317-.446.765-.473 1.343h-2.259v-.234c0-1.06.356-1.906 1.066-2.534.715-.634 1.677-.951 2.884-.951 1.233 0 2.213.3 2.94.898.731.593 1.097 1.39 1.097 2.391 0 .352-.043.67-.128.95-.08.277-.206.531-.377.763-.219.291-.558.608-1.017.95-.454.337-.729.546-.825.626-.203.186-.35.383-.44.589a1.927 1.927 0 00-.12.867c.005.06.007.106.007.136h-2.155m-.112 3.229v-2.21h2.363v2.21h-2.363"/><path id="text5819" fill="#181717" fill-rule="nonzero" d="M286.602 17.7l3.912-13.472h1.08l-3.927 13.471h-1.065"/><path id="text5928" fill="#C9DCEA" fill-rule="nonzero" d="M173.79 71.348c-.084 1.34-.564 2.406-1.44 3.197-.872.79-2.011 1.186-3.418 1.186-1.619 0-2.88-.545-3.78-1.635-.897-1.09-1.345-2.617-1.345-4.583 0-2.008.458-3.547 1.374-4.615.916-1.068 2.234-1.603 3.952-1.603 1.396 0 2.498.369 3.305 1.106.813.732 1.258 1.768 1.337 3.109h-2.22c-.095-.668-.347-1.175-.758-1.522-.411-.353-.966-.53-1.664-.53-.99 0-1.743.345-2.258 1.034-.515.69-.773 1.696-.773 3.021 0 1.282.255 2.273.765 2.973.515.7 1.246 1.05 2.192 1.05.683 0 1.243-.188 1.678-.562.436-.379.718-.921.847-1.626h2.206"/><path id="text5956" fill="#C9DCEA" fill-rule="nonzero" d="M161.288 70.602h7.481l-.475.983h-7.482l.476-.983m1.027-2.125h7.482l-.476.983h-7.481l.475-.983"/><path id="path3060" fill="#181717" fill-rule="nonzero" d="M246.307 31.467c0 .634.177 1.136.53 1.507.36.371.846.557 1.46.557.573 0 1.022-.18 1.347-.541.324-.36.486-.863.486-1.507 0-.593-.168-1.054-.504-1.383-.336-.33-.808-.495-1.416-.495-.597 0-1.063.165-1.4.495-.335.33-.503.785-.503 1.367m-.035-2.89c.284-.257.626-.45 1.025-.58.4-.133.846-.2 1.339-.2 1.216 0 2.19.33 2.92.989.735.66 1.103 1.538 1.103 2.635 0 1.164-.4 2.105-1.2 2.82-.799.717-1.853 1.075-3.162 1.075-1.512 0-2.662-.464-3.45-1.391-.782-.927-1.173-2.285-1.173-4.073 0-1.921.42-3.39 1.26-4.405.84-1.02 2.05-1.53 3.632-1.53 1.1 0 1.987.255 2.66.765.677.51 1.048 1.2 1.111 2.071h-2.52c-.058-.355-.214-.623-.469-.803-.255-.18-.611-.27-1.069-.27-.625 0-1.106.241-1.442.726-.336.479-.524 1.203-.565 2.171"/><path id="rect10188" fill="#FFF" stroke="#181717" d="M508.233 79.876h39.933v39.378h-39.933z"/><path id="path2917" fill="#C9DCEA" fill-rule="nonzero" d="M532.193 69.513v1.784c-.512.383-.997.665-1.455.848a3.66 3.66 0 01-1.344.267c-.226 0-.452-.022-.679-.065a4.552 4.552 0 01-.68-.186 22.53 22.53 0 01-.524-.201c-1.078-.404-1.897-.606-2.458-.606-.419 0-.857.102-1.315.307-.453.199-.962.52-1.528.96v-1.784c.526-.387 1.029-.675 1.506-.864.478-.194.928-.29 1.351-.29.576 0 1.293.156 2.15.468a.111.111 0 00.029.008c.088.032.224.083.406.153.763.296 1.354.444 1.772.444.418 0 .85-.1 1.292-.298.443-.2.935-.514 1.477-.945"/><path id="path2915" fill="#181717" fill-rule="nonzero" d="M517.137 108.474l-.651 1.887h1.856l.636-1.887h-1.841m0-4.764h1.634l-1.08 3.21h1.79l1.094-3.21h1.635l-1.095 3.21h2.093l-.547 1.554h-2.07l-.622 1.871h2.145l-.526 1.547h-2.152l-1.094 3.217h-1.634l1.094-3.217h-1.804l-1.102 3.217h-1.627l1.08-3.217h-2.123l.562-1.547h2.086l.636-1.871h-2.211l.547-1.555h2.196l1.095-3.21"/><path id="rect10196" fill="#FFF" stroke="#181717" d="M49.997 119.254H89.93v39.378H49.997z"/><path id="text5910" fill="#C9DCEA" fill-rule="nonzero" d="M106.902 31.171c.018-.655.181-1.209.49-1.661.316-.452.87-.91 1.661-1.373l.473-.262c1.101-.594 1.652-1.167 1.652-1.72 0-.323-.11-.577-.33-.763-.22-.187-.524-.28-.911-.28-.428 0-.759.116-.99.347-.233.226-.349.551-.349.975v.068h-1.553c0-.83.259-1.47.776-1.915.518-.447 1.259-.67 2.223-.67.869 0 1.56.203 2.071.61.518.401.777.938.777 1.61 0 .486-.134.904-.402 1.255-.268.35-.791.754-1.571 1.211-.173.108-.417.249-.732.424-.714.395-1.116.706-1.205.932h3.838v1.212h-5.918"/><path id="text5922" fill="#C9DCEA" fill-rule="nonzero" d="M146.835 29.844h1.603c.012.4.127.7.344.898.217.197.543.296.978.296.417 0 .74-.093.969-.28.229-.187.343-.453.343-.799 0-.35-.132-.614-.396-.79-.264-.181-.66-.272-1.19-.272h-.255v-.98h.185c.488 0 .846-.076 1.075-.23.235-.16.352-.4.352-.725 0-.274-.1-.49-.3-.65-.199-.165-.466-.247-.8-.247-.37 0-.656.093-.855.28-.2.181-.3.442-.3.782v.05h-1.568c.018-.72.265-1.269.74-1.647.482-.385 1.166-.577 2.053-.577.834 0 1.491.17 1.973.51.487.341.731.805.731 1.392 0 .308-.085.58-.255.815-.165.231-.412.42-.74.569.428.159.751.381.969.667.223.28.334.609.334.988 0 .713-.276 1.279-.828 1.696-.546.411-1.292.617-2.237.617-.934 0-1.656-.203-2.167-.609-.505-.406-.758-.98-.758-1.72v-.034"/><path id="path3131" fill="#181717" fill-rule="nonzero" d="M131.142 12.276c.232-.12.406-.254.522-.4a.747.747 0 00.174-.472.728.728 0 00-.2-.519c-.133-.147-.409-.317-.826-.51l-2.306-1.078c-.226.121-.4.257-.522.41a.789.789 0 00-.174.486c0 .205.084.386.253.543.174.152.554.364 1.14.636l1.94.904m-4.733 2.57h2.149c.046.41.18.713.4.912.226.2.545.299.957.299.383 0 .687-.081.913-.244a.799.799 0 00.34-.676c0-.23-.085-.43-.253-.597-.168-.173-.501-.37-1-.59l-2.08-.95c-.66-.3-1.154-.642-1.479-1.03a1.98 1.98 0 01-.487-1.305c0-.466.125-.875.374-1.226.256-.356.63-.652 1.123-.888a2.377 2.377 0 01-.644-.77 2.09 2.09 0 01-.209-.936c0-.786.299-1.417.896-1.894.598-.482 1.392-.723 2.384-.723 1.02 0 1.821.236 2.401.707.58.472.879 1.124.896 1.957h-2.053c-.012-.35-.128-.618-.348-.801-.215-.184-.525-.275-.93-.275-.36 0-.639.07-.836.212a.7.7 0 00-.287.597c0 .21.113.406.34.59.231.178.646.393 1.243.644l1.462.613c.742.32 1.29.676 1.644 1.07.354.387.53.835.53 1.343 0 .477-.133.894-.4 1.25-.26.35-.637.623-1.13.817.336.267.588.564.757.888.168.325.252.682.252 1.07 0 .806-.32 1.472-.957 1.996-.638.529-1.459.793-2.462.793-1.102 0-1.95-.24-2.54-.723-.592-.482-.914-1.192-.966-2.13"/><path id="text6073" fill="#181717" fill-rule="nonzero" d="M444.34 35.039v-8.34c0-.83.334-1.5 1.002-2.01.668-.514 1.559-.772 2.672-.772 1.135 0 2.023.25 2.665.75.642.5.963 1.187.963 2.062 0 .54-.095.983-.287 1.328-.186.345-.477.61-.87.795.611.235 1.07.58 1.375 1.035.31.455.466 1.014.466 1.68 0 1.12-.334 2.024-1.002 2.714-.668.69-1.544 1.035-2.626 1.035-.15 0-.319-.007-.505-.022a10.34 10.34 0 01-.59-.068v-1.755a2.769 2.769 0 00.52.03c.611 0 1.083-.162 1.414-.487.331-.33.497-.798.497-1.403 0-.585-.181-1.03-.544-1.334-.357-.305-.88-.458-1.569-.458h-.21l.008-1.537.101.015h.163c.461 0 .81-.11 1.049-.33.243-.225.365-.55.365-.975 0-.425-.127-.748-.38-.968-.25-.225-.614-.337-1.096-.337-.445 0-.785.125-1.018.375-.233.245-.35.605-.35 1.08v7.897h-2.214"/><path id="path2750" fill="#181717" fill-rule="nonzero" d="M417.384 129.151v-2.643h1.997v2.643h-1.997m0 6.683v-2.626h1.997v2.626h-1.997"/><path id="path2746" fill="#181717" fill-rule="nonzero" d="M377.464 128.949v-2.441h1.984v2.44h-1.984m0 8.959v-.943c.37-.129.641-.327.817-.596.176-.268.264-.618.264-1.047v-.202h-1.094v-2.424h1.997v2.328c0 .805-.167 1.45-.501 1.933-.334.489-.828.806-1.483.95"/><path id="text5803" fill="#181717" fill-rule="nonzero" d="M377.45 157.596v-.937c.37-.128.642-.326.818-.593.176-.267.264-.614.264-1.04v-.201h-1.081v-2.41h1.997v2.314c0 .795-.17 1.436-.508 1.922-.334.486-.83.8-1.49.945"/><path id="text5813" fill="#181717" fill-rule="nonzero" d="M417.384 154.487v-2.072h1.997v2.072h-1.997"/><path id="path2737" fill="#181717" fill-rule="nonzero" d="M63.973 145.16v1.75l-6.81 2.918 6.81 2.909v1.75l-8.985-3.876v-1.59l8.985-3.86"/><path id="path2742" fill="#181717" fill-rule="nonzero" d="M54.988 125.472l8.985 3.86v1.59l-8.985 3.876v-1.75l6.827-2.91-6.827-2.916v-1.75"/><path id="text6003" fill="#181717" fill-rule="nonzero" d="M477.764 86.458l-1.594 4.77h3.196l-1.602-4.77m-1.375-2.244h2.735l4.15 11.206h-2.485l-.782-2.305h-4.463l-.758 2.305h-2.493l4.096-11.206m1.868-1.43v-1.872h1.766v1.871h-1.766m-2.72 0v-1.871h1.766v1.871h-1.766"/><path id="text6023" fill="#181717" fill-rule="nonzero" d="M464.306 43.7h2.33v6.881c0 .85.173 1.47.518 1.862.345.388.893.581 1.645.581.761 0 1.314-.193 1.66-.58.35-.388.525-1.009.525-1.863V43.7h2.307v7.127c0 1.346-.386 2.378-1.157 3.098-.767.72-1.873 1.08-3.32 1.08-1.457 0-2.574-.357-3.35-1.072-.772-.72-1.158-1.755-1.158-3.106V43.7m4.972-1.37v-1.833H471v1.833h-1.72m-2.65 0v-1.833h1.72v1.833h-1.72"/><path id="text6041" fill="#181717" fill-rule="nonzero" d="M434.716 89.64c0 1.207.274 2.145.824 2.816.549.665 1.316.998 2.303.998.996 0 1.771-.333 2.326-.998.554-.67.83-1.61.83-2.816 0-1.206-.276-2.142-.83-2.807-.555-.67-1.33-1.006-2.326-1.006-.987 0-1.754.333-2.303.998-.55.666-.824 1.604-.824 2.815m-2.357 0c0-1.772.494-3.177 1.48-4.215.991-1.043 2.326-1.564 4.004-1.564 1.677 0 3.012.521 4.003 1.564.997 1.043 1.495 2.448 1.495 4.215 0 1.768-.498 3.173-1.495 4.216-.991 1.042-2.326 1.564-4.003 1.564-1.678 0-3.013-.522-4.004-1.564-.986-1.043-1.48-2.448-1.48-4.216m5.964-6.896v-1.832h1.724v1.832h-1.724m-2.654 0v-1.832h1.724v1.832h-1.724"/><path id="path2893" fill="#C9DCEA" fill-rule="nonzero" d="M90.991 73.43c-.274.422-.59.733-.949.934-.359.195-.782.293-1.27.293-.788 0-1.388-.215-1.802-.647-.408-.431-.613-1.069-.613-1.912 0-1.199.347-2.205 1.04-3.018.697-.812 1.554-1.219 2.57-1.219.4 0 .745.083 1.04.249.293.165.535.411.724.737l.397-.737h1.33l-1.099 4.5a1.757 1.757 0 00-.052.309c0 .175.06.308.18.399.119.085.296.128.53.128.194 0 .396-.05.605-.151.215-.1.414-.24.598-.421a3.96 3.96 0 00.972-1.408 4.545 4.545 0 00.336-1.768c0-1.205-.463-2.193-1.39-2.966-.922-.777-2.113-1.166-3.573-1.166a7.25 7.25 0 00-1.965.256 5.609 5.609 0 00-1.645.76 5.949 5.949 0 00-1.958 2.145 5.946 5.946 0 00-.68 2.822c0 1.54.516 2.772 1.547 3.695 1.032.918 2.41 1.378 4.133 1.378.808 0 1.595-.123 2.362-.37a7.857 7.857 0 002.153-1.068l.613.88a8.585 8.585 0 01-2.43 1.303 8.199 8.199 0 01-2.668.436c-.956 0-1.836-.123-2.638-.369a6.607 6.607 0 01-2.138-1.076c-.772-.607-1.35-1.307-1.734-2.1-.383-.792-.575-1.69-.575-2.694 0-.838.13-1.636.388-2.393a6.747 6.747 0 011.159-2.077 7.198 7.198 0 012.66-2.062c1.037-.467 2.19-.7 3.461-.7.842 0 1.632.115 2.37.346a6.101 6.101 0 011.935.963c.673.527 1.174 1.129 1.503 1.806.334.673.5 1.433.5 2.28 0 .829-.164 1.594-.493 2.296a4.984 4.984 0 01-1.405 1.791c-.349.281-.73.497-1.144.648a3.781 3.781 0 01-1.278.218c-.528 0-.926-.106-1.195-.316-.265-.211-.402-.522-.412-.933m.374-3.222c-.065-.406-.21-.715-.433-.925-.22-.216-.511-.324-.875-.324-.568 0-1.061.311-1.48.933-.418.622-.628 1.37-.628 2.243 0 .462.1.813.3 1.054.204.24.498.36.881.36.414 0 .79-.157 1.129-.473.344-.316.578-.728.703-1.234l.403-1.634"/><path id="path2898" fill="#C9DCEA" fill-rule="nonzero" d="M469.216 37.389l-3.912-13.472h1.065l3.927 13.472h-1.08"/><path id="path2919" fill="#181717" fill-rule="nonzero" d="M516.22 82.984h1.996v5.182h-1.996v-5.182"/><path id="text6099" fill="#D35155" fill-rule="nonzero" d="M490.263 22.88l-2.747 3.11h-1.246l1.729-3.11h2.264"/><path id="text5103" fill="#D35155" fill-rule="nonzero" d="M485.271 3.192h2.265l1.729 3.109h-1.247l-2.747-3.11"/><path id="text6117" fill="#C9DCEA" fill-rule="nonzero" d="M356.42 146.197h2.083l-.548 3.24c-.072.398-.127.776-.166 1.133a8.3 8.3 0 00-.057.864c0 .462.1.808.302 1.036.202.224.51.335.922.335.48 0 .853-.203 1.117-.61.27-.408.493-1.13.67-2.169l.649-3.83h2.082l-1.39 8.137h-1.931l.13-.872c-.202.387-.428.67-.678.85a1.439 1.439 0 01-.872.267c-.322 0-.608-.074-.857-.223-.25-.144-.476-.37-.678-.678l-.648 3.919h-2.06l1.93-11.4"/><path id="path3396" fill="#C9DCEA" fill-rule="nonzero" d="M78.948 141.016h1.997v15.544h-1.997v-15.544"/><path id="path3403" fill="#181717" fill-rule="nonzero" d="M9.564 5.327c-.4 0-.744.145-1.03.435-.28.29-.42.64-.42 1.048 0 .42.14.776.42 1.065.28.29.624.435 1.03.435.395 0 .733-.148 1.013-.443.28-.296.42-.648.42-1.057 0-.409-.14-.758-.42-1.048a1.358 1.358 0 00-1.013-.435m0-1.099c.692 0 1.28.256 1.763.767a2.54 2.54 0 01.733 1.832 2.53 2.53 0 01-.733 1.824 2.382 2.382 0 01-1.78.758 2.36 2.36 0 01-1.762-.75c-.478-.5-.717-1.11-.717-1.832 0-.721.242-1.335.725-1.84a2.373 2.373 0 011.771-.759"/><path id="text6091" fill="#D35155" fill-rule="nonzero" d="M8.632 23.917h1.865l3.56 5.181h-1.74l-2.746-3.426-2.76 3.426H5.07l3.56-5.18"/><path id="path2585" stroke="#181717" stroke-width="2" d="M18.55 109.927l7.487-9.671h-4.992V95.42h-4.992v4.836h-4.991z"/><text id="Strg" fill="#181717" fill-rule="nonzero" font-family="OpenSans-Regular, Open Sans" font-size="16" font-weight="normal"><tspan x="10.982" y="185.293">Strg</tspan></text><text id="tspan3451" fill="#181717" fill-rule="nonzero" font-family="OpenSans-Regular, Open Sans" font-size="16" font-weight="normal"><tspan x="553.078" y="185.293">Strg</tspan></text><g id="text3456" fill="#181717" fill-rule="nonzero" font-family="OpenSans-Regular, Open Sans" font-size="16" font-weight="normal" transform="translate(116.805 167.948)"><text id="tspan3460"><tspan x="0" y="17.345">Al</tspan> <tspan x="0" y="39.345">t</tspan></text></g><text id="tspan3466" fill="#C9DCEA" fill-rule="nonzero" font-family="OpenSans-Regular, Open Sans" font-size="16" font-weight="normal"><tspan x="405.324" y="185.293">Alt Gr</tspan></text><text id="Win" fill="#181717" fill-rule="nonzero" font-family="OpenSans-Regular, Open Sans" font-size="16" font-weight="normal"><tspan x="64.892" y="185.293">Win</tspan></text><text id="Win" fill="#181717" fill-rule="nonzero" font-family="OpenSans-Regular, Open Sans" font-size="16" font-weight="normal"><tspan x="464.226" y="185.293">Win</tspan></text><text id="Menu" fill="#181717" fill-rule="nonzero" font-family="OpenSans-Regular, Open Sans" font-size="14" font-weight="normal"><tspan x="499.171" y="185.293">Menu</tspan></text><circle id="Oval" cx="109.94" cy="138" r="26" stroke="#C06334" stroke-width="5"/></g></g></svg>
\ No newline at end of file
diff --git a/2-ui/3-event-details/5-keyboard-events/keyboard-dump.view/index.html b/2-ui/3-event-details/7-keyboard-events/keyboard-dump.view/index.html
similarity index 95%
rename from 2-ui/3-event-details/5-keyboard-events/keyboard-dump.view/index.html
rename to 2-ui/3-event-details/7-keyboard-events/keyboard-dump.view/index.html
index 401062830..a0d5a4f40 100644
--- a/2-ui/3-event-details/5-keyboard-events/keyboard-dump.view/index.html
+++ b/2-ui/3-event-details/7-keyboard-events/keyboard-dump.view/index.html
@@ -28,7 +28,7 @@
 
     <input type="text" placeholder="Press keys here" id="kinput">
 
-    <textarea id="area"></textarea>
+    <textarea id="area" readonly></textarea>
     <input type="button" value="Clear" onclick="area.value = ''" />
   </form>
   <script src="script.js"></script>
diff --git a/2-ui/3-event-details/5-keyboard-events/keyboard-dump.view/script.js b/2-ui/3-event-details/7-keyboard-events/keyboard-dump.view/script.js
similarity index 96%
rename from 2-ui/3-event-details/5-keyboard-events/keyboard-dump.view/script.js
rename to 2-ui/3-event-details/7-keyboard-events/keyboard-dump.view/script.js
index 5eba24c7a..d97f7a7b5 100644
--- a/2-ui/3-event-details/5-keyboard-events/keyboard-dump.view/script.js
+++ b/2-ui/3-event-details/7-keyboard-events/keyboard-dump.view/script.js
@@ -5,6 +5,8 @@ let lastTime = Date.now();
 function handle(e) {
   if (form.elements[e.type + 'Ignore'].checked) return;
 
+  area.scrollTop = 1e6;
+
   let text = e.type +
     ' key=' + e.key +
     ' code=' + e.code +
diff --git a/2-ui/3-event-details/5-keyboard-events/keyboard-dump.view/style.css b/2-ui/3-event-details/7-keyboard-events/keyboard-dump.view/style.css
similarity index 100%
rename from 2-ui/3-event-details/5-keyboard-events/keyboard-dump.view/style.css
rename to 2-ui/3-event-details/7-keyboard-events/keyboard-dump.view/style.css
diff --git a/2-ui/3-event-details/7-keyboard-events/us-layout.svg b/2-ui/3-event-details/7-keyboard-events/us-layout.svg
new file mode 100644
index 000000000..353f225f1
--- /dev/null
+++ b/2-ui/3-event-details/7-keyboard-events/us-layout.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="602" height="202" viewBox="0 0 602 202"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:&apos;PT Mono&apos;;font-weight:700;font-style:normal;src:local(&apos;PT MonoBold&apos;),url(/font/PTMonoBold.woff2) format(&apos;woff2&apos;),url(/font/PTMonoBold.woff) format(&apos;woff&apos;),url(/font/PTMonoBold.ttf) format(&apos;truetype&apos;)}</style></defs><g id="dom" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="KB_United_States-NoAltGr" transform="translate(1 1)"><path id="rect2186" fill="#FFF" stroke="#181717" d="M0 0h39.604v40H0z"/><path id="rect2218" fill="#FFF" stroke="#181717" d="M40.594 0h39.604v40H40.594z"/><path id="rect2222" fill="#FFF" stroke="#181717" d="M80.198 0h39.604v40H80.198z"/><path id="rect2228" fill="#FFF" stroke="#181717" d="M119.802 0h39.604v40h-39.604z"/><path id="rect2230" fill="#FFF" stroke="#181717" d="M160.396 0H200v40h-39.604z"/><path id="rect2232" fill="#FFF" stroke="#181717" d="M200 0h39.604v40H200z"/><path id="rect2234" fill="#FFF" stroke="#181717" d="M240.594 0h39.604v40h-39.604z"/><path id="rect2236" fill="#FFF" stroke="#181717" d="M280.198 0h39.604v40h-39.604z"/><path id="rect2238" fill="#FFF" stroke="#181717" d="M319.802 0h39.604v40h-39.604z"/><path id="rect2240" fill="#FFF" stroke="#181717" d="M360.396 0H400v40h-39.604z"/><path id="rect2242" fill="#FFF" stroke="#181717" d="M400 0h39.604v40H400z"/><path id="rect2244" fill="#FFF" stroke="#181717" d="M440.594 0h39.604v40h-39.604z"/><path id="rect2246" fill="#FFF" stroke="#181717" d="M480.198 0h39.604v40h-39.604z"/><path id="rect2248" fill="#D1CFCD" stroke="#181717" d="M519.802 0H600v40h-80.198z"/><path id="rect2250" fill="#D1CFCD" stroke="#181717" d="M0 40h60.396v40H0z"/><path id="rect2252" fill="#FFF" stroke="#181717" d="M60.396 40H100v40H60.396z"/><path id="rect2254" fill="#FFF" stroke="#181717" d="M100 40h39.604v40H100z"/><path id="rect2256" fill="#FFF" stroke="#181717" d="M140.594 40h39.604v40h-39.604z"/><path id="rect2258" fill="#FFF" stroke="#181717" d="M180.198 40h39.604v40h-39.604z"/><path id="rect2262" fill="#FFF" stroke="#181717" d="M219.802 40h39.604v40h-39.604z"/><path id="rect2264" fill="#FFF" stroke="#181717" d="M260.396 40H300v40h-39.604z"/><path id="rect2266" fill="#FFF" stroke="#181717" d="M300 40h39.604v40H300z"/><path id="rect2270" fill="#FFF" stroke="#181717" d="M340.594 40h39.604v40h-39.604z"/><path id="rect2272" fill="#FFF" stroke="#181717" d="M380.198 40h39.604v40h-39.604z"/><path id="rect2274" fill="#FFF" stroke="#181717" d="M419.802 40h39.604v40h-39.604z"/><path id="rect2278" fill="#FFF" stroke="#181717" d="M460.396 40H500v40h-39.604z"/><path id="rect2280" fill="#FFF" stroke="#181717" d="M500 40h39.604v40H500z"/><path id="rect2284" fill="#FFF" stroke="#181717" d="M539.604 40H600v40h-60.396z"/><path id="rect2286" fill="#D1CFCD" stroke="#181717" d="M0 80h70.297v40H0z"/><path id="rect2292" fill="#FFF" stroke="#181717" d="M70.297 80h39.604v40H70.297z"/><path id="rect2296" fill="#FFF" stroke="#181717" d="M109.901 80h39.604v40h-39.604z"/><path id="rect2298" fill="#FFF" stroke="#181717" d="M150.495 80h39.604v40h-39.604z"/><path id="rect2300" fill="#FFF" stroke="#181717" d="M190.099 80h39.604v40h-39.604z"/><path id="rect2302" fill="#FFF" stroke="#181717" d="M230.693 80h39.604v40h-39.604z"/><path id="rect2306" fill="#FFF" stroke="#181717" d="M270.297 80h39.604v40h-39.604z"/><path id="rect2308" fill="#FFF" stroke="#181717" d="M309.901 80h39.604v40h-39.604z"/><path id="rect2312" fill="#FFF" stroke="#181717" d="M350.495 80h39.604v40h-39.604z"/><path id="rect2314" fill="#FFF" stroke="#181717" d="M390.099 80h39.604v40h-39.604z"/><path id="rect2316" fill="#FFF" stroke="#181717" d="M430.693 80h39.604v40h-39.604z"/><path id="rect2318" fill="#FFF" stroke="#181717" d="M470.297 80h39.604v40h-39.604z"/><path id="rect2320" fill="#D1CFCD" stroke="#181717" d="M509.901 80H600v40h-90.099z"/><path id="rect2322" fill="#D1CFCD" stroke="#181717" d="M0 120h90.099v40H0z"/><path id="rect2324" fill="#FFF" stroke="#181717" d="M90.099 120h39.604v40H90.099z"/><path id="rect2326" fill="#FFF" stroke="#181717" d="M130.693 120h39.604v40h-39.604z"/><path id="rect2330" fill="#FFF" stroke="#181717" d="M170.297 120h39.604v40h-39.604z"/><path id="rect2334" fill="#FFF" stroke="#181717" d="M209.901 120h39.604v40h-39.604z"/><path id="rect2336" fill="#FFF" stroke="#181717" d="M250.495 120h39.604v40h-39.604z"/><path id="rect2338" fill="#FFF" stroke="#181717" d="M290.099 120h39.604v40h-39.604z"/><path id="rect2340" fill="#FFF" stroke="#181717" d="M330.693 120h39.604v40h-39.604z"/><path id="rect2342" fill="#FFF" stroke="#181717" d="M370.297 120h39.604v40h-39.604z"/><path id="rect2344" fill="#FFF" stroke="#181717" d="M409.901 120h39.604v40h-39.604z"/><path id="rect2346" fill="#FFF" stroke="#181717" d="M450.495 120h39.604v40h-39.604z"/><path id="rect2348" fill="#D1CFCD" stroke="#181717" d="M490.099 120H600v40H490.099z"/><path id="rect2350" fill="#D1CFCD" stroke="#181717" d="M0 160h60.396v40H0z"/><path id="rect2352" fill="#D1CFCD" stroke="#181717" d="M539.604 160H600v40h-60.396z"/><path id="rect2354" fill="#D1CFCD" stroke="#181717" d="M100 160h60.396v40H100z"/><path id="rect2360" fill="#D1CFCD" stroke="#181717" d="M400 160h60.396v40H400z"/><path id="rect2362" fill="#FFF" stroke="#181717" d="M160.396 160H400v40H160.396z"/><path id="rect2364" fill="#F6F3F1" stroke="#181717" d="M60.396 160H100v40H60.396z"/><path id="rect2366" fill="#F6F3F1" stroke="#181717" d="M460.396 160H500v40h-39.604z"/><path id="rect2368" fill="#F6F3F1" stroke="#181717" d="M500 160h39.604v40H500z"/><path id="text5091" fill="#181717" fill-rule="nonzero" d="M50.238 12.434l-.619-5.26V4h2.444v3.174l-.62 5.26h-1.205m-.587 3.254v-2.341h2.356v2.34h-2.356M50.238 36v-7.768h-2.713v-1.595h.174c.99 0 1.709-.153 2.158-.46.455-.307.722-.82.801-1.54h1.817V36h-2.237"/><path id="text5103" fill="#181717" fill-rule="nonzero" d="M15.842 9v1.75c-.559.376-1.088.653-1.587.832a4.387 4.387 0 01-1.466.262c-.248 0-.495-.021-.742-.063a5.413 5.413 0 01-.74-.183c-.13-.042-.32-.108-.573-.198-1.176-.396-2.07-.594-2.682-.594-.457 0-.935.1-1.434.301-.494.196-1.05.51-1.668.943V10.3a7.651 7.651 0 011.644-.848 4.307 4.307 0 011.474-.286c.628 0 1.41.154 2.344.46a.133.133 0 00.032.008c.097.031.245.082.443.15.833.29 1.477.436 1.934.436.456 0 .926-.098 1.41-.293.483-.196 1.02-.505 1.61-.927M8.037 23.069h2.078L11.701 26h-1.144l-2.521-2.931"/><path id="text5127" fill="#181717" fill-rule="nonzero" d="M90.732 13.574c-.291.443-.628.77-1.009.982-.381.206-.831.309-1.35.309-.837 0-1.475-.227-1.914-.681-.434-.454-.651-1.125-.651-2.012 0-1.261.368-2.32 1.104-3.175.74-.855 1.652-1.283 2.732-1.283.423 0 .791.087 1.104.261.312.174.569.433.77.776l.42-.776h1.415l-1.168 4.736a1.833 1.833 0 00-.055.324c0 .185.063.325.19.42.127.09.315.135.564.135.206 0 .42-.053.643-.159.228-.105.44-.253.636-.443.455-.422.8-.916 1.032-1.48a4.741 4.741 0 00.358-1.862c0-1.267-.493-2.307-1.478-3.12-.98-.818-2.245-1.227-3.796-1.227-.747 0-1.443.09-2.089.269-.64.18-1.223.446-1.747.8-.9.602-1.594 1.354-2.08 2.257a6.207 6.207 0 00-.723 2.97c0 1.62.548 2.916 1.644 3.887 1.096.966 2.56 1.45 4.391 1.45a8.25 8.25 0 002.51-.389 8.382 8.382 0 002.287-1.124l.652.926a9.152 9.152 0 01-2.582 1.37 8.79 8.79 0 01-2.835.46c-1.016 0-1.95-.13-2.803-.388a7.047 7.047 0 01-2.272-1.133c-.82-.638-1.435-1.375-1.842-2.21-.408-.833-.612-1.778-.612-2.834 0-.882.138-1.721.413-2.518a7.08 7.08 0 011.231-2.186 7.64 7.64 0 012.828-2.17c1.1-.49 2.327-.736 3.677-.736.894 0 1.734.121 2.517.364.79.238 1.475.576 2.057 1.014.715.554 1.247 1.188 1.597 1.9.354.708.532 1.508.532 2.4 0 .87-.175 1.676-.524 2.415a5.252 5.252 0 01-1.494 1.885 4.054 4.054 0 01-2.573.91c-.561 0-.985-.11-1.27-.332-.281-.222-.427-.55-.437-.982m.397-3.39c-.069-.427-.223-.752-.46-.973-.234-.227-.544-.34-.93-.34-.604 0-1.128.326-1.573.981-.444.655-.667 1.441-.667 2.36 0 .486.106.855.318 1.108.217.254.53.38.937.38.44 0 .84-.166 1.2-.498.365-.333.614-.766.746-1.299l.429-1.718M85.37 36c.01-1.014.228-1.871.651-2.574.424-.707 1.176-1.422 2.256-2.146.164-.11.402-.264.714-.459 1.43-.913 2.145-1.792 2.145-2.637 0-.501-.151-.897-.453-1.188-.302-.29-.715-.435-1.239-.435-.572 0-1.014.18-1.326.538-.307.354-.46.86-.46 1.52v.096H85.56c0-1.299.35-2.3 1.049-3.002s1.694-1.053 2.986-1.053c1.17 0 2.105.32 2.804.958.698.634 1.048 1.479 1.048 2.534 0 .755-.183 1.41-.548 1.964-.365.555-1.072 1.185-2.12 1.893-.223.153-.53.354-.922.602-.995.639-1.557 1.124-1.684 1.457h5.163V36H85.37"/><path id="text5139" fill="#181717" fill-rule="nonzero" d="M130.065 8.85l-.704 1.92h2.008l.688-1.92h-1.992m0-4.85h1.768l-1.168 3.267h1.936L133.785 4h1.769l-1.185 3.267h2.265l-.592 1.582h-2.24l-.673 1.905h2.32l-.568 1.575h-2.328l-1.184 3.274h-1.768l1.184-3.274h-1.952l-1.192 3.274h-1.76l1.168-3.274h-2.297l.609-1.575h2.256l.688-1.905h-2.392l.592-1.582h2.376L130.065 4m-3.552 28.245h2.2c.005.63.16 1.105.464 1.425.304.315.755.472 1.352.472.576 0 1.019-.147 1.328-.44.315-.3.472-.727.472-1.284 0-.556-.184-.976-.552-1.26-.363-.288-.904-.432-1.624-.432-.037 0-.096.002-.176.008-.075.005-.13.007-.168.007v-1.558h.248c.661 0 1.15-.126 1.464-.378.32-.257.48-.648.48-1.173 0-.436-.136-.78-.408-1.031-.267-.257-.632-.386-1.096-.386-.507 0-.899.147-1.176.44-.277.295-.416.712-.416 1.253v.094h-2.16c.026-1.155.37-2.039 1.032-2.653.667-.62 1.605-.929 2.816-.929 1.147 0 2.056.276 2.728.827.672.55 1.008 1.293 1.008 2.228 0 .493-.114.926-.344 1.298-.229.373-.573.68-1.032.921.587.252 1.03.601 1.328 1.047.304.441.456.969.456 1.583 0 1.128-.376 2.023-1.128 2.684-.752.661-1.778.992-3.08.992-1.285 0-2.278-.32-2.976-.96-.694-.646-1.04-1.562-1.04-2.748v-.047"/><path id="text5145" fill="#181717" fill-rule="nonzero" d="M169.832 14.64c.412-.056.727-.21.944-.458.216-.25.324-.581.324-.996 0-.368-.103-.671-.31-.91-.2-.244-.52-.433-.958-.568v2.933m-.899-5.32V6.675c-.392.052-.692.192-.898.42-.207.223-.31.524-.31.902 0 .316.096.58.287.793.196.213.503.39.921.53m0 8.517v-1.494c-1.137-.072-1.988-.412-2.552-1.019-.564-.606-.846-1.483-.846-2.629h2.024c.025.56.15 1.004.377 1.33.232.322.564.527.997.615v-3.22c-1.168-.306-1.998-.706-2.492-1.198-.493-.493-.74-1.167-.74-2.023 0-.949.292-1.714.876-2.294.59-.581 1.375-.884 2.356-.91V4h.899v.996c.981.051 1.746.357 2.295.917.549.555.85 1.338.906 2.35h-2.054c-.035-.483-.148-.85-.34-1.105-.186-.26-.455-.404-.807-.436v2.832c1.243.399 2.119.855 2.627 1.369.509.513.763 1.19.763 2.03 0 .99-.297 1.781-.891 2.372-.589.591-1.422.936-2.5 1.035v1.478h-.898m1.02 14.04v-4.769l-2.938 4.768h2.938M169.907 36v-2.403h-4.56v-1.96l3.986-6.457h2.68v6.643h1.254v1.774h-1.253V36h-2.107"/><path id="text5151" fill="#181717" fill-rule="nonzero" d="M213.66 12.728c0 .354.119.653.356.897.237.238.529.357.876.357.337 0 .627-.122.869-.365a1.23 1.23 0 00.363-.889c0-.339-.121-.627-.363-.865a1.166 1.166 0 00-.869-.365c-.347 0-.64.12-.876.357a1.173 1.173 0 00-.356.873m-1.713 0c0-.825.284-1.52.853-2.087.568-.566 1.266-.849 2.092-.849.81 0 1.5.289 2.07.865.573.571.86 1.262.86 2.071 0 .815-.287 1.513-.86 2.095a2.814 2.814 0 01-2.07.865c-.826 0-1.524-.286-2.092-.857-.569-.572-.853-1.273-.853-2.103m-4.588 2.96L214.103 4h1.27l-6.743 11.688h-1.271m-.695-8.728c0 .349.116.642.347.88.237.238.53.357.877.357.342 0 .632-.119.869-.357.242-.243.363-.537.363-.88 0-.339-.121-.627-.363-.865a1.166 1.166 0 00-.869-.365c-.347 0-.64.119-.877.357a1.187 1.187 0 00-.347.873m-1.714 0c0-.826.285-1.524.853-2.095.569-.577 1.264-.865 2.085-.865.81 0 1.5.29 2.069.873a2.85 2.85 0 01.86 2.087 2.85 2.85 0 01-.86 2.086 2.81 2.81 0 01-2.069.857c-.827 0-1.524-.283-2.093-.849-.563-.566-.845-1.264-.845-2.094m2.259 25.66h2.21c.038.497.204.883.498 1.158.295.27.69.405 1.185.405.61 0 1.076-.18 1.398-.54.326-.36.49-.875.49-1.547 0-.63-.167-1.124-.498-1.484-.332-.365-.79-.547-1.374-.547-.327 0-.614.066-.861.198a1.757 1.757 0 00-.632.587l-2.037-.119.734-6.093h6.5v1.92h-4.905l-.292 2.277c.248-.196.532-.341.853-.436.321-.1.68-.151 1.074-.151 1.127 0 2.035.344 2.724 1.031.695.688 1.043 1.59 1.043 2.706 0 1.222-.382 2.198-1.145 2.928-.764.725-1.788 1.087-3.072 1.087-1.169 0-2.1-.299-2.795-.897-.69-.603-1.056-1.43-1.098-2.483"/><path id="text5157" fill="#181717" fill-rule="nonzero" d="M248.477 4h2.056l3.922 4.418h-1.916l-3.026-2.922-3.042 2.922h-1.917L248.477 4m-.685 28.078c0 .646.166 1.158.498 1.536.337.378.794.567 1.37.567.538 0 .96-.184 1.264-.552.305-.367.457-.88.457-1.535 0-.604-.158-1.074-.473-1.41-.316-.336-.759-.504-1.33-.504-.56 0-.997.168-1.313.504-.315.336-.473.8-.473 1.394m-.032-2.946a2.55 2.55 0 01.962-.59 3.652 3.652 0 011.256-.205c1.142 0 2.055.336 2.74 1.008.69.672 1.036 1.567 1.036 2.686 0 1.186-.375 2.144-1.125 2.874S250.889 36 249.659 36c-1.418 0-2.497-.473-3.237-1.418-.734-.945-1.1-2.328-1.1-4.15 0-1.959.393-3.455 1.182-4.49.788-1.04 1.924-1.559 3.409-1.559 1.033 0 1.865.26 2.495.78.637.52.984 1.223 1.044 2.11h-2.365c-.054-.362-.201-.635-.44-.819-.24-.183-.574-.275-1.003-.275-.588 0-1.039.246-1.354.74-.316.488-.492 1.226-.53 2.213"/><path id="text5163" fill="#181717" fill-rule="nonzero" d="M288.584 10.586l-.571.436c-.23.17-.404.373-.519.611a1.815 1.815 0 00-.173.801c0 .45.146.828.436 1.135.29.307.654.46 1.09.46.321 0 .627-.069.917-.206.296-.143.57-.35.82-.619l-2-2.618m.602-2.5l.263-.198c.24-.175.418-.37.533-.587.116-.217.173-.466.173-.746 0-.27-.08-.484-.24-.643-.156-.158-.369-.238-.64-.238-.275 0-.493.082-.653.246-.16.159-.24.376-.24.65 0 .149.037.31.112.485.08.174.193.36.338.555l.354.476m-1.692 1.056l-.436-.603a3.832 3.832 0 01-.489-.89 2.72 2.72 0 01-.142-.88c0-.846.255-1.518.766-2.015.517-.503 1.216-.754 2.098-.754.847 0 1.516.23 2.007.69.491.46.737 1.082.737 1.865 0 .592-.145 1.124-.436 1.595-.286.465-.737.904-1.353 1.317l1.586 2.063c.15-.26.268-.55.353-.873a5.97 5.97 0 00.188-1.079h1.955a7.196 7.196 0 01-.406 1.912 6 6 0 01-.887 1.61l2.015 2.588h-2.557l-.751-.976a4.672 4.672 0 01-1.459.976 4.299 4.299 0 01-1.654.325c-1.022 0-1.86-.32-2.51-.96-.647-.64-.97-1.457-.97-2.452 0-.74.18-1.378.54-1.912.362-.534.963-1.05 1.805-1.547M289.742 36h-2.248c.08-1.55.434-3.087 1.06-4.61.632-1.523 1.531-3.02 2.699-4.49h-5.293v-1.937h7.631v1.706c-1.183 1.375-2.092 2.83-2.729 4.364-.631 1.534-1.005 3.19-1.12 4.967"/><path id="text5169" fill="#181717" fill-rule="nonzero" d="M328.705 8.587l-1.353 1.948-1.308-.935 1.477-1.893-2.153-.612.5-1.595 2.068.754V4h1.523v2.254l2.068-.738.516 1.594-2.154.597 1.462 1.878-1.339.982-1.307-1.98m-1.722 23.823c0 .55.148.974.446 1.273.302.298.733.448 1.292.448.533 0 .95-.152 1.253-.456.308-.304.461-.725.461-1.265 0-.518-.156-.934-.469-1.248-.312-.315-.728-.472-1.245-.472-.518 0-.939.16-1.262.48-.317.319-.476.732-.476 1.24m.176-4.822c0 .434.134.77.4 1.005.267.23.649.346 1.146.346.497 0 .88-.118 1.146-.354.272-.235.408-.568.408-.997 0-.42-.139-.75-.416-.99-.277-.24-.656-.361-1.138-.361-.471 0-.848.123-1.13.369-.277.246-.416.573-.416.982m-.792 2.183c-.461-.262-.794-.568-1-.919-.204-.35-.307-.798-.307-1.343 0-.963.323-1.72.969-2.27.646-.55 1.538-.825 2.676-.825 1.149 0 2.046.275 2.692.825.65.545.976 1.301.976 2.27 0 .518-.11.969-.33 1.351-.22.377-.551.68-.992.911.538.257.943.613 1.215 1.068.271.45.407 1 .407 1.65 0 1.094-.353 1.953-1.061 2.576-.702.623-1.671.935-2.907.935-1.25 0-2.222-.309-2.914-.927-.692-.618-1.039-1.48-1.039-2.584 0-.644.129-1.183.385-1.618.261-.44.672-.807 1.23-1.1"/><path id="text5175" fill="#181717" fill-rule="nonzero" d="M372.099 4a14.885 14.885 0 00-1.566 3.611 14.3 14.3 0 00-.512 3.855c0 1.34.17 2.622.512 3.847a14.884 14.884 0 001.566 3.611h-1.612c-.891-1.25-1.568-2.507-2.032-3.768-.458-1.267-.687-2.497-.687-3.69s.229-2.423.687-3.69c.464-1.266 1.14-2.525 2.032-3.776h1.612m-1.169 24.33c0-.644-.158-1.152-.474-1.523-.31-.377-.735-.566-1.275-.566-.51 0-.907.181-1.192.542-.28.361-.42.866-.42 1.515 0 .607.148 1.081.443 1.421.296.34.71.51 1.245.51.525 0 .935-.167 1.23-.502.295-.335.443-.8.443-1.397m.038 2.928a2.45 2.45 0 01-.901.589c-.346.13-.736.196-1.169.196-1.074 0-1.935-.332-2.581-.997-.647-.665-.97-1.554-.97-2.67 0-1.182.35-2.137 1.054-2.865.702-.727 1.63-1.091 2.78-1.091 1.334 0 2.347.474 3.04 1.421.698.942 1.046 2.319 1.046 4.13 0 1.947-.371 3.438-1.115 4.475-.743 1.036-1.813 1.554-3.208 1.554-.962 0-1.739-.256-2.33-.77-.59-.518-.914-1.221-.97-2.111l2.208.008c.05.36.188.63.412.808.224.178.54.267.947.267.55 0 .97-.246 1.26-.738.291-.492.456-1.227.497-2.206"/><path id="text5181" fill="#181717" fill-rule="nonzero" d="M406.175 4h1.63c.888 1.247 1.561 2.504 2.02 3.772.46 1.263.69 2.497.69 3.701 0 1.2-.23 2.434-.69 3.702-.459 1.268-1.132 2.522-2.02 3.764h-1.63a14.864 14.864 0 001.576-3.623c.347-1.23.52-2.512.52-3.843 0-1.335-.173-2.616-.52-3.842A15.002 15.002 0 00406.175 4m1.048 26.224c0 1.367.133 2.36.398 2.978.27.619.7.928 1.286.928.587 0 1.015-.312 1.286-.936.27-.623.405-1.613.405-2.97 0-1.362-.135-2.352-.405-2.97-.27-.619-.7-.928-1.286-.928-.587 0-1.015.31-1.286.927-.265.613-.398 1.604-.398 2.971m-2.273 0c0-1.933.327-3.38.98-4.338.658-.964 1.65-1.446 2.977-1.446 1.321 0 2.311.485 2.97 1.454.663.964.994 2.412.994 4.346 0 1.933-.329 3.376-.987 4.33-.653.953-1.645 1.43-2.977 1.43-1.326 0-2.319-.48-2.977-1.438-.653-.959-.98-2.405-.98-4.338"/><path id="text5187" fill="#181717" fill-rule="nonzero" d="M444.554 18h7.921v1.634h-7.92V18m1.786 15v-2.194h4.347V33h-4.347"/><path id="text5201" fill="#181717" fill-rule="nonzero" d="M488.853 6h1.502v3.952h3.704v1.543h-3.704v3.967h-1.502v-3.967h-3.704V9.952h3.704V6m-3.704 25.458h8.91V33h-8.91v-1.542m0-3.333h8.91v1.543h-8.91v-1.543"/><path id="text5427" fill="#181717" fill-rule="nonzero" d="M7.278 63.794v-6.402H4.95V56h6.253v1.392H8.892v6.402H7.278m8.037-.715c-.195.3-.45.53-.767.688a2.472 2.472 0 01-1.102.233c-.561 0-.995-.159-1.3-.476-.302-.318-.453-.77-.453-1.355 0-.543.151-.957.453-1.243.305-.286.808-.482 1.507-.587.16-.025.37-.053.629-.085.657-.085.985-.273.985-.566 0-.233-.073-.399-.218-.498-.146-.102-.389-.153-.73-.153-.312 0-.552.062-.719.185a.619.619 0 00-.25.53v.084H11.9v-.106c0-.589.21-1.051.629-1.386.419-.339.997-.508 1.736-.508.81 0 1.43.14 1.859.418.433.279.65.68.65 1.206v3.27c0 .24.024.42.074.54a.52.52 0 00.25.264v.26h-1.613a1.337 1.337 0 01-.123-.328 1.884 1.884 0 01-.048-.387m-.026-2.116c-.253.116-.544.21-.874.28-.327.07-.495.108-.506.111-.273.078-.465.175-.575.292-.107.116-.16.276-.16.481 0 .212.07.38.208.508.138.123.325.185.559.185.419 0 .747-.116.985-.35.242-.235.363-.556.363-.962v-.545M18.165 56h1.507v2.757c.192-.3.431-.526.719-.678.291-.155.621-.232.99-.232.7 0 1.272.287 1.716.862.443.571.665 1.316.665 2.233 0 .91-.222 1.645-.665 2.206-.444.561-1.023.841-1.737.841-.373 0-.697-.077-.974-.232-.274-.156-.522-.403-.746-.741v.778h-1.475V56m4.058 4.878c0-.529-.112-.943-.335-1.243a1.082 1.082 0 00-.922-.455c-.412 0-.731.148-.959.444-.223.293-.335.711-.335 1.254 0 .586.106 1.03.32 1.334.216.303.53.455.942.455.42 0 .739-.152.959-.455.22-.307.33-.752.33-1.334"/><path id="text5207" fill="#181717" fill-rule="nonzero" d="M526.261 29.323h1.868c.44 0 .762-.08.963-.241.201-.16.302-.414.302-.76 0-.36-.1-.618-.297-.775-.198-.16-.524-.241-.978-.241h-1.858v2.017m0-3.337h1.8c.39 0 .674-.066.854-.2.18-.135.27-.348.27-.638 0-.283-.088-.487-.265-.613-.173-.13-.463-.194-.869-.194h-1.79v1.645m-1.509 4.73V23h3.611c.784 0 1.381.168 1.79.503.413.332.62.815.62 1.45 0 .392-.077.719-.23.98a1.51 1.51 0 01-.686.608c.395.16.69.393.884.697.198.3.297.676.297 1.126 0 .75-.243 1.33-.729 1.74-.485.408-1.174.612-2.065.612h-3.492m10.625-.707c-.19.297-.44.524-.75.68-.308.155-.667.231-1.076.231-.548 0-.971-.157-1.27-.471-.295-.314-.442-.761-.442-1.341 0-.538.147-.948.442-1.231.299-.283.79-.477 1.473-.582.156-.024.36-.052.614-.083.641-.084.962-.271.962-.56 0-.231-.07-.395-.213-.493-.142-.102-.38-.152-.713-.152-.305 0-.54.06-.702.183-.163.122-.245.297-.245.524v.084h-1.415v-.105c0-.583.205-1.04.614-1.372.41-.336.975-.503 1.696-.503.791 0 1.396.138 1.816.414.423.275.635.674.635 1.194v3.237c0 .238.024.416.073.534.048.116.13.203.244.262v.257h-1.576a1.334 1.334 0 01-.12-.325 1.89 1.89 0 01-.047-.382m-.026-2.095c-.246.115-.53.207-.853.277-.32.07-.484.107-.494.11-.268.077-.455.173-.562.288-.104.116-.156.274-.156.477 0 .21.067.377.202.503.136.122.318.183.547.183.41 0 .73-.115.962-.346.236-.233.354-.551.354-.953v-.54m6.197.655h1.493c-.062.723-.324 1.294-.785 1.713-.462.42-1.055.629-1.78.629-.822 0-1.467-.269-1.935-.807-.465-.541-.698-1.288-.698-2.242 0-.95.238-1.694.713-2.231.479-.542 1.136-.812 1.972-.812.732 0 1.318.195 1.759.586.444.392.692.936.744 1.635h-1.504c-.041-.304-.147-.536-.317-.697-.17-.16-.394-.24-.671-.24-.375 0-.656.148-.843.444-.184.297-.276.742-.276 1.336 0 .548.095.971.286 1.268a.94.94 0 00.833.44c.28 0 .506-.086.676-.257.17-.171.281-.426.333-.765m2.482 2.148V23h1.472v4.05l1.8-2.028h1.822l-1.972 2.111 2.091 3.583h-1.815l-1.353-2.425-.573.623v1.802h-1.472m5.562-1.854h1.509c.014.29.118.506.312.65.194.139.486.209.874.209.295 0 .522-.05.682-.147a.475.475 0 00.244-.424c0-.259-.301-.452-.905-.582a13.134 13.134 0 01-.588-.136c-.735-.188-1.247-.412-1.535-.67-.284-.259-.427-.608-.427-1.048 0-.583.209-1.044.625-1.383.42-.342.987-.513 1.701-.513.756 0 1.35.17 1.78.508.433.339.664.815.692 1.43h-1.473a.706.706 0 00-.276-.56c-.17-.133-.407-.2-.712-.2-.288 0-.503.044-.646.131a.434.434 0 00-.208.393c0 .227.377.428 1.13.603.173.038.31.07.41.094.753.178 1.267.393 1.54.644.278.252.417.606.417 1.064 0 .646-.227 1.138-.682 1.477-.45.339-1.108.508-1.972.508-.78 0-1.39-.176-1.831-.53-.44-.352-.661-.837-.661-1.455v-.063m10.14-.959c0-.573-.107-1.01-.322-1.31-.215-.303-.527-.455-.936-.455-.403 0-.71.15-.921.45-.208.3-.312.739-.312 1.315 0 .538.109.953.327 1.247.222.293.534.44.937.44.381 0 .681-.15.9-.45.219-.301.328-.713.328-1.237M555.768 33v-7.978h1.441v.77c.219-.335.462-.58.729-.733.27-.154.588-.23.952-.23.697 0 1.262.277 1.696.832.434.552.65 1.278.65 2.18 0 .91-.216 1.651-.65 2.22-.434.566-.992.849-1.675.849-.361 0-.684-.077-.968-.23a1.927 1.927 0 01-.702-.671V33h-1.473m9.745-2.991c-.19.297-.44.524-.749.68-.309.155-.668.231-1.077.231-.548 0-.971-.157-1.27-.471-.294-.314-.442-.761-.442-1.341 0-.538.148-.948.443-1.231.298-.283.789-.477 1.472-.582.156-.024.36-.052.614-.083.642-.084.963-.271.963-.56 0-.231-.072-.395-.214-.493-.142-.102-.38-.152-.713-.152-.305 0-.539.06-.702.183-.163.122-.245.297-.245.524v.084h-1.415v-.105c0-.583.205-1.04.614-1.372.41-.336.975-.503 1.696-.503.791 0 1.397.138 1.816.414.423.275.635.674.635 1.194v3.237c0 .238.024.416.073.534.048.116.13.203.244.262v.257h-1.576a1.334 1.334 0 01-.12-.325 1.89 1.89 0 01-.047-.382m-.026-2.095c-.246.115-.53.207-.853.277-.319.07-.484.107-.494.11-.267.077-.455.173-.562.288-.104.116-.156.274-.156.477 0 .21.067.377.203.503.135.122.317.183.546.183.41 0 .73-.115.963-.346.235-.233.353-.551.353-.953v-.54m6.197.655h1.494c-.063.723-.325 1.294-.786 1.713-.461.42-1.055.629-1.78.629-.822 0-1.467-.269-1.935-.807-.465-.541-.697-1.288-.697-2.242 0-.95.237-1.694.712-2.231.48-.542 1.136-.812 1.972-.812.732 0 1.319.195 1.76.586.443.392.691.936.743 1.635h-1.504c-.041-.304-.147-.536-.317-.697-.17-.16-.394-.24-.671-.24-.375 0-.656.148-.843.444-.184.297-.276.742-.276 1.336 0 .548.096.971.286 1.268a.94.94 0 00.833.44c.28 0 .506-.086.676-.257.17-.171.281-.426.333-.765m5.937.42h1.509c-.153.6-.461 1.072-.926 1.414-.462.339-1.025.508-1.691.508-.819 0-1.468-.276-1.946-.828-.479-.555-.718-1.306-.718-2.252 0-.933.236-1.668.707-2.206.472-.537 1.117-.806 1.936-.806.867 0 1.537.265 2.008.796.472.527.708 1.28.708 2.258a4.312 4.312 0 01-.016.398h-3.777c.02.447.128.784.322 1.01.198.228.48.341.849.341.26 0 .473-.05.64-.152.166-.104.298-.265.395-.482m-2.206-1.718h2.227c-.014-.384-.116-.675-.307-.875-.188-.202-.458-.303-.812-.303-.33 0-.59.1-.78.303-.188.203-.297.495-.328.875"/><path id="path5439" stroke="#181717" stroke-width="3" d="M560.396 11.5h-28.713"/><path id="path5441" fill="#181717" d="M534.653 17V7l-9.9 5z"/><g id="g5459" transform="translate(29.703 50)"><path id="path5453" stroke="#181717" stroke-width="3" d="M25.401 5.5H6.611"/><path id="path5455" fill="#181717" d="M10.556 10.656V.344L.66 5.5z"/><path id="path5457" stroke="#181717" stroke-width="3" d="M.66.344v10.312"/></g><g id="g5464" transform="rotate(180 27.723 35.5)"><path id="path5466" stroke="#181717" stroke-width="3" d="M25.401 5.5H6.611"/><path id="path5468" fill="#181717" d="M10.556 10.656V.344L.66 5.5z"/><path id="path5470" stroke="#181717" stroke-width="3" d="M.66.344v10.312"/></g><path id="text5474" fill="#181717" fill-rule="nonzero" d="M71.131 54.066l-1.178-1.225 1.254-1.386 1.208 1.257c.161-.322.285-.69.37-1.104.086-.414.129-.865.129-1.354 0-1.305-.275-2.318-.824-3.038-.548-.726-1.316-1.088-2.303-1.088-.977 0-1.737.36-2.281 1.08-.544.72-.816 1.735-.816 3.046 0 1.306.272 2.321.816 3.047.544.72 1.304 1.08 2.28 1.08.253 0 .49-.027.71-.08a2.74 2.74 0 00.635-.235m1.609 1.62a4.191 4.191 0 01-1.322.613 6.03 6.03 0 01-1.631.21c-1.662 0-2.983-.565-3.965-1.693-.977-1.128-1.466-2.649-1.466-4.562 0-1.918.489-3.439 1.466-4.562.982-1.128 2.303-1.692 3.965-1.692 1.661 0 2.983.564 3.965 1.692.987 1.129 1.48 2.65 1.48 4.562a8.3 8.3 0 01-.302 2.305 5.583 5.583 0 01-.89 1.822l1.208 1.233L74.008 57l-1.268-1.314"/><path id="text5482" fill="#181717" fill-rule="nonzero" d="M106.308 56l-3.338-12h2.483l1.993 8.464L109.131 44h2.554l1.684 8.464L115.362 44h2.46l-3.33 12h-2.285l-1.803-9.19-1.811 9.19h-2.285"/><path id="text5492" fill="#181717" fill-rule="nonzero" d="M145.545 56V44h8.62v2.086h-6.21v2.558h5.678v2.053h-5.677v3.087h6.5V56h-8.911"/><path id="text5500" fill="#181717" fill-rule="nonzero" d="M187.62 49.246h2.903c.63 0 1.093-.127 1.387-.382.299-.256.448-.658.448-1.206 0-.522-.144-.915-.432-1.181-.288-.272-.718-.408-1.289-.408h-3.017v3.177M185.149 56V44h5.823c1.31 0 2.28.28 2.911.84.63.559.946 1.414.946 2.565 0 .734-.155 1.344-.465 1.833a2.307 2.307 0 01-1.32 1.002c.521.185.89.467 1.108.848.223.38.351.972.384 1.776l.049 1.417v.049c.016.717.17 1.151.465 1.303V56h-2.708a2.362 2.362 0 01-.204-.62 6.444 6.444 0 01-.082-.887l-.032-1.263c-.027-.744-.169-1.246-.424-1.507-.25-.26-.704-.391-1.362-.391h-2.618V56h-2.471"/><path id="text5504" fill="#181717" fill-rule="nonzero" d="M229.06 56v-9.857h-3.317V44h8.91v2.143h-3.294V56h-2.3"/><path id="text5518" fill="#181717" fill-rule="nonzero" d="M271.618 56h-2.268v-4.473L265.347 44h2.776l2.357 5.173L272.658 44h2.59l-3.63 7.527V56"/><path id="text5522" fill="#181717" fill-rule="nonzero" d="M305.94 44h2.311v7.304c0 .902.172 1.56.514 1.977.342.41.886.616 1.631.616.755 0 1.304-.205 1.646-.616.348-.411.521-1.07.521-1.977V44h2.288v7.565c0 1.428-.382 2.525-1.147 3.289-.76.764-1.858 1.146-3.293 1.146-1.445 0-2.552-.38-3.323-1.138-.765-.765-1.147-1.863-1.147-3.297V44"/><path id="text5526" fill="#181717" fill-rule="nonzero" d="M349.505 56V44h1.98v12h-1.98"/><path id="text5530" fill="#181717" fill-rule="nonzero" d="M386.495 50c0 1.253.273 2.227.817 2.923.545.69 1.306 1.036 2.284 1.036.989 0 1.758-.346 2.307-1.036.55-.696.825-1.67.825-2.923 0-1.253-.275-2.224-.825-2.915-.55-.696-1.318-1.044-2.307-1.044-.978 0-1.74.346-2.284 1.036-.544.691-.817 1.665-.817 2.923m-2.337 0c0-1.84.49-3.299 1.468-4.376.983-1.083 2.306-1.624 3.97-1.624 1.664 0 2.988.541 3.971 1.624.988 1.082 1.483 2.541 1.483 4.376 0 1.835-.495 3.294-1.483 4.376-.983 1.083-2.307 1.624-3.97 1.624-1.665 0-2.988-.541-3.971-1.624-.978-1.082-1.468-2.54-1.468-4.376"/><path id="text5534" fill="#181717" fill-rule="nonzero" d="M428.156 49.556h2.319c.628 0 1.084-.136 1.37-.407.284-.277.426-.72.426-1.328 0-.57-.14-1.002-.419-1.296-.28-.293-.696-.44-1.25-.44h-2.446v3.471m-.016 2.175V56h-2.397V44h5.183c1.224 0 2.15.329 2.778.986.633.651.95 1.61.95 2.876 0 1.238-.31 2.194-.926 2.867-.618.668-1.499 1.002-2.644 1.002h-2.944"/><path id="text5546" fill="#181717" fill-rule="nonzero" d="M473.267 43.016v1.634c-.049 0-.117-.002-.205-.008a3.648 3.648 0 00-.18-.007c-.552 0-.926.101-1.122.305-.192.198-.287.62-.287 1.267v1.877c0 .771-.123 1.319-.369 1.642-.246.324-.688.556-1.327.696.639.141 1.081.37 1.327.689.246.318.369.863.369 1.634v1.885c0 .642.095 1.061.287 1.26.19.198.565.297 1.122.297.033 0 .093-.003.18-.008.088-.005.156-.008.205-.008v1.635c-.076 0-.183.002-.32.007a8.326 8.326 0 01-1.672-.086 3.288 3.288 0 01-.933-.289 1.51 1.51 0 01-.664-.72c-.125-.297-.188-.816-.188-1.556v-1.97c0-.715-.14-1.221-.418-1.518-.279-.303-.748-.454-1.41-.454-.032 0-.087.003-.163.008a2.764 2.764 0 01-.172.008V49.6c.038 0 .095.003.172.008.076.005.13.008.164.008.655 0 1.122-.151 1.4-.454.285-.302.427-.813.427-1.533v-1.955c0-.746.063-1.27.188-1.572a1.51 1.51 0 01.664-.72c.257-.13.568-.227.934-.29a8.326 8.326 0 011.672-.085c.136.005.243.008.32.008m-4.302 20.053h4.137v1.666h-1.925v11.6h1.925V78h-4.137V63.07"/><path id="text5554" fill="#181717" fill-rule="nonzero" d="M506.93 43h.558c.6 0 1.084.031 1.45.094.366.063.672.162.918.297.311.167.53.407.655.72.132.308.197.824.197 1.55v1.971c0 .715.14 1.224.418 1.526.279.297.748.446 1.41.446.032 0 .087-.003.163-.008.077-.005.134-.008.172-.008v1.636h-.303c-.683 0-1.163.146-1.442.438-.279.292-.418.798-.418 1.518v1.972c0 .746-.065 1.27-.197 1.573a1.393 1.393 0 01-.655.704c-.257.13-.568.227-.934.29a8.322 8.322 0 01-1.672.085 8.903 8.903 0 00-.32-.007V56.16c.05 0 .118.003.206.008.087.005.147.008.18.008.552 0 .923-.102 1.114-.305.197-.199.295-.616.295-1.252v-1.87c0-.783.123-1.333.369-1.651.246-.324.688-.553 1.327-.689-.639-.14-1.081-.373-1.327-.696-.246-.324-.369-.872-.369-1.644v-1.893c0-.637-.098-1.054-.295-1.252-.191-.204-.562-.305-1.114-.305-.033 0-.093.002-.18.008a3.64 3.64 0 01-.205.007V43m4.375 20.063V78h-4.146v-1.667h1.934V64.73h-1.934v-1.666h4.146"/><path id="text5564" fill="#181717" fill-rule="nonzero" d="M549.198 42h1.611v16.137h-1.61V42m2.205 34l-3.88-13.403h1.057L552.475 76h-1.071"/><g id="g5770" fill="#181717" fill-rule="nonzero" font-family="OpenSans-Regular, Open Sans" font-size="13" font-weight="normal" transform="translate(2.97 83)"><g id="text5570" transform="translate(0 .166)"><text id="tspan5572"><tspan x=".102" y="14.34">Caps Lock</tspan></text></g></g><path id="text5641" fill="#181717" fill-rule="nonzero" d="M79.684 86.403l-1.582 5.108h3.17l-1.588-5.108M78.319 84h2.713l4.117 12h-2.466l-.775-2.468h-4.426L76.73 96h-2.473l4.062-12"/><path id="text5645" fill="#181717" fill-rule="nonzero" d="M115.842 92.17h2.224c.084.623.33 1.086.736 1.39.407.298.994.448 1.763.448.654 0 1.148-.121 1.48-.363.332-.242.498-.6.498-1.074 0-.69-.954-1.26-2.863-1.714a6.949 6.949 0 01-.298-.07c-1.021-.231-1.75-.491-2.187-.78a2.488 2.488 0 01-.885-1.034c-.203-.438-.305-.952-.305-1.544 0-1.107.362-1.954 1.086-2.541.724-.592 1.77-.888 3.14-.888 1.278 0 2.278.314 2.997.942.724.628 1.105 1.514 1.145 2.656h-2.164c-.04-.55-.243-.97-.61-1.258-.367-.289-.89-.433-1.57-.433-.59 0-1.046.121-1.368.363-.318.237-.476.577-.476 1.02 0 .602.622 1.052 1.867 1.35l.788.194c.798.211 1.364.376 1.696.494.337.119.63.25.878.394.446.257.78.6 1.004 1.027.223.422.334.93.334 1.521 0 1.184-.384 2.103-1.152 2.757-.769.649-1.853.973-3.25.973-1.38 0-2.46-.332-3.244-.996-.783-.664-1.205-1.609-1.264-2.834"/><path id="text5649" fill="#181717" fill-rule="nonzero" d="M157.8 93.833h1.926c1.115 0 1.921-.299 2.418-.896.502-.603.753-1.578.753-2.925 0-1.341-.232-2.327-.698-2.957-.465-.63-1.191-.945-2.18-.945h-2.22v7.723M155.447 96V84h4.574c1.791 0 3.125.497 4.003 1.49.882.995 1.324 2.502 1.324 4.522 0 1.097-.164 2.064-.492 2.9-.322.837-.793 1.51-1.411 2.02-.465.381-.994.655-1.585.824-.592.163-1.422.244-2.49.244h-3.923"/><path id="text5653" fill="#181717" fill-rule="nonzero" d="M196.04 96V84h7.92v2.086h-5.617v2.72h4.924v2.086h-4.924V96h-2.303"/><path id="text5657" fill="#181717" fill-rule="nonzero" d="M243.628 94.338c-.436.572-.934.992-1.493 1.26-.554.268-1.206.402-1.956.402-1.645 0-2.978-.552-4-1.655-1.017-1.108-1.526-2.561-1.526-4.36 0-1.815.509-3.266 1.526-4.354 1.016-1.087 2.371-1.631 4.064-1.631 1.474 0 2.677.343 3.609 1.028.931.68 1.485 1.619 1.66 2.815h-2.467c-.149-.593-.455-1.044-.918-1.353-.458-.31-1.057-.464-1.796-.464-.985 0-1.76.35-2.324 1.051-.559.696-.838 1.66-.838 2.892 0 1.237.292 2.206.878 2.907.585.701 1.39 1.052 2.411 1.052.767 0 1.408-.22 1.925-.657.516-.439.835-1.039.958-1.802h-2.667v-1.948h4.87v6.162h-1.62l-.296-1.345"/><path id="text5661" fill="#181717" fill-rule="nonzero" d="M275.248 96V84h2.479v4.473h4.942V84h2.48v12h-2.48v-5.32h-4.942V96h-2.48"/><path id="text5665" fill="#181717" fill-rule="nonzero" d="M316.832 91.324h2.155v1.41c0 .407.113.72.339.936.225.211.55.317.971.317.461 0 .782-.13.964-.389.181-.259.272-.745.272-1.458V84h2.23v8.251c0 .74-.042 1.284-.126 1.633-.078.343-.21.647-.397.911-.284.391-.674.69-1.17.896-.495.206-1.076.309-1.744.309-.613 0-1.155-.09-1.626-.27a2.949 2.949 0 01-1.177-.8 2.594 2.594 0 01-.537-.951c-.103-.354-.154-.935-.154-1.744v-.911"/><path id="text5669" fill="#181717" fill-rule="nonzero" d="M355.446 96V84h2.29v4.929L362.08 84h2.865l-4.444 4.855L365.347 96h-2.797l-3.628-5.49-1.186 1.27V96h-2.29"/><path id="text5673" fill="#181717" fill-rule="nonzero" d="M396.04 96V84h2.348v9.784h5.572V96h-7.92"/><path id="text5679" fill="#181717" fill-rule="nonzero" d="M96.04 136v-2.086l6.105-7.739h-5.983V124h8.788v2.086l-6.12 7.747h5.983V136H96.04"/><path id="text5683" fill="#181717" fill-rule="nonzero" d="M134.653 136l3.521-6.126-3.52-5.874h2.661l2.289 4.196 2.274-4.196h2.676l-3.52 5.857 3.52 6.143h-2.661l-2.289-4.155-2.289 4.155h-2.662"/><path id="text5687" fill="#181717" fill-rule="nonzero" d="M185.149 131.77c-.092 1.294-.616 2.323-1.573 3.086-.95.763-2.193 1.144-3.727 1.144-1.767 0-3.142-.526-4.125-1.577-.978-1.052-1.467-2.526-1.467-4.423 0-1.938.5-3.423 1.5-4.454.999-1.03 2.436-1.546 4.31-1.546 1.524 0 2.726.356 3.607 1.067.886.706 1.372 1.706 1.458 3h-2.423c-.102-.644-.378-1.134-.826-1.47-.449-.34-1.054-.51-1.815-.51-1.08 0-1.902.333-2.464.998s-.843 1.637-.843 2.915c0 1.237.279 2.193.835 2.869.562.675 1.359 1.012 2.39 1.012.746 0 1.357-.18 1.832-.54.475-.367.783-.89.924-1.57h2.407"/><path id="text5691" fill="#181717" fill-rule="nonzero" d="M218.72 136l-3.869-12h2.56l2.383 8.978 2.43-8.978h2.528l-3.823 12h-2.209"/><path id="text5695" fill="#181717" fill-rule="nonzero" d="M257.822 133.833h2.943c.694 0 1.2-.125 1.516-.375.317-.25.476-.643.476-1.181 0-.56-.156-.961-.468-1.206-.311-.25-.825-.374-1.54-.374h-2.927v3.136m0-5.19h2.836c.612 0 1.06-.103 1.344-.309.285-.212.427-.543.427-.994 0-.44-.14-.758-.418-.953-.274-.201-.73-.301-1.37-.301h-2.819v2.558M255.446 136v-12h5.688c1.235 0 2.174.26 2.82.782.65.516.975 1.268.975 2.257 0 .608-.12 1.116-.361 1.523-.24.407-.601.722-1.082.945.623.25 1.087.611 1.393 1.084.312.467.468 1.05.468 1.751 0 1.168-.383 2.07-1.148 2.705-.765.635-1.85.953-3.254.953h-5.5"/><path id="text5699" fill="#181717" fill-rule="nonzero" d="M295.05 136v-12h2.585l4.877 8.244V124h2.438v12h-2.552l-4.91-8.244V136h-2.438"/><path id="text5703" fill="#181717" fill-rule="nonzero" d="M333.663 136v-12h3.597l2.352 9.132 2.32-9.132h3.613v12h-2.28v-9.678l-2.4 9.678h-2.49l-2.432-9.678V136h-2.28"/><path id="text5725" fill="#181717" fill-rule="nonzero" d="M438.614 89.363V87h1.98v2.363h-1.98m0 5.974v-2.348h1.98v2.348h-1.98m.013 13.99v-2.362h1.967v2.363h-1.967m0 8.672v-.912c.366-.125.636-.318.81-.578.175-.26.262-.597.262-1.013v-.195h-1.085v-2.348h1.98v2.254c0 .78-.166 1.404-.497 1.872-.33.473-.82.78-1.47.92"/><path id="text5731" fill="#181717" fill-rule="nonzero" d="M480.71 85h1.468v4.301h-1.468V85m-2.492 0h1.468v4.301h-1.468V85m1.254 19.699h1.468V109h-1.468v-4.301"/><path id="text5737" fill="#181717" fill-rule="nonzero" d="M514.851 93.804V86h5.524v1.356h-3.979v1.664h3.638v1.335h-3.638v2.008h4.165v1.441h-5.71m6.775 0v-5.759h1.472v.683c.21-.279.458-.487.744-.625.286-.141.605-.212.956-.212.62 0 1.084.166 1.39.498.31.329.465.825.465 1.49v3.925h-1.503v-3.48c0-.414-.07-.709-.207-.886-.134-.176-.355-.264-.662-.264-.354 0-.635.109-.842.328-.206.215-.31.51-.31.885v3.417h-1.503m8.82.042l-.496.016c-.19.01-.31.016-.362.016-.575 0-.97-.11-1.183-.328-.21-.223-.315-.66-.315-1.309v-3.115h-.744v-1.081h.744v-1.573h1.488v1.573h.868v1.08h-.868v3.19c0 .152.032.253.098.302.065.046.2.07.403.07h.367v1.16m4.335-1.791h1.499c-.152.607-.459 1.084-.92 1.43-.458.343-1.018.514-1.68.514-.813 0-1.457-.279-1.932-.837-.475-.562-.713-1.321-.713-2.278 0-.943.234-1.687.703-2.23.468-.545 1.109-.817 1.922-.817.861 0 1.526.269 1.994.806.469.533.703 1.294.703 2.283a4.44 4.44 0 01-.015.403h-3.752c.02.452.128.793.32 1.022.197.23.478.345.843.345.258 0 .47-.052.635-.154.166-.106.297-.268.393-.487m-2.19-1.738h2.21c-.013-.389-.115-.684-.304-.885-.186-.205-.455-.307-.806-.307-.327 0-.586.102-.775.307-.186.205-.295.5-.326.885m4.764 3.486v-5.759h1.395v.985c.197-.395.426-.685.688-.868.261-.188.573-.281.935-.281.058 0 .103.002.134.005.035 0 .062.002.083.005l.005 1.563h-.501c-.41 0-.718.11-.925.329-.207.219-.31.544-.31.975v3.046h-1.504"/><path id="path5745" fill="#181717" d="M524.752 115v-10l-9.9 5z"/><path id="path5747" stroke="#181717" stroke-width="3" d="M539.604 100v10h-19.802"/><g id="g5790" transform="translate(6.901 120)"><text id="tspan5755" fill="#181717" fill-rule="nonzero" font-family="OpenSans-Regular, Open Sans" font-size="16" font-weight="normal"><tspan x=".208" y="17.237">Shift</tspan></text><path id="path5757" stroke="#181717" stroke-width="2" d="M8.16 19.535l-7.494 10h4.996v5h4.996v-5h4.996z"/></g><g id="g5795" transform="translate(495.05 127)"><g id="text5797" fill="#181717" fill-rule="nonzero" font-family="OpenSans-Regular, Open Sans" font-size="16" font-weight="normal" transform="translate(30.402)"><text id="tspan5799"><tspan x=".537" y="17.955">Shift</tspan></text></g><path id="path5801" stroke="#181717" stroke-width="2" d="M7.55 10.628L0 20.58h5.033v4.976h5.034V20.58H15.1z"/></g><path id="text5803" fill="#181717" fill-rule="nonzero" d="M384.158 126v1.71l-6.755 2.848 6.755 2.841v1.71l-8.91-3.786v-1.553l8.91-3.77m-5.605 32v-.913c.424-.125.736-.318.938-.578.202-.26.303-.598.303-1.014v-.195h-1.24v-2.35h2.291v2.256c0 .775-.194 1.4-.582 1.873-.384.474-.953.78-1.71.921"/><path id="text5813" fill="#181717" fill-rule="nonzero" d="M415.842 127l8.91 3.731v1.538l-8.91 3.746v-1.692l6.77-2.812-6.77-2.82V127m3.305 29v-2.325h2.277V156h-2.277"/><path id="text5819" fill="#181717" fill-rule="nonzero" d="M459.343 132.387c0-.056-.002-.131-.008-.224a4.45 4.45 0 01-.008-.217c0-.454.05-.831.151-1.13.101-.305.263-.59.485-.853.17-.196.421-.42.755-.673.339-.253.559-.437.66-.55.211-.233.357-.442.436-.628.08-.185.12-.39.12-.611 0-.49-.141-.873-.422-1.147-.28-.273-.672-.41-1.176-.41-.503 0-.9.165-1.191.496-.286.325-.442.784-.469 1.378h-2.24v-.24c0-1.09.352-1.957 1.056-2.602.71-.65 1.663-.976 2.86-.976 1.224 0 2.196.307 2.916.922.726.609 1.088 1.427 1.088 2.455 0 .361-.042.686-.127.976-.08.283-.204.544-.373.782-.217.3-.554.624-1.009.976-.45.345-.723.56-.818.642a1.828 1.828 0 00-.437.604 2.04 2.04 0 00-.12.891 1.8 1.8 0 01.008.14h-2.137m-.11 3.314v-2.269h2.343v2.27h-2.344M457.897 157l3.941-13.174h1.088L458.97 157h-1.073"/><path id="text5827" fill="#181717" fill-rule="nonzero" d="M11.801 181.18c-.057.863-.387 1.549-.988 2.057-.599.509-1.38.763-2.345.763-1.112 0-1.976-.35-2.595-1.052-.615-.7-.923-1.683-.923-2.948 0-1.292.315-2.282.944-2.97.628-.686 1.532-1.03 2.711-1.03.959 0 1.715.237 2.269.711.557.471.863 1.138.917 2h-1.524c-.064-.43-.238-.756-.52-.979-.282-.227-.663-.34-1.142-.34-.68 0-1.196.221-1.55.665-.353.443-.53 1.09-.53 1.943 0 .825.176 1.462.526 1.912.353.45.854.676 1.503.676.47 0 .853-.12 1.152-.361.3-.244.493-.593.581-1.047h1.514m3.569 2.65c-.136.003-.3.008-.49.015-.187.01-.306.016-.357.016-.567 0-.956-.107-1.167-.32-.207-.216-.31-.64-.31-1.273v-3.03h-.735v-1.052h.734v-1.531h1.468v1.53h.857v1.052h-.857v3.103c0 .148.033.246.097.294.065.045.197.067.398.067h.362v1.129m.861-.041v-5.603h1.376v.958c.194-.385.42-.666.678-.845a1.56 1.56 0 01.923-.273c.058 0 .102.001.133.005.033 0 .06.002.081.005l.005 1.52h-.494c-.405 0-.709.107-.913.32-.204.213-.306.53-.306.949v2.964h-1.483m4.068 0v-7.593h1.483v7.593H20.3"/><path id="text5831" fill="#181717" fill-rule="nonzero" d="M108.714 177.587l-1.097 3.373h2.2l-1.103-3.373m-.946-1.587h1.882l2.855 7.925h-1.71l-.538-1.63h-3.07l-.521 1.63h-1.716l2.818-7.925m5.468 7.925V176h1.565v7.925h-1.565m5.576.043a49.21 49.21 0 00-.516.016c-.197.01-.323.016-.377.016-.598 0-1.009-.111-1.231-.334-.219-.226-.328-.668-.328-1.328v-3.164h-.774v-1.097h.774v-1.598h1.549v1.598h.903v1.097h-.903v3.239c0 .154.034.256.102.307.068.046.208.07.42.07h.38v1.178"/><path id="text5835" fill="#181717" fill-rule="nonzero" d="M408.714 177.587l-1.097 3.373h2.2l-1.103-3.373m-.946-1.587h1.882l2.855 7.925h-1.71l-.538-1.63h-3.07l-.521 1.63h-1.716l2.818-7.925m5.468 7.925V176h1.565v7.925h-1.565m5.576.043a49.21 49.21 0 00-.516.016c-.197.01-.323.016-.377.016-.598 0-1.009-.111-1.231-.334-.219-.226-.328-.668-.328-1.328v-3.164h-.774v-1.097h.774v-1.598h1.549v1.598h.903v1.097h-.903v3.239c0 .154.034.256.102.307.068.046.208.07.42.07h.38v1.178"/><path id="text5839" fill="#181717" fill-rule="nonzero" d="M552.395 181.18c-.057.863-.387 1.549-.988 2.057-.599.509-1.38.763-2.345.763-1.111 0-1.976-.35-2.595-1.052-.615-.7-.922-1.683-.922-2.948 0-1.292.314-2.282.943-2.97.628-.686 1.532-1.03 2.711-1.03.959 0 1.715.237 2.269.711.557.471.863 1.138.917 2h-1.524c-.064-.43-.238-.756-.52-.979-.282-.227-.662-.34-1.142-.34-.68 0-1.196.221-1.55.665-.353.443-.53 1.09-.53 1.943 0 .825.176 1.462.526 1.912.353.45.854.676 1.503.676.47 0 .853-.12 1.152-.361.3-.244.493-.593.582-1.047h1.513m3.569 2.65c-.136.003-.3.008-.49.015-.187.01-.306.016-.356.016-.568 0-.957-.107-1.168-.32-.207-.216-.31-.64-.31-1.273v-3.03h-.735v-1.052h.734v-1.531h1.468v1.53h.857v1.052h-.857v3.103c0 .148.033.246.097.294.065.045.197.067.398.067h.362v1.129m.861-.041v-5.603h1.376v.958c.194-.385.42-.666.678-.845a1.56 1.56 0 01.923-.273c.058 0 .102.001.133.005.034 0 .06.002.081.005l.005 1.52h-.494c-.405 0-.709.107-.913.32-.204.213-.306.53-.306.949v2.964h-1.483m4.068 0v-7.593h1.483v7.593h-1.483"/><path id="text5872" fill="#181717" fill-rule="nonzero" d="M72.458 176.567L70.297 169h1.608l1.29 5.338 1.09-5.338h1.655l1.09 5.338L78.32 169h1.593l-2.156 7.567h-1.48l-1.167-5.795-1.172 5.795h-1.48m8.228-6.206V169h1.49v1.361h-1.49m0 6.206v-5.584h1.49v5.584h-1.49m2.816 0v-5.584h1.46v.663c.208-.27.453-.473.737-.606.283-.137.599-.206.947-.206.614 0 1.074.161 1.377.483.308.318.461.8.461 1.444v3.806h-1.49v-3.375c0-.4-.068-.687-.205-.858-.133-.171-.351-.257-.655-.257-.352 0-.63.106-.835.319-.204.209-.307.495-.307.858v3.313h-1.49m-12.55 13.152v-7.567h1.552v3.108l2.944-3.108h1.94l-3.01 3.062 3.282 4.505h-1.895l-2.457-3.463-.804.802v2.661h-1.552m10.676-1.695h1.485c-.15.589-.454 1.051-.911 1.387-.454.332-1.009.498-1.664.498-.806 0-1.444-.27-1.915-.812-.471-.544-.707-1.28-.707-2.209 0-.914.232-1.635.696-2.163.465-.527 1.1-.79 1.905-.79.853 0 1.512.26 1.977.78.464.517.696 1.255.696 2.214a4.215 4.215 0 01-.015.39h-3.718c.02.44.126.77.318.992.194.223.472.334.834.334.256 0 .466-.05.63-.149.164-.102.294-.26.39-.472m-2.172-1.685h2.192c-.014-.377-.115-.663-.302-.858-.185-.199-.451-.298-.8-.298-.323 0-.58.099-.767.298-.185.198-.292.484-.323.858m4.941 5.62v-1.207a1.976 1.976 0 00.348.02c.294 0 .514-.07.661-.21.147-.137.22-.345.22-.622a.799.799 0 00-.03-.154l-2.008-5.651h1.639l1.172 4.027 1.142-4.027h1.567l-2.289 6.586c-.17.493-.384.829-.64 1.007-.256.181-.64.272-1.152.272-.092 0-.191-.003-.297-.01a6.338 6.338 0 01-.333-.031"/><path id="text5878" fill="#181717" fill-rule="nonzero" d="M472.458 176.567L470.297 169h1.608l1.29 5.338 1.09-5.338h1.655l1.09 5.338 1.29-5.338h1.593l-2.156 7.567h-1.48l-1.167-5.795-1.172 5.795h-1.48m8.228-6.206V169h1.49v1.361h-1.49m0 6.206v-5.584h1.49v5.584h-1.49m2.816 0v-5.584h1.46v.663c.208-.27.453-.473.737-.606.283-.137.599-.206.947-.206.614 0 1.074.161 1.377.483.308.318.461.8.461 1.444v3.806h-1.49v-3.375c0-.4-.068-.687-.205-.858-.133-.171-.351-.257-.655-.257-.352 0-.63.106-.835.319-.204.209-.307.495-.307.858v3.313h-1.49m-12.55 13.152v-7.567h1.552v3.108l2.944-3.108h1.94l-3.01 3.062 3.282 4.505h-1.895l-2.457-3.463-.804.802v2.661h-1.552m10.676-1.695h1.485c-.15.589-.454 1.051-.911 1.387-.454.332-1.009.498-1.664.498-.806 0-1.444-.27-1.915-.812-.471-.544-.707-1.28-.707-2.209 0-.914.232-1.635.696-2.163.465-.527 1.1-.79 1.905-.79.853 0 1.512.26 1.977.78.464.517.696 1.255.696 2.214a4.215 4.215 0 01-.015.39h-3.718c.02.44.126.77.318.992.194.223.472.334.834.334.256 0 .466-.05.63-.149.164-.102.294-.26.39-.472m-2.172-1.685h2.192c-.014-.377-.115-.663-.302-.858-.185-.199-.451-.298-.8-.298-.323 0-.58.099-.767.298-.185.198-.292.484-.323.858m4.941 5.62v-1.207a1.976 1.976 0 00.348.02c.294 0 .514-.07.661-.21.147-.137.22-.345.22-.622a.8.8 0 00-.03-.154l-2.008-5.651h1.639l1.172 4.027 1.142-4.027h1.567l-2.289 6.586c-.17.493-.384.829-.64 1.007-.256.181-.64.272-1.152.272-.092 0-.191-.003-.297-.01a6.338 6.338 0 01-.333-.031"/><path id="text5884" fill="#181717" fill-rule="nonzero" d="M506.93 183.804V176h2.338l1.529 5.94 1.507-5.94h2.348v7.804h-1.482v-6.294l-1.56 6.294h-1.617l-1.58-6.294v6.294h-1.482m12.693-1.748h1.513c-.153.607-.463 1.084-.929 1.43-.462.343-1.027.514-1.695.514-.821 0-1.471-.279-1.951-.837-.48-.562-.72-1.321-.72-2.278 0-.943.236-1.687.71-2.23.472-.545 1.12-.817 1.94-.817.87 0 1.54.269 2.014.806.473.533.71 1.294.71 2.283a4.4 4.4 0 01-.016.403h-3.788c.02.452.129.793.323 1.022.199.23.482.345.85.345.262 0 .476-.052.643-.154.166-.106.299-.268.396-.487m-2.212-1.738h2.233c-.014-.389-.117-.684-.308-.885-.188-.205-.459-.307-.814-.307-.33 0-.591.102-.782.307-.188.205-.298.5-.33.885m4.811 3.486v-5.759h1.487v.683a2.05 2.05 0 01.751-.625c.289-.141.61-.212.965-.212.627 0 1.094.166 1.404.498.313.329.47.825.47 1.49v3.925h-1.519v-3.48c0-.414-.07-.709-.208-.886-.136-.176-.359-.264-.668-.264-.358 0-.642.109-.85.328-.21.215-.314.51-.314.885v3.417h-1.518m11.441-5.759v5.759h-1.487v-.683c-.215.279-.467.489-.756.63a2.191 2.191 0 01-.965.207c-.623 0-1.09-.166-1.404-.498-.31-.332-.464-.829-.464-1.49v-3.925h1.518v3.48c0 .41.068.704.204.88.135.173.36.26.673.26.355 0 .636-.108.845-.323.212-.22.318-.516.318-.89v-3.407h1.518"/><circle id="Oval" cx="109.168" cy="139" r="26" stroke="#C06334" stroke-width="5"/></g></g></svg>
\ No newline at end of file
diff --git a/2-ui/3-event-details/8-onscroll/1-endless-page/solution.md b/2-ui/3-event-details/8-onscroll/1-endless-page/solution.md
index 10945ccd7..54c101193 100644
--- a/2-ui/3-event-details/8-onscroll/1-endless-page/solution.md
+++ b/2-ui/3-event-details/8-onscroll/1-endless-page/solution.md
@@ -55,11 +55,11 @@ function populate() {
     // document bottom
     let windowRelativeBottom = document.documentElement.getBoundingClientRect().bottom;
 
-    // if the user scrolled far enough (<100px to the end)
-    if (windowRelativeBottom < document.documentElement.clientHeight + 100) {
-      // let's add more data
-      document.body.insertAdjacentHTML("beforeend", `<p>Date: ${new Date()}</p>`);
-    }
+    // if the user hasn't scrolled far enough (>100px to the end)
+    if (windowRelativeBottom > document.documentElement.clientHeight + 100) break;
+    
+    // let's add more data
+    document.body.insertAdjacentHTML("beforeend", `<p>Date: ${new Date()}</p>`);
   }
 }
 ```
diff --git a/2-ui/3-event-details/8-onscroll/article.md b/2-ui/3-event-details/8-onscroll/article.md
index 7b5cf4848..734bd84c6 100644
--- a/2-ui/3-event-details/8-onscroll/article.md
+++ b/2-ui/3-event-details/8-onscroll/article.md
@@ -1,6 +1,6 @@
 # Scrolling
 
-The `scroll` event allows to react on a page or element scrolling. There are quite a few good things we can do here.
+The `scroll` event allows reacting to a page or element scrolling. There are quite a few good things we can do here.
 
 For instance:
 - Show/hide additional controls or information depending on where in the document the user is.
@@ -34,4 +34,4 @@ If we add an event handler to these events and `event.preventDefault()` in it, t
 
 There are many ways to initiate a scroll, so it's more reliable to use CSS, `overflow` property.
 
-Here are few tasks that you can solve or look through to see the applications on `onscroll`.
+Here are few tasks that you can solve or look through to see applications of `onscroll`.
diff --git a/2-ui/4-forms-controls/1-form-elements/article.md b/2-ui/4-forms-controls/1-form-elements/article.md
index d989a5fb8..f22518d9d 100644
--- a/2-ui/4-forms-controls/1-form-elements/article.md
+++ b/2-ui/4-forms-controls/1-form-elements/article.md
@@ -8,11 +8,11 @@ Working with forms will be much more convenient when we learn them.
 
 Document forms are members of the special collection `document.forms`.
 
-That's a so-called "named collection": it's both named and ordered. We can use both the name or the number in the document to get the form.
+That's a so-called *"named collection"*: it's both named and ordered. We can use both the name or the number in the document to get the form.
 
 ```js no-beautify
-document.forms.my - the form with name="my"
-document.forms[0] - the first form in the document
+document.forms.my; // the form with name="my"
+document.forms[0]; // the first form in the document
 ```
 
 When we have a form, then any element is available in the named collection `form.elements`.
@@ -36,9 +36,9 @@ For instance:
 </script>
 ```
 
-There may be multiple elements with the same name, that's often the case with radio buttons.
+There may be multiple elements with the same name. This is typical with radio buttons and checkboxes.
 
-In that case `form.elements[name]` is a collection, for instance:
+In that case, `form.elements[name]` is a *collection*. For instance:
 
 ```html run height=40
 <form>
@@ -119,14 +119,13 @@ That's easy to see in an example:
 </script>
 ```
 
-That's usually not a problem, because we rarely change names of form elements.
+That's usually not a problem, however, because we rarely change names of form elements.
 
 ````
 
 ## Backreference: element.form
 
-For any element, the form is available as `element.form`. So a form references all elements, and elements
-reference the form.
+For any element, the form is available as `element.form`. So a form references all elements, and elements reference the form.
 
 Here's the picture:
 
@@ -156,7 +155,7 @@ Let's talk about form controls.
 
 ### input and textarea
 
-We can access their value as `input.value` (string) or `input.checked` (boolean) for checkboxes.
+We can access their value as `input.value` (string) or `input.checked` (boolean) for checkboxes and radio buttons.
 
 Like this:
 
@@ -178,18 +177,16 @@ It stores only the HTML that was initially on the page, not the current value.
 A `<select>` element has 3 important properties:
 
 1. `select.options` -- the collection of `<option>` subelements,
-2. `select.value` -- the value of the currently selected `<option>`,
-3. `select.selectedIndex` -- the number of the currently selected `<option>`.
+2. `select.value` -- the *value* of the currently selected `<option>`,
+3. `select.selectedIndex` -- the *number* of the currently selected `<option>`.
 
 They provide three different ways of setting a value for a `<select>`:
 
-1. Find the corresponding `<option>` element and set `option.selected` to `true`.
-2. Set `select.value` to the value.
-3. Set `select.selectedIndex` to the number of the option.
+1. Find the corresponding `<option>` element (e.g. among `select.options`) and set its `option.selected` to `true`.
+2. If we know a new value: set `select.value` to the new value.
+3. If we know the new option number: set `select.selectedIndex` to that number.
 
-The first way is the most obvious, but `(2)` and `(3)` are usually more convenient.
-
-Here is an example:
+Here is an example of all three methods:
 
 ```html run
 <select id="select">
@@ -200,15 +197,18 @@ Here is an example:
 
 <script>
   // all three lines do the same thing
-  select.options[2].selected = true;
+  select.options[2].selected = true; 
   select.selectedIndex = 2;
   select.value = 'banana';
+  // please note: options start from zero, so index 2 means the 3rd option.
 </script>
 ```
 
-Unlike most other controls, `<select>` allows to select multiple options at once if it has `multiple` attribute. That's feature is rarely used. In that case we need to use the first way: add/remove the `selected` property from `<option>` subelements.
+Unlike most other controls, `<select>` allows to select multiple options at once if it has `multiple` attribute. This attribute is rarely used, though.
+
+For multiple selected values, use the first way of setting values: add/remove the `selected` property from `<option>` subelements.
 
-We can get their collection as `select.options`, for instance:
+Here's an example of how to get selected values from a multi-select:
 
 ```html run
 <select id="select" *!*multiple*/!*>
@@ -231,31 +231,31 @@ The full specification of the `<select>` element is available in the specificati
 
 ### new Option
 
-This is rarely used on its own. But there's still an interesting thing.
-
-In the [specification](https://html.spec.whatwg.org/multipage/forms.html#the-option-element) there's a nice short syntax to create `<option>` elements:
+In the [specification](https://html.spec.whatwg.org/multipage/forms.html#the-option-element) there's a nice short syntax to create an `<option>` element:
 
 ```js
 option = new Option(text, value, defaultSelected, selected);
 ```
 
-Parameters:
+This syntax is optional. We can use `document.createElement('option')` and set attributes manually. Still, it may be shorter, so here are the parameters:
 
 - `text` -- the text inside the option,
 - `value` -- the option value,
 - `defaultSelected` -- if `true`, then `selected` HTML-attribute is created,
 - `selected` -- if `true`, then the option is selected.
 
-There may be a small confusion about `defaultSelected` and `selected`. That's simple: `defaultSelected` sets HTML-attribute, that we can get using `option.getAttribute('selected')`. And `selected` - whether the option is selected or not, that's more important. Usually both values are either set to `true` or not set (same as `false`).
+The difference between `defaultSelected` and `selected` is that `defaultSelected` sets the HTML-attribute (that we can get using `option.getAttribute('selected')`, while `selected` sets whether the option is selected or not.
 
-For instance:
+In practice, one should usually set _both_ values to `true` or `false`. (Or, simply omit them; both default to `false`.)
+
+For instance, here's a new "unselected" option:
 
 ```js
 let option = new Option("Text", "value");
 // creates <option value="value">Text</option>
 ```
 
-The same element selected:
+The same option, but selected:
 
 ```js
 let option = new Option("Text", "value", true, true);
@@ -289,9 +289,9 @@ Form navigation:
 `element.form`
 : Elements reference their form in the `form` property.
 
-Value is available as `input.value`, `textarea.value`, `select.value` etc, or `input.checked` for checkboxes and radio buttons.
+Value is available as `input.value`, `textarea.value`, `select.value`, etc. (For checkboxes and radio buttons, use `input.checked` to determine whether a value is selected.)
 
-For `<select>` we can also get the value by the index `select.selectedIndex` or through the options collection `select.options`.
+For `<select>`, one can also get the value by the index `select.selectedIndex` or through the options collection `select.options`.
 
 These are the basics to start working with forms. We'll meet many examples further in the tutorial.
 
diff --git a/2-ui/4-forms-controls/2-focus-blur/4-edit-td-click/task.md b/2-ui/4-forms-controls/2-focus-blur/4-edit-td-click/task.md
index 2cccea020..378bd1f54 100644
--- a/2-ui/4-forms-controls/2-focus-blur/4-edit-td-click/task.md
+++ b/2-ui/4-forms-controls/2-focus-blur/4-edit-td-click/task.md
@@ -6,7 +6,7 @@ importance: 5
 
 Make table cells editable on click.
 
-- On click -- the cell should became "editable" (textarea appears inside), we can change HTML. There should be no resize, all geometry should remain the same.
+- On click -- the cell should become "editable" (textarea appears inside), we can change HTML. There should be no resize, all geometry should remain the same.
 - Buttons OK and CANCEL appear below the cell to finish/cancel the editing.
 - Only one cell may be editable at a moment. While a `<td>` is in "edit mode", clicks on other cells are ignored.
 - The table may have many cells. Use event delegation.
diff --git a/2-ui/4-forms-controls/2-focus-blur/5-keyboard-mouse/task.md b/2-ui/4-forms-controls/2-focus-blur/5-keyboard-mouse/task.md
index fc48c21ff..644d814d9 100644
--- a/2-ui/4-forms-controls/2-focus-blur/5-keyboard-mouse/task.md
+++ b/2-ui/4-forms-controls/2-focus-blur/5-keyboard-mouse/task.md
@@ -9,4 +9,5 @@ Focus on the mouse. Then use arrow keys to move it:
 [demo src="solution"]
 
 P.S. Don't put event handlers anywhere except the `#mouse` element.
+
 P.P.S. Don't modify HTML/CSS, the approach should be generic and work with any element.
diff --git a/2-ui/4-forms-controls/2-focus-blur/article.md b/2-ui/4-forms-controls/2-focus-blur/article.md
index d42013e5b..c253dc11d 100644
--- a/2-ui/4-forms-controls/2-focus-blur/article.md
+++ b/2-ui/4-forms-controls/2-focus-blur/article.md
@@ -1,6 +1,6 @@
 # Focusing: focus/blur
 
-An element receives a focus when the user either clicks on it or uses the `key:Tab` key on the keyboard. There's also an `autofocus` HTML attribute that puts the focus into an element by default when a page loads and other means of getting a focus.
+An element receives the focus when the user either clicks on it or uses the `key:Tab` key on the keyboard. There's also an `autofocus` HTML attribute that puts the focus onto an element by default when a page loads and other means of getting the focus.
 
 Focusing on an element generally means: "prepare to accept the data here", so that's the moment when we can run the code to initialize the required functionality.
 
@@ -18,7 +18,7 @@ Let's use them for validation of an input field.
 
 In the example below:
 
-- The `blur` handler checks if the field the email is entered, and if not -- shows an error.
+- The `blur` handler checks if the field has an email entered, and if not -- shows an error.
 - The `focus` handler hides the error message (on `blur` it will be checked again):
 
 ```html run autorun height=60
@@ -90,6 +90,8 @@ If we enter something into the input and then try to use `key:Tab` or click away
 
 Please note that we can't "prevent losing focus" by calling `event.preventDefault()` in `onblur`, because `onblur` works *after* the element lost the focus.
 
+In practice though, one should think well, before implementing something like this, because we generally *should show errors* to the user, but *should not prevent their progress* in filling our form. They may want to fill other fields first.
+
 ```warn header="JavaScript-initiated focus loss"
 A focus loss can occur for many reasons.
 
@@ -104,11 +106,11 @@ The best recipe is to be careful when using these events. If we want to track us
 ```
 ## Allow focusing on any element: tabindex
 
-By default many elements do not support focusing.
+By default, many elements do not support focusing.
 
 The list varies a bit between browsers, but one thing is always correct: `focus/blur` support is guaranteed for elements that a visitor can interact with: `<button>`, `<input>`, `<select>`, `<a>` and so on.
 
-From the other hand, elements that exist to format something, such as `<div>`, `<span>`, `<table>` -- are unfocusable by default. The method `elem.focus()` doesn't work on them, and `focus/blur` events are never triggered.
+On the other hand, elements that exist to format something, such as `<div>`, `<span>`, `<table>` -- are unfocusable by default. The method `elem.focus()` doesn't work on them, and `focus/blur` events are never triggered.
 
 This can be changed using HTML-attribute `tabindex`.
 
@@ -118,7 +120,7 @@ That is: if we have two elements, the first has `tabindex="1"`, and the second h
 
 The switch order is: elements with `tabindex` from `1` and above go first (in the `tabindex` order), and then elements without `tabindex` (e.g. a regular `<input>`).
 
-Elements with matching `tabindex` are switched in the document source order (the default order).
+Elements without matching `tabindex` are switched in the document source order (the default order).
 
 There are two special values:
 
@@ -131,7 +133,7 @@ There are two special values:
 For instance, here's a list. Click the first item and press `key:Tab`:
 
 ```html autorun no-beautify
-Click the first item and press Tab. Keep track of the order. Please note that many subsequent Tabs can move the focus out of the iframe with the example.
+Click the first item and press Tab. Keep track of the order. Please note that many subsequent Tabs can move the focus out of the iframe in the example.
 <ul>
   <li tabindex="1">One</li>
   <li tabindex="0">Zero</li>
@@ -216,7 +218,7 @@ So here's another working variant:
 
 ## Summary
 
-Events `focus` and `blur` trigger on focusing/losing focus on the element.
+Events `focus` and `blur` trigger on an element focusing/losing focus.
 
 Their specials are:
 - They do not bubble. Can use capturing state instead or `focusin/focusout`.
diff --git a/2-ui/4-forms-controls/3-events-change-input/1-deposit-calculator/solution.view/index.html b/2-ui/4-forms-controls/3-events-change-input/1-deposit-calculator/solution.view/index.html
index 4850b2ca9..0515c839e 100644
--- a/2-ui/4-forms-controls/3-events-change-input/1-deposit-calculator/solution.view/index.html
+++ b/2-ui/4-forms-controls/3-events-change-input/1-deposit-calculator/solution.view/index.html
@@ -96,7 +96,7 @@
       let years = form.months.value / 12;
       if (!years) return;
 
-      let result = Math.round(initial * (1 + interest * years));
+      let result = Math.round(initial * (1 + interest) ** years);
 
       let height = result / form.money.value * 100 + 'px';
       document.getElementById('height-after').style.height = height;
diff --git a/2-ui/4-forms-controls/3-events-change-input/1-deposit-calculator/task.md b/2-ui/4-forms-controls/3-events-change-input/1-deposit-calculator/task.md
index e324577a9..73f0477ff 100644
--- a/2-ui/4-forms-controls/3-events-change-input/1-deposit-calculator/task.md
+++ b/2-ui/4-forms-controls/3-events-change-input/1-deposit-calculator/task.md
@@ -17,5 +17,5 @@ The formula is:
 // initial: the initial money sum
 // interest: e.g. 0.05 means 5% per year
 // years: how many years to wait
-let result = Math.round(initial * (1 + interest * years));
+let result = Math.round(initial * (1 + interest) ** years);
 ```
diff --git a/2-ui/4-forms-controls/3-events-change-input/article.md b/2-ui/4-forms-controls/3-events-change-input/article.md
index b43a305b3..480197ae5 100644
--- a/2-ui/4-forms-controls/3-events-change-input/article.md
+++ b/2-ui/4-forms-controls/3-events-change-input/article.md
@@ -58,29 +58,50 @@ So we can't use `event.preventDefault()` there -- it's just too late, there woul
 
 These events occur on cutting/copying/pasting a value.
 
-They belong to [ClipboardEvent](https://www.w3.org/TR/clipboard-apis/#clipboard-event-interfaces) class and provide access to the data that is copied/pasted.
+They belong to [ClipboardEvent](https://www.w3.org/TR/clipboard-apis/#clipboard-event-interfaces) class and provide access to the data that is cut/copied/pasted.
 
 We also can use `event.preventDefault()` to abort the action, then nothing gets copied/pasted.
 
-For instance, the code below prevents all such events and shows what we are trying to cut/copy/paste:
+For instance, the code below prevents all `cut/copy/paste` events and shows the text we're trying to cut/copy/paste:
 
 ```html autorun height=40 run
 <input type="text" id="input">
 <script>
-  input.oncut = input.oncopy = input.onpaste = function(event) {
-    alert(event.type + ' - ' + event.clipboardData.getData('text/plain'));
-    return false;
+  input.onpaste = function(event) {
+    alert("paste: " + event.clipboardData.getData('text/plain'));
+    event.preventDefault();
+  };
+
+  input.oncut = input.oncopy = function(event) {
+    alert(event.type + '-' + document.getSelection());
+    event.preventDefault();
   };
 </script>
 ```
 
-Please note, that it's possible to copy/paste not just text, but everything. For instance, we can copy a file in the OS file manager, and paste it.
+Please note: inside `cut` and `copy` event handlers a call to  `event.clipboardData.getData(...)` returns an empty string. That's because technically the data isn't in the clipboard yet. If we use `event.preventDefault()` it won't be copied at all.
+
+So the example above uses `document.getSelection()` to get the selected text. You can find more details about document selection in the article <info:selection-range>.
+
+It's possible to copy/paste not just text, but everything. For instance, we can copy a file in the OS file manager, and paste it.
+
+That's because `clipboardData` implements `DataTransfer` interface, commonly used for drag'n'drop and copy/pasting. It's a bit beyond our scope now, but you can find its methods in the [DataTransfer specification](https://html.spec.whatwg.org/multipage/dnd.html#the-datatransfer-interface).
+
+Also, there's an additional asynchronous API of accessing the clipboard: `navigator.clipboard`. More about it in the specification [Clipboard API and events](https://www.w3.org/TR/clipboard-apis/), [not supported by Firefox](https://caniuse.com/async-clipboard).
+
+### Safety restrictions
+
+The clipboard is a "global" OS-level thing. A user may switch between various applications, copy/paste different things, and a browser page shouldn't see all that.
+
+So most browsers allow seamless read/write access to the clipboard only in the scope of certain user actions, such as copying/pasting etc.
+
+It's forbidden to generate "custom" clipboard events with `dispatchEvent` in all browsers except Firefox. And even if we manage to dispatch such event, the specification clearly states that such "synthetic" events must not provide access to the clipboard.
 
-There's a list of methods [in the specification](https://www.w3.org/TR/clipboard-apis/#dfn-datatransfer) that can work with different data types including files, read/write to the clipboard.
+Even if someone decides to save `event.clipboardData` in an event handler, and then access it later -- it won't work.
 
-But please note that clipboard is a "global" OS-level thing. Most browsers allow read/write access to the clipboard only in the scope of certain user actions for the safety, e.g. in `onclick` event handlers.
+To reiterate, [event.clipboardData](https://www.w3.org/TR/clipboard-apis/#clipboardevent-clipboarddata) works solely in the context of user-initiated event handlers.
 
-Also it's forbidden to generate "custom" clipboard events with `dispatchEvent` in all browsers except Firefox.
+On the other hand, [navigator.clipboard](https://www.w3.org/TR/clipboard-apis/#h-navigator-clipboard) is the more recent API, meant for use in any context. It asks for user permission, if needed.
 
 ## Summary
 
@@ -90,4 +111,4 @@ Data change events:
 |---------|----------|-------------|
 | `change`| A value was changed. | For text inputs triggers on focus loss. |
 | `input` | For text inputs on every change. | Triggers immediately unlike `change`. |
-| `cut/copy/paste` | Cut/copy/paste actions. | The action can be prevented. The `event.clipboardData` property gives read/write access to the clipboard. |
+| `cut/copy/paste` | Cut/copy/paste actions. | The action can be prevented. The `event.clipboardData` property gives access to the clipboard. All browsers except Firefox also support `navigator.clipboard`. |
diff --git a/2-ui/5-loading/01-onload-ondomcontentloaded/article.md b/2-ui/5-loading/01-onload-ondomcontentloaded/article.md
index bc637e63e..07624a658 100644
--- a/2-ui/5-loading/01-onload-ondomcontentloaded/article.md
+++ b/2-ui/5-loading/01-onload-ondomcontentloaded/article.md
@@ -2,7 +2,7 @@
 
 The lifecycle of an HTML page has three important events:
 
-- `DOMContentLoaded` -- the browser fully loaded HTML, and the DOM tree is built, but external resources like pictures `<img>` and stylesheets may be not yet loaded.  
+- `DOMContentLoaded` -- the browser fully loaded HTML, and the DOM tree is built, but external resources like pictures `<img>` and stylesheets may not yet have loaded.
 - `load` -- not only HTML is loaded, but also all the external resources: images, styles etc.
 - `beforeunload/unload` -- the user is leaving the page.
 
@@ -33,7 +33,7 @@ For instance:
   function ready() {
     alert('DOM is ready');
 
-    // image is not yet loaded (unless was cached), so the size is 0x0
+    // image is not yet loaded (unless it was cached), so the size is 0x0
     alert(`Image size: ${img.offsetWidth}x${img.offsetHeight}`);
   }
 
@@ -45,7 +45,7 @@ For instance:
 <img id="img" src="https://en.js.cx/clipart/train.gif?speed=1&cache=0">
 ```
 
-In the example the `DOMContentLoaded` handler runs when the document is loaded, so it can see all the elements, including `<img>` below.
+In the example, the `DOMContentLoaded` handler runs when the document is loaded, so it can see all the elements, including `<img>` below.
 
 But it doesn't wait for the image to load. So `alert` shows zero sizes.
 
@@ -85,10 +85,10 @@ External style sheets don't affect DOM, so `DOMContentLoaded` does not wait for
 
 But there's a pitfall. If we have a script after the style, then that script must wait until the stylesheet loads:
 
-```html
+```html run
 <link type="text/css" rel="stylesheet" href="style.css">
 <script>
-  // the script doesn't not execute until the stylesheet is loaded
+  // the script doesn't execute until the stylesheet is loaded
   alert(getComputedStyle(document.body).marginTop);
 </script>
 ```
@@ -108,13 +108,13 @@ So if `DOMContentLoaded` is postponed by long-loading scripts, then autofill als
 
 ## window.onload [#window-onload]
 
-The `load` event on the `window` object triggers when the whole page is loaded including styles, images and other resources.
+The `load` event on the `window` object triggers when the whole page is loaded including styles, images and other resources. This event is available via the `onload` property.
 
 The example below correctly shows image sizes, because `window.onload` waits for all images:
 
 ```html run height=200 refresh
 <script>
-  window.onload = function() {
+  window.onload = function() { // can also use window.addEventListener('load', (event) => {
     alert('Page loaded');
 
     // image is loaded at this time
@@ -145,7 +145,7 @@ let analyticsData = { /* object with gathered data */ };
 
 window.addEventListener("unload", function() {
   navigator.sendBeacon("/analytics", JSON.stringify(analyticsData));
-};
+});
 ```
 
 - The request is sent as POST.
@@ -157,7 +157,7 @@ When the `sendBeacon` request is finished, the browser probably has already left
 There's also a `keepalive` flag for doing such "after-page-left" requests in  [fetch](info:fetch) method for generic network requests. You can find more information in the chapter <info:fetch-api>.
 
 
-If we want to cancel the transition to another page, we can't do it here. But we can use  another event -- `onbeforeunload`.
+If we want to cancel the transition to another page, we can't do it here. But we can use another event -- `onbeforeunload`.
 
 ## window.onbeforeunload [#window.onbeforeunload]
 
@@ -185,6 +185,26 @@ window.onbeforeunload = function() {
 
 The behavior was changed, because some webmasters abused this event handler by showing misleading and annoying messages. So right now old browsers still may show it as a message, but aside of that -- there's no way to customize the message shown to the user.
 
+````warn header="The `event.preventDefault()` doesn't work from a `beforeunload` handler"
+That may sound weird, but most browsers ignore `event.preventDefault()`.
+
+Which means, following code may not work:
+```js run
+window.addEventListener("beforeunload", (event) => {
+  // doesn't work, so this event handler doesn't do anything
+	event.preventDefault();
+});
+```
+
+Instead, in such handlers one should set `event.returnValue` to a string to get the result similar to the code above:
+```js run
+window.addEventListener("beforeunload", (event) => {
+  // works, same as returning from window.onbeforeunload
+	event.returnValue = "There are unsaved changes. Leave now?";
+});
+```
+````
+
 ## readyState
 
 What happens if we set the `DOMContentLoaded` handler after the document is loaded?
@@ -209,7 +229,7 @@ Like this:
 function work() { /*...*/ }
 
 if (document.readyState == 'loading') {
-  // loading yet, wait for the event
+  // still loading, wait for the event
   document.addEventListener('DOMContentLoaded', work);
 } else {
   // DOM is ready!
@@ -245,7 +265,7 @@ Here's a document with `<iframe>`, `<img>` and handlers that log events:
 
 <iframe src="iframe.html" onload="log('iframe onload')"></iframe>
 
-<img src="http://en.js.cx/clipart/train.gif" id="img">
+<img src="https://en.js.cx/clipart/train.gif" id="img">
 <script>
   img.onload = () => log('img onload');
 </script>
@@ -277,7 +297,7 @@ Page load events:
   - Images and other resources may also still continue loading.
 - The `load` event on `window` triggers when the page and all resources are loaded. We rarely use it, because there's usually no need to wait for so long.
 - The `beforeunload` event on `window` triggers when the user wants to leave the page. If we cancel the event, browser asks whether the user really wants to leave (e.g we have unsaved changes).
-- `The unload` event on `window` triggers when the user is finally leaving, in the handler we can only do simple things that do not involve delays or asking a user. Because of that limitation, it's rarely used. We can send out a network request with `navigator.sendBeacon`.
+- The `unload` event on `window` triggers when the user is finally leaving, in the handler we can only do simple things that do not involve delays or asking a user. Because of that limitation, it's rarely used. We can send out a network request with `navigator.sendBeacon`.
 - `document.readyState` is the current state of the document, changes can be tracked in the `readystatechange` event:
   - `loading` -- the document is loading.
   - `interactive` -- the document is parsed, happens at about the same time as `DOMContentLoaded`, but before it.
diff --git a/2-ui/5-loading/01-onload-ondomcontentloaded/readystate.view/index.html b/2-ui/5-loading/01-onload-ondomcontentloaded/readystate.view/index.html
index a4685a716..27df70939 100644
--- a/2-ui/5-loading/01-onload-ondomcontentloaded/readystate.view/index.html
+++ b/2-ui/5-loading/01-onload-ondomcontentloaded/readystate.view/index.html
@@ -9,8 +9,8 @@
   [20] readyState:interactive
   [21] DOMContentLoaded
   [30] iframe onload
-  [40] readyState:complete
   [40] img onload
+  [40] readyState:complete
   [40] window onload
   -->
 
diff --git a/2-ui/5-loading/02-script-async-defer/article.md b/2-ui/5-loading/02-script-async-defer/article.md
index ca82a7302..f97c000d6 100644
--- a/2-ui/5-loading/02-script-async-defer/article.md
+++ b/2-ui/5-loading/02-script-async-defer/article.md
@@ -3,7 +3,7 @@
 
 In modern websites, scripts are often "heavier" than HTML: their download size is larger, and processing time is also longer.
 
-When the browser loads HTML and comes across a `<script>...</script>` tag, it can't continue building the DOM. It must execute the script right now. The same happens for external scripts `<script src="..."></script>`: the browser must wait until the script downloads, execute it, and only after process the rest of the page.
+When the browser loads HTML and comes across a `<script>...</script>` tag, it can't continue building the DOM. It must execute the script right now. The same happens for external scripts `<script src="..."></script>`: the browser must wait for the script to download, execute the downloaded script, and only then can it process the rest of the page.
 
 That leads to two important issues:
 
@@ -37,7 +37,7 @@ Luckily, there are two `<script>` attributes that solve the problem for us: `def
 
 ## defer
 
-The `defer` attribute tells the browser that it should go on working with the page, and load the script "in background", then run the script when it loads.
+The `defer` attribute tells the browser not to wait for the script. Instead, the browser will continue to process the HTML, build DOM. The script loads "in the background", and then runs when the DOM is fully built.
 
 Here's the same example as above, but with `defer`:
 
@@ -50,16 +50,18 @@ Here's the same example as above, but with `defer`:
 <p>...content after script...</p>
 ```
 
+In other words:
+
 - Scripts with `defer` never block the page.
-- Scripts with `defer` always execute when the DOM is ready, but before `DOMContentLoaded` event.
+- Scripts with `defer` always execute when the DOM is ready (but before `DOMContentLoaded` event).
 
-The following example demonstrates that:
+The following example demonstrates the second part:
 
 ```html run height=100
 <p>...content before scripts...</p>
 
 <script>
-  document.addEventListener('DOMContentLoaded', () => alert("DOM ready after defer!")); // (2)
+  document.addEventListener('DOMContentLoaded', () => alert("DOM ready after defer!"));
 </script>
 
 <script defer src="https://javascript.info/article/script-async-defer/long.js?speed=1"></script>
@@ -68,40 +70,44 @@ The following example demonstrates that:
 ```
 
 1. The page content shows up immediately.
-2. `DOMContentLoaded` waits for the deferred script. It only triggers when the script `(2)` is downloaded and executed.
+2. `DOMContentLoaded` event handler waits for the deferred script. It only triggers when the script is downloaded and executed.
 
-Deferred scripts keep their relative order, just like regular scripts.
+**Deferred scripts keep their relative order, just like regular scripts.**
 
-So, if we have a long script first, and then a smaller one, then the latter one waits.
+Let's say, we have two deferred scripts: the `long.js` and then `small.js`:
 
 ```html
 <script defer src="https://javascript.info/article/script-async-defer/long.js"></script>
 <script defer src="https://javascript.info/article/script-async-defer/small.js"></script>
 ```
 
-```smart header="The small script downloads first, runs second"
-Browsers scan the page for scripts and download them in parallel, to improve performance. So in the example above both scripts download in parallel. The `small.js` probably makes it first.
+Browsers scan the page for scripts and download them in parallel, to improve performance. So in the example above both scripts download in parallel. The `small.js` probably finishes first.
 
-But the specification requires scripts to execute in the document order, so it waits for `long.js` to execute.
-```
+...But the `defer` attribute, besides telling the browser "not to block", ensures that the relative order is kept. So even though `small.js` loads first, it still waits and runs after `long.js` executes.
+
+That may be important for cases when we need to load a JavaScript library and then a script that depends on it.
 
 ```smart header="The `defer` attribute is only for external scripts"
 The `defer` attribute is ignored if the `<script>` tag has no `src`.
 ```
 
-
 ## async
 
+The `async` attribute is somewhat like `defer`. It also makes the script non-blocking. But it has important differences in the behavior.
+
 The `async` attribute means that a script is completely independent:
 
-- The page doesn't wait for async scripts, the contents are processed and displayed.
+- The browser doesn't block on `async` scripts (like `defer`).
+- Other scripts don't wait for `async` scripts, and `async` scripts don't wait for them.
 - `DOMContentLoaded` and async scripts don't wait for each other:
     - `DOMContentLoaded` may happen both before an async script (if an async script finishes loading after the page is complete)
     - ...or after an async script (if an async script is short or was in HTTP-cache)
-- Other scripts don't wait for `async` scripts, and `async` scripts don't wait for them.
 
+In other words, `async` scripts load in the background and run when ready. The DOM and other scripts don't wait for them, and they don't wait for anything. A fully independent script that runs when loaded. As simple, as it can get, right?
+
+Here's an example similar to what we've seen with `defer`: two scripts `long.js` and `small.js`, but now with `async` instead of `defer`.
 
-So, if we have several `async` scripts, they may execute in any order. Whatever loads first -- runs first:
+They don't wait for each other. Whatever loads first (probably `small.js`) -- runs first:
 
 ```html run height=100
 <p>...content before scripts...</p>
@@ -116,9 +122,9 @@ So, if we have several `async` scripts, they may execute in any order. Whatever
 <p>...content after scripts...</p>
 ```
 
-1. The page content shows up immediately: `async` doesn't block it.
-2. `DOMContentLoaded` may happen both before and after `async`, no guarantees here.
-3. Async scripts don't wait for each other. A smaller script `small.js` goes second, but probably loads before `long.js`, so runs first. That's called a "load-first" order.
+- The page content shows up immediately: `async` doesn't block it.
+- `DOMContentLoaded` may happen both before and after `async`, no guarantees here.
+- A smaller script `small.js` goes second, but probably loads before `long.js`, so `small.js` runs first. Although, it might be that `long.js` loads first, if cached, then it runs first. In other words, async scripts run in the "load-first" order.
 
 Async scripts are great when we integrate an independent third-party script into the page: counters, ads and so on, as they don't depend on our scripts, and our scripts shouldn't wait for them:
 
@@ -127,10 +133,15 @@ Async scripts are great when we integrate an independent third-party script into
 <script async src="https://google-analytics.com/analytics.js"></script>
 ```
 
+```smart header="The `async` attribute is only for external scripts"
+Just like `defer`, the `async` attribute is ignored if the `<script>` tag has no `src`.
+```
 
 ## Dynamic scripts
 
-We can also add a script dynamically using JavaScript:
+There's one more important way of adding a script to the page.
+
+We can create a script and append it to the document dynamically using JavaScript:
 
 ```js run
 let script = document.createElement('script');
@@ -146,20 +157,11 @@ That is:
 - They don't wait for anything, nothing waits for them.
 - The script that loads first -- runs first ("load-first" order).
 
+This can be changed if we explicitly set `script.async=false`. Then scripts will be executed in the document order, just like `defer`.
 
-```js run
-let script = document.createElement('script');
-script.src = "/article/script-async-defer/long.js";
-
-*!*
-script.async = false;
-*/!*
-
-document.body.append(script);
-```
-
-For example, here we add two scripts. Without `script.async=false` they would execute in load-first order (the `small.js` probably first). But with that flag the order is "as in the document":
+In this example, `loadScript(src)` function adds a script and also sets `async` to `false`.
 
+So `long.js` always runs first (as it's added first):
 
 ```js run
 function loadScript(src) {
@@ -174,6 +176,10 @@ loadScript("/article/script-async-defer/long.js");
 loadScript("/article/script-async-defer/small.js");
 ```
 
+Without `script.async=false`, scripts would execute in default, load-first order (the `small.js` probably first).
+
+Again, as with the `defer`, the order matters if we'd like to load a library and then another script that depends on it.
+
 
 ## Summary
 
@@ -183,15 +189,17 @@ But there are also essential differences between them:
 
 |         | Order | `DOMContentLoaded` |
 |---------|---------|---------|
-| `async` | *Load-first order*. Their document order doesn't matter -- which loads first |  Irrelevant. May load and execute while the document has not yet been fully downloaded. That happens if scripts are small or cached, and the document is long enough. |
+| `async` | *Load-first order*. Their document order doesn't matter -- which loads first runs first |  Irrelevant. May load and execute while the document has not yet been fully downloaded. That happens if scripts are small or cached, and the document is long enough. |
 | `defer` | *Document order* (as they go in the document). |  Execute after the document is loaded and parsed (they wait if needed), right before `DOMContentLoaded`. |
 
+In practice, `defer` is used for scripts that need the whole DOM and/or their relative execution order is important.
+
+And  `async` is used for independent scripts, like counters or ads. And their relative execution order does not matter.
+
 ```warn header="Page without scripts should be usable"
-Please note that if you're using `defer`, then the page is visible *before* the script loads.
+Please note: if you're using `defer` or `async`, then user will see the page *before* the script loads.
 
-So the user may read the page, but some graphical components are probably not ready yet.
+In such case, some graphical components are probably not initialized yet.
 
-There should be "loading" indications in the proper places, and disabled buttons should show as such, so the user can clearly see what's ready and what's not.
+Don't forget to put "loading" indication and disable buttons that aren't functional yet. Let the user clearly see what he can do on the page, and what's still getting ready.
 ```
-
-In practice, `defer` is used for scripts that need the whole DOM and/or their relative execution order is important. And  `async` is used for independent scripts, like counters or ads. And their relative execution order does not matter.
diff --git a/2-ui/5-loading/03-onload-onerror/article.md b/2-ui/5-loading/03-onload-onerror/article.md
index e1dcc7c70..590e54ab4 100644
--- a/2-ui/5-loading/03-onload-onerror/article.md
+++ b/2-ui/5-loading/03-onload-onerror/article.md
@@ -41,8 +41,8 @@ document.head.append(script);
 
 *!*
 script.onload = function() {
-  // the script creates a helper function "_"
-  alert(_); // the function is available
+  // the script creates a variable "_"
+  alert( _.VERSION ); // shows library version
 };
 */!*
 ```
@@ -107,7 +107,7 @@ That's for historical reasons.
 
 There's a rule: scripts from one site can't access contents of the other site. So, e.g. a script at `https://facebook.com` can't read the user's mailbox at `https://gmail.com`.
 
-Or, to be more precise, one origin (domain/port/protocol triplet) can't access the content from another one. So even if we have a subdomain, or just another port, these are different origins, no access to each other.
+Or, to be more precise, one origin (domain/port/protocol triplet) can't access the content from another one. So even if we have a subdomain, or just another port, these are different origins with no access to each other.
 
 This rule also affects resources from other domains.
 
@@ -159,7 +159,7 @@ Details may vary depending on the browser, but the idea is the same: any informa
 
 Why do we need error details?
 
-There are many services (and we can build our own) that listen for global errors using `window.onerror`, save errors and provide an interface to access and analyze them. That's great, as we can see real errors, triggered by our users. But if a script comes from another origin, then there's no much information about errors in it, as we've just seen.
+There are many services (and we can build our own) that listen for global errors using `window.onerror`, save errors and provide an interface to access and analyze them. That's great, as we can see real errors, triggered by our users. But if a script comes from another origin, then there's not much information about errors in it, as we've just seen.
 
 Similar cross-origin policy (CORS) is enforced for other types of resources as well.
 
@@ -169,7 +169,7 @@ There are three levels of cross-origin access:
 
 1. **No `crossorigin` attribute** -- access prohibited.
 2. **`crossorigin="anonymous"`** -- access allowed if the server responds with the header `Access-Control-Allow-Origin` with `*` or our origin. Browser does not send authorization information and cookies to remote server.
-3. **`crossorigin="use-credentials"`** -- access allowed if the server sends back the header `Access-Control-Allow-Origin` with our origin and `Access-Control-Allow-Credentials: true`.  Browser sends authorization information and cookies to remote server.
+3. **`crossorigin="use-credentials"`** -- access allowed if the server sends back the header `Access-Control-Allow-Origin` with our origin and `Access-Control-Allow-Credentials: true`. Browser sends authorization information and cookies to remote server.
 
 ```smart
 You can read more about cross-origin access in the chapter <info:fetch-crossorigin>. It describes the `fetch` method for network requests, but the policy is exactly the same.
diff --git a/2-ui/99-ui-misc/01-mutation-observer/article.md b/2-ui/99-ui-misc/01-mutation-observer/article.md
index 6a458fa02..3cf6f5397 100644
--- a/2-ui/99-ui-misc/01-mutation-observer/article.md
+++ b/2-ui/99-ui-misc/01-mutation-observer/article.md
@@ -1,7 +1,7 @@
 
 # Mutation observer
 
-`MutationObserver` is a built-in object that observes a DOM element and fires a callback in case of changes.
+`MutationObserver` is a built-in object that observes a DOM element and fires a callback when it detects a change.
 
 We'll first take a look at the syntax, and then explore a real-world use case, to see where such thing may be useful.
 
@@ -128,16 +128,16 @@ Such snippet in an HTML markup looks like this:
 ...
 ```
 
-Also we'll use a JavaScript highlighting library on our site, e.g. [Prism.js](https://prismjs.com/). A call to `Prism.highlightElem(pre)` examines the contents of such `pre` elements and adds into them special tags and styles for colored syntax highlighting, similar to what you see in examples here, at this page.
+For better readability and at the same time, to beautify it, we'll be using a JavaScript syntax highlighting library on our site, like [Prism.js](https://prismjs.com/). To get syntax highlighting for above snippet in Prism, `Prism.highlightElem(pre)` is called, which examines the contents of such `pre` elements and adds special tags and styles for colored syntax highlighting into those elements, similar to what you see in examples here, on this page.
 
-When exactly to run that highlighting method? We can do it on `DOMContentLoaded` event, or at the bottom of the page. At that moment we have our DOM ready, can search for elements `pre[class*="language"]` and call `Prism.highlightElem` on them:
+When exactly should we run that highlighting method? Well, we can do it on `DOMContentLoaded` event, or put the script at the bottom of the page. The moment our DOM is ready, we can search for elements `pre[class*="language"]` and call `Prism.highlightElem` on them:
 
 ```js
 // highlight all code snippets on the page
 document.querySelectorAll('pre[class*="language"]').forEach(Prism.highlightElem);
 ```
 
-Everything's simple so far, right? There are `<pre>` code snippets in HTML, we highlight them.
+Everything's simple so far, right? We find code snippets in HTML and highlight them.
 
 Now let's go on. Let's say we're going to dynamically fetch materials from a server. We'll study methods for that [later in the tutorial](info:fetch). For now it only matters that we fetch an HTML article from a webserver and display it on demand:
 
@@ -162,13 +162,13 @@ snippets.forEach(Prism.highlightElem);
 */!*
 ```
 
-...But imagine, we have many places in the code where we load contents: articles, quizzes, forum posts. Do we need to put the highlighting call everywhere? That's not very convenient, and also easy to forget.
+...But, imagine if we have many places in the code where we load our content - articles, quizzes, forum posts, etc. Do we need to put the highlighting call everywhere, to highlight the code in content after loading? That's not very convenient.
 
-And what if the content is loaded by a third-party module? E.g. we have a forum written by someone else, that loads contents dynamically, and we'd like to add syntax highlighting to it. No one likes to patch third-party scripts.
+And what if the content is loaded by a third-party module? For example, we have a forum written by someone else, that loads content dynamically, and we'd like to add syntax highlighting to it. No one likes patching third-party scripts.
 
 Luckily, there's another option.
 
-We can use `MutationObserver` to automatically detect when code snippets are inserted in the page and highlight them.
+We can use `MutationObserver` to automatically detect when code snippets are inserted into the page and highlight them.
 
 So we'll handle the highlighting functionality in one place, relieving us from the need to integrate it.
 
@@ -236,30 +236,37 @@ There's a method to stop observing the node:
 
 - `observer.disconnect()` -- stops the observation.
 
-When we stop the observing, it might be possible that some changes were not processed by the observer yet.
+When we stop the observing, it might be possible that some changes were not yet processed by the observer. In such cases, we use
 
-- `observer.takeRecords()` -- gets a list of unprocessed mutation records, those that happened, but the callback did not handle them.
+- `observer.takeRecords()` -- gets a list of unprocessed mutation records - those that happened, but the callback has not handled them.
 
 These methods can be used together, like this:
 
 ```js
-// we'd like to stop tracking changes
-observer.disconnect();
-
-// handle unprocessed some mutations
+// get a list of unprocessed mutations
+// should be called before disconnecting,
+// if you care about possibly unhandled recent mutations
 let mutationRecords = observer.takeRecords();
+
+// stop tracking changes
+observer.disconnect();
 ...
 ```
 
+
+```smart header="Records returned by `observer.takeRecords()` are removed from the processing queue"
+The callback won't be called for records, returned by `observer.takeRecords()`.
+```
+
 ```smart header="Garbage collection interaction"
-Observers use weak references to nodes internally. That is: if a node is removed from DOM, and becomes unreachable, then it becomes garbage collected.
+Observers use weak references to nodes internally. That is, if a node is removed from the DOM, and becomes unreachable, then it can be garbage collected.
 
 The mere fact that a DOM node is observed doesn't prevent the garbage collection.
 ```
 
 ## Summary  
 
-`MutationObserver` can react on changes in DOM: attributes, added/removed elements, text content.
+`MutationObserver` can react to changes in DOM - attributes, text content and adding/removing elements.
 
 We can use it to track changes introduced by other parts of our code, as well as to integrate with third-party scripts.
 
diff --git a/2-ui/99-ui-misc/02-selection-range/article.md b/2-ui/99-ui-misc/02-selection-range/article.md
index 862975dc1..09a20bc67 100644
--- a/2-ui/99-ui-misc/02-selection-range/article.md
+++ b/2-ui/99-ui-misc/02-selection-range/article.md
@@ -8,19 +8,17 @@ libs:
 
 In this chapter we'll cover selection in the document, as well as selection in form fields, such as `<input>`.
 
-JavaScript can do get the existing selection, select/deselect both as a whole or partially, remove the selected part from the document, wrap it into a tag, and so on.
+JavaScript can access an existing selection, select/deselect DOM nodes as a whole or partially, remove the selected content from the document, wrap it into a tag, and so on.
 
-You can get ready to use recipes at the end, in "Summary" section. But you'll get much more if you read the whole chapter. The underlying `Range` and `Selection` objects are easy to grasp, and then you'll need no recipes to make them do what you want.
+You can find some recipes for common tasks at the end of the chapter, in "Summary" section. Maybe that covers your current needs, but you'll get much more if you read the whole text.
 
-## Range
-
-The basic concept of selection is [Range](https://dom.spec.whatwg.org/#ranges): basically, a pair of "boundary points": range start and range end.
+The underlying `Range` and `Selection` objects are easy to grasp, and then you'll need no recipes to make them do what you want.
 
-Each point represented as a parent DOM node with the relative offset from its start. If the parent node is an element element node, then the offset is a child number, for a text node it's the position in the text. Examples to follow.
+## Range
 
-Let's select something.
+The basic concept of selection is [Range](https://dom.spec.whatwg.org/#ranges), that is essentially a pair of "boundary points": range start and range end.
 
-First, we can create a range (the constructor has no parameters):
+A `Range` object is created without parameters:
 
 ```js
 let range = new Range();
@@ -28,13 +26,45 @@ let range = new Range();
 
 Then we can set the selection boundaries using `range.setStart(node, offset)` and `range.setEnd(node, offset)`.
 
-For example, consider this fragment of HTML:
+As you might guess, further we'll use the `Range` objects for selection, but first let's create few such objects.
+
+### Selecting the text partially
+
+The interesting thing is that the first argument `node` in both methods can be either a text node or an element node, and the meaning of the second argument depends on that.
+
+**If `node` is a text node, then `offset` must be the position in its text.**
+
+For example, given the element `<p>Hello</p>`, we can create the range containing the letters "ll" as follows:
+
+```html run
+<p id="p">Hello</p>
+<script>
+  let range = new Range();
+  range.setStart(p.firstChild, 2);
+  range.setEnd(p.firstChild, 4);
+  
+  // toString of a range returns its content as text
+  console.log(range); // ll
+</script>
+```
+
+Here we take the first child of `<p>` (that's the text node) and specify the text positions inside it:
+
+![](range-hello-1.svg)
+
+### Selecting element nodes
+
+**Alternatively, if `node` is an element node, then `offset` must be the child number.** 
 
-```html
+That's handy for making ranges that contain nodes as a whole, not stop somewhere inside their text.
+
+For example, we have a more complex document fragment:
+
+```html autorun
 <p id="p">Example: <i>italic</i> and <b>bold</b></p>
 ```
 
-Here's its DOM structure, note that here text nodes are important for us:
+Here's its DOM structure with both element and text nodes:
 
 <div class="select-p-domtree"></div>
 
@@ -72,10 +102,21 @@ let selectPDomtree = {
 drawHtmlTree(selectPDomtree, 'div.select-p-domtree', 690, 320);
 </script>
 
-Let's select `"Example: <i>italic</i>"`. That's two first children of `<p>` (counting text nodes):
+Let's make a range for `"Example: <i>italic</i>"`.
+
+As we can see, this phrase consists of exactly two children of `<p>`, with indexes `0` and `1`:
 
 ![](range-example-p-0-1.svg)
 
+- The starting point has `<p>` as the parent `node`, and `0` as the offset.
+
+    So we can set it as `range.setStart(p, 0)`.
+- The ending point also has `<p>` as the parent `node`, but `2` as the offset (it specifies the range up to, but not including `offset`).
+
+    So we can set it as `range.setEnd(p, 2)`.
+
+Here's the demo. If you run it, you can see that the text gets selected:
+
 ```html run
 <p id="p">Example: <i>italic</i> and <b>bold</b></p>
 
@@ -87,18 +128,15 @@ Let's select `"Example: <i>italic</i>"`. That's two first children of `<p>` (cou
   range.setEnd(p, 2);
 */!*
 
-  // toString of a range returns its content as text (without tags)
-  alert(range); // Example: italic
+  // toString of a range returns its content as text, without tags
+  console.log(range); // Example: italic
 
-  // apply this range for document selection (explained later)
+  // apply this range for document selection (explained later below)
   document.getSelection().addRange(range);
 </script>
 ```
 
-- `range.setStart(p, 0)` -- sets the start at the 0th child of `<p>` (that's a text node `"Example: "`).
-- `range.setEnd(p, 2)` -- spans the range up to (but not including) 2nd child of `<p>` (that's a text node `" and "`, but as the end is not included, so the last selected node is `<i>`).
-
-Here's a more flexible test stand where you try more variants:
+Here's a more flexible test stand where you can set range start/end numbers and explore other variants:
 
 ```html run autorun
 <p id="p">Example: <i>italic</i> and <b>bold</b></p>
@@ -114,26 +152,28 @@ From <input id="start" type="number" value=1> – To <input id="end" type="numbe
     range.setEnd(p, end.value);
   */!*
 
-    // apply the selection, explained later
+    // apply the selection, explained later below
     document.getSelection().removeAllRanges();
     document.getSelection().addRange(range);
   };
 </script>
 ```
 
-E.g. selecting from `1` to `4` gives range `<i>italic</i> and <b>bold</b>`.
+E.g. selecting in the same `<p>` from offset `1` to `4` gives us the range `<i>italic</i> and <b>bold</b>`:
 
 ![](range-example-p-1-3.svg)
 
-We don't have to use the same node in `setStart` and `setEnd`. A range may span across many unrelated nodes. It's only important that the end is after the start.
+```smart header="Starting and ending nodes can be different"
+We don't have to use the same node in `setStart` and `setEnd`. A range may span across many unrelated nodes. It's only important that the end is after the start in the document.
+```
 
-### Selecting parts of text nodes
+### Selecting a bigger fragment
 
-Let's select the text partially, like this:
+Let's make a bigger selection in our example, like this:
 
 ![](range-example-p-2-b-3.svg)
 
-That's also possible, we just need to set the start and the end as a relative offset in text nodes.
+We already know how to do that. We just need to set the start and the end as a relative offset in text nodes.
 
 We need to create a range, that:
 - starts from position 2 in `<p>` first child (taking all but two first letters of "Ex<b>ample:</b> ")
@@ -148,14 +188,20 @@ We need to create a range, that:
   range.setStart(p.firstChild, 2);
   range.setEnd(p.querySelector('b').firstChild, 3);
 
-  alert(range); // ample: italic and bol
+  console.log(range); // ample: italic and bol
 
   // use this range for selection (explained later)
   window.getSelection().addRange(range);
 </script>
 ```
 
-The range object has following properties:
+As you can see, it's fairly easy to make a range of whatever we want.
+
+If we'd like to take nodes as a whole, we can pass elements in `setStart/setEnd`. Otherwise, we can work on the text level. 
+
+## Range properties
+
+The range object that we created in the example above has following properties:
 
 ![](range-example-p-2-b-3-range.svg)
 
@@ -168,9 +214,12 @@ The range object has following properties:
 - `commonAncestorContainer` -- the nearest common ancestor of all nodes within the range,
   - in the example above: `<p>`
 
-## Range methods
 
-There are many convenience methods to manipulate ranges.
+## Range selection methods
+
+There are many convenient methods to manipulate ranges.
+
+We've already seen `setStart` and `setEnd`, here are other similar methods.
 
 Set range start:
 
@@ -184,19 +233,23 @@ Set range end (similar methods):
 - `setEndBefore(node)` set end at: right before `node`
 - `setEndAfter(node)` set end at: right after `node`
 
-**As it was demonstrated, `node` can be both a text or element node: for text nodes `offset` skips that many of characters, while for element nodes that many child nodes.**
+Technically, `setStart/setEnd` can do anything, but more methods provide more convenience.
+
+In all these methods, `node` can be both a text or element node: for text nodes `offset` skips that many of characters, while for element nodes that many child nodes.
 
-Others:
+Even more methods to create ranges:
 - `selectNode(node)` set range to select the whole `node`
 - `selectNodeContents(node)` set range to select the whole `node` contents
 - `collapse(toStart)` if `toStart=true` set end=start, otherwise set start=end, thus collapsing the range
 - `cloneRange()` creates a new range with the same start/end
 
-To manipulate the content within the range:
+## Range editing methods
 
-- `deleteContents()` - remove range content from the document
-- `extractContents()` - remove range content from the document and return as [DocumentFragment](info:modifying-document#document-fragment)
-- `cloneContents()` - clone range content and return as [DocumentFragment](info:modifying-document#document-fragment)
+Once the range is created, we can manipulate its content using these methods:
+
+- `deleteContents()` -- remove range content from the document
+- `extractContents()` -- remove range content from the document and return as [DocumentFragment](info:modifying-document#document-fragment)
+- `cloneContents()` -- clone range content and return as [DocumentFragment](info:modifying-document#document-fragment)
 - `insertNode(node)` -- insert `node` into the document at the beginning of the range
 - `surroundContents(node)` -- wrap `node` around range content. For this to work, the range must contain both opening and closing tags for all elements inside it: no partial ranges like `<i>abc`.
 
@@ -204,7 +257,7 @@ With these methods we can do basically anything with selected nodes.
 
 Here's the test stand to see them in action:
 
-```html run autorun height=260
+```html run refresh autorun height=260
 Click buttons to run methods on the selection, "resetExample" to reset it.
 
 <p id="p">Example: <i>italic</i> and <b>bold</b></p>
@@ -237,7 +290,7 @@ Click buttons to run methods on the selection, "resetExample" to reset it.
       let newNode = document.createElement('u');
       try {
         range.surroundContents(newNode);
-      } catch(e) { alert(e) }
+      } catch(e) { console.log(e) }
     },
     resetExample() {
       p.innerHTML = `Example: <i>italic</i> and <b>bold</b>`;
@@ -259,16 +312,16 @@ Click buttons to run methods on the selection, "resetExample" to reset it.
 </script>
 ```
 
-There also exist methods to compare ranges, but these are rarely used. When you need them, please refer to the [spec](https://dom.spec.whatwg.org/#interface-range) or [MDN manual](https://developer.mozilla.org/en-US/docs/Web/API/Range).
+There also exist methods to compare ranges, but these are rarely used. When you need them, please refer to the [spec](https://dom.spec.whatwg.org/#interface-range) or [MDN manual](mdn:/api/Range).
 
 
 ## Selection
 
-`Range` is a generic object for managing selection ranges. We may create such objects, pass them around -- they do not visually select anything on their own.
+`Range` is a generic object for managing selection ranges. Although, creating a `Range` doesn't mean that we see a selection on screen.
 
-The document selection is represented by `Selection` object, that can be obtained as `window.getSelection()` or `document.getSelection()`.
+We may create `Range` objects, pass them around -- they do not visually select anything on their own.
 
-A selection may include zero or more ranges. At least, the [Selection API specification](https://www.w3.org/TR/selection-api/) says so. In practice though, only Firefox allows to select multiple ranges in the document by using `key:Ctrl+click` (`key:Cmd+click` for Mac).
+The document selection is represented by `Selection` object, that can be obtained as `window.getSelection()` or `document.getSelection()`. A selection may include zero or more ranges. At least, the [Selection API specification](https://www.w3.org/TR/selection-api/) says so. In practice though, only Firefox allows to select multiple ranges in the document by using `key:Ctrl+click` (`key:Cmd+click` for Mac).
 
 Here's a screenshot of a selection with 3 ranges, made in Firefox:
 
@@ -276,9 +329,19 @@ Here's a screenshot of a selection with 3 ranges, made in Firefox:
 
 Other browsers support at maximum 1 range. As we'll see, some of `Selection` methods imply that there may be many ranges, but again, in all browsers except Firefox, there's at maximum 1.
 
+Here's a small demo that shows the current selection (select something and click) as text:
+
+<button onclick="alert(document.getSelection())">alert(document.getSelection())</button>
+
 ## Selection properties
 
-Similar to a range, a selection has a start, called "anchor", and the end, called "focus".
+As said, a selection may in theory contain multiple ranges. We can get these range objects using the method:
+
+- `getRangeAt(i)` -- get i-th range, starting from `0`. In all browsers except Firefox, only `0` is used.
+
+Also, there exist properties that often provide better convenience.
+
+Similar to a range, a selection object has a start, called "anchor", and the end, called "focus".
 
 The main selection properties are:
 
@@ -289,37 +352,39 @@ The main selection properties are:
 - `isCollapsed` -- `true` if selection selects nothing (empty range), or doesn't exist.
 - `rangeCount` -- count of ranges in the selection, maximum `1` in all browsers except Firefox.
 
-````smart header="Selection end may be in the document before start"
-There are many ways to select the content, depending on the user agent: mouse, hotkeys, taps on a mobile etc.
+```smart header="Selection end/start vs Range"
+
+There's an important difference between a selection anchor/focus compared with a `Range` start/end.
+
+As we know, `Range` objects always have their start before the end. 
+
+For selections, that's not always the case.
 
-Some of them, such as a mouse, allow the same selection can be created in two directions: "left-to-right" and "right-to-left".
+Selecting something with a mouse can be done in both directions: either "left-to-right" or "right-to-left".
 
-If the start (anchor) of the selection goes in the document before the end (focus), this selection is said to have "forward" direction.
+In other words, when the mouse button is pressed, and then it moves forward in the document, then its end (focus) will be after its start (anchor).
 
 E.g. if the user starts selecting with mouse and goes from "Example" to "italic":
 
 ![](selection-direction-forward.svg)
 
-Otherwise, if they go from the end of "italic" to "Example", the selection is directed "backward", its focus will be before the anchor:
+...But the same selection could be done backwards: starting from  "italic" to "Example" (backward direction), then its end (focus) will be before the start (anchor):
 
 ![](selection-direction-backward.svg)
-
-That's different from `Range` objects that are always directed forward: the range start can't be after its end.
-````
+```
 
 ## Selection events
 
 There are events on to keep track of selection:
 
-- `elem.onselectstart` -- when a selection starts on `elem`, e.g. the user starts moving mouse with pressed button.
-    - Preventing the default action makes the selection not start.
-- `document.onselectionchange` -- whenever a selection changes.
-    - Please note: this handler can be set only on `document`.
+- `elem.onselectstart` -- when a selection *starts* specifically on element `elem` (or inside it). For instance, when the user presses the mouse button on it and starts to move the pointer.
+    - Preventing the default action cancels the selection start. So starting a selection from this element becomes impossible, but the element is still selectable. The visitor just needs to start the selection from elsewhere.
+- `document.onselectionchange` -- whenever a selection changes or starts.
+    - Please note: this handler can be set only on `document`, it tracks all selections in it.
 
 ### Selection tracking demo
 
-Here's a small demo that shows selection boundaries
-dynamically as it changes:
+Here's a small demo. It tracks the current selection on the `document` and shows its boundaries:
 
 ```html run height=80
 <p id="p">Select me: <i>italic</i> and <b>bold</b></p>
@@ -327,21 +392,25 @@ dynamically as it changes:
 From <input id="from" disabled> – To <input id="to" disabled>
 <script>
   document.onselectionchange = function() {
-    let {anchorNode, anchorOffset, focusNode, focusOffset} = document.getSelection();
+    let selection = document.getSelection();
 
-    from.value = `${anchorNode && anchorNode.data}:${anchorOffset}`;
-    to.value = `${focusNode && focusNode.data}:${focusOffset}`;
+    let {anchorNode, anchorOffset, focusNode, focusOffset} = selection;
+
+    // anchorNode and focusNode are text nodes usually
+    from.value = `${anchorNode?.data}, offset ${anchorOffset}`;
+    to.value = `${focusNode?.data}, offset ${focusOffset}`;
   };
 </script>
 ```
 
-### Selection getting demo
+### Selection copying demo
+
+There are two approaches to copying the selected content:
 
-To get the whole selection:
-- As text: just call `document.getSelection().toString()`.
-- As DOM nodes: get the underlying ranges and call their `cloneContents()` method (only first range if we don't support Firefox multiselection).
+1. We can use `document.getSelection().toString()` to get it as text.
+2. Otherwise, to copy the full DOM, e.g. if we need to keep formatting, we can get the underlying ranges with `getRangeAt(...)`. A `Range` object, in turn, has `cloneContents()` method that clones its content and returns as `DocumentFragment` object, that we can insert elsewhere.
 
-And here's the demo of getting the selection both as text and as DOM nodes:
+Here's the demo of copying the selected content both as text and as DOM nodes:
 
 ```html run height=100
 <p id="p">Select me: <i>italic</i> and <b>bold</b></p>
@@ -369,15 +438,15 @@ As text: <span id="astext"></span>
 
 ## Selection methods
 
-Selection methods to add/remove ranges:
+We can work with the selection by adding/removing ranges:
 
-- `getRangeAt(i)` -- get i-th range, starting from `0`. In all browsers except firefox, only `0` is used.
+- `getRangeAt(i)` -- get i-th range, starting from `0`. In all browsers except Firefox, only `0` is used.
 - `addRange(range)` -- add `range` to selection. All browsers except Firefox ignore the call, if the selection already has an associated range.
 - `removeRange(range)` -- remove `range` from the selection.
 - `removeAllRanges()` -- remove all ranges.
 - `empty()` -- alias to `removeAllRanges`.
 
-Also, there are convenience methods to manipulate the selection range directly, without `Range`:
+There are also convenience methods to manipulate the selection range directly, without intermediate `Range` calls:
 
 - `collapse(node, offset)` -- replace selected range with a new one that starts and ends at the given `node`, at position `offset`.
 - `setPosition(node, offset)` -- alias to `collapse`.
@@ -387,9 +456,9 @@ Also, there are convenience methods to manipulate the selection range directly,
 - `setBaseAndExtent(anchorNode, anchorOffset, focusNode, focusOffset)` - replace selection range with the given start `anchorNode/anchorOffset` and end `focusNode/focusOffset`. All content in-between them is selected.
 - `selectAllChildren(node)` -- select all children of the `node`.
 - `deleteFromDocument()` -- remove selected content from the document.
-- `containsNode(node, allowPartialContainment = false)` -- checks whether the selection contains `node` (partically if the second argument is `true`)
+- `containsNode(node, allowPartialContainment = false)` -- checks whether the selection contains `node` (partially if the second argument is `true`)
 
-So, for many tasks we can call `Selection` methods, no need to access the underlying `Range` object.
+For most tasks these methods are just fine, there's no need to access the underlying `Range` object.
 
 For example, selecting the whole contents of the paragraph `<p>`:
 
@@ -416,10 +485,10 @@ The same thing using ranges:
 </script>
 ```
 
-```smart header="To select, remove the existing selection first"
-If the selection already exists, empty it first with `removeAllRanges()`. And then add ranges. Otherwise, all browsers except Firefox ignore new ranges.
+```smart header="To select something, remove the existing selection first"
+If a document selection already exists, empty it first with `removeAllRanges()`. And then add ranges. Otherwise, all browsers except Firefox ignore new ranges.
 
-The exception is some selection methods, that replace the existing selection, like `setBaseAndExtent`.
+The exception is some selection methods, that replace the existing selection, such as `setBaseAndExtent`.
 ```
 
 ## Selection in form controls
@@ -495,7 +564,7 @@ Focus on me, the cursor will be at position 10.
     // zero delay setTimeout to run after browser "focus" action finishes
     setTimeout(() => {
       // we can set any selection
-      // if start=end, the cursor it exactly at that place
+      // if start=end, the cursor is exactly at that place
       area.selectionStart = area.selectionEnd = 10;
     });
   };
@@ -551,7 +620,7 @@ If nothing is selected, or we use equal `start` and `end` in `setRangeText`, the
 
 We can also insert something "at the cursor" using `setRangeText`.
 
-Here's an button that inserts `"HELLO"` at the cursor position and puts the cursor immediately after it. If the selection is not empty, then it gets replaced (we can do detect in by comparing `selectionStart!=selectionEnd` and do something else instead):
+Here's a button that inserts `"HELLO"` at the cursor position and puts the cursor immediately after it. If the selection is not empty, then it gets replaced (we can detect it by comparing `selectionStart!=selectionEnd` and do something else instead):
 
 ```html run autorun
 <input id="input" style="width:200px" value="Text Text Text Text Text">
@@ -583,7 +652,7 @@ To make something unselectable, there are three ways:
 
     This doesn't allow the selection to start at `elem`. But the user may start the selection elsewhere and include `elem` into it.
 
-    Then `elem` will become a part of `document.getSelection()`, so the selection actully happens, but its content is usually ignored in copy-paste.
+    Then `elem` will become a part of `document.getSelection()`, so the selection actually happens, but its content is usually ignored in copy-paste.
 
 
 2. Prevent default action in `onselectstart` or `mousedown` events.
@@ -621,7 +690,7 @@ The second API is very simple, as it works with text.
 The most used recipes are probably:
 
 1. Getting the selection:
-    ```js run
+    ```js
     let selection = document.getSelection();
 
     let cloned = /* element to clone the selected nodes to */;
@@ -632,8 +701,8 @@ The most used recipes are probably:
       cloned.append(selection.getRangeAt(i).cloneContents());
     }
     ```
-2. Setting the selection
-    ```js run
+2. Setting the selection:
+    ```js
     let selection = document.getSelection();
 
     // directly:
diff --git a/2-ui/99-ui-misc/02-selection-range/range-hello-1.svg b/2-ui/99-ui-misc/02-selection-range/range-hello-1.svg
new file mode 100644
index 000000000..2951607a2
--- /dev/null
+++ b/2-ui/99-ui-misc/02-selection-range/range-hello-1.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="147" height="80" viewBox="0 0 147 80"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:&apos;PT Mono&apos;;font-weight:700;font-style:normal;src:local(&apos;PT MonoBold&apos;),url(/font/PTMonoBold.woff2) format(&apos;woff2&apos;),url(/font/PTMonoBold.woff) format(&apos;woff&apos;),url(/font/PTMonoBold.ttf) format(&apos;truetype&apos;)}</style></defs><defs><path id="path-1" d="M63 17h25v21H63z"/><mask id="mask-2" width="25" height="21" x="0" y="0" fill="#fff" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox"><use xlink:href="#path-1"/></mask></defs><g id="selection-range" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="range-hello-1.svg"><use id="Rectangle" fill="#C9DCEA" stroke="#C9DCEA" stroke-dasharray="5,2" stroke-width="2" mask="url(#mask-2)" xlink:href="#path-1"/><text id="&lt;p&gt;Hello&lt;/p&gt;" fill="#AF6E24" font-family="PTMono-Regular, PT Mono" font-size="18" font-weight="normal" letter-spacing="1"><tspan x="5" y="33">&lt;p&gt;Hello&lt;/p&gt;</tspan></text><path id="Path-Copy" stroke="#C06334" stroke-width="2" d="M41 38v11h58.887V37"/><text id="p.firstChild" fill="#181717" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="25" y="69">p.firstChild</tspan></text></g></g></svg>
\ No newline at end of file
diff --git a/2-ui/99-ui-misc/03-event-loop/2-micro-macro-queue/solution.md b/2-ui/99-ui-misc/03-event-loop/2-micro-macro-queue/solution.md
new file mode 100644
index 000000000..2911b76cf
--- /dev/null
+++ b/2-ui/99-ui-misc/03-event-loop/2-micro-macro-queue/solution.md
@@ -0,0 +1,50 @@
+The console output is: 1 7 3 5 2 6 4.
+
+The task is quite simple, we just need to know how microtask and macrotask queues work.
+
+Let's see what's going on, step by step.
+
+```js
+console.log(1);
+// The first line executes immediately, it outputs `1`.
+// Macrotask and microtask queues are empty, as of now.
+
+setTimeout(() => console.log(2));
+// `setTimeout` appends the callback to the macrotask queue.
+// - macrotask queue content:
+//   `console.log(2)`
+
+Promise.resolve().then(() => console.log(3));
+// The callback is appended to the microtask queue.
+// - microtask queue content:
+//   `console.log(3)`
+
+Promise.resolve().then(() => setTimeout(() => console.log(4)));
+// The callback with `setTimeout(...4)` is appended to microtasks
+// - microtask queue content:
+//   `console.log(3); setTimeout(...4)`
+
+Promise.resolve().then(() => console.log(5));
+// The callback is appended to the microtask queue
+// - microtask queue content:
+//   `console.log(3); setTimeout(...4); console.log(5)`
+
+setTimeout(() => console.log(6));
+// `setTimeout` appends the callback to macrotasks
+// - macrotask queue content:
+//   `console.log(2); console.log(6)`
+
+console.log(7);
+// Outputs 7 immediately.
+```
+
+To summarize,
+
+1. Numbers `1` and `7` show up immediately, because simple `console.log` calls don't use any queues.
+2. Then, after the main code flow is finished, the microtask queue runs.
+    - It has commands: `console.log(3); setTimeout(...4); console.log(5)`.
+    - Numbers `3` and `5` show up, while `setTimeout(() => console.log(4))` adds the `console.log(4)` call to the end of the macrotask queue.
+    - The macrotask queue is now: `console.log(2); console.log(6); console.log(4)`.
+3. After the microtask queue becomes empty, the macrotask queue executes. It outputs `2`, `6`, `4`.
+
+Finally, we have the output: `1 7 3 5 2 6 4`.
\ No newline at end of file
diff --git a/2-ui/99-ui-misc/03-event-loop/2-micro-macro-queue/task.md b/2-ui/99-ui-misc/03-event-loop/2-micro-macro-queue/task.md
new file mode 100644
index 000000000..ad406b3be
--- /dev/null
+++ b/2-ui/99-ui-misc/03-event-loop/2-micro-macro-queue/task.md
@@ -0,0 +1,21 @@
+importance: 5
+
+---
+
+# What will be the output of this code?
+
+```js
+console.log(1);
+
+setTimeout(() => console.log(2));
+
+Promise.resolve().then(() => console.log(3));
+
+Promise.resolve().then(() => setTimeout(() => console.log(4)));
+
+Promise.resolve().then(() => console.log(5));
+
+setTimeout(() => console.log(6));
+
+console.log(7);
+```
diff --git a/2-ui/99-ui-misc/03-event-loop/article.md b/2-ui/99-ui-misc/03-event-loop/article.md
index 218dd2140..f33188491 100644
--- a/2-ui/99-ui-misc/03-event-loop/article.md
+++ b/2-ui/99-ui-misc/03-event-loop/article.md
@@ -9,7 +9,7 @@ In this chapter we first cover theoretical details about how things work, and th
 
 ## Event Loop
 
-The concept of *event loop* is very simple. There's an endless loop, when JavaScript engine waits for tasks, executes them and then sleeps waiting for more tasks.
+The *event loop* concept is very simple. There's an endless loop, where the JavaScript engine waits for tasks, executes them and then sleeps, waiting for more tasks.
 
 The general algorithm of the engine:
 
@@ -17,7 +17,7 @@ The general algorithm of the engine:
     - execute them, starting with the oldest task.
 2. Sleep until a task appears, then go to 1.
 
-That's a formalization for what we see when browsing a page. JavaScript engine does nothing most of the time, only runs if a script/handler/event activates.
+That's a formalization of what we see when browsing a page. The JavaScript engine does nothing most of the time, it only runs if a script/handler/event activates.
 
 Examples of tasks:
 
@@ -30,33 +30,33 @@ Tasks are set -- the engine handles them -- then waits for more tasks (while sle
 
 It may happen that a task comes while the engine is busy, then it's enqueued.
 
-The tasks form a queue, so-called "macrotask queue" (v8 term):
+The tasks form a queue, the so-called "macrotask queue" ([v8](https://v8.dev/) term):
 
 ![](eventLoop.svg)
 
-For instance, while the engine is busy executing a `script`, a user may move their mouse causing `mousemove`, and `setTimeout` may be due and so on, these tasks form a queue, as illustrated on the picture above.
+For instance, while the engine is busy executing a `script`, a user may move their mouse causing `mousemove`, and `setTimeout` may be due and so on, these tasks form a queue, as illustrated in the picture above.
 
-Tasks from the queue are processed on "first come – first served" basis. When the engine browser is done with the `script`, it handles `mousemove` event, then `setTimeout` handler, and so on.
+Tasks from the queue are processed on a "first come – first served" basis. When the engine browser is done with the `script`, it handles `mousemove` event, then `setTimeout` handler, and so on.
 
 So far, quite simple, right?
 
 Two more details:
-1. Rendering never happens while the engine executes a task. Doesn't matter if the task takes a long time. Changes to DOM are painted only after the task is complete.
-2. If a task takes too long, the browser can't do other tasks, process user events, so after a time it raises an alert like "Page Unresponsive" suggesting to kill the task with the whole page. That happens when there are a lot of complex calculations or a programming error leading to infinite loop.
+1. Rendering never happens while the engine executes a task. It doesn't matter if the task takes a long time. Changes to the DOM are painted only after the task is complete.
+2. If a task takes too long, the browser can't do other tasks, such as processing user events. So after some time, it raises an alert like "Page Unresponsive", suggesting killing the task with the whole page. That happens when there are a lot of complex calculations or a programming error leading to an infinite loop.
 
-That was a theory. Now let's see how we can apply that knowledge.
+That was the theory. Now let's see how we can apply that knowledge.
 
 ## Use-case 1: splitting CPU-hungry tasks
 
 Let's say we have a CPU-hungry task.
 
-For example, syntax-highlighting (used to colorize code examples on this page) is quite CPU-heavy. To highlight the code, it performs the analysis, creates many colored elements, adds them to the document -- for a big text that takes a lot of time.
+For example, syntax-highlighting (used to colorize code examples on this page) is quite CPU-heavy. To highlight the code, it performs the analysis, creates many colored elements, adds them to the document -- for a large amount of text that takes a lot of time.
 
 While the engine is busy with syntax highlighting, it can't do other DOM-related stuff, process user events, etc. It may even cause the browser to "hiccup" or even "hang" for a bit, which is unacceptable.
 
-We can evade problems by splitting the big task into pieces. Highlight first 100 lines, then schedule `setTimeout` (with zero-delay) another 100 lines, and so on.
+We can avoid problems by splitting the big task into pieces. Highlight the first 100 lines, then schedule `setTimeout` (with zero-delay) for the next 100 lines, and so on.
 
-To demonstrate the approach, for the sake of simplicity, instead of syntax-highlighting let's take a function that counts from `1` to `1000000000`.
+To demonstrate this approach, for the sake of simplicity, instead of text-highlighting, let's take a function that counts from `1` to `1000000000`.
 
 If you run the code below, the engine will "hang" for some time. For server-side JS that's clearly noticeable, and if you are running it in-browser, then try to click other buttons on the page -- you'll see that no other events get handled until the counting finishes.
 
@@ -78,9 +78,9 @@ function count() {
 count();
 ```
 
-The browser may even show "the script takes too long" warning.
+The browser may even show a "the script takes too long" warning.
 
-Let's split the job using nested `setTimeout`:
+Let's split the job using nested `setTimeout` calls:
 
 ```js run
 let i = 0;
@@ -113,13 +113,13 @@ A single run of `count` does a part of the job `(*)`, and then re-schedules itse
 2. Second run counts: `i=1000001..2000000`.
 3. ...and so on.
 
-Now, if a new side task (e.g. `onclick` event) appears while the engine is busy executing part 1, it gets queued and then executes when part 1 finished, before the next part. Periodic returns to event loop between `count` executions provide just enough "air" for the JavaScript engine to do something else, to react on other user actions.
+Now, if a new side task (e.g. `onclick` event) appears while the engine is busy executing part 1, it gets queued and then executes when part 1 finished, before the next part. Periodic returns to the event loop between `count` executions provide just enough "air" for the JavaScript engine to do something else, to react to other user actions.
 
-The notable thing is that both variants -- with and without splitting the job by `setTimeout` -- are comparable in speed. There's no much difference in the overall counting time.
+The notable thing is that both variants -- with and without splitting the job by `setTimeout` -- are comparable in speed. There's not much difference in the overall counting time.
 
 To make them closer, let's make an improvement.
 
-We'll move the scheduling in the beginning of the `count()`:
+We'll move the scheduling to the beginning of the `count()`:
 
 ```js run
 let i = 0;
@@ -128,7 +128,7 @@ let start = Date.now();
 
 function count() {
 
-  // move the scheduling at the beginning
+  // move the scheduling to the beginning
   if (i < 1e9 - 1e6) {
     setTimeout(count); // schedule the new call
   }
@@ -160,9 +160,9 @@ Finally, we've split a CPU-hungry task into parts - now it doesn't block the use
 
 Another benefit of splitting heavy tasks for browser scripts is that we can show progress indication.
 
-Usually the browser renders after the currently running code is complete. Doesn't matter if the task takes a long time. Changes to DOM are painted only after the task is finished.
+As mentioned earlier, changes to DOM are painted only after the currently running task is completed, irrespective of how long it takes.
 
-From one hand, that's great, because our function may create many elements, add them one-by-one to the document and change their styles -- the visitor won't see any "intermediate", unfinished state. An important thing, right?
+On one hand, that's great, because our function may create many elements, add them one-by-one to the document and change their styles -- the visitor won't see any "intermediate", unfinished state. An important thing, right?
 
 Here's the demo, the changes to `i` won't show up until the function finishes, so we'll see only the last value:
 
@@ -238,7 +238,7 @@ menu.onclick = function() {
 
 ## Macrotasks and Microtasks
 
-Along with *macrotasks*, described in this chapter, there exist *microtasks*, mentioned in the chapter <info:microtask-queue>.
+Along with *macrotasks*, described in this chapter, there are *microtasks*, mentioned in the chapter <info:microtask-queue>.
 
 Microtasks come solely from our code. They are usually created by promises: an execution of `.then/catch/finally` handler becomes a microtask. Microtasks are used "under the cover" of `await` as well, as it's another form of promise handling.
 
@@ -263,11 +263,11 @@ What's going to be the order here?
 2. `promise` shows second, because `.then` passes through the microtask queue, and runs after the current code.
 3. `timeout` shows last, because it's a macrotask.
 
-The richer event loop picture looks like this:
+The richer event loop picture looks like this (order is from top to bottom, that is: the script first, then microtasks, rendering and so on):
 
 ![](eventLoop-full.svg)
 
-**All microtasks are completed before any other event handling or rendering or any other macrotask takes place.**
+All microtasks are completed before any other event handling or rendering or any other macrotask takes place.
 
 That's important, as it guarantees that the application environment is basically the same (no mouse coordinate changes, no new network data, etc) between microtasks.
 
@@ -303,7 +303,7 @@ Here's an example with "counting progress bar", similar to the one shown previou
 
 ## Summary
 
-The more detailed algorithm of the event loop (though still simplified compare to the [specification](https://html.spec.whatwg.org/multipage/webappapis.html#event-loop-processing-model)):
+A more detailed event loop algorithm (though still simplified compared to the [specification](https://html.spec.whatwg.org/multipage/webappapis.html#event-loop-processing-model)):
 
 1. Dequeue and run the oldest task from the *macrotask* queue (e.g. "script").
 2. Execute all *microtasks*:
@@ -316,7 +316,7 @@ The more detailed algorithm of the event loop (though still simplified compare t
 To schedule a new *macrotask*:
 - Use zero delayed `setTimeout(f)`.
 
-That may be used to split a big calculation-heavy task into pieces, for the browser to be able to react on user events and show progress between them.
+That may be used to split a big calculation-heavy task into pieces, for the browser to be able to react to user events and show progress between them.
 
 Also, used in event handlers to schedule an action after the event is fully handled (bubbling done).
 
diff --git a/3-frames-and-windows/01-popup-windows/article.md b/3-frames-and-windows/01-popup-windows/article.md
index 3be07258e..f2c87d1e0 100644
--- a/3-frames-and-windows/01-popup-windows/article.md
+++ b/3-frames-and-windows/01-popup-windows/article.md
@@ -7,7 +7,7 @@ Basically, you just run:
 window.open('https://javascript.info/')
 ```
 
-...And it will open a new window with given URL. Most modern browsers are configured to open new tabs instead of separate windows.
+...And it will open a new window with given URL. Most modern browsers are configured to open url in new tabs instead of separate windows.
 
 Popups exist from really ancient times. The initial idea was to show another content without closing the main window. As of now, there are other ways to do that: we can load content dynamically with [fetch](info:fetch) and show it in a dynamically generated `<div>`. So, popups is not something we use everyday.
 
@@ -15,7 +15,7 @@ Also, popups are tricky on mobile devices, that don't show multiple windows simu
 
 Still, there are tasks where popups are still used, e.g. for OAuth authorization (login with Google/Facebook/...), because:
 
-1. A popup is a separate window with its own independent JavaScript environment. So opening a popup with a third-party non-trusted site is safe.
+1. A popup is a separate window which has its own independent JavaScript environment. So opening a popup from a third-party, non-trusted site is safe.
 2. It's very easy to open a popup.
 3. A popup can navigate (change URL) and send messages to the opener window.
 
@@ -38,26 +38,6 @@ button.onclick = () => {
 
 This way users are somewhat protected from unwanted popups, but the functionality is not disabled totally.
 
-What if the popup opens from `onclick`, but after `setTimeout`? That's a bit tricky.
-
-Try this code:
-
-```js run
-// open after 3 seconds
-setTimeout(() => window.open('http://google.com'), 3000);
-```
-
-The popup opens in Chrome, but gets blocked in Firefox.
-
-...If we decrease the delay, the popup works in Firefox too:
-
-```js run
-// open after 1 seconds
-setTimeout(() => window.open('http://google.com'), 1000);
-```
-
-The difference is that Firefox treats a timeout of 2000ms or less are acceptable, but after it -- removes the "trust", assuming that now it's "outside of the user action". So the first one is blocked, and the second one is not.
-
 ## window.open
 
 The syntax to open a popup is: `window.open(url, name, params)`:
@@ -69,7 +49,7 @@ name
 : A name of the new window. Each window has a `window.name`, and here we can specify which window to use for the popup. If there's already a window with such name -- the given URL opens in it, otherwise a new window is opened.
 
 params
-: The configuration string for the new window. It contains settings, delimited by a comma. There must be no spaces in params, for instance: `width:200,height=100`.
+: The configuration string for the new window. It contains settings, delimited by a comma. There must be no spaces in params, for instance: `width=200,height=100`.
 
 Settings for `params`:
 
@@ -87,9 +67,9 @@ Settings for `params`:
 
 There is also a number of less supported browser-specific features, which are usually not used. Check <a href="https://developer.mozilla.org/en/DOM/window.open">window.open in MDN</a> for examples.
 
-## Example: a minimalistic window   
+## Example: a minimalistic window
 
-Let's open a window with minimal set of features just to see which of them browser allows to disable:
+Let's open a window with minimal set of features, just to see which of them browser allows to disable:
 
 ```js run
 let params = `scrollbars=no,resizable=no,status=no,location=no,toolbar=no,menubar=no,
@@ -120,7 +100,7 @@ Rules for omitted settings:
 
 ## Accessing popup from window
 
-The `open` call returns a reference to the new window. It can be used to manipulate it's properties, change location and even more.
+The `open` call returns a reference to the new window. It can be used to manipulate its properties, change location and even more.
 
 In this example, we generate popup content from JavaScript:
 
@@ -154,7 +134,7 @@ Windows may freely access content of each other only if they come from the same
 Otherwise, e.g. if the main window is from `site.com`, and the popup from `gmail.com`, that's impossible for user safety reasons. For the details, see chapter <info:cross-window-communication>.
 ```
 
-## Accessing window from popup   
+## Accessing window from popup
 
 A popup may access the "opener" window as well using `window.opener` reference. It is `null` for all windows except popups.
 
@@ -192,7 +172,7 @@ newWindow.onload = function() {
 ```
 
 
-## Scrolling and resizing
+## Moving and resizing
 
 There are methods to move/resize a window:
 
@@ -237,28 +217,30 @@ There's also `window.onscroll` event.
 
 ## Focus/blur on a window
 
-Theoretically, there are `window.focus()` and `window.blur()` methods to focus/unfocus on a window.  Also there are `focus/blur` events that allow to focus a window and catch the moment when the visitor switches elsewhere.
+Theoretically, there are `window.focus()` and `window.blur()` methods to focus/unfocus on a window. And there are also `focus/blur` events that allow to catch the moment when the visitor focuses on a window and switches elsewhere.
+
+Although, in practice they are severely limited, because in the past evil pages abused them.
 
-In the past evil pages abused those. For instance, look at this code:
+For instance, look at this code:
 
 ```js run
 window.onblur = () => window.focus();
 ```
 
-When a user attempts to switch out of the window (`blur`), it brings it back to focus. The intention is to "lock" the user within the `window`.
+When a user attempts to switch out of the window (`window.onblur`), it brings the window back into focus. The intention is to "lock" the user within the `window`.
 
-So, there are limitations that forbid the code like that. There are many limitations to protect the user from ads and evils pages. They depend on the browser.
+So browsers had to introduce many limitations to forbid the code like that and protect the user from ads and evils pages. They depend on the browser.
 
-For instance, a mobile browser usually ignores that call completely. Also focusing doesn't work when a popup opens in a separate tab rather than a new window.
+For instance, a mobile browser usually ignores `window.focus()` completely. Also focusing doesn't work when a popup opens in a separate tab rather than a new window.
 
-Still, there are some things that can be done.
+Still, there are some use cases when such calls do work and can be useful.
 
 For instance:
 
-- When we open a popup, it's might be a good idea to run a `newWindow.focus()` on it. Just in case, for some OS/browser combinations it ensures that the user is in the new window now.
+- When we open a popup, it might be a good idea to run `newWindow.focus()` on it. Just in case, for some OS/browser combinations it ensures that the user is in the new window now.
 - If we want to track when a visitor actually uses our web-app, we can track `window.onfocus/onblur`. That allows us to suspend/resume in-page activities, animations etc. But please note that the `blur` event means that the visitor switched out from the window, but they still may observe it. The window is in the background, but still may be visible.
 
-## Summary   
+## Summary
 
 Popup windows are used rarely, as there are alternatives: loading and displaying information in-page, or in iframe.
 
@@ -268,7 +250,7 @@ If we're going to open a popup, a good practice is to inform the user about it.
 - Browsers block `open` calls from the code outside of user actions. Usually a notification appears, so that a user may allow them.
 - Browsers open a new tab by default, but if sizes are provided, then it'll be a popup window.
 - The popup may access the opener window using the `window.opener` property.
-- The main window and the popup can freely read and modify each other if they havee the same origin. Otherwise, they can change location of each other and [exchange messages.
+- The main window and the popup can freely read and modify each other if they have the same origin. Otherwise, they can change location of each other and [exchange messages](info:cross-window-communication).
 
 To close the popup: use `close()` call. Also the user may close them (just like any other windows). The `window.closed` is `true` after that.
 
diff --git a/3-frames-and-windows/03-cross-window-communication/article.md b/3-frames-and-windows/03-cross-window-communication/article.md
index 53f5f55fc..4d4e320e4 100644
--- a/3-frames-and-windows/03-cross-window-communication/article.md
+++ b/3-frames-and-windows/03-cross-window-communication/article.md
@@ -116,6 +116,13 @@ document.domain = 'site.com';
 
 That's all. Now they can interact without limitations. Again, that's only possible for pages with the same second-level domain.
 
+```warn header="Deprecated, but still working"
+The `document.domain` property is in the process of being removed from the [specification](https://html.spec.whatwg.org/multipage/origin.html#relaxing-the-same-origin-restriction). The cross-window messaging (explained soon below) is the suggested replacement.
+
+That said, as of now all browsers support it. And the support will be kept for the future, not to break old code that relies on `document.domain`.
+```
+
+
 ## Iframe: wrong document pitfall
 
 When an iframe comes from the same origin, and we may access its  `document`, there's a pitfall. It's not related to cross-origin things, but important to know.
@@ -263,12 +270,12 @@ The window that wants to send a message calls [postMessage](mdn:api/Window.postM
 Arguments:
 
 `data`
-: The data to send. Can be any object, the data is cloned using the "structured cloning algorithm". IE supports only strings, so we should `JSON.stringify` complex objects to support that browser.
+: The data to send. Can be any object, the data is cloned using the "structured serialization algorithm". IE supports only strings, so we should `JSON.stringify` complex objects to support that browser.
 
 `targetOrigin`
 : Specifies the origin for the target window, so that only a window from the given origin will get the message.
 
-The `targetOrigin` is a safety measure. Remember, if the target window comes from another origin, we can't read it's `location` in the sender window. So we can't be sure which site is open in the intended window right now: the user could navigate away, and the sender window has no idea about it.
+The `targetOrigin` is a safety measure. Remember, if the target window comes from another origin, we can't read its `location` in the sender window. So we can't be sure which site is open in the intended window right now: the user could navigate away, and the sender window has no idea about it.
 
 Specifying `targetOrigin` ensures that the window only receives the data if it's still at the right site. Important when the data is sensitive.
 
diff --git a/3-frames-and-windows/03-cross-window-communication/sandbox.view/index.html b/3-frames-and-windows/03-cross-window-communication/sandbox.view/index.html
index 478830610..46dd7b5cc 100644
--- a/3-frames-and-windows/03-cross-window-communication/sandbox.view/index.html
+++ b/3-frames-and-windows/03-cross-window-communication/sandbox.view/index.html
@@ -7,7 +7,7 @@
 
 <body>
 
-  <div>The iframe below is has <code>sandbox</code> attribute.</div>
+  <div>The iframe below has the <code>sandbox</code> attribute.</div>
 
   <iframe sandbox src="sandboxed.html" style="height:60px;width:90%"></iframe>
 
diff --git a/3-frames-and-windows/06-clickjacking/article.md b/3-frames-and-windows/06-clickjacking/article.md
index 1daa87dd0..34d0a91ae 100644
--- a/3-frames-and-windows/06-clickjacking/article.md
+++ b/3-frames-and-windows/06-clickjacking/article.md
@@ -154,7 +154,7 @@ Depending on your browser, the `iframe` above is either empty or alerting you th
 
 ## Showing with disabled functionality
 
-The `X-Frame-Options` header has a side-effect. Other sites won't be able to show our page in a frame, even if they have good reasons to do so.
+The `X-Frame-Options` header has a side effect. Other sites won't be able to show our page in a frame, even if they have good reasons to do so.
 
 So there are other solutions... For instance, we can "cover" the page with a `<div>` with styles `height: 100%; width: 100%;`, so that it will intercept all clicks. That `<div>` is to be removed if `window == top` or if we figure out that we don't need the protection.
 
diff --git a/4-binary/01-arraybuffer-binary-arrays/01-concat/_js.view/solution.js b/4-binary/01-arraybuffer-binary-arrays/01-concat/_js.view/solution.js
index 2f51384ef..00c37bb94 100644
--- a/4-binary/01-arraybuffer-binary-arrays/01-concat/_js.view/solution.js
+++ b/4-binary/01-arraybuffer-binary-arrays/01-concat/_js.view/solution.js
@@ -2,9 +2,9 @@ function concat(arrays) {
   // sum of individual array lengths
   let totalLength = arrays.reduce((acc, value) => acc + value.length, 0);
 
-  if (!arrays.length) return null;
-
   let result = new Uint8Array(totalLength);
+  
+  if (!arrays.length) return result;
 
   // for each array - copy it over result
   // next array is copied right after the previous one
diff --git a/4-binary/01-arraybuffer-binary-arrays/article.md b/4-binary/01-arraybuffer-binary-arrays/article.md
index b1d0bbb0d..2827e277e 100644
--- a/4-binary/01-arraybuffer-binary-arrays/article.md
+++ b/4-binary/01-arraybuffer-binary-arrays/article.md
@@ -30,11 +30,11 @@ Let's eliminate a possible source of confusion. `ArrayBuffer` has nothing in com
 
 **To manipulate an `ArrayBuffer`, we need to use a "view" object.**
 
-A view object does not store anything on it's own. It's the "eyeglasses" that give an interpretation of the bytes stored in the `ArrayBuffer`.
+A view object does not store anything on its own. It's the "eyeglasses" that give an interpretation of the bytes stored in the `ArrayBuffer`.
 
 For instance:
 
-- **`Uint8Array`** -- treats each byte in `ArrayBuffer` as a separate number, with possible values are from 0 to 255 (a byte is 8-bit, so it can hold only that much). Such value is called a "8-bit unsigned integer".
+- **`Uint8Array`** -- treats each byte in `ArrayBuffer` as a separate number, with possible values from 0 to 255 (a byte is 8-bit, so it can hold only that much). Such value is called a "8-bit unsigned integer".
 - **`Uint16Array`** -- treats every 2 bytes as an integer, with possible values from 0 to 65535. That's called a "16-bit unsigned integer".
 - **`Uint32Array`** -- treats every 4 bytes as an integer, with possible values from 0 to 4294967295. That's called a "32-bit unsigned integer".
 - **`Float64Array`** -- treats every 8 bytes as a floating point number with possible values from <code>5.0x10<sup>-324</sup></code> to <code>1.8x10<sup>308</sup></code>.
@@ -71,10 +71,13 @@ for(let num of view) {
 
 ## TypedArray
 
-The common term for all these views (`Uint8Array`, `Uint32Array`, etc) is [TypedArray](https://tc39.github.io/ecma262/#sec-typedarray-objects). They share the same set of methods and properities.
+The common term for all these views (`Uint8Array`, `Uint32Array`, etc) is [TypedArray](https://tc39.github.io/ecma262/#sec-typedarray-objects). They share the same set of methods and properties.
 
-They are much more like regular arrays: have indexes and iterable.
+Please note, there's no constructor called `TypedArray`, it's just a common "umbrella" term to represent one of views over `ArrayBuffer`: `Int8Array`, `Uint8Array` and so on, the full list will soon follow.
 
+When you see something like `new TypedArray`, it means any of `new Int8Array`, `new Uint8Array`, etc.
+
+Typed arrays behave like regular arrays: have indexes and are iterable.
 
 A typed array constructor (be it `Int8Array` or `Float64Array`, doesn't matter) behaves differently depending on argument types.
 
@@ -123,9 +126,9 @@ new TypedArray();
 
 We can create a `TypedArray` directly, without mentioning `ArrayBuffer`. But a view cannot exist without an underlying `ArrayBuffer`, so gets created automatically in all these cases except the first one (when provided).
 
-To access the `ArrayBuffer`, there are properties:
-- `arr.buffer` -- references the `ArrayBuffer`.
-- `arr.byteLength` -- the length of the `ArrayBuffer`.
+To access the underlying `ArrayBuffer`, there are following properties in `TypedArray`:
+- `buffer` -- references the `ArrayBuffer`.
+- `byteLength` -- the length of the `ArrayBuffer`.
 
 So, we can always move from one view to another:
 ```js
@@ -206,7 +209,7 @@ These methods allow us to copy typed arrays, mix them, create new arrays from ex
 
 ## DataView
 
-[DataView](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView) is a special super-flexible "untyped" view over `ArrayBuffer`. It allows to access the data on any offset in any format.
+[DataView](mdn:/JavaScript/Reference/Global_Objects/DataView) is a special super-flexible "untyped" view over `ArrayBuffer`. It allows to access the data on any offset in any format.
 
 - For typed arrays, the constructor dictates what the format is. The whole array is supposed to be uniform. The i-th number is `arr[i]`.
 - With `DataView` we access the data with methods like `.getUint8(i)` or `.getUint16(i)`. We choose the format at method call time instead of the construction time.
@@ -232,7 +235,7 @@ let dataView = new DataView(buffer);
 // get 8-bit number at offset 0
 alert( dataView.getUint8(0) ); // 255
 
-// now get 16-bit number at offset 0, it consists of 2 bytes, together iterpreted as 65535
+// now get 16-bit number at offset 0, it consists of 2 bytes, together interpreted as 65535
 alert( dataView.getUint16(0) ); // 65535 (biggest 16-bit unsigned int)
 
 // get 32-bit number at offset 0
@@ -241,7 +244,7 @@ alert( dataView.getUint32(0) ); // 4294967295 (biggest 32-bit unsigned int)
 dataView.setUint32(0, 0); // set 4-byte number to zero, thus setting all bytes to 0
 ```
 
-`DataView` is great when we store mixed-format data in the same buffer. E.g we store a sequence of pairs (16-bit integer, 32-bit float). Then `DataView` allows to access them easily.
+`DataView` is great when we store mixed-format data in the same buffer. For example, when we store a sequence of pairs (16-bit integer, 32-bit float), `DataView` allows to access them easily.
 
 ## Summary
 
@@ -256,7 +259,7 @@ To do almost any operation on `ArrayBuffer`, we need a view.
     - `Float32Array`, `Float64Array` -- for signed floating-point numbers of 32 and 64 bits.
 - Or a `DataView` -- the view that uses methods to specify a format, e.g. `getUint8(offset)`.
 
-In most cases we create and operate directly on typed arrays, leaving `ArrayBuffer` under cover, as a "common discriminator". We can access it as `.buffer` and make another view if needed.
+In most cases we create and operate directly on typed arrays, leaving `ArrayBuffer` under cover, as a "common denominator". We can access it as `.buffer` and make another view if needed.
 
 There are also two additional terms, that are used in descriptions of methods that operate on binary data:
 - `ArrayBufferView` is an umbrella term for all these kinds of views.
diff --git a/4-binary/02-text-decoder/article.md b/4-binary/02-text-decoder/article.md
index d9f5e8fa5..a0c80145c 100644
--- a/4-binary/02-text-decoder/article.md
+++ b/4-binary/02-text-decoder/article.md
@@ -2,7 +2,7 @@
 
 What if the binary data is actually a string? For instance, we received a file with textual data.
 
-The build-in [TextDecoder](https://encoding.spec.whatwg.org/#interface-textdecoder) object allows to read the value into an actual JavaScript string, given the buffer and the encoding.
+The built-in [TextDecoder](https://encoding.spec.whatwg.org/#interface-textdecoder) object allows one to read the value into an actual JavaScript string, given the buffer and the encoding.
 
 We first need to create it:
 ```js
@@ -12,7 +12,7 @@ let decoder = new TextDecoder([label], [options]);
 - **`label`** -- the encoding, `utf-8` by default, but `big5`, `windows-1251` and many other are also supported.
 - **`options`** -- optional object:
   - **`fatal`** -- boolean, if `true` then throw an exception for invalid (non-decodable) characters, otherwise (default) replace them with character `\uFFFD`.
-  - **`ignoreBOM`** -- boolean, if `true` then ignore BOM (an optional byte-order unicode mark), rarely needed.
+  - **`ignoreBOM`** -- boolean, if `true` then ignore BOM (an optional byte-order Unicode mark), rarely needed.
 
 ...And then decode:
 
@@ -58,7 +58,7 @@ alert( new TextDecoder().decode(binaryString) ); // Hello
 
 The syntax is:
 
-```js run
+```js
 let encoder = new TextEncoder();
 ```
 
diff --git a/4-binary/03-blob/article.md b/4-binary/03-blob/article.md
index 062e1834b..fc0150577 100644
--- a/4-binary/03-blob/article.md
+++ b/4-binary/03-blob/article.md
@@ -55,7 +55,7 @@ This behavior is similar to JavaScript strings: we can't change a character in a
 
 ## Blob as URL
 
-A Blob can be easily used as an URL for `<a>`, `<img>` or other tags, to show its contents.
+A Blob can be easily used as a URL for `<a>`, `<img>` or other tags, to show its contents.
 
 Thanks to `type`, we can also download/upload `Blob` objects, and the `type` naturally becomes `Content-Type` in network requests.
 
@@ -74,7 +74,7 @@ link.href = URL.createObjectURL(blob);
 
 We can also create a link dynamically in JavaScript and simulate a click by `link.click()`, then download starts automatically.
 
-Here's the similar code that causes user to download the dynamicallly created `Blob`, without any HTML:
+Here's the similar code that causes user to download the dynamically created `Blob`, without any HTML:
 
 ```js run
 let link = document.createElement('a');
@@ -97,11 +97,11 @@ That's what the value of `link.href` looks like:
 blob:https://javascript.info/1e67e00e-860d-40a5-89ae-6ab0cbee6273
 ```
 
-The browser for each URL generated by `URL.createObjectURL` stores an the URL -> `Blob` mapping internally. So such URLs are short, but allow to access the `Blob`.
+For each URL generated by `URL.createObjectURL` the browser stores a URL -> `Blob` mapping internally. So such URLs are short, but allow to access the `Blob`.
 
-A generated URL (and hence the link with it) is only valid within the current document, while it's open. And it allows to reference the `Blob` in `<img>`, `<a>`, basically any other object that expects an url.
+A generated URL (and hence the link with it) is only valid within the current document, while it's open. And it allows to reference the `Blob` in `<img>`, `<a>`, basically any other object that expects a URL.
 
-There's a side-effect though. While there's a mapping for a `Blob`, the `Blob` itself resides in the memory. The browser can't free it.
+There's a side effect though. While there's a mapping for a `Blob`, the `Blob` itself resides in the memory. The browser can't free it.
 
 The mapping is automatically cleared on document unload, so `Blob` objects are freed then. But if an app is long-living, then that doesn't happen soon.
 
@@ -119,7 +119,7 @@ An alternative to `URL.createObjectURL` is to convert a `Blob` into a base64-enc
 
 That encoding represents binary data as a string of ultra-safe "readable" characters with ASCII-codes from 0 to 64. And what's more important -- we can use this encoding in "data-urls".
 
-A [data url](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs) has the form `data:[<mediatype>][;base64],<data>`. We can use such urls everywhere, on par with "regular" urls.
+A [data url](mdn:/http/Data_URIs) has the form `data:[<mediatype>][;base64],<data>`. We can use such urls everywhere, on par with "regular" urls.
 
 For instance, here's a smiley:
 
@@ -151,7 +151,7 @@ reader.onload = function() {
 };
 ```
 
-Both ways of making an URL of a `Blob` are usable. But usually `URL.createObjectURL(blob)` is simpler and faster.
+Both ways of making a URL of a `Blob` are usable. But usually `URL.createObjectURL(blob)` is simpler and faster.
 
 ```compare title-plus="URL.createObjectURL(blob)" title-minus="Blob to data url"
 + We need to revoke them if care about memory.
@@ -166,8 +166,8 @@ We can create a `Blob` of an image, an image part, or even make a page screensho
 
 Image operations are done via `<canvas>` element:
 
-1. Draw an image (or its part) on canvas using [canvas.drawImage](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/drawImage).
-2. Call canvas method [.toBlob(callback, format, quality)](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob) that creates a `Blob` and runs `callback` with it when done.
+1. Draw an image (or its part) on canvas using [canvas.drawImage](mdn:/api/CanvasRenderingContext2D/drawImage).
+2. Call canvas method [.toBlob(callback, format, quality)](mdn:/api/HTMLCanvasElement/toBlob) that creates a `Blob` and runs `callback` with it when done.
 
 In the example below, an image is just copied, but we could cut from it, or transform it on canvas prior to making a blob:
 
@@ -186,7 +186,7 @@ let context = canvas.getContext('2d');
 context.drawImage(img, 0, 0);
 // we can context.rotate(), and do many other things on canvas
 
-// toBlob is async opereation, callback is called when done
+// toBlob is async operation, callback is called when done
 canvas.toBlob(function(blob) {
   // blob ready, download it
   let link = document.createElement('a');
@@ -211,21 +211,44 @@ For screenshotting a page, we can use a library such as <https://github.com/nikl
 
 The `Blob` constructor allows to create a blob from almost anything, including any `BufferSource`.
 
-But if we need to perform low-level processing, we can get the lowest-level `ArrayBuffer` from it using `FileReader`:
+But if we need to perform low-level processing, we can get the lowest-level `ArrayBuffer` from `blob.arrayBuffer()`:
 
 ```js
 // get arrayBuffer from blob
-let fileReader = new FileReader();
+const bufferPromise = await blob.arrayBuffer();
 
-*!*
-fileReader.readAsArrayBuffer(blob);
-*/!*
-
-fileReader.onload = function(event) {
-  let arrayBuffer = fileReader.result;
-};
+// or
+blob.arrayBuffer().then(buffer => /* process the ArrayBuffer */);
 ```
 
+## From Blob to stream
+
+When we read and write to a blob of more than `2 GB`, the use of `arrayBuffer` becomes more memory intensive for us. At this point, we can directly convert the blob to a stream.
+
+A stream is a special object that allows to read from it (or write into it) portion by portion. It's outside of our scope here, but here's an example, and you can read more at <https://developer.mozilla.org/en-US/docs/Web/API/Streams_API>. Streams are convenient for data that is suitable for processing piece-by-piece.
+
+The `Blob` interface's `stream()` method returns a `ReadableStream` which upon reading returns the data contained within the `Blob`.
+
+Then we can read from it, like this:
+
+```js
+// get readableStream from blob
+const readableStream = blob.stream();
+const stream = readableStream.getReader();
+
+while (true) {
+  // for each iteration: value is the next blob fragment
+  let { done, value } = await stream.read();
+  if (done) {
+    // no more data in the stream
+    console.log('all blob processed.');
+    break;
+  }
+
+   // do something with the data portion we've just read from the blob
+  console.log(value);
+}
+```
 
 ## Summary
 
@@ -235,7 +258,9 @@ That makes Blobs convenient for upload/download operations, that are so common i
 
 Methods that perform web-requests, such as [XMLHttpRequest](info:xmlhttprequest), [fetch](info:fetch) and so on, can work with `Blob` natively, as well as with other binary types.
 
-We can easily convert betweeen `Blob` and low-level binary data types:
+We can easily convert between `Blob` and low-level binary data types:
+
+- We can make a `Blob` from a typed array using `new Blob(...)` constructor.
+- We can get back `ArrayBuffer` from a Blob using `blob.arrayBuffer()`, and then create a view over it for low-level binary processing.
 
-- We can make a Blob from a typed array using `new Blob(...)` constructor.
-- We can get back `ArrayBuffer` from a Blob using `FileReader`, and then create a view over it for low-level binary processing.
+Conversion streams are very useful when we need to handle large blob. You can easily create a `ReadableStream` from a blob. The `Blob` interface's `stream()` method returns a `ReadableStream` which upon reading returns the data contained within the blob.
diff --git a/4-binary/04-file/article.md b/4-binary/04-file/article.md
index 43c0ca583..20878b650 100644
--- a/4-binary/04-file/article.md
+++ b/4-binary/04-file/article.md
@@ -61,8 +61,8 @@ The main methods:
 
 The choice of `read*` method depends on which format we prefer, how we're going to use the data.
 
-- `readAsArrayBuffer` - for binary files, to do low-level binary operations. For high-level operations, like slicing, `File` inherits from `Blob`, so we can call them directly, without reading.
-- `readAsText` - for text files, when we'd like to get a string.
+- `readAsArrayBuffer` -- for binary files, to do low-level binary operations. For high-level operations, like slicing, `File` inherits from `Blob`, so we can call them directly, without reading.
+- `readAsText` -- for text files, when we'd like to get a string.
 - `readAsDataURL` -- when we'd like to use this data in `src` for `img` or another tag. There's an alternative to reading a file for that, as discussed in chapter <info:blob>: `URL.createObjectURL(file)`.
 
 As the reading proceeds, there are events:
diff --git a/5-network/01-fetch/01-fetch-users/solution.md b/5-network/01-fetch/01-fetch-users/solution.md
index 369e34fbe..af8a9fe21 100644
--- a/5-network/01-fetch/01-fetch-users/solution.md
+++ b/5-network/01-fetch/01-fetch-users/solution.md
@@ -3,7 +3,11 @@ Do pobrania użytkownika wykorzystamy: `fetch('https://api.github.com/users/USER
 
 Jeżeli odpowiedź zostanie zwrócona ze statusem `200`, wywołamy metodę `.json()`, aby móc odczytać javascriptowy obiekt.
 
+<<<<<<< HEAD
 Jeżeli natomiast `fetch` się nie powiedzie lub status odpowiedzi będzie inny niz 200, wówczas w tablicy wynikowej zwracamy po prostu `null`.
+=======
+Otherwise, if a `fetch` fails, or the response has non-200 status, we just return `null` in the resulting array.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 Kod wygląda następująco:
 
diff --git a/5-network/01-fetch/article.md b/5-network/01-fetch/article.md
index 32eb82358..9bb6ae586 100644
--- a/5-network/01-fetch/article.md
+++ b/5-network/01-fetch/article.md
@@ -1,7 +1,11 @@
 
 # Fetch
 
+<<<<<<< HEAD
 Ilekroć jest to potrzebne, JavaScript potrafi wykonywać żądania sieciowe do serwera i pobierać nowe informacje.
+=======
+JavaScript can send network requests to the server and load new information whenever it's needed.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 Można na przykład użyć żądania sieciowego do:
 
@@ -27,7 +31,11 @@ let promise = fetch(url, [options])
 - **`url`** -- adres URL zapytania.
 - **`options`** -- parametry opcjonalne: metoda, nagłówki, itp.
 
+<<<<<<< HEAD
 Bez `options` mamy do czynienia ze zwykłym zapytaniem GET, pobierającym zawartość adresu `url`.
+=======
+Without `options`, this is a simple GET request, downloading the contents of the `url`.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 Przeglądarka natychmiast uruchamia zapytanie i zwraca obietnicę (ang. *promise*), której kod wywołujący powinien użyć do uzyskania wyniku.
 
@@ -61,12 +69,21 @@ if (response.ok) { // jeżeli kod odpowiedzi HTTP jest z zakresu 200-299
 
 Obiekt klasy `Response` (pol. *odpowiedź*) zapewnia wiele metod bazujących na obietnicach, które pozwalają na dostęp do ciała odpowiedzi i zwrócenie go w różnych formach:
 
+<<<<<<< HEAD
 - **`response.text()`** -- odczytaj odpowiedź i zwróć jako tekst,
 - **`response.json()`** -- odczytaj odpowiedź i zwróć jako JSON,
 - **`response.formData()`** -- zwróć odpowiedź jako obiekt typu `FormData` (wyjaśnienie w [następnym rozdziale](info:formdata)),
 - **`response.blob()`** -- zwróć odpowiedź jako [Blob](info:blob) (dane binarne z typem),
 - **`response.arrayBuffer()`** -- zwróć odpowiedź jako [ArrayBuffer](info:arraybuffer-binary-arrays) (niskopoziomowa reprezentacja danych binarnych),
 - ponadto `response.body` jest sam w sobie obiektem typu [ReadableStream](https://streams.spec.whatwg.org/#rs-class), co pozwala na odczytywanie go kawałek po kawałku. Ale o tym nieco później.
+=======
+- **`response.text()`** -- read the response and return as text,
+- **`response.json()`** -- parse the response as JSON,
+- **`response.formData()`** -- return the response as `FormData` object (explained in the [next chapter](info:formdata)),
+- **`response.blob()`** -- return the response as [Blob](info:blob) (binary data with type),
+- **`response.arrayBuffer()`** -- return the response as [ArrayBuffer](info:arraybuffer-binary-arrays) (low-level representation of binary data),
+- additionally, `response.body` is a [ReadableStream](https://streams.spec.whatwg.org/#rs-class) object, it allows you to read the body chunk-by-chunk, we'll see an example later.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 Pobierzmy dla przykładu obiekt JSON z ostatnimi commitami z GitHuba.
 
@@ -128,8 +145,14 @@ Można wybrać tyko jedną z metod odczytywania ciała odpowiedzi.
 Jeśli już zdecydowaliśmy się na `response.text()`, wówczas `response.json()` nie zadziała, ponieważ zawartość ciała odpowiedzi została już wcześniej przetworzona.
 
 ```js
+<<<<<<< HEAD
 let text = await response.text(); // ciało odpowiedzi zostaje przetworzone
 let parsed = await response.json(); // nie powiedzie się (przetworzone wcześniej)
+=======
+let text = await response.text(); // response body consumed
+let parsed = await response.json(); // fails (already consumed)
+```
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 ````
 
 ## Nagłówki odpowiedzi
@@ -191,12 +214,21 @@ Dzięki nim protokół HTTP działa prawidłowo i jest bezpieczny, dlatego też
 
 Do wykonania żądania z metodą `POST` lub jakąkolwiek inną musimy użyć opcji dostępnych w funkcji `fetch`:
 
+<<<<<<< HEAD
 - **`method`** -- metoda HTTP, np. `POST`,
 - **`body`** -- ciało żądania, może przyjąć formę:
   - łańcucha znaków (np. w formacie JSON),
   - obiektu `FormData`, aby móc przesłać dane jako `form/multipart`,
   - `Blob`/`BufferSource`, aby przesłać dane w formie binarnej,
   - [URLSearchParams](info:url), aby przesłać dane jako `x-www-form-urlencoded`, rzadko używane. 
+=======
+- **`method`** -- HTTP-method, e.g. `POST`,
+- **`body`** -- the request body, one of:
+  - a string (e.g. JSON-encoded),
+  - `FormData` object, to submit the data as `multipart/form-data`,
+  - `Blob`/`BufferSource` to send binary data,
+  - [URLSearchParams](info:url), to submit the data in `x-www-form-urlencoded` encoding, rarely used.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 Najczęściej używanym formatem jest JSON.
 
@@ -230,7 +262,11 @@ Ponieważ jednak zamierzamy wysłać obiekt JSON, użyjemy obiektu `headers` do
 
 Za pomocą `fetch` możemy także przesłać dane binarne, używając obiektów `Blob` albo `BufferSource`.
 
+<<<<<<< HEAD
 W poniższym przykładzie mamy znacznik `<canvas>`, który pozwala na rysowanie poprzez poruszanie nad nim myszką. Kliknięcie na przycisk "Prześlij" wysyła obraz do serwera:
+=======
+In this example, there's a `<canvas>` where we can draw by moving a mouse over it. A click on the "submit" button sends the image to the server:
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ```html run autorun height="90"
 <body style="margin:0">
@@ -295,6 +331,7 @@ fetch(url, options)
   .then(result => /* zrób coś z parametrem result */)
 ```
 
+<<<<<<< HEAD
 Właściwości żądania:
 - `response.status` -- kod odpowiedzi HTTP,
 - `response.ok` -- `true` dla kodów odpowiedzi z przedziału 200-299.
@@ -306,6 +343,19 @@ Metody służące do przetwarzania ciała odpowiedzi:
 - **`response.formData()`** -- zwróć odpowiedź jako obiekt `FormData` (kodowanie form/multipart, zobacz następny rozdział),
 - **`response.blob()`** -- zwróć odpowiedź jako [Blob](info:blob) (dane binarne z typem),
 - **`response.arrayBuffer()`** -- zwróć odpowiedź jako [ArrayBuffer](info:arraybuffer-binary-arrays) (niskopoziomowa reprezentacja danych binarnych),
+=======
+Response properties:
+- `response.status` -- HTTP code of the response,
+- `response.ok` -- `true` if the status is 200-299.
+- `response.headers` -- Map-like object with HTTP headers.
+
+Methods to get response body:
+- **`response.text()`** -- return the response as text,
+- **`response.json()`** -- parse the response as JSON object,
+- **`response.formData()`** -- return the response as `FormData` object (`multipart/form-data` encoding, see the next chapter),
+- **`response.blob()`** -- return the response as [Blob](info:blob) (binary data with type),
+- **`response.arrayBuffer()`** -- return the response as [ArrayBuffer](info:arraybuffer-binary-arrays) (low-level binary data),
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 Poznane jak dotąd opcje metody `fetch`:
 - `method` -- metoda żądania HTTP,
diff --git a/5-network/02-formdata/article.md b/5-network/02-formdata/article.md
index 41971479f..dddc142d8 100644
--- a/5-network/02-formdata/article.md
+++ b/5-network/02-formdata/article.md
@@ -12,7 +12,11 @@ let formData = new FormData([form]);
 
 Przechwyci on automatycznie wszystkie pola formularza HTML na stronie.
 
+<<<<<<< HEAD
 `FormData` posiada tę szczególną cechę, że metody sieciowe takie jak `fetch` mogą przyjmować obiekt `FormData` jako ciało. Jest on wówczas kodowany i wysyłany jako `Content-Type: form/multipart`.
+=======
+The special thing about `FormData` is that network methods, such as `fetch`, can accept a `FormData` object as a body. It's encoded and sent out with `Content-Type: multipart/form-data`.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 Z perspektywy serwera wygląda to jak zwykłe przesłanie formularza.
 
@@ -47,7 +51,11 @@ Jak widać, to niemal jedna linijka:
 </script>
 ```
 
+<<<<<<< HEAD
 Kod serwera jest poza naszym zakresem zainteresowania, zatem nie pokazujemy go w tym przykładzie. W każdym razie serwer akceptuje żądanie POST i odpowiada komunikatem: "Użytkownik zapisany".
+=======
+In this example, the server code is not presented, as it's beyond our scope. The server accepts the POST request and replies "User saved".
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ## Metody FormData
 
@@ -75,13 +83,21 @@ formData.append('key2', 'value2');
 
 // Wylicz pary klucz/wartość
 for(let [name, value] of formData) {
+<<<<<<< HEAD
   alert(`${name}=${value}`); // key1=value1 oraz key2=value2
+=======
+  alert(`${name} = ${value}`); // key1 = value1, then key2 = value2
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 }
 ```
 
 ## Wysyłanie formularza z plikiem
 
+<<<<<<< HEAD
 Formularz jest zawsze wysyłany jako `Content-Type: form/multipart`, gdyż takie kodowanie pozwala na wysyłkę plików. Tak więc pola `<input type="file">` są również wysyłane, podobnie jak ma to miejsce w zwykłym przesłaniu formularza.
+=======
+The form is always sent as `Content-Type: multipart/form-data`, this encoding allows to send files. So, `<input type="file">` fields are sent also, similar to a usual form submission.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 Oto przykład takiego formularza:
 
@@ -168,7 +184,11 @@ Serwer odczytuje dane formularza i plik, tak jakby było to zwykłe przesyłanie
 
 Obiekty klasy [FormData](https://xhr.spec.whatwg.org/#interface-formdata) służą do przechwycenia formularza HTML i przesłania go za pomocą `fetch` lub innej funkcji sieciowej.
 
+<<<<<<< HEAD
 Możemy albo utworzyć `new FormData(form)` na podstawie formularza HTML, albo stworzyć obiekt bez formularza, a następnie dołączyć do niego pola metodami:
+=======
+We can either create `new FormData(form)` from an HTML form, or create an object without a form at all, and then append fields with methods:
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 - `formData.append(name, value)`
 - `formData.append(name, blob, fileName)`
diff --git a/5-network/03-fetch-progress/article.md b/5-network/03-fetch-progress/article.md
index 867a865b7..9b817f5a0 100644
--- a/5-network/03-fetch-progress/article.md
+++ b/5-network/03-fetch-progress/article.md
@@ -5,11 +5,19 @@ Metoda `fetch` pozwala śledzić postęp pobierania (ang. *download*).
 
 Należy pamiętać, że `fetch` nie ma możliwości śledzenia postępu wysyłania danych (ang. *upload*). Do tego celu należy użyć [XMLHttpRequest](info:xmlhttprequest). Omówimy to w dalszej części.
 
+<<<<<<< HEAD
 W celu śledzenia postępu pobierania możemy wykorzystać właściwość `response.body`. Jest to specjalny obiekt `ReadableStream` (pol. *odczytywalny strumień*), który udostępnia ciało odpowiedzi na bieżąco, kawałek po kawałku (ang. *chunk*). Odczytywalne strumienie zostały opisane w specyfikacji [API Strumieni](https://streams.spec.whatwg.org/#rs-class).
+=======
+To track download progress, we can use `response.body` property. It's a `ReadableStream` -- a special object that provides body chunk-by-chunk, as it comes. Readable streams are described in the [Streams API](https://streams.spec.whatwg.org/#rs-class) specification.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 W przeciwieństwie do `response.text()`, `response.json()` czy innych metod, `response.body` pozwala na całkowitą kontrolę nad procesem odczytu, co pozwala na określenie, jaka ilość danych jest zużywana w dowolnym momencie.
 
+<<<<<<< HEAD
 Oto przykład kodu, który odczytuje odpowiedź z `response.body`:
+=======
+Here's the sketch of code that reads the response from `response.body`:
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 ```js
 // zamiast response.json() i innych metod
@@ -107,6 +115,14 @@ Wyjaśnijmy wszystko krok po kroku:
     let blob = new Blob(chunks);
     ```
 
+<<<<<<< HEAD
 W rezultacie otrzymujemy łańcuch znaków lub `Blob` (w zależności od potrzeb) oraz możliwość śledzenia postępu całego procesu.
 
 Ważne, aby pamiętać, że powyższe nie dotyczy postępu *wysyłania*  (obecnie niemożliwe za pomocą `fetch`), a jedynie postępu *pobierania* danych.
+=======
+At the end we have the result (as a string or a blob, whatever is convenient), and progress-tracking in the process.
+
+Once again, please note, that's not for *upload* progress (no way now with `fetch`), only for *download* progress.
+
+Also, if the size is unknown, we should check `receivedLength` in the loop and break it once it reaches a certain limit. So that the `chunks` won't overflow the memory. 
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
diff --git a/5-network/04-fetch-abort/article.md b/5-network/04-fetch-abort/article.md
index 757846287..eadc5aac2 100644
--- a/5-network/04-fetch-abort/article.md
+++ b/5-network/04-fetch-abort/article.md
@@ -1,61 +1,81 @@
 
 # Fetch: Abort
 
-As we know, `fetch` returns a promise. And JavaScript generally has no concept of "aborting" a promise. So how can we abort a `fetch`?
+As we know, `fetch` returns a promise. And JavaScript generally has no concept of "aborting" a promise. So how can we cancel an ongoing `fetch`? E.g. if the user actions on our site indicate that the `fetch` isn't needed any more.
 
-There's a special built-in object for such purposes: `AbortController`, that can be used to abort not only `fetch`, but other asynchronous tasks as well.
+There's a special built-in object for such purposes: `AbortController`. It can be used to abort not only `fetch`, but other asynchronous tasks as well.
 
-The usage is pretty simple:
+The usage is very straightforward:
 
-- Step 1: create a controller:
+## The AbortController object
 
-    ```js
-    let controller = new AbortController();
-    ```
+Create a controller:
 
-    A controller is an extremely simple object.
+```js
+let controller = new AbortController();
+```
 
-    - It has a single method `abort()`, and a single property `signal`.
-    - When `abort()` is called:
-        - `abort` event triggers on `controller.signal`
-        - `controller.signal.aborted` property becomes `true`.
+A controller is an extremely simple object.
 
-    All parties interested to learn about `abort()` call set listeners on `controller.signal` to track it.
+- It has a single method `abort()`,
+- And a single property `signal` that allows to set event listeners on it.
 
-    Like this (without `fetch` yet):
+When `abort()` is called:
+- `controller.signal` emits the `"abort"` event.
+- `controller.signal.aborted` property becomes `true`.
 
-    ```js run
-    let controller = new AbortController();
-    let signal = controller.signal;
+Generally, we have two parties in the process:
+1. The one that performs a cancelable operation, it sets a listener on `controller.signal`.
+2. The one that cancels: it calls `controller.abort()` when needed.
 
-    // triggers when controller.abort() is called
-    signal.addEventListener('abort', () => alert("abort!"));
+Here's the full example (without `fetch` yet):
 
-    controller.abort(); // abort!
+```js run
+let controller = new AbortController();
+let signal = controller.signal;
+
+// The party that performs a cancelable operation
+// gets the "signal" object
+// and sets the listener to trigger when controller.abort() is called
+signal.addEventListener('abort', () => alert("abort!"));
 
-    alert(signal.aborted); // true
-    ```
+// The other party, that cancels (at any point later):
+controller.abort(); // abort!
 
-- Step 2: pass the `signal` property to `fetch` option:
+// The event triggers and signal.aborted becomes true
+alert(signal.aborted); // true
+```
 
-    ```js
-    let controller = new AbortController();
-    fetch(url, {
-      signal: controller.signal
-    });
-    ```
+As we can see, `AbortController` is just a mean to pass `abort` events when `abort()` is called on it.
 
-    The `fetch` method knows how to work with `AbortController`, it listens to `abort` on `signal`.
+We could implement the same kind of event listening in our code on our own, without the `AbortController` object.
 
-- Step 3: to abort, call `controller.abort()`:
+But what's valuable is that `fetch` knows how to work with the `AbortController` object. It's integrated in it.
 
-    ```js
-    controller.abort();
-    ```
+## Using with fetch
 
-    We're done: `fetch` gets the event from `signal` and aborts the request.
+To be able to cancel `fetch`, pass the `signal` property of an `AbortController` as a `fetch` option:
 
-When a fetch is aborted, its promise rejects with an error `AbortError`, so we should handle it, e.g. in `try..catch`:
+```js
+let controller = new AbortController();
+fetch(url, {
+  signal: controller.signal
+});
+```
+
+The `fetch` method knows how to work with `AbortController`. It will listen to `abort` events on `signal`.
+
+Now, to abort, call `controller.abort()`:
+
+```js
+controller.abort();
+```
+
+We're done: `fetch` gets the event from `signal` and aborts the request.
+
+When a fetch is aborted, its promise rejects with an error `AbortError`, so we should handle it, e.g. in `try..catch`.
+
+Here's the full example with `fetch` aborted after 1 second:
 
 ```js run async
 // abort in 1 second
@@ -75,28 +95,31 @@ try {
 }
 ```
 
-**`AbortController` is scalable, it allows to cancel multiple fetches at once.**
+## AbortController is scalable
 
-For instance, here we fetch many `urls` in parallel, and the controller aborts them all:
+`AbortController` is scalable. It allows to cancel multiple fetches at once.
+
+Here's a sketch of code that fetches many `urls` in parallel, and uses a single controller to abort them all:
 
 ```js
 let urls = [...]; // a list of urls to fetch in parallel
 
 let controller = new AbortController();
 
+// an array of fetch promises
 let fetchJobs = urls.map(url => fetch(url, {
   signal: controller.signal
 }));
 
 let results = await Promise.all(fetchJobs);
 
-// if controller.abort() is called from elsewhere,
+// if controller.abort() is called from anywhere,
 // it aborts all fetches
 ```
 
-If we have our own asynchronous jobs, different from `fetch`, we can use a single `AbortController` to stop those, together with fetches.
+If we have our own asynchronous tasks, different from `fetch`, we can use a single `AbortController` to stop those, together with fetches.
 
-We just need to listen to its `abort` event:
+We just need to listen to its `abort` event in our tasks:
 
 ```js
 let urls = [...];
@@ -114,8 +137,12 @@ let fetchJobs = urls.map(url => fetch(url, { // fetches
 // Wait for fetches and our task in parallel
 let results = await Promise.all([...fetchJobs, ourJob]);
 
-// if controller.abort() is called from elsewhere,
+// if controller.abort() is called from anywhere,
 // it aborts all fetches and ourJob
 ```
 
-So `AbortController` is not only for `fetch`, it's a universal object to abort asynchronous tasks, and `fetch` has built-in integration with it.
+## Summary
+
+- `AbortController` is a simple object that generates an `abort` event on its `signal` property when the `abort()` method is called (and also sets `signal.aborted` to `true`).
+- `fetch` integrates with it: we pass the `signal` property as the option, and then `fetch` listens to it, so it's possible to abort the `fetch`.
+- We can use `AbortController` in our code. The "call `abort()`" -> "listen to `abort` event" interaction is simple and universal. We can use it even without `fetch`.
diff --git a/5-network/05-fetch-crossorigin/article.md b/5-network/05-fetch-crossorigin/article.md
index 1394433d9..4420f43c7 100644
--- a/5-network/05-fetch-crossorigin/article.md
+++ b/5-network/05-fetch-crossorigin/article.md
@@ -28,7 +28,7 @@ Seriously. Let's make a very brief historical digression.
 
 **For many years a script from one site could not access the content of another site.**
 
-That simple, yet powerful rule was a foundation of the internet security. E.g. an evil script from website `hacker.com` could not access user's mailbox at website `gmail.com`. People felt safe.
+That simple, yet powerful rule was a foundation of the internet security. E.g. an evil script from website `hacker.com` could not access the user's mailbox at website `gmail.com`. People felt safe.
 
 JavaScript also did not have any special methods to perform network requests at that time. It was a toy language to decorate a web page.
 
@@ -44,7 +44,7 @@ One way to communicate with another server was to submit a `<form>` there. Peopl
 <iframe name="iframe"></iframe>
 */!*
 
-<!-- a form could be dynamically generated and submited by JavaScript -->
+<!-- a form could be dynamically generated and submitted by JavaScript -->
 *!*
 <form target="iframe" method="POST" action="http://another.com/…">
 */!*
@@ -97,43 +97,43 @@ After a while, networking methods appeared in browser JavaScript.
 
 At first, cross-origin requests were forbidden. But as a result of long discussions, cross-origin requests were allowed, but with any new capabilities requiring an explicit allowance by the server, expressed in special headers.
 
-## Simple requests
+## Safe requests
 
 There are two types of cross-origin requests:
 
-1. Simple requests.
+1. Safe requests.
 2. All the others.
 
-Simple Requests are, well, simpler to make, so let's start with them.
+Safe Requests are simpler to make, so let's start with them.
 
-A [simple request](http://www.w3.org/TR/cors/#terminology) is a request that satisfies two conditions:
+A request is safe if it satisfies two conditions:
 
-1. [Simple method](http://www.w3.org/TR/cors/#simple-method): GET, POST or HEAD
-2. [Simple headers](http://www.w3.org/TR/cors/#simple-header) -- the only allowed custom headers are:
+1. [Safe method](https://fetch.spec.whatwg.org/#cors-safelisted-method): GET, POST or HEAD
+2. [Safe headers](https://fetch.spec.whatwg.org/#cors-safelisted-request-header) -- the only allowed custom headers are:
     - `Accept`,
     - `Accept-Language`,
     - `Content-Language`,
     - `Content-Type` with the value `application/x-www-form-urlencoded`, `multipart/form-data` or `text/plain`.
 
-Any other request is considered "non-simple". For instance, a request with `PUT` method or with an `API-Key` HTTP-header does not fit the limitations.
+Any other request is considered "unsafe". For instance, a request with `PUT` method or with an `API-Key` HTTP-header does not fit the limitations.
 
-**The essential difference is that a "simple request" can be made with a `<form>` or a `<script>`, without any special methods.**
+**The essential difference is that a safe request can be made with a `<form>` or a `<script>`, without any special methods.**
 
-So, even a very old server should be ready to accept a simple request.
+So, even a very old server should be ready to accept a safe request.
 
 Contrary to that, requests with non-standard headers or e.g. method `DELETE` can't be created this way. For a long time JavaScript was unable to do such requests. So an old server may assume that such requests come from a privileged source, "because a webpage is unable to send them".
 
-When we try to make a non-simple request, the browser sends a special "preflight" request that asks the server -- does it agree to accept such cross-origin requests, or not?
+When we try to make a unsafe request, the browser sends a special "preflight" request that asks the server -- does it agree to accept such cross-origin requests, or not?
 
-And, unless the server explicitly confirms that with headers, a non-simple request is not sent.
+And, unless the server explicitly confirms that with headers, an unsafe request is not sent.
 
 Now we'll go into details.
 
-## CORS for simple requests
+## CORS for safe requests
 
-If a request is cross-origin, the browser always adds `Origin` header to it.
+If a request is cross-origin, the browser always adds the `Origin` header to it.
 
-For instance, if we request `https://anywhere.com/request` from `https://javascript.info/page`, the headers will be like:
+For instance, if we request `https://anywhere.com/request` from `https://javascript.info/page`, the headers will look like:
 
 ```http
 GET /request
@@ -144,9 +144,9 @@ Origin: https://javascript.info
 ...
 ```
 
-As you can see, `Origin` header contains exactly the origin (domain/protocol/port), without a path.
+As you can see, the `Origin` header contains exactly the origin (domain/protocol/port), without a path.
 
-The server can inspect the `Origin` and, if it agrees to accept such a request, adds a special header `Access-Control-Allow-Origin` to the response. That header should contain the allowed origin (in our case `https://javascript.info`), or a star `*`. Then the response is successful, otherwise an error.
+The server can inspect the `Origin` and, if it agrees to accept such a request, add a special header `Access-Control-Allow-Origin` to the response. That header should contain the allowed origin (in our case `https://javascript.info`), or a star `*`. Then the response is successful, otherwise it's an error.
 
 The browser plays the role of a trusted mediator here:
 1. It ensures that the correct `Origin` is sent with a cross-origin request.
@@ -165,10 +165,11 @@ Access-Control-Allow-Origin: https://javascript.info
 
 ## Response headers
 
-For cross-origin request, by default JavaScript may only access so-called "simple" response headers:
+For cross-origin request, by default JavaScript may only access so-called "safe" response headers:
 
 - `Cache-Control`
 - `Content-Language`
+- `Content-Length`
 - `Content-Type`
 - `Expires`
 - `Last-Modified`
@@ -176,13 +177,7 @@ For cross-origin request, by default JavaScript may only access so-called "simpl
 
 Accessing any other response header causes an error.
 
-```smart
-There's no `Content-Length` header in the list!
-
-This header contains the full response length. So, if we're downloading something and would like to track the percentage of progress, then an additional permission is required to access that header (see below).
-```
-
-To grant JavaScript access to any other response header, the server must send  `Access-Control-Expose-Headers` header. It contains a comma-separated list of non-simple header names that should be made accessible.
+To grant JavaScript access to any other response header, the server must send the `Access-Control-Expose-Headers` header. It contains a comma-separated list of unsafe header names that should be made accessible.
 
 For example:
 
@@ -190,37 +185,40 @@ For example:
 200 OK
 Content-Type:text/html; charset=UTF-8
 Content-Length: 12345
+Content-Encoding: gzip
 API-Key: 2c9de507f2c54aa1
 Access-Control-Allow-Origin: https://javascript.info
 *!*
-Access-Control-Expose-Headers: Content-Length,API-Key
+Access-Control-Expose-Headers: Content-Encoding,API-Key
 */!*
 ```
 
-With such `Access-Control-Expose-Headers` header, the script is allowed to read `Content-Length` and `API-Key` headers of the response.
+With such an `Access-Control-Expose-Headers` header, the script is allowed to read the `Content-Encoding` and `API-Key` headers of the response.
 
-## "Non-simple" requests
+## "Unsafe" requests
 
 We can use any HTTP-method: not just `GET/POST`, but also `PATCH`, `DELETE` and others.
 
 Some time ago no one could even imagine that a webpage could make such requests. So there may still exist webservices that treat a non-standard method as a signal: "That's not a browser". They can take it into account when checking access rights.
 
-So, to avoid misunderstandings, any "non-simple" request -- that couldn't be done in the old times, the browser does not make such requests right away. Before it sends a preliminary, so-called "preflight" request, asking for permission.
+So, to avoid misunderstandings, any "unsafe" request -- that couldn't be done in the old times, the browser does not make such requests right away. First, it sends a preliminary, so-called "preflight" request, to ask for permission.
 
-A preflight request uses method `OPTIONS`, no body and two headers:
+A preflight request uses the method `OPTIONS`, no body and three headers:
 
-- `Access-Control-Request-Method` header has the method of the non-simple request.
-- `Access-Control-Request-Headers` header provides a comma-separated list of its non-simple HTTP-headers.
+- `Access-Control-Request-Method` header has the method of the unsafe request.
+- `Access-Control-Request-Headers` header provides a comma-separated list of its unsafe HTTP-headers.
+- `Origin` header tells from where the request came. (such as `https://javascript.info`)
 
 If the server agrees to serve the requests, then it should respond with empty body, status 200 and headers:
 
+- `Access-Control-Allow-Origin` must be either `*` or the requesting origin, such as `https://javascript.info`, to allow it.
 - `Access-Control-Allow-Methods` must have the allowed method.
 - `Access-Control-Allow-Headers` must have a list of allowed headers.
 - Additionally, the header `Access-Control-Max-Age` may specify a number of seconds to cache the permissions. So the browser won't have to send a preflight for subsequent requests that satisfy given permissions.
 
 ![](xhr-preflight.svg)
 
-Let's see how it works step-by-step on example, for a cross-origin `PATCH` request (this method is often used to update data):
+Let's see how it works step-by-step on the example of a cross-origin `PATCH` request (this method is often used to update data):
 
 ```js
 let response = await fetch('https://site.com/service.json', {
@@ -232,14 +230,14 @@ let response = await fetch('https://site.com/service.json', {
 });
 ```
 
-There are three reasons why the request is not simple (one is enough):
+There are three reasons why the request is unsafe (one is enough):
 - Method `PATCH`
 - `Content-Type` is not one of: `application/x-www-form-urlencoded`, `multipart/form-data`, `text/plain`.
-- "Non-simple" `API-Key` header.
+- "Unsafe" `API-Key` header.
 
 ### Step 1 (preflight request)
 
-Prior to sending such request, the browser, on its own, sends a preflight request that looks like this:
+Prior to sending such a request, the browser, on its own, sends a preflight request that looks like this:
 
 ```http
 OPTIONS /service.json
@@ -254,20 +252,24 @@ Access-Control-Request-Headers: Content-Type,API-Key
 - Cross-origin special headers:
     - `Origin` -- the source origin.
     - `Access-Control-Request-Method` -- requested method.
-    - `Access-Control-Request-Headers` -- a comma-separated list of "non-simple" headers.
+    - `Access-Control-Request-Headers` -- a comma-separated list of "unsafe" headers.
 
 ### Step 2 (preflight response)
 
-The server should respond with status 200 and headers:
+The server should respond with status 200 and the headers:
+- `Access-Control-Allow-Origin: https://javascript.info`
 - `Access-Control-Allow-Methods: PATCH`
 - `Access-Control-Allow-Headers: Content-Type,API-Key`.
 
 That allows future communication, otherwise an error is triggered.
 
-If the server expects other methods and headers in the future, it makes sense to allow them in advance by adding to the list:
+If the server expects other methods and headers in the future, it makes sense to allow them in advance by adding them to the list.
+
+For example, this response also allows `PUT`, `DELETE` and additional headers:
 
 ```http
 200 OK
+Access-Control-Allow-Origin: https://javascript.info
 Access-Control-Allow-Methods: PUT,PATCH,DELETE
 Access-Control-Allow-Headers: API-Key,Content-Type,If-Modified-Since,Cache-Control
 Access-Control-Max-Age: 86400
@@ -275,13 +277,13 @@ Access-Control-Max-Age: 86400
 
 Now the browser can see that `PATCH` is in `Access-Control-Allow-Methods` and `Content-Type,API-Key` are in the list `Access-Control-Allow-Headers`, so it sends out the main request.
 
-Besides, the preflight response is cached for time, specified by `Access-Control-Max-Age` header (86400 seconds, one day), so subsequent requests will not cause a preflight. Assuming that they fit the cached allowances, they will be sent directly.
+If there's the header `Access-Control-Max-Age` with a number of seconds, then the preflight permissions are cached for the given time. The response above will be cached for 86400 seconds (one day). Within this timeframe, subsequent requests will not cause a preflight. Assuming that they fit the cached allowances, they will be sent directly.
 
 ### Step 3 (actual request)
 
-When the preflight is successful, the browser now makes the main request. The algorithm here is the same as for simple requests.
+When the preflight is successful, the browser now makes the main request. The process here is the same as for safe requests.
 
-The main request has `Origin` header (because it's cross-origin):
+The main request has the `Origin` header (because it's cross-origin):
 
 ```http
 PATCH /service.json
@@ -309,9 +311,9 @@ JavaScript only gets the response to the main request or an error if there's no
 
 ## Credentials
 
-A cross-origin request by default does not bring any credentials (cookies or HTTP authentication).
+A cross-origin request initiated by JavaScript code by default does not bring any credentials (cookies or HTTP authentication).
 
-That's uncommon for HTTP-requests. Usually, a request to `http://site.com` is accompanied by all cookies from that domain. But cross-origin requests made by JavaScript methods are an exception.
+That's uncommon for HTTP-requests. Usually, a request to `http://site.com` is accompanied by all cookies from that domain. Cross-origin requests made by JavaScript methods on the other hand are an exception.
 
 For example, `fetch('http://another.com')` does not send any cookies, even those  (!) that belong to `another.com` domain.
 
@@ -329,7 +331,7 @@ fetch('http://another.com', {
 });
 ```
 
-Now `fetch` sends cookies originating from `another.com` without request to that site.
+Now `fetch` sends cookies originating from `another.com` with request to that site.
 
 If the server agrees to accept the request *with credentials*, it should add a header `Access-Control-Allow-Credentials: true` to the response, in addition to `Access-Control-Allow-Origin`.
 
@@ -345,9 +347,9 @@ Please note: `Access-Control-Allow-Origin` is prohibited from using a star `*` f
 
 ## Summary
 
-From the browser point of view, there are two kinds of cross-origin requests: "simple" and all the others.
+From the browser point of view, there are two kinds of cross-origin requests: "safe" and all the others.
 
-[Simple requests](http://www.w3.org/TR/cors/#terminology) must satisfy the following conditions:
+"Safe" requests must satisfy the following conditions:
 - Method: GET, POST or HEAD.
 - Headers -- we can set only:
     - `Accept`
@@ -355,14 +357,14 @@ From the browser point of view, there are two kinds of cross-origin requests: "s
     - `Content-Language`
     - `Content-Type` to the value `application/x-www-form-urlencoded`, `multipart/form-data` or `text/plain`.
 
-The essential difference is that simple requests were doable since ancient times using `<form>` or `<script>` tags, while non-simple were impossible for browsers for a long time.
+The essential difference is that safe requests were doable since ancient times using `<form>` or `<script>` tags, while unsafe were impossible for browsers for a long time.
 
-So, the practical difference is that simple requests are sent right away, with `Origin` header, while for the other ones the browser makes a preliminary "preflight" request, asking for permission.
+So, the practical difference is that safe requests are sent right away, with the `Origin` header, while for the other ones the browser makes a preliminary "preflight" request, asking for permission.
 
-**For simple requests:**
+**For safe requests:**
 
-- → The browser sends `Origin` header with the origin.
-- ← For requests without credentials (not sent default), the server should set:
+- → The browser sends the `Origin` header with the origin.
+- ← For requests without credentials (not sent by default), the server should set:
     - `Access-Control-Allow-Origin` to `*` or same value as `Origin`
 - ← For requests with credentials, the server should set:
     - `Access-Control-Allow-Origin` to same value as `Origin`
@@ -370,13 +372,13 @@ So, the practical difference is that simple requests are sent right away, with `
 
 Additionally, to grant JavaScript access to any response headers except `Cache-Control`,  `Content-Language`, `Content-Type`, `Expires`, `Last-Modified` or `Pragma`, the server should list the allowed ones in `Access-Control-Expose-Headers` header.
 
-**For non-simple requests, a preliminary "preflight" request is issued before the requested one:**
+**For unsafe requests, a preliminary "preflight" request is issued before the requested one:**
 
-- → The browser sends `OPTIONS` request to the same URL, with headers:
+- → The browser sends an `OPTIONS` request to the same URL, with the headers:
     - `Access-Control-Request-Method` has requested method.
-    - `Access-Control-Request-Headers` lists non-simple requested headers.
-- ← The server should respond with status 200 and headers:
+    - `Access-Control-Request-Headers` lists unsafe requested headers.
+- ← The server should respond with status 200 and the headers:
     - `Access-Control-Allow-Methods` with a list of allowed methods,
     - `Access-Control-Allow-Headers` with a list of allowed headers,
-    - `Access-Control-Max-Age` with a number of seconds to cache permissions.
-- Then the actual request is sent, the previous "simple" scheme is applied.
+    - `Access-Control-Max-Age` with a number of seconds to cache the permissions.
+- Then the actual request is sent, and the previous "safe" scheme is applied.
diff --git a/5-network/06-fetch-api/article.md b/5-network/06-fetch-api/article.md
index aea14320e..5f55c78ef 100644
--- a/5-network/06-fetch-api/article.md
+++ b/5-network/06-fetch-api/article.md
@@ -21,10 +21,10 @@ let promise = fetch(url, {
     // depending on the request body
     "Content-Type": "text/plain;charset=UTF-8"
   },
-  body: undefined // string, FormData, Blob, BufferSource, or URLSearchParams
+  body: undefined, // string, FormData, Blob, BufferSource, or URLSearchParams
   referrer: "about:client", // or "" to send no Referer header,
   // or an url from the current origin
-  referrerPolicy: "no-referrer-when-downgrade", // no-referrer, origin, same-origin...
+  referrerPolicy: "strict-origin-when-cross-origin", // no-referrer-when-downgrade, no-referrer, origin, same-origin...
   mode: "cors", // same-origin, no-cors
   credentials: "same-origin", // omit, include
   cache: "default", // no-store, reload, no-cache, force-cache, or only-if-cached
@@ -42,17 +42,17 @@ We fully covered `method`, `headers` and `body` in the chapter <info:fetch>.
 
 The `signal` option is covered in <info:fetch-abort>.
 
-Now let's explore the rest of capabilities.
+Now let's explore the remaining capabilities.
 
 ## referrer, referrerPolicy
 
-These options govern how `fetch` sets HTTP `Referer` header.
+These options govern how `fetch` sets the HTTP `Referer` header.
 
 Usually that header is set automatically and contains the url of the page that made the request. In most scenarios, it's not important at all, sometimes, for security purposes, it makes sense to remove or shorten it.
 
-**The `referrer` option allows to set any `Referer` within the current origin) or remove it.**
+**The `referrer` option allows to set any `Referer` (within the current origin) or remove it.**
 
-To send no referer, set an empty string:
+To send no referrer, set an empty string:
 ```js
 fetch('/page', {
 *!*
@@ -81,39 +81,39 @@ Requests are split into 3 types:
 2. Request to another origin.
 3. Request from HTTPS to HTTP (from safe to unsafe protocol).
 
-Unlike `referrer` option that allows to set the exact `Referer` value, `referrerPolicy` tells the browser general rules for each request type.
+Unlike the `referrer` option that allows to set the exact `Referer` value, `referrerPolicy` tells the browser general rules for each request type.
 
 Possible values are described in the [Referrer Policy specification](https://w3c.github.io/webappsec-referrer-policy/):
 
-- **`"no-referrer-when-downgrade"`** -- the default value: full `Referer` is sent always, unless we send a request from HTTPS to HTTP (to less secure protocol).
+- **`"strict-origin-when-cross-origin"`** -- the default value: for same-origin send the full `Referer`, for cross-origin send only the origin, unless it's HTTPS→HTTP request, then send nothing.
+- **`"no-referrer-when-downgrade"`** -- full `Referer` is always sent, unless we send a request from HTTPS to HTTP (to the less secure protocol).
 - **`"no-referrer"`** -- never send `Referer`.
 - **`"origin"`** -- only send the origin in `Referer`, not the full page URL, e.g. only `http://site.com` instead of `http://site.com/path`.
-- **`"origin-when-cross-origin"`** -- send full `Referer` to the same origin, but only the origin part for cross-origin requests (as above).
-- **`"same-origin"`** -- send full `Referer` to the same origin, but no referer for for cross-origin requests.
-- **`"strict-origin"`** -- send only origin, don't send `Referer` for HTTPS→HTTP requests.
-- **`"strict-origin-when-cross-origin"`** -- for same-origin send full `Referer`, for cross-origin send only origin, unless it's HTTPS→HTTP request, then send nothing.
-- **`"unsafe-url"`** -- always send full url in `Referer`, even for HTTPS→HTTP requests.
+- **`"origin-when-cross-origin"`** -- send the full `Referer` to the same origin, but only the origin part for cross-origin requests (as above).
+- **`"same-origin"`** -- send the full `Referer` to the same origin, but no `Referer` for cross-origin requests.
+- **`"strict-origin"`** -- send only the origin, not the `Referer` for HTTPS→HTTP requests.
+- **`"unsafe-url"`** -- always send the full url in `Referer`, even for HTTPS→HTTP requests.
 
 Here's a table with all combinations:
 
 | Value | To same origin | To another origin | HTTPS→HTTP |
 |-------|----------------|-------------------|------------|
 | `"no-referrer"` | - | - | - |
-| `"no-referrer-when-downgrade"` or `""` (default) | full | full | - |
+| `"no-referrer-when-downgrade"` | full | full | - |
 | `"origin"` | origin | origin | origin |
 | `"origin-when-cross-origin"` | full | origin | origin |
 | `"same-origin"` | full | - | - |
 | `"strict-origin"` | origin | origin | - |
-| `"strict-origin-when-cross-origin"` | full | origin | - |
+| `"strict-origin-when-cross-origin"` or `""` (default) | full | origin | - |
 | `"unsafe-url"` | full | full | full |
 
-Let's say we have an admin zone with URL structure that shouldn't be known from outside of the site.
+Let's say we have an admin zone with a URL structure that shouldn't be known from outside of the site.
 
 If we send a `fetch`, then by default it always sends the `Referer` header with the full url of our page (except when we request from HTTPS to HTTP, then no `Referer`).
 
 E.g. `Referer: https://javascript.info/admin/secret/paths`.
 
-If we'd like other websites know only the origin part, not URL-path, we can set the option:
+If we'd like other websites know only the origin part, not the URL-path, we can set the option:
 
 ```js
 fetch('https://another.com/page', {
@@ -129,7 +129,7 @@ Its only difference compared to the default behavior is that for requests to ano
 ```smart header="Referrer policy is not only for `fetch`"
 Referrer policy, described in the [specification](https://w3c.github.io/webappsec-referrer-policy/), is not just for `fetch`, but more global.
 
-In particular, it's possible to set the default policy for the whole page using `Referrer-Policy` HTTP header, or per-link, with `<a rel="noreferrer">`.
+In particular, it's possible to set the default policy for the whole page using the `Referrer-Policy` HTTP header, or per-link, with `<a rel="noreferrer">`.
 ```
 
 ## mode
@@ -138,7 +138,7 @@ The `mode` option is a safe-guard that prevents occasional cross-origin requests
 
 - **`"cors"`** -- the default, cross-origin requests are allowed, as described in <info:fetch-crossorigin>,
 - **`"same-origin"`** -- cross-origin requests are forbidden,
-- **`"no-cors"`** -- only simple cross-origin requests are allowed.
+- **`"no-cors"`** -- only safe cross-origin requests are allowed.
 
 This option may be useful when the URL for `fetch` comes from a 3rd-party, and we want a "power off switch" to limit cross-origin capabilities.
 
@@ -147,18 +147,18 @@ This option may be useful when the URL for `fetch` comes from a 3rd-party, and w
 The `credentials` option specifies whether `fetch` should send cookies and HTTP-Authorization headers with the request.
 
 - **`"same-origin"`** -- the default, don't send for cross-origin requests,
-- **`"include"`** -- always send, requires `Accept-Control-Allow-Credentials` from cross-origin server in order for JavaScript to access the response, that was covered in the chapter <info:fetch-crossorigin>,
+- **`"include"`** -- always send, requires `Access-Control-Allow-Credentials` from cross-origin server in order for JavaScript to access the response, that was covered in the chapter <info:fetch-crossorigin>,
 - **`"omit"`** -- never send, even for same-origin requests.
 
 ## cache
 
-By default, `fetch` requests make use of standard HTTP-caching. That is, it honors `Expires`, `Cache-Control` headers, sends `If-Modified-Since`, and so on. Just like regular HTTP-requests do.
+By default, `fetch` requests make use of standard HTTP-caching. That is, it respects the `Expires` and `Cache-Control` headers, sends `If-Modified-Since` and so on. Just like regular HTTP-requests do.
 
 The `cache` options allows to ignore HTTP-cache or fine-tune its usage:
 
 - **`"default"`** -- `fetch` uses standard HTTP-cache rules and headers,
 - **`"no-store"`** -- totally ignore HTTP-cache, this mode becomes the default if we set a header `If-Modified-Since`, `If-None-Match`, `If-Unmodified-Since`, `If-Match`, or `If-Range`,
-- **`"reload"`** -- don't take the result from HTTP-cache (if any), but populate cache with the response (if response headers allow),
+- **`"reload"`** -- don't take the result from HTTP-cache (if any), but populate the cache with the response (if the response headers permit this action),
 - **`"no-cache"`** -- create a conditional request if there is a cached response, and a normal request otherwise. Populate HTTP-cache with the response,
 - **`"force-cache"`** -- use a response from HTTP-cache, even if it's stale. If there's no response in HTTP-cache, make a regular HTTP-request, behave normally,
 - **`"only-if-cached"`** -- use a response from HTTP-cache, even if it's stale. If there's no response in HTTP-cache, then error. Only works when `mode` is `"same-origin"`.
@@ -171,15 +171,15 @@ The `redirect` option allows to change that:
 
 - **`"follow"`** -- the default, follow HTTP-redirects,
 - **`"error"`** -- error in case of HTTP-redirect,
-- **`"manual"`** -- don't follow HTTP-redirect, but `response.url` will be the new URL, and `response.redirected` will be `true`, so that we can perform the redirect manually to the new URL (if needed).
+- **`"manual"`** -- allows to process HTTP-redirects manually. In case of redirect, we'll get a special response object, with `response.type="opaqueredirect"` and zeroed/empty status and most other properies.
 
 ## integrity
 
 The `integrity` option allows to check if the response matches the known-ahead checksum.
 
-As described in the [specification](https://w3c.github.io/webappsec-subresource-integrity/), supported hash-functions are SHA-256, SHA-384, and SHA-512, there might be others depending on a browser.
+As described in the [specification](https://w3c.github.io/webappsec-subresource-integrity/), supported hash-functions are SHA-256, SHA-384, and SHA-512, there might be others depending on the browser.
 
-For example, we're downloading a file, and we know that it's SHA-256 checksum is "abcdef" (a real checksum is longer, of course).
+For example, we're downloading a file, and we know that its SHA-256 checksum is "abcdef" (a real checksum is longer, of course).
 
 We can put it in the `integrity` option, like this:
 
@@ -195,11 +195,11 @@ Then `fetch` will calculate SHA-256 on its own and compare it with our string. I
 
 The `keepalive` option indicates that the request may "outlive" the webpage that initiated it.
 
-For example, we gather statistics about how the current visitor uses our page (mouse clicks, page fragments he views), to analyze and improve user experience.
+For example, we gather statistics on how the current visitor uses our page (mouse clicks, page fragments he views), to analyze and improve the user experience.
 
-When the visitor leaves our page -- we'd like to save the data at our server.
+When the visitor leaves our page -- we'd like to save the data to our server.
 
-We can use `window.onunload` event for that:
+We can use the `window.onunload` event for that:
 
 ```js run
 window.onunload = function() {
@@ -213,12 +213,12 @@ window.onunload = function() {
 };
 ```
 
-Normally, when a document is unloaded, all associated network requests are aborted. But `keepalive` option tells the browser to perform the request in background, even after it leaves the page. So this option is essential for our request to succeed.
+Normally, when a document is unloaded, all associated network requests are aborted. But the `keepalive` option tells the browser to perform the request in the background, even after it leaves the page. So this option is essential for our request to succeed.
 
-It has few limitations:
+It has a few limitations:
 
-- We can't send megabytes: the body limit for `keepalive` requests is 64kb.
-    - If gather more data, we can send it out regularly in packets, so that there won't be a lot left for the last `onunload` request.
-    - The limit is for all currently ongoing requests. So we can't cheat it by creating 100 requests, each 64kb.
-- We can't handle the server response if the request is made in `onunload`, because the document is already unloaded at that time, functions won't work.
-    - Usually, the server sends empty response to such requests, so it's not a problem.
+- We can't send megabytes: the body limit for `keepalive` requests is 64KB.
+    - If we need to gather a lot of statistics about the visit, we should send it out regularly in packets, so that there won't be a lot left for the last `onunload` request.
+    - This limit applies to all `keepalive` requests together. In other words, we can perform multiple `keepalive` requests in parallel, but the sum of their body lengths should not exceed 64KB.
+- We can't handle the server response if the document is unloaded. So in our example `fetch` will succeed due to `keepalive`, but subsequent functions won't work.
+    - In most cases, such as sending out statistics, it's not a problem, as the server just accepts the data and usually sends an empty response to such requests.
diff --git a/5-network/07-url/article.md b/5-network/07-url/article.md
index b2e11b592..58b3ab1ae 100644
--- a/5-network/07-url/article.md
+++ b/5-network/07-url/article.md
@@ -3,9 +3,9 @@
 
 The built-in [URL](https://url.spec.whatwg.org/#api) class provides a convenient interface for creating and parsing URLs.
 
-There are no networking methods that require exactly an `URL` object, strings are good enough. So technically we don't have to use `URL`. But sometimes it can be really helpful.
+There are no networking methods that require exactly a `URL` object, strings are good enough. So technically we don't have to use `URL`. But sometimes it can be really helpful.
 
-## Creating an URL
+## Creating a URL
 
 The syntax to create a new `URL` object:
 
@@ -63,14 +63,14 @@ Here's the cheatsheet for URL components:
 
 
 ```smart header="We can pass `URL` objects to networking (and most other) methods instead of a string"
-We can use an `URL` object in `fetch` or `XMLHttpRequest`, almost everywhere where an URL-string is expected.
+We can use a `URL` object in `fetch` or `XMLHttpRequest`, almost everywhere where a URL-string is expected.
 
-Generally, `URL` object can be passed to any method instead of a string, as most method will perform the string conversion, that turns an `URL` object into a string with full URL.
+Generally, the `URL` object can be passed to any method instead of a string, as most methods will perform the string conversion, that turns a `URL` object into a string with full URL.
 ```
 
 ## SearchParams "?..."
 
-Let's say we want to create an url with given search params, for instance, `https://google.com/search?query=JavaScript`.
+Let's say we want to create a url with given search params, for instance, `https://google.com/search?query=JavaScript`.
 
 We can provide them in the URL string:
 
@@ -80,7 +80,7 @@ new URL('https://google.com/search?query=JavaScript')
 
 ...But parameters need to be encoded if they contain spaces, non-latin letters, etc (more about that below).
 
-So there's URL property for that: `url.searchParams`, an object of type [URLSearchParams](https://url.spec.whatwg.org/#urlsearchparams).
+So there's a URL property for that: `url.searchParams`, an object of type [URLSearchParams](https://url.spec.whatwg.org/#urlsearchparams).
 
 It provides convenient methods for search parameters:
 
@@ -88,7 +88,7 @@ It provides convenient methods for search parameters:
 - **`delete(name)`** -- remove the parameter by `name`,
 - **`get(name)`** -- get the parameter by `name`,
 - **`getAll(name)`** -- get all parameters with the same `name` (that's possible, e.g. `?user=John&user=Pete`),
-- **`has(name)`** -- check for the existance of the parameter by `name`,
+- **`has(name)`** -- check for the existence of the parameter by `name`,
 - **`set(name, value)`** -- set/replace the parameter,
 - **`sort()`** -- sort parameters by name, rarely needed,
 - ...and it's also iterable, similar to `Map`.
@@ -145,10 +145,10 @@ If we use a string though, we need to encode/decode special characters manually.
 
 There are built-in functions for that:
 
-- [encodeURI](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI) - encodes URL as a whole.
-- [decodeURI](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURI) - decodes it back.
-- [encodeURIComponent](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent) - encodes a URL component, such as a search parameter, or a hash, or a pathname.
-- [decodeURIComponent](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent) - decodes it back.
+- [encodeURI](mdn:/JavaScript/Reference/Global_Objects/encodeURI) - encodes URL as a whole.
+- [decodeURI](mdn:/JavaScript/Reference/Global_Objects/decodeURI) - decodes it back.
+- [encodeURIComponent](mdn:/JavaScript/Reference/Global_Objects/encodeURIComponent) - encodes a URL component, such as a search parameter, or a hash, or a pathname.
+- [decodeURIComponent](mdn:/JavaScript/Reference/Global_Objects/decodeURIComponent) - decodes it back.
 
 A natural question is: "What's the difference between `encodeURIComponent` and `encodeURI`? When we should use either?"
 
@@ -201,7 +201,7 @@ So we should use only `encodeURIComponent` for each search parameter, to correct
 ````smart header="Encoding difference compared to `URL`"
 Classes [URL](https://url.spec.whatwg.org/#url-class) and [URLSearchParams](https://url.spec.whatwg.org/#interface-urlsearchparams) are based on the latest URI specification: [RFC3986](https://tools.ietf.org/html/rfc3986), while `encode*` functions are based on the obsolete version [RFC2396](https://www.ietf.org/rfc/rfc2396.txt).
 
-There are few differences, e.g. IPv6 addresses are encoded differently:
+There are a few differences, e.g. IPv6 addresses are encoded differently:
 
 ```js run
 // valid url with IPv6 address
diff --git a/5-network/08-xmlhttprequest/article.md b/5-network/08-xmlhttprequest/article.md
index 51e9625a9..43d816cab 100644
--- a/5-network/08-xmlhttprequest/article.md
+++ b/5-network/08-xmlhttprequest/article.md
@@ -2,7 +2,7 @@
 
 `XMLHttpRequest` is a built-in browser object that allows to make HTTP requests in JavaScript.
 
-Despite of having the word "XML" in its name, it can operate on any data, not only in XML format. We can upload/download files, track progress and much more.
+Despite having the word "XML" in its name, it can operate on any data, not only in XML format. We can upload/download files, track progress and much more.
 
 Right now, there's another, more modern method `fetch`, that somewhat deprecates `XMLHttpRequest`.
 
@@ -93,7 +93,7 @@ xhr.onload = function() {
   if (xhr.status != 200) { // analyze HTTP status of the response
     alert(`Error ${xhr.status}: ${xhr.statusText}`); // e.g. 404: Not Found
   } else { // show the result
-    alert(`Done, got ${xhr.response.length} bytes`); // responseText is the server
+    alert(`Done, got ${xhr.response.length} bytes`); // response is the server response
   }
 };
 
@@ -151,7 +151,7 @@ We can use `xhr.responseType` property to set the response format:
 - `"text"` -- get as string,
 - `"arraybuffer"` -- get as `ArrayBuffer` (for binary data, see chapter <info:arraybuffer-binary-arrays>),
 - `"blob"` -- get as `Blob` (for binary data, see chapter <info:blob>),
-- `"document"` -- get as XML document (can use XPath and other XML methods),
+- `"document"` -- get as XML document (can use XPath and other XML methods) or HTML document (based on the MIME type of the received data),
 - `"json"` -- get as JSON (parsed automatically).
 
 For example, let's get the response as JSON:
@@ -190,7 +190,7 @@ All states, as in [the specification](https://xhr.spec.whatwg.org/#states):
 UNSENT = 0; // initial state
 OPENED = 1; // open called
 HEADERS_RECEIVED = 2; // response headers received
-LOADING = 3; // response is loading (a data packed is received)
+LOADING = 3; // response is loading (a data packet is received)
 DONE = 4; // request complete
 ```
 
@@ -269,7 +269,7 @@ There are 3 methods for HTTP-headers:
 
     ```warn header="Headers limitations"
     Several headers are managed exclusively by the browser, e.g. `Referer` and `Host`.
-    The full list is [in the specification](http://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader-method).
+    The full list is [in the specification](https://xhr.spec.whatwg.org/#the-setrequestheader()-method).
 
     `XMLHttpRequest` is not allowed to change them, for the sake of user safety and correctness of the request.
     ```
@@ -332,7 +332,7 @@ There are 3 methods for HTTP-headers:
 
 ## POST, FormData
 
-To make a POST request, we can use the built-in [FormData](https://developer.mozilla.org/en-US/docs/Web/API/FormData) object.
+To make a POST request, we can use the built-in [FormData](mdn:api/FormData) object.
 
 The syntax:
 
@@ -509,10 +509,10 @@ xhr.onerror = function() {
 };
 ```
 
-There are actually more events, the [modern specification](http://www.w3.org/TR/XMLHttpRequest/#events) lists them (in the lifecycle order):
+There are actually more events, the [modern specification](https://xhr.spec.whatwg.org/#events) lists them (in the lifecycle order):
 
 - `loadstart` -- the request has started.
-- `progress` -- a data packet of the response has arrived, the whole response body at the moment is in `responseText`.
+- `progress` -- a data packet of the response has arrived, the whole response body at the moment is in `response`.
 - `abort` -- the request was canceled by the call `xhr.abort()`.
 - `error` -- connection error has occurred, e.g. wrong domain name. Doesn't happen for HTTP-errors like 404.
 - `load` -- the request has finished successfully.
diff --git a/5-network/09-resume-upload/article.md b/5-network/09-resume-upload/article.md
index 1164a1a98..b0aa447d6 100644
--- a/5-network/09-resume-upload/article.md
+++ b/5-network/09-resume-upload/article.md
@@ -24,7 +24,7 @@ To resume upload, we need to know *exactly* the number of bytes received by the
 
 1. First, create a file id, to uniquely identify the file we're going to upload:
     ```js
-    let fileId = file.name + '-' + file.size + '-' + +file.lastModifiedDate;
+    let fileId = file.name + '-' + file.size + '-' + file.lastModified;
     ```
     That's needed for resume upload, to tell the server what we're resuming.
 
@@ -44,11 +44,11 @@ To resume upload, we need to know *exactly* the number of bytes received by the
 
     This assumes that the server tracks file uploads by `X-File-Id` header. Should be implemented at server-side.
 
-    If the file don't yet exist at the server, then the server response should be `0`
+    If the file doesn't yet exist at the server, then the server response should be `0`
 
 3. Then, we can use `Blob` method `slice` to send the file from `startByte`:
     ```js
-    xhr.open("POST", "upload", true);
+    xhr.open("POST", "upload");
 
     // File id, so that the server knows which file we upload
     xhr.setRequestHeader('X-File-Id', fileId);
diff --git a/5-network/09-resume-upload/upload-resume.view/uploader.js b/5-network/09-resume-upload/upload-resume.view/uploader.js
index 2e53ce4a3..10002039c 100644
--- a/5-network/09-resume-upload/upload-resume.view/uploader.js
+++ b/5-network/09-resume-upload/upload-resume.view/uploader.js
@@ -6,7 +6,7 @@ class Uploader {
 
     // create fileId that uniquely identifies the file
     // we could also add user session identifier (if had one), to make it even more unique
-    this.fileId = file.name + '-' + file.size + '-' + +file.lastModifiedDate;
+    this.fileId = file.name + '-' + file.size + '-' + file.lastModified;
   }
 
   async getUploadedBytes() {
diff --git a/5-network/10-long-polling/article.md b/5-network/10-long-polling/article.md
index 68eec844e..e9d8abe39 100644
--- a/5-network/10-long-polling/article.md
+++ b/5-network/10-long-polling/article.md
@@ -1,12 +1,12 @@
 # Long polling
 
-Long polling is the simplest way of having persistent connection with server, that doesn't use any specific protocol like WebSocket or Server Side Events.
+Long polling is the simplest way of having persistent connection with server, that doesn't use any specific protocol like WebSocket or Server Sent Events.
 
 Being very easy to implement, it's also good enough in a lot of cases.
 
 ## Regular Polling
 
-The simplest way to get new information from the server is periodic polling. That is, regular requests to the server: "Hello, I'm here, do you have any information for me?". For example, once in 10 seconds.
+The simplest way to get new information from the server is periodic polling. That is, regular requests to the server: "Hello, I'm here, do you have any information for me?". For example, once every 10 seconds.
 
 In response, the server first takes a notice to itself that the client is online, and second - sends a packet of messages it got till that moment.
 
@@ -29,7 +29,7 @@ The flow:
 3. When a message appears - the server responds to the request with it.
 4. The browser makes a new request immediately.
 
-The situation when the browser sent a request and has a pending connection with the server, is standard for this method. Only when a message is delivered, the connection is reestablished.
+This situation, where the browser has sent a request and keeps a pending connection with the server, is standard for this method. Only when a message is delivered, the connection is closed and reestablished.
 
 ![](long-polling.svg)
 
@@ -70,11 +70,13 @@ As you can see, `subscribe` function makes a fetch, then waits for the response,
 ```warn header="Server should be ok with many pending connections"
 The server architecture must be able to work with many pending connections.
 
-Certain server architectures run a process per connect. For many connections there will be as many processes, and each process takes a lot of memory. So many connections just consume it all.
+Certain server architectures run one process per connection, resulting in there being as many processes as there are connections, while each process consumes quite a bit of memory. So, too many connections will just consume it all.
 
-That's often the case for backends written in PHP, Ruby languages, but technically isn't a language, but rather implementation issue. Most modern language allow to implement a proper backend, but some of them make it easier than the other.
+That's often the case for backends written in languages like PHP and Ruby.
 
-Backends written using Node.js usually don't have such problems.
+Servers written using Node.js usually don't have such problems.
+
+That said, it isn't a programming language issue. Most modern languages, including PHP and Ruby allow to implement a proper backend. Just please make sure that your server architecture works fine with many simultaneous connections.
 ```
 
 ## Demo: a chat
diff --git a/5-network/11-websocket/article.md b/5-network/11-websocket/article.md
index eab41b18f..268b674f0 100644
--- a/5-network/11-websocket/article.md
+++ b/5-network/11-websocket/article.md
@@ -1,6 +1,6 @@
 # WebSocket
 
-The `WebSocket` protocol, described in the specification [RFC 6455](http://tools.ietf.org/html/rfc6455) provides a way to exchange data between browser and server via a persistent connection. The data can be passed in both directions as "packets", without breaking the connection and additional HTTP-requests.
+The `WebSocket` protocol, described in the specification [RFC 6455](https://datatracker.ietf.org/doc/html/rfc6455), provides a way to exchange data between browser and server via a persistent connection. The data can be passed in both directions as "packets", without breaking the connection and the need of additional HTTP-requests.
 
 WebSocket is especially great for services that require continuous data exchange, e.g. online games, real-time trading systems and so on.
 
@@ -15,11 +15,11 @@ let socket = new WebSocket("*!*ws*/!*://javascript.info");
 There's also encrypted `wss://` protocol. It's like HTTPS for websockets.
 
 ```smart header="Always prefer `wss://`"
-The `wss://` protocol not only encrypted, but also more reliable.
+The `wss://` protocol is not only encrypted, but also more reliable.
 
 That's because `ws://` data is not encrypted, visible for any intermediary. Old proxy servers do not know about WebSocket, they may see "strange" headers and abort the connection.
 
-On the other hand, `wss://` is WebSocket over TLS, (same as HTTPS is HTTP over TLS), the transport security layer encrypts the data at sender and decrypts at the receiver. So data packets are passed encrypted through proxies. They can't see what's inside and let them through.
+On the other hand, `wss://` is WebSocket over TLS, (same as HTTPS is HTTP over TLS), the transport security layer encrypts the data at the sender and decrypts it at the receiver. So data packets are passed encrypted through proxies. They can't see what's inside and let them through.
 ```
 
 Once the socket is created, we should listen to events on it. There are totally 4 events:
@@ -56,7 +56,7 @@ socket.onclose = function(event) {
 };
 
 socket.onerror = function(error) {
-  alert(`[error] ${error.message}`);
+  alert(`[error]`);
 };
 ```
 
@@ -72,11 +72,11 @@ Now let's talk more in-depth.
 
 When `new WebSocket(url)` is created, it starts connecting immediately.
 
-During the connection the browser (using headers) asks the server: "Do you support Websocket?" And if the server replies "yes", then the talk continues in WebSocket protocol, which is not HTTP at all.
+During the connection, the browser (using headers) asks the server: "Do you support Websocket?" And if the server replies "yes", then the talk continues in WebSocket protocol, which is not HTTP at all.
 
 ![](websocket-handshake.svg)
 
-Here's an example of browser headers for request made by `new WebSocket("wss://javascript.info/chat")`.
+Here's an example of browser headers for a request made by `new WebSocket("wss://javascript.info/chat")`.
 
 ```
 GET /chat
@@ -88,10 +88,10 @@ Sec-WebSocket-Key: Iv8io/9s+lYFgZWcXczP8Q==
 Sec-WebSocket-Version: 13
 ```
 
-- `Origin` -- the origin of the client page, e.g. `https://javascript.info`. WebSocket objects are cross-origin by nature. There are no special headers or other limitations. Old servers are unable to handle WebSocket anyway, so there are no compabitility issues. But `Origin` header is important, as it allows the server to decide whether or not to talk WebSocket with this website.
+- `Origin` -- the origin of the client page, e.g. `https://javascript.info`. WebSocket objects are cross-origin by nature. There are no special headers or other limitations. Old servers are unable to handle WebSocket anyway, so there are no compatibility issues. But the `Origin` header is important, as it allows the server to decide whether or not to talk WebSocket with this website.
 - `Connection: Upgrade` -- signals that the client would like to change the protocol.
 - `Upgrade: websocket` -- the requested protocol is "websocket".
-- `Sec-WebSocket-Key` -- a random browser-generated key for security.
+- `Sec-WebSocket-Key` -- a random browser-generated key, used to ensure that the server supports WebSocket protocol. It's random to prevent proxies from caching any following communication.
 - `Sec-WebSocket-Version` -- WebSocket protocol version, 13 is the current one.
 
 ```smart header="WebSocket handshake can't be emulated"
@@ -107,9 +107,9 @@ Connection: Upgrade
 Sec-WebSocket-Accept: hsBlbuDTkk24srzEOTBUlZAlC2g=
 ```
 
-Here `Sec-WebSocket-Accept` is `Sec-WebSocket-Key`, recoded using a special algorithm. The browser uses it to make sure that the response corresponds to the request.
+Here `Sec-WebSocket-Accept` is `Sec-WebSocket-Key`, recoded using a special algorithm. Upon seeing it, the browser understands that the server really does support the WebSocket protocol.
 
-Afterwards, the data is transfered using WebSocket protocol, we'll see its structure ("frames") soon. And that's not HTTP at all.
+Afterwards, the data is transferred using the WebSocket protocol, we'll see its structure ("frames") soon. And that's not HTTP at all.
 
 ### Extensions and subprotocols
 
@@ -117,9 +117,9 @@ There may be additional headers `Sec-WebSocket-Extensions` and `Sec-WebSocket-Pr
 
 For instance:
 
-- `Sec-WebSocket-Extensions: deflate-frame` means that the browser supports data compression. An extension is something related to transferring the data, functionality that extends WebSocket protocol. The header `Sec-WebSocket-Extensions` is sent automatically by the browser, with the list of all extenions it supports.
+- `Sec-WebSocket-Extensions: deflate-frame` means that the browser supports data compression. An extension is something related to transferring the data, functionality that extends the WebSocket protocol. The header `Sec-WebSocket-Extensions` is sent automatically by the browser, with the list of all extensions it supports.
 
-- `Sec-WebSocket-Protocol: soap, wamp` means that we'd like to transfer not just any data, but the data in [SOAP](http://en.wikipedia.org/wiki/SOAP) or WAMP ("The WebSocket Application Messaging Protocol") protocols. WebSocket subprotocols are registered in the [IANA catalogue](http://www.iana.org/assignments/websocket/websocket.xml). So, this header describes data formats that we're going to use.
+- `Sec-WebSocket-Protocol: soap, wamp` means that we'd like to transfer not just any data, but the data in [SOAP](https://en.wikipedia.org/wiki/SOAP) or WAMP ("The WebSocket Application Messaging Protocol") protocols. WebSocket subprotocols are registered in the [IANA catalogue](https://www.iana.org/assignments/websocket/websocket.xml). So, this header describes the data formats that we're going to use.
 
     This optional header is set using the second parameter of `new WebSocket`. That's the array of subprotocols, e.g. if we'd like to use SOAP or WAMP:
 
@@ -173,16 +173,16 @@ In the browser, we directly work only with text or binary frames.
 
 **WebSocket `.send()` method can send either text or binary data.**
 
-A call `socket.send(body)` allows `body` in string or a binary format, including `Blob`, `ArrayBuffer`, etc. No settings required: just send it out in any format.
+A call `socket.send(body)` allows `body` in string or a binary format, including `Blob`, `ArrayBuffer`, etc. No settings are required: just send it out in any format.
 
 **When we receive the data, text always comes as string. And for binary data, we can choose between `Blob` and `ArrayBuffer` formats.**
 
-That's set by `socket.bufferType` property, it's `"blob"` by default, so binary data comes as `Blob` objects.
+That's set by `socket.binaryType` property, it's `"blob"` by default, so binary data comes as `Blob` objects.
 
 [Blob](info:blob) is a high-level binary object, it directly integrates with `<a>`, `<img>` and other tags, so that's a sane default. But for binary processing, to access individual data bytes, we can change it to `"arraybuffer"`:
 
 ```js
-socket.bufferType = "arraybuffer";
+socket.binaryType = "arraybuffer";
 socket.onmessage = (event) => {
   // event.data is either a string (if text) or arraybuffer (if binary)
 };
@@ -194,7 +194,7 @@ Imagine, our app is generating a lot of data to send. But the user has a slow ne
 
 We can call `socket.send(data)` again and again. But the data will be buffered (stored) in memory and sent out only as fast as network speed allows.
 
-The `socket.bufferedAmount` property stores how many bytes are buffered at this moment, waiting to be sent over the network.
+The `socket.bufferedAmount` property stores how many bytes remain buffered at this moment, waiting to be sent over the network.
 
 We can examine it to see whether the socket is actually available for transmission.
 
@@ -221,7 +221,7 @@ socket.close([code], [reason]);
 - `code` is a special WebSocket closing code (optional)
 - `reason` is a string that describes the reason of closing (optional)
 
-Then the other party in `close` event handler gets the code and the reason, e.g.:
+Then the other party in the `close` event handler gets the code and the reason, e.g.:
 
 ```js
 // closing party:
@@ -238,7 +238,7 @@ socket.onclose = event => {
 Most common code values:
 
 - `1000` -- the default, normal closure (used if no `code` supplied),
-- `1006` -- no way to such code manually, indicates that the connection was lost (no close frame).
+- `1006` -- no way to set such code manually, indicates that the connection was lost (no close frame).
 
 There are other codes like:
 
@@ -249,7 +249,7 @@ There are other codes like:
 
 The full list can be found in [RFC6455, §7.4.1](https://tools.ietf.org/html/rfc6455#section-7.4.1).
 
-WebSocket codes are somewhat like HTTP codes, but different. In particular, any codes less than `1000` are reserved, there'll be an error if we try to set such a code.
+WebSocket codes are somewhat like HTTP codes, but different. In particular, codes lower than `1000` are reserved, there'll be an error if we try to set such a code.
 
 ```js
 // in case connection is broken
@@ -321,8 +321,8 @@ Server-side code is a little bit beyond our scope. Here we'll use Node.js, but y
 The server-side algorithm will be:
 
 1. Create `clients = new Set()` -- a set of sockets.
-2. For each accepted websocket, add it to the set `clients.add(socket)` and setup `message` event listener to get its messages.
-3. When a message received: iterate over clients and send it to everyone.
+2. For each accepted websocket, add it to the set `clients.add(socket)` and set `message` event listener to get its messages.
+3. When a message is received: iterate over clients and send it to everyone.
 4. When a connection is closed: `clients.delete(socket)`.
 
 ```js
@@ -359,7 +359,7 @@ Here's the working example:
 
 [iframe src="chat" height="100" zip]
 
-You can also download it (upper-right button in the iframe) and run locally. Just don't forget to install [Node.js](https://nodejs.org/en/) and `npm install ws` before running.
+You can also download it (upper-right button in the iframe) and run it locally. Just don't forget to install [Node.js](https://nodejs.org/en/) and `npm install ws` before running.
 
 ## Summary
 
@@ -383,6 +383,6 @@ Events:
 
 WebSocket by itself does not include reconnection, authentication and many other high-level mechanisms. So there are client/server libraries for that, and it's also possible to implement these capabilities manually.
 
-Sometimes, to integrate WebSocket into existing project, people run WebSocket server in parallel with the main HTTP-server, and they share a single database. Requests to WebSocket use `wss://ws.site.com`, a subdomain that leads to WebSocket server, while `https://site.com` goes to the main HTTP-server.
+Sometimes, to integrate WebSocket into existing projects, people run a WebSocket server in parallel with the main HTTP-server, and they share a single database. Requests to WebSocket use `wss://ws.site.com`, a subdomain that leads to the WebSocket server, while `https://site.com` goes to the main HTTP-server.
 
 Surely, other ways of integration are also possible.
diff --git a/5-network/11-websocket/demo.view/server.js b/5-network/11-websocket/demo.view/server.js
index 111a7ce75..bff739938 100644
--- a/5-network/11-websocket/demo.view/server.js
+++ b/5-network/11-websocket/demo.view/server.js
@@ -21,6 +21,7 @@ function accept(req, res) {
 
 function onConnect(ws) {
   ws.on('message', function (message) {
+    message = message.toString();
     let name = message.match(/([\p{Alpha}\p{M}\p{Nd}\p{Pc}\p{Join_C}]+)$/gu) || "Guest";
     ws.send(`Hello from server, ${name}!`);
 
diff --git a/5-network/12-server-sent-events/article.md b/5-network/12-server-sent-events/article.md
index f6fd8dbdf..c59d671a4 100644
--- a/5-network/12-server-sent-events/article.md
+++ b/5-network/12-server-sent-events/article.md
@@ -66,7 +66,7 @@ eventSource.onmessage = function(event) {
 
 ### Cross-origin requests
 
-`EventSource` supports cross-origin requests, like `fetch` any other networking methods. We can use any URL:
+`EventSource` supports cross-origin requests, like `fetch` and any other networking methods. We can use any URL:
 
 ```js
 let source = new EventSource("https://another-site.com/events");
@@ -215,7 +215,7 @@ It offers:
 - Message ids to resume events, the last received identifier is sent in `Last-Event-ID` header upon reconnection.
 - The current state is in the `readyState` property.
 
-That makes `EventSource` a viable alternative to `WebSocket`, as it's more low-level and lacks such built-in features (though they can be implemented).
+That makes `EventSource` a viable alternative to `WebSocket`, as the latter is more low-level and lacks such built-in features (though they can be implemented).
 
 In many real-life applications, the power of `EventSource` is just enough.
 
diff --git a/5-network/12-server-sent-events/eventsource.view/server.js b/5-network/12-server-sent-events/eventsource.view/server.js
index 34c7b1253..ad279aaab 100644
--- a/5-network/12-server-sent-events/eventsource.view/server.js
+++ b/5-network/12-server-sent-events/eventsource.view/server.js
@@ -1,6 +1,8 @@
 let http = require('http');
 let url = require('url');
 let querystring = require('querystring');
+let static = require('node-static');
+let fileServer = new static.Server('.');
 
 function onDigits(req, res) {
   res.writeHead(200, {
@@ -36,7 +38,6 @@ function accept(req, res) {
   }
 
   fileServer.serve(req, res);
-
 }
 
 
diff --git a/6-data-storage/01-cookie/article.md b/6-data-storage/01-cookie/article.md
index ba1ffa71b..1b9e93414 100644
--- a/6-data-storage/01-cookie/article.md
+++ b/6-data-storage/01-cookie/article.md
@@ -1,18 +1,18 @@
 # Cookies, document.cookie
 
-Cookies are small strings of data that are stored directly in the browser. They are a part of HTTP protocol, defined by [RFC 6265](https://tools.ietf.org/html/rfc6265) specification.
+Cookies are small strings of data that are stored directly in the browser. They are a part of the HTTP protocol, defined by the [RFC 6265](https://tools.ietf.org/html/rfc6265) specification.
 
-Cookies are usually set by a web-server using response `Set-Cookie` HTTP-header. Then the browser automatically adds them to (almost) every request to the same domain using `Cookie` HTTP-header.
+Cookies are usually set by a web server using the response `Set-Cookie` HTTP header. Then, the browser automatically adds them to (almost) every request to the same domain using the `Cookie` HTTP header.
 
 One of the most widespread use cases is authentication:
 
-1. Upon sign in, the server uses `Set-Cookie` HTTP-header in the response to set a cookie with a unique "session identifier".
-2. Next time when the request is set to the same domain, the browser sends the cookie over the net using `Cookie` HTTP-header.
+1. Upon sign-in, the server uses the `Set-Cookie` HTTP header in the response to set a cookie with a unique "session identifier".
+2. Next time the request is sent to the same domain, the browser sends the cookie over the net using the `Cookie` HTTP header.
 3. So the server knows who made the request.
 
 We can also access cookies from the browser, using `document.cookie` property.
 
-There are many tricky things about cookies and their options. In this chapter we'll cover them in detail.
+There are many tricky things about cookies and their attributes. In this chapter, we'll cover them in detail.
 
 ## Reading from document.cookie
 
@@ -31,17 +31,17 @@ alert( document.cookie ); // cookie1=value1; cookie2=value2;...
 ```
 
 
-The value of `document.cookie` consists of `name=value` pairs, delimited by `; `. Each one is a separate cookie.
+The value of `document.cookie` consists of `name=value` pairs, delimited by `; `. Each one is a separate cookie.
 
-To find a particular cookie, we can split `document.cookie` by `; `, and then find the right name. We can use either a regular expression or array functions to do that.
+To find a particular cookie, we can split `document.cookie` by `; `, and then find the right name. We can use either a regular expression or array functions to do that.
 
-We leave it as an exercise for the reader. Also, at the end of the chapter you'll find helper functions to manipulate cookies.
+We leave it as an exercise for the reader. Also, at the end of the chapter, you'll find helper functions to manipulate cookies.
 
 ## Writing to document.cookie
 
-We can write to `document.cookie`. But it's not a data property, it's an accessor (getter/setter). An assignment to it is treated specially.
+We can write to `document.cookie`. But it's not a data property, it's an [accessor (getter/setter)](info:property-accessors). An assignment to it is treated specially.
 
-**A write operation to `document.cookie` updates only cookies mentioned in it, but doesn't touch other cookies.**
+**A write operation to `document.cookie` updates only the cookie mentioned in it and doesn't touch other cookies.**
 
 For instance, this call sets a cookie with the name `user` and value `John`:
 
@@ -50,12 +50,12 @@ document.cookie = "user=John"; // update only cookie named 'user'
 alert(document.cookie); // show all cookies
 ```
 
-If you run it, then probably you'll see multiple cookies. That's because `document.cookie=` operation does not overwrite all cookies. It only sets the mentioned cookie `user`.
+If you run it, you will likely see multiple cookies. That's because the `document.cookie=` operation does not overwrite all cookies. It only sets the mentioned cookie `user`.
 
-Technically, name and value can have any characters, to keep the valid formatting they should be escaped using a built-in `encodeURIComponent` function:
+Technically, name and value can have any characters. To keep the valid formatting, they should be escaped using a built-in `encodeURIComponent` function:
 
 ```js run
-// special characters (spaces), need encoding
+// special characters (spaces) need encoding
 let name = "my name";
 let value = "John Smith"
 
@@ -67,57 +67,52 @@ alert(document.cookie); // ...; my%20name=John%20Smith
 
 
 ```warn header="Limitations"
-There are few limitations:
-- The `name=value` pair, after `encodeURIComponent`, should not exceed 4kb. So we can't store anything huge in a cookie.
-- The total number of cookies per domain is limited to around 20+, the exact limit depends on a browser.
+There are a few limitations:
+- You can only set/update a single cookie at a time using `document.cookie`.
+- The `name=value` pair, after `encodeURIComponent`, should not exceed 4KB. So we can't store anything huge in a cookie.
+- The total number of cookies per domain is limited to around 20+, the exact limit depends on the browser.
 ```
 
-Cookies have several options, many of them are important and should be set.
+Cookies have several attributes, many of which are important and should be set.
 
-The options are listed after `key=value`, delimited by `;`, like this:
+The attributes are listed after `key=value`, delimited by `;`, like this:
 
 ```js run
 document.cookie = "user=John; path=/; expires=Tue, 19 Jan 2038 03:14:07 GMT"
 ```
 
-## path
-
-- **`path=/mypath`**
-
-The url path prefix, the cookie will be accessible for pages under that path. Must be absolute. By default, it's the current path.
-
-If a cookie is set with `path=/admin`, it's visible at pages `/admin` and `/admin/something`, but not at `/home` or `/adminpage`.
-
-Usually, we should set `path` to the root: `path=/` to make the cookie accessible from all website pages.
-
 ## domain
 
 - **`domain=site.com`**
 
-A domain where the cookie is accessible. In practice though, there are limitations. We can't set any domain.
+A domain defines where the cookie is accessible. In practice though, there are limitations. We can't set any domain.
 
-By default, a cookie is accessible only at the domain that set it. So, if the cookie was set by `site.com`, we won't get it `other.com`.
+**There's no way to let a cookie be accessible from another 2nd-level domain, so `other.com` will never receive a cookie set at `site.com`.**
+
+It's a safety restriction, to allow us to store sensitive data in cookies that should be available only on one site.
+
+By default, a cookie is accessible only at the domain that set it.
 
-...But what's more tricky, we also won't get the cookie at a subdomain `forum.site.com`!
+Please note, by default, a cookie is not shared with a subdomain, such as `forum.site.com`.
 
 ```js
-// at site.com
+// if we set a cookie at site.com website...
 document.cookie = "user=John"
 
-// at forum.site.com
+// ...we won't see it at forum.site.com
 alert(document.cookie); // no user
 ```
 
-**There's no way to let a cookie be accessible from another 2nd-level domain, so `other.com` will never receive a cookie set at `site.com`.**
+...But this can be changed. If we'd like to allow subdomains like `forum.site.com` to get a cookie set at `site.com`, that's possible.
 
-It's a safety restriction, to allow us to store sensitive data in cookies, that should be available only on one site.
+For that to happen, when setting a cookie at `site.com`, we should explicitly set the `domain` attribute to the root domain: `domain=site.com`. Then all subdomains will see such a cookie.
 
-...But if we'd like to allow subdomains like `forum.site.com` get a cookie, that's possible. When setting a cookie at `site.com`, we should explicitly set `domain` option to the root domain: `domain=site.com`:
+For example:
 
 ```js
 // at site.com
 // make the cookie accessible on any subdomain *.site.com:
-document.cookie = "user=John; domain=site.com"
+document.cookie = "user=John; *!*domain=site.com*/!*"
 
 // later
 
@@ -125,21 +120,33 @@ document.cookie = "user=John; domain=site.com"
 alert(document.cookie); // has cookie user=John
 ```
 
-For historical reasons, `domain=.site.com` (a dot before `site.com`) also works the same way, allowing access to the cookie from subdomains. That's an old notation, should be used if we need to support very old browsers.
+```warn header="Legacy syntax"
+Historically, `domain=.site.com` (with a dot before `site.com`) used to work the same way, allowing access to the cookie from subdomains. Leading dots in domain names are now ignored, but some browsers may decline to set the cookie containing such dots.
+```
+
+To summarize, the `domain` attribute allows to make a cookie accessible at subdomains.
+
+## path
+
+- **`path=/mypath`**
+
+The URL path prefix must be absolute. It makes the cookie accessible for pages under that path. By default, it's the current path.
 
-So, `domain` option allows to make a cookie accessible at subdomains.
+If a cookie is set with `path=/admin`, it's visible on pages `/admin` and `/admin/something`, but not at `/home`, `/home/admin` or `/`.
+
+Usually, we should set `path` to the root: `path=/` to make the cookie accessible from all website pages. If this attribute is not set the default is calculated using [this method](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#path_default_value).
 
 ## expires, max-age
 
-By default, if a cookie doesn't have one of these options, it disappears when the browser is closed. Such cookies are called "session cookies"
+By default, if a cookie doesn't have one of these attributes, it disappears when the browser/tab is closed. Such cookies are called "session cookies"
 
-To let cookies survive browser close, we can set either `expires` or `max-age` option.
+To let cookies survive a browser close, we can set either the `expires` or `max-age` attribute. `max-Age` has precedence if both are set.
 
 - **`expires=Tue, 19 Jan 2038 03:14:07 GMT`**
 
-Cookie expiration date, when the browser will delete it automatically.
+The cookie expiration date defines the time when the browser will automatically delete it (according to the browser's time zone).
 
-The date must be exactly in this format, in GMT timezone. We can use `date.toUTCString` to get it. For instance, we can set the cookie to expire in 1 day:
+The date must be exactly in this format, in the GMT timezone. We can use `date.toUTCString` to get it. For instance, we can set the cookie to expire in 1 day:
 
 ```js
 // +1 day from now
@@ -152,17 +159,17 @@ If we set `expires` to a date in the past, the cookie is deleted.
 
 -  **`max-age=3600`**
 
-An alternative to `expires`, specifies the cookie expiration in seconds from the current moment.
+It's an alternative to `expires` and specifies the cookie's expiration in seconds from the current moment.
 
-If zero or negative, then the cookie is deleted:
+If set to zero or a negative value, the cookie is deleted:
 
 ```js
-// cookie will die +1 hour from now
+// cookie will die in +1 hour from now
 document.cookie = "user=John; max-age=3600";
 
 // delete cookie (let it expire right now)
 document.cookie = "user=John; max-age=0";
-```  
+```
 
 ## secure
 
@@ -174,98 +181,101 @@ The cookie should be transferred only over HTTPS.
 
 That is, cookies are domain-based, they do not distinguish between the protocols.
 
-With this option, if a cookie is set by `https://site.com`, then it doesn't appear when the same site is accessed by HTTP, as `http://site.com`. So if a cookie has sensitive content that should never be sent over unencrypted HTTP, then the flag is the right thing.
+With this attribute, if a cookie is set by `https://site.com`, then it doesn't appear when the same site is accessed by HTTP, as `http://site.com`. So if a cookie has sensitive content that should never be sent over unencrypted HTTP, the `secure` flag is the right thing.
 
 ```js
 // assuming we're on https:// now
-// set the cookie secure (only accessible if over HTTPS)
+// set the cookie to be secure (only accessible over HTTPS)
 document.cookie = "user=John; secure";
-```  
+```
 
 ## samesite
 
-That's another security attribute `samesite`. It's designed to protect from so-called XSRF (cross-site request forgery) attacks.
+This is another security attribute `samesite`. It's designed to protect from so-called XSRF (cross-site request forgery) attacks.
 
 To understand how it works and when it's useful, let's take a look at XSRF attacks.
 
 ### XSRF attack
 
-Imagine, you are logged into the site `bank.com`. That is: you have an authentication cookie from that site. Your browser sends it to `bank.com` with every request, so that it recognizes you and performs all sensitive financial operations.
+Imagine, you are logged into the site `bank.com`. That is: you have an authentication cookie from that site. Your browser sends it to `bank.com` with every request so that it recognizes you and performs all sensitive financial operations.
 
 Now, while browsing the web in another window, you accidentally come to another site `evil.com`. That site has JavaScript code that submits a form `<form action="https://bank.com/pay">` to `bank.com` with fields that initiate a transaction to the hacker's account.
 
-The browser sends cookies every time you visit the site `bank.com`, even if the form was submitted from `evil.com`. So the bank recognizes you and actually performs the payment.
+The browser sends cookies every time you visit the site `bank.com`, even if the form was submitted from `evil.com`. So the bank recognizes you and performs the payment.
 
 ![](cookie-xsrf.svg)
 
-That's called a "Cross-Site Request Forgery" (in short, XSRF) attack.
+This is a so-called "Cross-Site Request Forgery" (in short, XSRF) attack.
 
-Real banks are protected from it of course. All forms generated by `bank.com` have a special field, so called "XSRF protection token", that an evil page can't generate or extract from a remote page (it can submit a form there, but can't get the data back). And the site `bank.com` checks for such token in every form it receives.
+Real banks are protected from it of course. All forms generated by `bank.com` have a special field, a so-called "XSRF protection token", that an evil page can't generate or extract from a remote page. It can submit a form there, but can't get the data back. The site `bank.com` checks for such a token in every form it receives.
 
-But such protection takes time to implement: we need to ensure that every form has the token field, and we must also check all requests.
+Such a protection takes time to implement though. We need to ensure that every form has the required token field, and we must also check all requests.
 
-### Enter cookie samesite option
+### Use cookie samesite attribute
 
-The cookie `samesite` option provides another way to protect from such attacks, that (in theory) should not require "xsrf protection tokens".
+The cookie `samesite` attribute provides another way to protect from such attacks, that (in theory) should not require "xsrf protection tokens".
 
 It has two possible values:
 
-- **`samesite=strict` (same as `samesite` without value)**
+- **`samesite=strict`**
 
 A cookie with `samesite=strict` is never sent if the user comes from outside the same site.
 
-In other words, whether a user follows a link from their mail or submits a form from `evil.com`, or does any operation that originates from another domain, the cookie is not sent.
+In other words, whether a user follows a link from their email, submits a form from `evil.com`, or does any operation that originates from another domain, the cookie is not sent.
 
-If authentication cookies have `samesite` option, then XSRF attack has no chances to succeed, because a submission from `evil.com` comes without cookies. So `bank.com` will not recognize the user and will not proceed with the payment.
+If authentication cookies have the `samesite=strict` attribute, then an XSRF attack has no chance of succeeding, because a submission from `evil.com` comes without cookies. So `bank.com` will not recognize the user and will not proceed with the payment.
 
-The protection is quite reliable. Only operations that come from `bank.com` will send the `samesite` cookie, e.g. a form submission from another page at `bank.com`.
+The protection is quite reliable. Only operations that come from `bank.com` will send the `samesite=strict` cookie, e.g. a form submission from another page at `bank.com`.
 
 Although, there's a small inconvenience.
 
-When a user follows a legitimate link to `bank.com`, like from their own notes, they'll be surprised that `bank.com` does not recognize them. Indeed, `samesite=strict` cookies are not sent in that case.
+When a user follows a legitimate link to `bank.com`, like from their notes, they'll be surprised that `bank.com` does not recognize them. Indeed, `samesite=strict` cookies are not sent in that case.
 
-We could work around that by using two cookies: one for "general recognition", only for the purposes of saying: "Hello, John", and the other one for data-changing operations with `samesite=strict`. Then a person coming from outside of the site will see a welcome, but payments must be initiated from the bank website, for the second cookie to be sent.
+We could work around that by using two cookies: one for "general recognition", only to say: "Hello, John", and the other one for data-changing operations with `samesite=strict`. Then, a person coming from outside of the site will see a welcome, but payments must be initiated from the bank's website, for the second cookie to be sent.
 
-- **`samesite=lax`**
+- **`samesite=lax` (same as `samesite` without value)**
 
-A more relaxed approach that also protects from XSRF and doesn't break user experience.
+A more relaxed approach that also protects from XSRF and doesn't break the user experience.
 
 Lax mode, just like `strict`, forbids the browser to send cookies when coming from outside the site, but adds an exception.
 
 A `samesite=lax` cookie is sent if both of these conditions are true:
 1. The HTTP method is "safe" (e.g. GET, but not POST).
 
-    The full list of safe HTTP methods is in the [RFC7231 specification](https://tools.ietf.org/html/rfc7231). Basically, these are the methods that should be used for reading, but not writing the data. They must not perform any data-changing operations. Following a link is always GET, the safe method.
+    The full list of safe HTTP methods is in the [RFC7231 specification](https://tools.ietf.org/html/rfc7231#section-4.2.1). These are the methods that should be used for reading, but not writing the data. They must not perform any data-changing operations. Following a link is always GET, the safe method.
 
-2. The operation performs top-level navigation (changes URL in the browser address bar).
+2. The operation performs a top-level navigation (changes URL in the browser address bar).
 
-    That's usually true, but if the navigation is performed in an `<iframe>`, then it's not top-level. Also, JavaScript methods for network requests do not perform any navigation, hence they don't fit.
+    This is usually true, but if the navigation is performed in an `<iframe>`, then it is not top-level. Additionally, JavaScript methods for network requests do not perform any navigation.
 
-So, what `samesite=lax` does is basically allows a most common "go to URL" operation to have cookies. E.g. opening a website link from notes satisfies these conditions.
+So, what `samesite=lax` does, is to allow the most common "go to URL" operation to have cookies. E.g. opening a website link from notes that satisfy these conditions.
 
-But anything more complicated, like a network request from another site or a form submittion loses cookies.
+But anything more complicated, like a network request from another site or a form submission, loses cookies.
 
 If that's fine for you, then adding `samesite=lax` will probably not break the user experience and add protection.
 
-Overall, `samesite` is a great option, but it has an important drawback:
-- `samesite` is ignored (not supported) by old browsers, year 2017 or so.
+Overall, `samesite` is a great attribute.
+
+There's a drawback:
+
+- `samesite` is ignored (not supported) by very old browsers, the year 2017 or so.
 
 **So if we solely rely on `samesite` to provide protection, then old browsers will be vulnerable.**
 
-But we surely can use `samesite` together with other protection measures, like xsrf tokens, to add an additional layer of defence and then, in the future, when old browsers die out, we'll probably be able to drop xsrf tokens.
+But we can use `samesite` together with other protection measures, like xsrf tokens, to add a layer of defence and then, in the future, when old browsers die out, we'll probably be able to drop xsrf tokens.
 
 ## httpOnly
 
-This option has nothing to do with JavaScript, but we have to mention it for completeness.
+This attribute has nothing to do with JavaScript, but we have to mention it for completeness.
 
-The web-server uses `Set-Cookie` header to set a cookie. And it may set the `httpOnly` option.
+The web server uses the `Set-Cookie` header to set a cookie. Also, it may set the `httpOnly` attribute.
 
-This option forbids any JavaScript access to the cookie. We can't see such cookie or manipulate it using `document.cookie`.
+This attribute forbids any JavaScript access to the cookie. We can't see such a cookie or manipulate it using `document.cookie`.
 
-That's used as a precaution measure, to protect from certain attacks when a hacker injects his own JavaScript code into a page and waits for a user to visit that page. That shouldn't be possible at all, a hacker should not be able to inject their code into our site, but there may be bugs that let hackers do it.
+This is used as a precautionary measure, to protect from certain attacks when a hacker injects his own JavaScript code into a page and waits for a user to visit that page. That shouldn't be possible at all, hackers should not be able to inject their code into our site, but there may be bugs that let them do it.
 
 
-Normally, if such thing happens, and a user visits a web-page with hacker's JavaScript code, then that code executes and gains access to `document.cookie` with user cookies containing authentication information. That's bad.
+Normally, if such a thing happens, and a user visits a web-page with a hacker's JavaScript code, then that code executes and gains access to `document.cookie` with user cookies containing authentication information. That's bad.
 
 But if a cookie is `httpOnly`, then `document.cookie` doesn't see it, so it is protected.
 
@@ -275,10 +285,9 @@ Here's a small set of functions to work with cookies, more convenient than a man
 
 There exist many cookie libraries for that, so these are for demo purposes. Fully working though.
 
-
 ### getCookie(name)
 
-The shortest way to access cookie is to use a [regular expression](info:regular-expressions).
+The shortest way to access a cookie is to use a [regular expression](info:regular-expressions).
 
 The function `getCookie(name)` returns the cookie with the given `name`:
 
@@ -297,30 +306,30 @@ Here `new RegExp` is generated dynamically, to match `; name=<value>`.
 
 Please note that a cookie value is encoded, so `getCookie` uses a built-in `decodeURIComponent` function to decode it.
 
-### setCookie(name, value, options)
+### setCookie(name, value, attributes)
 
-Sets the cookie `name` to the given `value` with `path=/` by default (can be modified to add other defaults):
+Sets the cookie's `name` to the given `value` with `path=/` by default (can be modified to add other defaults):
 
 ```js run
-function setCookie(name, value, options = {}) {
+function setCookie(name, value, attributes = {}) {
 
-  options = {
+  attributes = {
     path: '/',
     // add other defaults here if necessary
-    ...options
+    ...attributes
   };
 
-  if (options.expires && options.expires.toUTCString) {
-    options.expires = options.expires.toUTCString();
+  if (attributes.expires instanceof Date) {
+    attributes.expires = attributes.expires.toUTCString();
   }
 
   let updatedCookie = encodeURIComponent(name) + "=" + encodeURIComponent(value);
 
-  for (let optionKey in options) {
-    updatedCookie += "; " + optionKey;
-    let optionValue = options[optionKey];
-    if (optionValue !== true) {
-      updatedCookie += "=" + optionValue;
+  for (let attributeKey in attributes) {
+    updatedCookie += "; " + attributeKey;
+    let attributeValue = attributes[attributeKey];
+    if (attributeValue !== true) {
+      updatedCookie += "=" + attributeValue;
     }
   }
 
@@ -344,7 +353,7 @@ function deleteCookie(name) {
 ```
 
 ```warn header="Updating or deleting must use same path and domain"
-Please note: when we update or delete a cookie, we should use exactly the same path and domain options as when we set it.
+Please note: when we update or delete a cookie, we should use exactly the same path and domain attributes as when we set it.
 ```
 
 Together: [cookie.js](cookie.js).
@@ -352,11 +361,11 @@ Together: [cookie.js](cookie.js).
 
 ## Appendix: Third-party cookies
 
-A cookie is called "third-party" if it's placed by domain other than the page user is visiting.
+A cookie is called "third-party" if it's placed by a domain other than the page the user is visiting.
 
 For instance:
 1. A page at `site.com` loads a banner from another site: `<img src="https://ads.com/banner.png">`.
-2. Along with the banner, the remote server at `ads.com` may set `Set-Cookie` header with cookie like `id=1234`. Such cookie originates from `ads.com` domain, and will only be visible at `ads.com`:
+2. Along with the banner, the remote server at `ads.com` may set the `Set-Cookie` header with a cookie like `id=1234`. Such a cookie originates from the `ads.com` domain, and will only be visible at `ads.com`:
 
     ![](cookie-third-party.svg)
 
@@ -364,14 +373,14 @@ For instance:
 
     ![](cookie-third-party-2.svg)
 
-4. What's even more important, when the users moves from `site.com` to another site `other.com` that also has a banner, then `ads.com` gets the cookie, as it belongs to `ads.com`, thus recognizing the visitor and tracking him as he moves between sites:
+4. What's even more important is, when the user moves from `site.com` to another site `other.com`, which also has a banner, then `ads.com` gets the cookie, as it belongs to `ads.com`, thus recognizing the visitor and tracking him as he moves between sites:
 
     ![](cookie-third-party-3.svg)
 
 
 Third-party cookies are traditionally used for tracking and ads services, due to their nature. They are bound to the originating domain, so `ads.com` can track the same user between different sites, if they all access it.
 
-Naturally, some people don't like being tracked, so browsers allow to disable such cookies.
+Naturally, some people don't like being tracked, so browsers allow them to disable such cookies.
 
 Also, some modern browsers employ special policies for such cookies:
 - Safari does not allow third-party cookies at all.
@@ -386,17 +395,17 @@ If a script sets a cookie, then no matter where the script came from -- the cook
 
 ## Appendix: GDPR
 
-This topic is not related to JavaScript at all, just something to keep in mind when setting cookies.
+This topic is not related to JavaScript at all, it is just something to keep in mind when setting cookies.
 
-There's a legislation in Europe called GDPR, that enforces a set of rules for websites to respect users' privacy. And one of such rules is to require an explicit permission for tracking cookies from a user.
+There's a legislation in Europe called GDPR, that enforces a set of rules for websites to respect the users' privacy. One of these rules is to require explicit permission for tracking cookies from the user.
 
 Please note, that's only about tracking/identifying/authorizing cookies.
 
 So, if we set a cookie that just saves some information, but neither tracks nor identifies the user, then we are free to do it.
 
-But if we are going to set a cookie with an authentication session or a tracking id, then a user must allow that.
+But if we are going to set a cookie with an authentication session or a tracking ID, then a user must allow that.
 
-Websites generally have two variants of following GDPR. You must have seen them both already in the web:
+Websites generally have two variants of complying with GDPR. You are likely to have seen them both on the web:
 
 1. If a website wants to set tracking cookies only for authenticated users.
 
@@ -404,26 +413,26 @@ Websites generally have two variants of following GDPR. You must have seen them
 
 2. If a website wants to set tracking cookies for everyone.
 
-    To do so legally, a website shows a modal "splash screen" for newcomers, and require them to agree for cookies. Then the website can set them and let people see the content. That can be disturbing for new visitors though. No one likes to see "must-click" modal splash screens instead of the content. But GDPR requires an explicit agreement.
+    To do so legally, a website shows a modal "splash screen" for newcomers and requires them to agree to the cookies. Then the website can set them and let people see the content. That can be disturbing for new visitors though. No one likes to see such "must-click" modal splash screens instead of the content. But GDPR requires an explicit agreement.
 
 
-GDPR is not only about cookies, it's about other privacy-related issues too, but that's too much beyond our scope.
+GDPR is not only about cookies, it is about other privacy-related issues too, but that is beyond our scope.
 
 
 ## Summary
 
-`document.cookie` provides access to cookies
-- write operations modify only cookies mentioned in it.
-- name/value must be encoded.
-- one cookie up to 4kb, 20+ cookies per site (depends on a browser).
+`document.cookie` provides access to cookies.
+- Write operations modify only the cookie mentioned in it.
+- Name/value must be encoded.
+- One cookie may not exceed 4KB in size. The number of cookies allowed on a domain is around 20+ (varies by browser).
 
-Cookie options:
+Cookie attributes:
 - `path=/`, by default current path, makes the cookie visible only under that path.
-- `domain=site.com`, by default a cookie is visible on current domain only, if set explicitly to the domain, makes the cookie visible on subdomains.
-- `expires` or `max-age` sets cookie expiration time, without them the cookie dies when the browser is closed.
+- `domain=site.com`, by default a cookie is visible on the current domain only. If the domain is set explicitly, the cookie becomes visible on subdomains.
+- `expires` or `max-age` sets the cookie expiration time. Without them, the cookie dies when the browser is closed.
 - `secure` makes the cookie HTTPS-only.
-- `samesite` forbids the browser to send the cookie with requests coming from outside the site, helps to prevent XSRF attacks.
+- `samesite` forbids the browser to send the cookie with requests coming from outside the site. This helps to prevent XSRF attacks.
 
 Additionally:
-- Third-party cookies may be forbidden by the browser, e.g. Safari does that by default.
+- The browser may forbid third-party cookies, e.g. Safari does that by default. There is also work in progress to implement this in Chrome.
 - When setting a tracking cookie for EU citizens, GDPR requires to ask for permission.
diff --git a/6-data-storage/01-cookie/cookie.js b/6-data-storage/01-cookie/cookie.js
index 7d8eebf3e..653ea5b7f 100644
--- a/6-data-storage/01-cookie/cookie.js
+++ b/6-data-storage/01-cookie/cookie.js
@@ -1,6 +1,6 @@
 function getCookie(name) {
   let matches = document.cookie.match(new RegExp(
-    "(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)"
+    "(?:^|; )" + name.replace(/([.$?*|{}()[\]\\/+^])/g, '\\$1') + "=([^;]*)"
   ));
   return matches ? decodeURIComponent(matches[1]) : undefined;
 }
@@ -13,7 +13,7 @@ function setCookie(name, value, options = {}) {
     ...options
   };
 
-  if (options.expires.toUTCString) {
+  if (options.expires instanceof Date) {
     options.expires = options.expires.toUTCString();
   }
 
diff --git a/6-data-storage/02-localstorage/article.md b/6-data-storage/02-localstorage/article.md
index 9b2279e17..a99bcb653 100644
--- a/6-data-storage/02-localstorage/article.md
+++ b/6-data-storage/02-localstorage/article.md
@@ -6,11 +6,11 @@ What's interesting about them is that the data survives a page refresh (for `ses
 
 We already have cookies. Why additional objects?
 
-- Unlike cookies, web storage objects are not sent to server with each request. Because of that, we can store much more. Most browsers allow at least 2 megabytes of data (or more) and have settings to configure that.
+- Unlike cookies, web storage objects are not sent to server with each request. Because of that, we can store much more. Most modern browsers allow at least 5 megabytes of data (or more) and have settings to configure that.
 - Also unlike cookies, the server can't manipulate storage objects via HTTP headers. Everything's done in JavaScript.
 - The storage is bound to the origin (domain/protocol/port triplet). That is, different protocols or subdomains infer different storage objects, they can't access data from each other.
 
-Both storage objects provide same methods and properties:
+Both storage objects provide the same methods and properties:
 
 - `setItem(key, value)` -- store key/value pair.
 - `getItem(key)` -- get the value by key.
@@ -19,7 +19,7 @@ Both storage objects provide same methods and properties:
 - `key(index)` -- get the key on a given position.
 - `length` -- the number of stored items.
 
-As you can see, it's like a `Map` collection (`setItem/getItem/removeItem`), but also keeps elements order and allows to access by index with `key(index)`.
+As you can see, it's like a `Map` collection (`setItem/getItem/removeItem`), but also allows access by index with `key(index)`.
 
 Let's see how it works.
 
@@ -64,6 +64,7 @@ delete localStorage.test;
 That's allowed for historical reasons, and mostly works, but generally not recommended, because:
 
 1. If the key is user-generated, it can be anything, like `length` or `toString`, or another built-in method of `localStorage`. In that case `getItem/setItem` work fine, while object-like access fails:
+
     ```js run
     let key = 'length';
     localStorage[key] = 5; // Error, can't assign length
@@ -119,25 +120,24 @@ for(let key of keys) {
 
 The latter works, because `Object.keys` only returns the keys that belong to the object, ignoring the prototype.
 
-
 ## Strings only
 
 Please note that both key and value must be strings.
 
-If were any other type, like a number, or an object, it gets converted to string automatically:
+If they were any other type, like a number, or an object, they would get converted to a string automatically:
 
 ```js run
-sessionStorage.user = {name: "John"};
-alert(sessionStorage.user); // [object Object]
+localStorage.user = {name: "John"};
+alert(localStorage.user); // [object Object]
 ```
 
 We can use `JSON` to store objects though:
 
 ```js run
-sessionStorage.user = JSON.stringify({name: "John"});
+localStorage.user = JSON.stringify({name: "John"});
 
 // sometime later
-let user = JSON.parse( sessionStorage.user );
+let user = JSON.parse( localStorage.user );
 alert( user.name ); // John
 ```
 
@@ -148,7 +148,6 @@ Also it is possible to stringify the whole storage object, e.g. for debugging pu
 alert( JSON.stringify(localStorage, null, 2) );
 ```
 
-
 ## sessionStorage
 
 The `sessionStorage` object is used much less often than `localStorage`.
@@ -180,7 +179,7 @@ That's exactly because `sessionStorage` is bound not only to the origin, but als
 
 ## Storage event
 
-When the data gets updated in `localStorage` or `sessionStorage`, [storage](https://www.w3.org/TR/webstorage/#the-storage-event) event triggers, with properties:
+When the data gets updated in `localStorage` or `sessionStorage`, [storage](https://html.spec.whatwg.org/multipage/webstorage.html#the-storageevent-interface) event triggers, with properties:
 
 - `key` – the key that was changed (`null` if `.clear()` is called).
 - `oldValue` – the old value (`null` if the key is newly added).
@@ -202,7 +201,7 @@ If both windows are listening for `window.onstorage`, then each one will react o
 
 ```js run
 // triggers on updates made to the same storage from other documents
-window.onstorage = event => {
+window.onstorage = event => { // can also use window.addEventListener('storage', event => {
   if (event.key != 'now') return;
   alert(event.key + ':' + event.newValue + " at " + event.url);
 };
@@ -216,13 +215,14 @@ Also, `event.storageArea` contains the storage object -- the event is the same f
 
 **That allows different windows from the same origin to exchange messages.**
 
-Modern browsers also support [Broadcast channel API](https://developer.mozilla.org/en-US/docs/Web/API/Broadcast_Channel_API), the special API for same-origin inter-window communication, it's more full featured, but less supported. There are libraries that polyfill that API, based on `localStorage`, that make it available everywhere.
+Modern browsers also support [Broadcast channel API](mdn:/api/Broadcast_Channel_API), the special API for same-origin inter-window communication, it's more full featured, but less supported. There are libraries that polyfill that API, based on `localStorage`, that make it available everywhere.
 
 ## Summary
 
-Web storage objects `localStorage` and `sessionStorage` allow to store key/value in the browser.
+Web storage objects `localStorage` and `sessionStorage` allow to store key/value pairs in the browser.
+
 - Both `key` and `value` must be strings.
-- The limit is 2mb+, depends on the browser.
+- The limit is 5mb+, depends on the browser.
 - They do not expire.
 - The data is bound to the origin (domain/port/protocol).
 
diff --git a/6-data-storage/03-indexeddb/article.md b/6-data-storage/03-indexeddb/article.md
index 861a90877..43344e487 100644
--- a/6-data-storage/03-indexeddb/article.md
+++ b/6-data-storage/03-indexeddb/article.md
@@ -5,22 +5,28 @@ libs:
 
 # IndexedDB
 
-IndexedDB is a built-in database, much more powerful than `localStorage`.
+IndexedDB is a database that is built into a browser, much more powerful than `localStorage`.
 
-- Key/value storage: value can be (almost) anything, multiple key types.
+- Stores almost any kind of values by keys, multiple key types.
 - Supports transactions for reliability.
 - Supports key range queries, indexes.
-- Can store much more data than `localStorage`.
+- Can store much bigger volumes of data than `localStorage`.
 
 That power is usually excessive for traditional client-server apps. IndexedDB is intended for offline apps, to be combined with ServiceWorkers and other technologies.
 
 The native interface to IndexedDB, described in the specification <https://www.w3.org/TR/IndexedDB>, is event-based.
 
-We can also use `async/await` with the help of a promise-based wrapper, like <https://github.com/jakearchibald/idb>. That's pretty convenient, but the wrapper is not perfect, it can't replace events for all cases. So we'll start with events, and  then, after we gain understanding of IndexedDb, we'll use the wrapper.
+We can also use `async/await` with the help of a promise-based wrapper, like <https://github.com/jakearchibald/idb>. That's pretty convenient, but the wrapper is not perfect, it can't replace events for all cases. So we'll start with events, and then, after we gain an understanding of IndexedDB, we'll use the wrapper.
+
+```smart header="Where's the data?"
+Technically, the data is usually stored in the visitor's home directory, along with browser settings, extensions, etc.
+
+Different browsers and OS-level users have each their own independant storage.
+```
 
 ## Open database
 
-To start working with IndexedDB, we first need to open a database.
+To start working with IndexedDB, we first need to `open` (connect to) a database.
 
 The syntax:
 
@@ -31,22 +37,24 @@ let openRequest = indexedDB.open(name, version);
 - `name` -- a string, the database name.
 - `version` -- a positive integer version, by default `1` (explained below).
 
-We can have many databases with different names, but all of them exist within the current origin (domain/protocol/port). Different websites can't access databases of each other.
+We can have many databases with different names, but all of them exist within the current origin (domain/protocol/port). Different websites can't access each other's databases.
 
-After the call, we need to listen to events on `openRequest` object:
-- `success`: database is ready, there's the "database object" in `openRequest.result`, that we should use it for further calls.
+The call returns `openRequest` object, we should listen to events on it:
+- `success`: database is ready, there's the "database object" in `openRequest.result`, we should use it for further calls.
 - `error`: opening failed.
 - `upgradeneeded`: database is ready, but its version is outdated (see below).
 
 **IndexedDB has a built-in mechanism of "schema versioning", absent in server-side databases.**
 
-Unlike server-side databases, IndexedDB is client-side, the data is stored in the browser, so we, developers, don't have direct access to it. But when we publish a new version of our app, we may need to update the database.
+Unlike server-side databases, IndexedDB is client-side, the data is stored in the browser, so we, developers, don't have full-time access to it. So, when we have published a new version of our app, and the user visits our webpage, we may need to update the database.
 
 If the local database version is less than specified in `open`, then a special event `upgradeneeded` is triggered, and we can compare versions and upgrade data structures as needed.
 
-The event also triggers when the database did not exist yet, so we can perform initialization.
+The `upgradeneeded` event also triggers when the database doesn't yet exist (technically, its version is `0`), so we can perform the initialization.
+
+Let's say we published the first version of our app.
 
-When we first publish our app, we open it with version `1` and perform the initialization in `upgradeneeded` handler:
+Then we can open the database with version `1` and perform the initialization in an `upgradeneeded` handler like this:
 
 ```js
 let openRequest = indexedDB.open("store", *!*1*/!*);
@@ -62,19 +70,21 @@ openRequest.onerror = function() {
 
 openRequest.onsuccess = function() {
   let db = openRequest.result;
-  // continue to work with database using db object
+  // continue working with database using db object
 };
 ```
 
-When we publish the 2nd version:
+Then, later, we publish the 2nd version.
+
+We can open it with version `2` and perform the upgrade like this:
 
 ```js
 let openRequest = indexedDB.open("store", *!*2*/!*);
 
-openRequest.onupgradeneeded = function() {
+openRequest.onupgradeneeded = function(event) {
   // the existing database version is less than 2 (or it doesn't exist)
   let db = openRequest.result;
-  switch(db.version) { // existing db version
+  switch(event.oldVersion) { // existing db version
     case 0:
       // version 0 means that the client had no database
       // perform initialization
@@ -85,9 +95,9 @@ openRequest.onupgradeneeded = function() {
 };
 ```
 
-So, in `openRequest.onupgradeneeded` we update the database. Soon we'll see how it's done. And then, only if its handler finishes without errors, `openRequest.onsuccess` triggers.
+Please note: as our current version is `2`, the `onupgradeneeded` handler has a code branch for version `0`, suitable for users that are accessing for the first time and have no database, and also for version `1`, for upgrades.
 
-After `openRequest.onsuccess` we have the database object in `openRequest.result`, that we'll use for further operations.
+And then, only if `onupgradeneeded` handler finishes without errors, `openRequest.onsuccess` triggers, and the database is considered successfully opened.
 
 To delete a database:
 
@@ -96,29 +106,32 @@ let deleteRequest = indexedDB.deleteDatabase(name)
 // deleteRequest.onsuccess/onerror tracks the result
 ```
 
-```warn header="Can we open an old version?"
-Now what if we try to open a database with a lower version than the current one? E.g. the existing DB version is 3, and we try to `open(...2)`.
+```warn header="We can't open a database using an older open call version"
+If the current user database has a higher version than in the `open` call, e.g. the existing DB version is `3`, and we try to `open(...2)`, then that's an error, `openRequest.onerror` triggers.
 
-That's an error, `openRequest.onerror` triggers.
+That's rare, but such a thing may happen when a visitor loads outdated JavaScript code, e.g. from a proxy cache. So the code is old, but his database is new.
 
-Such thing may happen if the visitor loaded an outdated code, e.g. from a proxy cache. We should check `db.version`, suggest him to reload the page. And also re-check our caching headers to ensure that the visitor never gets old code.
+To protect from errors, we should check `db.version` and suggest a page reload. Use proper HTTP caching headers to avoid loading the old code, so that you'll never have such problems.
 ```
 
 ### Parallel update problem
 
 As we're talking about versioning, let's tackle a small related problem.
 
-Let's say, a visitor opened our site in a browser tab, with database version 1.
+Let's say:
+1. A visitor opened our site in a browser tab, with database version `1`.
+2. Then we rolled out an update, so our code is newer.
+3. And then the same visitor opens our site in another tab.
 
-Then we rolled out an update, and the same visitor opens our site in another tab. So there are two tabs, both with our site, but one has an open connection with DB version 1, while the other one attempts to update it in `upgradeneeded` handler.
+So there's a tab with an open connection to DB version `1`, while the second one attempts to update it to version `2` in its `upgradeneeded` handler.
 
-The problem is that a database is shared between two tabs, as that's the same site, same origin. And it can't be both version 1 and 2. To perform the update to version 2, all connections to version 1 must be closed.
+The problem is that a database is shared between two tabs, as it's the same site, same origin. And it can't be both version `1` and `2`. To perform the update to version `2`, all connections to version 1 must be closed, including the one in the first tab.
 
-In order to organize that, the `versionchange` event triggers an open database object when a parallel upgrade is attempted. We should listen to it, so that we should close the database (and probably suggest the visitor to reload the page, to load the updated code).
+In order to organize that, the `versionchange` event triggers on the "outdated" database object. We should listen for it and close the old database connection (and probably suggest a page reload, to load the updated code).
 
-If we don't close it, then the second, new connection will be blocked with `blocked` event instead of `success`.
+If we don't listen for the `versionchange` event and don't close the old connection, then the second, new connection won't be made. The `openRequest` object will emit the `blocked` event instead of `success`. So the second tab won't work.
 
-Here's the code to do that:
+Here's the code to correctly handle the parallel upgrade. It installs the `onversionchange` handler, that triggers if the current database connection becomes outdated (db version is updated elsewhere) and closes the connection.
 
 ```js
 let openRequest = indexedDB.open("store", 2);
@@ -141,20 +154,24 @@ openRequest.onsuccess = function() {
 
 *!*
 openRequest.onblocked = function() {
-  // there's another open connection to same database
-  // and it wasn't closed after db.onversionchange triggered for them
+  // this event shouldn't trigger if we handle onversionchange correctly
+
+  // it means that there's another open connection to the same database
+  // and it wasn't closed after db.onversionchange triggered for it
 };
 */!*
 ```
 
-Here we do two things:
+...In other words, here we do two things:
 
-1. Add `db.onversionchange` listener after a successful opening, to be informed about a parallel update attempt.
-2. Add `openRequest.onblocked` listener to handle the case when an old connection wasn't closed. This doesn't happen if we close it in `db.onversionchange`.
+1. The `db.onversionchange` listener informs us about a parallel update attempt, if the current database version becomes outdated.
+2. The `openRequest.onblocked` listener informs us about the opposite situation: there's a connection to an outdated version elsewhere, and it doesn't close, so the newer connection can't be made.
 
-There are other variants. For example, we can take time to close things gracefully in `db.onversionchange`, prompt the visitor to save the data before the connection is closed. The new updating connection will be blocked immediatelly after `db.onversionchange` finished without closing, and we can ask the visitor in the new tab to close other tabs for the update.
+We can handle things more gracefully in `db.onversionchange`, prompt the visitor to save the data before the connection is closed and so on. 
 
-Such update collision happens rarely, but we should at least have some handling for it, e.g. `onblocked` handler, so that our script doesn't surprise the user by dying silently.
+Or, an alternative approach would be to not close the database in `db.onversionchange`, but instead use the `onblocked` handler (in the new tab) to alert the visitor, tell him that the newer version can't be loaded until they close other tabs.
+
+These update collisions happen rarely, but we should at least have some handling for them, at least an `onblocked` handler, to prevent our script from dying silently.
 
 ## Object store
 
@@ -168,21 +185,20 @@ Despite being named an "object store", primitives can be stored too.
 
 IndexedDB uses the [standard serialization algorithm](https://www.w3.org/TR/html53/infrastructure.html#section-structuredserializeforstorage) to clone-and-store an object. It's like `JSON.stringify`, but more powerful, capable of storing much more datatypes.
 
-An example of object that can't be stored: an object with circular references. Such objects are not serializable. `JSON.stringify` also fails for such objects.
+An example of an object that can't be stored: an object with circular references. Such objects are not serializable. `JSON.stringify` also fails for such objects.
 
 **There must be a unique `key` for every value in the store.**     
 
-A key must have a type one of: number, date, string, binary, or array. It's an unique identifier: we can search/remove/update values by the key.
+A key must be one of these types - number, date, string, binary, or array. It's a unique identifier, so we can search/remove/update values by the key.
 
 ![](indexeddb-structure.svg)
 
-
-As we'll see very soon, we can provide a key when we add a value to the store, similar to `localStorage`. But when we store objects, IndexedDB allows to setup an object property as the key, that's much more convenient. Or we can auto-generate keys.
+As we'll see very soon, we can provide a key when we add a value to the store, similar to `localStorage`. But when we store objects, IndexedDB allows setting up an object property as the key, which is much more convenient. Or we can auto-generate keys.
 
 But we need to create an object store first.
 
-
 The syntax to create an object store:
+
 ```js
 db.createObjectStore(name[, keyOptions]);
 ```
@@ -197,15 +213,17 @@ Please note, the operation is synchronous, no `await` needed.
 If we don't supply `keyOptions`, then we'll need to provide a key explicitly later, when storing an object.
 
 For instance, this object store uses `id` property as the key:
+
 ```js
 db.createObjectStore('books', {keyPath: 'id'});
 ```
 
 **An object store can only be created/modified while updating the DB version, in `upgradeneeded` handler.**
 
-That's a technical limitation. Outside of the handler we'll be able to add/remove/update the data, but object stores can be created/removed/altered only during version update.
+That's a technical limitation. Outside of the handler we'll be able to add/remove/update the data, but object stores can only be created/removed/altered during a version update.
+
+To perform a database version upgrade, there are two main approaches:
 
-To perform database version upgrade, there are two main approaches:
 1. We can implement per-version upgrade functions: from 1 to 2, from 2 to 3, from 3 to 4 etc. Then, in `upgradeneeded` we can compare versions (e.g. old 2, now 4) and run per-version upgrades step by step, for every intermediate version (2 to 3, then 3 to 4).
 2. Or we can just examine the database: get a list of existing object stores as `db.objectStoreNames`. That object is a [DOMStringList](https://html.spec.whatwg.org/multipage/common-dom-interfaces.html#domstringlist) that provides `contains(name)` method to check for existance. And then we can do updates depending on what exists and what doesn't.
 
@@ -225,7 +243,6 @@ openRequest.onupgradeneeded = function() {
 };
 ```
 
-
 To delete an object store:
 
 ```js
@@ -236,9 +253,10 @@ db.deleteObjectStore('books')
 
 The term "transaction" is generic, used in many kinds of databases.
 
-A transaction is a group operations, that should either all succeed or all fail.
+A transaction is a group of operations, that should either all succeed or all fail.
+
+For instance, when a person buys something, we need to:
 
-For instance, when a person buys something, we need:
 1. Subtract the money from their account.
 2. Add the item to their inventory.
 
@@ -250,7 +268,7 @@ Transactions can guarantee that.
 
 To start a transaction:
 
-```js run
+```js
 db.transaction(store[, type]);
 ```
 
@@ -259,12 +277,12 @@ db.transaction(store[, type]);
   - `readonly` -- can only read, the default.
   - `readwrite` -- can only read and write the data, but not create/remove/alter object stores.
 
-There's also `versionchange` transaction type: such transactions can do everything, but we can't create them manually. IndexedDB automatically creates a `versionchange` transaction when opening the database, for `updateneeded` handler. That's why it's a single place where we can update the database structure, create/remove object stores.
+There's also `versionchange` transaction type: such transactions can do everything, but we can't create them manually. IndexedDB automatically creates a `versionchange` transaction when opening the database, for `upgradeneeded` handler. That's why it's a single place where we can update the database structure, create/remove object stores.
 
-```smart header="Why there exist different types of transactions?"
+```smart header="Why are there different types of transactions?"
 Performance is the reason why transactions need to be labeled either `readonly` and `readwrite`.
 
-Many `readonly` transactions are able to access concurrently the same store, but `readwrite` transactions can't. A `readwrite` transaction "locks" the store for writing. The next transaction must wait before the previous one finishes before accessing the same store.
+Many `readonly` transactions are able to access the same store concurrently, but `readwrite` transactions can't. A `readwrite` transaction "locks" the store for writing. The next transaction must wait before the previous one finishes before accessing the same store.
 ```
 
 After the transaction is created, we can add an item to the store, like this:
@@ -298,7 +316,7 @@ request.onerror = function() {
 
 There were basically four steps:
 
-1. Create a transaction, mention all stores it's going to access, at `(1)`.
+1. Create a transaction, mentioning all the stores it's going to access, at `(1)`.
 2. Get the store object using `transaction.objectStore(name)`, at `(2)`.
 3. Perform the request to the object store `books.add(book)`, at `(3)`.
 4. ...Handle request success/error `(4)`, then we can make other requests if needed, etc.
@@ -306,7 +324,7 @@ There were basically four steps:
 Object stores support two methods to store a value:
 
 - **put(value, [key])**
-    Add the `value` to the store. The `key` is supplied only if the object store did not have `keyPath` or `autoIncrement` option. If there's already a value with same key, it will be replaced.
+    Add the `value` to the store. The `key` is supplied only if the object store did not have `keyPath` or `autoIncrement` option. If there's already a value with the same key, it will be replaced.
 
 - **add(value, [key])**
     Same as `put`, but if there's already a value with the same key, then the request fails, and an error with the name `"ConstraintError"` is generated.
@@ -318,7 +336,7 @@ Similar to opening a database, we can send a request: `books.add(book)`, and the
 
 ## Transactions' autocommit
 
-In the example above we started the transaction and made `add` request. But as we stated previously, a transaction may have multiple associated requests, that must either all success or all fail. How do we mark the transaction as finished, no more requests to come?
+In the example above we started the transaction and made `add` request. But as we stated previously, a transaction may have multiple associated requests, that must either all succeed or all fail. How do we mark the transaction as finished, with no more requests to come?
 
 The short answer is: we don't.
 
@@ -330,9 +348,9 @@ Usually, we can assume that a transaction commits when all its requests are comp
 
 So, in the example above no special call is needed to finish the transaction.
 
-Transactions auto-commit principle has an important side effect. We can't insert an async operation like `fetch`, `setTimeout` in the middle of transaction. IndexedDB will not keep the transaction waiting till these are done.
+Transactions auto-commit principle has an important side effect. We can't insert an async operation like `fetch`, `setTimeout` in the middle of a transaction. IndexedDB will not keep the transaction waiting till these are done.
 
-In the code below `request2` in line `(*)` fails, because the transaction is already committed, can't make any request in it:
+In the code below, `request2` in the line `(*)` fails, because the transaction is already committed, and can't make any request in it:
 
 ```js
 let request1 = books.add(book);
@@ -353,7 +371,7 @@ That's because `fetch` is an asynchronous operation, a macrotask. Transactions a
 
 Authors of IndexedDB spec believe that transactions should be short-lived. Mostly for performance reasons.
 
-Notably, `readwrite` transactions "lock" the stores for writing. So if one part of application initiated `readwrite` on `books` object store, then another part that wants to do the same has to wait: the new transaction "hangs" till the first one is done. That can lead to strange delays if transactions take a long time.
+Notably, `readwrite` transactions "lock" the stores for writing. So if one part of the application initiated `readwrite` on `books` object store, then another part that wants to do the same has to wait: the new transaction "hangs" till the first one is done. That can lead to strange delays if transactions take a long time.
 
 So, what to do?
 
@@ -458,24 +476,29 @@ request.onerror = function(event) {
 };
 ```
 
-## Searching by keys
+## Searching
 
 There are two main types of search in an object store:
-1. By a key or a key range. That is: by `book.id` in our "books" storage.
-2. By another object field, e.g. `book.price`.
 
-First let's deal with the keys and key ranges `(1)`.
+1. By a key value or a key range. In our "books" storage that would be a value or range of values of `book.id`.
+2. By another object field, e.g. `book.price`. This required an additional data structure, named "index".
+
+### By key
+
+First let's deal with the first type of search: by key.
 
-Methods that involve searching support either exact keys or so-called "range queries" -- [IDBKeyRange](https://www.w3.org/TR/IndexedDB/#keyrange) objects that specify a "key range".
+Searching methods support both exact key values and so-called "ranges of values" -- [IDBKeyRange](https://www.w3.org/TR/IndexedDB/#keyrange) objects that specify an acceptable "key range".
 
-Ranges are created using following calls:
+`IDBKeyRange` objects are created using following calls:
 
 - `IDBKeyRange.lowerBound(lower, [open])` means: `≥lower` (or `>lower` if `open` is true)
 - `IDBKeyRange.upperBound(upper, [open])` means: `≤upper` (or `<upper` if `open` is true)
-- `IDBKeyRange.bound(lower, upper, [lowerOpen], [upperOpen])` means: between `lower` and `upper`. If the open flags is true, the corresponding key is not included in the range. 
+- `IDBKeyRange.bound(lower, upper, [lowerOpen], [upperOpen])` means: between `lower` and `upper`. If the open flags is true, the corresponding key is not included in the range.
 - `IDBKeyRange.only(key)` -- a range that consists of only one `key`, rarely used.
 
-All searching methods accept a `query` argument that can be either an exact key or a key range:
+We'll see practical examples of using them very soon.
+
+To perform the actual search, there are following methods. They accept a `query` argument that can be either an exact key or a key range:
 
 - `store.get(query)` -- search for the first value by a key or a range.
 - `store.getAll([query], [count])` -- search for all values, limit by `count` if given.
@@ -494,24 +517,23 @@ books.get('js')
 // get books with 'css' <= id <= 'html'
 books.getAll(IDBKeyRange.bound('css', 'html'))
 
-// get books with 'html' < id
-books.getAll(IDBKeyRange.lowerBound('html', true))
+// get books with id < 'html'
+books.getAll(IDBKeyRange.upperBound('html', true))
 
 // get all books
 books.getAll()
 
-// get all keys: id > 'js'
+// get all keys, where id > 'js'
 books.getAllKeys(IDBKeyRange.lowerBound('js', true))
 ```
 
 ```smart header="Object store is always sorted"
-Object store sorts values by key internally.
+An object store sorts values by key internally.
 
 So requests that return many values always return them in sorted by key order.
 ```
 
-
-## Searching by any field with an index
+### By a field using an index
 
 To search by other object fields, we need to create an additional data structure named "index".
 
@@ -540,7 +562,7 @@ openRequest.onupgradeneeded = function() {
   // we must create the index here, in versionchange transaction
   let books = db.createObjectStore('books', {keyPath: 'id'});
 *!*
-  let index = inventory.createIndex('price_idx', 'price');
+  let index = books.createIndex('price_idx', 'price');
 */!*
 };
 ```
@@ -593,6 +615,7 @@ The `delete` method looks up values to delete by a query, the call format is sim
 - **`delete(query)`** -- delete matching values by query.
 
 For instance:
+
 ```js
 // delete the book with id='js'
 books.delete('js');
@@ -611,6 +634,7 @@ request.onsuccess = function() {
 ```
 
 To delete everything:
+
 ```js
 books.clear(); // clear the storage.
 ```
@@ -630,6 +654,7 @@ Cursors provide the means to work around that.
 As an object store is sorted internally by key, a cursor walks the store in key order (ascending by default).
 
 The syntax:
+
 ```js
 // like getAll, but with a cursor:
 let request = store.openCursor(query, [direction]);
@@ -676,7 +701,7 @@ Whether there are more values matching the cursor or not -- `onsuccess` gets cal
 
 In the example above the cursor was made for the object store.
 
-But we also can make a cursor over an index. As we remember, indexes allow to search by an object field. Cursors over indexes to precisely the same as over object stores -- they save memory by returning one value at a time.
+But we also can make a cursor over an index. As we remember, indexes allow to search by an object field. Cursors over indexes do precisely the same as over object stores -- they save memory by returning one value at a time.
 
 For cursors over indexes, `cursor.key` is the index key (e.g. price), and we should use `cursor.primaryKey` property for the object key:
 
@@ -687,7 +712,7 @@ let request = priceIdx.openCursor(IDBKeyRange.upperBound(5));
 request.onsuccess = function() {
   let cursor = request.result;
   if (cursor) {
-    let key = cursor.primaryKey; // next object store key (id field)
+    let primaryKey = cursor.primaryKey; // next object store key (id field)
     let value = cursor.value; // next object store object (book object)
     let key = cursor.key; // next index key (price)
     console.log(key, value);
@@ -707,7 +732,7 @@ Let's use a thin promise wrapper <https://github.com/jakearchibald/idb> further
 Then, instead of `onsuccess/onerror` we can write like this:
 
 ```js
-let db = await idb.openDb('store', 1, db => {
+let db = await idb.openDB('store', 1, db => {
   if (db.oldVersion == 0) {
     // perform the initialization
     db.createObjectStore('books', {keyPath: 'id'});
@@ -727,7 +752,6 @@ try {
 } catch(err) {
   console.log('error', err.message);
 }
-
 ```
 
 So we have all the sweet "plain async code" and "try..catch" stuff.
@@ -750,10 +774,8 @@ window.addEventListener('unhandledrejection', event => {
 
 ### "Inactive transaction" pitfall
 
-
 As we already know, a transaction auto-commits as soon as the browser is done with the current code and microtasks. So if we put a *macrotask* like `fetch` in the middle of a transaction, then the transaction won't wait for it to finish. It just auto-commits. So the next request in it would fail.
 
-
 For a promise wrapper and `async/await` the situation is the same.
 
 Here's an example of `fetch` in the middle of the transaction:
@@ -771,7 +793,8 @@ await inventory.add({ id: 'js', price: 10, created: new Date() }); // Error
 
 The next `inventory.add` after `fetch` `(*)` fails with an "inactive transaction" error, because the transaction is already committed and closed at that time.
 
-The workaround is same as when working with native IndexedDB: either make a new transaction or just split things apart.
+The workaround is the same as when working with native IndexedDB: either make a new transaction or just split things apart.
+
 1. Prepare the data and fetch all that's needed first.
 2. Then save in the database.
 
@@ -798,7 +821,7 @@ let result = await promise; // if still needed
 
 IndexedDB can be thought of as a "localStorage on steroids". It's a simple key-value database, powerful enough for offline apps, yet simple to use.
 
-The best manual is the specification, [the current one](https://w3c.github.io/IndexedDB) is 2.0, but few methods from [3.0](https://w3c.github.io/IndexedDB/) (it's not much different) are partially supported.
+The best manual is the specification, [the current one](https://www.w3.org/TR/IndexedDB-2/) is 2.0, but few methods from [3.0](https://w3c.github.io/IndexedDB/) (it's not much different) are partially supported.
 
 The basic usage can be described with a few phrases:
 
diff --git a/7-animation/1-bezier-curve/article.md b/7-animation/1-bezier-curve/article.md
index 10a047bf2..63b9a03ce 100644
--- a/7-animation/1-bezier-curve/article.md
+++ b/7-animation/1-bezier-curve/article.md
@@ -4,6 +4,12 @@ Bezier curves are used in computer graphics to draw shapes, for CSS animation an
 
 They are a very simple thing, worth to study once and then feel comfortable in the world of vector graphics and advanced animations.
 
+```smart header="Some theory, please"
+This article provides a theoretical, but very needed insight into what Bezier curves are, while [the next one](info:css-animations#bezier-curve) shows how we can use them for CSS animations.
+
+Please take your time to read and understand the concept, it'll serve you well.
+```
+
 ## Control points
 
 A [bezier curve](https://en.wikipedia.org/wiki/B%C3%A9zier_curve) is defined by control points.
@@ -31,7 +37,7 @@ For two points we have a linear curve (that's a straight line), for three points
 
     ![](bezier4-e.svg) ![](bezier3-e.svg)
 
-Because of that last property, in computer graphics it's possible to optimize intersection tests. If convex hulls do not intersect, then curves do not either. So checking for the convex hulls intersection first can give a very fast "no intersection" result. Checking the intersection or convex hulls is much easier, because they are rectangles, triangles and so on (see the picture above), much simpler figures than the curve.
+Because of that last property, in computer graphics it's possible to optimize intersection tests. If convex hulls do not intersect, then curves do not either. So checking for the convex hulls intersection first can give a very fast "no intersection" result. Checking the intersection of convex hulls is much easier, because they are rectangles, triangles and so on (see the picture above), much simpler figures than the curve.
 
 **The main value of Bezier curves for drawing -- by moving the points the curve is changing *in intuitively obvious way*.**
 
@@ -50,7 +56,7 @@ Here are some examples:
 ## De Casteljau's algorithm
 
 There's a mathematical formula for Bezier curves, but let's cover it a bit later, because
-[De Casteljau's algorithm](https://en.wikipedia.org/wiki/De_Casteljau%27s_algorithm) it is identical to the mathematical definition and visually shows how it is constructed.
+[De Casteljau's algorithm](https://en.wikipedia.org/wiki/De_Casteljau%27s_algorithm) is identical to the mathematical definition and visually shows how it is constructed.
 
 First let's see the 3-points example.
 
@@ -176,7 +182,7 @@ Instead of <code>x<sub>1</sub>, y<sub>1</sub>, x<sub>2</sub>, y<sub>2</sub>, x<s
 For instance, if control points are  `(0,0)`, `(0.5, 1)` and `(1, 0)`, the equations become:
 
 - <code>x = (1−t)<sup>2</sup> * 0 + 2(1−t)t * 0.5 + t<sup>2</sup> * 1 = (1-t)t + t<sup>2</sup> = t</code>
-- <code>y = (1−t)<sup>2</sup> * 0 + 2(1−t)t * 1 + t<sup>2</sup> * 0 = 2(1-t)t = –t<sup>2</sup> + 2t</code>
+- <code>y = (1−t)<sup>2</sup> * 0 + 2(1−t)t * 1 + t<sup>2</sup> * 0 = 2(1-t)t = –2t<sup>2</sup> + 2t</code>
 
 Now as `t` runs from `0` to `1`, the set of values `(x,y)` for each `t` forms the curve for such control points.
 
diff --git a/7-animation/1-bezier-curve/demo.svg b/7-animation/1-bezier-curve/demo.svg
index 5240697ee..56d5b3fbe 100644
--- a/7-animation/1-bezier-curve/demo.svg
+++ b/7-animation/1-bezier-curve/demo.svg
@@ -153,6 +153,9 @@ http://www.w3.org/Graphics/SVG/IG/resources/svgprimer.html#path_C
 	      points[i].y = y;
 	      setPointCoords(point, i);
 	      drawPath();
+	      if (t > 0) {
+	        drawT(points, t - STEP);
+	      }
 	    }
 	    document.onmouseup = function() {
 	      document.onmousemove = document.onmouseup = null;
@@ -212,6 +215,7 @@ http://www.w3.org/Graphics/SVG/IG/resources/svgprimer.html#path_C
 	  }
 	}
 
+	const STEP = 0.005;
 	let t = 0;
 	let timer;
 
@@ -241,7 +245,7 @@ http://www.w3.org/Graphics/SVG/IG/resources/svgprimer.html#path_C
 	      return;
 	    }
 
-	    t += 0.005;
+	    t += STEP;
 	  }, 30);
 	}
 
diff --git a/7-animation/2-css-animations/1-animate-logo-css/solution.view/index.html b/7-animation/2-css-animations/1-animate-logo-css/solution.view/index.html
index 4e90e2478..d77f25e28 100644
--- a/7-animation/2-css-animations/1-animate-logo-css/solution.view/index.html
+++ b/7-animation/2-css-animations/1-animate-logo-css/solution.view/index.html
@@ -27,12 +27,12 @@
   <img id="flyjet" src="https://en.js.cx/clipart/flyjet.jpg">
 
   <script>
-    flyjet.onclick = function() {
+    let ended = false; // will change to true after the animation finishes
 
-      let ended = false;
+    flyjet.onclick = function() {
 
       flyjet.addEventListener('transitionend', function() {
-        if (!ended) {
+        if (!ended) { // check to show the message only once
           ended = true;
           alert('Done!');
         }
diff --git a/7-animation/2-css-animations/2-animate-logo-bezier-css/task.md b/7-animation/2-css-animations/2-animate-logo-bezier-css/task.md
index 9e21f4101..18e63b480 100644
--- a/7-animation/2-css-animations/2-animate-logo-bezier-css/task.md
+++ b/7-animation/2-css-animations/2-animate-logo-bezier-css/task.md
@@ -4,7 +4,7 @@ importance: 5
 
 # Animate the flying plane (CSS)
 
-Modify the solution of the previous task <info:task/animate-logo-css> to make the plane grow more than it's original size 400x240px (jump out), and then return to that size.
+Modify the solution of the previous task <info:task/animate-logo-css> to make the plane grow more than its original size 400x240px (jump out), and then return to that size.
 
 Here's how it should look (click on the plane):
 
diff --git a/7-animation/2-css-animations/3-animate-circle/solution.view/index.html b/7-animation/2-css-animations/3-animate-circle/solution.view/index.html
index 88b154254..43b927e8a 100644
--- a/7-animation/2-css-animations/3-animate-circle/solution.view/index.html
+++ b/7-animation/2-css-animations/3-animate-circle/solution.view/index.html
@@ -5,7 +5,7 @@
   <meta charset="utf-8">
   <style>
     .circle {
-      transition-property: width, height, margin-left, margin-top;
+      transition-property: width, height;
       transition-duration: 2s;
       position: fixed;
       transform: translateX(-50%) translateY(-50%);
diff --git a/7-animation/2-css-animations/3-animate-circle/source.view/index.html b/7-animation/2-css-animations/3-animate-circle/source.view/index.html
index a423280de..e305f4cf6 100644
--- a/7-animation/2-css-animations/3-animate-circle/source.view/index.html
+++ b/7-animation/2-css-animations/3-animate-circle/source.view/index.html
@@ -5,7 +5,7 @@
   <meta charset="utf-8">
   <style>
     .circle {
-      transition-property: width, height, margin-left, margin-top;
+      transition-property: width, height;
       transition-duration: 2s;
       position: fixed;
       transform: translateX(-50%) translateY(-50%);
diff --git a/1-js/11-async/01-callbacks/01-animate-circle-callback/solution.md b/7-animation/2-css-animations/4-animate-circle-callback/solution.md
similarity index 100%
rename from 1-js/11-async/01-callbacks/01-animate-circle-callback/solution.md
rename to 7-animation/2-css-animations/4-animate-circle-callback/solution.md
diff --git a/1-js/11-async/01-callbacks/01-animate-circle-callback/solution.view/index.html b/7-animation/2-css-animations/4-animate-circle-callback/solution.view/index.html
similarity index 94%
rename from 1-js/11-async/01-callbacks/01-animate-circle-callback/solution.view/index.html
rename to 7-animation/2-css-animations/4-animate-circle-callback/solution.view/index.html
index b2192681c..64746e85f 100644
--- a/1-js/11-async/01-callbacks/01-animate-circle-callback/solution.view/index.html
+++ b/7-animation/2-css-animations/4-animate-circle-callback/solution.view/index.html
@@ -10,7 +10,7 @@
       text-align: center;
     }
     .circle {
-      transition-property: width, height, margin-left, margin-top;
+      transition-property: width, height;
       transition-duration: 2s;
       position: fixed;
       transform: translateX(-50%) translateY(-50%);
diff --git a/1-js/11-async/01-callbacks/01-animate-circle-callback/task.md b/7-animation/2-css-animations/4-animate-circle-callback/task.md
similarity index 100%
rename from 1-js/11-async/01-callbacks/01-animate-circle-callback/task.md
rename to 7-animation/2-css-animations/4-animate-circle-callback/task.md
diff --git a/7-animation/2-css-animations/article.md b/7-animation/2-css-animations/article.md
index 844a27587..a6a41eaeb 100644
--- a/7-animation/2-css-animations/article.md
+++ b/7-animation/2-css-animations/article.md
@@ -1,14 +1,14 @@
 # CSS-animations
 
-CSS animations allow to do simple animations without JavaScript at all.
+CSS animations make it possible to do simple animations without JavaScript at all.
 
-JavaScript can be used to control CSS animation and make it even better with a little of code.
+JavaScript can be used to control CSS animations and make them even better, with little code.
 
 ## CSS transitions [#css-transition]
 
 The idea of CSS transitions is simple. We describe a property and how its changes should be animated. When the property changes, the browser paints the animation.
 
-That is: all we need is to change the property. And the fluent transition is made by the browser.
+That is, all we need is to change the property, and the fluid transition will be done by the browser.
 
 For instance, the CSS below animates changes of `background-color` for 3 seconds:
 
@@ -47,7 +47,7 @@ There are 4 properties to describe CSS transitions:
 - `transition-timing-function`
 - `transition-delay`
 
-We'll cover them in a moment, for now let's note that the common `transition` property allows to declare them together in the order: `property duration timing-function delay`, and also animate multiple properties at once.
+We'll cover them in a moment, for now let's note that the common `transition` property allows declaring them together in the order: `property duration timing-function delay`, as well as animating multiple properties at once.
 
 For instance, this button animates both `color` and `font-size`:
 
@@ -70,25 +70,25 @@ growing.onclick = function() {
 </script>
 ```
 
-Now let's cover animation properties one by one.
+Now, let's cover animation properties one by one.
 
 ## transition-property
 
-In `transition-property` we write a list of property to animate, for instance: `left`, `margin-left`, `height`, `color`.
+In `transition-property`, we write a list of properties to animate, for instance: `left`, `margin-left`, `height`, `color`. Or we could write `all`, which means "animate all properties".
 
-Not all properties can be animated, but [many of them](http://www.w3.org/TR/css3-transitions/#animatable-properties-). The value `all` means "animate all properties".
+Do note that, there are properties which can not be animated. However, [most of the generally used properties are animatable](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animated_properties).
 
 ## transition-duration
 
-In `transition-duration` we can specify how long the animation should take. The time should be in [CSS time format](http://www.w3.org/TR/css3-values/#time): in seconds `s` or milliseconds `ms`.
+In `transition-duration` we can specify how long the animation should take. The time should be in [CSS time format](https://www.w3.org/TR/css3-values/#time): in seconds `s` or milliseconds `ms`.
 
 ## transition-delay
 
-In `transition-delay` we can specify the delay *before* the animation. For instance, if  `transition-delay: 1s`, then animation starts after 1 second after the change.
+In `transition-delay` we can specify the delay *before* the animation. For instance, if `transition-delay` is `1s` and `transition-duration` is `2s`, then the animation starts 1 second after the property change and the total duration will be 2 seconds.
 
-Negative values are also possible. Then the animation starts from the middle. For instance, if `transition-duration` is `2s`, and the delay is `-1s`, then the animation takes 1 second and starts from the half.
+Negative values are also possible. Then the animation is shown immediately, but the starting point of the animation will be after given value (time). For example, if `transition-delay` is `-1s` and `transition-duration` is `2s`, then animation starts from the halfway point and total duration will be 1 second.
 
-Here's the animation shifts numbers from `0` to `9` using CSS `translate` property:
+Here the animation shifts numbers from `0` to `9` using CSS `translate` property:
 
 [codetabs src="digits"]
 
@@ -108,13 +108,13 @@ In the example above JavaScript adds the class `.animate` to the element -- and
 stripe.classList.add('animate');
 ```
 
-We can also start it "from the middle", from the exact number, e.g. corresponding to the current second, using the negative `transition-delay`.
+We could also start it from somewhere in the middle of the transition, from an exact number, e.g. corresponding to the current second, using a negative `transition-delay`.
 
 Here if you click the digit -- it starts the animation from the current second:
 
 [codetabs src="digits-negative-delay"]
 
-JavaScript does it by an extra line:
+JavaScript does it with an extra line:
 
 ```js
 stripe.onclick = function() {
@@ -129,25 +129,25 @@ stripe.onclick = function() {
 
 ## transition-timing-function
 
-Timing function describes how the animation process is distributed along the time. Will it start slowly and then go fast or vise versa.
+The timing function describes how the animation process is distributed along its timeline. Will it start slowly and then go fast, or vice versa.
 
-That's the most complicated property from the first sight. But it becomes very simple if we devote a bit time to it.
+It appears to be the most complicated property at first. But it becomes very simple if we devote a bit time to it.
 
-That property accepts two kinds of values: a Bezier curve or steps. Let's start from the curve, as it's used more often.
+That property accepts two kinds of values: a Bezier curve or steps. Let's start with the curve, as it's used more often.
 
 ### Bezier curve
 
-The timing function can be set as a [Bezier curve](/bezier-curve) with 4 control points that satisfies the conditions:
+The timing function can be set as a [Bezier curve](/bezier-curve) with 4 control points that satisfy the conditions:
 
 1. First control point: `(0,0)`.
 2. Last control point: `(1,1)`.
-3. For intermediate points values of `x` must be in the interval `0..1`, `y` can be anything.
+3. For intermediate points, the values of `x` must be in the interval `0..1`, `y` can be anything.
 
 The syntax for a Bezier curve in CSS: `cubic-bezier(x2, y2, x3, y3)`. Here we need to specify only 2nd and 3rd control points, because the 1st one is fixed to `(0,0)` and the 4th one is `(1,1)`.
 
-The timing function describes how fast the animation process goes in time.
+The timing function describes how fast the animation process goes.
 
-- The `x` axis is the time: `0` -- the starting moment, `1` -- the last moment of `transition-duration`.
+- The `x` axis is the time: `0` -- the start, `1` -- the end of `transition-duration`.
 - The `y` axis specifies the completion of the process: `0` -- the starting value of the property, `1` -- the final value.
 
 The simplest variant is when the animation goes uniformly, with the same linear speed. That can be specified by the curve `cubic-bezier(0, 0, 1, 1)`.
@@ -168,7 +168,7 @@ The CSS `transition` is based on that curve:
 .train {
   left: 0;
   transition: left 5s cubic-bezier(0, 0, 1, 1);
-  /* JavaScript sets left to 450px */
+  /* click on a train sets left to 450px, thus triggering the animation */
 }
 ```
 
@@ -191,13 +191,13 @@ CSS:
 .train {
   left: 0;
   transition: left 5s cubic-bezier(0, .5, .5, 1);
-  /* JavaScript sets left to 450px */
+  /* click on a train sets left to 450px, thus triggering the animation */
 }
 ```
 
 There are several built-in curves: `linear`, `ease`, `ease-in`, `ease-out` and `ease-in-out`.
 
-The `linear` is a shorthand for `cubic-bezier(0, 0, 1, 1)` -- a straight line, we saw it already.
+The `linear` is a shorthand for `cubic-bezier(0, 0, 1, 1)` -- a straight line, which we described above.
 
 Other names are shorthands for the following `cubic-bezier`:
 
@@ -210,27 +210,27 @@ Other names are shorthands for the following `cubic-bezier`:
 
 So we could use `ease-out` for our slowing down train:
 
-
 ```css
 .train {
   left: 0;
   transition: left 5s ease-out;
-  /* transition: left 5s cubic-bezier(0, .5, .5, 1); */
+  /* same as transition: left 5s cubic-bezier(0, .5, .5, 1); */
 }
 ```
 
 But it looks a bit differently.
 
-**A Bezier curve can make the animation "jump out" of its range.**
+**A Bezier curve can make the animation exceed its range.**
 
-The control points on the curve can have any `y` coordinates: even negative or huge. Then the Bezier curve would also jump very low or high, making the animation go beyond its normal range.
+The control points on the curve can have any `y` coordinates: even negative or huge ones. Then the Bezier curve would also extend very low or high, making the animation go beyond its normal range.
 
 In the example below the animation code is:
+
 ```css
 .train {
   left: 100px;
   transition: left 5s cubic-bezier(.5, -1, .5, 2);
-  /* JavaScript sets left to 400px */
+  /* click on a train sets left to 450px */
 }
 ```
 
@@ -244,21 +244,29 @@ But if you click the train, you'll see that:
 
 [codetabs src="train-over"]
 
-Why it happens -- pretty obvious if we look at the graph of the given Bezier curve:
+Why it happens is pretty obvious if we look at the graph of the given Bezier curve:
 
 ![](bezier-train-over.svg)
 
-We moved the `y` coordinate of the 2nd point below zero, and for the 3rd point we made put it over `1`, so the curve goes out of the "regular" quadrant. The `y` is out of the "standard" range `0..1`.
+We moved the `y` coordinate of the 2nd point below zero, and for the 3rd point we made it over `1`, so the curve goes out of the "regular" quadrant. The `y` is out of the "standard" range `0..1`.
 
-As we know, `y` measures "the completion of the animation process". The value `y = 0` corresponds to the starting property value and `y = 1` -- the ending value. So values `y<0` move the property lower than the starting `left` and `y>1` -- over the final `left`.
+As we know, `y` measures "the completion of the animation process". The value `y = 0` corresponds to the starting property value and `y = 1` -- the ending value. So values `y<0` move the property beyond the starting `left` and `y>1` -- past the final `left`.
 
 That's a "soft" variant for sure. If we put `y` values like `-99` and `99` then the train would jump out of the range much more.
 
-But how to make the Bezier curve for a specific task? There are many tools. For instance, we can do it on the site <http://cubic-bezier.com/>.
+But how do we make a Bezier curve for a specific task? There are many tools.
+
+- For instance, we can do it on the site <https://cubic-bezier.com>.
+- Browser developer tools also have special support for Bezier curves in CSS:
+    1. Open the developer tools with `key:F12` (Mac: `key:Cmd+Opt+I`).
+    2. Select the `Elements` tab, then pay attention to the `Styles` sub-panel at the right side.
+    3. CSS properties with a word `cubic-bezier` will have an icon before this word.
+    4. Click this icon to edit the curve.
+
 
 ### Steps
 
-Timing function `steps(number of steps[, start/end])` allows to split animation into steps.
+The timing function `steps(number of steps[, start/end])` allows splitting an transition into multiple steps.
 
 Let's see that in an example with digits.
 
@@ -266,7 +274,19 @@ Here's a list of digits, without any animations, just as a source:
 
 [codetabs src="step-list"]
 
-We'll make the digits appear in a discrete way by making the part of the list outside of the red "window" invisible and shifting the list to the left with each step.
+In the HTML, a stripe of digits is enclosed into a fixed-length `<div id="digits">`:
+
+```html
+<div id="digit">
+  <div id="stripe">0123456789</div>
+</div>
+```
+
+The `#digit` div has a fixed width and a border, so it looks like a red window.
+
+We'll make a timer: the digits will appear one by one, in a discrete way.
+
+To achieve that, we'll hide the `#stripe` outside of `#digit` using `overflow: hidden`, and then shift the `#stripe` to the left step-by-step.
 
 There will be 9 steps, a step-move for each digit:
 
@@ -277,58 +297,60 @@ There will be 9 steps, a step-move for each digit:
 }
 ```
 
-In action:
-
-[codetabs src="step"]
-
 The first argument of `steps(9, start)` is the number of steps. The transform will be split into 9 parts (10% each). The time interval is automatically divided into 9 parts as well, so `transition: 9s` gives us 9 seconds for the whole animation – 1 second per digit.
 
 The second argument is one of two words: `start` or `end`.
 
-The `start` means that in the beginning of animation we need to do make the first step immediately.
+The `start` means that in the beginning of animation we need to make the first step immediately.
+
+In action:
+
+[codetabs src="step"]
 
-We can observe that during the animation: when we click on the digit it changes to `1` (the first step) immediately, and then changes in the beginning of the next second.
+A click on the digit changes it to `1` (the first step) immediately, and then changes in the beginning of the next second.
 
 The process is progressing like this:
 
 - `0s` -- `-10%` (first change in the beginning of the 1st second, immediately)
 - `1s` -- `-20%`
 - ...
-- `8s` -- `-80%`
+- `8s` -- `-90%`
 - (the last second shows the final value).
 
+Here, the first change was immediate because of `start` in the `steps`.
+
 The alternative value `end` would mean that the change should be applied not in the beginning, but at the end of each second.
 
-So the process would go like this:
+So the process for `steps(9, end)` would go like this:
 
-- `0s` -- `0`
+- `0s` -- `0` (during the first second nothing changes)
 - `1s` -- `-10%` (first change at the end of the 1st second)
 - `2s` -- `-20%`
 - ...
 - `9s` -- `-90%`
 
-Here's `step(9, end)` in action (note the pause between the first digit change):
+Here's `steps(9, end)` in action (note the pause before the first digit change):
 
 [codetabs src="step-end"]
 
-There are also shorthand values:
+There are also some pre-defined shorthands for `steps(...)`:
 
 - `step-start` -- is the same as `steps(1, start)`. That is, the animation starts immediately and takes 1 step. So it starts and finishes immediately, as if there were no animation.
 - `step-end` -- the same as `steps(1, end)`: make the animation in a single step at the end of `transition-duration`.
 
-These values are rarely used, because that's not really animation, but rather a single-step change.
+These values are rarely used, as they represent not a real animation, but rather a single-step change. We mention them here for completeness.
 
-## Event transitionend
+## Event: "transitionend"
 
-When the CSS animation finishes the `transitionend` event triggers.
+When the CSS animation finishes, the `transitionend` event triggers.
 
 It is widely used to do an action after the animation is done. Also we can join animations.
 
-For instance, the ship in the example below starts to swim there and back on click, each time farther and farther to the right:
+For instance, the ship in the example below starts to sail there and back when clicked, each time farther and farther to the right:
 
 [iframe src="boat" height=300 edit link]
 
-The animation is initiated by the function `go` that re-runs each time when the transition finishes and flips the direction:
+The animation is initiated by the function `go` that re-runs each time the transition finishes, and flips the direction:
 
 ```js
 boat.onclick = function() {
@@ -337,11 +359,11 @@ boat.onclick = function() {
 
   function go() {
     if (times % 2) {
-      // swim to the right
+      // sail to the right
       boat.classList.remove('back');
       boat.style.marginLeft = 100 * times + 200 + 'px';
     } else {
-      // swim to the left
+      // sail to the left
       boat.classList.add('back');
       boat.style.marginLeft = 100 * times - 200 + 'px';
     }
@@ -357,7 +379,7 @@ boat.onclick = function() {
 };
 ```
 
-The event object for `transitionend` has few specific properties:
+The event object for `transitionend` has a few specific properties:
 
 `event.propertyName`
 : The property that has finished animating. Can be good if we animate multiple properties simultaneously.
@@ -369,7 +391,7 @@ The event object for `transitionend` has few specific properties:
 
 We can join multiple simple animations together using the `@keyframes` CSS rule.
 
-It specifies the "name" of the animation and rules: what, when and where to animate. Then using the `animation` property we attach the animation to the element and specify additional parameters for it.
+It specifies the "name" of the animation and rules - what, when and where to animate. Then using the `animation` property, we can attach the animation to the element and specify additional parameters for it.
 
 Here's an example with explanations:
 
@@ -405,11 +427,92 @@ Here's an example with explanations:
 
 There are many articles about `@keyframes` and a [detailed specification](https://drafts.csswg.org/css-animations/).
 
-Probably you won't need `@keyframes` often, unless everything is in the constant move on your sites.
+You probably won't need `@keyframes` often, unless everything is in constant motion on your sites.
+
+## Performance
+
+Most CSS properties can be animated, because most of them are numeric values. For instance, `width`, `color`, `font-size` are all numbers. When you animate them, the browser gradually changes these numbers frame by frame, creating a smooth effect.
+
+However, not all animations will look as smooth as you'd like, because different CSS properties cost differently to change.
+
+In more technical details, when there's a style change, the browser goes through 3 steps to render the new look:
+
+1. **Layout**: re-compute the geometry and position of each element, then
+2. **Paint**: re-compute how everything should look like at their places, including background, colors,
+3. **Composite**: render the final results into pixels on screen, apply CSS transforms if they exist.
+
+During a CSS animation, this process repeats every frame. However, CSS properties that never affect geometry or position, such as `color`, may skip the Layout step. If a `color` changes, the browser  doesn't calculate any new geometry, it goes to Paint -> Composite. And there are few properties that directly go to Composite. You can find a longer list of CSS properties and which stages they trigger at <https://csstriggers.com>.
+
+The calculations may take time, especially on pages with many elements and a complex layout. And the delays are actually visible on most devices, leading to "jittery", less fluid animations.
+
+Animations of properties that skip the Layout step are faster. It's even better if Paint is skipped too.
+
+The `transform` property is a great choice, because:
+- CSS transforms affect the target element box as a whole (rotate, flip, stretch, shift it).
+- CSS transforms never affect neighbour elements.
+
+...So browsers apply `transform` "on top" of existing Layout and Paint calculations, in the Composite stage.
+
+In other words, the browser calculates the Layout (sizes, positions), paints it with colors, backgrounds, etc at the Paint stage, and then applies `transform` to element boxes that need it.
+
+Changes (animations) of the `transform` property never trigger Layout and Paint steps. More than that, the browser  leverages the graphics accelerator (a special chip on the CPU or graphics card) for CSS transforms, thus making them very efficient.
+
+Luckily, the `transform` property is very powerful. By using `transform` on an element, you could rotate and flip it, stretch and shrink it, move it around, and [much more](https://developer.mozilla.org/docs/Web/CSS/transform#syntax). So instead of `left/margin-left` properties we can use `transform: translateX(…)`, use `transform: scale` for increasing element size, etc.
+
+The `opacity` property also never triggers Layout (also skips Paint in Mozilla Gecko). We can use it for show/hide or fade-in/fade-out effects.
+
+Paring `transform` with `opacity` can usually solve most of our needs, providing fluid, good-looking animations.
+
+For example, here clicking on the `#boat` element adds the class with `transform: translateX(300px)` and `opacity: 0`, thus making it move `300px` to the right and disappear:
+
+```html run height=260 autorun no-beautify
+<img src="https://js.cx/clipart/boat.png" id="boat">
+
+<style>
+#boat {
+  cursor: pointer;
+  transition: transform 2s ease-in-out, opacity 2s ease-in-out;
+}
+
+.move {
+  transform: translateX(300px);
+  opacity: 0;
+}
+</style>
+<script>
+  boat.onclick = () => boat.classList.add('move');
+</script>
+```
+
+Here's a more complex example, with `@keyframes`:
+
+```html run height=80 autorun no-beautify
+<h2 onclick="this.classList.toggle('animated')">click me to start / stop</h2>
+<style>
+  .animated {
+    animation: hello-goodbye 1.8s infinite;
+    width: fit-content;
+  }
+  @keyframes hello-goodbye {
+    0% {
+      transform: translateY(-60px) rotateX(0.7turn);
+      opacity: 0;
+    }
+    50% {
+      transform: none;
+      opacity: 1;
+    }
+    100% {
+      transform: translateX(230px) rotateZ(90deg) scale(0.5);
+      opacity: 0;
+    }
+  }
+</style>
+```
 
 ## Summary
 
-CSS animations allow to smoothly (or not) animate changes of one or multiple CSS properties.
+CSS animations allow smoothly (or step-by-step) animated changes of one or multiple CSS properties.
 
 They are good for most animation tasks. We're also able to use JavaScript for animations, the next chapter is devoted to that.
 
@@ -419,9 +522,11 @@ Limitations of CSS animations compared to JavaScript animations:
 + Simple things done simply.
 + Fast and lightweight for CPU.
 - JavaScript animations are flexible. They can implement any animation logic, like an "explosion" of an element.
-- Not just property changes. We can create new elements in JavaScript for purposes of animation.
+- Not just property changes. We can create new elements in JavaScript as part of the animation.
 ```
 
-The majority of animations can be implemented using CSS as described in this chapter. And  `transitionend` event allows to run JavaScript after the animation, so it integrates fine with the code.
+In early examples in this chapter, we animate `font-size`, `left`, `width`, `height`, etc. In real life projects, we should use `transform: scale()` and `transform: translate()` for better performance.
+
+The majority of animations can be implemented using CSS as described in this chapter. And the `transitionend` event allows JavaScript to be run after the animation, so it integrates fine with the code.
 
 But in the next chapter we'll do some JavaScript animations to cover more complex cases.
diff --git a/7-animation/3-js-animation/1-animate-ball/solution.md b/7-animation/3-js-animation/1-animate-ball/solution.md
index 5d3f08eef..0dc67b8bd 100644
--- a/7-animation/3-js-animation/1-animate-ball/solution.md
+++ b/7-animation/3-js-animation/1-animate-ball/solution.md
@@ -2,7 +2,7 @@ To bounce we can use CSS property `top` and `position:absolute` for the ball ins
 
 The bottom coordinate of the field is `field.clientHeight`. The CSS `top` property refers to the upper edge of the ball. So it should go from `0` till `field.clientHeight - ball.clientHeight`, that's the final lowest position of the upper edge of the ball.
 
-To to get the "bouncing" effect we can use the timing function `bounce` in `easeOut` mode.
+To get the "bouncing" effect we can use the timing function `bounce` in `easeOut` mode.
 
 Here's the final code for the animation:
 
diff --git a/7-animation/3-js-animation/1-animate-ball/solution.view/index.html b/7-animation/3-js-animation/1-animate-ball/solution.view/index.html
index 7e031e8d1..146033cf7 100644
--- a/7-animation/3-js-animation/1-animate-ball/solution.view/index.html
+++ b/7-animation/3-js-animation/1-animate-ball/solution.view/index.html
@@ -21,7 +21,7 @@
     }
 
     function bounce(timeFraction) {
-      for (let a = 0, b = 1, result; 1; a += b, b /= 2) {
+      for (let a = 0, b = 1; 1; a += b, b /= 2) {
         if (timeFraction >= (7 - 4 * a) / 11) {
           return -Math.pow((11 - 6 * a - 11 * timeFraction) / 4, 2) + Math.pow(b, 2)
         }
diff --git a/7-animation/3-js-animation/2-animate-ball-hops/solution.view/index.html b/7-animation/3-js-animation/2-animate-ball-hops/solution.view/index.html
index b246f422f..f587ff607 100644
--- a/7-animation/3-js-animation/2-animate-ball-hops/solution.view/index.html
+++ b/7-animation/3-js-animation/2-animate-ball-hops/solution.view/index.html
@@ -21,7 +21,7 @@
     }
 
     function bounce(timeFraction) {
-      for (let a = 0, b = 1, result; 1; a += b, b /= 2) {
+      for (let a = 0, b = 1; 1; a += b, b /= 2) {
         if (timeFraction >= (7 - 4 * a) / 11) {
           return -Math.pow((11 - 6 * a - 11 * timeFraction) / 4, 2) + Math.pow(b, 2)
         }
diff --git a/7-animation/3-js-animation/article.md b/7-animation/3-js-animation/article.md
index 004954340..b85e91e21 100644
--- a/7-animation/3-js-animation/article.md
+++ b/7-animation/3-js-animation/article.md
@@ -77,9 +77,9 @@ setInterval(animate3, 20);
 
 These several independent redraws should be grouped together, to make the redraw easier for the browser and hence load less CPU load and look smoother.
 
-There's one more thing to keep in mind. Sometimes when CPU is overloaded, or there are other reasons to redraw less often (like when the browser tab is hidden), so we really shouldn't run it every `20ms`.
+There's one more thing to keep in mind. Sometimes CPU is overloaded, or there are other reasons to redraw less often (like when the browser tab is hidden), so we really shouldn't run it every `20ms`.
 
-But how do we know about that in JavaScript? There's a specification [Animation timing](http://www.w3.org/TR/animation-timing/) that provides the function `requestAnimationFrame`. It addresses all these issues and even more.
+But how do we know about that in JavaScript? There's a specification [Animation timing](https://www.w3.org/TR/animation-timing/) that provides the function `requestAnimationFrame`. It addresses all these issues and even more.
 
 The syntax:
 ```js
@@ -96,7 +96,7 @@ The returned value `requestId` can be used to cancel the call:
 cancelAnimationFrame(requestId);
 ```
 
-The `callback` gets one argument -- the time passed from the beginning of the page load in microseconds. This time can also be obtained by calling [performance.now()](mdn:api/Performance/now).
+The `callback` gets one argument -- the time passed from the beginning of the page load in milliseconds. This time can also be obtained by calling [performance.now()](mdn:api/Performance/now).
 
 Usually `callback` runs very soon, unless the CPU is overloaded or the laptop battery is almost discharged, or there's another reason.
 
@@ -159,7 +159,7 @@ Function `animate` accepts 3 parameters that essentially describes the animation
     }
     ```
 
-    It's graph:
+    Its graph:
     ![](linear.svg)
 
     That's just like `transition-timing-function: linear`. There are more interesting variants shown below.
@@ -227,7 +227,7 @@ See in action (click to activate):
 
 [iframe height=40 src="quad" link]
 
-...Or the cubic curve or event greater `n`. Increasing the power makes it speed up faster.
+...Or the cubic curve or even greater `n`. Increasing the power makes it speed up faster.
 
 Here's the graph for `progress` in the power `5`:
 
@@ -283,7 +283,7 @@ The `bounce` function does the same, but in the reverse order: "bouncing" starts
 
 ```js
 function bounce(timeFraction) {
-  for (let a = 0, b = 1, result; 1; a += b, b /= 2) {
+  for (let a = 0, b = 1; 1; a += b, b /= 2) {
     if (timeFraction >= (7 - 4 * a) / 11) {
       return -Math.pow((11 - 6 * a - 11 * timeFraction) / 4, 2) + Math.pow(b, 2)
     }
@@ -397,7 +397,7 @@ The effect is clearly seen if we compare the graphs of `easeIn`, `easeOut` and `
 
 ![](circ-ease.svg)
 
-- <span style="color:#EE6B47">Red</span> is the regular variantof `circ` (`easeIn`).
+- <span style="color:#EE6B47">Red</span> is the regular variant of `circ` (`easeIn`).
 - <span style="color:#8DB173">Green</span> -- `easeOut`.
 - <span style="color:#62C0DC">Blue</span> -- `easeInOut`.
 
@@ -405,7 +405,7 @@ As we can see, the graph of the first half of the animation is the scaled down `
 
 ## More interesting "draw"
 
-Instead of moving the element we can do something else. All we need is to write the write the proper `draw`.
+Instead of moving the element we can do something else. All we need is to write the proper `draw`.
 
 Here's the animated "bouncing" text typing:
 
@@ -452,4 +452,4 @@ Surely we could improve it, add more bells and whistles, but JavaScript animatio
 
 JavaScript animations can use any timing function. We covered a lot of examples and transformations to make them even more versatile. Unlike CSS, we are not limited to Bezier curves here.
 
-The same is about `draw`: we can animate anything, not just CSS properties.
+The same is true about `draw`: we can animate anything, not just CSS properties.
diff --git a/7-animation/3-js-animation/bounce-easeinout.view/index.html b/7-animation/3-js-animation/bounce-easeinout.view/index.html
index 837c50db1..aed3d9d08 100644
--- a/7-animation/3-js-animation/bounce-easeinout.view/index.html
+++ b/7-animation/3-js-animation/bounce-easeinout.view/index.html
@@ -26,7 +26,7 @@
 
 
     function bounce(timeFraction) {
-      for (let a = 0, b = 1, result; 1; a += b, b /= 2) {
+      for (let a = 0, b = 1; 1; a += b, b /= 2) {
         if (timeFraction >= (7 - 4 * a) / 11) {
           return -Math.pow((11 - 6 * a - 11 * timeFraction) / 4, 2) + Math.pow(b, 2)
         }
diff --git a/7-animation/3-js-animation/bounce-easeout.view/index.html b/7-animation/3-js-animation/bounce-easeout.view/index.html
index e52eae8de..69dbb7ce0 100644
--- a/7-animation/3-js-animation/bounce-easeout.view/index.html
+++ b/7-animation/3-js-animation/bounce-easeout.view/index.html
@@ -22,7 +22,7 @@
     }
 
     function bounce(timeFraction) {
-      for (let a = 0, b = 1, result; 1; a += b, b /= 2) {
+      for (let a = 0, b = 1; 1; a += b, b /= 2) {
         if (timeFraction >= (7 - 4 * a) / 11) {
           return -Math.pow((11 - 6 * a - 11 * timeFraction) / 4, 2) + Math.pow(b, 2)
         }
diff --git a/7-animation/3-js-animation/bounce.view/index.html b/7-animation/3-js-animation/bounce.view/index.html
index 1be2580d9..3575ed820 100644
--- a/7-animation/3-js-animation/bounce.view/index.html
+++ b/7-animation/3-js-animation/bounce.view/index.html
@@ -19,7 +19,7 @@
       animate({
         duration: 3000,
         timing: function bounce(timeFraction) {
-          for (let a = 0, b = 1, result; 1; a += b, b /= 2) {
+          for (let a = 0, b = 1; 1; a += b, b /= 2) {
             if (timeFraction >= (7 - 4 * a) / 11) {
               return -Math.pow((11 - 6 * a - 11 * timeFraction) / 4, 2) + Math.pow(b, 2)
             }
diff --git a/7-animation/3-js-animation/text.view/index.html b/7-animation/3-js-animation/text.view/index.html
index e404fe5c4..4947e4cd4 100644
--- a/7-animation/3-js-animation/text.view/index.html
+++ b/7-animation/3-js-animation/text.view/index.html
@@ -29,14 +29,14 @@
         timing: bounce,
         draw: function(progress) {
           let result = (to - from) * progress + from;
-          textArea.value = text.substr(0, Math.ceil(result))
+          textArea.value = text.slice(0, Math.ceil(result))
         }
       });
     }
 
 
     function bounce(timeFraction) {
-      for (let a = 0, b = 1, result; 1; a += b, b /= 2) {
+      for (let a = 0, b = 1; 1; a += b, b /= 2) {
         if (timeFraction >= (7 - 4 * a) / 11) {
           return -Math.pow((11 - 6 * a - 11 * timeFraction) / 4, 2) + Math.pow(b, 2)
         }
diff --git a/8-web-components/1-webcomponents-intro/article.md b/8-web-components/1-webcomponents-intro/article.md
index 3279cb133..c3522dea9 100644
--- a/8-web-components/1-webcomponents-intro/article.md
+++ b/8-web-components/1-webcomponents-intro/article.md
@@ -26,9 +26,9 @@ The International Space Station:
 
 ...And this thing flies, keeps humans alive in space!
 
-How such complex devices are created?
+How are such complex devices created?
 
-Which principles we could borrow to make our development same-level reliable and scalable? Or, at least, close to it.
+Which principles could we borrow to make our development same-level reliable and scalable? Or, at least, close to it?
 
 ## Component architecture
 
diff --git a/8-web-components/2-custom-elements/article.md b/8-web-components/2-custom-elements/article.md
index 702ff9073..a84ed1192 100644
--- a/8-web-components/2-custom-elements/article.md
+++ b/8-web-components/2-custom-elements/article.md
@@ -115,7 +115,7 @@ customElements.define("time-formatted", TimeFormatted); // (2)
 ></time-formatted>
 ```
 
-1. The class has only one method `connectedCallback()` -- the browser calls it when `<time-formatted>` element is added to page (or when HTML parser detects it), and it uses the built-in [Intl.DateTimeFormat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat) data formatter, well-supported across the browsers, to show a nicely formatted time.
+1. The class has only one method `connectedCallback()` -- the browser calls it when `<time-formatted>` element is added to page (or when HTML parser detects it), and it uses the built-in [Intl.DateTimeFormat](mdn:/JavaScript/Reference/Global_Objects/DateTimeFormat) data formatter, well-supported across the browsers, to show a nicely formatted time.
 2. We need to register our new element by `customElements.define(tag, class)`.
 3. And then we can use it everywhere.
 
@@ -149,7 +149,7 @@ The `connectedCallback` triggers when the element is added to the document. Not
 
 In the current implementation of `<time-formatted>`, after the element is rendered, further attribute changes don't have any effect. That's strange for an HTML element. Usually, when we change an attribute, like `a.href`, we expect the change to be immediately visible. So let's fix this.
 
-We can observe attributes by providing their list in `observedAttributes()` static getter. For such attributes, `attributeChangedCallback` is called when they are modified. It doesn't trigger for an attribute for performance reasons.
+We can observe attributes by providing their list in `observedAttributes()` static getter. For such attributes, `attributeChangedCallback` is called when they are modified. It doesn't trigger for other, unlisted attributes (that's for performance reasons).
 
 Here's a new `<time-formatted>`, that auto-updates when attributes change:
 
@@ -320,7 +320,7 @@ For example, buttons are instances of `HTMLButtonElement`, let's build upon it.
     class HelloButton extends HTMLButtonElement { /* custom element methods */ }
     ```
 
-2. Provide an third argument to `customElements.define`, that specifies the tag:
+2. Provide the third argument to `customElements.define`, that specifies the tag:
     ```js
     customElements.define('hello-button', HelloButton, *!*{extends: 'button'}*/!*);
     ```    
@@ -365,7 +365,7 @@ Our new button extends the built-in one. So it keeps the same styles and standar
 ## References
 
 - HTML Living Standard: <https://html.spec.whatwg.org/#custom-elements>.
-- Compatiblity: <https://caniuse.com/#feat=custom-elements>.
+- Compatiblity: <https://caniuse.com/#feat=custom-elementsv1>.
 
 ## Summary
 
@@ -397,4 +397,4 @@ Custom elements can be of two types:
     /* <button is="my-button"> */
     ```
 
-Custom elements are well-supported among browsers. Edge is a bit behind, but there's a polyfill <https://github.com/webcomponents/polyfills/tree/master/packages/webcomponentsjs>.
+Custom elements are well-supported among browsers. There's a polyfill <https://github.com/webcomponents/polyfills/tree/master/packages/webcomponentsjs>.
diff --git a/8-web-components/3-shadow-dom/article.md b/8-web-components/3-shadow-dom/article.md
index fafc4754c..92614f777 100644
--- a/8-web-components/3-shadow-dom/article.md
+++ b/8-web-components/3-shadow-dom/article.md
@@ -37,7 +37,7 @@ input::-webkit-slider-runnable-track {
 
 Once again, `pseudo` is a non-standard attribute. Chronologically, browsers first started to experiment with internal DOM structures to implement controls, and then, after time, shadow DOM was standardized to allow us, developers, to do the similar thing.
 
-Further on, we'll use the modern shadow DOM standard, covered by [DOM spec](https://dom.spec.whatwg.org/#shadow-trees) other related specifications.
+Further on, we'll use the modern shadow DOM standard, covered by [DOM spec](https://dom.spec.whatwg.org/#shadow-trees) and other related specifications.
 
 ## Shadow tree
 
diff --git a/8-web-components/4-template-element/article.md b/8-web-components/4-template-element/article.md
index d0fe12af0..5499c4edc 100644
--- a/8-web-components/4-template-element/article.md
+++ b/8-web-components/4-template-element/article.md
@@ -1,7 +1,7 @@
 
 # Template element
 
-A built-in `<template>` element serves as a storage for HTML markup templates. The browser ignores it contents, only checks for syntax validity, but we can access and use it in JavaScript, to create other elements.
+A built-in `<template>` element serves as a storage for HTML markup templates. The browser ignores its contents, only checks for syntax validity, but we can access and use it in JavaScript, to create other elements.
 
 In theory, we could create any invisible element somewhere in HTML for HTML markup storage purposes. What's special about `<template>`?
 
diff --git a/8-web-components/5-slots-composition/article.md b/8-web-components/5-slots-composition/article.md
index 66b89a71e..c41e26e05 100644
--- a/8-web-components/5-slots-composition/article.md
+++ b/8-web-components/5-slots-composition/article.md
@@ -130,6 +130,7 @@ For example, the second `<span>` here is ignored (as it's not a top-level child
 If there are multiple elements in light DOM with the same slot name, they are appended into the slot, one after another.
 
 For example, this:
+
 ```html
 <user-card>
   <span slot="username">John</span>
@@ -227,11 +228,11 @@ The flattened DOM looks like this:
       </slot>
     </div>
     <fieldset>
-      <legend>About me</legend>
+      <legend>Other information</legend>
 *!*
       <slot>
-        <div>Hello</div>
-        <div>I am John!</div>
+        <div>I like to swim.</div>
+        <div>...And play volleyball too!</div>
       </slot>
 */!*
     </fieldset>
@@ -268,7 +269,7 @@ The shadow DOM template with proper slots:
 ```
 
 1. `<span slot="title">` goes into `<slot name="title">`.
-2. There are many `<li slot="item">` in the template, but only one `<slot name="item">` in the template. So all such `<li slot="item">` are appended to `<slot name="item">` one after another, thus forming the list.
+2. There are many `<li slot="item">` in the `<custom-menu>`, but only one `<slot name="item">` in the template. So all such `<li slot="item">` are appended to `<slot name="item">` one after another, thus forming the list.
 
 The flattened DOM becomes:
 
@@ -380,7 +381,7 @@ If we'd like to track internal modifications of light DOM from JavaScript, that'
 
 Finally, let's mention the slot-related JavaScript methods.
 
-As we've seen before, JavaScript looks at the "real" DOM, without flattening. But, if the shadow tree has `{mode: 'open'}`, then we can figure out which elements assigned to a slot and, vise-versa, the slot by the element inside it:
+As we've seen before, JavaScript looks at the "real" DOM, without flattening. But, if the shadow tree has `{mode: 'open'}`, then we can figure out which elements assigned to a slot and, vice-versa, the slot by the element inside it:
 
 - `node.assignedSlot` -- returns the `<slot>` element that the `node` is assigned to.
 - `slot.assignedNodes({flatten: true/false})` -- DOM nodes, assigned to the slot. The `flatten` option is `false` by default. If explicitly set to `true`, then it looks more deeply into the flattened DOM, returning nested slots in case of nested components and the fallback content if no node assigned.
@@ -408,7 +409,7 @@ customElements.define('custom-menu', class extends HTMLElement {
       <ul><slot name="item"></slot></ul>
     </div>`;
 
-    // slottable is added/removed/replaced
+    // triggers when slot content changes
 *!*
     this.shadowRoot.firstElementChild.addEventListener('slotchange', e => {
       let slot = e.target;
@@ -446,7 +447,7 @@ Composition does not really move nodes, from JavaScript point of view the DOM is
 
 JavaScript can access slots using methods:
 - `slot.assignedNodes/Elements()` -- returns nodes/elements inside the `slot`.
-- `node.assignedSlot` -- the reverse meethod, returns slot by a node.
+- `node.assignedSlot` -- the reverse property, returns slot by a node.
 
 If we'd like to know what we're showing, we can track slot contents using:
 - `slotchange` event -- triggers the first time a slot is filled, and on any add/remove/replace operation of the slotted element, but not its children. The slot is `event.target`.
diff --git a/8-web-components/6-shadow-dom-style/article.md b/8-web-components/6-shadow-dom-style/article.md
index 2be81fbb2..98e246a7f 100644
--- a/8-web-components/6-shadow-dom-style/article.md
+++ b/8-web-components/6-shadow-dom-style/article.md
@@ -111,22 +111,7 @@ customElements.define('custom-dialog', class extends HTMLElement {
 
 Now the additional centering styles are only applied to the first dialog: `<custom-dialog centered>`.
 
-## :host-context(selector)
-
-Same as `:host`, but applied only if the shadow host or any of its ancestors in the outer document matches the `selector`.
-
-E.g. `:host-context(.dark-theme)` matches only if there's `dark-theme` class on `<custom-dialog>` on anywhere above it:
-
-```html
-<body class="dark-theme">
-  <!--
-    :host-context(.dark-theme) applies to custom-dialogs inside .dark-theme
-  -->
-  <custom-dialog>...</custom-dialog>
-</body>
-```
-
-To summarize, we can use `:host`-family of selectors to style the main element of the component, depending on the context. These styles (unless `!important`) can be overridden by the document.
+To summarize, we can use `:host`-family of selectors to style the main element of the component. These styles (unless `!important`) can be overridden by the document.
 
 ## Styling slotted content
 
@@ -259,7 +244,6 @@ For example, in shadow DOM we can use `--user-card-field-color` CSS variable to
 </style>
 <div class="field">Name: <slot name="username"></slot></div>
 <div class="field">Birthday: <slot name="birthday"></slot></div>
-</style>
 ```
 
 Then, we can declare this property in the outer document for `<user-card>`:
@@ -318,7 +302,7 @@ Shadow DOM can include styles, such as `<style>` or `<link rel="stylesheet">`.
 
 Local styles can affect:
 - shadow tree,
-- shadow host with `:host`-family pseudoclasses,
+- shadow host with `:host` and `:host()` pseudoclasses,
 - slotted elements (coming from light DOM), `::slotted(selector)` allows to select  slotted elements themselves, but not their children.
 
 Document styles can affect:
diff --git a/9-regular-expressions/01-regexp-introduction/article.md b/9-regular-expressions/01-regexp-introduction/article.md
index a35d19a7b..ade62cdf2 100644
--- a/9-regular-expressions/01-regexp-introduction/article.md
+++ b/9-regular-expressions/01-regexp-introduction/article.md
@@ -29,7 +29,7 @@ In both cases `regexp` becomes an instance of the built-in `RegExp` class.
 
 The main difference between these two syntaxes is that pattern using slashes `/.../` does not allow for expressions to be inserted (like string template literals with `${...}`). They are fully static.
 
-Slashes are used when we know the regular expression at the code writing time -- and that's the most common situation. While `new RegExp`, is more often used when we need to create a regexp "on the fly" from a dynamically generated string. For instance:
+Slashes are used when we know the regular expression at the code writing time -- and that's the most common situation. While `new RegExp` is more often used when we need to create a regexp "on the fly" from a dynamically generated string. For instance:
 
 ```js
 let tag = prompt("What tag do you want to find?", "h2");
@@ -56,7 +56,7 @@ There are only 6 of them in JavaScript:
 : Enables "dotall" mode, that allows a dot `pattern:.` to match newline character `\n` (covered in the chapter <info:regexp-character-classes>).
 
 `pattern:u`
-: Enables full unicode support. The flag enables correct processing of surrogate pairs. More about that in the chapter <info:regexp-unicode>.
+: Enables full Unicode support. The flag enables correct processing of surrogate pairs. More about that in the chapter <info:regexp-unicode>.
 
 `pattern:y`
 : "Sticky" mode: searching at the exact position in the text  (covered in the chapter <info:regexp-sticky>)
diff --git a/9-regular-expressions/02-regexp-character-classes/article.md b/9-regular-expressions/02-regexp-character-classes/article.md
index 5b4258869..201c78a05 100644
--- a/9-regular-expressions/02-regexp-character-classes/article.md
+++ b/9-regular-expressions/02-regexp-character-classes/article.md
@@ -1,6 +1,6 @@
 # Character classes
 
-Consider a practical task -- we have a phone number like `"+7(903)-123-45-67"`, and we need to turn it into pure numbers: `79035419441`.
+Consider a practical task -- we have a phone number like `"+7(903)-123-45-67"`, and we need to turn it into pure numbers: `79031234567`.
 
 To do so, we can find and remove anything that's not a number. Character classes can help with that.
 
@@ -8,7 +8,7 @@ A *character class* is a special notation that matches any symbol from a certain
 
 For the start, let's explore the "digit" class. It's written as `pattern:\d` and corresponds to "any single digit".
 
-For instance, the let's find the first digit in the phone number:
+For instance, let's find the first digit in the phone number:
 
 ```js run
 let str = "+7(903)-123-45-67";
@@ -30,7 +30,7 @@ let regexp = /\d/g;
 alert( str.match(regexp) ); // array of matches: 7,9,0,3,1,2,3,4,5,6,7
 
 // let's make the digits-only phone number of them:
-alert( str.match(regexp).join('') ); // 79035419441
+alert( str.match(regexp).join('') ); // 79031234567
 ```
 
 That was a character class for digits. There are other character classes as well.
@@ -120,7 +120,7 @@ alert( "CS-4".match(regexp) ); // CS-4
 alert( "CS 4".match(regexp) ); // CS 4 (space is also a character)
 ```
 
-Please note that a dot means "any character", but not the "absense of a character". There must be a character to match it:
+Please note that a dot means "any character", but not the "absence of a character". There must be a character to match it:
 
 ```js run
 alert( "CS4".match(/CS.4/) ); // null, no match because there's no character for the dot
@@ -144,18 +144,18 @@ That's what flag `pattern:s` does. If a regexp has it, then a dot `pattern:.` ma
 alert( "A\nB".match(/A.B/s) ); // A\nB (match!)
 ```
 
-````warn header="Not supported in Firefox, IE, Edge"
-Check <https://caniuse.com/#search=dotall> for the most recent state of support. At the time of writing it doesn't include Firefox, IE, Edge.
+````warn header="Not supported in IE"
+The `pattern:s` flag is not supported in IE.
 
-Luckily, there's an alternative, that works everywhere. We can use a regexp like `pattern:[\s\S]` to match "any character".
+Luckily, there's an alternative, that works everywhere. We can use a regexp like `pattern:[\s\S]` to match "any character" (this pattern will be covered in the article <info:regexp-character-sets-and-ranges>).
 
 ```js run
 alert( "A\nB".match(/A[\s\S]B/) ); // A\nB (match!)
 ```
 
-The pattern `pattern:[\s\S]` literally says: "a space character OR not a space character". In other words, "anything". We could use another pair of complementary classes, such as `pattern:[\d\D]`, that doesn't matter.
+The pattern `pattern:[\s\S]` literally says: "a space character OR not a space character". In other words, "anything". We could use another pair of complementary classes, such as `pattern:[\d\D]`, that doesn't matter. Or even the `pattern:[^]` -- as it means match any character except nothing.
 
-This trick works everywhere. Also we can use it if we don't want to set `pattern:s` flag, in cases when we want a regular "no-newline" dot too in the pattern.
+Also we can use this trick if we want both kind of "dots" in the same pattern: the actual dot `pattern:.` behaving the regular way ("not including a newline"), and also a way to match "any character" with `pattern:[\s\S]` or alike.
 ````
 
 ````warn header="Pay attention to spaces"
@@ -179,7 +179,7 @@ alert( "1 - 5".match(/\d\s-\s\d/) ); // 1 - 5, also works
 
 **A space is a character. Equal in importance with any other character.**
 
-We can't add or remove spaces from a regular expression and expect to work the same.
+We can't add or remove spaces from a regular expression and expect it to work the same.
 
 In other words, in a regular expression all characters matter, spaces too.
 ````
@@ -198,6 +198,6 @@ There exist following character classes:
 
 ...But that's not all!
 
-Unicode encoding, used by JavaScript for strings, provides many properties for characters, like: which language the letter belongs to (if it's a letter) it is it a punctuation sign, etc.
+Unicode encoding, used by JavaScript for strings, provides many properties for characters, like: which language the letter belongs to (if it's a letter), is it a punctuation sign, etc.
 
 We can search by these properties as well. That requires flag `pattern:u`, covered in the next article.
diff --git a/9-regular-expressions/03-regexp-unicode/article.md b/9-regular-expressions/03-regexp-unicode/article.md
index a8a5f4f5b..1be163aff 100644
--- a/9-regular-expressions/03-regexp-unicode/article.md
+++ b/9-regular-expressions/03-regexp-unicode/article.md
@@ -1,12 +1,12 @@
 # Unicode: flag "u" and class \p{...}
 
-JavaScript uses [Unicode encoding](https://en.wikipedia.org/wiki/Unicode) for strings. Most characters are encoding with 2 bytes, but that allows to represent at most 65536 characters.
+JavaScript uses [Unicode encoding](https://en.wikipedia.org/wiki/Unicode) for strings. Most characters are encoded with 2 bytes, but that allows to represent at most 65536 characters.
 
 That range is not big enough to encode all possible characters, that's why some rare characters are encoded with 4 bytes, for instance like `𝒳` (mathematical X) or `😄` (a smile), some hieroglyphs and so on.
 
-Here are the unicode values of some characters:
+Here are the Unicode values of some characters:
 
-| Character  | Unicode | Bytes count in unicode  |
+| Character  | Unicode | Bytes count in Unicode  |
 |------------|---------|--------|
 | a | `0x0061` |  2 |
 | ≈ | `0x2248` |  2 |
@@ -33,27 +33,21 @@ Unlike strings, regular expressions have flag `pattern:u` that fixes such proble
 
 ## Unicode properties \p{...}
 
-```warn header="Not supported in Firefox and Edge"
-Despite being a part of the standard since 2018, unicode properties are not supported in Firefox ([bug](https://bugzilla.mozilla.org/show_bug.cgi?id=1361876)) and Edge ([bug](https://github.com/Microsoft/ChakraCore/issues/2969)).
-
-There's [XRegExp](http://xregexp.com) library that provides "extended" regular expressions with cross-browser support for unicode properties.
-```
-
 Every character in Unicode has a lot of properties. They describe what "category" the character belongs to, contain miscellaneous information about it.
 
 For instance, if a character has `Letter` property, it means that the character belongs to an alphabet (of any language). And `Number` property means that it's a digit: maybe Arabic or Chinese, and so on.
 
 We can search for characters with a property, written as `pattern:\p{…}`. To use `pattern:\p{…}`, a regular expression must have flag `pattern:u`.
 
-For instance, `\p{Letter}` denotes a letter in any of language. We can also use `\p{L}`, as `L` is an alias of `Letter`. There are shorter aliases for almost every property.
+For instance, `\p{Letter}` denotes a letter in any language. We can also use `\p{L}`, as `L` is an alias of `Letter`. There are shorter aliases for almost every property.
 
-In the example below three kinds of letters will be found: English, Georgean and Korean.
+In the example below three kinds of letters will be found: English, Georgian and Korean.
 
 ```js run
 let str = "A ბ ㄱ";
 
 alert( str.match(/\p{L}/gu) ); // A,ბ,ㄱ
-alert( str.match(/\p{L}/g) ); // null (no matches, as there's no flag "u")
+alert( str.match(/\p{L}/g) ); // null (no matches, \p doesn't work without the flag "u")
 ```
 
 Here's the main character categories and their subcategories:
@@ -93,7 +87,7 @@ Here's the main character categories and their subcategories:
   - control `Cc`,
   - format `Cf`,
   - not assigned `Cn`,
-  -- private use `Co`,
+  - private use `Co`,
   - surrogate `Cs`.
 
 
@@ -113,7 +107,7 @@ Unicode supports many different properties, their full list would require a lot
 
 ### Example: hexadecimal numbers
 
-For instance, let's look for hexadecimal numbers, written as `xFF`, where `F` is a hex digit (0..1 or A..F).
+For instance, let's look for hexadecimal numbers, written as `xFF`, where `F` is a hex digit (0..9 or A..F).
 
 A hex digit can be denoted as `pattern:\p{Hex_Digit}`:
 
@@ -127,7 +121,7 @@ alert("number: xAF".match(regexp)); // xAF
 
 Let's look for Chinese hieroglyphs.
 
-There's a unicode property `Script` (a writing system), that may have a value: `Cyrillic`, `Greek`, `Arabic`, `Han` (Chinese) and so on, [here's the full list]("https://en.wikipedia.org/wiki/Script_(Unicode)").
+There's a Unicode property `Script` (a writing system), that may have a value: `Cyrillic`, `Greek`, `Arabic`, `Han` (Chinese) and so on, [here's the full list](https://en.wikipedia.org/wiki/Script_(Unicode)).
 
 To look for characters in a given writing system we should use `pattern:Script=<value>`, e.g. for Cyrillic letters: `pattern:\p{sc=Cyrillic}`, for Chinese hieroglyphs: `pattern:\p{sc=Han}`, and so on:
 
@@ -141,14 +135,14 @@ alert( str.match(regexp) ); // 你,好
 
 ### Example: currency
 
-Characters that denote a currency, such as `$`, `€`, `¥`, have unicode property  `pattern:\p{Currency_Symbol}`, the short alias: `pattern:\p{Sc}`.
+Characters that denote a currency, such as `$`, `€`, `¥`, have Unicode property  `pattern:\p{Currency_Symbol}`, the short alias: `pattern:\p{Sc}`.
 
 Let's use it to look for prices in the format "currency, followed by a digit":
 
 ```js run
 let regexp = /\p{Sc}\d/gu;
 
-let  str = `Prices: $2, €1, ¥9`;
+let str = `Prices: $2, €1, ¥9`;
 
 alert( str.match(regexp) ); // $2,€1,¥9
 ```
diff --git a/9-regular-expressions/04-regexp-anchors/article.md b/9-regular-expressions/04-regexp-anchors/article.md
index c34999ee5..63e4efa93 100644
--- a/9-regular-expressions/04-regexp-anchors/article.md
+++ b/9-regular-expressions/04-regexp-anchors/article.md
@@ -16,7 +16,7 @@ The pattern `pattern:^Mary` means: "string start and then Mary".
 Similar to this, we can test if the string ends with `snow` using `pattern:snow$`:
 
 ```js run
-let str1 = "it's fleece was white as snow";
+let str1 = "its fleece was white as snow";
 alert( /snow$/.test(str1) ); // true
 ```
 
diff --git a/9-regular-expressions/05-regexp-multiline-mode/article.md b/9-regular-expressions/05-regexp-multiline-mode/article.md
index 539f9fa23..82f4d781d 100644
--- a/9-regular-expressions/05-regexp-multiline-mode/article.md
+++ b/9-regular-expressions/05-regexp-multiline-mode/article.md
@@ -16,7 +16,7 @@ let str = `1st place: Winnie
 3rd place: Eeyore`;
 
 *!*
-alert( str.match(/^\d/gm) ); // 1, 2, 3
+console.log( str.match(/^\d/gm) ); // 1, 2, 3
 */!*
 ```
 
@@ -28,14 +28,14 @@ let str = `1st place: Winnie
 3rd place: Eeyore`;
 
 *!*
-alert( str.match(/^\d/g) ); // 1
+console.log( str.match(/^\d/g) ); // 1
 */!*
 ```
 
 That's because by default a caret `pattern:^` only matches at the beginning of the text, and in the multiline mode -- at the start of any line.
 
 ```smart
-"Start of a line" formally means "immediately after a line break": the test  `pattern:^` in multiline mode matches at all positions preceeded by a newline character `\n`.
+"Start of a line" formally means "immediately after a line break": the test  `pattern:^` in multiline mode matches at all positions preceded by a newline character `\n`.
 
 And at the text start.
 ```
@@ -51,10 +51,10 @@ let str = `Winnie: 1
 Piglet: 2
 Eeyore: 3`;
 
-alert( str.match(/\d$/gm) ); // 1,2,3
+console.log( str.match(/\d$/gm) ); // 1,2,3
 ```
 
-Without the flag `m`, the dollar `pattern:$` would only match the end of the whole text, so only the very last digit would be found.
+Without the flag `pattern:m`, the dollar `pattern:$` would only match the end of the whole text, so only the very last digit would be found.
 
 ```smart
 "End of a line" formally means "immediately before a line break": the test  `pattern:$` in multiline mode matches at all positions succeeded by a newline character `\n`.
@@ -75,7 +75,7 @@ let str = `Winnie: 1
 Piglet: 2
 Eeyore: 3`;
 
-alert( str.match(/\d\n/gm) ); // 1\n,2\n
+console.log( str.match(/\d\n/g) ); // 1\n,2\n
 ```
 
 As we can see, there are 2 matches instead of 3.
diff --git a/9-regular-expressions/06-regexp-boundary/article.md b/9-regular-expressions/06-regexp-boundary/article.md
index e4df252a4..06b5ac9f7 100644
--- a/9-regular-expressions/06-regexp-boundary/article.md
+++ b/9-regular-expressions/06-regexp-boundary/article.md
@@ -25,9 +25,9 @@ So, it matches the pattern `pattern:\bHello\b`, because:
 
 1. At the beginning of the string matches the first test `pattern:\b`.
 2. Then matches the word `pattern:Hello`.
-3. Then the test `pattern:\b` matches again, as we're between `subject:o` and a space.
+3. Then the test `pattern:\b` matches again, as we're between `subject:o` and a comma.
 
-The pattern `pattern:\bJava\b` would also match. But not `pattern:\bHell\b` (because there's no word boundary after `l`) and not `Java!\b` (because the exclamation sign is not a wordly character `pattern:\w`, so there's no word boundary after it).
+So the pattern `pattern:\bHello\b` would match, but not `pattern:\bHell\b` (because there's no word boundary after `l`) and not `Java!\b` (because the exclamation sign is not a wordly character `pattern:\w`, so there's no word boundary after it).
 
 ```js run
 alert( "Hello, Java!".match(/\bHello\b/) ); // Hello
diff --git a/9-regular-expressions/07-regexp-escaping/article.md b/9-regular-expressions/07-regexp-escaping/article.md
index 7bf989471..1ad3ac98c 100644
--- a/9-regular-expressions/07-regexp-escaping/article.md
+++ b/9-regular-expressions/07-regexp-escaping/article.md
@@ -3,9 +3,9 @@
 
 As we've seen, a backslash `pattern:\` is used to denote character classes, e.g. `pattern:\d`. So it's a special character in regexps (just like in regular strings).
 
-There are other special characters as well, that have special meaning in a regexp. They are used to do more powerful searches. Here's a full list of them: `pattern:[ \ ^ $ . | ? * + ( )`.
+There are other special characters as well, that have special meaning in a regexp, such as `pattern:[ ] { } ( ) \ ^ $ . | ? * +`. They are used to do more powerful searches.
 
-Don't try to remember the list -- soon we'll deal with each of them separately and you'll know them by heart automatically.
+Don't try to remember the list -- soon we'll deal with each of them, and you'll know them by heart automatically.
 
 ## Escaping
 
@@ -65,7 +65,7 @@ The similar search in one of previous examples worked with `pattern:/\d\.\d/`, b
 
 The reason is that backslashes are "consumed" by a string. As we may recall, regular strings have their own special characters, such as `\n`, and a backslash is used for escaping.
 
-Here's how "\d\.\d" is preceived:
+Here's how "\d\.\d" is perceived:
 
 ```js run
 alert("\d\.\d"); // d.d
@@ -96,4 +96,4 @@ alert( "Chapter 5.1".match(regexp) ); // 5.1
 
 - To search for special characters `pattern:[ \ ^ $ . | ? * + ( )` literally, we need to prepend them with a backslash `\` ("escape them").
 - We also need to escape `/` if we're inside `pattern:/.../` (but not inside `new RegExp`).
-- When passing a string `new RegExp`, we need to double backslashes `\\`, cause string quotes consume one of them.
+- When passing a string to `new RegExp`, we need to double backslashes `\\`, cause string quotes consume one of them.
diff --git a/9-regular-expressions/08-regexp-character-sets-and-ranges/1-find-range-1/solution.md b/9-regular-expressions/08-regexp-character-sets-and-ranges/1-find-range-1/solution.md
index 378471611..85c7748f7 100644
--- a/9-regular-expressions/08-regexp-character-sets-and-ranges/1-find-range-1/solution.md
+++ b/9-regular-expressions/08-regexp-character-sets-and-ranges/1-find-range-1/solution.md
@@ -5,7 +5,7 @@ Answers: **no, yes**.
     ```js run
     alert( "Java".match(/Java[^script]/) ); // null
     ```
-- Yes, because the part `pattern:[^script]` part matches the character `"S"`. It's not one of `pattern:script`. As the regexp is case-sensitive (no `pattern:i` flag), it treats `"S"` as a different character from `"s"`.
+- Yes, because the `pattern:[^script]` part matches the character `"S"`. It's not one of `pattern:script`. As the regexp is case-sensitive (no `pattern:i` flag), it treats `"S"` as a different character from `"s"`.
 
     ```js run
     alert( "JavaScript".match(/Java[^script]/) ); // "JavaS"
diff --git a/9-regular-expressions/08-regexp-character-sets-and-ranges/article.md b/9-regular-expressions/08-regexp-character-sets-and-ranges/article.md
index cb6a27e9d..b7b82d45f 100644
--- a/9-regular-expressions/08-regexp-character-sets-and-ranges/article.md
+++ b/9-regular-expressions/08-regexp-character-sets-and-ranges/article.md
@@ -57,16 +57,16 @@ For instance:
 
 - **\d** -- is the same as `pattern:[0-9]`,
 - **\w** -- is the same as `pattern:[a-zA-Z0-9_]`,
-- **\s** -- is the same as `pattern:[\t\n\v\f\r ]`, plus few other rare unicode space characters.
+- **\s** -- is the same as `pattern:[\t\n\v\f\r ]`, plus few other rare Unicode space characters.
 ```
 
 ### Example: multi-language \w
 
 As the character class `pattern:\w` is a shorthand for `pattern:[a-zA-Z0-9_]`, it can't find Chinese hieroglyphs, Cyrillic letters, etc.
 
-We can write a more universal pattern, that looks for wordly characters in any language. That's easy with unicode properties: `pattern:[\p{Alpha}\p{M}\p{Nd}\p{Pc}\p{Join_C}]`.
+We can write a more universal pattern, that looks for wordly characters in any language. That's easy with Unicode properties: `pattern:[\p{Alpha}\p{M}\p{Nd}\p{Pc}\p{Join_C}]`.
 
-Let's decipher it. Similar to `pattern:\w`, we're making a set of our own that includes characters with following unicode properties:
+Let's decipher it. Similar to `pattern:\w`, we're making a set of our own that includes characters with following Unicode properties:
 
 - `Alphabetic` (`Alpha`) - for letters,
 - `Mark` (`M`) - for accents,
@@ -85,10 +85,10 @@ let str = `Hi 你好 12`;
 alert( str.match(regexp) ); // H,i,你,好,1,2
 ```
 
-Of course, we can edit this pattern: add unicode properties or remove them. Unicode properties are covered in more details in the article <info:regexp-unicode>.
+Of course, we can edit this pattern: add Unicode properties or remove them. Unicode properties are covered in more details in the article <info:regexp-unicode>.
 
-```warn header="Unicode properties aren't supported in Edge and Firefox"
-Unicode properties `pattern:p{…}` are not yet implemented in Edge and Firefox. If we really need them, we can use library [XRegExp](http://xregexp.com/).
+```warn header="Unicode properties aren't supported in IE"
+Unicode properties `pattern:p{…}` are not implemented in IE. If we really need them, we can use library [XRegExp](https://xregexp.com/).
 
 Or just use ranges of characters in a language that interests us, e.g.  `pattern:[а-я]` for Cyrillic letters.
 ```
diff --git a/9-regular-expressions/09-regexp-quantifiers/2-find-html-colors-6hex/solution.md b/9-regular-expressions/09-regexp-quantifiers/2-find-html-colors-6hex/solution.md
index b9e1f85a5..afee89c50 100644
--- a/9-regular-expressions/09-regexp-quantifiers/2-find-html-colors-6hex/solution.md
+++ b/9-regular-expressions/09-regexp-quantifiers/2-find-html-colors-6hex/solution.md
@@ -17,7 +17,7 @@ alert( str.match(regexp) );  // #121212,#AA00ef
 The problem is that it finds the color in longer sequences:
 
 ```js run
-alert( "#12345678".match( /#[a-f0-9]{6}/gi ) ) // #12345678
+alert( "#12345678".match( /#[a-f0-9]{6}/gi ) ) // #123456
 ```
 
 To fix that, we can add `pattern:\b` to the end:
diff --git a/9-regular-expressions/10-regexp-greedy-and-lazy/1-lazy-greedy/task.md b/9-regular-expressions/10-regexp-greedy-and-lazy/1-lazy-greedy/task.md
index b46f55917..596f61a4e 100644
--- a/9-regular-expressions/10-regexp-greedy-and-lazy/1-lazy-greedy/task.md
+++ b/9-regular-expressions/10-regexp-greedy-and-lazy/1-lazy-greedy/task.md
@@ -3,5 +3,5 @@
 What's the match here?
 
 ```js
-"123 456".match(/\d+? \d+?/g) ); // ?
+alert( "123 456".match(/\d+? \d+?/g) ); // ?
 ```
diff --git a/9-regular-expressions/10-regexp-greedy-and-lazy/4-find-html-tags-greedy-lazy/task.md b/9-regular-expressions/10-regexp-greedy-and-lazy/4-find-html-tags-greedy-lazy/task.md
index 8e96c921d..6759152ff 100644
--- a/9-regular-expressions/10-regexp-greedy-and-lazy/4-find-html-tags-greedy-lazy/task.md
+++ b/9-regular-expressions/10-regexp-greedy-and-lazy/4-find-html-tags-greedy-lazy/task.md
@@ -12,4 +12,4 @@ let str = '<> <a href="/"> <input type="radio" checked> <b>';
 alert( str.match(regexp) ); // '<a href="/">', '<input type="radio" checked>', '<b>'
 ```
 
-Here we assume that tag attributes may not contain `<` and `>` (inside squotes too), that simplifies things a bit. 
+Here we assume that tag attributes may not contain `<` and `>` (inside quotes too), that simplifies things a bit.
diff --git a/9-regular-expressions/10-regexp-greedy-and-lazy/article.md b/9-regular-expressions/10-regexp-greedy-and-lazy/article.md
index 79abc559d..e20175075 100644
--- a/9-regular-expressions/10-regexp-greedy-and-lazy/article.md
+++ b/9-regular-expressions/10-regexp-greedy-and-lazy/article.md
@@ -8,7 +8,7 @@ Let's take the following task as an example.
 
 We have a text and need to replace all quotes `"..."` with guillemet marks: `«...»`. They are preferred for typography in many countries.
 
-For instance: `"Hello, world"` should become `«Hello, world»`. There exist other quotes, such as `„Witam, świat!”` (Polish) or `「你好,世界」` (Chinese), but for our task let's choose `«...»`.
+For instance: `"Hello, world"` should become `«Hello, world»`. There exist other quotes, such as `„Witaj, świecie!”` (Polish) or `「你好,世界」` (Chinese), but for our task let's choose `«...»`.
 
 The first thing to do is to locate quoted strings, and then we can replace them.
 
@@ -88,7 +88,7 @@ These common words do not make it obvious why the regexp fails, so let's elabora
 
 That's probably not what we expected, but that's how it works.
 
-**In the greedy mode (by default) a quantifier is repeated as many times as possible.**
+**In the greedy mode (by default) a quantified character is repeated as many times as possible.**
 
 The regexp engine adds to the match as many characters as it can for `pattern:.+`, and then shortens that one by one, if the rest of the pattern doesn't match.
 
@@ -109,7 +109,7 @@ let regexp = /".+?"/g;
 
 let str = 'a "witch" and her "broom" is one';
 
-alert( str.match(regexp) ); // witch, broom
+alert( str.match(regexp) ); // "witch", "broom"
 ```
 
 To clearly understand the change, let's trace the search step by step.
@@ -179,7 +179,7 @@ let regexp = /"[^"]+"/g;
 
 let str = 'a "witch" and her "broom" is one';
 
-alert( str.match(regexp) ); // witch, broom
+alert( str.match(regexp) ); // "witch", "broom"
 ```
 
 The regexp `pattern:"[^"]+"` gives correct results, because it looks for a quote `pattern:'"'` followed by one or more non-quotes `pattern:[^"]`, and then the closing quote.
@@ -293,9 +293,9 @@ alert( str2.match(regexp) ); // <a href="link1" class="doc">, <a href="link2" cl
 Quantifiers have two modes of work:
 
 Greedy
-: By default the regular expression engine tries to repeat the quantifier as many times as possible. For instance, `pattern:\d+` consumes all possible digits. When it becomes impossible to consume more (no more digits or string end), then it continues to match the rest of the pattern. If there's no match then it decreases the number of repetitions (backtracks) and tries again.
+: By default the regular expression engine tries to repeat the quantified character as many times as possible. For instance, `pattern:\d+` consumes all possible digits. When it becomes impossible to consume more (no more digits or string end), then it continues to match the rest of the pattern. If there's no match then it decreases the number of repetitions (backtracks) and tries again.
 
 Lazy
-: Enabled by the question mark `pattern:?` after the quantifier. The regexp engine tries to match the rest of the pattern before each repetition of the quantifier.
+: Enabled by the question mark `pattern:?` after the quantifier. The regexp engine tries to match the rest of the pattern before each repetition of the quantified character.
 
 As we've seen, the lazy mode is not a "panacea" from the greedy search. An alternative is a "fine-tuned" greedy search, with exclusions, as in the pattern `pattern:"[^"]+"`.
diff --git a/9-regular-expressions/11-regexp-groups/01-test-mac/solution.md b/9-regular-expressions/11-regexp-groups/01-test-mac/solution.md
index 26f7888f7..f7a5f1e39 100644
--- a/9-regular-expressions/11-regexp-groups/01-test-mac/solution.md
+++ b/9-regular-expressions/11-regexp-groups/01-test-mac/solution.md
@@ -9,7 +9,7 @@ Now let's show that the match should capture all the text: start at the beginnin
 Finally:
 
 ```js run
-let regexp = /^[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}$/i;
+let regexp = /^[0-9a-f]{2}(:[0-9a-f]{2}){5}$/i;
 
 alert( regexp.test('01:32:54:67:89:AB') ); // true
 
diff --git a/9-regular-expressions/11-regexp-groups/01-test-mac/task.md b/9-regular-expressions/11-regexp-groups/01-test-mac/task.md
index 029a4803a..a2e799cfa 100644
--- a/9-regular-expressions/11-regexp-groups/01-test-mac/task.md
+++ b/9-regular-expressions/11-regexp-groups/01-test-mac/task.md
@@ -16,5 +16,5 @@ alert( regexp.test('0132546789AB') ); // false (no colons)
 
 alert( regexp.test('01:32:54:67:89') ); // false (5 numbers, must be 6)
 
-alert( regexp.test('01:32:54:67:89:ZZ') ) // false (ZZ ad the end)
+alert( regexp.test('01:32:54:67:89:ZZ') ) // false (ZZ at the end)
 ```
diff --git a/9-regular-expressions/11-regexp-groups/03-find-decimal-numbers/solution.md b/9-regular-expressions/11-regexp-groups/03-find-decimal-numbers/solution.md
index c4349f9a0..813d619ef 100644
--- a/9-regular-expressions/11-regexp-groups/03-find-decimal-numbers/solution.md
+++ b/9-regular-expressions/11-regexp-groups/03-find-decimal-numbers/solution.md
@@ -1,4 +1,4 @@
-A positive number with an optional decimal part is (per previous task): `pattern:\d+(\.\d+)?`.
+A positive number with an optional decimal part is: `pattern:\d+(\.\d+)?`.
 
 Let's add the optional `pattern:-` in the beginning:
 
diff --git a/9-regular-expressions/11-regexp-groups/04-parse-expression/solution.md b/9-regular-expressions/11-regexp-groups/04-parse-expression/solution.md
index 130c57be3..b23813395 100644
--- a/9-regular-expressions/11-regexp-groups/04-parse-expression/solution.md
+++ b/9-regular-expressions/11-regexp-groups/04-parse-expression/solution.md
@@ -1,4 +1,4 @@
-A regexp for a number is: `pattern:-?\d+(\.\d+)?`. We created it in previous tasks.
+A regexp for a number is: `pattern:-?\d+(\.\d+)?`. We created it in the previous task.
 
 An operator is `pattern:[-+*/]`. The hyphen `pattern:-` goes first in the square brackets, because in the middle it would mean a character range, while we just want a character `-`.
 
@@ -10,8 +10,8 @@ The full regular expression: `pattern:-?\d+(\.\d+)?\s*[-+*/]\s*-?\d+(\.\d+)?`.
 
 It has 3 parts, with `pattern:\s*` between them:
 1. `pattern:-?\d+(\.\d+)?` - the first number,
-1. `pattern:[-+*/]` - the operator,
-1. `pattern:-?\d+(\.\d+)?` - the second number.
+2. `pattern:[-+*/]` - the operator,
+3. `pattern:-?\d+(\.\d+)?` - the second number.
 
 To make each of these parts a separate element of the result array, let's enclose them in parentheses: `pattern:(-?\d+(\.\d+)?)\s*([-+*/])\s*(-?\d+(\.\d+)?)`.
 
@@ -54,3 +54,17 @@ function parse(expr) {
 
 alert( parse("-1.23 * 3.45") );  // -1.23, *, 3.45
 ```
+
+As an alternative to using the non-capturing `?:`, we could name the groups, like this:
+
+```js run
+function parse(expr) {
+	let regexp = /(?<a>-?\d+(?:\.\d+)?)\s*(?<operator>[-+*\/])\s*(?<b>-?\d+(?:\.\d+)?)/;
+
+	let result = expr.match(regexp);
+
+	return [result.groups.a, result.groups.operator, result.groups.b];
+}
+
+alert( parse("-1.23 * 3.45") );  // -1.23, *, 3.45;
+```
\ No newline at end of file
diff --git a/9-regular-expressions/11-regexp-groups/article.md b/9-regular-expressions/11-regexp-groups/article.md
index ab25066d7..8fec60ccc 100644
--- a/9-regular-expressions/11-regexp-groups/article.md
+++ b/9-regular-expressions/11-regexp-groups/article.md
@@ -18,7 +18,7 @@ Without parentheses, the pattern `pattern:go+` means `subject:g` character, foll
 Parentheses group characters together, so `pattern:(go)+` means `match:go`, `match:gogo`, `match:gogogo` and so on.
 
 ```js run
-alert( 'Gogogo now!'.match(/(go)+/i) ); // "Gogogo"
+alert( 'Gogogo now!'.match(/(go)+/ig) ); // "Gogogo"
 ```
 
 ### Example: domain
@@ -209,17 +209,17 @@ alert(results[0]); // <h1>,h1 (1st tag)
 alert(results[1]); // <h2>,h2 (2nd tag)
 ```
 
-As we can see, the first difference is very important, as demonstrated in the line `(*)`. We can't get the match as `results[0]`, because that object isn't pseudoarray. We can turn it into a real `Array` using `Array.from`. There are more details about pseudoarrays and iterables in the article <info:iterable>.
+As we can see, the first difference is very important, as demonstrated in the line `(*)`. We can't get the match as `results[0]`, because that object is a pseudoarray. We can turn it into a real `Array` using `Array.from`. There are more details about pseudoarrays and iterables in the article <info:iterable>.
 
-There's no need in `Array.from` if we're looping over results:
+There's no need for `Array.from` if we're looping over results:
 
 ```js run
 let results = '<h1> <h2>'.matchAll(/<(.*?)>/gi);
 
 for(let result of results) {
   alert(result);
-  // первый вывод: <h1>,h1
-  // второй: <h2>,h2
+  // first alert: <h1>,h1
+  // second: <h2>,h2
 }
 ```
 
@@ -249,7 +249,7 @@ The call to `matchAll` does not perform the search. Instead, it returns an itera
 
 So, there will be found as many results as needed, not more.
 
-E.g. there are potentially 100 matches in the text, but in a `for..of` loop we found 5 of them, then decided it's enough and make a `break`. Then the engine won't spend time finding other 95 mathces.
+E.g. there are potentially 100 matches in the text, but in a `for..of` loop we found 5 of them, then decided it's enough and made a `break`. Then the engine won't spend time finding other 95 matches.
 ```
 
 ## Named groups
@@ -335,7 +335,7 @@ In the example below we only get the name `match:John` as a separate member of t
 let str = "Gogogo John!";
 
 *!*
-// ?: exludes 'go' from capturing
+// ?: excludes 'go' from capturing
 let regexp = /(?:go)+ (\w+)/i;
 */!*
 
diff --git a/9-regular-expressions/12-regexp-backreferences/article.md b/9-regular-expressions/12-regexp-backreferences/article.md
index 83beb803a..b80fa85cf 100644
--- a/9-regular-expressions/12-regexp-backreferences/article.md
+++ b/9-regular-expressions/12-regexp-backreferences/article.md
@@ -57,7 +57,7 @@ In the replacement string we use a dollar sign: `pattern:$1`, while in the patte
 
 If a regexp has many parentheses, it's convenient to give them names.
 
-To reference a named group we can use `pattern:\k<имя>`.
+To reference a named group we can use `pattern:\k<name>`.
 
 In the example below the group with quotes is named `pattern:?<quote>`, so the backreference is `pattern:\k<quote>`:
 
diff --git a/9-regular-expressions/13-regexp-alternation/02-find-matching-bbtags/solution.md b/9-regular-expressions/13-regexp-alternation/02-find-matching-bbtags/solution.md
index 9b3fa1877..fb6682b6b 100644
--- a/9-regular-expressions/13-regexp-alternation/02-find-matching-bbtags/solution.md
+++ b/9-regular-expressions/13-regexp-alternation/02-find-matching-bbtags/solution.md
@@ -1,14 +1,14 @@
 
-Opening tag is `pattern:\[(b|url|quote)\]`.
+Opening tag is `pattern:\[(b|url|quote)]`.
 
 Then to find everything till the closing tag -- let's use the pattern `pattern:.*?` with flag `pattern:s` to match any character including the newline and then add a backreference to the closing tag.
 
-The full pattern: `pattern:\[(b|url|quote)\].*?\[/\1\]`.
+The full pattern: `pattern:\[(b|url|quote)\].*?\[/\1]`.
 
 In action:
 
 ```js run
-let regexp = /\[(b|url|quote)\].*?\[\/\1\]/gs;
+let regexp = /\[(b|url|quote)].*?\[\/\1]/gs;
 
 let str = `
   [b]hello![/b]
@@ -20,4 +20,4 @@ let str = `
 alert( str.match(regexp) ); // [b]hello![/b],[quote][url]http://google.com[/url][/quote]
 ```
 
-Please note that besides escaping `pattern:[` and `pattern:]`, we had to escape a slash for the closing tag `pattern:[\/\1]`, because normally the slash closes the pattern.
+Please note that besides escaping `pattern:[`, we had to escape a slash for the closing tag `pattern:[\/\1]`, because normally the slash closes the pattern.
diff --git a/9-regular-expressions/13-regexp-alternation/03-match-quoted-string/solution.md b/9-regular-expressions/13-regexp-alternation/03-match-quoted-string/solution.md
index 5a007aee0..2749f3ff0 100644
--- a/9-regular-expressions/13-regexp-alternation/03-match-quoted-string/solution.md
+++ b/9-regular-expressions/13-regexp-alternation/03-match-quoted-string/solution.md
@@ -3,7 +3,7 @@ The solution: `pattern:/"(\\.|[^"\\])*"/g`.
 Step by step:
 
 - First we look for an opening quote `pattern:"`
-- Then if we have a backslash `pattern:\\` (we technically have to double it in the pattern, because it is a special character, so that's a single backslash in fact), then any character is fine after it (a dot).
+- Then if we have a backslash `pattern:\\` (we have to double it in the pattern because it is a special character), then any character is fine after it (a dot).
 - Otherwise we take any character except a quote (that would mean the end of the string) and a backslash (to prevent lonely backslashes, the backslash is only used with some other symbol after it): `pattern:[^"\\]`
 - ...And so on till the closing quote.
 
diff --git a/9-regular-expressions/13-regexp-alternation/03-match-quoted-string/task.md b/9-regular-expressions/13-regexp-alternation/03-match-quoted-string/task.md
index ad41d91b1..27b6bc5c8 100644
--- a/9-regular-expressions/13-regexp-alternation/03-match-quoted-string/task.md
+++ b/9-regular-expressions/13-regexp-alternation/03-match-quoted-string/task.md
@@ -2,7 +2,7 @@
 
 Create a regexp to find strings in double quotes `subject:"..."`.
 
-The strings should support escaping, the same way as JavaScript strings do. For instance, quotes can be inserted as `subject:\"` a newline as `subject:\n`, and the slash itself as `subject:\\`.
+The strings should support escaping, the same way as JavaScript strings do. For instance, quotes can be inserted as `subject:\"` a newline as `subject:\n`, and the backslash itself as `subject:\\`.
 
 ```js
 let str = "Just like \"here\".";
@@ -18,11 +18,11 @@ Examples of strings to match:
 ```js
 .. *!*"test me"*/!* ..  
 .. *!*"Say \"Hello\"!"*/!* ... (escaped quotes inside)
-.. *!*"\\"*/!* ..  (double slash inside)
-.. *!*"\\ \""*/!* ..  (double slash and an escaped quote inside)
+.. *!*"\\"*/!* ..  (double backslash inside)
+.. *!*"\\ \""*/!* ..  (double backslash and an escaped quote inside)
 ```
 
-In JavaScript we need to double the slashes to pass them right into the string, like this:
+In JavaScript we need to double the backslashes to pass them right into the string, like this:
 
 ```js run
 let str = ' .. "test me" .. "Say \\"Hello\\"!" .. "\\\\ \\"" .. ';
diff --git a/9-regular-expressions/13-regexp-alternation/article.md b/9-regular-expressions/13-regexp-alternation/article.md
index 007d8f6a6..0fe2175c7 100644
--- a/9-regular-expressions/13-regexp-alternation/article.md
+++ b/9-regular-expressions/13-regexp-alternation/article.md
@@ -20,7 +20,7 @@ alert( str.match(regexp) ); // 'HTML', 'CSS', 'JavaScript'
 
 We already saw a similar thing -- square brackets. They allow to choose between multiple characters, for instance `pattern:gr[ae]y` matches `match:gray` or `match:grey`.
 
-Square brackets allow only characters or character sets. Alternation allows any expressions. A regexp `pattern:A|B|C` means one of expressions `A`, `B` or `C`.
+Square brackets allow only characters or character classes. Alternation allows any expressions. A regexp `pattern:A|B|C` means one of expressions `A`, `B` or `C`.
 
 For instance:
 
@@ -33,7 +33,7 @@ To apply alternation to a chosen part of the pattern, we can enclose it in paren
 
 ## Example: regexp for time
 
-In previous articles there was a task to build a regexp for searching time in the form `hh:mm`, for instance `12:00`. But a simple `pattern:\d\d:\d\d` is too vague. It accepts `25:99` as the time (as 99 seconds match the pattern, but that time is invalid).
+In previous articles there was a task to build a regexp for searching time in the form `hh:mm`, for instance `12:00`. But a simple `pattern:\d\d:\d\d` is too vague. It accepts `25:99` as the time (as 99 minutes match the pattern, but that time is invalid).
 
 How can we make a better pattern?
 
@@ -47,7 +47,7 @@ We can write both variants in a regexp using alternation: `pattern:[01]\d|2[0-3]
 
 Next, minutes must be from `00` to `59`. In the regular expression language that can be written as `pattern:[0-5]\d`: the first digit `0-5`, and then any digit.
 
-If we glue minutes and seconds together, we get the pattern: `pattern:[01]\d|2[0-3]:[0-5]\d`.
+If we glue hours and minutes together, we get the pattern: `pattern:[01]\d|2[0-3]:[0-5]\d`.
 
 We're almost done, but there's a problem. The alternation `pattern:|` now happens to be between `pattern:[01]\d` and `pattern:2[0-3]:[0-5]\d`.
 
diff --git a/9-regular-expressions/14-regexp-lookahead-lookbehind/1-find-non-negative-integers/solution.md b/9-regular-expressions/14-regexp-lookahead-lookbehind/1-find-non-negative-integers/solution.md
index a824409f9..ebc12689d 100644
--- a/9-regular-expressions/14-regexp-lookahead-lookbehind/1-find-non-negative-integers/solution.md
+++ b/9-regular-expressions/14-regexp-lookahead-lookbehind/1-find-non-negative-integers/solution.md
@@ -1,7 +1,7 @@
 
 The regexp for an integer number is `pattern:\d+`.
 
-We can exclude negatives by prepending it with the negative lookahead: `pattern:(?<!-)\d+`.
+We can exclude negatives by prepending it with the negative lookbehind: `pattern:(?<!-)\d+`.
 
 Although, if we try it now, we may notice one more "extra" result:
 
diff --git a/9-regular-expressions/14-regexp-lookahead-lookbehind/2-insert-after-head/solution.md b/9-regular-expressions/14-regexp-lookahead-lookbehind/2-insert-after-head/solution.md
index 980a7fe66..68bca8842 100644
--- a/9-regular-expressions/14-regexp-lookahead-lookbehind/2-insert-after-head/solution.md
+++ b/9-regular-expressions/14-regexp-lookahead-lookbehind/2-insert-after-head/solution.md
@@ -1,29 +1,36 @@
+In order to insert after the `<body>` tag, we must first find it. We can use the regular expression pattern `pattern:<body.*?>` for that.
 
-Для того, чтобы вставить после тега `<body>`, нужно вначале его найти. Будем использовать регулярное выражение `pattern:<body.*>`.
+In this task, we don't need to modify the `<body>` tag. We only need to add the text after it.
 
-Далее, нам нужно оставить сам тег `<body>` на месте и добавить текст после него.
+Here's how we can do it:
 
-Это можно сделать вот так:
 ```js run
 let str = '...<body style="...">...';
-str = str.replace(/<body.*>/, '$&<h1>Hello</h1>');
+str = str.replace(/<body.*?>/, '$&<h1>Hello</h1>');
 
 alert(str); // ...<body style="..."><h1>Hello</h1>...
 ```
 
-В строке замены `$&` означает само совпадение, то есть мы заменяем `pattern:<body.*>` заменяется на самого себя плюс `<h1>Hello</h1>`.
+In the replacement string `$&` means the match itself, that is, the part of the source text that corresponds to `pattern:<body.*?>`. It gets replaced by itself plus `<h1>Hello</h1>`.
 
-Альтернативный вариант - использовать ретроспективную проверку:
+An alternative is to use lookbehind:
 
 ```js run
 let str = '...<body style="...">...';
-str = str.replace(/(?<=<body.*>)/, `<h1>Hello</h1>`);
+str = str.replace(/(?<=<body.*?>)/, `<h1>Hello</h1>`);
 
 alert(str); // ...<body style="..."><h1>Hello</h1>...
 ```
 
-Такое регулярное выражение на каждой позиции будет проверять, не идёт ли прямо перед ней `pattern:<body.*>`. Если да - совпадение найдено. Но сам тег `pattern:<body.*>` в совпадение не входит, он только участвует в проверке. А других символов после проверки в нём нет, так что текст совпадения будет пустым.
+As you can see, there's only lookbehind part in this regexp.
 
-Происходит замена "пустой строки", перед которой идёт `pattern:<body.*>` на `<h1>Hello</h1>`. Что, как раз, и есть вставка этой строки после `<body>`.
+It works like this:
+- At every position in the text.
+- Check if it's preceded by `pattern:<body.*?>`.
+- If it's so, then we have the match.
 
-P.S. Этому регулярному выражению не помешают флаги: `pattern:/<body.*>/si`, чтобы в "точку" входил перевод строки (тег может занимать несколько строк), а также чтобы теги в другом регистре типа `match:<BODY>` тоже находились.
+The tag `pattern:<body.*?>` won't be returned. The result of this regexp is literally an empty string, but it matches only at positions preceded by `pattern:<body.*?>`.
+
+So it replaces the "empty line", preceded by `pattern:<body.*?>`, with `<h1>Hello</h1>`. That's the insertion after `<body>`.
+
+P.S. Regexp flags, such as `pattern:s` and `pattern:i` can also be useful: `pattern:/<body.*?>/si`. The `pattern:s` flag makes the dot `pattern:.` match a newline character, and `pattern:i` flag makes `pattern:<body>` also match `match:<BODY>` case-insensitively.
diff --git a/9-regular-expressions/14-regexp-lookahead-lookbehind/2-insert-after-head/task.md b/9-regular-expressions/14-regexp-lookahead-lookbehind/2-insert-after-head/task.md
index ac9e5e4ce..5ee42798a 100644
--- a/9-regular-expressions/14-regexp-lookahead-lookbehind/2-insert-after-head/task.md
+++ b/9-regular-expressions/14-regexp-lookahead-lookbehind/2-insert-after-head/task.md
@@ -1,13 +1,13 @@
-# Вставьте после фрагмента
+# Insert After Head
 
-Есть строка с HTML-документом.
+We have a string with an HTML Document.
 
-Вставьте после тега `<body>` (у него могут быть атрибуты) строку `<h1>Hello</h1>`.
+Write a regular expression that inserts `<h1>Hello</h1>` immediately after `<body>` tag. The tag may have attributes.
 
-Например:
+For instance:
 
 ```js
-let regexp = /ваше регулярное выражение/;
+let regexp = /your regular expression/;
 
 let str = `
 <html>
@@ -20,7 +20,8 @@ let str = `
 str = str.replace(regexp, `<h1>Hello</h1>`);
 ```
 
-После этого значение `str`:
+After that the value of `str` should be:
+
 ```html
 <html>
   <body style="height: 200px"><h1>Hello</h1>
diff --git a/9-regular-expressions/14-regexp-lookahead-lookbehind/article.md b/9-regular-expressions/14-regexp-lookahead-lookbehind/article.md
index 31393cd03..cee8215f9 100644
--- a/9-regular-expressions/14-regexp-lookahead-lookbehind/article.md
+++ b/9-regular-expressions/14-regexp-lookahead-lookbehind/article.md
@@ -1,6 +1,6 @@
 # Lookahead and lookbehind
 
-Sometimes we need to find only those matches for a pattern that are followed or preceeded by another pattern.
+Sometimes we need to find only those matches for a pattern that are followed or preceded by another pattern.
 
 There's a special syntax for that, called "lookahead" and "lookbehind", together referred to as "lookaround".
 
@@ -26,14 +26,14 @@ More complex tests are possible, e.g. `pattern:X(?=Y)(?=Z)` means:
 
 1. Find `pattern:X`.
 2. Check if `pattern:Y` is immediately after `pattern:X` (skip if isn't).
-3. Check if `pattern:Z` is immediately after `pattern:X` (skip if isn't).
-4. If both tests passed, then it's the match.
+3. Check if `pattern:Z` is also immediately after `pattern:X` (skip if isn't).
+4. If both tests passed, then the `pattern:X` is a match, otherwise continue searching.
 
-In other words, such pattern means that we're looking for `pattern:X` followed by   `pattern:Y` and `pattern:Z` at the same time.
+In other words, such pattern means that we're looking for `pattern:X` followed by `pattern:Y` and `pattern:Z` at the same time.
 
 That's only possible if patterns `pattern:Y` and `pattern:Z` aren't mutually exclusive.
 
-For example, `pattern:\d+(?=\s)(?=.*30)` looks for `pattern:\d+` only if it's followed by a space, and there's `30` somewhere after it:
+For example, `pattern:\d+(?=\s)(?=.*30)` looks for `pattern:\d+` that is followed by a space `pattern:(?=\s)`, and there's `30` somewhere after it `pattern:(?=.*30)`:
 
 ```js run
 let str = "1 turkey costs 30€";
@@ -54,11 +54,15 @@ The syntax is: `pattern:X(?!Y)`, it means "search `pattern:X`, but only if not f
 ```js run
 let str = "2 turkeys cost 60€";
 
-alert( str.match(/\d+(?!€)/) ); // 2 (the price is skipped)
+alert( str.match(/\d+\b(?!€)/g) ); // 2 (the price is not matched)
 ```
 
 ## Lookbehind
 
+```warn header="Lookbehind browser compatibility"
+Please Note: Lookbehind is not supported in non-V8 browsers, such as Safari, Internet Explorer.
+```
+
 Lookahead allows to add a condition for "what follows".
 
 Lookbehind is similar, but it looks behind. That is, it allows to match a pattern only if there's something before it.
@@ -81,7 +85,7 @@ And, if we need the quantity -- a number, not preceded by `subject:$`, then we c
 ```js run
 let str = "2 turkeys cost $60";
 
-alert( str.match(/(?<!\$)\d+/) ); // 2 (skipped the price)
+alert( str.match(/(?<!\$)\b\d+/g) ); // 2 (the price is not matched)
 ```
 
 ## Capturing groups
diff --git a/9-regular-expressions/15-regexp-catastrophic-backtracking/article.md b/9-regular-expressions/15-regexp-catastrophic-backtracking/article.md
index 59467f938..c1d4040f7 100644
--- a/9-regular-expressions/15-regexp-catastrophic-backtracking/article.md
+++ b/9-regular-expressions/15-regexp-catastrophic-backtracking/article.md
@@ -1,20 +1,20 @@
 # Catastrophic backtracking
 
-Some regular expressions are looking simple, but can execute veeeeeery long time, and even "hang" the JavaScript engine.
+Some regular expressions are looking simple, but can execute a veeeeeery long time, and even "hang" the JavaScript engine.
 
-Sooner or later most developers occasionally face such behavior, because it's quite easy to create such a regexp.
-
-The typical symptom -- a regular expression works fine sometimes, but for certain strings it "hangs", consuming 100% of CPU.
+Sooner or later most developers occasionally face such behavior. The typical symptom -- a regular expression works fine sometimes, but for certain strings it "hangs", consuming 100% of CPU.
 
 In such case a web-browser suggests to kill the script and reload the page. Not a good thing for sure.
 
-For server-side JavaScript it may become a vulnerability if regular expressions process user data.
+For server-side JavaScript such a regexp may hang the server process, that's even worse. So we definitely should take a look at it.
 
 ## Example
 
-Let's say we have a string, and we'd like to check if it consists of words  `pattern:\w+` with an optional space `pattern:\s?` after each.
+Let's say we have a string, and we'd like to check if it consists of words `pattern:\w+` with an optional space `pattern:\s?` after each.
+
+An obvious way to construct a regexp would be to take a word followed by an optional space `pattern:\w+\s?` and then repeat it with `*`.
 
-We'll use a regexp `pattern:^(\w+\s?)*$`, it specifies 0 or more such words.
+That leads us to the regexp `pattern:^(\w+\s?)*$`, it specifies zero or more such words, that start at the beginning `pattern:^` and finish at the end `pattern:$` of the line.
 
 In action:
 
@@ -25,36 +25,34 @@ alert( regexp.test("A good string") ); // true
 alert( regexp.test("Bad characters: $@#") ); // false
 ```
 
-It seems to work. The result is correct. Although, on certain strings it takes a lot of time. So long that JavaScript engine "hangs" with 100% CPU consumption.
+The regexp seems to work. The result is correct. Although, on certain strings it takes a lot of time. So long that JavaScript engine "hangs" with 100% CPU consumption.
 
-If you run the example below, you probably won't see anything, as JavaScript will just "hang". A web-browser will stop reacting on events, the UI will stop working. After some time it will suggest to reloaad the page. So be careful with this:
+If you run the example below, you probably won't see anything, as JavaScript will just "hang". A web-browser will stop reacting on events, the UI will stop working (most browsers allow only scrolling). After some time it will suggest to reload the page. So be careful with this:
 
 ```js run
 let regexp = /^(\w+\s?)*$/;
-let str = "An input string that takes a long time or even makes this regexp to hang!";
+let str = "An input string that takes a long time or even makes this regexp hang!";
 
 // will take a very long time
 alert( regexp.test(str) );
 ```
 
-Some regular expression engines can handle such search, but most of them can't.
+To be fair, let's note that some regular expression engines can handle such a search effectively, for example V8 engine version starting from 8.8 can do that (so Google Chrome 88 doesn't hang here), while Firefox browser does hang. 
 
 ## Simplified example
 
-What's the matter? Why the regular expression "hangs"?
+What's the matter? Why does the regular expression hang?
 
 To understand that, let's simplify the example: remove spaces `pattern:\s?`. Then it becomes `pattern:^(\w+)*$`.
 
 And, to make things more obvious, let's replace `pattern:\w` with `pattern:\d`. The resulting regular expression still hangs, for instance:
 
-<!-- let str = `AnInputStringThatMakesItHang!`; -->
-
 ```js run
 let regexp = /^(\d+)*$/;
 
-let str = "012345678901234567890123456789!";
+let str = "012345678901234567890123456789z";
 
-// will take a very long time
+// will take a very long time (careful!)
 alert( regexp.test(str) );
 ```
 
@@ -62,45 +60,49 @@ So what's wrong with the regexp?
 
 First, one may notice that the regexp `pattern:(\d+)*` is a little bit strange. The quantifier `pattern:*` looks extraneous. If we want a number, we can use `pattern:\d+`.
 
-Indeed, the regexp is artificial. But the reason why it is slow is the same as those we saw above. So let's understand it, and then the previous example will become obvious.
+Indeed, the regexp is artificial; we got it by simplifying the previous example. But the reason why it is slow is the same. So let's understand it, and then the previous example will become obvious.
 
-What happens during the search of `pattern:^(\d+)*$` in the line `subject:123456789!` (shortened a bit for clarity), why does it take so long?
+What happens during the search of `pattern:^(\d+)*$` in the line `subject:123456789z` (shortened a bit for clarity, please note a non-digit character `subject:z` at the end, it's important), why does it take so long?
 
-1. First, the regexp engine tries to find a number `pattern:\d+`. The plus `pattern:+` is greedy by default, so it consumes all digits:
+Here's what the regexp engine does:
+
+1. First, the regexp engine tries to find the content of the parentheses: the number `pattern:\d+`. The plus `pattern:+` is greedy by default, so it consumes all digits:
 
     ```
     \d+.......
     (123456789)z
     ```
 
-    Then it tries to apply the star quantifier, but there are no more digits, so it the star doesn't give anything.
+    After all digits are consumed, `pattern:\d+` is considered found (as `match:123456789`).
+
+    Then the star quantifier `pattern:(\d+)*` applies. But there are no more digits in the text, so the star doesn't give anything.
 
-    The next in the pattern is the string end `pattern:$`, but in the text we have `subject:!`, so there's no match:
+    The next character in the pattern is the string end `pattern:$`. But in the text we have `subject:z` instead, so there's no match:
 
     ```
                X
     \d+........$
-    (123456789)!
+    (123456789)z
     ```
 
 2. As there's no match, the greedy quantifier `pattern:+` decreases the count of repetitions, backtracks one character back.
 
-    Now `pattern:\d+` takes all digits except the last one:
+    Now `pattern:\d+` takes all digits except the last one (`match:12345678`):
     ```
     \d+.......
-    (12345678)9!
+    (12345678)9z
     ```
-3. Then the engine tries to continue the search from the new position (`9`).
+3. Then the engine tries to continue the search from the next position (right after `match:12345678`).
 
-    The star `pattern:(\d+)*` can be applied -- it gives the number `match:9`:
+    The star `pattern:(\d+)*` can be applied -- it gives one more match of `pattern:\d+`, the number `match:9`:
 
     ```
 
     \d+.......\d+
-    (12345678)(9)!
+    (12345678)(9)z
     ```
 
-    The engine tries to match `pattern:$` again, but fails, because meets `subject:!`:
+    The engine tries to match `pattern:$` again, but fails, because it meets `subject:z` instead:
 
     ```
                  X
@@ -109,7 +111,7 @@ What happens during the search of `pattern:^(\d+)*$` in the line `subject:123456
     ```
 
 
-4. There's no match, so the engine will continue backtracking, decreasing the number of repetitions. Backtracking generally works like this: the last greedy quantifier decreases the number of repetitions until it can. Then the previous greedy quantifier decreases, and so on.
+4. There's no match, so the engine will continue backtracking, decreasing the number of repetitions. Backtracking generally works like this: the last greedy quantifier decreases the number of repetitions until it reaches the minimum. Then the previous greedy quantifier decreases, and so on.
 
     All possible combinations are attempted. Here are their examples.
 
@@ -118,7 +120,7 @@ What happens during the search of `pattern:^(\d+)*$` in the line `subject:123456
     ```
                  X
     \d+......\d+
-    (1234567)(89)!
+    (1234567)(89)z
     ```
 
     The first number has 7 digits, and then two numbers of 1 digit each:
@@ -126,7 +128,7 @@ What happens during the search of `pattern:^(\d+)*$` in the line `subject:123456
     ```
                    X
     \d+......\d+\d+
-    (1234567)(8)(9)!
+    (1234567)(8)(9)z
     ```
 
     The first number has 6 digits, and then a number of 3 digits:
@@ -134,7 +136,7 @@ What happens during the search of `pattern:^(\d+)*$` in the line `subject:123456
     ```
                  X
     \d+.......\d+
-    (123456)(789)!
+    (123456)(789)z
     ```
 
     The first number has 6 digits, and then 2 numbers:
@@ -142,27 +144,23 @@ What happens during the search of `pattern:^(\d+)*$` in the line `subject:123456
     ```
                    X
     \d+.....\d+ \d+
-    (123456)(78)(9)!
+    (123456)(78)(9)z
     ```
 
     ...And so on.
 
 
-There are many ways to split a set of digits `123456789` into numbers. To be precise, there are <code>2<sup>n</sup>-1</code>, where `n` is the length of the set.
-
-For `n=20` there are about 1 million combinations, for `n=30` - a thousand times more. Trying each of them is exactly the reason why the search takes so long.
+There are many ways to split a sequence of digits `123456789` into numbers. To be precise, there are <code>2<sup>n</sup>-1</code>, where `n` is the length of the sequence.
 
-What to do?
+- For `123456789` we have `n=9`, that gives 511 combinations.
+- For a longer sequence with `n=20` there are about one million (1048575) combinations.
+- For `n=30` - a thousand times more (1073741823 combinations).
 
-Should we turn on the lazy mode?
-
-Unfortunately, that won't help: if we replace `pattern:\d+` with `pattern:\d+?`, the regexp will still hang. The order of combinations will change, but not their total count.
-
-Some regular expression engines have tricky tests and finite automations that allow to avoid going through all combinations or make it much faster, but not all engines, and not in all cases.
+Trying each of them is exactly the reason why the search takes so long.
 
 ## Back to words and strings
 
-The similar thing happens in our first example, when we look words by pattern `pattern:^(\w+\s?)*$` in the string `subject:An input that hangs!`.
+The similar thing happens in our first example, when we look for words by pattern `pattern:^(\w+\s?)*$` in the string `subject:An input that hangs!`.
 
 The reason is that a word can be represented as one `pattern:\w+` or many:
 
@@ -176,7 +174,15 @@ The reason is that a word can be represented as one `pattern:\w+` or many:
 
 For a human, it's obvious that there may be no match, because the string ends with an exclamation sign `!`, but the regular expression expects a wordly character `pattern:\w` or a space `pattern:\s` at the end. But the engine doesn't know that.
 
-It tries all combinations of how the regexp `pattern:(\w+\s?)*` can "consume" the string, including variants with spaces `pattern:(\w+\s)*` and without them `pattern:(\w+)*` (because spaces `pattern:\s?` are optional). As there are many such combinations, the search takes a lot of time.
+It tries all combinations of how the regexp `pattern:(\w+\s?)*` can "consume" the string, including variants with spaces `pattern:(\w+\s)*` and without them `pattern:(\w+)*` (because spaces `pattern:\s?` are optional). As there are many such combinations (we've seen it with digits), the search takes a lot of time.
+
+What to do?
+
+Should we turn on the lazy mode?
+
+Unfortunately, that won't help: if we replace `pattern:\w+` with `pattern:\w+?`, the regexp will still hang. The order of combinations will change, but not their total count.
+
+Some regular expression engines have tricky tests and finite automations that allow to avoid going through all combinations or make it much faster, but most engines don't, and it doesn't always help.
 
 ## How to fix?
 
@@ -184,39 +190,43 @@ There are two main approaches to fixing the problem.
 
 The first is to lower the number of possible combinations.
 
-Let's rewrite the regular expression as `pattern:^(\w+\s)*\w*` - we'll look for any number of words followed by a space `pattern:(\w+\s)*`, and then (optionally) a word `pattern:\w*`.
+Let's make the space non-optional by rewriting the regular expression as `pattern:^(\w+\s)*\w*$` - we'll look for any number of words followed by a space `pattern:(\w+\s)*`, and then (optionally) a final word `pattern:\w*`.
 
 This regexp is equivalent to the previous one (matches the same) and works well:
 
 ```js run
 let regexp = /^(\w+\s)*\w*$/;
-let str = "An input string that takes a long time or even makes this regex to hang!";
+let str = "An input string that takes a long time or even makes this regex hang!";
 
 alert( regexp.test(str) ); // false
 ```
 
 Why did the problem disappear?
 
-Now the star `pattern:*` goes after `pattern:\w+\s` instead of `pattern:\w+\s?`. It became impossible to represent one word of the string with multiple successive `pattern:\w+`. The time needed to try such combinations is now saved.
+That's because now the space is mandatory.
 
-For example, the previous pattern `pattern:(\w+\s?)*` could match the word `subject:string` as two `pattern:\w+`:
+The previous regexp, if we omit the space, becomes `pattern:(\w+)*`, leading to many combinations of `\w+` within a single word
+
+So `subject:input` could be matched as two repetitions of `pattern:\w+`, like this:
 
-```js run
-\w+\w+
-string
+```
+\w+  \w+
+(inp)(ut)
 ```
 
-The previous pattern, due to the optional `pattern:\s` allowed variants `pattern:\w+`, `pattern:\w+\s`, `pattern:\w+\w+` and so on.
+The new pattern is different: `pattern:(\w+\s)*` specifies repetitions of words followed by a space! The `subject:input` string can't be matched as two repetitions of `pattern:\w+\s`, because the space is mandatory.
 
-With the rewritten pattern `pattern:(\w+\s)*`, that's impossible: there may be  `pattern:\w+\s` or `pattern:\w+\s\w+\s`, but not `pattern:\w+\w+`. So the overall combinations count is greatly decreased.
+The time needed to try a lot of (actually most of) combinations is now saved.
 
 ## Preventing backtracking
 
-It's not always convenient to rewrite a regexp. And it's not always obvious how to do it.
+It's not always convenient to rewrite a regexp though. In the example above it was easy, but it's not always obvious how to do it.
+
+Besides, a rewritten regexp is usually more complex, and that's not good. Regexps are complex enough without extra efforts.
 
-The alternative approach is to forbid backtracking for the quantifier.
+Luckily, there's an alternative approach. We can forbid backtracking for the quantifier.
 
-The regular expressions engine tries many combinations that are obviously wrong for a human.
+The root of the problem is that the regexp engine tries many combinations that are obviously wrong for a human.
 
 E.g. in the regexp `pattern:(\d+)*$` it's obvious for a human, that `pattern:+` shouldn't backtrack. If we replace one `pattern:\d+` with two separate `pattern:\d+\d+`, nothing changes:
 
@@ -228,21 +238,28 @@ E.g. in the regexp `pattern:(\d+)*$` it's obvious for a human, that `pattern:+`
 (1234)(56789)!
 ```
 
-And in the original example `pattern:^(\w+\s?)*$` we may want to forbid backtracking in `pattern:\w+`. That is: `pattern:\w+` should match a whole word, with the maximal possible length. There's no need to lower the repetitions count in `pattern:\w+`, try to split it into two words `pattern:\w+\w+` and so on.
+And in the original example `pattern:^(\w+\s?)*$` we may want to forbid backtracking in `pattern:\w+`. That is: `pattern:\w+` should match a whole word, with the maximal possible length. There's no need to lower the repetitions count in `pattern:\w+` or to split it into two words `pattern:\w+\w+` and so on.
+
+Modern regular expression engines support possessive quantifiers for that. Regular quantifiers become possessive if we add `pattern:+` after them. That is, we use `pattern:\d++` instead of `pattern:\d+` to stop `pattern:+` from backtracking.
 
-Modern regular expression engines support possessive quantifiers for that. They are like greedy ones, but don't backtrack (so they are actually simpler than regular quantifiers).
+Possessive quantifiers are in fact simpler than "regular" ones. They just match as many as they can, without any backtracking. The search process without backtracking is simpler.
 
 There are also so-called "atomic capturing groups" - a way to disable backtracking inside parentheses.
 
-Unfortunately, in JavaScript they are not supported. But there's another way.
+...But the bad news is that, unfortunately, in JavaScript they are not supported.
+
+We can emulate them though using a "lookahead transform".
 
 ### Lookahead to the rescue!
 
-We can prevent backtracking using lookahead.
+So we've come to real advanced topics. We'd like a quantifier, such as `pattern:+` not to backtrack, because sometimes backtracking makes no sense.
+
+The pattern to take as many repetitions of `pattern:\w` as possible without backtracking is: `pattern:(?=(\w+))\1`. Of course, we could take another pattern instead of `pattern:\w`.
 
-The pattern to take as much repetitions of `pattern:\w` as possible without backtracking is: `pattern:(?=(\w+))\1`.
+That may seem odd, but it's actually a very simple transform.
 
 Let's decipher it:
+
 - Lookahead `pattern:?=` looks forward for the longest word `pattern:\w+` starting at the current position.
 - The contents of parentheses with `pattern:?=...` isn't memorized by the engine, so wrap `pattern:\w+` into parentheses. Then the engine will memorize their contents
 - ...And allow us to reference it in the pattern as `pattern:\1`.
@@ -266,7 +283,7 @@ alert( "JavaScript".match(/(?=(\w+))\1Script/)); // null
 We can put a more complex regular expression into `pattern:(?=(\w+))\1` instead of `pattern:\w`, when we need to forbid backtracking for `pattern:+` after it.
 
 ```smart
-There's more about the relation between possessive quantifiers and lookahead in articles [Regex: Emulate Atomic Grouping (and Possessive Quantifiers) with LookAhead](http://instanceof.me/post/52245507631/regex-emulate-atomic-grouping-with-lookahead) and [Mimicking Atomic Groups](http://blog.stevenlevithan.com/archives/mimic-atomic-groups).
+There's more about the relation between possessive quantifiers and lookahead in articles [Regex: Emulate Atomic Grouping (and Possessive Quantifiers) with LookAhead](https://instanceof.me/post/52245507631/regex-emulate-atomic-grouping-with-lookahead) and [Mimicking Atomic Groups](https://blog.stevenlevithan.com/archives/mimic-atomic-groups).
 ```
 
 Let's rewrite the first example using lookahead to prevent backtracking:
@@ -276,7 +293,7 @@ let regexp = /^((?=(\w+))\2\s?)*$/;
 
 alert( regexp.test("A good string") ); // true
 
-let str = "An input string that takes a long time or even makes this regex to hang!";
+let str = "An input string that takes a long time or even makes this regex hang!";
 
 alert( regexp.test(str) ); // false, works and fast!
 ```
@@ -287,7 +304,7 @@ Here `pattern:\2` is used instead of `pattern:\1`, because there are additional
 // parentheses are named ?<word>, referenced as \k<word>
 let regexp = /^((?=(?<word>\w+))\k<word>\s?)*$/;
 
-let str = "An input string that takes a long time or even makes this regex to hang!";
+let str = "An input string that takes a long time or even makes this regex hang!";
 
 alert( regexp.test(str) ); // false
 
diff --git a/9-regular-expressions/16-regexp-sticky/article.md b/9-regular-expressions/16-regexp-sticky/article.md
index f3650c916..ece2c960f 100644
--- a/9-regular-expressions/16-regexp-sticky/article.md
+++ b/9-regular-expressions/16-regexp-sticky/article.md
@@ -3,11 +3,9 @@
 
 The flag `pattern:y` allows to perform the search at the given position in the source string.
 
-To grasp the use case of `pattern:y` flag, and see how great it is, let's explore a practical use case.
+To grasp the use case of `pattern:y` flag, and better understand the ways of regexps, let's explore a practical example.
 
-One of common tasks for regexps is "lexical analysis": we get a text, e.g. in a programming language, and analyze it for structural elements.
-
-For instance, HTML has tags and attributes, JavaScript code has functions, variables, and so on.
+One of common tasks for regexps is "lexical analysis": we get a text, e.g. in a programming language, and need to find its structural elements. For instance, HTML has tags and attributes, JavaScript code has functions, variables, and so on.
 
 Writing lexical analyzers is a special area, with its own tools and algorithms, so we don't go deep in there, but there's a common task: to read something at the given position.
 
@@ -15,24 +13,27 @@ E.g. we have a code string `subject:let varName = "value"`, and we need to read
 
 We'll look for variable name using regexp `pattern:\w+`. Actually, JavaScript variable names need a bit more complex regexp for accurate matching, but here it doesn't matter.
 
-A call to `str.match(/\w+/)` will find only the first word in the line. Or all words with the flag `pattern:g`. But we need only one word at position `4`.
+- A call to `str.match(/\w+/)` will find only the first word in the line (`let`). That's not it.
+- We can add the flag `pattern:g`. But then the call `str.match(/\w+/g)` will look for all words in the text, while we need one word at position `4`. Again, not what we need.
+
+**So, how to search for a regexp exactly at the given position?**
 
-To search from the given position, we can use method `regexp.exec(str)`.
+Let's try using method `regexp.exec(str)`.
 
-If the `regexp` doesn't have flags `pattern:g` or `pattern:y`, then this method looks for the first match in the string `str`, exactly like `str.match(regexp)`. Such simple no-flags case doesn't interest us here.
+For a `regexp` without flags `pattern:g` and `pattern:y`, this method looks only for the first match, it works exactly like `str.match(regexp)`.
 
-If there's flag `pattern:g`, then it performs the search in the string `str`, starting from position stored in its `regexp.lastIndex` property. And, if it finds a match, then sets `regexp.lastIndex` to the index immediately after the match.
+...But if there's flag `pattern:g`, then it performs the search in `str`, starting from position stored in the `regexp.lastIndex` property. And, if it finds a match, then sets `regexp.lastIndex` to the index immediately after the match.
 
-When a regexp is created, its `lastIndex` is `0`.
+In other words, `regexp.lastIndex` serves as a starting point for the search, that each `regexp.exec(str)` call resets to the new value ("after the last match"). That's only if there's `pattern:g` flag, of course.
 
 So, successive calls to `regexp.exec(str)` return matches one after another.
 
-An example (with flag `pattern:g`):
+Here's an example of such calls:
 
 ```js run
-let str = 'let varName';
-
+let str = 'let varName'; // Let's find all words in this string
 let regexp = /\w+/g;
+
 alert(regexp.lastIndex); // 0 (initially lastIndex=0)
 
 let word1 = regexp.exec(str);
@@ -48,8 +49,6 @@ alert(word3); // null (no more matches)
 alert(regexp.lastIndex); // 0 (resets at search end)
 ```
 
-Every match is returned as an array with groups and additional properties.
-
 We can get all matches in the loop:
 
 ```js run
@@ -65,11 +64,13 @@ while (result = regexp.exec(str)) {
 }
 ```
 
-Such use of `regexp.exec` is an alternative to method `str.matchAll`.
+Such use of `regexp.exec` is an alternative to method `str.matchAll`, with a bit more control over the process.
 
-Unlike other methods, we can set our own `lastIndex`, to start the search from the given position.
+Let's go back to our task.
 
-For instance, let's find a word, starting from position `4`:
+We can manually set `lastIndex` to `4`, to start the search from the given position!
+
+Like this:
 
 ```js run
 let str = 'let varName = "value"';
@@ -84,9 +85,15 @@ let word = regexp.exec(str);
 alert(word); // varName
 ```
 
+Hooray! Problem solved! 
+
 We performed a search of `pattern:\w+`, starting from position `regexp.lastIndex = 4`.
 
-Please note: the search starts at position `lastIndex` and then goes further. If there's no word at position `lastIndex`, but it's somewhere after it, then it will be found:
+The result is correct.
+
+...But wait, not so fast.
+
+Please note: the `regexp.exec` call starts searching at position `lastIndex` and then goes further. If there's no word at position `lastIndex`, but it's somewhere after it, then it will be found:
 
 ```js run
 let str = 'let varName = "value"';
@@ -94,17 +101,19 @@ let str = 'let varName = "value"';
 let regexp = /\w+/g;
 
 *!*
+// start the search from position 3
 regexp.lastIndex = 3;
 */!*
 
-let word = regexp.exec(str);
+let word = regexp.exec(str); 
+// found the match at position 4
 alert(word[0]); // varName
 alert(word.index); // 4
 ```
 
-...So, with flag `pattern:g` property `lastIndex` sets the starting position for the search.
+For some tasks, including the lexical analysis, that's just wrong. We need to find a match exactly at the given position at the text, not somewhere after it. And that's what the flag `y` is for.
 
-**Flag `pattern:y` makes `regexp.exec` to look exactly at position `lastIndex`, not before, not after it.**
+**The flag `pattern:y` makes `regexp.exec` to search exactly at position `lastIndex`, not "starting from" it.**
 
 Here's the same search with flag `pattern:y`:
 
@@ -122,6 +131,8 @@ alert( regexp.exec(str) ); // varName (word at position 4)
 
 As we can see, regexp `pattern:/\w+/y` doesn't match at position `3` (unlike the flag  `pattern:g`), but matches at position `4`.
 
-Imagine, we have a long text, and there are no matches in it, at all. Then searching with flag `pattern:g` will go till the end of the text, and this will take significantly more time than the search with flag `pattern:y`.
+Not only that's what we need, there's an important performance gain when using flag `pattern:y`.
+
+Imagine, we have a long text, and there are no matches in it, at all. Then a search with flag `pattern:g` will go till the end of the text and find nothing, and this will take significantly more time than the search with flag `pattern:y`, that checks only the exact position.
 
-In such tasks like lexical analysis, there are usually many searches at an exact position. Using flag `pattern:y` is the key for a good performance.
+In tasks like lexical analysis, there are usually many searches at an exact position, to check what we have there. Using flag `pattern:y` is the key for correct implementations and a good performance.
diff --git a/9-regular-expressions/17-regexp-methods/article.md b/9-regular-expressions/17-regexp-methods/article.md
index ef578020d..897d0ffb6 100644
--- a/9-regular-expressions/17-regexp-methods/article.md
+++ b/9-regular-expressions/17-regexp-methods/article.md
@@ -20,7 +20,7 @@ It has 3 modes:
     alert( result.length ); // 2
 
     // Additional information:
-    alert( result.index );  // 0 (match position)
+    alert( result.index );  // 7 (match position)
     alert( result.input );  // I love JavaScript (source string)
     ```
 
@@ -65,7 +65,7 @@ There are 3 differences from `match`:
 
 1. It returns an iterable object with matches instead of an array. We can make a regular array from it using `Array.from`.
 2. Every match is returned as an array with capturing groups (the same format as `str.match` without flag `pattern:g`).
-3. If there are no results, it returns not `null`, but an empty iterable object.
+3. If there are no results, it returns an empty iterable object instead of `null`.
 
 Usage example:
 
@@ -86,7 +86,7 @@ alert( firstMatch.index );  // 0
 alert( firstMatch.input );  // <h1>Hello, world!</h1>
 ```
 
-If we use `for..of` to loop over `matchAll` matches, then we don't need `Array.from`, разумеется, не нужен.
+If we use `for..of` to loop over `matchAll` matches, then we don't need `Array.from` any more.
 
 ## str.split(regexp|substr, limit)
 
@@ -95,13 +95,13 @@ Splits the string using the regexp (or a substring) as a delimiter.
 We can use `split` with strings, like this:
 
 ```js run
-alert('12-34-56'.split('-')) // array of [12, 34, 56]
+alert('12-34-56'.split('-')) // array of ['12', '34', '56']
 ```
 
 But we can split by a regular expression, the same way:
 
 ```js run
-alert('12, 34, 56'.split(/,\s*/)) // array of [12, 34, 56]
+alert('12, 34, 56'.split(/,\s*/)) // array of ['12', '34', '56']
 ```
 
 ## str.search(regexp)
@@ -142,9 +142,8 @@ To find all hyphens, we need to use not the string `"-"`, but a regexp `pattern:
 alert( '12-34-56'.replace( *!*/-/g*/!*, ":" ) )  // 12:34:56
 ```
 
-The second argument is a replacement string. We can use special character in it:
+The second argument is a replacement string. We can use special characters in it:
 
-| Symbols | Action in the replacement string |
 | Symbols | Action in the replacement string |
 |--------|--------|
 |`$&`|inserts the whole match|
@@ -205,9 +204,6 @@ alert(result); // Smith, John
 
 If there are many groups, it's convenient to use rest parameters to access them:
 
-
-Если в регулярном выражении много скобочных групп, то бывает удобно использовать остаточные аргументы для обращения к ним:
-
 ```js run
 let str = "John Smith";
 
@@ -232,9 +228,26 @@ alert(result); // Smith, John
 
 Using a function gives us the ultimate replacement power, because it gets all the information about the match, has access to outer variables and can do everything.
 
+## str.replaceAll(str|regexp, str|func)
+
+This method is essentially the same as `str.replace`, with two major differences:
+
+1. If the first argument is a string, it replaces *all occurrences* of the string, while `replace` replaces only the *first occurrence*.
+2. If the first argument is a regular expression without the `g` flag, there'll be an error. With `g` flag, it works the same as `replace`.
+
+The main use case for `replaceAll` is replacing all occurrences of a string.
+
+Like this:
+
+```js run
+// replace all dashes by a colon
+alert('12-34-56'.replaceAll("-", ":")) // 12:34:56
+```
+
+
 ## regexp.exec(str)
 
-The method `regexp.exec(str)` method returns a match for `regexp` in the string `str`.  Unlike previous methods, it's called on a regexp, not on a string.
+The `regexp.exec(str)` method returns a match for `regexp` in the string `str`.  Unlike previous methods, it's called on a regexp, not on a string.
 
 It behaves differently depending on whether the regexp has flag `pattern:g`.
 
diff --git a/BACKERS.md b/BACKERS.md
new file mode 100644
index 000000000..36b1532bc
--- /dev/null
+++ b/BACKERS.md
@@ -0,0 +1,6 @@
+
+# Sponsors and Supporters
+
+## Supporters
+
+- Ilya Zelenko
diff --git a/LICENSE.md b/LICENSE.md
index acfce9082..cbada5307 100644
--- a/LICENSE.md
+++ b/LICENSE.md
@@ -7,7 +7,7 @@ As of now, we license the tutorial to almost everyone for free under the terms o
 
 ## License (Short)
 
-The license is basically [CC-BY-NC](https://creativecommons.org/licenses/by-nc/4.0/legalcode), revocable and exclusive.
+The license is based on [CC-BY-NC](https://creativecommons.org/licenses/by-nc/4.0/legalcode).
 
 It gives the right to:
 - **Share** – copy and redistribute the tutorial in any medium or material.
@@ -15,68 +15,62 @@ It gives the right to:
 
 Under the following terms:
 
-- **Attribution** — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use.
+- **Attribution** — You must give appropriate credit. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use.
 - **NonCommercial** — You may not use the material for commercial purposes.
 
 ## License (Legal)
 
-By exercising the Licensed Rights (defined below), You accept and agree to be bound by the terms and conditions of this license ("Public License"). To the extent this Public License may be interpreted as a contract, You are granted the Licensed Rights in consideration of Your acceptance of these terms and conditions, and the Licensor grants You such rights in consideration of benefits the Licensor receives from making the Licensed Material available under these terms and conditions.
+By exercising the Licensed Rights (defined below), You accept and agree to be bound by the terms and conditions of this license ("License"). To the extent this License may be interpreted as a contract, You are granted the Licensed Rights in consideration of Your acceptance of these terms and conditions, and the Licensor grants You such rights in consideration of benefits the Licensor receives from making the Licensed Material available under these terms and conditions.
 
 ### Section 1 – Definitions.
 
-a. __Adapted Material__ means material subject to Copyright and Similar Rights that is derived from or based upon the Licensed Material and in which the Licensed Material is translated, altered, arranged, transformed, or otherwise modified in a manner requiring permission under the Copyright and Similar Rights held by the Licensor. For purposes of this Public License, where the Licensed Material is a musical work, performance, or sound recording, Adapted Material is always produced where the Licensed Material is synched in timed relation with a moving image.
+a. __Adapted Material__ means material subject to Copyright and Similar Rights that is derived from or based upon the Licensed Material and in which the Licensed Material is translated, altered, arranged, transformed, or otherwise modified in a manner requiring permission under the Copyright and Similar Rights held by the Licensor. For purposes of this License, where the Licensed Material is a musical work, performance, or sound recording, Adapted Material is always produced where the Licensed Material is synched in timed relation with a moving image.
 
-b. __Adapter's License__ means the license You apply to Your Copyright and Similar Rights in Your contributions to Adapted Material in accordance with the terms and conditions of this Public License.
+b. __Adapter's License__ means the license You apply to Your Copyright and Similar Rights in Your contributions to Adapted Material in accordance with the terms and conditions of this License.
 
-c. __Copyright and Similar Rights__ means copyright and/or similar rights closely related to copyright including, without limitation, performance, broadcast, sound recording, and Sui Generis Database Rights, without regard to how the rights are labeled or categorized. For purposes of this Public License, the rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights.
+c. __Copyright and Similar Rights__ means copyright and/or similar rights closely related to copyright including, without limitation, performance, broadcast, sound recording, and Sui Generis Database Rights, without regard to how the rights are labeled or categorized. For purposes of this License, the rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights.
 
 d. __Effective Technological Measures__ means those measures that, in the absence of proper authority, may not be circumvented under laws fulfilling obligations under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, and/or similar international agreements.
 
 e. __Exceptions and Limitations__ means fair use, fair dealing, and/or any other exception or limitation to Copyright and Similar Rights that applies to Your use of the Licensed Material.
 
-f. __Licensed Material__ means the artistic or literary work, database, or other material to which the Licensor applied this Public License.
+f. __Licensed Material__ means the artistic or literary work, database, or other material to which the Licensor applied this License.
 
-g. __Licensed Rights__ means the rights granted to You subject to the terms and conditions of this Public License, which are limited to all Copyright and Similar Rights that apply to Your use of the Licensed Material and that the Licensor has authority to license.
+g. __Licensed Rights__ means the rights granted to You subject to the terms and conditions of this License, which are limited to all Copyright and Similar Rights that apply to Your use of the Licensed Material and that the Licensor has authority to license.
 
-h. __Licensor__ means the individual(s) or entity(ies) granting rights under this Public License.
+h. __Licensor__ means the individual(s) or entity(ies) granting rights under this License.
 
-i. __NonCommercial__ means not primarily intended for or directed towards commercial advantage or monetary compensation. For purposes of this Public License, the exchange of the Licensed Material for other material subject to Copyright and Similar Rights by digital file-sharing or similar means is NonCommercial provided there is no payment of monetary compensation in connection with the exchange.
+i. __NonCommercial__ means not primarily intended for or directed towards commercial advantage or monetary compensation. For purposes of this License, the exchange of the Licensed Material for other material subject to Copyright and Similar Rights by digital file-sharing or similar means is NonCommercial provided there is no payment of monetary compensation in connection with the exchange.
 
 j. __Share__ means to provide material to the public by any means or process that requires permission under the Licensed Rights, such as reproduction, public display, public performance, distribution, dissemination, communication, or importation, and to make material available to the public including in ways that members of the public may access the material from a place and at a time individually chosen by them.
 
 k. __Sui Generis Database Rights__ means rights other than copyright resulting from Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, as amended and/or succeeded, as well as other essentially equivalent rights anywhere in the world.
 
-l. __You__ means the individual or entity exercising the Licensed Rights under this Public License. Your has a corresponding meaning.
+l. __You__ means the individual or entity exercising the Licensed Rights under this License. Your has a corresponding meaning.
 
 ### Section 2 – Scope.
 
 a. ___License grant.___
 
-   1. Subject to the terms and conditions of this Public License, the Licensor hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive, irrevocable license to exercise the Licensed Rights in the Licensed Material to:
+   1. Subject to the terms and conditions of this License, the Licensor hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive license to exercise the Licensed Rights in the Licensed Material to:
 
        A. reproduce and Share the Licensed Material, in whole or in part, for NonCommercial purposes only; and
 
        B. produce, reproduce, and Share Adapted Material for NonCommercial purposes only.
 
-   2. __Exceptions and Limitations.__ For the avoidance of doubt, where Exceptions and Limitations apply to Your use, this Public License does not apply, and You do not need to comply with its terms and conditions.
+   2. __Exceptions and Limitations.__ For the avoidance of doubt, where Exceptions and Limitations apply to Your use, this License does not apply, and You do not need to comply with its terms and conditions.
 
-   3. __Term.__ The term of this Public License is specified in Section 6(a).
+   3. __Term.__ The term of this License is specified in Section 6(a).
 
-   4. __Media and formats; technical modifications allowed.__ The Licensor authorizes You to exercise the Licensed Rights in all media and formats whether now known or hereafter created, and to make technical modifications necessary to do so. The Licensor waives and/or agrees not to assert any right or authority to forbid You from making technical modifications necessary to exercise the Licensed Rights, including technical modifications necessary to circumvent Effective Technological Measures. For purposes of this Public License, simply making modifications authorized by this Section 2(a)(4) never produces Adapted Material.
+   4. __Media and formats; technical modifications allowed.__ The Licensor authorizes You to exercise the Licensed Rights in all media and formats whether now known or hereafter created, and to make technical modifications necessary to do so. The Licensor waives and/or agrees not to assert any right or authority to forbid You from making technical modifications necessary to exercise the Licensed Rights, including technical modifications necessary to circumvent Effective Technological Measures. For purposes of this License, simply making modifications authorized by this Section 2(a)(4) never produces Adapted Material.
 
-   5. __Downstream recipients.__
-
-        A. __Offer from the Licensor – Licensed Material.__ Every recipient of the Licensed Material automatically receives an offer from the Licensor to exercise the Licensed Rights under the terms and conditions of this Public License.
-
-        B. __No downstream restrictions.__ You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, the Licensed Material if doing so restricts exercise of the Licensed Rights by any recipient of the Licensed Material.
-
-   6. __No endorsement.__ Nothing in this Public License constitutes or may be construed as permission to assert or imply that You are, or that Your use of the Licensed Material is, connected with, or sponsored, endorsed, or granted official status by, the Licensor or others designated to receive attribution as provided in Section 3(a)(1)(A)(i).
+   5. __No endorsement.__ Nothing in this License constitutes or may be construed as permission to assert or imply that You are, or that Your use of the Licensed Material is, connected with, or sponsored, endorsed, or granted official status by, the Licensor or others designated to receive attribution as provided in Section 3.
 
 b. ___Other rights.___
 
-   1. Moral rights, such as the right of integrity, are not licensed under this Public License, nor are publicity, privacy, and/or other similar personality rights; however, to the extent possible, the Licensor waives and/or agrees not to assert any such rights held by the Licensor to the limited extent necessary to allow You to exercise the Licensed Rights, but not otherwise.
+   1. Moral rights, such as the right of integrity, are not licensed under this License, nor are publicity, privacy, and/or other similar personality rights; however, to the extent possible, the Licensor waives and/or agrees not to assert any such rights held by the Licensor to the limited extent necessary to allow You to exercise the Licensed Rights, but not otherwise.
 
-   2. Patent and trademark rights are not licensed under this Public License.
+   2. Patent and trademark rights are not licensed under this License.
 
    3. To the extent possible, the Licensor waives any right to collect royalties from You for the exercise of the Licensed Rights, whether directly or through a collecting society under any voluntary or waivable statutory or compulsory licensing scheme. In all other cases the Licensor expressly reserves any right to collect such royalties, including when the Licensed Material is used other than for NonCommercial purposes.
 
@@ -84,31 +78,15 @@ b. ___Other rights.___
 
 Your exercise of the Licensed Rights is expressly made subject to the following conditions.
 
-a. ___Attribution.___
-
-   1. If You Share the Licensed Material (including in modified form), You must:
-
-       A. retain the following if it is supplied by the Licensor with the Licensed Material:
-
-         i. identification of the creator(s) of the Licensed Material and any others designated to receive attribution, in any reasonable manner requested by the Licensor (including by pseudonym if designated);
+1. If You Share the Licensed Material (including in modified form), You must attribute the Licensor by adding:
 
-         ii. a copyright notice;
+   i. identification of the creator(s) of the Licensed Material and any others designated to receive attribution, in any reasonable manner requested by the Licensor (including by pseudonym if designated);
 
-         iii. a notice that refers to this Public License;
+   ii. a URI or hyperlink to the Licensed Material to the extent reasonably practicable;
 
-         iv. a notice that refers to the disclaimer of warranties;
+2. You may satisfy the conditions in Section 3(1) in any reasonable manner based on the medium, means, and context in which You Share the Licensed Material. For example, it may be reasonable to satisfy the conditions by providing a URI or hyperlink to a resource that includes the required information.
 
-         v. a URI or hyperlink to the Licensed Material to the extent reasonably practicable;
-
-       B. indicate if You modified the Licensed Material and retain an indication of any previous modifications; and
-
-       C. indicate the Licensed Material is licensed under this Public License, and include the text of, or the URI or hyperlink to, this Public License.
-
-   2. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner based on the medium, means, and context in which You Share the Licensed Material. For example, it may be reasonable to satisfy the conditions by providing a URI or hyperlink to a resource that includes the required information.
-
-   3. If requested by the Licensor, You must remove any of the information required by Section 3(a)(1)(A) to the extent reasonably practicable.
-
-   4. If You Share Adapted Material You produce, the Adapter's License You apply must not prevent recipients of the Adapted Material from complying with this Public License.
+3. If requested by the Licensor, You must remove any of the information required by Section 3(1) to the extent reasonably practicable.
 
 ### Section 4 – Sui Generis Database Rights.
 
@@ -118,21 +96,21 @@ a. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract,
 
 b. if You include all or a substantial portion of the database contents in a database in which You have Sui Generis Database Rights, then the database in which You have Sui Generis Database Rights (but not its individual contents) is Adapted Material; and
 
-c. You must comply with the conditions in Section 3(a) if You Share all or a substantial portion of the contents of the database.
+c. You must comply with the conditions in Section 3 if You Share all or a substantial portion of the contents of the database.
 
-For the avoidance of doubt, this Section 4 supplements and does not replace Your obligations under this Public License where the Licensed Rights include other Copyright and Similar Rights.
+For the avoidance of doubt, this Section 4 supplements and does not replace Your obligations under this License where the Licensed Rights include other Copyright and Similar Rights.
 
 ### Section 5 – Disclaimer of Warranties and Limitation of Liability.
 
 a. __Unless otherwise separately undertaken by the Licensor, to the extent possible, the Licensor offers the Licensed Material as-is and as-available, and makes no representations or warranties of any kind concerning the Licensed Material, whether express, implied, statutory, or other. This includes, without limitation, warranties of title, merchantability, fitness for a particular purpose, non-infringement, absence of latent or other defects, accuracy, or the presence or absence of errors, whether or not known or discoverable. Where disclaimers of warranties are not allowed in full or in part, this disclaimer may not apply to You.__
 
-b. __To the extent possible, in no event will the Licensor be liable to You on any legal theory (including, without limitation, negligence) or otherwise for any direct, special, indirect, incidental, consequential, punitive, exemplary, or other losses, costs, expenses, or damages arising out of this Public License or use of the Licensed Material, even if the Licensor has been advised of the possibility of such losses, costs, expenses, or damages. Where a limitation of liability is not allowed in full or in part, this limitation may not apply to You.__
+b. __To the extent possible, in no event will the Licensor be liable to You on any legal theory (including, without limitation, negligence) or otherwise for any direct, special, indirect, incidental, consequential, punitive, exemplary, or other losses, costs, expenses, or damages arising out of this License or use of the Licensed Material, even if the Licensor has been advised of the possibility of such losses, costs, expenses, or damages. Where a limitation of liability is not allowed in full or in part, this limitation may not apply to You.__
 
 c. The disclaimer of warranties and limitation of liability provided above shall be interpreted in a manner that, to the extent possible, most closely approximates an absolute disclaimer and waiver of all liability.
 
 ### Section 6 – Term and Termination.
 
-a. This Public License applies for the term of the Copyright and Similar Rights licensed here. However, if You fail to comply with this Public License, then Your rights under this Public License terminate automatically.
+a. This License applies for the term of the Copyright and Similar Rights licensed here. However, if You fail to comply with this License, then Your rights under this License terminate automatically.
 
 b. Where Your right to use the Licensed Material has terminated under Section 6(a), it reinstates:
 
@@ -140,24 +118,26 @@ b. Where Your right to use the Licensed Material has terminated under Section 6(
 
    2. upon express reinstatement by the Licensor.
 
-   For the avoidance of doubt, this Section 6(b) does not affect any right the Licensor may have to seek remedies for Your violations of this Public License.
+   For the avoidance of doubt, this Section 6(b) does not affect any right the Licensor may have to seek remedies for Your violations of this License.
+
+c. Notwithstanding the above, the Licensor reserves the right to terminate this License with respect to You if the Licensor expressly notifies You of the termination.
 
-c. For the avoidance of doubt, the Licensor may also offer the Licensed Material under separate terms or conditions or stop distributing the Licensed Material at any time; however, doing so will not terminate this Public License.
+d. For the avoidance of doubt, the Licensor may also offer the Licensed Material under separate terms or conditions or stop distributing the Licensed Material at any time.
 
-d. Sections 1, 5, 6, 7, and 8 survive termination of this Public License.
+e. Sections 1, 5, 6, 7, and 8 survive termination of this License.
 
 ### Section 7 – Other Terms and Conditions.
 
 a. The Licensor shall not be bound by any additional or different terms or conditions communicated by You unless expressly agreed.
 
-b. Any arrangements, understandings, or agreements regarding the Licensed Material not stated herein are separate from and independent of the terms and conditions of this Public License.
+b. Any arrangements, understandings, or agreements regarding the Licensed Material not stated herein are separate from and independent of the terms and conditions of this License.
 
 ### Section 8 – Interpretation.
 
-a. For the avoidance of doubt, this Public License does not, and shall not be interpreted to, reduce, limit, restrict, or impose conditions on any use of the Licensed Material that could lawfully be made without permission under this Public License.
+a. For the avoidance of doubt, this License does not, and shall not be interpreted to, reduce, limit, restrict, or impose conditions on any use of the Licensed Material that could lawfully be made without permission under this License.
 
-b. To the extent possible, if any provision of this Public License is deemed unenforceable, it shall be automatically reformed to the minimum extent necessary to make it enforceable. If the provision cannot be reformed, it shall be severed from this Public License without affecting the enforceability of the remaining terms and conditions.
+b. To the extent possible, if any provision of this License is deemed unenforceable, it shall be automatically reformed to the minimum extent necessary to make it enforceable. If the provision cannot be reformed, it shall be severed from this License without affecting the enforceability of the remaining terms and conditions.
 
-c. No term or condition of this Public License will be waived and no failure to comply consented to unless expressly agreed to by the Licensor.
+c. No term or condition of this License will be waived and no failure to comply consented to unless expressly agreed to by the Licensor.
 
-d. Nothing in this Public License constitutes or may be interpreted as a limitation upon, or waiver of, any privileges and immunities that apply to the Licensor or You, including from the legal processes of any jurisdiction or authority.
+d. Nothing in this License constitutes or may be interpreted as a limitation upon, or waiver of, any privileges and immunities that apply to the Licensor or You, including from the legal processes of any jurisdiction or authority.
diff --git a/README.md b/README.md
index 7eb207246..2321ca34a 100755
--- a/README.md
+++ b/README.md
@@ -21,6 +21,7 @@ If maintainers do not respond, or if you'd like to become a maintainer, write us
 
 🎉 Thank you!
 
+<<<<<<< HEAD
 Your name and the contribution size will appear in the "About project" page when the translation gets published.
 
 P.S. The full list of languages can be found at <https://javascript.info/translate>.
@@ -30,12 +31,31 @@ P.S. The full list of languages can be found at <https://javascript.info/transla
 Every chapter, an article or a task resides in its own folder.
 
 The folder is named `N-url`, where `N` – is the number for sorting (articles are ordered), and `url` is the URL-slug on the site.
+=======
+Something's wrong? A topic is missing? Explain it to people, add it as PR 👏
+
+**You can edit the text in any editor.** The tutorial uses an enhanced "markdown" format, easy to grasp. And if you want to see how it looks on-site, there's a server to run the tutorial locally at <https://github.com/javascript-tutorial/server>.
+
+The list of contributors is available at <https://javascript.info/about#contributors>.
+
+## Structure
+
+Every chapter, article, or task has its folder.
+
+The folder is named like `N-url`, where `N` is a number for the sorting purposes and `URL` is the URL part with the title of the material.
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 The folder has one of files:
 
+<<<<<<< HEAD
 - `index.md` for a section,
 - `article.md` for an article,
 - `task.md` for a task formulation (+`solution.md` with the solution text if any).
+=======
+  - `index.md` stands for a chapter
+  - `article.md` stands for an article
+  - `task.md` stands for a task (solution must be provided in `solution.md` file as well)
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
 
 A file starts with the `# Title Header`, and then the text in Markdown-like format, editable in a simple text editor. 
 
@@ -112,6 +132,7 @@ Some files, usually tasks, have YAML metadata at the top, delimited by `---`:
 ```md
 importance: 5
 
+<<<<<<< HEAD
 ---
 ...
 ```
@@ -133,3 +154,8 @@ Please don't translate or remove the `[#...]` part, it's for URL anchors.
 You can run the tutorial server locally to see how the translation looks.
 
 The server and install instructions are at <https://github.com/javascript-tutorial/server>. 
+=======
+---  
+♥  
+Ilya Kantor @iliakan
+>>>>>>> 34a80e70f8cce5794be259d25f815d7a7db7cbe3
diff --git a/figures.sketch b/figures.sketch
index 877c1c628..104333192 100644
Binary files a/figures.sketch and b/figures.sketch differ
diff --git a/svgs.zip b/svgs.zip
new file mode 100644
index 000000000..46eeb9862
Binary files /dev/null and b/svgs.zip differ