vasille 2.3.7 → 2.3.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/cdn/es2015.js CHANGED
@@ -349,9 +349,6 @@ class Reactive extends Destroyable {
349
349
  }
350
350
  runFunctional(f, ...args) {
351
351
  stack(this);
352
- // yet another ts bug
353
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
354
- // @ts-ignore
355
352
  const result = f(...args);
356
353
  unstack();
357
354
  return result;
@@ -1480,7 +1477,7 @@ class Fragment extends Reactive {
1480
1477
  * @param cb {function(Tag, *)} callback
1481
1478
  */
1482
1479
  tag(tagName, input, cb
1483
- // @ts-ignore
1480
+ // @ts-expect-error
1484
1481
  ) {
1485
1482
  const $ = this.$;
1486
1483
  const node = new Tag(input);
@@ -1489,7 +1486,7 @@ class Fragment extends Reactive {
1489
1486
  node.init();
1490
1487
  this.pushNode(node);
1491
1488
  node.ready();
1492
- // @ts-ignore
1489
+ // @ts-expect-error
1493
1490
  return node.node;
1494
1491
  }
1495
1492
  /**
package/lib/core/core.js CHANGED
@@ -220,9 +220,6 @@ export class Reactive extends Destroyable {
220
220
  }
221
221
  runFunctional(f, ...args) {
222
222
  stack(this);
223
- // yet another ts bug
224
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
225
- // @ts-ignore
226
223
  const result = f(...args);
227
224
  unstack();
228
225
  return result;
package/lib/node/node.js CHANGED
@@ -163,7 +163,7 @@ export class Fragment extends Reactive {
163
163
  * @param cb {function(Tag, *)} callback
164
164
  */
165
165
  tag(tagName, input, cb
166
- // @ts-ignore
166
+ // @ts-expect-error
167
167
  ) {
168
168
  const $ = this.$;
169
169
  const node = new Tag(input);
@@ -172,7 +172,7 @@ export class Fragment extends Reactive {
172
172
  node.init();
173
173
  this.pushNode(node);
174
174
  node.ready();
175
- // @ts-ignore
175
+ // @ts-expect-error
176
176
  return node.node;
177
177
  }
178
178
  /**
@@ -0,0 +1 @@
1
+ {"root":["../src/index.ts","../src/binding/attribute.ts","../src/binding/binding.ts","../src/binding/class.ts","../src/binding/style.ts","../src/core/core.ts","../src/core/destroyable.ts","../src/core/errors.ts","../src/core/ivalue.ts","../src/functional/options.ts","../src/models/array-model.ts","../src/models/listener.ts","../src/models/map-model.ts","../src/models/model.ts","../src/models/object-model.ts","../src/models/set-model.ts","../src/node/app.ts","../src/node/node.ts","../src/node/watch.ts","../src/spec/html.ts","../src/spec/react.ts","../src/spec/svg.ts","../src/value/expression.ts","../src/value/mirror.ts","../src/value/pointer.ts","../src/value/reference.ts","../src/views/array-view.ts","../src/views/base-view.ts","../src/views/map-view.ts","../src/views/object-view.ts","../src/views/repeat-node.ts","../src/views/set-view.ts"],"version":"5.6.2"}
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Reactive = exports.ReactivePrivate = exports.unstack = exports.stack = exports.current = void 0;
3
+ exports.Reactive = exports.ReactivePrivate = exports.current = void 0;
4
+ exports.stack = stack;
5
+ exports.unstack = unstack;
4
6
  const destroyable_js_1 = require("./destroyable.js");
5
7
  const errors_1 = require("./errors");
6
8
  const expression_1 = require("../value/expression");
@@ -13,11 +15,9 @@ function stack(node) {
13
15
  currentStack.push(exports.current);
14
16
  exports.current = node;
15
17
  }
16
- exports.stack = stack;
17
18
  function unstack() {
18
19
  exports.current = currentStack.pop();
19
20
  }
20
- exports.unstack = unstack;
21
21
  /**
22
22
  * Private stuff of a reactive object
23
23
  * @class ReactivePrivate
@@ -226,9 +226,6 @@ class Reactive extends destroyable_js_1.Destroyable {
226
226
  }
227
227
  runFunctional(f, ...args) {
228
228
  stack(this);
229
- // yet another ts bug
230
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
231
- // @ts-ignore
232
229
  const result = f(...args);
233
230
  unstack();
234
231
  return result;
@@ -1,23 +1,22 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.wrongBinding = exports.userError = exports.internalError = exports.notOverwritten = void 0;
3
+ exports.notOverwritten = notOverwritten;
4
+ exports.internalError = internalError;
5
+ exports.userError = userError;
6
+ exports.wrongBinding = wrongBinding;
4
7
  const reportIt = "Report it here: https://gitlab.com/vasille-js/vasille-js/-/issues";
5
8
  function notOverwritten() {
6
9
  console.error("Vasille-SFP: Internal error", "Must be overwritten", reportIt);
7
10
  return "not-overwritten";
8
11
  }
9
- exports.notOverwritten = notOverwritten;
10
12
  function internalError(msg) {
11
13
  console.error("Vasille-SFP: Internal error", msg, reportIt);
12
14
  return "internal-error";
13
15
  }
14
- exports.internalError = internalError;
15
16
  function userError(msg, err) {
16
17
  console.error("Vasille-SFP: User error", msg);
17
18
  return err;
18
19
  }
19
- exports.userError = userError;
20
20
  function wrongBinding(msg) {
21
21
  return userError(msg, "wrong-binding");
22
22
  }
23
- exports.wrongBinding = wrongBinding;
@@ -167,7 +167,7 @@ class Fragment extends core_1.Reactive {
167
167
  * @param cb {function(Tag, *)} callback
168
168
  */
169
169
  tag(tagName, input, cb
170
- // @ts-ignore
170
+ // @ts-expect-error
171
171
  ) {
172
172
  const $ = this.$;
173
173
  const node = new Tag(input);
@@ -176,7 +176,7 @@ class Fragment extends core_1.Reactive {
176
176
  node.init();
177
177
  this.pushNode(node);
178
178
  node.ready();
179
- // @ts-ignore
179
+ // @ts-expect-error
180
180
  return node.node;
181
181
  }
182
182
  /**
@@ -0,0 +1 @@
1
+ {"root":["../src/index.ts","../src/binding/attribute.ts","../src/binding/binding.ts","../src/binding/class.ts","../src/binding/style.ts","../src/core/core.ts","../src/core/destroyable.ts","../src/core/errors.ts","../src/core/ivalue.ts","../src/functional/options.ts","../src/models/array-model.ts","../src/models/listener.ts","../src/models/map-model.ts","../src/models/model.ts","../src/models/object-model.ts","../src/models/set-model.ts","../src/node/app.ts","../src/node/node.ts","../src/node/watch.ts","../src/spec/html.ts","../src/spec/react.ts","../src/spec/svg.ts","../src/value/expression.ts","../src/value/mirror.ts","../src/value/pointer.ts","../src/value/reference.ts","../src/views/array-view.ts","../src/views/base-view.ts","../src/views/map-view.ts","../src/views/object-view.ts","../src/views/repeat-node.ts","../src/views/set-view.ts"],"version":"5.6.2"}
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "vasille",
3
- "description": "Vasille - Safe. Fast. Powerful.",
3
+ "description": "Vasille - Safe. Simple. Powerful.",
4
4
  "main": "lib/index.js",
5
5
  "types": "types/index.d.ts",
6
- "version": "2.3.7",
6
+ "version": "2.3.8",
7
7
  "exports": {
8
8
  "import": "./lib/index.js",
9
9
  "browser": "./lib/index.js",
@@ -14,14 +14,11 @@
14
14
  "scripts": {
15
15
  "prettier": "npx prettier src test --check",
16
16
  "build": "tsc --build tsconfig-build.json",
17
- "build-es5": "tsc --build tsconfig-build-es5.json",
18
17
  "build-node": "tsc --build tsconfig-build-node.json",
19
18
  "test": "jest",
20
19
  "test-coverage": "jest --coverage",
21
20
  "update-types": "tsc --build tsconfig-types.json",
22
- "update-flowjs": "node flow-typed/create.cjs",
23
- "cdn-create": "node cdn/create.cjs",
24
- "es5-check": "es-check es5 cdn/*es5.js"
21
+ "cdn-create": "node cdn/create.cjs"
25
22
  },
26
23
  "repository": {
27
24
  "type": "git",
@@ -33,30 +30,27 @@
33
30
  "web",
34
31
  "app",
35
32
  "safe",
36
- "fast",
33
+ "simple",
37
34
  "poweful"
38
35
  ],
39
36
  "author": "Vasile Lixcode <lixcode@vivaldi.net> (https://t.me/lixcode)",
40
37
  "license": "MIT",
41
38
  "devDependencies": {
42
- "@types/debug": "4.1.7",
43
- "@types/eslint": "8.4.1",
44
- "@types/eslint-scope": "3.7.3",
45
- "@types/estree": "0.0.51",
46
- "@types/events": "3.0.0",
47
- "@types/jest": "27.4.1",
48
- "@types/jsdom": "16.2.14",
49
- "@types/node": "^18.14.6",
50
- "@typescript-eslint/eslint-plugin": "5.18.0",
51
- "@typescript-eslint/parser": "5.18.0",
52
- "es-check": "latest",
53
- "eslint": "latest",
54
- "flow-bin": "latest",
55
- "jest": "27.5.1",
56
- "jsdom": "19.0.0",
57
- "prettier": "2.7.1",
58
- "ts-jest": "27.1.4",
59
- "tslint-config-prettier": "^1.18.0",
60
- "typescript": "^4.9.5"
39
+ "@types/debug": "4.1.12",
40
+ "@types/eslint": "9.6.1",
41
+ "@types/eslint-scope": "3.7.7",
42
+ "@types/estree": "1.0.6",
43
+ "@types/events": "3.0.3",
44
+ "@types/jest": "29.5.13",
45
+ "@types/jsdom": "21.1.7",
46
+ "@typescript-eslint/eslint-plugin": "8.8.0",
47
+ "@typescript-eslint/parser": "8.8.0",
48
+ "eslint": "9.0.0",
49
+ "jest": "29.7.0",
50
+ "jsdom": "25.0.1",
51
+ "prettier": "3.3.3",
52
+ "ts-jest": "29.2.5",
53
+ "tslint-config-prettier": "1.18.0",
54
+ "typescript": "5.6.2"
61
55
  }
62
56
  }
@@ -0,0 +1 @@
1
+ {"root":["../src/index.ts","../src/binding/attribute.ts","../src/binding/binding.ts","../src/binding/class.ts","../src/binding/style.ts","../src/core/core.ts","../src/core/destroyable.ts","../src/core/errors.ts","../src/core/ivalue.ts","../src/functional/options.ts","../src/models/array-model.ts","../src/models/listener.ts","../src/models/map-model.ts","../src/models/model.ts","../src/models/object-model.ts","../src/models/set-model.ts","../src/node/app.ts","../src/node/node.ts","../src/node/watch.ts","../src/spec/html.ts","../src/spec/react.ts","../src/spec/svg.ts","../src/value/expression.ts","../src/value/mirror.ts","../src/value/pointer.ts","../src/value/reference.ts","../src/views/array-view.ts","../src/views/base-view.ts","../src/views/map-view.ts","../src/views/object-view.ts","../src/views/repeat-node.ts","../src/views/set-view.ts"],"version":"5.6.2"}
package/LICENSE.md DELETED
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2019 Vasile Lelițac
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
package/README.md DELETED
@@ -1,215 +0,0 @@
1
- # Vasille Core Library
2
-
3
- ![Vasille.js logo](https://gitlab.com/vasille-js/vasille-js/-/raw/v2/img/logo.png)
4
-
5
- `Vasille` core library is frontend solution for `safe`, `fast` & `powerful` applications.
6
-
7
- [![build](https://gitlab.com/vasille-js/vasille-js/badges/v2/pipeline.svg)](https://gitlab.com/vasille-js/vasille-js)
8
- [![npm](https://img.shields.io/npm/v/vasille?style=flat-square)](https://www.npmjs.com/package/vasille)
9
-
10
- ## Table of content
11
-
12
- * [Installation](#installation)
13
- * [How to use Vasille](#how-to-use-vasille)
14
- * [How SAFE is Vasille](#how-safe-is-vasille)
15
- * [How FAST is Vasille](#how-fast-is-vasille)
16
- * [How POWERFUL is Vasille](#how-powerful-is-vasille)
17
- * [Best Practices](#best-practices)
18
-
19
-
20
- <hr>
21
-
22
- ## Installation
23
-
24
- ```
25
- npm install vasille --save
26
- npm install vasille-less --save
27
- npm install vasille-magic --save
28
- ```
29
-
30
- ## How to use Vasille
31
-
32
- There are several modes to use Vasille.
33
-
34
- ### Documentation for beginners (how to create the first project step by step):
35
- * [`Vasille Core Library` - the hard way - `low-level`](https://gitlab.com/vasille-js/vasille-js/-/blob/v2/pages/GetStarted.md)
36
- * [`Vasille Less Library` - perfect for me - `high-level`](https://gitlab.com/vasille-js/vasille-less/-/blob/v2/pages/GetStarted.md)
37
- * [`Vasille Magic` - perfect for you - `highest-level`](https://gitlab.com/vasille-js/vasille-magic/-/blob/master/pages/GetStarted.md)
38
-
39
- ### Full documentation:
40
- * [`Vasille Core Library API`- write anything - `low-level`](https://gitlab.com/vasille-js/vasille-js/-/blob/v2/pages/Vasille-Core-Library-API.md)
41
- * [`Vasille Less Library API`- write less do more - `high-level`](https://gitlab.com/vasille-js/vasille-less/-/blob/v2/pages/Vasille-Less-Library-API.md)
42
- * [`Vasille Magic API`- compiler writes for you - `highest-level`](https://gitlab.com/vasille-js/vasille-magic/-/blob/master/pages/Vasille-Magic-API.md)
43
-
44
- ### Getting ready be example
45
- * [TypeScript Example](https://gitlab.com/vasille-js/learning/vasille-ts-example)
46
- * [JavaScript Example (Vasille Magic not supported)](https://gitlab.com/vasille-js/learning/vasille-js-example)
47
- * [Flow.js Example (Vasille Magic not supported)](https://gitlab.com/vasille-js/learning/vasille-flow-js-example)
48
-
49
- <hr>
50
-
51
- ## How SAFE is Vasille
52
-
53
- The safe of your application is ensured by
54
- * `100%` coverage of `vasille` code by unit tests.
55
- Each function, each branch are working as designed.
56
- * `strong typing` makes your javascript/typescript code safe as C++ code.
57
- All entities of `vasille` core library are strong typed, including:
58
- * data fields & properties.
59
- * computed properties (function parameters & result).
60
- * methods.
61
- * events (defined handlers & event emit).
62
- * DOM events & DOM operation (attributing, styling, etc.).
63
- * slots of component.
64
- * references to children.
65
- * What you write is what you get - there is no hidden operations, you can control everything.
66
- * No asynchronous code, when the line of code is executed, the DOM and reactive things are already synced.
67
-
68
- ## How FAST is Vasille
69
-
70
- The test project was coded using the next frameworks:
71
- * Angular /
72
- [Try Initial](https://vasille-js.gitlab.io/project-x32/angular/) /
73
- [Try Optimized](https://vasille-js.gitlab.io/project-x32-if/angular/).
74
- * React /
75
- [Try Initial](https://vasille-js.gitlab.io/project-x32/react/) /
76
- [Try Optimized](https://vasille-js.gitlab.io/project-x32-if/react/).
77
- * Vue 2 /
78
- [Try Initial](https://vasille-js.gitlab.io/project-x32/vue-2/) /
79
- [Try Optimized](https://vasille-js.gitlab.io/project-x32-if/vue-2/).
80
- * Vue 3 /
81
- [Try Initial](https://vasille-js.gitlab.io/project-x32/vue-3/) /
82
- [Try Optimized](https://vasille-js.gitlab.io/project-x32-if/vue-3/).
83
- * Svelte /
84
- [Try Initial](https://vasille-js.gitlab.io/project-x32/svelte/) /
85
- [Try Optimized](https://vasille-js.gitlab.io/project-x32-if/svelte/).
86
- * Vasille /
87
- [Try Initial](https://vasille-js.gitlab.io/project-x32/vasille-js/) /
88
- [Try Optimized](https://vasille-js.gitlab.io/project-x32-if/vasille-js/).
89
-
90
- The result of test are demonstrated in figures 1 & 2.
91
- The test result are measured in FPS (frames per second), which is calculated as `1000 / ft`,
92
- where `ft` is an average frame time in ms of 20 frames. All values are absolute. Higher is better.
93
-
94
- The initial version is updating all the page content in each frame.
95
- The page reactivity connections are very complex, and we get poor results in Angular, React, Vue & Svelte.
96
-
97
- The optimized version disables the offscreen & non-actual content, which simplifies the
98
- reactivity complexity in time. Angular & Svelte give result similar to Vasille.
99
- React & Vue continue to be slow in the beginning of test.
100
-
101
- **Conclusion:** The reactivity system of Vasille is very fast
102
- and its complexity is not slowing down the application.
103
-
104
- <hr>
105
-
106
- &nbsp;
107
-
108
- Figure 1: Initial version
109
-
110
- ![results 1](https://gitlab.com/vasille-js/vasille-js/-/raw/v2/img/scores-wo.png)
111
-
112
- <hr>
113
-
114
- &nbsp;
115
-
116
- Figure 2: Optimized version
117
-
118
- ![results 2](https://gitlab.com/vasille-js/vasille-js/-/raw/v2/img/scores-o.png)
119
-
120
- <hr>
121
-
122
- ## How POWERFUL is Vasille
123
-
124
- The secret of `Vasille` is a good task decomposition. The core library is composed of
125
- an effective reactive module and a DOM generation engine based on it.
126
-
127
- <hr>
128
-
129
- ### Reactivity Module
130
-
131
- Reactivity module is used to create a model of data. It can contain self-updating values,
132
- forward-only shared data. Reactivity of objects/fields can be disabled/enabled manually.
133
-
134
- ![Reactivity Module](https://gitlab.com/vasille-js/vasille-js/-/raw/v2/img/reactive.png)
135
-
136
- * `Destroyable` is an entity which has a custom destructor.
137
- * `IValue<T>` is a common interface for any value container, with next members:
138
- * `get $` gets the encapsulated value.
139
- * `set $` manually update the encapsulated value, if enabled triggers updating of all linked data.
140
- * `disable` disables the reactivity.
141
- * `enable` enables the reactivity and triggers updating of all linked data.
142
- * `Reference<T>` contains a value of type `T`.
143
- * `Mirror<T>` syncs self value with another `IValue` container, can be used to share a value forward-only.
144
- * `Pointer<T>` same as `Mirror`, but it can switch between `IValue` target anytime.
145
- * `Expression<ReturnType, Args...>` is a self-updating value.
146
- * `Reactive` is a reactive object which can have multiple reactive fields, emit/receive events/signals.
147
-
148
- <hr>
149
-
150
- ### DOM Generation Engine
151
-
152
- DOM Generation Engine is used to describe a virtual DOM of reactive fragments,
153
- which will be reflected into a browser DOM and keep up to date it.
154
-
155
- ![DOM Generation Engine](https://gitlab.com/vasille-js/vasille-js/-/raw/v2/img/nodes.png)
156
-
157
- * `Fragment` describes a virtual DOM node, which has siblings, children, parent & slots.
158
- * `TextNode` reflects a `Text` node.
159
- * `INode` reflects a `Element` node.
160
- * `Tag` reflect a self created `Element` node.
161
- * `Extension` reflects an existing `Element` node.
162
- * `Component` reflects a `Element` node created by a `Tag` child.
163
- * `AppNode` is root of a `Vasille` application, can be used to create applications in application.
164
- * `App` is root of a definitive `Vasille` application.
165
- * `DebugNode` reflects a `Comment` node, useful for debug.
166
- * `Watch` recompose children nodes on model value change.
167
- * `RepeatNode` creates multiples children nodes using the same code multiple time.
168
- * `BaseView` represent a view in context of MVC (Model-View-Controller).
169
- * `ObjectView` repeats slot content for each value of `ObjectModel`.
170
- * `MapView` repeats slot content for each `MapModel` value.
171
- * `SetView` repeats slot content for each `SetModel` value.
172
- * `ArrayView` repeats slot content for each `ArrayModel` value respecting its order.
173
-
174
- <hr>
175
-
176
- ### CDN
177
-
178
- ```html
179
- ES2015 version
180
- <script src="https://unpkg.com/vasille"></script>
181
- ES5 Compatible version
182
- <script src="https://unpkg.com/vasille/cdn/es5.js"></script>
183
- ```
184
-
185
- ### Flow.js typedef
186
- Add the next lines to `[libs]` section in your `.flowconfig` file
187
- ```
188
- node_modules/vasille/flow-typed
189
- node_modules/vasille-less/flow-typed
190
- node_modules/vasille-magic/flow-typed
191
- ```
192
-
193
- ## Best Practices applicable to Vasille Core Library
194
-
195
- * [Reactive Object Practice](https://gitlab.com/vasille-js/vasille-practices/-/blob/main/practices/reactive-object.ts)
196
- * [Application](https://gitlab.com/vasille-js/vasille-practices/-/blob/main/practices/application.ts)
197
- * [Application in Application](https://gitlab.com/vasille-js/vasille-practices/-/blob/main/practices/application-in-application.ts)
198
- * [Signaling](https://gitlab.com/vasille-js/vasille-practices/-/blob/main/practices/signaling.ts)
199
- * [Forward Only Data Exchange](https://gitlab.com/vasille-js/vasille-practices/-/blob/main/practices/forward-only.ts)
200
- * [Absolute, Relative & Auto Values](https://gitlab.com/vasille-js/vasille-practices/-/blob/main/practices/auto-value.ts)
201
- * [Signaling Intercepting](https://gitlab.com/vasille-js/vasille-practices/-/blob/main/practices/singaling-intercepting.ts)
202
- * [Debugging](https://gitlab.com/vasille-js/vasille-practices/-/blob/main/practices/debugging.ts)
203
- * [Fragment vs Component](https://gitlab.com/vasille-js/vasille-practices/-/blob/main/practices/fragment-component.ts)
204
- * [Extensions](https://gitlab.com/vasille-js/vasille-practices/-/blob/main/practices/extension.ts)
205
- * [Model-View-Controller](https://gitlab.com/vasille-js/vasille-practices/-/blob/main/practices/model-view-controller.ts)
206
-
207
- ## Questions
208
-
209
- If you have questions, fell free to contact the maintainer of project:
210
-
211
- * [Author's Email](mailto:lixcode@vivaldi.net)
212
- * [Project Discord Server](https://discord.gg/SNcXNZxz)
213
- * [Author's Telegram](https://t.me/lixcode)
214
- * [Author's VK](https://vk.com/lixcode)
215
-