thoth-markup-lang 11.0.0 โ†’ 12.0.0

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.
Files changed (4) hide show
  1. package/README.md +223 -24
  2. package/engine.php +220 -21
  3. package/package.json +16 -3
  4. package/thoth.js +278 -104
package/README.md CHANGED
@@ -1,43 +1,242 @@
1
- # THOTH: The Sovereign Intelligence Suite (v11.0.0 Pulse Edition)
1
+ # ๐Ÿง  THOTH: The Sovereign Intelligence Suite
2
+ ### v12.0.0 โ€” Sovereign Cloud Edition
2
3
 
3
4
  <p align="center">
4
- <img src="https://img.shields.io/npm/v/thoth-markup-lang?style=for-the-badge&color=06b6d4&logo=npm" alt="NPM Version" />
5
- <img src="https://img.shields.io/badge/Version-11.0.0--Pulse-f59e0b?style=for-the-badge" alt="Pulse Version" />
6
- <img src="https://img.shields.io/badge/Engineered_In-Egypt_๐Ÿ‡ช๐Ÿ‡ฌ-020617?style=for-the-badge&logo=code" alt="Egypt" />
5
+ <img src="https://img.shields.io/npm/v/thoth-markup-lang?style=for-the-badge&color=06b6d4&logo=npm" />
6
+ <img src="https://img.shields.io/badge/Architecture-Sovereign-f59e0b?style=for-the-badge" />
7
+ <img src="https://img.shields.io/badge/Built%20In-Egypt%20๐Ÿ‡ช๐Ÿ‡ฌ-020617?style=for-the-badge" />
7
8
  </p>
8
9
 
9
- **The Binary Wisdom of Web Architecture.** THOTH is a high-performance, sovereign, indentation-based markup language and recursive runtime engine. It eliminates structural noise, removes bracket chaos, and redefines web development through pure, architectural logic.
10
+ <p align="center">
11
+ <b>Not a framework. Not a library. This is a new way to think.</b>
12
+ </p>
13
+
14
+ ---
15
+
16
+ ## โšก What is THOTH?
17
+
18
+ THOTH is an **Asynchronous Reactive Web Engine** built to eliminate the chaos of traditional web development.
19
+
20
+ No closing tags.
21
+ No JS dependency for core logic.
22
+ No unnecessary complexity.
23
+
24
+ Just **pure architecture**.
25
+
26
+ > You donโ€™t write code with THOTHโ€ฆ you *define systems*.
27
+
28
+ ---
29
+
30
+ ## ๐Ÿง  Why THOTH Exists
31
+
32
+ Modern web development is bloated:
33
+ - Too many frameworks
34
+ - Too much boilerplate
35
+ - Too much mental overhead
36
+
37
+ THOTH flips the table:
38
+
39
+ โœ” Indentation instead of tags
40
+ โœ” Native state instead of external stores
41
+ โœ” Built-in routing instead of config hell
42
+ โœ” Direct API binding without JavaScript
43
+
44
+ ---
45
+
46
+ ## ๐Ÿ’Ž Core Features
47
+
48
+ ### โ˜๏ธ Sovereign Cloud Engine
49
+ Fetch APIs natively:
50
+ ```text
51
+ API users="https://jsonplaceholder.typicode.com/users"
52
+ ```
53
+
54
+ ---
55
+
56
+ ### โšก Native State System
57
+ ```text
58
+ State counter: 0
59
+ ```
60
+
61
+ Reactive updates โ€” no re-render hacks.
10
62
 
11
63
  ---
12
64
 
13
- ## ๐Ÿ›๏ธ Architectural Philosophy
65
+ ### ๐ŸŒ Smart SPA Routing
66
+ ```text
67
+ Route "/":
68
+ Route "/dashboard":
69
+ ```
14
70
 
15
- THOTH represents a monumental paradigm shift from "tag-heavy" legacy markup to **Recursive Indentation Logic**. With the release of **v11.0.0 (Pulse Edition)**, the engine introduces an ultra-fast parsing core and Python-style error handling, enforcing absolute structural purity. It requires all sovereign files to declare their identity with the `TYPE THOTH` protocol, ensuring architectural integrity and preventing unauthorized code execution.
71
+ Zero config. Zero libraries.
16
72
 
17
- - **Official Website:** [THOTH Language Portal](https://honeydew-pigeon-679592.hostingersite.com/)
18
- - **Lead Architect:** Engineer Abdelfatah Abdelhamed
73
+ ---
74
+
75
+ ### ๐Ÿ“ Flex Layout Engine
76
+ ```text
77
+ Row gap="20px" align="center":
78
+ Column width="300px":
79
+ ```
80
+
81
+ Responsive by design.
82
+
83
+ ---
84
+
85
+ ### ๐Ÿงฉ Component System
86
+ ```text
87
+ Define Card:
88
+ Box:
89
+ Text: @{{title}}
90
+ ```
91
+
92
+ Reusable. Clean. No duplication.
93
+
94
+ ---
95
+
96
+ ### ๐Ÿ”— Data Binding
97
+ ```text
98
+ Text: @{{name}}
99
+ ```
100
+
101
+ Direct binding. No middle layers.
19
102
 
20
103
  ---
21
104
 
22
- ## ๐Ÿ’Ž Intelligence Suite Features (v11.0.0 Pulse)
105
+ ### ๐Ÿ” Auth Guards
106
+ ```text
107
+ Header Auth="admin":
108
+ ```
23
109
 
24
- * **โšก Ultra-Fast Parser Core [NEW]:** Upgraded O(n) string manipulation algorithms for blazing-fast indentation computation and rendering.
25
- * **๐Ÿž Python-Style Tracebacks [NEW]:** Intelligent error handling that pinpoints exact file, line number, and syntax faults in both Terminal and a Browser Overlay.
26
- * **๐Ÿ›ก๏ธ Strict Identification:** Mandatory `TYPE THOTH` protocol header to ensure uncompromised file sovereignty.
27
- * **๐Ÿ’Ž Zero-Bracket Architecture:** Eliminates opening/closing DOM tags, reducing syntax noise by up to 70%.
28
- * **๐Ÿ”— Recursive Data Binding:** Native integration with JSON flat-file databases using `@{{key}}` syntax.
29
- * **๐Ÿ” Procedural Middleware (Auth Guard):** Secure structural DOM nodes natively using `Auth="role"` attributes.
30
- * **๐Ÿš€ Pulse Dev Server & Live Reload:** Integrated HTTP server with automated browser synchronization and state tracking.
31
- * **๐Ÿ” Advanced Meta SEO Engine:** Automated generation of HTML5 Meta Tags directly from your JSON data context.
32
- * **๐Ÿ“ฆ Scoped Components:** Modular file architecture and management through the `Import:` directive.
33
- * **๐Ÿ’‰ Hybrid Injection:** Native support for scoped `StyleSheet` (Raw CSS) and `Scripting` (Raw JS) inside the `.thoth` environment.
110
+ Security built into structure.
34
111
 
35
112
  ---
36
113
 
37
- ## ๐Ÿš€ Technical Implementation
114
+ ### ๐Ÿž Smart Tracebacks
115
+ Errors actually help you:
38
116
 
39
- ### 1. Global Installation
40
- Install the THOTH Engine globally via NPM to access the sovereign CLI:
117
+ ```text
118
+ File "app.thoth", line 12
119
+ APIError: Failed to fetch data
120
+ ```
121
+
122
+ ---
123
+
124
+ ## ๐Ÿš€ Quick Start
125
+
126
+ ### 1. Install
41
127
 
42
128
  ```bash
43
- npm install -g thoth-markup-lang
129
+ npm install -g thoth-markup-lang
130
+ ```
131
+
132
+ ---
133
+
134
+ ### 2. Create App
135
+
136
+ **app.thoth**
137
+ ```text
138
+ TYPE THOTH
139
+
140
+ Define UserCard:
141
+ Column width="300px":
142
+ Box class="card":
143
+ Sub: @{{name}}
144
+ Text: "Email: @{{email}}"
145
+
146
+ State active_users: 0
147
+
148
+ API users="https://jsonplaceholder.typicode.com/users"
149
+
150
+ Container:
151
+ Route "/":
152
+ Row gap="20px":
153
+ Repeat Over="users":
154
+ UserCard name="@{{name}}", email="@{{email}}"
155
+
156
+ Row:
157
+ Text: "Users: @{{active_users}}"
158
+ Button action="set:active_users=active_users+1": "Ping"
159
+ ```
160
+
161
+ ---
162
+
163
+ ### 3. Run
164
+
165
+ ```bash
166
+ thoth serve app.thoth
167
+ ```
168
+
169
+ ---
170
+
171
+ ### 4. Build
172
+
173
+ ```bash
174
+ thoth build app.thoth
175
+ ```
176
+
177
+ ---
178
+
179
+ ## ๐Ÿ›๏ธ Philosophy
180
+
181
+ THOTH is built on one idea:
182
+
183
+ > **Structure is more important than syntax.**
184
+
185
+ Everything else is noise.
186
+
187
+ ---
188
+
189
+ ## ๐Ÿ”ฅ What Makes THOTH Different?
190
+
191
+ | Traditional Web | THOTH |
192
+ |------|--------|
193
+ | HTML + CSS + JS | One unified system |
194
+ | Manual state | Native state |
195
+ | React/Vue routing | Built-in routing |
196
+ | API via JS | Native API binding |
197
+ | JSX / Templates | Pure indentation |
198
+
199
+ ---
200
+
201
+ ## ๐Ÿงช Example Output
202
+
203
+ From this:
204
+ ```text
205
+ Text: "Hello World"
206
+ ```
207
+
208
+ To clean HTML โ€” instantly.
209
+
210
+ ---
211
+
212
+ ## ๐Ÿ›ก๏ธ Sovereign Rules
213
+
214
+ Every file MUST start with:
215
+
216
+ ```text
217
+ TYPE THOTH
218
+ ```
219
+
220
+ No exceptions.
221
+
222
+ ---
223
+
224
+ ## ๐ŸŒ Vision
225
+
226
+ THOTH is not trying to compete with frameworks.
227
+
228
+ Itโ€™s trying to **replace the need for them**.
229
+
230
+ ---
231
+
232
+ ## ๐Ÿ‘‘ Final Word
233
+
234
+ > โ€œSovereignty is not writing codeโ€ฆ
235
+ > it is controlling how code is written.โ€
236
+
237
+ ---
238
+
239
+ <p align="center">
240
+ <b>Engineered by Abdelfatah Abdelhamed</b><br>
241
+ <i>Cairo, Egypt ๐Ÿ‡ช๐Ÿ‡ฌ</i>
242
+ </p>
package/engine.php CHANGED
@@ -1,15 +1,20 @@
1
1
  <?php
2
2
  /**
3
- * THOTH Sovereign Runtime Engine v11.0 - Pulse Edition
3
+ * THOTH Sovereign Runtime Engine v12.0.0 - The Sovereign Cloud
4
4
  * Architect: Engineer Abdelfatah Abdelhamed ๐Ÿ‡ช๐Ÿ‡ฌ
5
5
  * --------------------------------------------------
6
- * ุงู„ู…ูŠุฒุงุช ุงู„ู…ุฏู…ุฌุฉ (ุงู„ู†ุณุฎุฉ ุงู„ู…ุทูˆุฑุฉ):
6
+ * ุงู„ู…ูŠุฒุงุช ุงู„ู…ุฏู…ุฌุฉ (ุงู„ู†ุณุฎุฉ ุงู„ู†ู‡ุงุฆูŠุฉ):
7
7
  * 1. ุงู„ุชูˆุซูŠู‚ ุงู„ู…ุนู…ุงุฑูŠ: ุฅู„ุฒุงู…ูŠุฉ ูˆุฌูˆุฏ TYPE THOTH ููŠ ุงู„ุณุทุฑ ุงู„ุฃูˆู„.
8
8
  * 2. ู†ุธุงู… Middleware (Auth Guard): ุงู„ุชุญูƒู… ุงู„ูƒุงู…ู„ ููŠ ุตู„ุงุญูŠุงุช ุงู„ูˆุตูˆู„.
9
9
  * 3. ู†ุธุงู… ุงู„ุจูŠุงู†ุงุช ุงู„ุฏูŠู†ุงู…ูŠูƒูŠ: JSON Binding & Recursive Loops.
10
10
  * 4. ู†ุธุงู… Meta SEO ุงู„ุฐูƒูŠ: ุชูˆู„ูŠุฏ ุนู†ุงุตุฑ Meta ุจู†ุงุกู‹ ุนู„ู‰ ุงู„ุจูŠุงู†ุงุช.
11
11
  * 5. Python-Style Traceback: ู…ุชุชุจุน ุฃุฎุทุงุก ุฐูƒูŠ ูŠุญุฏุฏ ุงู„ุณุทุฑ ูˆู†ูˆุน ุงู„ุฎุทุฃ ุจุฏู‚ุฉ.
12
12
  * 6. High-Performance Core: ุชุณุฑูŠุน ุงู„ุชุญู„ูŠู„ ุจุงุณุชุฎุฏุงู… ุฏูˆุงู„ PHP ุงู„ุญุฏูŠุซุฉ.
13
+ * 7. Sovereign Components: ุงู„ู‚ุฏุฑุฉ ุนู„ู‰ ุชุนุฑูŠู ูˆุฅุนุงุฏุฉ ุงุณุชุฎุฏุงู… ุงู„ู…ูƒูˆู†ุงุช.
14
+ * 8. State Management: ุญู‚ู† ู…ุชุบูŠุฑุงุช ุงู„ุญุงู„ุฉ ู„ุฅู†ุดุงุก ูˆุงุฌู‡ุงุช ุชูุงุนู„ูŠุฉ.
15
+ * 9. Layout Engine: ู†ุธุงู… ุดุจูƒุงุช ู…ุฏู…ุฌ (Row / Column) ุจุฎูˆุงุต Flexbox.
16
+ * 10. Smart Routing: ู†ุธุงู… ุชู†ู‚ู„ ุฏุงุฎู„ูŠ ู…ุฏู…ุฌ ู„ุจู†ุงุก ุชุทุจูŠู‚ุงุช SPA.
17
+ * 11. API Fetch Engine [NEW]: ุฌู„ุจ ุงู„ุจูŠุงู†ุงุช ุงู„ุฎุงุฑุฌูŠุฉ ุจุฑู…ุฌูŠุงู‹ ุจุฏูˆู† ูƒุชุงุจุฉ JS.
13
18
  */
14
19
 
15
20
  session_start();
@@ -32,7 +37,8 @@ class ThothEngine {
32
37
  'Header' => 'header', 'Footer' => 'footer', 'Bold' => 'strong',
33
38
  'Link' => 'a', 'Image' => 'img', 'List' => 'ul', 'Item' => 'li',
34
39
  'Button' => 'button', 'Input' => 'input', 'Break' => 'br',
35
- 'Line' => 'hr', 'Layout' => 'main'
40
+ 'Line' => 'hr', 'Layout' => 'main',
41
+ 'Row' => 'div', 'Column' => 'div'
36
42
  ];
37
43
 
38
44
  private $voidTags = ['img', 'br', 'hr', 'input', 'meta', 'link'];
@@ -41,6 +47,9 @@ class ThothEngine {
41
47
  private $devMode = true;
42
48
  private $currentLine = 0;
43
49
  private $currentFile = "";
50
+
51
+ private $components = [];
52
+ private $stateVars = [];
44
53
 
45
54
  /**
46
55
  * ุงู„ู…ุฏุฎู„ ุงู„ุฑุฆูŠุณูŠ ู„ู„ู…ุญุฑูƒ
@@ -60,7 +69,10 @@ class ThothEngine {
60
69
  if ($firstLine !== "TYPE THOTH") {
61
70
  return $this->devErrorOverlay("SyntaxError: Missing Identity Protocol. File must begin with TYPE THOTH.", 1, $lines[0]);
62
71
  }
63
- unset($lines[0]); // ุฅุฒุงู„ุฉ ุณุทุฑ ุงู„ุชุนุฑูŠู ู…ู† ุงู„ู…ุนุงู„ุฌุฉ
72
+ unset($lines[0]);
73
+
74
+ // ุงุณุชุฎุฑุงุฌ ุงู„ู…ุณุงุฑ ุงู„ุญุงู„ูŠ ู„ู†ุธุงู… ุงู„ู€ Routing
75
+ $requestedRoute = isset($_GET['route']) ? '/' . ltrim($_GET['route'], '/') : '/';
64
76
 
65
77
  try {
66
78
  $htmlBody = "";
@@ -73,30 +85,89 @@ class ThothEngine {
73
85
  $repeatBuffer = [];
74
86
  $repeatKey = "";
75
87
  $repeatIndent = 0;
88
+
89
+ $isDefiningComponent = false;
90
+ $currentComponentName = "";
91
+ $componentIndent = 0;
76
92
 
77
93
  foreach ($lines as $index => $line) {
78
94
  $this->currentLine = $index + 1;
79
95
  $trimmed = trim($line);
80
96
 
81
- // ุชุณุฑูŠุน ู…ุนุงู„ุฌุฉ ุงู„ุฃุณุทุฑ ุงู„ูุงุฑุบุฉ ูˆุงู„ุชุนู„ูŠู‚ุงุช ุจุงุณุชุฎุฏุงู… str_starts_with
82
97
  if ($trimmed === "" || str_starts_with($trimmed, '#')) continue;
83
98
 
84
99
  $indent = strlen($line) - strlen(ltrim($line));
85
100
 
86
- // Middleware Guard
101
+ // Guard System
87
102
  if ($skipUntilIndent !== -1) {
88
103
  if ($indent > $skipUntilIndent) continue;
89
104
  else $skipUntilIndent = -1;
90
105
  }
91
106
 
107
+ // --- 1. ุงู„ุชู†ู‚ู„ ุงู„ุฐูƒูŠ (Smart Routing) ---
108
+ if (str_starts_with($trimmed, 'Route "')) {
109
+ preg_match('/Route "([^"]+)"/', $trimmed, $matches);
110
+ $routePath = $matches[1] ?? '';
111
+ if ($routePath !== $requestedRoute) {
112
+ $skipUntilIndent = $indent;
113
+ }
114
+ continue;
115
+ }
116
+
117
+ // --- 2. Middleware ---
92
118
  if (preg_match('/Auth="([^"]+)"/', $trimmed, $matches)) {
93
119
  if (!$this->checkAuth($matches[1])) {
94
120
  $skipUntilIndent = $indent;
95
121
  continue;
96
122
  }
97
123
  }
124
+
125
+ // --- 3. Sovereign Components ---
126
+ if ($isDefiningComponent) {
127
+ if ($indent > $componentIndent) {
128
+ $this->components[$currentComponentName][] = $line;
129
+ continue;
130
+ } else {
131
+ $isDefiningComponent = false;
132
+ }
133
+ }
134
+
135
+ if (str_starts_with($trimmed, 'Define ')) {
136
+ $sep = $this->findSeparator($trimmed);
137
+ if($sep === -1) throw new ThothSyntaxError("ComponentError: Missing ':' in Define statement.", $this->currentLine, $line);
138
+ $currentComponentName = trim(substr($trimmed, 7, $sep - 7));
139
+ $this->components[$currentComponentName] = [];
140
+ $componentIndent = $indent;
141
+ $isDefiningComponent = true;
142
+ continue;
143
+ }
144
+
145
+ // --- 4. State Management ---
146
+ if (str_starts_with($trimmed, 'State ')) {
147
+ $parts = explode(':', substr($trimmed, 6), 2);
148
+ if (count($parts) === 2) {
149
+ $stateKey = trim($parts[0]);
150
+ $stateVal = trim($parts[1]);
151
+ $this->stateVars[$stateKey] = $stateVal;
152
+ } else {
153
+ throw new ThothSyntaxError("StateError: Invalid State syntax. Expected 'State name: value'.", $this->currentLine, $line);
154
+ }
155
+ continue;
156
+ }
157
+
158
+ // --- 5. API Fetch Engine (ุงู„ุฑุจุท ุงู„ุฎุงุฑุฌูŠ ุงู„ุณูŠุงุฏูŠ) ---
159
+ if (str_starts_with($trimmed, 'API ')) {
160
+ if (preg_match('/API\s+([a-zA-Z0-9_]+)="([^"]+)"/', $trimmed, $matches)) {
161
+ $apiKey = $matches[1];
162
+ $apiUrl = $matches[2];
163
+ $this->fetchExternalApi($apiKey, $apiUrl, $this->currentLine, $line);
164
+ } else {
165
+ throw new ThothSyntaxError("APIError: Invalid API syntax. Expected 'API name=\"URL\"'.", $this->currentLine, $line);
166
+ }
167
+ continue;
168
+ }
98
169
 
99
- // Repeat System
170
+ // --- 6. Repeat System ---
100
171
  if ($isRepeatMode) {
101
172
  if ($indent > $repeatIndent) { $repeatBuffer[] = $line; continue; }
102
173
  else { $htmlBody .= $this->processRepeat($repeatKey, $repeatBuffer); $isRepeatMode = false; $repeatBuffer = []; }
@@ -109,7 +180,7 @@ class ThothEngine {
109
180
  $repeatIndent = $indent; $isRepeatMode = true; continue;
110
181
  }
111
182
 
112
- // Components & Data
183
+ // --- 7. DataSource & Imports ---
113
184
  if (str_starts_with($trimmed, 'DataSource:')) { $this->loadData(trim(substr($trimmed, 11))); continue; }
114
185
  if (str_starts_with($trimmed, 'Var ')) { $this->parseVariable($trimmed); continue; }
115
186
  if (str_starts_with($trimmed, 'Import:')) {
@@ -121,24 +192,31 @@ class ThothEngine {
121
192
  $line = $this->resolveDynamicData($line);
122
193
  $trimmed = trim($line);
123
194
 
124
- // Raw Injection (CSS/JS)
195
+ // --- 8. Raw Injection (CSS/JS) ---
125
196
  if ($inRawMode) {
126
197
  if ($indent <= $rawIndent && !empty($trimmed)) { $inRawMode = false; $htmlBody .= "</$rawType>\n"; }
127
198
  else { $htmlBody .= $line . "\n"; continue; }
128
199
  }
129
200
 
130
201
  $sep = $this->findSeparator($trimmed);
131
- if($sep === -1 && !empty($trimmed) && !isset($this->tagMap[explode(' ', $trimmed)[0]]) && !in_array(strtolower(explode(' ', $trimmed)[0]), $this->voidTags) && $cmd !== "StyleSheet" && $cmd !== "Scripting"){
132
- // ุงู„ุฐูƒุงุก ุงู„ุงุตุทู†ุงุนูŠ ู„ุงูƒุชุดุงู ุงู„ุฃุฎุทุงุก ุงู„ู…ุทุจุนูŠุฉ
133
- throw new ThothSyntaxError("ParseError: Invalid syntax or missing separator ':'.", $this->currentLine, $line);
134
- }
135
-
202
+
136
203
  $cmdPart = ($sep !== -1) ? trim(substr($trimmed, 0, $sep)) : $trimmed;
137
204
  $val = ($sep !== -1) ? trim(substr($trimmed, $sep + 1)) : "";
138
205
 
139
206
  $spacePos = strpos($cmdPart, ' ');
140
207
  $cmd = ($spacePos !== false) ? substr($cmdPart, 0, $spacePos) : $cmdPart;
141
208
  $attrs = ($spacePos !== false) ? trim(substr($cmdPart, $spacePos)) : "";
209
+
210
+ // Component Instantiation
211
+ if (isset($this->components[$cmd])) {
212
+ $componentHtml = $this->processComponent($cmd, $attrs, $indent);
213
+ $htmlBody .= $componentHtml;
214
+ continue;
215
+ }
216
+
217
+ if($sep === -1 && !empty($trimmed) && !isset($this->tagMap[explode(' ', $trimmed)[0]]) && !in_array(strtolower(explode(' ', $trimmed)[0]), $this->voidTags) && $cmd !== "StyleSheet" && $cmd !== "Scripting"){
218
+ throw new ThothSyntaxError("ParseError: Invalid syntax or missing separator ':'. Unrecognized command or component '$cmd'.", $this->currentLine, $line);
219
+ }
142
220
 
143
221
  if ($cmd === "StyleSheet" || $cmd === "Scripting") {
144
222
  $inRawMode = true; $rawType = ($cmd === "StyleSheet") ? "style" : "script";
@@ -152,12 +230,38 @@ class ThothEngine {
152
230
  }
153
231
 
154
232
  $tag = isset($this->tagMap[$cmd]) ? $this->tagMap[$cmd] : strtolower($cmd);
233
+
234
+ // --- 9. Layout Engine ---
235
+ $injectedStyle = "";
236
+ if ($cmd === 'Row') {
237
+ $injectedStyle = "display:flex; flex-wrap:wrap;";
238
+ if (preg_match('/gap="([^"]+)"/', $attrs, $m)) $injectedStyle .= " gap:{$m[1]};";
239
+ if (preg_match('/align="([^"]+)"/', $attrs, $m)) $injectedStyle .= " align-items:{$m[1]};";
240
+ $attrs = preg_replace('/(gap|align)="[^"]+"/', '', $attrs);
241
+ } elseif ($cmd === 'Column') {
242
+ $injectedStyle = "display:flex; flex-direction:column;";
243
+ if (preg_match('/width="([^"]+)"/', $attrs, $m)) $injectedStyle .= " flex:0 0 {$m[1]}; max-width:{$m[1]};";
244
+ else $injectedStyle .= " flex:1;";
245
+ $attrs = preg_replace('/width="[^"]+"/', '', $attrs);
246
+ }
247
+
155
248
  $cleanAttrs = preg_replace('/Auth="[^"]+"/', '', $attrs);
156
- $openingTag = "<$tag" . ($cleanAttrs ? " $cleanAttrs" : "") . ">";
249
+ $cleanAttrs = $this->injectStateBindings($tag, $cleanAttrs);
250
+
251
+ if (!empty($injectedStyle)) {
252
+ if (strpos($cleanAttrs, 'style="') !== false) {
253
+ $cleanAttrs = preg_replace('/style="([^"]*)"/', 'style="$1 ' . $injectedStyle . '"', $cleanAttrs);
254
+ } else {
255
+ $cleanAttrs .= ' style="' . trim($injectedStyle) . '"';
256
+ }
257
+ }
258
+
259
+ $openingTag = "<$tag" . ($cleanAttrs ? " " . trim($cleanAttrs) : "") . ">";
157
260
 
158
261
  if (in_array($tag, $this->voidTags)) {
159
262
  $htmlBody .= str_repeat(" ", $indent) . $openingTag . "\n";
160
263
  } elseif ($val !== "") {
264
+ $val = $this->injectStateText($val);
161
265
  $htmlBody .= str_repeat(" ", $indent) . $openingTag . $val . "</$tag>\n";
162
266
  } else {
163
267
  $htmlBody .= str_repeat(" ", $indent) . $openingTag . "\n";
@@ -182,6 +286,31 @@ class ThothEngine {
182
286
  return (isset($_SESSION['user_role']) && $_SESSION['user_role'] === $role);
183
287
  }
184
288
 
289
+ /**
290
+ * ุฏุงู„ุฉ ุฌู„ุจ ุงู„ุจูŠุงู†ุงุช ู…ู† ุงู„ู€ APIs ุงู„ุฎุงุฑุฌูŠุฉ
291
+ */
292
+ private function fetchExternalApi($key, $url, $lineNum, $lineContent) {
293
+ $options = [
294
+ 'http' => [
295
+ 'method' => 'GET',
296
+ 'header' => "User-Agent: THOTH-Sovereign-Engine/12.0\r\n"
297
+ ]
298
+ ];
299
+ $context = stream_context_create($options);
300
+ $response = @file_get_contents($url, false, $context);
301
+
302
+ if ($response === false) {
303
+ throw new ThothSyntaxError("APIError: Failed to fetch external data from '$url'.", $lineNum, $lineContent);
304
+ }
305
+
306
+ $data = json_decode($response, true);
307
+ if ($data === null) {
308
+ throw new ThothSyntaxError("APIParseError: Received invalid JSON response from '$url'.", $lineNum, $lineContent);
309
+ }
310
+
311
+ $this->dataContext[$key] = $data;
312
+ }
313
+
185
314
  private function processRepeat($key, $linesBuffer) {
186
315
  $dataArray = $this->dataContext[$key] ?? [];
187
316
  $output = "";
@@ -193,6 +322,54 @@ class ThothEngine {
193
322
  }
194
323
  return $output;
195
324
  }
325
+
326
+ private function processComponent($componentName, $attrsStr, $baseIndent) {
327
+ $buffer = $this->components[$componentName];
328
+ $output = "";
329
+ preg_match_all('/([a-zA-Z0-9_]+)="([^"]+)"/', $attrsStr, $matches);
330
+ $props = [];
331
+ if(!empty($matches[1])) {
332
+ foreach($matches[1] as $idx => $propName) {
333
+ $props['@'.$propName] = $matches[2][$idx];
334
+ }
335
+ }
336
+
337
+ $subEngine = new ThothEngine();
338
+ $subEngine->dataContext = $this->dataContext;
339
+ $subEngine->variables = array_merge($this->variables, $props);
340
+ $subEngine->tagMap = $this->tagMap;
341
+ $subEngine->voidTags = $this->voidTags;
342
+
343
+ $tempCode = "TYPE THOTH\n";
344
+ foreach($buffer as $l) {
345
+ $tempCode .= str_repeat(" ", $baseIndent) . $l . "\n";
346
+ }
347
+
348
+ $tempFile = tempnam(sys_get_temp_dir(), 'thoth_comp_');
349
+ file_put_contents($tempFile, $tempCode);
350
+ $output = $subEngine->render($tempFile, true);
351
+ unlink($tempFile);
352
+
353
+ return $output;
354
+ }
355
+
356
+ private function injectStateBindings($tag, $attrs) {
357
+ if (preg_match('/action="([^"]+)"/', $attrs, $match)) {
358
+ $action = $match[1];
359
+ $jsAction = "thothState.dispatch('{$action}')";
360
+ $attrs = preg_replace('/action="[^"]+"/', "onclick=\"{$jsAction}\"", $attrs);
361
+ }
362
+ return $attrs;
363
+ }
364
+
365
+ private function injectStateText($text) {
366
+ foreach ($this->stateVars as $key => $val) {
367
+ if (strpos($text, "@{{$key}}") !== false) {
368
+ $text = str_replace("@{{$key}}", "<span data-thoth-state='{$key}'>{$val}</span>", $text);
369
+ }
370
+ }
371
+ return $text;
372
+ }
196
373
 
197
374
  private function resolveDynamicData($text) {
198
375
  $text = str_replace(array_keys($this->variables), array_values($this->variables), $text);
@@ -227,10 +404,6 @@ class ThothEngine {
227
404
  return "<div style='font-family:sans-serif; background:#020617; color:#fff; height:100vh; display:flex; flex-direction:column; align-items:center; justify-content:center;'><h1>$title</h1><p style='color:#06b6d4'>$msg</p></div>";
228
405
  }
229
406
 
230
- /**
231
- * Python-Style Traceback Overlay
232
- * ุชุตู…ูŠู… ู‡ู†ุฏุณูŠ ุฐูƒูŠ ูŠุญุฏุฏ ุงู„ุฎุทุฃ ูˆุงู„ู…ูƒุงู† ูˆุงู„ู…ู„ู ุจุงู„ุชูุตูŠู„
233
- */
234
407
  private function devErrorOverlay($msg, $line, $lineContent = "") {
235
408
  $escapedContent = htmlspecialchars($lineContent);
236
409
  return "
@@ -263,6 +436,32 @@ class ThothEngine {
263
436
  $title = $this->dataContext['site_title'] ?? "THOTH Compiled System";
264
437
  $desc = $this->dataContext['site_desc'] ?? "Architected by Abdelfatah Abdelhamed";
265
438
 
439
+ $stateJson = json_encode($this->stateVars);
440
+ $stateScript = "
441
+ <script>
442
+ // THOTH Frontend State Engine v12.0
443
+ const thothState = {
444
+ data: $stateJson,
445
+ dispatch: function(actionStr) {
446
+ if(actionStr.startsWith('set:')) {
447
+ let logic = actionStr.replace('set:', '').split('=');
448
+ let key = logic[0];
449
+ let expr = logic[1];
450
+ if(expr.includes('+1')) this.data[key] = parseInt(this.data[key]) + 1;
451
+ else if(expr.includes('-1')) this.data[key] = parseInt(this.data[key]) - 1;
452
+ else this.data[key] = expr;
453
+ this.render();
454
+ }
455
+ },
456
+ render: function() {
457
+ document.querySelectorAll('[data-thoth-state]').forEach(el => {
458
+ let key = el.getAttribute('data-thoth-state');
459
+ if(this.data[key] !== undefined) el.innerText = this.data[key];
460
+ });
461
+ }
462
+ };
463
+ </script>";
464
+
266
465
  $liveReload = $this->devMode ? "<script>
267
466
  let lastMod = null;
268
467
  setInterval(async () => {
@@ -279,9 +478,9 @@ class ThothEngine {
279
478
  " <meta charset='UTF-8'>\n" .
280
479
  " <meta name='viewport' content='width=device-width, initial-scale=1.0'>\n" .
281
480
  " <meta name='description' content='$desc'>\n" .
282
- " <meta name='generator' content='THOTH Sovereign Engine 11.0'>\n" .
481
+ " <meta name='generator' content='THOTH Sovereign Engine 12.0.0'>\n" .
283
482
  " <title>$title</title>\n" .
284
- "</head>\n<body>\n$body\n$liveReload</body>\n</html>";
483
+ "</head>\n<body style=\"margin:0; font-family:sans-serif;\">\n$body\n$stateScript\n$liveReload</body>\n</html>";
285
484
  }
286
485
  }
287
486
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "thoth-markup-lang",
3
- "version": "11.0.0",
4
- "description": "THOTH Sovereign Suite (Pulse Edition): A revolutionary indentation-based markup ecosystem featuring Strict File Identification (TYPE THOTH), Python-style tracebacks, recursive JSON data-binding, procedural middleware auth guards, and an ultra-high-performance runtime. Engineered by Engineer Abdelfatah Abdelhamed.",
3
+ "version": "12.0.0",
4
+ "description": "THOTH Sovereign Suite v12.0.0 (The Sovereign Cloud): The ultimate indentation-based reactive web engine. Features native API Fetch Engine, Smart Routing (SPA builder), Native Layouts (Flexbox), Sovereign Components, State Management, Python-style tracebacks, and an ultra-high-performance runtime. Engineered by Engineer Abdelfatah Abdelhamed.",
5
5
  "main": "thoth.js",
6
6
  "bin": {
7
7
  "thoth": "./thoth.js"
@@ -14,13 +14,26 @@
14
14
  "serve": "node thoth.js serve --port 3000 --strict",
15
15
  "validate": "node thoth.js validate --all",
16
16
  "auth-setup": "node thoth.js auth --init",
17
- "version": "echo THOTH v11.0.0 Pulse Edition Sovereign Intelligence Suite"
17
+ "version": "echo THOTH v12.0.0 The Sovereign Cloud Intelligence Suite"
18
18
  },
19
19
  "keywords": [
20
20
  "thoth",
21
21
  "thoth-lang",
22
22
  "markup-language",
23
23
  "sovereign-engine",
24
+ "sovereign-cloud",
25
+ "api-fetch",
26
+ "data-fetching",
27
+ "rest-api",
28
+ "web-engine",
29
+ "smart-routing",
30
+ "spa-builder",
31
+ "layout-engine",
32
+ "flexbox-grid",
33
+ "core-framework",
34
+ "sovereign-components",
35
+ "state-management",
36
+ "reactive-ui",
24
37
  "pulse-edition",
25
38
  "python-style-traceback",
26
39
  "smart-error-handling",
package/thoth.js CHANGED
@@ -1,22 +1,28 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  /**
4
- * THOTH Engine v11.0.0 - Pulse Edition (Sovereign Intelligence Suite)
4
+ * THOTH Engine v12.0.0 - The Sovereign Cloud (Intelligence Suite)
5
5
  * Lead Developer & Architect: Engineer Abdelfatah Abdelhamed ๐Ÿ‡ช๐Ÿ‡ฌ
6
6
  * ------------------------------------------------------------------
7
- * ุงู„ู…ูŠุฒุงุช ุงู„ู…ุฏู…ุฌุฉ:
7
+ * ุงู„ู…ูŠุฒุงุช ุงู„ู…ุฏู…ุฌุฉ (ุงู„ู†ุณุฎุฉ ุงู„ู†ู‡ุงุฆูŠุฉ):
8
8
  * 1. Strict Identification: ุฅู„ุฒุงู…ูŠุฉ ูˆุฌูˆุฏ TYPE THOTH ููŠ ุงู„ุณุทุฑ ุงู„ุฃูˆู„.
9
9
  * 2. Middleware Support: ู†ุธุงู… Auth Guard ุงู„ู…ุชู‚ุฏู… ู„ุชุตููŠุฉ ุงู„ุนู†ุงุตุฑ.
10
10
  * 3. Dynamic Meta Engine: ุชูˆู„ูŠุฏ ูˆุณูˆู… ุงู„ู…ูŠุชุง ุชู„ู‚ุงุฆูŠุงู‹ ู…ู† ุณูŠุงู‚ ุงู„ุจูŠุงู†ุงุช.
11
11
  * 4. Dev Server & Live Reload: ุฎุงุฏู… ู…ุญู„ูŠ ู„ู…ุฑุงู‚ุจุฉ ุงู„ุชุบูŠูŠุฑุงุช ู„ุญุธูŠุงู‹.
12
12
  * 5. Recursive Data Engine: ู†ุธุงู… ุงู„ู€ Loops ูˆุงู„ู€ JSON ูˆุงู„ู€ Variables.
13
13
  * 6. Python-Style Traceback: ู…ุชุชุจุน ุฃุฎุทุงุก ุฐูƒูŠ ูˆุฏู‚ูŠู‚ ุฌุฏุงู‹.
14
- * 7. Ultra-Fast Parser: ุชุณุฑูŠุน ุฎูˆุงุฑุฒู…ูŠุงุช ุงู„ู€ Indentation ูˆุงู„ู€ String manipulation.
14
+ * 7. Ultra-Fast Parser: ุชุณุฑูŠุน ุฎูˆุงุฑุฒู…ูŠุงุช ุงู„ู€ Indentation.
15
+ * 8. Sovereign Components: ุงู„ู‚ุฏุฑุฉ ุนู„ู‰ ุชุนุฑูŠู ูˆุฅุนุงุฏุฉ ุงุณุชุฎุฏุงู… ุงู„ู…ูƒูˆู†ุงุช.
16
+ * 9. State Management: ุญู‚ู† ู…ุชุบูŠุฑุงุช ุงู„ุญุงู„ุฉ ู„ุฅู†ุดุงุก ูˆุงุฌู‡ุงุช ุชูุงุนู„ูŠุฉ.
17
+ * 10. Layout Engine: ู†ุธุงู… ุดุจูƒุงุช ู…ุฏู…ุฌ (Row / Column) ุจุฎูˆุงุต Flexbox.
18
+ * 11. Smart Routing: ู†ุธุงู… ุชู†ู‚ู„ ุฏุงุฎู„ูŠ ู…ุฏู…ุฌ ู„ุจู†ุงุก ุชุทุจูŠู‚ุงุช SPA.
19
+ * 12. API Fetch Engine [NEW]: ู…ุญุฑูƒ ู„ุงุชุฒุงู…ู†ูŠ (Async) ู„ุฌู„ุจ ุจูŠุงู†ุงุช ุงู„ู€ APIs.
15
20
  */
16
21
 
17
22
  const fs = require('fs');
18
23
  const path = require('path');
19
24
  const http = require('http');
25
+ const https = require('https');
20
26
 
21
27
  // --- ูƒู„ุงุณ ุชุชุจุน ุงู„ุฃุฎุทุงุก ุงู„ุฐูƒูŠ (Python-Style Error Traceback) ---
22
28
  class ThothSyntaxError extends Error {
@@ -36,17 +42,17 @@ const TAG_MAP = {
36
42
  'Header': 'header', 'Footer': 'footer', 'Article': 'article', 'Aside': 'aside',
37
43
  'Link': 'a', 'Image': 'img', 'Button': 'button', 'List': 'ul', 'Item': 'li',
38
44
  'Input': 'input', 'Form': 'form', 'Label': 'label', 'Break': 'br', 'Line': 'hr',
39
- 'Main': 'main', 'Layout': 'section'
45
+ 'Main': 'main', 'Layout': 'section',
46
+ 'Row': 'div', 'Column': 'div'
40
47
  };
41
48
 
42
49
  const VOID_ELEMENTS = ['img', 'br', 'hr', 'input', 'meta', 'link'];
43
50
 
44
- // --- ุณูŠุงู‚ ุงู„ุชุดุบูŠู„ ุงู„ุณูŠุงุฏูŠ ---
45
- let dataContext = {};
46
- let config = {
51
+ // --- ุณูŠุงู‚ ุงู„ุชุดุบูŠู„ ุงู„ุณูŠุงุฏูŠ ุงู„ุนุงู… ---
52
+ let globalConfig = {
47
53
  devMode: process.argv.includes('--dev') || process.argv.includes('serve'),
48
54
  port: 3000,
49
- currentUserRole: 'admin', // ุงู„ู‚ูŠู…ุฉ ุงู„ุงูุชุฑุงุถูŠุฉ ู„ู…ุญุงูƒุงุฉ ุงู„ู…ูŠุฏู„ูˆูŠุฑ
55
+ currentUserRole: 'admin',
50
56
  strictMode: true
51
57
  };
52
58
 
@@ -59,25 +65,38 @@ if (!command || (!target && command !== 'serve')) {
59
65
  process.exit(1);
60
66
  }
61
67
 
62
- /**
63
- * ุนุฑุถ ุฅุฑุดุงุฏุงุช ุงู„ุงุณุชุฎุฏุงู… ุงู„ุชู‚ู†ูŠุฉ
64
- */
65
68
  function displayUsage() {
66
69
  const yellow = '\x1b[33m';
67
70
  const cyan = '\x1b[36m';
68
71
  const reset = '\x1b[0m';
69
72
  console.log(yellow + 'โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”' + reset);
70
- console.log('\x1b[1m\x1b[32m THOTH INTELLIGENCE SUITE v11.0.0 (Pulse) \x1b[0m');
73
+ console.log('\x1b[1m\x1b[32m THOTH INTELLIGENCE SUITE v12.0.0 (The Sovereign Cloud) \x1b[0m');
71
74
  console.log(cyan + ' Lead Architect: Engineer Abdelfatah Abdelhamed' + reset);
72
75
  console.log(yellow + 'โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”' + reset);
73
76
  console.log(' Usage:');
74
77
  console.log(' thoth build [file].thoth (Production Compilation)');
75
- console.log(' thoth serve [file].thoth (Live Dev Server + Traceback)');
78
+ console.log(' thoth serve [file].thoth (Live SPA Server + Traceback)');
79
+ }
80
+
81
+ // --- ู…ุญุฑูƒ ุงู„ุงุชุตุงู„ ุงู„ุฎุงุฑุฌูŠ ุงู„ุณูŠุงุฏูŠ (ู…ุชูˆุงูู‚ ู…ุน ูƒู„ ู†ุณุฎ Node) ---
82
+ function fetchJSON(url) {
83
+ return new Promise((resolve, reject) => {
84
+ const client = url.startsWith('https') ? https : http;
85
+ client.get(url, { headers: { 'User-Agent': 'THOTH-Sovereign-Engine/12.0' } }, (res) => {
86
+ let data = '';
87
+ res.on('data', chunk => data += chunk);
88
+ res.on('end', () => {
89
+ if (res.statusCode >= 200 && res.statusCode < 300) {
90
+ try { resolve(JSON.parse(data)); }
91
+ catch (e) { reject(new Error('Invalid JSON response format.')); }
92
+ } else {
93
+ reject(new Error(`HTTP Error: ${res.statusCode}`));
94
+ }
95
+ });
96
+ }).on('error', reject);
97
+ });
76
98
  }
77
99
 
78
- /**
79
- * ู…ุนุงู„ุฌุฉ ุงู„ุจูŠุงู†ุงุช ุงู„ุฏูŠู†ุงู…ูŠูƒูŠุฉ @{{key}} ูˆ @Variable (Fast Regex)
80
- */
81
100
  const DATA_REGEX = /@\{\{([^}]+)\}\}/g;
82
101
  function resolveData(text, context, variables = {}) {
83
102
  let resolved = text;
@@ -90,54 +109,138 @@ function resolveData(text, context, variables = {}) {
90
109
  });
91
110
  }
92
111
 
93
- /**
94
- * ู…ุญุฑูƒ ุงู„ุชุฌู…ูŠุน ุงู„ู…ุนู…ุงุฑูŠ (ุงู„ู…ุณุฑุน)
95
- */
96
- function compileThoth(inputPath, isDev = false) {
97
- if (!fs.existsSync(inputPath)) {
98
- throw new ThothSyntaxError(`Source Integrity Error: File not found.`, 0, "", inputPath);
112
+ function injectStateText(text, stateVars) {
113
+ let processedText = text;
114
+ for (const [key, val] of Object.entries(stateVars)) {
115
+ const token = `@{{${key}}}`;
116
+ if (processedText.includes(token)) {
117
+ processedText = processedText.replace(new RegExp(token, 'g'), `<span data-thoth-state="${key}">${val}</span>`);
118
+ }
99
119
  }
120
+ return processedText;
121
+ }
100
122
 
101
- const source = fs.readFileSync(inputPath, 'utf8');
102
- const lines = source.split(/\r?\n/);
123
+ function injectStateBindings(attrs) {
124
+ const match = attrs.match(/action="([^"]+)"/);
125
+ if (match) {
126
+ const actionStr = match[1];
127
+ const jsAction = `thothState.dispatch('${actionStr}')`;
128
+ return attrs.replace(/action="[^"]+"/, `onclick="${jsAction}"`);
129
+ }
130
+ return attrs;
131
+ }
132
+
133
+ /**
134
+ * ุงู„ู…ุญุฑูƒ ุงู„ุฃุณุงุณูŠ (ุชุญูˆู„ ุฅู„ู‰ Async/Await ู„ุฏุนู… ุงู„ุณุญุงุจุฉ ุงู„ุณูŠุงุฏูŠุฉ)
135
+ */
136
+ async function compileThothEngine(sourceContent, inputPath, isDev = false, isSubCall = false, inheritedContext = {}, inheritedComponents = {}, requestedRoute = '/') {
137
+ const lines = sourceContent.split(/\r?\n/);
103
138
 
104
- // --- ุงู„ุชุญู‚ู‚ ู…ู† ุดุฑุท ุงู„ุณูŠุงุฏุฉ ุงู„ุฃูˆู„ ---
105
139
  if (lines[0].trim() !== "TYPE THOTH") {
106
- throw new ThothSyntaxError("Architectural Identity Error: Missing 'TYPE THOTH' protocol to ensure sovereignty.", 1, lines[0], inputPath);
140
+ throw new ThothSyntaxError("Architectural Identity Error: Missing 'TYPE THOTH' protocol.", 1, lines[0], inputPath);
107
141
  }
108
142
 
109
143
  let htmlContent = "";
110
144
  let stack = [];
111
- let variables = {};
145
+
146
+ let dataContext = { ...inheritedContext.dataContext };
147
+ let variables = { ...inheritedContext.variables };
148
+ let stateVars = { ...inheritedContext.stateVars };
149
+ let componentsContext = { ...inheritedComponents };
150
+
112
151
  let rawScope = { active: false, type: '', indent: 0 };
113
152
  let skipIndent = -1;
114
153
  let repeatScope = { active: false, key: '', indent: 0, buffer: [] };
154
+
155
+ let componentScope = { active: false, name: '', indent: 0, buffer: [] };
115
156
 
116
157
  for (let i = 1; i < lines.length; i++) {
117
158
  const lineNum = i + 1;
118
159
  let line = lines[i];
119
160
 
120
- // ุชุณุฑูŠุน ุงูƒุชุดุงู ุงู„ู…ุณุงูุงุช (ุฃุณุฑุน ู…ู† Regex search)
121
161
  const trimmed = line.trimStart();
122
162
  if (!trimmed || trimmed.startsWith('#')) continue;
123
163
  const indent = line.length - trimmed.length;
124
164
  const fullyTrimmed = trimmed.trimEnd();
125
165
 
126
- // --- 1. Middleware / Auth Guard ---
127
166
  if (skipIndent !== -1) {
128
167
  if (indent > skipIndent) continue;
129
168
  else skipIndent = -1;
130
169
  }
131
170
 
171
+ // --- 1. ุงู„ุชู†ู‚ู„ ุงู„ุฐูƒูŠ (Smart Routing) ---
172
+ if (fullyTrimmed.startsWith('Route "')) {
173
+ const match = fullyTrimmed.match(/Route "([^"]+)"/);
174
+ const routePath = match ? match[1] : '';
175
+ if (routePath !== requestedRoute) {
176
+ skipIndent = indent;
177
+ }
178
+ continue;
179
+ }
180
+
181
+ // --- 2. Middleware / Auth Guard ---
132
182
  const authMatch = fullyTrimmed.match(/Auth="([^"]+)"/);
133
183
  if (authMatch) {
134
- if (authMatch[1] !== config.currentUserRole && authMatch[1] !== 'guest') {
184
+ if (authMatch[1] !== globalConfig.currentUserRole && authMatch[1] !== 'guest') {
135
185
  skipIndent = indent;
136
186
  continue;
137
187
  }
138
188
  }
139
189
 
140
- // --- 2. Repeat Logic (Recursive) ---
190
+ // --- 3. Sovereign Components (Define) ---
191
+ if (componentScope.active) {
192
+ if (indent > componentScope.indent) {
193
+ componentScope.buffer.push(line);
194
+ continue;
195
+ } else {
196
+ componentsContext[componentScope.name] = [...componentScope.buffer];
197
+ componentScope.active = false;
198
+ componentScope.buffer = [];
199
+ }
200
+ }
201
+
202
+ if (fullyTrimmed.startsWith('Define ')) {
203
+ const colonIdx = fullyTrimmed.indexOf(':');
204
+ if (colonIdx === -1) throw new ThothSyntaxError("ComponentError: Missing ':' in Define statement.", lineNum, line, inputPath);
205
+ const compName = fullyTrimmed.substring(7, colonIdx).trim();
206
+ componentScope.name = compName;
207
+ componentScope.active = true;
208
+ componentScope.indent = indent;
209
+ continue;
210
+ }
211
+
212
+ // --- 4. State Management ---
213
+ if (fullyTrimmed.startsWith('State ')) {
214
+ const colonIdx = fullyTrimmed.indexOf(':');
215
+ if (colonIdx !== -1) {
216
+ const stateKey = fullyTrimmed.substring(6, colonIdx).trim();
217
+ const stateVal = fullyTrimmed.substring(colonIdx + 1).trim();
218
+ stateVars[stateKey] = stateVal;
219
+ variables[`@{{${stateKey}}}`] = stateVal;
220
+ } else {
221
+ throw new ThothSyntaxError(`StateError: Invalid State syntax. Expected 'State name: value'.`, lineNum, line, inputPath);
222
+ }
223
+ continue;
224
+ }
225
+
226
+ // --- 5. API Fetch Engine [NEW] ---
227
+ if (fullyTrimmed.startsWith('API ')) {
228
+ const match = fullyTrimmed.match(/API\s+([a-zA-Z0-9_]+)="([^"]+)"/);
229
+ if (match) {
230
+ const apiKey = match[1];
231
+ const apiUrl = match[2];
232
+ try {
233
+ dataContext[apiKey] = await fetchJSON(apiUrl);
234
+ } catch (err) {
235
+ throw new ThothSyntaxError(`APIError: Failed to fetch external data from '${apiUrl}'. ${err.message}`, lineNum, line, inputPath);
236
+ }
237
+ } else {
238
+ throw new ThothSyntaxError("APIError: Invalid API syntax. Expected 'API name=\"URL\"'.", lineNum, line, inputPath);
239
+ }
240
+ continue;
241
+ }
242
+
243
+ // --- 6. Repeat Logic (Recursive & Async) ---
141
244
  if (repeatScope.active) {
142
245
  if (indent > repeatScope.indent) {
143
246
  repeatScope.buffer.push(line);
@@ -147,9 +250,10 @@ function compileThoth(inputPath, isDev = false) {
147
250
  if(!Array.isArray(list)) {
148
251
  throw new ThothSyntaxError(`DataMappingError: '${repeatScope.key}' is not a valid Array in Context.`, lineNum, line, inputPath);
149
252
  }
150
- list.forEach(item => {
151
- htmlContent += processBuffer(repeatScope.buffer, item, variables, inputPath, lineNum);
152
- });
253
+ for (const item of list) {
254
+ const mergedContext = { dataContext: { ...dataContext, ...item }, variables, stateVars };
255
+ htmlContent += await processBuffer(repeatScope.buffer, mergedContext, componentsContext, inputPath, lineNum, requestedRoute);
256
+ }
153
257
  repeatScope.active = false;
154
258
  repeatScope.buffer = [];
155
259
  }
@@ -164,15 +268,14 @@ function compileThoth(inputPath, isDev = false) {
164
268
  continue;
165
269
  }
166
270
 
167
- // --- 3. Data Ingestion & Variables ---
271
+ // --- 7. DataSource & Variables ---
168
272
  if (fullyTrimmed.startsWith('DataSource:')) {
169
273
  const jsonFileName = fullyTrimmed.split(':')[1].trim();
170
274
  const dPath = path.resolve(path.dirname(inputPath), jsonFileName);
171
- if (!fs.existsSync(dPath)) {
172
- throw new ThothSyntaxError(`MissingDataError: DataSource '${jsonFileName}' not found.`, lineNum, line, inputPath);
173
- }
275
+ if (!fs.existsSync(dPath)) throw new ThothSyntaxError(`MissingDataError: DataSource '${jsonFileName}' not found.`, lineNum, line, inputPath);
174
276
  try {
175
- dataContext = JSON.parse(fs.readFileSync(dPath, 'utf8'));
277
+ const parsedData = JSON.parse(fs.readFileSync(dPath, 'utf8'));
278
+ dataContext = { ...dataContext, ...parsedData };
176
279
  } catch(e) {
177
280
  throw new ThothSyntaxError(`JSONParseError: Invalid JSON format in '${jsonFileName}'.`, lineNum, line, inputPath);
178
281
  }
@@ -182,14 +285,23 @@ function compileThoth(inputPath, isDev = false) {
182
285
  if (fullyTrimmed.startsWith('Var ')) {
183
286
  const vParts = fullyTrimmed.substring(4).split(':');
184
287
  if (vParts.length === 2) variables['@' + vParts[0].trim()] = vParts[1].trim();
185
- else throw new ThothSyntaxError(`VariableError: Invalid Var syntax. Expected 'Var name: value'.`, lineNum, line, inputPath);
288
+ else throw new ThothSyntaxError(`VariableError: Invalid Var syntax.`, lineNum, line, inputPath);
289
+ continue;
290
+ }
291
+
292
+ if (fullyTrimmed.startsWith('Import:')) {
293
+ const importFile = fullyTrimmed.substring(7).trim();
294
+ const importPath = path.resolve(path.dirname(inputPath), importFile);
295
+ if (!fs.existsSync(importPath)) throw new ThothSyntaxError(`ImportError: Module '${importFile}' not found.`, lineNum, line, inputPath);
296
+ const importContent = fs.readFileSync(importPath, 'utf8');
297
+ const subCall = await compileThothEngine(importContent, importPath, false, true, { dataContext, variables, stateVars }, componentsContext, requestedRoute);
298
+ htmlContent += subCall.html;
186
299
  continue;
187
300
  }
188
301
 
189
302
  line = resolveData(line, dataContext, variables);
190
303
  const processedTrimmed = line.trim();
191
304
 
192
- // --- 4. Raw Code Injection (CSS/JS) ---
193
305
  if (rawScope.active) {
194
306
  if (indent <= rawScope.indent && processedTrimmed !== "") {
195
307
  rawScope.active = false;
@@ -200,7 +312,6 @@ function compileThoth(inputPath, isDev = false) {
200
312
  }
201
313
  }
202
314
 
203
- // --- ุฎูˆุงุฑุฒู…ูŠุฉ ุชุญู„ูŠู„ ุงู„ูุตู„ ุงู„ุฐูƒูŠ (Strict Parser) ---
204
315
  let colonIdx = -1;
205
316
  let inQuotes = false;
206
317
  for (let j = 0; j < processedTrimmed.length; j++) {
@@ -213,7 +324,7 @@ function compileThoth(inputPath, isDev = false) {
213
324
 
214
325
  const firstSpace = instr.indexOf(' ');
215
326
  const tagName = firstSpace !== -1 ? instr.substring(0, firstSpace) : instr;
216
- const attrs = firstSpace !== -1 ? instr.substring(firstSpace).trim() : "";
327
+ let attrs = firstSpace !== -1 ? instr.substring(firstSpace).trim() : "";
217
328
 
218
329
  if (tagName === "StyleSheet" || tagName === "Scripting") {
219
330
  rawScope.active = true;
@@ -223,74 +334,134 @@ function compileThoth(inputPath, isDev = false) {
223
334
  continue;
224
335
  }
225
336
 
226
- // ุฅุฏุงุฑุฉ ุงู„ู…ูƒุฏุณ (Stack Indentation)
337
+ // --- 8. Component Instantiation ---
338
+ if (componentsContext[tagName]) {
339
+ let props = {};
340
+ const propMatches = attrs.matchAll(/([a-zA-Z0-9_]+)="([^"]+)"/g);
341
+ for (const match of propMatches) { props[`@${match[1]}`] = match[2]; }
342
+
343
+ let compSource = "TYPE THOTH\n";
344
+ componentsContext[tagName].forEach(l => { compSource += ' '.repeat(indent) + l + '\n'; });
345
+
346
+ const subMergedVars = { ...variables, ...props };
347
+ const subRes = await compileThothEngine(compSource, inputPath, false, true, { dataContext, variables: subMergedVars, stateVars }, componentsContext, requestedRoute);
348
+ htmlContent += subRes.html;
349
+ continue;
350
+ }
351
+
227
352
  while (stack.length > 0 && stack[stack.length - 1].indent >= indent) {
228
353
  htmlContent += `</${stack.pop().name}>\n`;
229
354
  }
230
355
 
231
356
  const tag = TAG_MAP[tagName] || tagName.toLowerCase();
232
- const cleanAttrs = attrs.replace(/Auth="[^"]+"/, '').trim();
357
+
358
+ // --- 9. Layout Engine (Row & Column) ---
359
+ let injectedStyle = "";
360
+ if (tagName === 'Row') {
361
+ injectedStyle = "display:flex; flex-wrap:wrap;";
362
+ const gapMatch = attrs.match(/gap="([^"]+)"/);
363
+ if (gapMatch) injectedStyle += ` gap:${gapMatch[1]};`;
364
+ const alignMatch = attrs.match(/align="([^"]+)"/);
365
+ if (alignMatch) injectedStyle += ` align-items:${alignMatch[1]};`;
366
+ attrs = attrs.replace(/(gap|align)="[^"]+"/g, '');
367
+ } else if (tagName === 'Column') {
368
+ injectedStyle = "display:flex; flex-direction:column;";
369
+ const widthMatch = attrs.match(/width="([^"]+)"/);
370
+ if (widthMatch) injectedStyle += ` flex:0 0 ${widthMatch[1]}; max-width:${widthMatch[1]};`;
371
+ else injectedStyle += " flex:1;";
372
+ attrs = attrs.replace(/width="[^"]+"/g, '');
373
+ }
374
+
375
+ let cleanAttrs = attrs.replace(/Auth="[^"]+"/, '').trim();
376
+ cleanAttrs = injectStateBindings(cleanAttrs);
377
+
378
+ if (injectedStyle !== "") {
379
+ if (cleanAttrs.includes('style="')) cleanAttrs = cleanAttrs.replace(/style="([^"]*)"/, `style="$1 ${injectedStyle.trim()}"`);
380
+ else cleanAttrs += ` style="${injectedStyle.trim()}"`;
381
+ }
382
+
233
383
  const open = `<${tag}${cleanAttrs ? ' ' + cleanAttrs : ''}>`;
234
384
 
235
385
  if (VOID_ELEMENTS.includes(tag)) {
236
386
  htmlContent += ' '.repeat(indent) + open + '\n';
237
387
  } else if (val) {
238
- htmlContent += ' '.repeat(indent) + `${open}${val}</${tag}>\n`;
388
+ const finalVal = injectStateText(val, stateVars);
389
+ htmlContent += ' '.repeat(indent) + `${open}${finalVal}</${tag}>\n`;
239
390
  } else {
240
391
  htmlContent += ' '.repeat(indent) + open + '\n';
241
392
  stack.push({ name: tag, indent: indent });
242
393
  }
243
394
  }
244
395
 
245
- // ุฅุบู„ุงู‚ ุฃูŠ ุชูƒุฑุงุฑ ู…ุชุจู‚ูŠ
396
+ if (componentScope.active) componentsContext[componentScope.name] = [...componentScope.buffer];
246
397
  if (repeatScope.active) {
247
398
  const list = dataContext[repeatScope.key] || [];
248
- list.forEach(item => { htmlContent += processBuffer(repeatScope.buffer, item, variables, inputPath, lines.length); });
399
+ for (const item of list) {
400
+ const mergedContext = { dataContext: { ...dataContext, ...item }, variables, stateVars };
401
+ htmlContent += await processBuffer(repeatScope.buffer, mergedContext, componentsContext, inputPath, lines.length, requestedRoute);
402
+ }
249
403
  }
250
404
 
251
405
  while (stack.length > 0) htmlContent += `</${stack.pop().name}>\n`;
252
406
 
253
- return generateBoilerplate(htmlContent, isDev);
407
+ if (isSubCall) return { html: htmlContent, dataContext, stateVars };
408
+ return generateBoilerplate(htmlContent, dataContext, stateVars, isDev);
409
+ }
410
+
411
+ /**
412
+ * ุฏุงู„ุฉ ุงู„ุชุบู„ูŠู ุงู„ุนุงู…ุฉ
413
+ */
414
+ async function compileThoth(inputPath, isDev = false, requestedRoute = '/') {
415
+ if (!fs.existsSync(inputPath)) throw new ThothSyntaxError(`Source Integrity Error: File not found.`, 0, "", inputPath);
416
+ const source = fs.readFileSync(inputPath, 'utf8');
417
+ const result = await compileThothEngine(source, inputPath, isDev, false, {}, {}, requestedRoute);
418
+ return result.html;
254
419
  }
255
420
 
256
421
  /**
257
422
  * ู…ุนุงู„ุฌุฉ ุงู„ู€ Buffer ุฏุงุฎู„ ุงู„ู€ Loop
258
423
  */
259
- function processBuffer(buffer, item, variables, filePath, baseLineNum) {
260
- let res = "";
261
- let bStack = [];
262
- buffer.forEach((l, idx) => {
263
- const ind = l.length - l.trimStart().length;
264
- let pLine = resolveData(l, item, variables);
265
- const t = pLine.trim();
266
- let cIdx = t.indexOf(':'); // Fast path for loops
267
- let cmdStr = cIdx !== -1 ? t.substring(0, cIdx).trim() : t;
268
- let valStr = cIdx !== -1 ? t.substring(cIdx + 1).trim() : "";
269
-
270
- const space = cmdStr.indexOf(' ');
271
- const tag = TAG_MAP[cmdStr.substring(0, space === -1 ? cmdStr.length : space)] || cmdStr.toLowerCase();
272
-
273
- while (bStack.length > 0 && bStack[bStack.length - 1].indent >= ind) res += `</${bStack.pop().name}>\n`;
274
-
275
- const op = `<${tag}${space !== -1 ? ' ' + cmdStr.substring(space).trim() : ''}>`;
276
- if (VOID_ELEMENTS.includes(tag)) res += ' '.repeat(ind) + op + '\n';
277
- else if (valStr) res += ' '.repeat(ind) + `${op}${valStr}</${tag}>\n`;
278
- else { res += ' '.repeat(ind) + op + '\n'; bStack.push({ name: tag, indent: ind }); }
279
- });
280
- while (bStack.length > 0) res += `</${bStack.pop().name}>\n`;
281
- return res;
424
+ async function processBuffer(buffer, scopeContext, componentsContext, filePath, baseLineNum, requestedRoute) {
425
+ let tempSource = "TYPE THOTH\n";
426
+ buffer.forEach(l => tempSource += l + "\n");
427
+ const res = await compileThothEngine(tempSource, filePath, false, true, scopeContext, componentsContext, requestedRoute);
428
+ return res.html;
282
429
  }
283
430
 
284
431
  /**
285
- * ุชูˆู„ูŠุฏ ู‡ูŠูƒู„ HTML5 ุงู„ู…ุนูŠุงุฑูŠ ู…ุน ุงู„ู€ Meta Tags
432
+ * ุชูˆู„ูŠุฏ ู‡ูŠูƒู„ HTML5 ุงู„ู…ุนูŠุงุฑูŠ
286
433
  */
287
- function generateBoilerplate(content, isDev) {
434
+ function generateBoilerplate(content, dataContext, stateVars, isDev) {
288
435
  const title = dataContext.site_title || "THOTH Sovereign Architecture";
289
436
  const desc = dataContext.site_desc || "Engineered by Abdelfatah Abdelhamed";
437
+ const stateJson = JSON.stringify(stateVars);
290
438
 
439
+ const stateEngineScript = `
440
+ <script>
441
+ const thothState = {
442
+ data: ${stateJson},
443
+ dispatch: function(actionStr) {
444
+ if(actionStr.startsWith('set:')) {
445
+ let logic = actionStr.replace('set:', '').split('=');
446
+ let key = logic[0]; let expr = logic[1];
447
+ if(expr.includes('+1')) this.data[key] = parseInt(this.data[key]) + 1;
448
+ else if(expr.includes('-1')) this.data[key] = parseInt(this.data[key]) - 1;
449
+ else this.data[key] = expr;
450
+ this.render();
451
+ }
452
+ },
453
+ render: function() {
454
+ document.querySelectorAll('[data-thoth-state]').forEach(el => {
455
+ let key = el.getAttribute('data-thoth-state');
456
+ if(this.data[key] !== undefined) el.innerText = this.data[key];
457
+ });
458
+ }
459
+ };
460
+ </script>`;
461
+
291
462
  const liveReload = isDev ? `
292
463
  <script>
293
- console.log('%c THOTH PULSE DEV MODE: ACTIVE ', 'background:#06b6d4;color:#000;font-weight:bold;');
464
+ console.log('%c THOTH CLOUD DEV MODE: ACTIVE ', 'background:#06b6d4;color:#000;font-weight:bold;');
294
465
  let lastMod = null;
295
466
  setInterval(async () => {
296
467
  try {
@@ -302,26 +473,24 @@ function generateBoilerplate(content, isDev) {
302
473
  }, 1500);
303
474
  </script>` : "";
304
475
 
305
- return `<!DOCTYPE html>
476
+ return { html: `<!DOCTYPE html>
306
477
  <html lang="ar" dir="rtl">
307
478
  <head>
308
479
  <meta charset="UTF-8">
309
480
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
310
481
  <meta name="description" content="${desc}">
311
- <meta name="generator" content="THOTH Sovereign Engine v11.0.0">
482
+ <meta name="generator" content="THOTH Sovereign Engine v12.0.0">
312
483
  <meta name="author" content="Engineer Abdelfatah Abdelhamed">
313
484
  <title>${title}</title>
314
485
  </head>
315
- <body style="margin:0; background:#020617; color:#f8fafc;">
486
+ <body style="margin:0; background:#020617; color:#f8fafc; font-family:sans-serif;">
316
487
  ${content}
488
+ ${stateEngineScript}
317
489
  ${liveReload}
318
490
  </body>
319
- </html>`;
491
+ </html>`};
320
492
  }
321
493
 
322
- /**
323
- * ุฏุงู„ุฉ ุชูˆู„ูŠุฏ ูˆุงุฌู‡ุฉ ุชุชุจุน ุงู„ุฃุฎุทุงุก (Browser Overlay)
324
- */
325
494
  function getBrowserTracebackHTML(e) {
326
495
  if (e.name === 'ThothSyntaxError') {
327
496
  const escapedContent = e.lineContent.replace(/</g, '&lt;').replace(/>/g, '&gt;');
@@ -353,12 +522,9 @@ function getBrowserTracebackHTML(e) {
353
522
  </body>`;
354
523
  }
355
524
 
356
- /**
357
- * ุทุจุงุนุฉ ุงู„ุฃุฎุทุงุก ููŠ ุงู„ุชูŠุฑู…ูŠู†ุงู„
358
- */
359
525
  function printTerminalError(e) {
360
526
  if (e.name === 'ThothSyntaxError') {
361
- console.error('\x1b[31m%s\x1b[0m', `\nโš ๏ธ THOTH Traceback (most recent call last):`);
527
+ console.error('\x1b[31m%s\x1b[0m', `\nโš ๏ธ THOTH Traceback:`);
362
528
  console.error('\x1b[90m%s\x1b[0m', ` File "${e.filePath}", line ${e.lineNum}, in <module>`);
363
529
  console.error(` ${e.lineContent}`);
364
530
  console.error('\x1b[31m%s\x1b[0m', ` ^`);
@@ -370,14 +536,17 @@ function printTerminalError(e) {
370
536
 
371
537
  // --- ุทุจู‚ุฉ ุงู„ุชู†ููŠุฐ ---
372
538
  if (command === 'serve') {
373
- const server = http.createServer((req, res) => {
539
+ const server = http.createServer(async (req, res) => {
540
+ if (req.url === '/favicon.ico') { res.writeHead(204); return res.end(); }
541
+
374
542
  try {
375
- const html = compileThoth(target, true);
376
- res.writeHead(200, {
377
- 'Content-Type': 'text/html',
378
- 'Cache-Control': 'no-cache',
379
- 'ETag': Date.now().toString()
380
- });
543
+ const parsedUrl = new URL(req.url, `http://localhost:${globalConfig.port}`);
544
+ const requestedRoute = parsedUrl.pathname;
545
+
546
+ // ุงุณุชุฎุฏุงู… await ุนุดุงู† ุงู„ู…ุญุฑูƒ ูŠู‚ุฏุฑ ูŠุฌู„ุจ ุจูŠุงู†ุงุช ุงู„ู€ API
547
+ const html = await compileThoth(target, true, requestedRoute);
548
+
549
+ res.writeHead(200, { 'Content-Type': 'text/html', 'Cache-Control': 'no-cache', 'ETag': Date.now().toString() });
381
550
  res.end(html);
382
551
  } catch (e) {
383
552
  printTerminalError(e);
@@ -386,20 +555,25 @@ if (command === 'serve') {
386
555
  }
387
556
  });
388
557
 
389
- server.listen(config.port, () => {
558
+ server.listen(globalConfig.port, () => {
390
559
  console.log('\x1b[36m%s\x1b[0m', `โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€`);
391
- console.log(` โœ” SERVER ACTIVE: http://localhost:${config.port}`);
560
+ console.log(` โœ” SERVER ACTIVE: http://localhost:${globalConfig.port}`);
392
561
  console.log(` โœ” ARCHITECTURE: ${target}`);
393
- console.log(` โœ” MODE: Pulse Edition v11.0.0`);
562
+ console.log(` โœ” MODE: The Sovereign Cloud v12.0.0`);
394
563
  console.log('\x1b[36m%s\x1b[0m', `โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€`);
395
564
  });
565
+ } else if (command === 'build') {
566
+ // ุงู„ุชู†ููŠุฐ ุบูŠุฑ ุงู„ู…ุชุฒุงู…ู† ู„ู„ุจู†ุงุก
567
+ (async () => {
568
+ try {
569
+ const out = await compileThoth(target, false);
570
+ fs.writeFileSync(target.replace('.thoth', '.html'), out);
571
+ console.log(`\x1b[32m [SUCCESS] Architecture materialized: ${target.replace('.thoth', '.html')}\x1b[0m`);
572
+ } catch (e) {
573
+ printTerminalError(e);
574
+ process.exit(1);
575
+ }
576
+ })();
396
577
  } else {
397
- try {
398
- const out = compileThoth(target, false);
399
- fs.writeFileSync(target.replace('.thoth', '.html'), out);
400
- console.log(`\x1b[32m [SUCCESS] Architecture materialized: ${target.replace('.thoth', '.html')}\x1b[0m`);
401
- } catch (e) {
402
- printTerminalError(e);
403
- process.exit(1);
404
- }
578
+ displayUsage();
405
579
  }