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 7a15d32a..6cbb3c4d 100644
--- a/1-js/02-first-steps/01-hello-world/article.md
+++ b/1-js/02-first-steps/01-hello-world/article.md
@@ -1,10 +1,10 @@
# Hello, world!
-The tutorial that you're reading is about core Javascript, that is platform-independant. So you'll be able to learn how to use Node.JS and other things based on that knowledge.
+The tutorial that you're reading is about the core Javascript, that is platform-independant. So you'll be able to learn how to use Node.JS and other things based on that knowledge.
-But we need a working environment to run our scripts, and browser is probably a good choice. Also we'll use few browser-specific commands like `alert`, but will keep their amount to the minimum.
+But we need a working environment to run our scripts, and, just because this book is online, the browser is probably a good choice. We'll use a few browser-specific commands like `alert`, but will keep their amount to the minimum.
-So we'll start with attaching a script to the webpage. For other environments like Node.JS there are other, probably even easier ways to run it.
+So here we'll see how to attach a script to the webpage, that's simple enough. For server-side environments you can just execute it with a command like `"node my.js"` for Node.JS.
[cut]
diff --git a/1-js/02-first-steps/02-structure/article.md b/1-js/02-first-steps/02-structure/article.md
index 0066b33a..ffd0980b 100644
--- a/1-js/02-first-steps/02-structure/article.md
+++ b/1-js/02-first-steps/02-structure/article.md
@@ -1,6 +1,6 @@
# Code structure
-The first overall thing to know is the code structure.
+The first thing to study is the building blocks of the code.
[cut]
@@ -54,8 +54,8 @@ The code outputs `6`, because JavaScript does not insert semicolons here. It is
Errors which occur in such cases are quite hard to find and fix.
-````smart header="An example of the error"
-If you're curious to see a concrete example, check this code out:
+````smart header="An example of an error"
+If you're curious to see a concrete example of such an error, check this code out:
```js run
[1, 2].forEach(alert)
@@ -63,34 +63,37 @@ If you're curious to see a concrete example, check this code out:
It shows `1` then `2`.
-No need to think about the meaning of the brackets `[]` and `forEach`, for now -- it does not matter. Let's just remember the result.
+No need to think about the meaning of the brackets `[]` and `forEach` yet. We'll study them, for now -- it does not matter. Let's just remember the result.
-Now let's put an `alert` before the code. And *not* finish it with a semicolon:
+Now let's add an `alert` before the code. And *not* finish it with a semicolon:
```js run no-beautify
-alert( "There will be an error" ) // shown
+alert( "There will be an error" )
-[1, 2].forEach(alert) // doesn't work any more!
+[1, 2].forEach(alert)
```
Now if we run it, only the first `alert` is shown, and then an error.
But everything is fine again if we add a semicolon after `alert`:
```js run
-alert( "All fine now" ); // shown
+alert( "All fine now" );
-[1, 2].forEach(alert) // this works too
+[1, 2].forEach(alert)
```
+Now we have the "All fine now" message and then `1` and `2`.
+
+
The error in the no-semicolon variant occurs because automatic semicolon insertion rules are complex, and in particular, JavaScript does not imply a semicolon before square brackets `[...]`.
-And, because the semicolon is not auto-inserted, the code is treated as a single statement, like this:
+And, because the semicolon is not auto-inserted, the code in the first example is treated as a single statement, like this:
```js run no-beautify
alert( "There will be an error" )[1, 2].forEach(alert)
```
-And in this particular case, that's just wrong, hence the error. There are other situations when such thing happens.
+But it should be two separate statements, not a single one. Such a merging in this case is just wrong, hence the error. There are other situations when such thing happens.
````
It's recommended to put semicolons between statements even if they are separated by newlines. This rule is widely adopted by the community. Let's note once again -- *it is possible* to leave out semicolons most of time. But it's safer, especially for a beginner -- to put them.
@@ -105,12 +108,12 @@ Comments can be put into any place of the script. They don't affect the executio
The rest of the line is a comment. It may occupy a full line of its own or follow a statement.
-Like this:
+Like here:
```js run
-// This shows "Hello" (the comment occupies a line of its own)
+// This comment occupies a line of its own
alert( 'Hello' );
-alert( 'World' ); // ...this shows "World" (the comment follows a statement)
+alert( 'World' ); // This comment follows the statement
```
**Multiline comments start with a slash and a star "/*"
and end with a star and a slash "*/"
.**
@@ -125,7 +128,7 @@ alert( 'Hello' );
alert( 'World' );
```
-The content of comments is ignored, so if we put a code inside /* ... */
or after `//` it won't execute.
+The content of comments is ignored, so if we put a code inside /* ... */
it won't execute.
Sometimes it comes handy to temporarily disable a part of the code:
diff --git a/1-js/02-first-steps/05-types/article.md b/1-js/02-first-steps/05-types/article.md
index 747a17af..41d31c50 100644
--- a/1-js/02-first-steps/05-types/article.md
+++ b/1-js/02-first-steps/05-types/article.md
@@ -43,13 +43,13 @@ Besides regular numbers there are so-called "special numeric values" which also
- `NaN` represents a computational error. It is a result of an incorrect or an undefined mathematical operation, for instance:
```js run
- alert( "not a number" / 2 ); // NaN
+ alert( "not a number" / 2 ); // NaN, such division is erroneous
```
`NaN` is sticky. Any further operation on `NaN` would give `NaN`:
```js run
- alert( "not a number" / 2 + 5 ); // NaN + 5 is still NaN
+ alert( "not a number" / 2 + 5 ); // NaN
```
So, if there's `NaN` somewhere in a mathematical expression, it propagates to the whole result.
@@ -66,6 +66,8 @@ We'll see more into working with numbers in the chapter .
## A string
+A string in Javascript must be quoted.
+
```js
let str = "Hello";
let str2 = 'Single quotes are ok too';
@@ -78,7 +80,7 @@ In JavaScript, there are 3 types of quotes.
2. Single quotes: `'Hello'`.
3. Backticks: `Hello`
.
-Double and single quotes are similar, "simple" quotes.
+Double and single quotes are "simple" quotes. They mark the beginning and the end of the string, that's all. There's no difference between them in Javascript.
Backticks are "extended functionality" quotes. They allow to embed variables and expressions into a string by wrapping them in `${…}`, for example:
@@ -94,10 +96,15 @@ alert( `the result is ${1 + 2}` ); // the result is 3
The expression inside `${…}` is evaluated and the result becomes a part of the string. We can put anything there: a variable like `name` or an arithmetical expression like `1 + 2` or something more complex.
+Please note that other quotes do not allow such embedding!
+```js run
+alert( "the result is ${1 + 2}" ); // the result is ${1 + 2} (double quotes do nothing)
+```
+
We'll cover strings more thoroughly in the chapter .
```smart header="There is no *character* type."
-In some languages, there is a special "character" type for a single character. For example, in the C language it is `char`.
+In some languages, there is a special "character" type for a single character. For example, in the C language and in Java it is `char`.
In JavaScript, there is no such type. There's only one type: `string`. A string may consist of only one character or many of them.
```
@@ -111,8 +118,8 @@ This type is commonly used to store yes/no values: `true` means "yes, correct",
For instance:
```js
-let checked1 = true; // yes, the form field is checked
-let checked2 = false; // no, the form field is not checked
+let nameChecked = true; // yes, the form field name is checked
+let ageChecked = false; // no, the form field age is not checked
```
Boolean values also come as the result of comparisons:
diff --git a/1-js/02-first-steps/14-function-basics/article.md b/1-js/02-first-steps/14-function-basics/article.md
index 6eab133c..c1c6bd3b 100644
--- a/1-js/02-first-steps/14-function-basics/article.md
+++ b/1-js/02-first-steps/14-function-basics/article.md
@@ -380,6 +380,59 @@ For example, [jQuery](http://jquery.com) framework defines a function `$`, [LoDa
These are exceptions. Generally functions names should be concise, but descriptive.
```
+## Functions == Comments
+
+Functions should be short and do exactly one thing. If that thing is big, maybe it's worth to split the function into parts.
+
+Sometimes following this rule may be not easy, but it's a definitely good thing.
+
+...So why functions equal comments?
+
+A separate function is not only easier to test and debug -- its very existence is a great comment!
+
+For instance, compare the two functions `showPrimes(n)` below. Each one outputs [prime numbers](https://en.wikipedia.org/wiki/Prime_number) up to `n`.
+
+The first variant uses a label:
+
+```js
+function showPrimes(n) {
+ nextPrime: for (let i = 2; i < n; i++) {
+
+ for (let j = 2; j < i; j++) {
+ if (i % j == 0) continue nextPrime;
+ }
+
+ alert( i ); // a prime
+ }
+}
+```
+
+The second variant uses an additional function `isPrime(n)` to test for primality:
+
+```js
+function showPrimes(n) {
+
+ for (let i = 2; i < n; i++) {
+ *!*if (!isPrime(i)) continue;*/!*
+
+ alert(i); // a prime
+ }
+}
+
+function isPrime(n) {
+ for (let i = 2; i < n; i++) {
+ if ( n % i == 0) return false;
+ }
+ return true;
+}
+```
+
+The second variant is easier to understand isn't it? Instead of the code piece we see a name of the action (`isPrime`). Sometimes people refer to such code as *self-describing*.
+
+```summary
+So the idea is: functions can be created even if we don't intend to reuse them. They structure the code and make it readable.
+```
+
## Summary
A function declaration looks like this:
diff --git a/1-js/02-first-steps/15-function-expressions-arrows/article.md b/1-js/02-first-steps/15-function-expressions-arrows/article.md
index 2a232f05..e2bb3f7c 100644
--- a/1-js/02-first-steps/15-function-expressions-arrows/article.md
+++ b/1-js/02-first-steps/15-function-expressions-arrows/article.md
@@ -95,7 +95,7 @@ The answer is simple:
- A Function Expression is used inside the statement: `let sayHi = ...;`, as a value. It's not a code block. The semicolon `;` is recommended at the end of statements, no matter what is the value. So the semicolon here is not related to Function Expression itself in any way, it just terminates the statement.
````
-## Anonymous functions
+## Callback functions
Let's see an example where function expressions come really handy.
@@ -134,9 +134,13 @@ ask("Do you agree?", showOk, showCancel);
The code looks kind of too simple, right? Why would anyone need such `ask`?
-...It turns out that in the browser such functions are very required, the minor difference is that they ask not with a simple `confirm`, but output a much richer looking question window. But that's another story.
+...It turns out that in the browser (and on the server-side in some cases) such functions are quite popular. The major difference between a real-life implementation 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 a function usually draws a nice-looking question window. But that's another story.
-Right now let's see how we can write the same much shorter:
+The arguments of `ask` are called *callback functions* or just *callbacks*. The idea is that we pass the functions and expect them to be "called back" in certain circumstances.
+
+So, `showOk` becomes the callback for the "yes" answer and `showCancel` -- for the "no" answer.
+
+We can use Function Expressions to write the same much shorter:
```js run no-beautify
function ask(question, yes, no) {
@@ -153,9 +157,9 @@ ask(
*/!*
```
-Here functions are declared right inside the `ask(...)` call. They have no name (anonymous) and are not accessible outside of `ask`, but that's just what we need.
+Here functions are declared right inside the `ask(...)` call. They have no name, and so are called *anonymous*. Such functions are not accessible outside of `ask`, but that's just what we want here.
-Such code appears very naturally, it's in the spirit of Javascript.
+Such code appears in our scripts very naturally, it's in the spirit of Javascript.
```smart header="A function is a value representing an \"action\""
@@ -405,7 +409,17 @@ let double = n => n*2;
alert( double(3) ); // 6
```
-If there are no arguments, we can put empty brackets. For instance, here's the rewritten example with `welcome()`:
+If there are no arguments, we can put empty brackets:
+
+```js run
+let sayHi = () => alert("Hello!");
+
+sayHi();
+```
+
+Arrow functions can be used same way as Function Expressions.
+
+For instance, here's the rewritten example with `welcome()`:
```js run
let age = prompt("What is your age?", 18);
@@ -439,45 +453,26 @@ alert( sum(1, 2) ); // 3
```
```smart header="More to come"
-Here we praised arrow functions for shortness. But that's not all! Arrow functions have other interesting features. We'll return to them later and see where else they shine.
+Here we praised arrow functions for shortness. But that's not all! Arrow functions have other interesting features. We'll return to them later in the chapter .
-As for now, we can already use them for one-line actions.
+As for now, we can already use them for one-line actions and callbacks.
```
## Summary
-[todo review]
-
- Functions are values. They can be assigned, copied or declared in any place of the code.
- If the function is declared as a separate statement, in the main code flow -- that's called a Function Declaration.
- If the function is created as a part of an expression -- it's a Function Expression.
-- Function Declarations are processed before the code block is executed. They are visible everywhere in the block (or the script).
+- Function Declarations are processed before the code block is executed. They are visible everywhere in the block.
- Function Expressions are created when the execution flow reaches them.
- Function Expressions allow to specify an optional name for internal needs (Named Function Expression).
-If we simple want to create a function, then in most cases Function Declaration is preferable.
+In most cases Function Declaration is preferable, because it is visible prior to the declaration itself. And is usually more readable.
-Novice programmers sometimes tend to overuse Function Expression by creating many functions with `let func = function()`, but compare, which code is more readable:
+So we should use Function Expression only when Function Declaration does not fit the task. We've seen a couple of examples of that in the chapter. And will see more in the future.
-```js no-beautify
-let f = function() { /* expression */ }
+Arrow functions are handy for one-liners. The come in two flavors:
-function f() { /* declaration */ }
-```
-
-Function Declaration is shorter and more obvious. The additional bonus -- it can be called before the actual declaration.
-
-**Use Function Expression only when Function Declaration does not fit the task.**
-
-We've seen a couple of examples of that in the chapter. And will see more in the future.
-
-We also touched two other ways to create a function:
-
-- Arrow functions are handy for one-liners. The come in two flavours:
- 1. Without figure brackets: `(...args) => expression` -- returns the evaluated `expression`.
- 2. With brackets: `(...args) => { body }` -- need an explicit `return` statement to return something, but can be more complex.
-
-- `new Function(args, body)`
-
- This syntax allows to create a function from a string, that may be composed dynamically during the execution.
+1. Without figure brackets: `(...args) => expression` -- returns the evaluated `expression`. The right side must be a single expression.
+2. With figure brackets: `(...args) => { body }` -- they need an explicit `return` statement to return something, but can be more complex and contain multiple statements.
diff --git a/1-js/02-first-steps/16-javascript-specials/article.md b/1-js/02-first-steps/16-javascript-specials/article.md
index cc69e119..5406bbfb 100644
--- a/1-js/02-first-steps/16-javascript-specials/article.md
+++ b/1-js/02-first-steps/16-javascript-specials/article.md
@@ -1,10 +1,8 @@
-# JavaScript specials: all together
+# Javascript specials
-[todo finish me. is this needed?]
+This chapter aims to list features of JavaScript that we've learned, paying special attention to subtle moments.
-This chapter aims to list features of JavaScript that we've learned, paying special attention to unobvious moments.
-
-That's especially useful if you came from another language or, just as a recap.
+That's especially useful if you came from another language or just as a recap.
[cut]
@@ -37,13 +35,13 @@ Semicolons are not required after code blocks `{...}` and syntax constructs with
```js
function f() {
- // no semicolon after function declaration
+ // no semicolon needed after function declaration
}
-for(;;) { /* no semicolon */ }
+for(;;) { /* no semicolon after the loop */ }
```
-...But even if we can put a semicolon there, that's not an error, extra semicolons do nothing.
+...But even if we can put an "extra" semicolon somewhere, that's not an error, it will be ignored.
More in: .
@@ -61,7 +59,7 @@ The directive must be at the top of a script or at the beginning of a function.
Without `"use strict"`, everything still works, but some features behave in old-fasion, "compatible" way. We'd generally prefer the modern behavior.
-Later we'll get acquanted with advanced features of the language that enable strict mode implicitly.
+Advanced features of the language (like classes that we'll study in the future) that enable strict mode implicitly.
More in: .
@@ -94,7 +92,13 @@ There are 7 data types:
- `undefined` -- a type with a single value `undefined`, meaning "not assigned",
- `object` and `symbol` -- for complex data structures and unique identifiers, we didn't learn them yet.
-More in: , .
+The `typeof` operator returns the type for a value, with two special behaviors:
+```js
+typeof null == "object" // error in the language
+typeof function(){} == "function" // functions are treated specially
+```
+
+More in: and .
## Interaction
@@ -117,8 +121,8 @@ For instance:
let userName = prompt("Your name?", "Alice");
let isTeaWanted = confirm("Do you want some tea?");
-alert( "Visitor: " + userName );
-alert( "Tea wanted: " + isTeaWanted );
+alert( "Visitor: " + userName ); // Alice
+alert( "Tea wanted: " + isTeaWanted ); // true
```
More in: .
@@ -130,7 +134,7 @@ JavaScript supports following operators:
Arithmetical
: Regular: `* + - /`, also `%` for the remainder and `**` for power of a number.
- Binary plus `+` contatenates strings.
+ Binary plus `+` concatenates strings.
If any of the operands is a string -- the other one is converted to string too:
@@ -143,7 +147,8 @@ Assignments
: There is a simple assignment: `a = b` and combined ones like `a *= 2`.
Bitwise
-: Bitwise operators work with integers on bit-level: see the [docs](mdn:JavaScript/Reference/Operators/Bitwise_Operators) when they are needed.
+: Bitwise operators work with integers on bit-level: see the [docs](mdn:JavaScript/Refereno
+ ce/Operators/Bitwise_Operators) when they are needed.
Ternary
: The only operator with three parameters: `cond ? resultA : result B`
@@ -152,189 +157,140 @@ Logical operators
: Logical AND `&&` and OR `||` perform short-circuit evaluation and then return the value where it stopped.
Comparisons
-: Equality check `===` immediately fails if types are different.
-
- Other comparisons perform type conversions, usually to a number:
+: 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:
```js run
alert( 0 == false ); // true
- alert( true > 0 ); // true
+ alert( 0 == '' ); // true
```
+ Other comparisons convert to a number as well.
+
+ The strict equality operator `===` doesn't do the conversion: different types always mean different values for it, so:
+
+
+
Values `null` and `undefined` are special: they equal `==` each other and don't equal anything else.
Greater/less comparisons compare strings character-by-character, other types are converted to a number.
-Others
+Logical operators
: There are few others, like a comma operator.
-More in: , .
+More in: , , .
-## Логические операторы
+## Loops
-В JavaScript есть логические операторы: И (обозначается `&&`), ИЛИ (обозначается `||`) и НЕ (обозначается `!`). Они интерпретируют любое значение как логическое.
-
-Не стоит путать их с [побитовыми операторами](/bitwise-operators) И, ИЛИ, НЕ, которые тоже есть в JavaScript и работают с числами на уровне битов.
-
-Как и в большинстве других языков, в логических операторах используется "короткий цикл" вычислений. Например, вычисление выражения `1 && 0 && 2` остановится после первого И `&&`, т.к. понятно что результат будет ложным (ноль интерпретируется как `false`).
-
-**Результатом логического оператора служит последнее значение в коротком цикле вычислений.**
-
-Можно сказать и по-другому: значения хоть и интерпретируются как логические, но то, которое в итоге определяет результат, возвращается без преобразования.
-
-Например:
-
-```js run
-alert( 0 && 1 ); // 0
-alert( 1 && 2 && 3 ); // 3
-alert( null || 1 || 2 ); // 1
-```
-
-Подробнее: .
-
-## Циклы
-
-- Поддерживаются три вида циклов:
+- We covered 3 types of loops:
```js
// 1
- while (условие) {
+ while (condition) {
...
}
// 2
do {
...
- } while (условие);
+ } while (condition);
// 3
- for let i = 0; i < 10; i++) {
+ for(let i = 0; i < 10; i++) {
...
}
```
-- Переменную можно объявлять прямо в цикле, но видна она будет и за его пределами.
-- Поддерживаются директивы `break/continue` для выхода из цикла/перехода на следующую итерацию.
- Для выхода одновременно из нескольких уровней цикла можно задать метку.
+- The variable declared in `for(let...)` loop is visible only inside the loop. But we can also omit `let` and reuse an existing variable.
+- Directives `break/continue` allow to exit the whole loop/current iteration. Use labels to break nested loops.
- Синтаксис: "`имя_метки:`", ставится она только перед циклами и блоками, например:
+Details in: .
- ```js
- *!*outer:*/!*
- for(;;) {
- ...
- for(;;) {
- ...
- *!*break outer;*/!*
- }
- }
- ```
+Later we'll study more types of loops to deal with objects.
- Переход на метку возможен только изнутри цикла, и только на внешний блок по отношению к данному циклу. В произвольное место программы перейти нельзя.
+## The "switch" construct
-Подробнее: .
+The "switch" construct can replace multiple `if` checks. It uses `===` for comparisons.
-## Конструкция switch
-
-При сравнениях в конструкции `switch` используется оператор `===`.
-
-Например:
+For instance:
```js run
-let age = prompt('Ваш возраст', 18);
+let age = prompt('Your age?', 18);
switch (age) {
case 18:
- alert( 'Никогда не сработает' ); // результат prompt - строка, а не число
+ alert("Won't work"); // the result of prompt is a string, not a number число
- case "18": // вот так - сработает!
- alert( 'Вам 18 лет!' );
+ case "18":
+ alert("This works!"");
break;
default:
- alert( 'Любое значение, не совпавшее с case' );
+ alert("Any value not equal to one above");
}
```
-Подробнее: .
+Details in: .
-## Функции
+## Functions
-Синтаксис функций в JavaScript:
+We covered 3 ways to create a function in Javascript:
-```js run
-// function имя(список параметров) { тело }
-function sum(a, b) {
- let result = a + b;
+1. Function Declaration: the function in the main code flow
- return result;
-}
+ ```js
+ function sum(a, b) {
+ let result = a + b;
-// использование:
-alert( sum(1, 2) ); // 3
-```
-
-- `sum` -- имя функции, ограничения на имя функции -- те же, что и на имя переменной.
-- Переменные, объявленные через `let` внутри функции, видны везде внутри этой функции, блоки `if`, `for` и т.п. на видимость не влияют.
-- Параметры копируются в локальные переменные `a`, `b`.
-- Функция без `return` считается возвращающей `undefined`. Вызов `return` без значения также возвращает `undefined`:
-
- ```js run no-beautify
- function f() { }
- alert( f() ); // undefined
+ return result;
+ }
```
-Подробнее: .
+2. Function Expression: the function in the context of an expression
-## Function Declaration и Expression
+ ```js
+ let sum = function(a, b) {
+ let result = a + b;
-Функция в JavaScript является обычным значением.
+ return result;
+ }
+ ```
-Её можно создать в любом месте кода и присвоить в переменную, вот так:
+ Function expression can have a name, like `sum = function name(a, b)`, but that `name` is only visible inside that function.
-```js run
-let sum = function(a, b) {
- let result = a + b;
+3. Arrow functions:
- return result;
-}
+ ```js
+ // expression at the right side
+ let sum = (a, b) => a + b;
-alert( sum(1, 2) ); // 3
-```
+ // or multiline syntax with { ... }, need return here:
+ let sum = (a, b) => {
+ // ...
+ return a + b;
+ }
-Такой синтаксис, при котором функция объявляется в контексте выражения (в данном случае, выражения присваивания), называется Function Expression, а обычный синтаксис, при котором функция объявляется в основном потоке кода -- Function Declaration.
+ // without arguments
+ let sayHi = () => alert("Hello");
-Функции, объявленные через Function Declaration, отличаются от Function Expression тем, что интерпретатор создаёт их при входе в область видимости (в начале выполнения скрипта), так что они работают до объявления.
+ // with a single argument
+ let double = n => n * 2;
+ ```
-Обычно это удобно, но может быть проблемой, если нужно объявить функцию в зависимости от условия. В этом случае, а также в других ситуациях, когда хочется создать функцию "здесь и сейчас", используют Function Expression.
-Детали: .
+- Functions may have local variables -- those declared inside its body. 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`.
-## Named Function Expression
-Если объявление функции является частью какого-либо выражения, например `let f = function...` или любого другого, то это Function Expression.
+| Function Declaration | Function Expression |
+|----------------------|---------------------|
+| visible in the whole code block | created when the execution reaches it |
+| - | can have a name, visible only inside the function |
-В этом случае функции можно присвоить "внутреннее" имя, указав его после `function`. Оно будет видно только внутри этой функции и позволяет обратиться к функции изнутри себя. Обычно это используется для рекурсивных вызовов.
+More: see , .
-Например, создадим функцию для вычисления факториала как Function Expression и дадим ей имя `me`:
+## More to come
-```js run
-let factorial = function me(n) {
- return (n == 1) ? n : n * me(n - 1);
-}
+That was a brief list of Javascript specials that we need to know to code well.
-alert( factorial(5) ); // 120
-*!*
-alert( me ); // ошибка, нет такой переменной
-*/!*
-```
-
-Ограничение видимости для имени не работает в IE8-, но вызов с его помощью работает во всех браузерах.
-
-Более развёрнуто: .
-
-## Итого
-
-В этой главе мы повторили основные особенности JavaScript, знание которых необходимо для обхода большинства "граблей", да и просто для написания хорошего кода.
-
-Это, конечно, лишь основы. Дальше вы узнаете много других особенностей и приёмов программирования на этом языке.
+As of now that were only basics. Further in the tutorial you'll find more specials and advanced features of Javascript.
diff --git a/1-js/03-code-quality/01-debugging-chrome/article.md b/1-js/03-code-quality/01-debugging-chrome/article.md
new file mode 100644
index 00000000..7e16d22e
--- /dev/null
+++ b/1-js/03-code-quality/01-debugging-chrome/article.md
@@ -0,0 +1,181 @@
+# Debugging in Chrome
+
+Before going further, let's talk about debugging.
+
+All modern browsers and most other environments support "debugging" -- a special UI in developer tools that makes finding and fixing errors much easier.
+
+We'll be talking about Chrome here, because they are probably the most feature-rich.
+
+[cut]
+
+## The "sources" pane
+
+Your Chrome version may look a little bit different, but it still should be obvious what's there.
+
+- Open the [example page](debugging/index.html) in Chrome.
+- Turn on developer tools with `key:F12` (Mac: `key:Cmd+Opt+I`).
+- Select the `sources` pane.
+
+Here's what you should see if you are doing it for the first time:
+
+
+
+The toggler button opens the tab with files.
+
+Let's click it and select `index.html` and then `hello.js` in the tree view. That's what should show up:
+
+
+
+Here we can see three zones:
+
+1. **Resources zone** lists html, javascript, css and other files including images that are attached to the page. Currently active chrome extensions may appear here too.
+2. **Source zone** shows the source code.
+3. **Information and control zone** is for debugging, we'll explore it later.
+
+Now you could click the same toggler again to hide the resources list, as we won't need it soon.
+
+## Console
+
+If we press `Esc`, then a console opens below, to type commands into.
+
+After a statement is executed, its result is shown.
+
+For example, here `1+2` results in `3` and `hello("debugger")` call shows a message, but there's no result, so it's `undefined`:
+
+
+
+## Breakpoints
+
+Let's examine what's going on within the code. In `hello.js`, click at the line number `4`, right on the `4` digit.
+
+Contratulations! You've set a breakpoint. Please also click on the number for line `8`.
+
+Should look like this:
+
+
+
+A *breakpoint* is a point of code where the debugger will automatically pause the Javascript execution.
+
+While the code is paused, we can examine current variables, execute commands in the console etc. That is -- debug it.
+
+Breakpoints also show in the right pane. We can always find a list of breakpoints there.
+
+It allows to:
+- Quickly jump to the breakpoint in the code (by clicking on it in the right pane).
+- Temporarily disable the breakpoint by unchecking it.
+- Remove the breakpoint by right-clicking the text and selecting Remove.
+- ...And so on.
+
+````smart header="Breakpoint alternatives"
+- We can make debugger to pause the code by using the `debugger` command, like this:
+
+ ```js
+ function hello(name) {
+ let phrase = `Hello, ${name}!`;
+
+ *!*
+ debugger; // <-- the debugger stops here
+ */!*
+
+ say(phrase);
+ }
+ ```
+- *Right click* on the line number allows to create a conditional breakpoint. It only triggers when a given expression is truthy.
+
+ That's handy when we need to stop only for a certain variable value or for a certain function parameters.
+````
+
+## Pause and look around
+
+In our example, `hello()` is called during page load, so the easiest way to activate debugger -- is to reload the page. So let's press `key:F5` (Windows, Linux) or `key:Cmd+R` (Mac).
+
+As the breakpoint is set, the execution pauses at the 4th line:
+
+
+
+Please open the informational dropdowns to the right (labelled with arrows). They allow to examine the current code state:
+
+1. **`Watch` -- shows current values for any expressions.**
+
+ You can click the plus `+` and input an expression. The debugger will shown its value at any moment, automatically recalculating it in in the process.
+
+2. **`Call Stack` -- shows the nested calls chain.**
+
+ At the current moment the debugger is inside `hello()` call, called by a script in `index.html` (no function there).
+
+ If you click the item there, the debugger jumps to the corresponding code, and all its variables can be examined as well.
+3. **`Scope` -- current variables.**
+
+ `Local` shows local function variables. You can also see their values highlighted right over the source.
+
+ `Global` has global variables (out of any functions).
+
+ There's also `this` keyword there that we didn't study yet, but we'll do that soon.
+
+## Tracing the execution
+
+Now let's time to *trace* the script.
+
+There are buttons for it at the right-top:
+
+ -- continue the execution, hotkey `key:F8`.
+: Resumes the execution. If there are no additional breakpoints, then the execution just continues and the debugger looses the control.
+
+ Let's click it:
+
+ 
+
+ The execution has resumed, reached another breakpoint inside `say()` and paused there. Take a look at the "Call stack" at the right. It has increased by one more call. We're inside `say()` now.
+
+ -- make a step (run the next command), but *not go into the function*, hotkey `key:F10`.
+: If we click it now, `alert` will be shown. The important thing is that if `alert` were not native, but a Javascript function, then the execution would "step over it", skipping the function internals.
+
+ -- make a step, hotkey `key:F11`.
+: The same as the previous one, but "steps in" nested functions. Clicking this will step through all script actions one by one.
+
+ -- continue the execution till the end of the current function, hotkey `key:Shift+F11`.
+: The execution would stop at the very last line of the current function. That's handy when we accidentally entered a nested call using , but it does not interest us and we want to continue to its end as soon as possible.
+
+ -- enable/disable all breakpoints.
+: That button does not move the execution. Just a mass on/off for breakpoints.
+
+ -- enable/disable automatic pause in case of an error.
+: When it's enabled (by default it is), an error pauses the execution and we can analyze variables to see what went wrong. So if our script dies with error, we can open debugger and reload the page to see where it stopped and what was the context at that moment.
+
+```smart header="Continue to here"
+Right click on the line number opens the contextual menu where we can "Continue to here". That's handy when we want to move multiple steps forward, but too lazy to set a breakpoint.
+```
+
+## Logging
+
+To output something to console, there's `console.log` function.
+
+For instance, this logs values from `0` to `4`:
+
+```js run
+// open console to see
+for (let i = 0; i < 5; i++) {
+ console.log("value", i);
+}
+```
+
+To see the output, you can either switch to "Console" tab in developer tools or press `key:Esc` while in another tab: that opens the console at the bottom.
+
+That's called "logging". If we have enough logging in our code, then we can see what's going on from the records, without the debugger.
+
+## Summary
+
+As we can see, there are 3 main ways to pause a script:
+1. A breakpoint.
+2. The `debugger` statements.
+3. An error (if dev tools are open and the button is "on")
+
+Then the debugging process usually consists of examining variables and stepping on to see where the execution goes the wrong way.
+
+There's much more power in developer tools.
+
+The better manual is at
+
+The information from this chapter is enough to begin debugging, but later, especially if you are doing in-browser stuff, please go there and look through more advanced capabilities of developer tools.
+
+Oh, and also you can click at various places of dev tools and just see what's showing up. That's probably the fastest route to learn dev tools. Don't forget about the right click as well!
diff --git a/1-js/03-code-quality/01-debugging-chrome/chrome-open-sources.png b/1-js/03-code-quality/01-debugging-chrome/chrome-open-sources.png
new file mode 100644
index 00000000..efa3c19d
Binary files /dev/null and b/1-js/03-code-quality/01-debugging-chrome/chrome-open-sources.png differ
diff --git a/1-js/03-code-quality/01-debugging-chrome/chrome-open-sources@2x.png b/1-js/03-code-quality/01-debugging-chrome/chrome-open-sources@2x.png
new file mode 100644
index 00000000..e184bdd0
Binary files /dev/null and b/1-js/03-code-quality/01-debugging-chrome/chrome-open-sources@2x.png differ
diff --git a/1-js/03-code-quality/01-debugging-chrome/chrome-sources-breakpoint.png b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-breakpoint.png
new file mode 100644
index 00000000..2fe449c9
Binary files /dev/null and b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-breakpoint.png differ
diff --git a/1-js/03-code-quality/01-debugging-chrome/chrome-sources-breakpoint@2x.png b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-breakpoint@2x.png
new file mode 100644
index 00000000..e4abc89d
Binary files /dev/null and b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-breakpoint@2x.png differ
diff --git a/1-js/03-code-quality/01-debugging-chrome/chrome-sources-console.png b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-console.png
new file mode 100644
index 00000000..98b22e77
Binary files /dev/null and b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-console.png differ
diff --git a/1-js/03-code-quality/01-debugging-chrome/chrome-sources-console@2x.png b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-console@2x.png
new file mode 100644
index 00000000..3269a80f
Binary files /dev/null and b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-console@2x.png differ
diff --git a/1-js/03-code-quality/01-debugging-chrome/chrome-sources-debugger-pause.png b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-debugger-pause.png
new file mode 100644
index 00000000..719293d2
Binary files /dev/null and b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-debugger-pause.png differ
diff --git a/1-js/03-code-quality/01-debugging-chrome/chrome-sources-debugger-pause@2x.png b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-debugger-pause@2x.png
new file mode 100644
index 00000000..5c22ab36
Binary files /dev/null and b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-debugger-pause@2x.png differ
diff --git a/1-js/03-code-quality/01-debugging-chrome/chrome-sources-debugger-trace-1.png b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-debugger-trace-1.png
new file mode 100644
index 00000000..1848ccfa
Binary files /dev/null and b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-debugger-trace-1.png differ
diff --git a/1-js/03-code-quality/01-debugging-chrome/chrome-sources-debugger-trace-1@2x.png b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-debugger-trace-1@2x.png
new file mode 100644
index 00000000..fcabf722
Binary files /dev/null and b/1-js/03-code-quality/01-debugging-chrome/chrome-sources-debugger-trace-1@2x.png differ
diff --git a/1-js/03-code-quality/01-debugging-chrome/chrome-tabs.png b/1-js/03-code-quality/01-debugging-chrome/chrome-tabs.png
new file mode 100644
index 00000000..ff91c531
Binary files /dev/null and b/1-js/03-code-quality/01-debugging-chrome/chrome-tabs.png differ
diff --git a/1-js/03-code-quality/01-debugging-chrome/chrome-tabs@2x.png b/1-js/03-code-quality/01-debugging-chrome/chrome-tabs@2x.png
new file mode 100644
index 00000000..09b10bf4
Binary files /dev/null and b/1-js/03-code-quality/01-debugging-chrome/chrome-tabs@2x.png differ
diff --git a/1-js/03-code-quality/1-debugging-chrome/chrome_break_error.png b/1-js/03-code-quality/01-debugging-chrome/chrome_break_error.png
similarity index 100%
rename from 1-js/03-code-quality/1-debugging-chrome/chrome_break_error.png
rename to 1-js/03-code-quality/01-debugging-chrome/chrome_break_error.png
diff --git a/1-js/03-code-quality/1-debugging-chrome/chrome_break_error@2x.png b/1-js/03-code-quality/01-debugging-chrome/chrome_break_error@2x.png
similarity index 100%
rename from 1-js/03-code-quality/1-debugging-chrome/chrome_break_error@2x.png
rename to 1-js/03-code-quality/01-debugging-chrome/chrome_break_error@2x.png
diff --git a/1-js/03-code-quality/1-debugging-chrome/chrome_sources.png b/1-js/03-code-quality/01-debugging-chrome/chrome_sources.png
similarity index 100%
rename from 1-js/03-code-quality/1-debugging-chrome/chrome_sources.png
rename to 1-js/03-code-quality/01-debugging-chrome/chrome_sources.png
diff --git a/1-js/03-code-quality/1-debugging-chrome/chrome_sources@2x.png b/1-js/03-code-quality/01-debugging-chrome/chrome_sources@2x.png
similarity index 100%
rename from 1-js/03-code-quality/1-debugging-chrome/chrome_sources@2x.png
rename to 1-js/03-code-quality/01-debugging-chrome/chrome_sources@2x.png
diff --git a/1-js/03-code-quality/1-debugging-chrome/chrome_sources_break.png b/1-js/03-code-quality/01-debugging-chrome/chrome_sources_break.png
similarity index 100%
rename from 1-js/03-code-quality/1-debugging-chrome/chrome_sources_break.png
rename to 1-js/03-code-quality/01-debugging-chrome/chrome_sources_break.png
diff --git a/1-js/03-code-quality/1-debugging-chrome/chrome_sources_break@2x.png b/1-js/03-code-quality/01-debugging-chrome/chrome_sources_break@2x.png
similarity index 100%
rename from 1-js/03-code-quality/1-debugging-chrome/chrome_sources_break@2x.png
rename to 1-js/03-code-quality/01-debugging-chrome/chrome_sources_break@2x.png
diff --git a/1-js/03-code-quality/1-debugging-chrome/chrome_sources_breakpoint.png b/1-js/03-code-quality/01-debugging-chrome/chrome_sources_breakpoint.png
similarity index 100%
rename from 1-js/03-code-quality/1-debugging-chrome/chrome_sources_breakpoint.png
rename to 1-js/03-code-quality/01-debugging-chrome/chrome_sources_breakpoint.png
diff --git a/1-js/03-code-quality/1-debugging-chrome/chrome_sources_breakpoint@2x.png b/1-js/03-code-quality/01-debugging-chrome/chrome_sources_breakpoint@2x.png
similarity index 100%
rename from 1-js/03-code-quality/1-debugging-chrome/chrome_sources_breakpoint@2x.png
rename to 1-js/03-code-quality/01-debugging-chrome/chrome_sources_breakpoint@2x.png
diff --git a/1-js/03-code-quality/1-debugging-chrome/chrome_sources_buttons.png b/1-js/03-code-quality/01-debugging-chrome/chrome_sources_buttons.png
similarity index 100%
rename from 1-js/03-code-quality/1-debugging-chrome/chrome_sources_buttons.png
rename to 1-js/03-code-quality/01-debugging-chrome/chrome_sources_buttons.png
diff --git a/1-js/03-code-quality/1-debugging-chrome/chrome_sources_buttons@2x.png b/1-js/03-code-quality/01-debugging-chrome/chrome_sources_buttons@2x.png
similarity index 100%
rename from 1-js/03-code-quality/1-debugging-chrome/chrome_sources_buttons@2x.png
rename to 1-js/03-code-quality/01-debugging-chrome/chrome_sources_buttons@2x.png
diff --git a/1-js/03-code-quality/1-debugging-chrome/console_error.png b/1-js/03-code-quality/01-debugging-chrome/console_error.png
similarity index 100%
rename from 1-js/03-code-quality/1-debugging-chrome/console_error.png
rename to 1-js/03-code-quality/01-debugging-chrome/console_error.png
diff --git a/1-js/03-code-quality/1-debugging-chrome/console_error@2x.png b/1-js/03-code-quality/01-debugging-chrome/console_error@2x.png
similarity index 100%
rename from 1-js/03-code-quality/1-debugging-chrome/console_error@2x.png
rename to 1-js/03-code-quality/01-debugging-chrome/console_error@2x.png
diff --git a/1-js/03-code-quality/01-debugging-chrome/debugging.view/hello.js b/1-js/03-code-quality/01-debugging-chrome/debugging.view/hello.js
new file mode 100644
index 00000000..4236740e
--- /dev/null
+++ b/1-js/03-code-quality/01-debugging-chrome/debugging.view/hello.js
@@ -0,0 +1,9 @@
+function hello(name) {
+ let phrase = `Hello, ${name}!`;
+
+ say(phrase);
+}
+
+function say(phrase) {
+ alert(`** ${phrase} **`);
+}
diff --git a/1-js/03-code-quality/01-debugging-chrome/debugging.view/index.html b/1-js/03-code-quality/01-debugging-chrome/debugging.view/index.html
new file mode 100644
index 00000000..6c651e85
--- /dev/null
+++ b/1-js/03-code-quality/01-debugging-chrome/debugging.view/index.html
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+ An example for debugging.
+
+
+
+
+
diff --git a/1-js/03-code-quality/1-debugging-chrome/head.html b/1-js/03-code-quality/01-debugging-chrome/head.html
similarity index 100%
rename from 1-js/03-code-quality/1-debugging-chrome/head.html
rename to 1-js/03-code-quality/01-debugging-chrome/head.html
diff --git a/1-js/03-code-quality/1-debugging-chrome/manage1.png b/1-js/03-code-quality/01-debugging-chrome/manage1.png
similarity index 100%
rename from 1-js/03-code-quality/1-debugging-chrome/manage1.png
rename to 1-js/03-code-quality/01-debugging-chrome/manage1.png
diff --git a/1-js/03-code-quality/1-debugging-chrome/manage1@2x.png b/1-js/03-code-quality/01-debugging-chrome/manage1@2x.png
similarity index 100%
rename from 1-js/03-code-quality/1-debugging-chrome/manage1@2x.png
rename to 1-js/03-code-quality/01-debugging-chrome/manage1@2x.png
diff --git a/1-js/03-code-quality/1-debugging-chrome/manage2.png b/1-js/03-code-quality/01-debugging-chrome/manage2.png
similarity index 100%
rename from 1-js/03-code-quality/1-debugging-chrome/manage2.png
rename to 1-js/03-code-quality/01-debugging-chrome/manage2.png
diff --git a/1-js/03-code-quality/1-debugging-chrome/manage2@2x.png b/1-js/03-code-quality/01-debugging-chrome/manage2@2x.png
similarity index 100%
rename from 1-js/03-code-quality/1-debugging-chrome/manage2@2x.png
rename to 1-js/03-code-quality/01-debugging-chrome/manage2@2x.png
diff --git a/1-js/03-code-quality/1-debugging-chrome/manage3.png b/1-js/03-code-quality/01-debugging-chrome/manage3.png
similarity index 100%
rename from 1-js/03-code-quality/1-debugging-chrome/manage3.png
rename to 1-js/03-code-quality/01-debugging-chrome/manage3.png
diff --git a/1-js/03-code-quality/1-debugging-chrome/manage3@2x.png b/1-js/03-code-quality/01-debugging-chrome/manage3@2x.png
similarity index 100%
rename from 1-js/03-code-quality/1-debugging-chrome/manage3@2x.png
rename to 1-js/03-code-quality/01-debugging-chrome/manage3@2x.png
diff --git a/1-js/03-code-quality/1-debugging-chrome/manage4.png b/1-js/03-code-quality/01-debugging-chrome/manage4.png
similarity index 100%
rename from 1-js/03-code-quality/1-debugging-chrome/manage4.png
rename to 1-js/03-code-quality/01-debugging-chrome/manage4.png
diff --git a/1-js/03-code-quality/1-debugging-chrome/manage4@2x.png b/1-js/03-code-quality/01-debugging-chrome/manage4@2x.png
similarity index 100%
rename from 1-js/03-code-quality/1-debugging-chrome/manage4@2x.png
rename to 1-js/03-code-quality/01-debugging-chrome/manage4@2x.png
diff --git a/1-js/03-code-quality/1-debugging-chrome/manage5.png b/1-js/03-code-quality/01-debugging-chrome/manage5.png
similarity index 100%
rename from 1-js/03-code-quality/1-debugging-chrome/manage5.png
rename to 1-js/03-code-quality/01-debugging-chrome/manage5.png
diff --git a/1-js/03-code-quality/1-debugging-chrome/manage5@2x.png b/1-js/03-code-quality/01-debugging-chrome/manage5@2x.png
similarity index 100%
rename from 1-js/03-code-quality/1-debugging-chrome/manage5@2x.png
rename to 1-js/03-code-quality/01-debugging-chrome/manage5@2x.png
diff --git a/1-js/03-code-quality/1-debugging-chrome/manage6.png b/1-js/03-code-quality/01-debugging-chrome/manage6.png
similarity index 100%
rename from 1-js/03-code-quality/1-debugging-chrome/manage6.png
rename to 1-js/03-code-quality/01-debugging-chrome/manage6.png
diff --git a/1-js/03-code-quality/1-debugging-chrome/manage6@2x.png b/1-js/03-code-quality/01-debugging-chrome/manage6@2x.png
similarity index 100%
rename from 1-js/03-code-quality/1-debugging-chrome/manage6@2x.png
rename to 1-js/03-code-quality/01-debugging-chrome/manage6@2x.png
diff --git a/1-js/03-code-quality/1-debugging-chrome/statusbarButtonGlyphs.svg b/1-js/03-code-quality/01-debugging-chrome/statusbarButtonGlyphs.svg
similarity index 100%
rename from 1-js/03-code-quality/1-debugging-chrome/statusbarButtonGlyphs.svg
rename to 1-js/03-code-quality/01-debugging-chrome/statusbarButtonGlyphs.svg
diff --git a/1-js/03-code-quality/2-coding-style/1-style-errors/solution.md b/1-js/03-code-quality/02-coding-style/1-style-errors/solution.md
similarity index 100%
rename from 1-js/03-code-quality/2-coding-style/1-style-errors/solution.md
rename to 1-js/03-code-quality/02-coding-style/1-style-errors/solution.md
diff --git a/1-js/03-code-quality/2-coding-style/1-style-errors/task.md b/1-js/03-code-quality/02-coding-style/1-style-errors/task.md
similarity index 100%
rename from 1-js/03-code-quality/2-coding-style/1-style-errors/task.md
rename to 1-js/03-code-quality/02-coding-style/1-style-errors/task.md
diff --git a/1-js/03-code-quality/02-coding-style/article.md b/1-js/03-code-quality/02-coding-style/article.md
new file mode 100644
index 00000000..ae601047
--- /dev/null
+++ b/1-js/03-code-quality/02-coding-style/article.md
@@ -0,0 +1,310 @@
+# Coding style
+
+Our code must be as clean and easy to read as possible.
+
+That is actually an art of programming -- to take a complex task and code it in a way that is both correct and human-readable.
+
+One thing to help is the good code style.
+
+[cut]
+
+## Syntax
+
+A cheatsheet with the rules (more details below):
+
+
+
+
+Nothing is "carved in stone" here, so let's discuss the rules in detail.
+
+### Figure brackets
+
+In most JavaScript projects figure brackets are written on the same line. A so-called "egyptian" style. There's also a space before an opening bracket.
+
+A corner-case if a single-line `if/for`. Should we use brackets at all? If yes, then where?
+
+Here are the annotated variants, so you can judge about their readability on your own:
+
+
+
+
+As a summary, for a really short code one line is acceptable: like `if (cond) return null`.
+
+But a separate line for each statement in brackets is usually better.
+
+### Line length
+
+The maximal line length should be limited. No one likes to eye-follow a long horizontal line. It's better to split it.
+
+The maximal line length is agreed on the team-level. It's usually 80 or 120 characters.
+
+### Indents
+
+There are two types of indents:
+
+- **A horizontal indent: 2(4) spaces.**
+
+ A horizantal identation is made using either 2 or 4 spaces or the "Tab" symbol. Which one to choose is a kind of an old holy war. Spaces are a little more common nowadays.
+
+ One of advantages of spaces over tabs is that they allow more flexible configurations of indents than the "Tab" symbol.
+
+ For instance, we can align the arguments with the opening bracket, like this:
+
+ ```js no-beautify
+ show(parameters,
+ aligned, // 5 spaces padding at the left
+ one,
+ after,
+ another
+ ) {
+ // ...
+ }
+ ```
+
+- **A vertical indent, line breaks for splitting the code in logical blocks.**
+
+ Even a single function can often be divided in logical blocks. In the example below, the initialization of variables, the main loop and returning the result are split vertically:
+
+ ```js
+ function pow(x, n) {
+ let result = 1;
+ // <--
+ for (let i = 0; i < n; i++) {
+ result *= x;
+ }
+ // <--
+ return result;
+ }
+ ```
+
+ Insert an additional line break where it helps to make the code more readable. There should not be more than 9 lines of code without a vertical indentation.
+
+### A semicolon
+
+A semicolons should be after each statement. Even if could possibly be skipped.
+
+There are languages where a semicolon is truly optional. It's rarely used there.
+
+But in JavaScript a line break is sometimes interpreted as a semicolon and sometimes not. That leaves a place for programming errors, so semicolons should be at place.
+
+### Nesting levels
+
+There should not be too many nesting levels.
+
+Sometimes it's a good idea to use the ["continue"](info:while-for#continue) directive in the loop to evade extra nesting in `if(..) { ... }`:
+
+Instead of:
+
+```js
+for (let i = 0; i < 10; i++) {
+ if (cond) {
+ ... // <- one more nesting level
+ }
+}
+```
+
+We can write:
+
+```js
+for (let i = 0; i < 10; i++) {
+ if (!cond) *!*continue*/!*;
+ ... // <- no extra nesting level
+}
+```
+
+The similar thing can be done with `if/else` and `return`.
+
+For example, two constructs below are identical.
+
+The first one:
+
+```js
+function pow(x, n) {
+ if (n < 0) {
+ alert("Negative 'n' not supported");
+ } else {
+ let result = 1;
+
+ for (let i = 0; i < n; i++) {
+ result *= x;
+ }
+
+ return result;
+ }
+}
+```
+
+And this:
+
+```js
+function pow(x, n) {
+ if (n < 0) {
+ alert("Negative 'n' not supported");
+ return;
+ }
+
+ let result = 1;
+
+ for (let i = 0; i < n; i++) {
+ result *= x;
+ }
+
+ return result;
+}
+```
+
+...But the second one is more readable, because the "edge case" is handled early on, and then we have the "main" code flow, without an additional nesting.
+
+## Functions below the code
+
+If you are writing several "helper" functions and the code to use them, then there are three ways to place them.
+
+1. Functions above the code that uses them:
+
+ ```js
+ // *!*function declarations*/!*
+ function createElement() {
+ ...
+ }
+
+ function setHandler(elem) {
+ ...
+ }
+
+ function walkAround() {
+ ...
+ }
+
+ // *!*the code which uses them*/!*
+ var elem = createElement();
+ setHandler(elem);
+ walkAround();
+ ```
+2. Code first, then functions
+
+ ```js
+ // *!*the code which uses the functions*/!*
+ var elem = createElement();
+ setHandler(elem);
+ walkAround();
+
+ // --- *!*helper functions*/!* ---
+
+ function createElement() {
+ ...
+ }
+
+ function setHandler(elem) {
+ ...
+ }
+
+ function walkAround() {
+ ...
+ }
+ ```
+3. Mixed, a function is described when it's first used.
+
+Most of time, the second variant is preferred.
+
+That's because when reading a code, we first want to know "what it does". If the code goes first, then it provides that information. And then maybe we won't need to read functions at all, especially if their names are adequate to what they're doing.
+
+## Style guides
+
+There are many peculiar details in the code style.
+
+As the team becomes bigger, a common agreement on them becomes the "team style guide".
+
+There are many open style guides, so there we could just accept the one we like the most.
+
+- [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)
+
+There exist more there in the wild.
+
+As you become more mature in Javascript programming, you might want to read them all to pick up the common principles.
+
+## Style checkers
+
+There are great tools that can check the code style automatically. They are called "linters".
+
+Please note, they not only check the style, but sometimes help to find bugs, like a typo in variable name or a function.
+
+So it's really beneficial to install one. Even if you don't want to stick to a "code style". They help to find typos -- and that's already good enough.
+
+Most well known are:
+
+- [JSLint](http://www.jslint.com/) -- one of the oldest open-source solutions.
+- [JSHint](http://www.jshint.com/) -- the more "featured" variant of JSLint.
+- [ESLint](http://eslint.org/) -- the newest breed.
+
+All of them can do the job. The author uses [ESLint](http://eslint.org/).
+
+Here are simple steps to start using it:
+
+1. Install [Node.JS](https://nodejs.org/), necessary to run them.
+2. Install eslint: `npm i -g eslint` (npm is Node.JS package installer).
+3. Create a config file `.eslintrc` in your Javascript project (the dot at the start is mandatory).
+
+An example of `.eslintrc`:
+
+```js
+{
+ "extends": "eslint:recommended",
+ "env": {
+ "browser": true,
+ "es6": true
+ },
+ "rules": {
+ "no-console": 0,
+ "no-constant-condition": ["error", { "checkLoops": false }]
+ },
+ "indent": 2
+}
+```
+
+Then install/enable the plugin for your editor that integrates with ESLint. The majority of editors have it.
+
+Also you can see [the manual](http://eslint.org/docs/user-guide/getting-started) for advanced examples, rules and options of ESLint.
+
+## Summary
+
+All syntax rules from this chapter and the style guides aim to increase readability.
+
+When you read style guides and think about "how to write better", the sole criterion is "does the code become more readable and easier to understand?" Then it becomes easier to pick up the best practices for that. Or even abandon some in cases when you see that they don't help.
diff --git a/1-js/03-code-quality/2-coding-style/code-style.png b/1-js/03-code-quality/02-coding-style/code-style.png
similarity index 100%
rename from 1-js/03-code-quality/2-coding-style/code-style.png
rename to 1-js/03-code-quality/02-coding-style/code-style.png
diff --git a/1-js/03-code-quality/2-coding-style/code-style@2x.png b/1-js/03-code-quality/02-coding-style/code-style@2x.png
similarity index 100%
rename from 1-js/03-code-quality/2-coding-style/code-style@2x.png
rename to 1-js/03-code-quality/02-coding-style/code-style@2x.png
diff --git a/1-js/03-code-quality/2-coding-style/figure-bracket-style.png b/1-js/03-code-quality/02-coding-style/figure-bracket-style.png
similarity index 100%
rename from 1-js/03-code-quality/2-coding-style/figure-bracket-style.png
rename to 1-js/03-code-quality/02-coding-style/figure-bracket-style.png
diff --git a/1-js/03-code-quality/2-coding-style/figure-bracket-style@2x.png b/1-js/03-code-quality/02-coding-style/figure-bracket-style@2x.png
similarity index 100%
rename from 1-js/03-code-quality/2-coding-style/figure-bracket-style@2x.png
rename to 1-js/03-code-quality/02-coding-style/figure-bracket-style@2x.png
diff --git a/1-js/03-code-quality/03-comments/article.md b/1-js/03-code-quality/03-comments/article.md
new file mode 100644
index 00000000..d82c7c1d
--- /dev/null
+++ b/1-js/03-code-quality/03-comments/article.md
@@ -0,0 +1,217 @@
+# Comments
+
+Comments are generally a good thing. But novices in programming generally get that wrong. They write comments explaining "what is going on in the code".
+
+**But the amount of such "explanatory" comments should be minimal.**
+
+Seriously, a good code should be easy to understand without them.
+
+There's a great rule about that: "if the code is not clear without a comment, then may be it should be rewritten instead".
+
+[cut]
+
+Sometimes it's beneficial to replace a code piece with a function, like here:
+
+```js
+function showPrimes(n) {
+ nextPrime:
+ for (let i = 2; i < n; i++) {
+
+*!*
+ // check if i is a prime number
+*/!*
+ for (let j = 2; j < i; j++) {
+ if (i % j == 0) continue nextPrime;
+ }
+
+ alert(i);
+ }
+}
+```
+
+The better variant:
+
+
+```js
+function showPrimes(n) {
+
+ for (let i = 2; i < n; i++) {
+ *!*if (!isPrime(i)) continue;*/!*
+
+ alert(i);
+ }
+}
+
+function isPrime(n) {
+ for (let i = 2; i < n; i++) {
+ if ( n % i == 0) return false;
+ }
+ return true;
+}
+```
+
+Now we can understand the code easily without the comment. Such code is called *self-descriptive*.
+
+And if we have a long "code sheet" like this:
+
+```js
+// here we add whiskey
+for(let i = 0; i < 10; i++) {
+ let drop = getWhiskey();
+ smell(drop);
+ add(drop, glass);
+}
+
+// here we add juice
+for(let t = 0; t < 3; t++) {
+ let tomato = getTomato();
+ examine(tomato);
+ let juice = press(tomato);
+ add(juice, glass);
+}
+
+// ...
+```
+
+Then it might be a better variant to refactor it into functions like:
+
+```js
+addWhiskey(glass);
+addJuice(glass);
+
+function addWhiskey(container) {
+ for(let i = 0; i < 10; i++) {
+ let drop = getWhiskey();
+ //...
+ }
+}
+
+function addJuice(container) {
+ for(let t = 0; t < 3; t++) {
+ let tomato = getTomato();
+ //...
+ }
+}
+```
+
+That's readable without comments. And also the code structure is better when split. It's clear what every function does, what it takes and what it returns.
+
+In reality, we can't totally evade "explanatory" comments. There are complex algorithms. And there are smart code tweaks made for optimization. But generally we should try to keep the code as simple as possible, and apply those only when needed.
+
+## Good comments
+
+Which comments are good?
+
+Describe the architecture
+: That's the list of components, how they interact, what's the control flow in various situations... In short -- the bird's eye view of the code. There's a special diagram language [UML](http://wikipedia.org/wiki/Unified_Modeling_Language) for high-level architecture diagrams. Definitely worth studying.
+
+Document a function usage
+: There's a special syntax [JSDoc](http://en.wikipedia.org/wiki/JSDoc) to document a function: usage, parameters, returned value.
+
+ 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 to understand the purpose of the function and use it the right way. Even 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/jsdoc3/jsdoc) that can generate HTML-documentation from the comments. You can read more information about JSDoc at .
+
+Why the task is solved this way?
+: What's written is important. But what's *not* written maybe even more important to understand what's going on. Why the task is solved exactly this way? The code gives no answer.
+
+ If there are many ways to solve the task, why this one? Especially when it's not the most obvious one.
+
+ Without such comments the following situation is possible:
+ 1. You (or your colleague) open the code written some time ago, and see it's "suboptimal".
+ 2. You think: "How stupid I was then, and how much smarter I'm now", and rewrite using the "more obvious and correct" variant.
+ 3. ...The urge to rewrite was good. But in the process you see that the "more obvious" solution is actually lacking. Hopefully, you revert to the correct variant, but the time was spent.
+
+ Comments that explain the solution are very important. They help to understand what happens and continue development the right way.
+
+Any subtle features of the code? Where they are used?
+: If the code has anything subtle, it's definitely worth commenting.
+
+One of signs of a good developer is his comments. Good comments allow to maintain the code well, return to it after a long delay and use features more effectively.
+
+## Style guides
+
+A style guide contains general rules about "how to write": which quotes to use, how many spaces to indent, where to put line breaks etc. A lot of minor things.
+
+In total, when all members of a team use the same style guide, the code looks uniform. No matter who of the team wrote it, still the same style.
+
+Surely, a team may think out a style guide themselves. But as of now, there's no need to. There are many tried, worked out style guides, easy to adopt.
+
+For instance:
+
+- [Google JavaScript Style Guide](https://google.github.io/styleguide/javascriptguide.xml)
+- [Airbnb JavaScript Style Guide](https://github.com/airbnb/javascript)
+- [Idiomatic.JS](https://github.com/rwaldron/idiomatic.js)
+- (there are more)
+
+If you're a novice developer, then you could start with the cheatsheet in the chapter , and later browse the style guides to see what looks best.
+
+Also consider the automatic style checkers, described below.
+
+## Automated style linters
+
+There are tools that automate style checking, called "linters".
+
+Most known are:
+
+- [JSLint](http://www.jslint.com/) -- one of the first linters.
+- [JSHint](http://www.jshint.com/) -- more settings than JSHint.
+- [ESLint](http://eslint.org/) -- probably the newest one.
+
+The author of this chapter uses ESLint.
+
+Most linters are integrated with editors: just enable the plugin in the editor and configure the style.
+
+For instance, for ESLint you should do the following:
+
+1. Install Node.JS (can take from the ).
+2. Install ESLint with the command `npm install -g eslint`.
+3. Create a config file named `.eslintrc` in the root of your Javascript project (in the folder that contains all your files).
+
+Here's an example of `.eslintrc`:
+
+```js
+{
+ "extends": "eslint:recommended",
+ "env": {
+ "browser": true,
+ "node": true,
+ "es6": true
+ },
+ "rules": {
+ "no-console": 0,
+ },
+ "indent": 2
+}
+```
+
+Here the directive `"extends"` denotes that we base on the "eslint:recommended" set of settings, and then we specify our own.
+
+It is possible to download style rule sets from the web and extend them instead. See for more details about installation.
+
+Using a linter has the great side-effect. Linters catch typos. For instance, when an undefined variable is accessed, a linter detects it and (if integrated with an editor) highlights. In most cases that's a mistype. So we can fix it right ahead.
+
+For that reason even if you're not concerned about styles, using a linter is really recommended.
+
+
+## Summary
+
+Code style is important, especially in the team. When other people look at your code, the impression is largely defined by the style. Good code is easier to read and understand.
+
+Speaking about style rules: quotes, spaces etc, we should keep in mind that all of them are good *only* if they make the code better. More readable, easier to maintain. That's the main thing to keep in mind when choosing the style or discussing which one is better.
diff --git a/1-js/03-code-quality/04-ninja-code/article.md b/1-js/03-code-quality/04-ninja-code/article.md
new file mode 100644
index 00000000..323e7be3
--- /dev/null
+++ b/1-js/03-code-quality/04-ninja-code/article.md
@@ -0,0 +1,226 @@
+# How to write bad code?
+
+Programmer ninjas of the past used these tricks to make code maintainers cry. Code review gurus search for signs of them in test tasks. Novice developers sometimes use them even better than programmer ninjas (indeed there's power in being a newbie!).
+
+Read them carefully and find who you are -- a ninja, a novice, or maybe a code reviewer?
+
+[cut]
+
+## Brevity is the soul of wit
+
+Make the code as short as possible. Show how smart you are.
+
+Let subtle language features guide you.
+
+For instance, take a look at the ternary operator `'?'`:
+
+```js
+// taken from a well-known javascript library
+i = i ? i < 0 ? Math.max(0, len + i) : i : 0;
+```
+
+The developer who comes across such line and tries to understand the value of `i` will probably come to you seeking for an answer.
+
+Tell him that the shorter is the better. Initiate him into the paths of ninja. Don't forget to give him [Tao Te Ching](http://www.w66.eu/elib/html/ttk.html).
+
+## One-letter variables
+
+```quote author="Laozi (Tao Te Ching)"
+The Dao hides in wordlessness. Only the Dao is well begun and well
+completed.
+```
+
+Another way to code faster (and much worse!) is to use single-letter variable names everywhere. Like `a`, `b` or `c`.
+
+That makes the variable blend in the code like a real ninja in the forest. No one will be able to find it using the "search" of the editor. And even if someone does, he won't be able to "decipher" what it means.
+
+...But there's an exception. A real ninja will never use `i` as the counter in a `"for"` loop. Anywhere, but not there. Look, there's so much more exotic letters. For instance, `x` or `y`.
+
+The approach is even more effective when the loop body takes 1-2 pages (make it longer? yes, if you can). Then it becomes impossible to guess that the variable is the loop counter, when looking in the middle of the code.
+
+## Can't one-letter? Then shorten
+
+If the team rules forbid to use one-letter and vague names -- shorten them.
+
+Like this:
+
+- `list` -> `lst`.
+- `userAgent` -> `ua`.
+- `browser` -> `brsr`.
+- ...etc
+
+Only the one with a truly good intuition will be able to understand all such names. Try to shorten everything. Only a worthy person will be able to uphold development of such code.
+
+## Soar high. Be abstract.
+
+```quote author="Laozi (Tao Te Ching)"
+The great square is cornerless
+The great vessel is last complete,
+The great note is rarified sound,
+The great image has no form.
+```
+
+While choosing a name try to use the most abstract word. Like `obj`, `data`, `value`, `item`, `elem` and so on.
+
+- **The ideal variable for a variable is `data`.** Use it everywhere where you can. Indeed, every variable holds *data*, right?
+
+ ...But what to do if `data` is already taken? Try `value`, it's also universal. A variable always has a *value*, correct?
+
+ Taken as well? An experienced ninja should find a way.
+
+- **Name the variable by its type: `str`, `num`, `list`...**
+
+ ...But will that make the code worse? Actually, yes!
+
+ From the one hand, the variable name still means something. It says what's inside the variable: a string, a number or an list. But when a person unfamiliar to the Dao will try to understand the code -- he'll be surprised to see that there's actually no information at all!
+
+ Actually, the value type is easy to see by debugging. But what's the meaning of the variable? Which string/number it stores? There's just no way to figure out without a good meditation!
+
+- **...But what if there's no more such names?** Just add a letter: `item1, item2, elem5, data1`...
+
+## Attention test
+
+Only a truly attentive programmer should be able to understand the code. But how to check that?
+
+**One of the ways -- is to use similar variable names, like `date` and `data`.**
+
+Mix them where you can.
+
+A quick read of such code becomes impossible. And when there's a typo... Ummm... We're stuck for long, time to drink some tea.
+
+
+## Smart synonyms
+
+```quote author="Confucius"
+The hardest thing of all is to find a black cat in a dark room, especially if there is no cat.
+```
+
+Don't be bored. Use *similar* names for *same* things.
+
+For instance, the function prefixes. If a function shows something on the screen -- start it with `display..` (like `displayMessage`), and the similar function that shows a question should start with `show...` (like `showName`).
+
+**Insinuate that there's a subtle difference difference between such functions, while there is none.**
+
+Make a pact with fellow ninjas of the team: if John starts "showing" functions with `display...` in his code, then Peter could use `render..`, and Ann -- `paint...`.
+
+...And now the hat trick!
+
+**For two functions with important differences -- use the same word!**
+
+For instance, the function `printPage(page)` will use a printer. And the function `printText(text)` will put the text on-screen.
+
+Let an unfamiliar reader think well over things: "Where does `printMessage(message)` put the message?". To make it really shine, `printMessage(message)` should output it in the new window!
+
+## Reuse names
+
+```quote author="Laozi (Tao Te Ching)"
+Once the whole is divided, the parts
+need names.
+There are already enough names.
+One must know when to stop.
+```
+
+Add a new variable only when absolutely necessary.
+
+Instead, reuse existing names. Just write new values into them.
+
+In a function try to use only variables passed as parameters.
+
+That would make it impossible to identify what's exactly in the variable *now*. And also where it comes from. A person without a skill would have to analyze the code line-by-line and track the changes through every code branch.
+
+**An advanced variant of the approach is to covertly (!) replace the value with something alike, for instance:**
+
+```js
+function ninjaFunction(elem) {
+ // 20 lines of code working with elem
+
+ elem = clone(elem);
+
+ // 20 more lines, now working with the new elem!
+}
+```
+
+A fellow programmer who wants to work with `elem` in the second half of the function will be surprised... Only during the debugging, after examining the code he will find out that he worked with he's working with the clone!
+
+Deadly effective even against an experienced ninja. Met in the code regularly.
+
+## Underscores for fun
+
+Put underscores `_` and `__` before variable names. Like `_name` or `__value`. It would be great if only you know their meaning. Or, better, without meaning at all.
+
+You kill two rabbits with one shot. First, the code becomes longer and less readable, and the second, a fellow developer may spend a long time trying to figure out what the underscores mean.
+
+A smart ninja puts underscores at one spot of code and evades them at other places. That makes the code even more fragile and increases the probability of future errors.
+
+## Show your love
+
+Let everyone see how magnificent your entities are! Names like `superElement`, `megaFrame` and `niceItem` will definitely enlighten the reader.
+
+Indeed, from one hand, something is written: `super..`, `mega..`, `nice..` But from the other hand -- that brings no details. The reader may decide to look for a hidden meaning and meditate for an hour or two.
+
+## Overlap outer variables
+
+```quote author="Guan Yin Zi"
+When in the light, can't see anything in the darkness.
+When in the darkness, can see everything in the light.
+```
+
+Use same names for variables inside and outside a function. As simple. No efforts required.
+
+```js
+let *!*user*/!* = authenticateUser();
+
+function render() {
+ let *!*user*/!* = anotherValue();
+ ...
+ ...many lines...
+ ...
+ ... // <-- a programmer wants to work with user here and...
+ ...
+}
+```
+
+A programmer who jumps inside the `render` will probably miss to notice that the local `user` overlaps the outer one. Then he'll try to work with it assuming that it's the resulf of `authenticateUser()`... The trap is sprung! Hello, debugger...
+
+## Powerful functions!
+
+```quote author="Laozi (Tao Te Ching)"
+The great Tao flows everywhere,
+both to the left and to the right.
+```
+
+Don't limit the function by what's written in its name. Be wider.
+
+For instance, a function `validateEmail(email)` could, besides checking the email for correctness, to show an error message and ask to re-enter the email.
+
+**Add at least two more actions to the main purpose of the function.**
+
+They should not be obvious from the function name. A true ninja coder will make them not obvious from the code as well.
+
+**Joining several actions into one protects your code from reuse.**
+
+Imagine, another developer wants only to check the email, and not output any message. Your function `validateEmail(email)` that does both will not suit him. So he will not break your meditation by asking anything about it.
+
+
+## Side-effects everywhere!
+
+There are functions that look like they don't change anything. Like `isReady()`, `checkPermission()`, `findTags()`... They are assumed to carry out calculations, find and return the data, without changing anything outside of them. That's called "no side-effects".
+
+
+**A really beautiful trick -- is to add a "useful" action to them, besides the main task.**
+
+The expression of dazed surprise on the face of your colleague when he see a function named `is..`, `check..` or `find...` changing something -- will definitely broaden your boundaries of reason.
+
+**Another way to surprise -- is to return a non-standard result.**
+
+Show your original thinking! Let the call of `checkPermission` return not `true/false`, but a complex object with the results of the check.
+
+Those developers who try to write `if (checkPermission(..))`, will wonder why it doesn't work. Tell them: "Read the docs!". And give this article.
+
+## Summary
+
+All "pieces of advice" above are from the real code... Sometimes, written by experienced developers. Maybe even more experienced than you are ;)
+
+- Follow some of them -- and your code will become full of surprises.
+- Follow many of them -- and your code will become truly yours, no one would want to change it.
+- Follow all -- and your code will become a valuable lesson for young developers looking for enlightment.
diff --git a/1-js/03-code-quality/4-testing/1-pow-nan-spec/_js.view/solution.js b/1-js/03-code-quality/05-testing/1-pow-nan-spec/_js.view/solution.js
similarity index 100%
rename from 1-js/03-code-quality/4-testing/1-pow-nan-spec/_js.view/solution.js
rename to 1-js/03-code-quality/05-testing/1-pow-nan-spec/_js.view/solution.js
diff --git a/1-js/03-code-quality/4-testing/1-pow-nan-spec/_js.view/source.js b/1-js/03-code-quality/05-testing/1-pow-nan-spec/_js.view/source.js
similarity index 100%
rename from 1-js/03-code-quality/4-testing/1-pow-nan-spec/_js.view/source.js
rename to 1-js/03-code-quality/05-testing/1-pow-nan-spec/_js.view/source.js
diff --git a/1-js/03-code-quality/4-testing/1-pow-nan-spec/_js.view/test.js b/1-js/03-code-quality/05-testing/1-pow-nan-spec/_js.view/test.js
similarity index 100%
rename from 1-js/03-code-quality/4-testing/1-pow-nan-spec/_js.view/test.js
rename to 1-js/03-code-quality/05-testing/1-pow-nan-spec/_js.view/test.js
diff --git a/1-js/03-code-quality/4-testing/1-pow-nan-spec/solution.md b/1-js/03-code-quality/05-testing/1-pow-nan-spec/solution.md
similarity index 100%
rename from 1-js/03-code-quality/4-testing/1-pow-nan-spec/solution.md
rename to 1-js/03-code-quality/05-testing/1-pow-nan-spec/solution.md
diff --git a/1-js/03-code-quality/4-testing/1-pow-nan-spec/task.md b/1-js/03-code-quality/05-testing/1-pow-nan-spec/task.md
similarity index 100%
rename from 1-js/03-code-quality/4-testing/1-pow-nan-spec/task.md
rename to 1-js/03-code-quality/05-testing/1-pow-nan-spec/task.md
diff --git a/1-js/03-code-quality/4-testing/2-pow-test-0/solution.md b/1-js/03-code-quality/05-testing/2-pow-test-0/solution.md
similarity index 100%
rename from 1-js/03-code-quality/4-testing/2-pow-test-0/solution.md
rename to 1-js/03-code-quality/05-testing/2-pow-test-0/solution.md
diff --git a/1-js/03-code-quality/4-testing/2-pow-test-0/solution.view/index.html b/1-js/03-code-quality/05-testing/2-pow-test-0/solution.view/index.html
similarity index 100%
rename from 1-js/03-code-quality/4-testing/2-pow-test-0/solution.view/index.html
rename to 1-js/03-code-quality/05-testing/2-pow-test-0/solution.view/index.html
diff --git a/1-js/03-code-quality/4-testing/2-pow-test-0/solution.view/test.js b/1-js/03-code-quality/05-testing/2-pow-test-0/solution.view/test.js
similarity index 100%
rename from 1-js/03-code-quality/4-testing/2-pow-test-0/solution.view/test.js
rename to 1-js/03-code-quality/05-testing/2-pow-test-0/solution.view/test.js
diff --git a/1-js/03-code-quality/4-testing/2-pow-test-0/source.view/index.html b/1-js/03-code-quality/05-testing/2-pow-test-0/source.view/index.html
similarity index 100%
rename from 1-js/03-code-quality/4-testing/2-pow-test-0/source.view/index.html
rename to 1-js/03-code-quality/05-testing/2-pow-test-0/source.view/index.html
diff --git a/1-js/03-code-quality/4-testing/2-pow-test-0/source.view/test.js b/1-js/03-code-quality/05-testing/2-pow-test-0/source.view/test.js
similarity index 100%
rename from 1-js/03-code-quality/4-testing/2-pow-test-0/source.view/test.js
rename to 1-js/03-code-quality/05-testing/2-pow-test-0/source.view/test.js
diff --git a/1-js/03-code-quality/4-testing/2-pow-test-0/task.md b/1-js/03-code-quality/05-testing/2-pow-test-0/task.md
similarity index 100%
rename from 1-js/03-code-quality/4-testing/2-pow-test-0/task.md
rename to 1-js/03-code-quality/05-testing/2-pow-test-0/task.md
diff --git a/1-js/03-code-quality/4-testing/3-pow-test-wrong/solution.md b/1-js/03-code-quality/05-testing/3-pow-test-wrong/solution.md
similarity index 100%
rename from 1-js/03-code-quality/4-testing/3-pow-test-wrong/solution.md
rename to 1-js/03-code-quality/05-testing/3-pow-test-wrong/solution.md
diff --git a/1-js/03-code-quality/4-testing/3-pow-test-wrong/task.md b/1-js/03-code-quality/05-testing/3-pow-test-wrong/task.md
similarity index 100%
rename from 1-js/03-code-quality/4-testing/3-pow-test-wrong/task.md
rename to 1-js/03-code-quality/05-testing/3-pow-test-wrong/task.md
diff --git a/1-js/03-code-quality/4-testing/article.md b/1-js/03-code-quality/05-testing/article.md
similarity index 100%
rename from 1-js/03-code-quality/4-testing/article.md
rename to 1-js/03-code-quality/05-testing/article.md
diff --git a/1-js/03-code-quality/4-testing/beforeafter.view/index.html b/1-js/03-code-quality/05-testing/beforeafter.view/index.html
similarity index 100%
rename from 1-js/03-code-quality/4-testing/beforeafter.view/index.html
rename to 1-js/03-code-quality/05-testing/beforeafter.view/index.html
diff --git a/1-js/03-code-quality/4-testing/beforeafter.view/test.js b/1-js/03-code-quality/05-testing/beforeafter.view/test.js
similarity index 100%
rename from 1-js/03-code-quality/4-testing/beforeafter.view/test.js
rename to 1-js/03-code-quality/05-testing/beforeafter.view/test.js
diff --git a/1-js/03-code-quality/4-testing/index.html b/1-js/03-code-quality/05-testing/index.html
similarity index 100%
rename from 1-js/03-code-quality/4-testing/index.html
rename to 1-js/03-code-quality/05-testing/index.html
diff --git a/1-js/03-code-quality/4-testing/pow-1.view/index.html b/1-js/03-code-quality/05-testing/pow-1.view/index.html
similarity index 100%
rename from 1-js/03-code-quality/4-testing/pow-1.view/index.html
rename to 1-js/03-code-quality/05-testing/pow-1.view/index.html
diff --git a/1-js/03-code-quality/4-testing/pow-1.view/test.js b/1-js/03-code-quality/05-testing/pow-1.view/test.js
similarity index 100%
rename from 1-js/03-code-quality/4-testing/pow-1.view/test.js
rename to 1-js/03-code-quality/05-testing/pow-1.view/test.js
diff --git a/1-js/03-code-quality/4-testing/pow-2.view/index.html b/1-js/03-code-quality/05-testing/pow-2.view/index.html
similarity index 100%
rename from 1-js/03-code-quality/4-testing/pow-2.view/index.html
rename to 1-js/03-code-quality/05-testing/pow-2.view/index.html
diff --git a/1-js/03-code-quality/4-testing/pow-2.view/test.js b/1-js/03-code-quality/05-testing/pow-2.view/test.js
similarity index 100%
rename from 1-js/03-code-quality/4-testing/pow-2.view/test.js
rename to 1-js/03-code-quality/05-testing/pow-2.view/test.js
diff --git a/1-js/03-code-quality/4-testing/pow-3.view/index.html b/1-js/03-code-quality/05-testing/pow-3.view/index.html
similarity index 100%
rename from 1-js/03-code-quality/4-testing/pow-3.view/index.html
rename to 1-js/03-code-quality/05-testing/pow-3.view/index.html
diff --git a/1-js/03-code-quality/4-testing/pow-3.view/test.js b/1-js/03-code-quality/05-testing/pow-3.view/test.js
similarity index 100%
rename from 1-js/03-code-quality/4-testing/pow-3.view/test.js
rename to 1-js/03-code-quality/05-testing/pow-3.view/test.js
diff --git a/1-js/03-code-quality/4-testing/pow-4.view/index.html b/1-js/03-code-quality/05-testing/pow-4.view/index.html
similarity index 100%
rename from 1-js/03-code-quality/4-testing/pow-4.view/index.html
rename to 1-js/03-code-quality/05-testing/pow-4.view/index.html
diff --git a/1-js/03-code-quality/4-testing/pow-4.view/test.js b/1-js/03-code-quality/05-testing/pow-4.view/test.js
similarity index 100%
rename from 1-js/03-code-quality/4-testing/pow-4.view/test.js
rename to 1-js/03-code-quality/05-testing/pow-4.view/test.js
diff --git a/1-js/03-code-quality/4-testing/pow-full.view/index.html b/1-js/03-code-quality/05-testing/pow-full.view/index.html
similarity index 100%
rename from 1-js/03-code-quality/4-testing/pow-full.view/index.html
rename to 1-js/03-code-quality/05-testing/pow-full.view/index.html
diff --git a/1-js/03-code-quality/4-testing/pow-full.view/test.js b/1-js/03-code-quality/05-testing/pow-full.view/test.js
similarity index 100%
rename from 1-js/03-code-quality/4-testing/pow-full.view/test.js
rename to 1-js/03-code-quality/05-testing/pow-full.view/test.js
diff --git a/1-js/03-code-quality/4-testing/pow-min.view/index.html b/1-js/03-code-quality/05-testing/pow-min.view/index.html
similarity index 100%
rename from 1-js/03-code-quality/4-testing/pow-min.view/index.html
rename to 1-js/03-code-quality/05-testing/pow-min.view/index.html
diff --git a/1-js/03-code-quality/4-testing/pow-min.view/test.js b/1-js/03-code-quality/05-testing/pow-min.view/test.js
similarity index 100%
rename from 1-js/03-code-quality/4-testing/pow-min.view/test.js
rename to 1-js/03-code-quality/05-testing/pow-min.view/test.js
diff --git a/1-js/03-code-quality/4-testing/pow-nan-assert.view/index.html b/1-js/03-code-quality/05-testing/pow-nan-assert.view/index.html
similarity index 100%
rename from 1-js/03-code-quality/4-testing/pow-nan-assert.view/index.html
rename to 1-js/03-code-quality/05-testing/pow-nan-assert.view/index.html
diff --git a/1-js/03-code-quality/4-testing/pow-nan-assert.view/test.js b/1-js/03-code-quality/05-testing/pow-nan-assert.view/test.js
similarity index 100%
rename from 1-js/03-code-quality/4-testing/pow-nan-assert.view/test.js
rename to 1-js/03-code-quality/05-testing/pow-nan-assert.view/test.js
diff --git a/1-js/03-code-quality/4-testing/pow-nan.view/index.html b/1-js/03-code-quality/05-testing/pow-nan.view/index.html
similarity index 100%
rename from 1-js/03-code-quality/4-testing/pow-nan.view/index.html
rename to 1-js/03-code-quality/05-testing/pow-nan.view/index.html
diff --git a/1-js/03-code-quality/4-testing/pow-nan.view/test.js b/1-js/03-code-quality/05-testing/pow-nan.view/test.js
similarity index 100%
rename from 1-js/03-code-quality/4-testing/pow-nan.view/test.js
rename to 1-js/03-code-quality/05-testing/pow-nan.view/test.js
diff --git a/1-js/03-code-quality/5-polyfills/article.md b/1-js/03-code-quality/06-polyfills/article.md
similarity index 100%
rename from 1-js/03-code-quality/5-polyfills/article.md
rename to 1-js/03-code-quality/06-polyfills/article.md
diff --git a/1-js/03-code-quality/1-debugging-chrome/article.md b/1-js/03-code-quality/1-debugging-chrome/article.md
deleted file mode 100644
index 5d3af482..00000000
--- a/1-js/03-code-quality/1-debugging-chrome/article.md
+++ /dev/null
@@ -1,228 +0,0 @@
-# TODO: Отладка в браузере Chrome
-
-Перед тем, как двигаться дальше, поговорим об отладке скриптов.
-
-Все современные браузеры поддерживают для этого "инструменты разработчика". Исправление ошибок с их помощью намного проще и быстрее.
-
-На текущий момент самые многофункциональные инструменты -- в браузере Chrome. Также очень хорош Firebug (для Firefox).
-
-[cut]
-
-## Общий вид панели Sources
-
-В вашей версии Chrome панель может выглядеть несколько по-иному, но что где находится, должно быть понятно.
-
-Зайдите на [страницу с примером](debugging/index.html) браузером Chrome.
-
-Откройте инструменты разработчика: `key:F12` или в меню `Инструменты > Инструменты Разработчика`.
-
-Выберите сверху `Sources`.
-
-
-
-Вы видите три зоны:
-
-1. **Зона исходных файлов.** В ней находятся все подключённые к странице файлы, включая JS/CSS. Выберите `pow.js`, если он не выбран.
-2. **Зона текста.** В ней находится текст файлов.
-3. **Зона информации и контроля.** Мы поговорим о ней позже.
-
-Обычно зона исходных файлов при отладке не нужна. Скройте её кнопкой .
-
-## Общие кнопки управления
-
-
-
-Три наиболее часто используемые кнопки управления:
-
-Формат
-: Нажатие форматирует текст текущего файла, расставляет отступы. Нужна, если вы хотите разобраться в чужом коде, плохо отформатированном или сжатом.
-
-Консоль
-: Очень полезная кнопка, открывает тут же консоль для запуска команд. Можно смотреть код и тут же запускайть функции. Её нажатие можно заменить на клавишу Esc
.
-
-Окно
-: Если код очень большой, то можно вынести инструменты разработки вбок или в отдельное окно, зажав эту кнопку и выбрав соответствующий вариант из списка.
-
-## Точки остановки
-
-Открыли файл `pow.js` во вкладке Sources? Кликните на 6й строке файла `pow.js`, прямо на цифре 6.
-
-Поздравляю! Вы поставили "точку остановки" или, как чаще говорят, "брейкпойнт".
-
-Выглядет это должно примерно так:
-
-
-
-Слово *Брейкпойнт* (breakpoint) -- часто используемый английский жаргонизм. Это то место в коде, где отладчик будет *автоматически* останавливать выполнение JavaScript, как только оно до него дойдёт.
-
-**В остановленном коде можно посмотреть текущие значения переменных, выполнять команды и т.п., в общем -- отлаживать его.**
-
-Вы можете видеть, что информация о точке остановки появилась справа, в подвкладке Breakpoints.
-
-Вкладка Breakpoints очень удобна, когда код большой, она позволяет:
-
-- Быстро перейти на место кода, где стоит брейкпойнт кликом на текст.
-- Временно выключить брейкпойнт кликом на чекбокс.
-- Быстро удалить брейкпойнт правым кликом на текст и выбором Remove, и так далее.
-
-````smart header="Дополнительные возможности"
-- Остановку можно инициировать и напрямую из кода скрипта, командой `debugger`:
-
- ```js
- function pow(x, n) {
- ...
- debugger; // <-- отладчик остановится тут
- ...
- }
- ```
-- *Правый клик* на номер строки `pow.js` позволит создать условную точку остановки (conditional breakpoint), т.е. задать условие, при котором точка остановки сработает.
-
- Это удобно, если остановка нужна только при определённом значении переменной или параметра функции.
-````
-
-## Остановиться и осмотреться
-
-Наша функция выполняется сразу при загрузке страницы, так что самый простой способ активировать отладчик JavaScript -- перезагрузить её. Итак, нажимаем `key:F5` (Windows, Linux) или `key:Cmd+R` (Mac).
-
-Если вы сделали всё, как описано выше, то выполнение прервётся как раз на 6й строке.
-
-
-
-Обратите внимание на информационные вкладки справа (отмечены стрелками).
-
-В них мы можем посмотреть текущее состояние:
-
-1. **`Watch Expressions` -- показывает текущие значения любых выражений.**
-
- Можно раскрыть эту вкладку, нажать мышью `+` на ней и ввести любое выражение. Отладчик будет отображать его значение на текущий момент, автоматически перевычисляя его при проходе по коду.
-2. **`Call Stack` -- стек вызовов, все вложенные вызовы, которые привели к текущему месту кода.**
-
- На текущий момент видно, отладчик находится в функции `pow` (pow.js, строка 6), вызванной из анонимного кода (index.html, строка 13).
-3. **`Scope Variables` -- переменные.**
-
- На текущий момент строка 6 ещё не выполнилась, поэтому `result` равен `undefined`.
-
- В `Local` показываются переменные функции: объявленные через `var` и параметры. Вы также можете там видеть ключевое слово `this`, если вы не знаете, что это такое -- ничего страшного, мы это обсудим позже, в следующих главах учебника.
-
- В `Global` -- глобальные переменные и функции.
-
-## Управление выполнением
-
-Пришло время, как говорят, "погонять" скрипт и "оттрейсить" (от англ. trace -- отслеживать) его работу.
-
-Обратим внимание на панель управления справа-сверху, в ней есть 6 кнопок:
-
- -- продолжить выполнение, горячая клавиша `key:F8`.
-: Продолжает выполнения скрипта с текущего момента в обычном режиме. Если скрипт не встретит новых точек остановки, то в отладчик управление больше не вернётся.
-
- Нажмите на эту кнопку.
-
- Скрипт продолжится, далее, в 6й строке находится рекурсивный вызов функции `pow`, т.е. управление перейдёт в неё опять (с другими аргументами) и сработает точка остановки, вновь включая отладчик.
-
- При этом вы увидите, что выполнение стоит на той же строке, но в `Call Stack` появился новый вызов.
-
- Походите по стеку вверх-вниз -- вы увидите, что действительно аргументы разные.
-
- -- сделать шаг, не заходя внутрь функции, горячая клавиша `key:F10`.
-: Выполняет одну команду скрипта. Если в ней есть вызов функции -- то отладчик обходит его стороной, т.е. не переходит на код внутри.
-
- Эта кнопка очень удобна, если в текущей строке вызывается функция JS-фреймворка или какая-то другая, которая нас ну совсем не интересует. Тогда выполнение продолжится дальше, без захода в эту функцию, что нам и нужно.
-
- Обратим внимание, в данном случае эта кнопка при нажатии всё-таки перейдёт внутрь вложенного вызова `pow`, так как внутри `pow` находится брейкпойнт, а на включённых брейкпойнтах отладчик останавливается всегда.
-
- -- сделать шаг, горячая клавиша `key:F11`.
-: Выполняет одну команду скрипта и переходит к следующей. Если есть вложенный вызов, то заходит внутрь функции.
-
- Эта кнопка позволяет подробнейшим образом пройтись по очереди по командам скрипта.
-
- -- выполнять до выхода из текущей функции, горячая клавиша `key:Shift+F11`.
-: Выполняет команды до завершения текущей функции.
-
- Эта кнопка очень удобна в случае, если мы нечаянно вошли во вложенный вызов, который нам не интересен -- чтобы быстро из него выйти.
-
- -- отключить/включить все точки остановки.
-: Эта кнопка никак не двигает нас по коду, она позволяет временно отключить все точки остановки в файле.
-
- -- включить/отключить автоматическую остановку при ошибке.
-: Эта кнопка -- одна из самых важных.
-
- Нажмите её несколько раз. В старых версиях Chrome у неё три режима -- нужен фиолетовый, в новых -- два, тогда достаточно синего.
-
- Когда она включена, то при ошибке в коде он автоматически остановится и мы сможем посмотреть в отладчике текущие значения переменных, при желании выполнить команды и выяснить, как так получилось.
-
-**Процесс отладки заключается в том, что мы останавливаем скрипт, смотрим, что с переменными, переходим дальше и ищем, где поведение отклоняется от правильного.**
-
-```smart header="Continue to here"
-Правый клик на номер строки открывает контекстное меню, в котором можно запустить выполнение кода до неё (Continue to here). Это удобно, когда хочется сразу прыгнуть вперёд и breakpoint неохота ставить.
-```
-
-## Консоль
-
-При отладке, кроме просмотра переменных и передвижения по скрипту, бывает полезно запускать команды JavaScript. Для этого нужна консоль.
-
-В неё можно перейти, нажав кнопку "Console" вверху-справа, а можно и открыть в дополнение к отладчику, нажав на кнопку или клавишей `key:ESC`.
-
-**Самая любимая команда разработчиков: `console.log(...)`.**
-
-Она пишет переданные ей аргументы в консоль, например:
-
-```js run
-// результат будет виден в консоли
-for (var i = 0; i < 5; i++) {
- console.log("значение", i);
-}
-```
-
-Полную информацию по специальным командам консоли вы можете получить на странице [Chrome Console API](https://developer.chrome.com/devtools/docs/console-api) и [Chrome CommandLine API](https://developer.chrome.com/devtools/docs/commandline-api). Почти все команды также действуют в Firebug (отладчик для браузера Firefox).
-
-Консоль поддерживают все браузеры, и, хотя IE10- поддерживает далеко не все функции, но `console.log` работает везде. Используйте его для вывода отладочной информации по ходу работы скрипта.
-
-## Ошибки
-
-Ошибки JavaScript выводятся в консоли.
-
-Например, прервите отладку -- для этого достаточно закрыть инструменты разрабтчика -- и откройте [страницу с ошибкой](error/index.html).
-
-Перейдите во вкладку Console инструментов разработчика (`key:Ctrl+Shift+J` / `key:Cmd+Shift+J`).
-
-В консоли вы увидите что-то подобное:
-
-
-Красная строка -- это сообщение об ошибке.
-
-Если кликнуть на ссылке `pow.js` в консоли, справа в строке с ошибкой, то мы перейдём непосредственно к месту в скрипте, где возникла ошибка.
-
-Однако почему она возникла?
-
-Более подробно прояснить произошедшее нам поможет отладчик. Он может "заморозить" выполнение скрипта на момент ошибки и дать нам возможность посмотреть значения переменных и стека на тот момент.
-
-Для этого:
-
-1. Перейдите на вкладку Sources.
-2. Включите остановку при ошибке, кликнув на кнопку 
-3. Перезагрузите страницу.
-
-После перезагрузки страницы JavaScript-код запустится снова и отладчик остановит выполнение на строке с ошибкой:
-
-
-
-Можно посмотреть значения переменных. Открыть консоль и попробовать запустить что-то в ней. Поставить брейкпойнты раньше по коду и посмотреть, что привело к такой печальной картине, и так далее.
-
-## Итого
-
-Отладчик позволяет:
-
-- Останавливаться на отмеченном месте (breakpoint) или по команде `debugger`.
-- Выполнять код -- по одной строке или до определённого места.
-- Смотреть переменные, выполнять команды в консоли и т.п.
-
-В этой главе кратко описаны возможности отладчика Google Chrome, относящиеся именно к работе с кодом.
-
-Пока что это всё, что нам надо, но, конечно, инструменты разработчика умеют много чего ещё. В частности, вкладка Elements -- позволяет работать со страницей (понадобится позже), Timeline -- смотреть, что именно делает браузер и сколько это у него занимает и т.п.
-
-Осваивать можно двумя путями:
-
-1. [Официальная документация](https://developer.chrome.com/devtools) (на англ.)
-2. Кликать в разных местах и смотреть, что получается. Не забывать о клике правой кнопкой мыши.
-
-Мы ещё вернёмся к отладчику позже, когда будем работать с HTML.
diff --git a/1-js/03-code-quality/1-debugging-chrome/debugging.view/index.html b/1-js/03-code-quality/1-debugging-chrome/debugging.view/index.html
deleted file mode 100644
index 246dd753..00000000
--- a/1-js/03-code-quality/1-debugging-chrome/debugging.view/index.html
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
- Пример для отладчика.
-
-
-
-
-
-
\ No newline at end of file
diff --git a/1-js/03-code-quality/1-debugging-chrome/debugging.view/pow.js b/1-js/03-code-quality/1-debugging-chrome/debugging.view/pow.js
deleted file mode 100644
index 8a9e30db..00000000
--- a/1-js/03-code-quality/1-debugging-chrome/debugging.view/pow.js
+++ /dev/null
@@ -1,8 +0,0 @@
-function pow(x, n) {
- if (n == 1) {
- return x;
- }
-
- var result = x * pow(x, n - 1);
- return result;
-}
\ No newline at end of file
diff --git a/1-js/03-code-quality/1-debugging-chrome/error.view/index.html b/1-js/03-code-quality/1-debugging-chrome/error.view/index.html
deleted file mode 100644
index 246dd753..00000000
--- a/1-js/03-code-quality/1-debugging-chrome/error.view/index.html
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
- Пример для отладчика.
-
-
-
-
-
-
\ No newline at end of file
diff --git a/1-js/03-code-quality/1-debugging-chrome/error.view/pow.js b/1-js/03-code-quality/1-debugging-chrome/error.view/pow.js
deleted file mode 100644
index 5939b71b..00000000
--- a/1-js/03-code-quality/1-debugging-chrome/error.view/pow.js
+++ /dev/null
@@ -1,8 +0,0 @@
-function pow(x, n) {
- if (n == 1) {
- return y;
- }
-
- var result = x * pow(x, n - 1);
- return result;
-}
\ No newline at end of file
diff --git a/1-js/03-code-quality/2-coding-style/article.md b/1-js/03-code-quality/2-coding-style/article.md
deleted file mode 100644
index ede36450..00000000
--- a/1-js/03-code-quality/2-coding-style/article.md
+++ /dev/null
@@ -1,433 +0,0 @@
-# TODO: Coding style
-
-Our code must be as clean and easy to read as possible.
-
-That is actually an art of programming -- to take a complex task and describe it using a programming language in a way that is both correct and human-readable.
-
-One thing to help is a good code style. In this chapter we cover it's components.
-
-[cut]
-
-## Syntax
-
-A cheatsheet with the rules (more details below):
-
-
-
-
-Nothing is "carved in stone" here, so let's discuss the rules in detail.
-
-### Figure brackets
-
-In most JavaScript projects figure brackets are written on the same line. A so-called "egyptian" style. There's also a space before an opening bracket.
-
-A corner-case if a single-line `if/for`. Should we use brackets at all? If yes, then where?
-
-Here are the annotated variants, so you can judge about their readability on your own:
-
-
-
-
-As a summary, for a really short code one line is acceptable: like `if (cond) return null`.
-
-But a separate line for each statement in brackets is usually better.
-
-### Line length
-
-The maximal line length should be limited. No one likes to eye-follow a long horizontal line. Doesn't matter if it's a text or an OR'ed list of `if` conditions. It's better to split it.
-
-The maximal line length is agreed on the team-level. It's usually 80 or 120 characters.
-
-### Indents
-
-There are two types of indents:
-
-- **A horizontal indent: 2(4) spaces.**
-
- A horizantal identation is made using either spaces or the "Tab" symbol (displayed as 2 or 4 or even 8 spaces, but 8 is too much).
-
- Which one to choose is a kind of an old holy war. Spaces are a little more common nowadays.
-
- One of advantages of spaces over tabs is that they allow more flexible configurations of indents than the "Tab" symbol.
-
- For instance, we can align the arguments with the opening bracket, like this:
-
- ```js no-beautify
- show(parameters,
- aligned,
- one,
- after,
- another
- ) {
- // ...
- }
- ```
-
-- **A vertical indent, line breaks for splitting the code in logical blocks.**
-
- Even a single function can often be divided in logical blocks. In the example below, the initialization of variables, the main loop and returning the result are split vertically:
-
- ```js
- function pow(x, n) {
- let result = 1;
- // <--
- for (let i = 0; i < n; i++) {
- result *= x;
- }
- // <--
- return result;
- }
- ```
-
- Insert an additional line break where it helps to make the code more readable. There should not be more than 9 lines of code without a vertical indentation.
-
-### A semicolon
-
-A semicolons should be after each statement. Even if could possibly be skipped.
-
-There are languages where a semicolon is truly optional. It's rarely used there.
-
-But in JavaScript a line break is sometimes interpreted as a semicolon and sometimes not. That leaves a place for programming errors, so semicolons should be at place.
-
-### Nesting levels
-
-There should not be too many nesting levels.
-
-Sometimes it's a good idea to use the ["continue"](info:while-for#continue) directive in the loop to evade extra nesting in `if(..) { ... }`:
-
-Instead of:
-
-```js
-for (let i = 0; i < 10; i++) {
- if (cond) {
- ... // <- one more nesting level
- }
-}
-```
-
-We can write:
-
-```js
-for (let i = 0; i < 10; i++) {
- if (!cond) *!*continue*/!*;
- ... // <- no extra nesting level
-}
-```
-
-The similar thing can be done with `if/else` and `return`.
-
-For example, two constructs below are identical.
-
-The first one:
-
-```js
-function isEven(n) { // returns whether the number is even
- if (n % 2 == 0) {
- return true;
-*!*
- } else {
- return false;
- }
-*/!*
-}
-```
-
-The second one:
-
-```js
-function isEven(n) {
- if (n % 2 == 0) {
- return true;
- }
-
-*!*
- return false;
-*/!*
-}
-```
-
-If there's a `return` inside the `if` block, then we need no `else` after it.
-
-By the way, the very this function we can be implemented in a shorter way:
-
-```js
-function isEven(n) {
- return !(n % 2);
-}
-```
-
-But the code became less obvious.
-
-...Of course we can write even shorter here:
-**The most important not shortness, but simplicity and readability of the code.**
-
-A shorter code is not always simpler to understand and maintain.
-
-## The Naming
-
-As a general rule:
-
-- A variable name should be a noun.
-- A function name should be a verb, or start with a verbal prefix. There can be exceptions if covered by another rule.
-
-The camel-case notation is used for long words.
-
-We discussed that before -- see [function basics](info:function-basics#function-naming) and [variables](info:variables#variable-naming).
-
-A name should be descriptive and long enough, with the exception of:
- - loop counter variables, `i` is a well-recognized name for a loop counter.
- - functions/libraries that are well known and used very often.
- - other cases when the code readability doesn't suffer.
-
-
-
-## Functions = Comments
-
-Functions should be short and do exactly one thing. If that thing is big, maybe it's worth to split the function into parts.
-
-Sometimes following this rule may be not easy, but it's a definitely good thing.
-
-...So what's here about comments?
-
-A separate function is not only easier to test and debug -- it's very existance is a great comment!
-
-For instance, compare the two functions `showPrimes(n)` below. Each one outputs [prime numbers](https://en.wikipedia.org/wiki/Prime_number) up to `n`.
-
-The first variant uses a label:
-
-```js
-function showPrimes(n) {
- nextPrime: for (var i = 2; i < n; i++) {
-
- for (var j = 2; j < i; j++) {
- if (i % j == 0) continue nextPrime;
- }
-
- alert( i ); // a prime
- }
-}
-```
-
-The second variant uses an additional function `isPrime(n)` to test primality:
-
-```js
-function showPrimes(n) {
-
- for (let i = 2; i < n; i++) {
- *!*if (!isPrime(i)) continue;*/!*
-
- alert(i); // a prime
- }
-}
-
-function isPrime(n) {
- for (let i = 2; i < n; i++) {
- if ( n % i == 0) return false;
- }
- return true;
-}
-```
-
-The second variant is easier to understand isn't it? Instead of the code piece we see a name of the action (`isPrime`). Sometimes people refer to such code as *self-describing*.
-
-## Functions below the code
-
-There are three way to place the "helper" functions used in the code.
-
-1. Above the code that uses them:
-
- ```js
- // *!*function declarations*/!*
- function createElement() {
- ...
- }
-
- function setHandler(elem) {
- ...
- }
-
- function walkAround() {
- ...
- }
-
- // *!*the code which uses them*/!*
- var elem = createElement();
- setHandler(elem);
- walkAround();
- ```
-2. Code first, then functions
-
- ```js
- // *!*the code which uses the functions*/!*
- var elem = createElement();
- setHandler(elem);
- walkAround();
-
- // --- *!*helper functions*/!* ---
-
- function createElement() {
- ...
- }
-
- function setHandler(elem) {
- ...
- }
-
- function walkAround() {
- ...
- }
- ```
-3. Mixed, a function is described when it's first used.
-
-Most of time, the second variant is preferred.
-
-That's because when reading a code, we first want to know "what it does". If the code goes first, then it provides that information. And then maybe we won't need to read functions at all, especially if their names are adequate to what they're doing.
-
-## Bad comments
-
-В коде нужны комментарии.
-
-Сразу начну с того, каких комментариев быть почти не должно.
-
-**Должен быть минимум комментариев, которые отвечают на вопрос "что происходит в коде?"**
-
-Что интересно, в коде начинающих разработчиков обычно комментариев либо нет, либо они как раз такого типа: "что делается в этих строках".
-
-Серьёзно, хороший код и так понятен.
-
-Об этом замечательно выразился Р.Мартин в книге ["Чистый код"](http://www.ozon.ru/context/detail/id/21916535/): "Если вам кажется, что нужно добавить комментарий для улучшения понимания, это значит, что ваш код недостаточно прост, и, может, стоит переписать его".
-
-Если у вас образовалась длинная "простыня", то, возможно, стоит разбить её на отдельные функции, и тогда из их названий будет понятно, что делает тот или иной фрагмент.
-
-Да, конечно, бывают сложные алгоритмы, хитрые решения для оптимизации, поэтому нельзя такие комментарии просто запретить. Но перед тем, как писать подобное -- подумайте: "Нельзя ли сделать код понятным и без них?"
-
-## Хорошие комментарии
-
-А какие комментарии полезны и приветствуются?
-
-- **Архитектурный комментарий -- "как оно, вообще, устроено".**
-
- Какие компоненты есть, какие технологии использованы, поток взаимодействия. О чём и зачем этот скрипт. Взгляд с высоты птичьего полёта. Эти комментарии особенно нужны, если вы не один, а проект большой.
-
- Для описания архитектуры, кстати, создан специальный язык [UML](http://ru.wikipedia.org/wiki/Unified_Modeling_Language), красивые диаграммы, но можно и без этого. Главное -- чтобы понятно.
-- **Справочный комментарий перед функцией -- о том, что именно она делает, какие параметры принимает и что возвращает.**
-
- Для таких комментариев существует синтаксис [JSDoc](http://en.wikipedia.org/wiki/JSDoc).
-
- ```js
- /**
- * Возвращает x в степени n, только для натуральных n
- *
- * @param {number} x Число для возведения в степень.
- * @param {number} n Показатель степени, натуральное число.
- * @return {number} x в степени n.
- */
- function pow(x, n) {
- ...
- }
- ```
-
- Такие комментарии позволяют сразу понять, что принимает и что делает функция, не вникая в код.
-
- Кстати, они автоматически обрабатываются многими редакторами, например [Aptana](http://aptana.com) и редакторами от [JetBrains](http://www.jetbrains.com/), которые учитывают их при автодополнении, а также выводят их в автоподсказках при наборе кода.
-
- Кроме того, есть инструменты, например [JSDoc 3](https://github.com/jsdoc3/jsdoc), которые умеют генерировать по таким комментариям документацию в формате HTML. Более подробную информацию об этом можно также найти на сайте .
-
-**...Но куда более важными могут быть комментарии, которые объясняют не *что*, а *почему* в коде происходит именно это!**
-
-Как правило, из кода можно понять, что он делает. Бывает, конечно, всякое, но, в конце концов, вы этот код *видите*. Однако гораздо важнее может быть то, чего вы *не видите*!
-
-*Почему* это сделано именно так? На это сам код ответа не даёт.
-
-Например:
-
-Есть несколько способов решения задачи. Почему выбран именно этот?
-: Например, пробовали решить задачу по-другому, но не получилось -- напишите об этом. Почему вы выбрали именно этот способ решения? Особенно это важно в тех случаях, когда используется не первый приходящий в голову способ, а какой-то другой.
-
- Без этого возможна, например, такая ситуация:
-
-- Вы открываете код, который был написан какое-то время назад, и видите, что он "неоптимален".
-- Думаете: "Какой я был дурак", и переписываете под "более очевидный и правильный" вариант.
-- ...Порыв, конечно, хороший, да только этот вариант вы уже обдумали раньше. И отказались, а почему -- забыли. В процессе переписывания вспомнили, конечно (к счастью), но результат - потеря времени на повторное обдумывание.
-
- Комментарии, которые объясняют выбор решения, очень важны. Они помогают понять происходящее и предпринять правильные шаги при развитии кода.
-
-Какие неочевидные возможности обеспечивает этот код? Где ещё они используются?
-: В хорошем коде должно быть минимум неочевидного. Но там, где это есть -- пожалуйста, комментируйте.
-
-```smart header="Комментарии -- это важно"
-Один из показателей хорошего разработчика -- качество комментариев, которые позволяют эффективно поддерживать код, возвращаться к нему после любой паузы и легко вносить изменения.
-```
-
-## Руководства по стилю
-
-Когда написанием проекта занимается целая команда, то должен существовать один стандарт кода, описывающий где и когда ставить пробелы, запятые, переносы строк и т.п.
-
-Сейчас, когда есть столько готовых проектов, нет смысла придумывать целиком своё руководство по стилю. Можно взять уже готовое, и которому, по желанию, всегда можно что-то добавить.
-
-Большинство есть на английском, сообщите мне, если найдёте хороший перевод:
-
-- [Google JavaScript Style Guide](http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml)
-- [JQuery Core Style Guidelines](http://docs.jquery.com/JQuery_Core_Style_Guidelines)
-- [Airbnb JavaScript Style Guide](https://github.com/airbnb/javascript)
-- [Idiomatic.JS](https://github.com/rwldrn/idiomatic.js) (есть [перевод](https://github.com/rwldrn/idiomatic.js/tree/master/translations/ru_RU))
-- [Dojo Style Guide](http://dojotoolkit.org/community/styleGuide)
-
-Для того, чтобы начать разработку, вполне хватит элементов стилей, обозначенных в этой главе. В дальнейшем, посмотрев эти руководства, вы можете выработать и свой стиль, но лучше не делать его особенно "уникальным и неповторимым", себе дороже потом будет с людьми сотрудничать.
-
-## Автоматизированные средства проверки
-
-Существуют средства, проверяющие стиль кода.
-
-Самые известные -- это:
-
-- [JSLint](http://www.jslint.com/) -- проверяет код на соответствие [стилю JSLint](http://www.jslint.com/lint.html), в онлайн-интерфейсе вверху можно ввести код, а внизу различные настройки проверки, чтобы сделать её более мягкой.
-- [JSHint](http://www.jshint.com/) -- вариант JSLint с большим количеством настроек.
-- [Closure Linter](https://developers.google.com/closure/utilities/) -- проверка на соответствие [Google JavaScript Style Guide](http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml).
-
-В частности, JSLint и JSHint интегрированы с большинством редакторов, они гибко настраиваются под нужный стиль и совершенно незаметно улучшают разработку, подсказывая, где и что поправить.
-
-Побочный эффект -- они видят некоторые ошибки, например необъявленные переменные. У меня это обычно результат опечатки, которые таким образом сразу отлавливаются. Очень рекомендую поставить что-то из этого. Я использую [JSHint](http://www.jshint.com/).
-
-## Итого
-
-Описанные принципы оформления кода уместны в большинстве проектов. Есть и другие полезные соглашения.
-
-Следуя (или не следуя) им, необходимо помнить, что любые советы по стилю хороши лишь тогда, когда делают код читаемее, понятнее, проще в поддержке.
-
diff --git a/1-js/03-code-quality/3-write-unmain-code/article.md b/1-js/03-code-quality/3-write-unmain-code/article.md
deleted file mode 100644
index 3be7f57e..00000000
--- a/1-js/03-code-quality/3-write-unmain-code/article.md
+++ /dev/null
@@ -1,297 +0,0 @@
-# TODO: Как писать неподдерживаемый код?
-
-```warn header="Познай свой код"
-Эта статья представляет собой мой вольный перевод [How To Write Unmaintainable Code](http://mindprod.com/jgloss/unmain.html) ("как писать неподдерживаемый код") с дополнениями, актуальными для JavaScript.
-
-Возможно, в каких-то из этих советов вам даже удастся узнать "этого парня в зеркале".
-```
-
-Предлагаю вашему вниманию советы мастеров древности, следование которым создаст дополнительные рабочие места для JavaScript-разработчиков.
-
-Если вы будете им следовать, то ваш код будет так сложен в поддержке, что у JavaScript'еров, которые придут после вас, даже простейшее изменение займет годы *оплачиваемого* труда! А сложные задачи оплачиваются хорошо, так что они, определённо, скажут вам "Спасибо".
-
-Более того, *внимательно* следуя этим правилам, вы сохраните и своё рабочее место, так как все будут бояться вашего кода и бежать от него...
-
-...Впрочем, всему своя мера. При написании такого кода он не должен *выглядеть* сложным в поддержке, код должен *быть* таковым.
-
-Явно кривой код может написать любой дурак. Это заметят, и вас уволят, а код будет переписан с нуля. Вы не можете такого допустить. Эти советы учитывают такую возможность. Да здравствует дзен.
-
-[cut]
-
-## Соглашения -- по настроению
-
-```quote author="Сериал \"Симпсоны\", серия Helter Shelter"
-Рабочий-чистильщик осматривает дом:
-"...Вот только жук у вас необычный...
-И чтобы с ним справиться, я должен жить как жук, стать жуком, думать как жук."
-(грызёт стол Симпсонов)
-```
-
-Чтобы помешать другому программисту исправить ваш код, вы должны понять путь его мыслей.
-
-Представьте, перед ним -- ваш большой скрипт. И ему нужно поправить его. У него нет ни времени ни желания, чтобы читать его целиком, а тем более -- досконально разбирать. Он хотел бы по-быстрому найти нужное место, сделать изменение и убраться восвояси без появления побочных эффектов.
-
-Он рассматривает ваш код как бы через трубочку из туалетной бумаги. Это не даёт ему общей картины, он ищет тот небольшой фрагмент, который ему необходимо изменить. По крайней мере, он надеется, что этот фрагмент будет небольшим.
-
-**На что он попытается опереться в этом поиске -- так это на соглашения, принятые в программировании, об именах переменных, названиях функций и методов...**
-
-Как затруднить задачу? Можно везде нарушать соглашения -- это помешает ему, но такое могут заметить, и код будет переписан. Как поступил бы ниндзя на вашем месте?
-
-**...Правильно! Следуйте соглашениям "в общем", но иногда -- нарушайте их.**
-
-Тщательно разбросанные по коду нарушения соглашений с одной стороны не делают код явно плохим при первом взгляде, а с другой -- имеют в точности тот же, и даже лучший эффект, чем явное неследование им!
-
-### Пример из jQuery
-
-```warn header="jQuery / DOM"
-Этот пример требует знаний jQuery/DOM, если пока их у вас нет -- пропустите его, ничего страшного, но обязательно вернитесь к нему позже. Подобное стоит многих часов отладки.
-```
-
-Во фреймворке jQuery есть метод [wrap](http://api.jquery.com/wrap/), который обёртывает один элемент вокруг другого:
-
-```js
-var img = $('
'); // создали новые элементы (jQuery-синтаксис)
-var div = $(''); // и поместили в переменную
-
-img.wrap(div); // обернуть img в div
-div.append('');
-```
-
-Результат кода после операции `wrap` -- два элемента, один вложен в другой:
-
-```html
-
-
![]()
-
-```
-
-А что же после `append`?
-
-Можно предположить, что `` добавится в конец `div`, сразу после `img`... Но ничего подобного!
-
-Искусный ниндзя уже нанёс свой удар и поведение кода стало неправильным, хотя разработчик об этом даже не подозревает.
-
-Как правило, методы jQuery работают с теми элементами, которые им переданы. Но не здесь!
-
-Внутри вызова `img.wrap(div)` происходит клонирование `div` и вокруг `img` оборачивается не сам `div`, а его клон. При этом исходная переменная `div` не меняется, в ней как был пустой `div`, так и остался.
-
-В итоге, после вызова получается два независимых `div'а`: первый содержит `img` (этот неявный клон никуда не присвоен), а второй -- наш `span`.
-
-Объяснения не очень понятны? Написано что-то странное? Это просто разум, привыкший, что соглашения уважаются, не допускает мысли, что вызов `wrap` -- неявно клонирует элемент. Ведь другие jQuery-методы, кроме `clone` этого не делают.
-
-Как говорил [Учитель](https://ru.wikipedia.org/wiki/%D0%9A%D0%BE%D0%BD%D1%84%D1%83%D1%86%D0%B8%D0%B9): "В древности люди учились для того, чтобы совершенствовать себя. Нынче учатся для того, чтобы удивить других".
-
-## Краткость -- сестра таланта!
-
-Пишите "как короче", а не как понятнее. "Меньше букв" -- уважительная причина для нарушения любых соглашений.
-
-Ваш верный помощник -- возможности языка, использованные неочевидным образом.
-
-Обратите внимание на оператор вопросительный знак `'?'`, например:
-
-```js
-// код из jQuery
-i = i ? i < 0 ? Math.max(0, len + i) : i : 0;
-```
-
-Разработчик, встретивший эту строку и попытавшийся понять, чему же всё-таки равно `i`, скорее всего придёт к вам за разъяснениями. Смело скажите ему, что короче -- это всегда лучше. Посвятите и его в пути ниндзя. Не забудьте вручить [Дао дэ цзин](http://lib.ru/POECHIN/lao1.txt).
-
-## Именование
-
-Существенную часть науки о создании неподдерживаемого кода занимает искусство выбора имён.
-
-### Однобуквенные переменные
-
-Называйте переменные коротко: `a`, `b` или `c`.
-
-В этом случае никто не сможет найти её, используя фунцию "Поиск" текстового редактора.
-
-Более того, даже найдя -- никто не сможет "расшифровать" её и догадаться, что она означает.
-
-### Не используйте i для цикла
-
-В тех местах, где однобуквенные переменные общеприняты, например, в счетчике цикла -- ни в коем случае не используйте стандартные названия `i`, `j`, `k`. Где угодно, только не здесь!
-
-Остановите свой взыскательный взгляд на чём-нибудь более экзотическом. Например, `x` или `y`.
-
-Эффективность этого подхода особенно заметна, если тело цикла занимает одну-две страницы (чем длиннее -- тем лучше).
-
-В этом случае заметить, что переменная -- счетчик цикла, без пролистывания вверх, невозможно.
-
-### Русские слова и сокращения
-
-Если вам *приходится* использовать длинные, понятные имена переменных -- что поделать.. Но и здесь есть простор для творчества!
-
-**Назовите переменные "калькой" с русского языка или как-то "улучшите" английское слово.**
-
-В одном месте напишите `var ssilka`, в другом `var ssylka`, в третьем `var link`, в четвёртом -- `var lnk`... Это действительно великолепно работает и очень креативно!
-
-Количество ошибок при поддержке такого кода увеличивается во много раз.
-
-### Будьте абстрактны при выборе имени
-
-```quote author="Лао-цзы"
-Лучший кувшин лепят всю жизнь.
-Высокая музыка неподвластна слуху.
-Великий образ не имеет формы.
-```
-
-При выборе имени старайтесь применить максимально абстрактное слово, например `obj`, `data`, `value`, `item`, `elem` и т.п.
-
-- **Идеальное имя для переменной: `data`.** Используйте это имя везде, где можно. В конце концов, каждая переменная содержит *данные*, не правда ли?
-
- Но что делать, если имя `data` уже занято? Попробуйте `value`, оно не менее универсально. Ведь каждая переменная содержит *значение*.
-
- Занято и это? Есть и другой вариант.
-- **Называйте переменную по типу данных, которые она хранит: `obj`, `num`, `arr`...**
-
- Насколько это усложнит разработку? Как ни странно, намного!
-
- Казалось бы, название переменной содержит информацию, говорит о том, что в переменной -- число, объект или массив... С другой стороны, **когда непосвящённый будет разбирать этот код -- он с удивлением обнаружит, что информации нет!**
-
- Ведь как раз тип легко понять, запустив отладчик и посмотрев, что внутри. Но в чём смысл этой переменной? Что за массив/объект/число в ней хранится? Без долгой медитации над кодом тут не обойтись!
-- **Что делать, если и эти имена кончились? Просто добавьте цифру:** `item1, item2, elem5, data1`...
-
-### Похожие имена
-
-Только истинно внимательный программист достоин понять ваш код. Но как проверить, достоин ли читающий?
-
-**Один из способов -- использовать похожие имена переменных, например `data` и `date`.** Бегло прочитать такой код почти невозможно. А уж заметить опечатку и поправить её... Ммммм... Мы здесь надолго, время попить чайку.
-
-### А.К.Р.О.Н.И.М
-
-Используйте сокращения, чтобы сделать код короче.
-
-Например `ie` (Inner Element), `mc` (Money Counter) и другие. Если вы обнаружите, что путаетесь в них сами -- героически страдайте, но не переписывайте код. Вы знали, на что шли.
-
-### Хитрые синонимы
-
-```quote author="Конфуций"
-Очень трудно найти чёрную кошку в тёмной комнате, особенно когда её там нет.
-```
-
-**Чтобы было не скучно -- используйте *похожие названия* для обозначения *одинаковых действий*.**
-
-Например, если метод показывает что-то на экране -- начните его название с `display..` (скажем, `displayElement`), а в другом месте объявите аналогичный метод как `show..` (`showFrame`).
-
-**Как бы намекните этим, что существует тонкое различие между способами показа в этих методах, хотя на самом деле его нет.**
-
-По возможности, договоритесь с членами своей команды. Если Вася в своих классах использует `display..`, то Валера -- обязательно `render..`, а Петя -- `paint..`.
-
-**...И напротив, если есть две функции с важными отличиями -- используйте одно и то же слово для их описания!** Например, с `print...` можно начать метод печати на принтере `printPage`, а также -- метод добавления текста на страницу `printText`.
-
-А теперь, пусть читающий код думает: "Куда же выводит сообщение `printMessage`?". Особый шик -- добавить элемент неожиданности. Пусть `printMessage` выводит не туда, куда все, а в новое окно!
-
-### Словарь терминов -- это еда!
-
-Ни в коем случае не поддавайтесь требованиям написать словарь терминов для проекта. Если же он уже есть -- не следуйте ему, а лучше проглотите и скажите, что так и былО!
-
-Пусть читающий ваш код программист напрасно ищет различия в `helloUser` и `welcomeVisitor` и пытается понять, когда что использовать. Вы-то знаете, что на самом деле различий нет, но искать их можно о-очень долго.
-
-**Для обозначения посетителя в одном месте используйте `user`, а в другом `visitor`, в третьем -- просто `u`. Выбирайте одно имя или другое, в зависимости от функции и настроения.**
-
-Это воплотит сразу два ключевых принципа ниндзя-дизайна -- *сокрытие информации* и *подмена понятий*!
-
-### Повторно используйте имена
-
-По возможности, повторно используйте имена переменных, функций и свойств. Просто записывайте в них новые значения.
-
-Добавляйте новое имя только если это абсолютно необходимо.
-
-В функции старайтесь обойтись только теми переменными, которые были переданы как параметры.
-
-Это не только затруднит идентификацию того, что *сейчас* находится в переменной, но и сделает почти невозможным поиск места, в котором конкретное значение было присвоено.
-
-Цель -- максимально усложнить отладку и заставить читающего код программиста построчно анализировать код и конспектировать изменения переменных для каждой ветки исполнения.
-
-**Продвинутый вариант этого подхода -- незаметно (!) подменить переменную на нечто похожее, например:**
-
-```js
-function ninjaFunction(elem) {
- // 20 строк кода, работающего с elem
-
- elem = elem.cloneNode(true);
-
- // еще 20 строк кода, работающего с elem
-}
-```
-
-Программист, пожелавший добавить действия с `elem` во вторую часть функции, будет удивлён. Лишь во время отладки, посмотрев весь код, он с удивлением обнаружит, что оказывается имел дело с клоном!
-
-Регулярные встречи с этим приемом на практике говорят: защититься невозможно. Эффективно даже против опытного ниндзи.
-
-### Добавляйте подчеркивания
-
-Добавляйте подчеркивания `_` и `__` к именам переменных. Желательно, чтобы их смысл был известен только вам, а лучше -- вообще без явной причины.
-
-Этим вы достигните двух целей. Во-первых, код станет длиннее и менее читаемым, а во-вторых, другой программист будет долго искать смысл в подчёркиваниях. Особенно хорошо сработает и внесет сумятицу в его мысли, если в некоторых частях проекта подчеркивания будут, а в некоторых -- нет.
-
-В процессе развития кода вы, скорее всего, будете путаться и смешивать стили: добавлять имена с подчеркиваниями там, где обычно подчеркиваний нет, и наоборот. Это нормально и полностью соответствует третьей цели -- увеличить количество ошибок при внесении исправлений.
-
-### Покажите вашу любовь к разработке
-
-Пусть все видят, какими замечательными сущностями вы оперируете! Имена `superElement`, `megaFrame` и `niceItem` при благоприятном положении звёзд могут привести к просветлению читающего.
-
-Действительно, с одной стороны, кое-что написано: `super..`, `mega..`, `nice..` С другой -- это не несёт никакой конкретики. Читающий может решить поискать в этом глубинный смысл и замедитировать на часок-другой оплаченного рабочего времени.
-
-### Перекрывайте внешние переменные
-
-```quote author="Гуань Инь-цзы"
-Находясь на свету, нельзя ничего увидеть в темноте.
-Пребывая же в темноте, увидишь все, что находится на свету.
-```
-
-Почему бы не использовать одинаковые переменные внутри и снаружи функции? Это просто и не требует придумывать новых имён.
-
-```js
-var *!*user*/!* = authenticateUser();
-
-function render() {
- var *!*user*/!* = anotherValue();
- ...
- ...многобукв...
- ...
- ... // <-- программист захочет внести исправления сюда, и..
- ...
-}
-```
-
-Зашедший в середину метода `render` программист, скорее всего, не заметит, что переменная `user` локально перекрыта и попытается работать с ней, полагая, что это результат `authenticateUser()`... Ловушка захлопнулась! Здравствуй, отладчик.
-
-## Мощные функции!
-
-Не ограничивайте действия функции тем, что написано в её названии. Будьте шире.
-
-Например, функция `validateEmail(email)` может, кроме проверки e-mail на правильность, выводить сообщение об ошибке и просить заново ввести e-mail.
-
-**Выберите хотя бы пару дополнительных действий, кроме основного назначения функции.**
-
-Главное -- они должны быть неочевидны из названия функции. Истинный ниндзя-девелопер сделает так, что они будут неочевидны и из кода тоже.
-
-**Объединение нескольких смежных действий в одну функцию защитит ваш код от повторного использования.**
-
-Представьте, что другому разработчику нужно только проверить адрес, а сообщение -- не выводить. Ваша функция `validateEmail(email)`, которая делает и то и другое, ему не подойдёт. Работодатель будет вынужден оплатить создание новой.
-
-## Внимание.. Сюр-при-из!
-
-Есть функции, название которых говорит о том, что они ничего не меняют. Например, `isReady`, `checkPermission`, `findTags`... Предполагается, что при вызове они произведут некие вычисления, или найдут и возвратят полезные данные, но при этом их не изменят. В трактатах это называется "отсутствие сторонних эффектов".
-
-**По-настоящему красивый приём -- делать в таких функциях что-нибудь полезное, заодно с процессом проверки. Что именно -- совершенно неважно.**
-
-Удивление и ошеломление, которое возникнет у вашего коллеги, когда он увидит, что функция с названием на `is..`, `check..` или `find...` что-то меняет -- несомненно, расширит его границы разумного!
-
-**Ещё одна вариация такого подхода -- возвращать нестандартное значение.**
-
-Ведь общеизвестно, что `is..` и `check..` обычно возвращают `true/false`. Продемонстрируйте оригинальное мышление. Пусть вызов `checkPermission` возвращает не результат `true/false`, а объект с результатами проверки! А чего, полезно.
-
-Те же разработчики, кто попытается написать проверку `if (checkPermission(..))`, будут весьма удивлены результатом. Ответьте им: "надо читать документацию!". И перешлите эту статью.
-
-## Заключение
-
-Все советы выше пришли из реального кода... И в том числе от разработчиков с большим опытом.
-
-Возможно, даже больше вашего, так что не судите опрометчиво ;)
-
-- Следуйте нескольким из них -- и ваш код станет полон сюрпризов.
-- Следуйте многим -- и ваш код станет истинно вашим, никто не захочет изменять его.
-- Следуйте всем -- и ваш код станет ценным уроком для молодых разработчиков, ищущих просветления.
diff --git a/1-js/index.md b/1-js/index.md
index 2973f97f..741c4207 100644
--- a/1-js/index.md
+++ b/1-js/index.md
@@ -2,5 +2,5 @@
Here we learn JavaScript, starting from the scratch and to advanced concepts like OOP.
-We'll be using browser as an environment, but the main attention goes to JavaScript itself.
+We concentrate on the language itself here, with the minimum of environment-specific notes.
diff --git a/figures.sketch b/figures.sketch
index 5819b5c3..46affef0 100644
Binary files a/figures.sketch and b/figures.sketch differ