@misterscan/sesi 1.2.3 → 1.3.2
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/.agents/rules/sesi-must-read.md +116 -0
- package/.agents/workflows/create-sesi-script.md +44 -0
- package/.agents/workflows/fix-sesi-script.md +14 -0
- package/.github/prompts/MakeInSesi.prompt.md +79 -0
- package/README.md +163 -51
- package/bin/sesi.js +196 -38
- package/chatbot/chatbot.html +488 -0
- package/{main → chatbot}/chatbot.sesi +1 -2
- package/chatbot/chatbot_server.py +105 -0
- package/chatbot/sesi_db_chatbot.sesi +278 -0
- package/dist/ai-runtime.js +2 -2
- package/dist/builtins.d.ts.map +1 -1
- package/dist/builtins.js +199 -5
- package/dist/builtins.js.map +1 -1
- package/dist/index.d.ts +12 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +90 -6
- package/dist/index.js.map +1 -1
- package/dist/interpreter.d.ts +21 -2
- package/dist/interpreter.d.ts.map +1 -1
- package/dist/interpreter.js +201 -92
- package/dist/interpreter.js.map +1 -1
- package/dist/lexer.d.ts.map +1 -1
- package/dist/lexer.js +8 -4
- package/dist/lexer.js.map +1 -1
- package/dist/parser.d.ts +1 -0
- package/dist/parser.d.ts.map +1 -1
- package/dist/parser.js +21 -12
- package/dist/parser.js.map +1 -1
- package/dist/sesi.bundled.js +2526 -1487
- package/dist/types.d.ts +14 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +33 -1
- package/dist/types.js.map +1 -1
- package/docs/ARCHITECTURE.md +21 -13
- package/docs/BUILTINS.md +136 -19
- package/docs/CLI.md +200 -0
- package/docs/COMPARISON.md +16 -13
- package/docs/IMAGE_GENERATION.md +13 -14
- package/docs/IMPLEMENTATION_SUMMARY.md +174 -110
- package/docs/QUICKSTART.md +173 -39
- package/docs/README.md +202 -54
- package/docs/{SYSTEMS_REASONING.md → REASONING.md} +115 -120
- package/docs/ROADMAP.md +51 -47
- package/docs/SKILLS.md +73 -98
- package/docs/SPECIFICATION.md +59 -40
- package/examples/03_functions.sesi +30 -1
- package/examples/07_prompts.sesi +27 -3
- package/examples/08_model_call.sesi +6 -4
- package/examples/09_structured_output.sesi +19 -3
- package/examples/10_code_generation.sesi +6 -4
- package/examples/11_memory_conversation.sesi +47 -15
- package/examples/12_classification.sesi +62 -7
- package/examples/13_data_pipeline.sesi +55 -28
- package/examples/14_folder_explainer.sesi +52 -51
- package/examples/15_image_generation.sesi +15 -14
- package/examples/16_modules.sesi +27 -27
- package/examples/19_search_web.sesi +18 -2
- package/examples/20_model_aliases.sesi +22 -0
- package/examples/21_custom_tools.sesi +27 -0
- package/examples/22_reasoning_plus_custom_tools.sesi +19 -0
- package/main/tests/test-args.sesi +7 -0
- package/main/tests/test_args.sesi +7 -0
- package/main/tests/test_general_modules.sesi +127 -0
- package/main/tests/test_grounding.sesi +2 -0
- package/package.json +26 -22
- package/docs/DISTRIBUTED_SYSTEMS.md +0 -71
- package/docs/sesi_ai_chronicles.md +0 -209
- package/main/conversational_classifier_weights.json +0 -45
- package/main/conversational_sentences.json +0 -304
- package/main/epochs.sesi +0 -94
- package/main/gpu_orchestrator.sesi +0 -36
- package/main/hardware_diagnostics.sesi +0 -118
- package/main/inference.sesi +0 -54
- package/main/native_chatbot.sesi +0 -180
- package/main/native_synthesizer.sesi +0 -83
- package/main/nn_personas_trainer.sesi +0 -302
- package/main/nn_responses_trainer.sesi +0 -269
- package/main/nn_sentences_trainer.sesi +0 -330
- package/main/orchestrator.sesi +0 -15
- package/main/personas.json +0 -124
- package/main/personas_classifier_weights.json +0 -45
- package/main/playground.sesi +0 -3
- package/main/predictive_typing.sesi +0 -127
- package/main/query_brain.sesi +0 -45
- package/main/response_classifier_weights.json +0 -45
- package/main/retro_chat.html +0 -239
- package/main/retro_chat_generator.sesi +0 -745
- package/main/sesi_ai.sesi +0 -158
- package/main/sesi_db_chatbot.sesi +0 -280
- package/main/setup_swarm.sesi +0 -5
- package/main/start.sesi +0 -13
- package/main/terminal.log +0 -56
- package/main/terminal_chat.py +0 -385
- package/main/unified_sesi_ai.sesi +0 -334
- package/main/varied_responses.json +0 -304
|
@@ -1,745 +0,0 @@
|
|
|
1
|
-
// Sesi Script: retro_chat_generator.sesi
|
|
2
|
-
// 📻 90s NATIVELY NEURAL-ADAPTIVE CHAT SIMULATOR (V4)
|
|
3
|
-
// Embeds trained response classifier synapses to run live neural inference!
|
|
4
|
-
// Characters dynamically classify each other's topics and adapt their speech brains in real-time!
|
|
5
|
-
|
|
6
|
-
print "=================================================="
|
|
7
|
-
print "📻 INITIATING NATIVE NEURAL CHATWAY SIMULATOR (V4)..."
|
|
8
|
-
print "=================================================="
|
|
9
|
-
|
|
10
|
-
// Genius integer floor function
|
|
11
|
-
fn floor(x) {
|
|
12
|
-
let s = str(x)
|
|
13
|
-
let parts = split(s, ".")
|
|
14
|
-
return num(parts[0])
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
// 1. Load Persona Database
|
|
18
|
-
print "📂 Loading character personas..."
|
|
19
|
-
let raw_personas = read_file("main/personas.json")
|
|
20
|
-
let parsed_personas = from_json(raw_personas)
|
|
21
|
-
let personas = parsed_personas["personas"]
|
|
22
|
-
let num_personas = len(personas)
|
|
23
|
-
|
|
24
|
-
// 2. Select two distinct random characters
|
|
25
|
-
let idx_a = floor(random() * num_personas)
|
|
26
|
-
let idx_b = floor(random() * num_personas)
|
|
27
|
-
while idx_b == idx_a {
|
|
28
|
-
idx_b = floor(random() * num_personas)
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
let char_a = personas[idx_a]
|
|
32
|
-
let char_b = personas[idx_b]
|
|
33
|
-
|
|
34
|
-
print "🎯 Character A Selected: " + char_a["name"] + " (Age: " + str(char_a["age"]) + ")"
|
|
35
|
-
print "🎯 Character B Selected: " + char_b["name"] + " (Age: " + str(char_b["age"]) + ")"
|
|
36
|
-
print "--------------------------------------------------"
|
|
37
|
-
|
|
38
|
-
// 3. Load 300 purified responses
|
|
39
|
-
let raw_responses = read_file("main/varied_responses.json")
|
|
40
|
-
let parsed_responses = from_json(raw_responses)
|
|
41
|
-
let responses = parsed_responses["responses"]
|
|
42
|
-
|
|
43
|
-
// 4. Load Calibrated Neural weights
|
|
44
|
-
print "🧠 Loading calibrated 10x3 classifier synapses..."
|
|
45
|
-
let raw_weights = read_file("main/response_classifier_weights.json")
|
|
46
|
-
let parsed_weights = from_json(raw_weights)
|
|
47
|
-
let nn_weights = parsed_weights["weights"]
|
|
48
|
-
let nn_biases = parsed_weights["biases"]
|
|
49
|
-
let vocab = ["synthesizer", "vinyl", "record", "wood", "gears", "clock", "compiler", "framework", "memory", "offline"]
|
|
50
|
-
print "✅ Neural synapses successfully online."
|
|
51
|
-
print "--------------------------------------------------"
|
|
52
|
-
|
|
53
|
-
// Helper to determine persona semantic category
|
|
54
|
-
fn get_persona_category(persona) {
|
|
55
|
-
let p = persona["personality"]
|
|
56
|
-
let t = persona["tone"]
|
|
57
|
-
let combined = p + " " + t
|
|
58
|
-
let words = split(combined, " ")
|
|
59
|
-
let w_len = len(words)
|
|
60
|
-
|
|
61
|
-
let w = 0
|
|
62
|
-
while w < w_len {
|
|
63
|
-
let word = words[w]
|
|
64
|
-
if word == "synthesizer" { return "audio" }
|
|
65
|
-
if word == "vinyl" { return "audio" }
|
|
66
|
-
if word == "record" { return "audio" }
|
|
67
|
-
if word == "music" { return "audio" }
|
|
68
|
-
if word == "audio" { return "audio" }
|
|
69
|
-
if word == "chiptune" { return "audio" }
|
|
70
|
-
|
|
71
|
-
if word == "wood" { return "mechanical" }
|
|
72
|
-
if word == "furniture" { return "mechanical" }
|
|
73
|
-
if word == "watch" { return "mechanical" }
|
|
74
|
-
if word == "clock" { return "mechanical" }
|
|
75
|
-
if word == "gears" { return "mechanical" }
|
|
76
|
-
if word == "Game" { return "mechanical" }
|
|
77
|
-
if word == "Boy" { return "mechanical" }
|
|
78
|
-
if word == "botanist" { return "mechanical" }
|
|
79
|
-
if word == "architect" { return "mechanical" }
|
|
80
|
-
w = w + 1
|
|
81
|
-
}
|
|
82
|
-
return "systems"
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
let cat_a = get_persona_category(char_a)
|
|
86
|
-
let cat_b = get_persona_category(char_b)
|
|
87
|
-
|
|
88
|
-
// 5. Function to compile a custom Markov table for a specific category
|
|
89
|
-
fn compile_markov_for_category(category) {
|
|
90
|
-
let corpus_text = ""
|
|
91
|
-
let start_idx = 0
|
|
92
|
-
let end_idx = 100
|
|
93
|
-
|
|
94
|
-
if category == "mechanical" {
|
|
95
|
-
start_idx = 100
|
|
96
|
-
end_idx = 200
|
|
97
|
-
}
|
|
98
|
-
if category == "systems" {
|
|
99
|
-
start_idx = 200
|
|
100
|
-
end_idx = 300
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
let idx = start_idx
|
|
104
|
-
while idx < end_idx {
|
|
105
|
-
corpus_text = corpus_text + " " + responses[idx]
|
|
106
|
-
idx = idx + 1
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
let words = split(corpus_text, " ")
|
|
110
|
-
let w_len = len(words)
|
|
111
|
-
let table = {}
|
|
112
|
-
|
|
113
|
-
let w_idx = 0
|
|
114
|
-
while w_idx < (w_len - 1) {
|
|
115
|
-
let w1 = words[w_idx]
|
|
116
|
-
let w2 = words[w_idx + 1]
|
|
117
|
-
let key_exists = type(table[w1]) == "array"
|
|
118
|
-
if key_exists == false {
|
|
119
|
-
table[w1] = []
|
|
120
|
-
}
|
|
121
|
-
let list = table[w1]
|
|
122
|
-
push(list, w2)
|
|
123
|
-
w_idx = w_idx + 1
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
let pkg = {}
|
|
127
|
-
pkg["table"] = table
|
|
128
|
-
pkg["words"] = words
|
|
129
|
-
pkg["len"] = w_len
|
|
130
|
-
return pkg
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
// Compile vocabulary brains for all 3 classes dynamically
|
|
134
|
-
let brain_audio = compile_markov_for_category("audio")
|
|
135
|
-
let brain_mech = compile_markov_for_category("mechanical")
|
|
136
|
-
let brain_sys = compile_markov_for_category("systems")
|
|
137
|
-
|
|
138
|
-
// Helper to resolve specific brain reference
|
|
139
|
-
fn get_brain_pkg(category) {
|
|
140
|
-
if category == "audio" { return brain_audio }
|
|
141
|
-
if category == "mechanical" { return brain_mech }
|
|
142
|
-
return brain_sys
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
print "🧠 Concurrently trained all three offline speech classes!"
|
|
146
|
-
print "--------------------------------------------------"
|
|
147
|
-
|
|
148
|
-
// 6. Intelligent terminating sentence walker with Dynamic Repetition Penalty & Bigram Blocking
|
|
149
|
-
fn walk_complete_sentence(brain_pkg, start_word) {
|
|
150
|
-
let table = brain_pkg["table"]
|
|
151
|
-
let words_list = brain_pkg["words"]
|
|
152
|
-
let c_len = brain_pkg["len"]
|
|
153
|
-
|
|
154
|
-
let current_word = start_word
|
|
155
|
-
let sentence = current_word
|
|
156
|
-
|
|
157
|
-
// Track generated word history for sliding-window presence penalties & bigram blocking
|
|
158
|
-
let history = [start_word]
|
|
159
|
-
|
|
160
|
-
let steps = 1
|
|
161
|
-
let max_steps = 30
|
|
162
|
-
|
|
163
|
-
while steps < max_steps {
|
|
164
|
-
let w_len = len(current_word)
|
|
165
|
-
let last_char = current_word[w_len - 1]
|
|
166
|
-
if last_char == "." { return sentence }
|
|
167
|
-
if last_char == "!" { return sentence }
|
|
168
|
-
if last_char == "?" { return sentence }
|
|
169
|
-
|
|
170
|
-
let choices = table[current_word]
|
|
171
|
-
let has_choices = type(choices) == "array"
|
|
172
|
-
|
|
173
|
-
let next_word = ""
|
|
174
|
-
|
|
175
|
-
if has_choices == false {
|
|
176
|
-
// Pick random word from corpus that hasn't been used recently (lookback of 15 words)
|
|
177
|
-
let attempts = 0
|
|
178
|
-
let found_candidate = false
|
|
179
|
-
while attempts < 15 {
|
|
180
|
-
let r_idx = floor(random() * c_len)
|
|
181
|
-
let candidate = words_list[r_idx]
|
|
182
|
-
|
|
183
|
-
let is_repeat = false
|
|
184
|
-
let h_len = len(history)
|
|
185
|
-
let lookback = 15
|
|
186
|
-
if h_len < lookback { lookback = h_len }
|
|
187
|
-
let k = 0
|
|
188
|
-
while k < lookback {
|
|
189
|
-
if history[h_len - 1 - k] == candidate {
|
|
190
|
-
is_repeat = true
|
|
191
|
-
}
|
|
192
|
-
k = k + 1
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
if is_repeat == false {
|
|
196
|
-
next_word = candidate
|
|
197
|
-
found_candidate = true
|
|
198
|
-
attempts = 999 // break
|
|
199
|
-
}
|
|
200
|
-
attempts = attempts + 1
|
|
201
|
-
}
|
|
202
|
-
if found_candidate == false {
|
|
203
|
-
let r_idx = floor(random() * c_len)
|
|
204
|
-
next_word = words_list[r_idx]
|
|
205
|
-
}
|
|
206
|
-
} else {
|
|
207
|
-
let num_choices = len(choices)
|
|
208
|
-
if num_choices == 0 {
|
|
209
|
-
let attempts = 0
|
|
210
|
-
let found_candidate = false
|
|
211
|
-
while attempts < 15 {
|
|
212
|
-
let r_idx = floor(random() * c_len)
|
|
213
|
-
let candidate = words_list[r_idx]
|
|
214
|
-
|
|
215
|
-
let is_repeat = false
|
|
216
|
-
let h_len = len(history)
|
|
217
|
-
let lookback = 15
|
|
218
|
-
if h_len < lookback { lookback = h_len }
|
|
219
|
-
let k = 0
|
|
220
|
-
while k < lookback {
|
|
221
|
-
if history[h_len - 1 - k] == candidate {
|
|
222
|
-
is_repeat = true
|
|
223
|
-
}
|
|
224
|
-
k = k + 1
|
|
225
|
-
}
|
|
226
|
-
if is_repeat == false {
|
|
227
|
-
next_word = candidate
|
|
228
|
-
found_candidate = true
|
|
229
|
-
attempts = 999
|
|
230
|
-
}
|
|
231
|
-
attempts = attempts + 1
|
|
232
|
-
}
|
|
233
|
-
if found_candidate == false {
|
|
234
|
-
let r_idx = floor(random() * c_len)
|
|
235
|
-
next_word = words_list[r_idx]
|
|
236
|
-
}
|
|
237
|
-
} else {
|
|
238
|
-
// Select from bigram choices with repetition penalty & bigram blocking
|
|
239
|
-
let attempts = 0
|
|
240
|
-
let found_candidate = false
|
|
241
|
-
while attempts < 20 {
|
|
242
|
-
let r_idx = floor(random() * num_choices)
|
|
243
|
-
let candidate = choices[r_idx]
|
|
244
|
-
|
|
245
|
-
let is_repeat = false
|
|
246
|
-
let h_len = len(history)
|
|
247
|
-
|
|
248
|
-
// 1. Sliding window lookback (15 words) to avoid duplicates
|
|
249
|
-
let lookback = 15
|
|
250
|
-
if h_len < lookback { lookback = h_len }
|
|
251
|
-
let k = 0
|
|
252
|
-
while k < lookback {
|
|
253
|
-
if history[h_len - 1 - k] == candidate {
|
|
254
|
-
is_repeat = true
|
|
255
|
-
}
|
|
256
|
-
k = k + 1
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
// 2. Strict Bigram Blocking (banning repeated transitions current_word -> candidate)
|
|
260
|
-
if is_repeat == false {
|
|
261
|
-
let b_idx = 0
|
|
262
|
-
while b_idx < (h_len - 1) {
|
|
263
|
-
let p1 = history[b_idx]
|
|
264
|
-
let p2 = history[b_idx + 1]
|
|
265
|
-
if p1 == current_word {
|
|
266
|
-
if p2 == candidate {
|
|
267
|
-
is_repeat = true
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
b_idx = b_idx + 1
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
if is_repeat == false {
|
|
275
|
-
next_word = candidate
|
|
276
|
-
found_candidate = true
|
|
277
|
-
attempts = 999
|
|
278
|
-
}
|
|
279
|
-
attempts = attempts + 1
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
if found_candidate == false {
|
|
283
|
-
// Fallback: Pick a non-repeating choice if possible
|
|
284
|
-
let fallback_idx = floor(random() * num_choices)
|
|
285
|
-
next_word = choices[fallback_idx]
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
push(history, next_word)
|
|
291
|
-
sentence = sentence + " " + next_word
|
|
292
|
-
current_word = next_word
|
|
293
|
-
steps = steps + 1
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
return sentence + "."
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
// 7. Live Neural Inference Engine
|
|
300
|
-
// Runs full forward pass classification inside the Sesi tree-walker!
|
|
301
|
-
fn predict_neural_class(sentence_text) {
|
|
302
|
-
let words = split(sentence_text, " ")
|
|
303
|
-
let w_len = len(words)
|
|
304
|
-
let x = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
|
|
305
|
-
|
|
306
|
-
let v_idx = 0
|
|
307
|
-
while v_idx < 10 {
|
|
308
|
-
let keyword = vocab[v_idx]
|
|
309
|
-
let found = 0.0
|
|
310
|
-
let w = 0
|
|
311
|
-
while w < w_len {
|
|
312
|
-
let raw_word = words[w]
|
|
313
|
-
let word = raw_word
|
|
314
|
-
let w_char_len = len(word)
|
|
315
|
-
if w_char_len > 1 {
|
|
316
|
-
let last_char = word[w_char_len - 1]
|
|
317
|
-
if last_char == "." { word = split(word, ".")[0] }
|
|
318
|
-
if last_char == "!" { word = split(word, "!")[0] }
|
|
319
|
-
if last_char == "?" { word = split(word, "?")[0] }
|
|
320
|
-
if last_char == "," { word = split(word, ",")[0] }
|
|
321
|
-
}
|
|
322
|
-
if word == keyword {
|
|
323
|
-
found = 1.0
|
|
324
|
-
}
|
|
325
|
-
w = w + 1
|
|
326
|
-
}
|
|
327
|
-
x[v_idx] = found
|
|
328
|
-
v_idx = v_idx + 1
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
let max_val = -999.0
|
|
332
|
-
let pred_class = "systems" // Default fallback
|
|
333
|
-
|
|
334
|
-
let c_idx = 0
|
|
335
|
-
while c_idx < 3 {
|
|
336
|
-
let sum = 0.0
|
|
337
|
-
let w_row = nn_weights[c_idx]
|
|
338
|
-
let k = 0
|
|
339
|
-
while k < 10 {
|
|
340
|
-
sum = sum + (x[k] * w_row[k])
|
|
341
|
-
k = k + 1
|
|
342
|
-
}
|
|
343
|
-
let val = sum + nn_biases[c_idx]
|
|
344
|
-
let absVal = val
|
|
345
|
-
if val < 0.0 { absVal = 0.0 - val }
|
|
346
|
-
let act = 0.5 + (0.5 * (val / (1.0 + absVal)))
|
|
347
|
-
|
|
348
|
-
if act > max_val {
|
|
349
|
-
max_val = act
|
|
350
|
-
if c_idx == 0 { pred_class = "audio" }
|
|
351
|
-
if c_idx == 1 { pred_class = "mechanical" }
|
|
352
|
-
if c_idx == 2 { pred_class = "systems" }
|
|
353
|
-
}
|
|
354
|
-
c_idx = c_idx + 1
|
|
355
|
-
}
|
|
356
|
-
return pred_class
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
// 8. Context Seed Ingester aligned to Dynamic Target Brain
|
|
360
|
-
fn get_context_seed(previous_message, target_brain) {
|
|
361
|
-
let table = target_brain["table"]
|
|
362
|
-
let words_list = target_brain["words"]
|
|
363
|
-
let c_len = target_brain["len"]
|
|
364
|
-
|
|
365
|
-
let msg_words = split(previous_message, " ")
|
|
366
|
-
let m_len = len(msg_words)
|
|
367
|
-
let matched = []
|
|
368
|
-
|
|
369
|
-
let w = 0
|
|
370
|
-
while w < m_len {
|
|
371
|
-
let raw_word = msg_words[w]
|
|
372
|
-
let word = raw_word
|
|
373
|
-
let w_char_len = len(word)
|
|
374
|
-
|
|
375
|
-
if w_char_len > 1 {
|
|
376
|
-
let last_char = word[w_char_len - 1]
|
|
377
|
-
if last_char == "." { word = split(word, ".")[0] }
|
|
378
|
-
if last_char == "!" { word = split(word, "!")[0] }
|
|
379
|
-
if last_char == "?" { word = split(word, "?")[0] }
|
|
380
|
-
if last_char == "," { word = split(word, ",")[0] }
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
let exists = type(table[word]) == "array"
|
|
384
|
-
if exists {
|
|
385
|
-
push(matched, word)
|
|
386
|
-
}
|
|
387
|
-
w = w + 1
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
let num_matched = len(matched)
|
|
391
|
-
if num_matched > 0 {
|
|
392
|
-
let r_idx = floor(random() * num_matched)
|
|
393
|
-
return matched[r_idx]
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
let r_idx = floor(random() * c_len)
|
|
397
|
-
return words_list[r_idx]
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
// 9. Generate Neural-Adaptive dialogue!
|
|
401
|
-
print "🤖 Simulating live neural-adaptive dialogue (real-time neural inference)..."
|
|
402
|
-
let chat_lines = []
|
|
403
|
-
let neural_categories = []
|
|
404
|
-
|
|
405
|
-
// Turn 1: Char A starts in their natural class
|
|
406
|
-
let start_1 = "I"
|
|
407
|
-
if cat_a == "systems" { start_1 = "Let's" }
|
|
408
|
-
if cat_a == "mechanical" { start_1 = "It" }
|
|
409
|
-
let brain_1 = get_brain_pkg(cat_a)
|
|
410
|
-
let msg_1 = walk_complete_sentence(brain_1, start_1)
|
|
411
|
-
push(chat_lines, char_a["name"] + ": " + msg_1)
|
|
412
|
-
push(neural_categories, cat_a)
|
|
413
|
-
|
|
414
|
-
// Turn 2: Run neural classification on A's message -> B adapts their brain!
|
|
415
|
-
let neural_topic_1 = predict_neural_class(msg_1)
|
|
416
|
-
print " ➜ Message 1 Neural Classification: [" + neural_topic_1 + "]"
|
|
417
|
-
let brain_2 = get_brain_pkg(neural_topic_1)
|
|
418
|
-
let seed_2 = get_context_seed(msg_1, brain_2)
|
|
419
|
-
let msg_2 = walk_complete_sentence(brain_2, seed_2)
|
|
420
|
-
push(chat_lines, char_b["name"] + ": " + msg_2)
|
|
421
|
-
push(neural_categories, neural_topic_1)
|
|
422
|
-
|
|
423
|
-
// Turn 3: Run neural classification on B's message -> A adapts their brain!
|
|
424
|
-
let neural_topic_2 = predict_neural_class(msg_2)
|
|
425
|
-
print " ➜ Message 2 Neural Classification: [" + neural_topic_2 + "]"
|
|
426
|
-
let brain_3 = get_brain_pkg(neural_topic_2)
|
|
427
|
-
let seed_3 = get_context_seed(msg_2, brain_3)
|
|
428
|
-
let msg_3 = walk_complete_sentence(brain_3, seed_3)
|
|
429
|
-
push(chat_lines, char_a["name"] + ": " + msg_3)
|
|
430
|
-
push(neural_categories, neural_topic_2)
|
|
431
|
-
|
|
432
|
-
// Turn 4: Run neural classification on A's message -> B adapts their brain!
|
|
433
|
-
let neural_topic_3 = predict_neural_class(msg_3)
|
|
434
|
-
print " ➜ Message 3 Neural Classification: [" + neural_topic_3 + "]"
|
|
435
|
-
let brain_4 = get_brain_pkg(neural_topic_3)
|
|
436
|
-
let seed_4 = get_context_seed(msg_3, brain_4)
|
|
437
|
-
let msg_4 = walk_complete_sentence(brain_4, seed_4)
|
|
438
|
-
push(chat_lines, char_b["name"] + ": " + msg_4)
|
|
439
|
-
push(neural_categories, neural_topic_3)
|
|
440
|
-
|
|
441
|
-
// Turn 5: Run neural classification on B's message -> A adapts their brain!
|
|
442
|
-
let neural_topic_4 = predict_neural_class(msg_4)
|
|
443
|
-
print " ➜ Message 4 Neural Classification: [" + neural_topic_4 + "]"
|
|
444
|
-
let brain_5 = get_brain_pkg(neural_topic_4)
|
|
445
|
-
let seed_5 = get_context_seed(msg_4, brain_5)
|
|
446
|
-
let msg_5 = walk_complete_sentence(brain_5, seed_5)
|
|
447
|
-
push(chat_lines, char_a["name"] + ": " + msg_5)
|
|
448
|
-
push(neural_categories, neural_topic_4)
|
|
449
|
-
|
|
450
|
-
// Turn 6: Run neural classification on A's message -> B adapts their brain!
|
|
451
|
-
let neural_topic_5 = predict_neural_class(msg_5)
|
|
452
|
-
print " ➜ Message 5 Neural Classification: [" + neural_topic_5 + "]"
|
|
453
|
-
let brain_6 = get_brain_pkg(neural_topic_5)
|
|
454
|
-
let seed_6 = get_context_seed(msg_5, brain_6)
|
|
455
|
-
let msg_6 = walk_complete_sentence(brain_6, seed_6)
|
|
456
|
-
push(chat_lines, char_b["name"] + ": " + msg_6)
|
|
457
|
-
push(neural_categories, neural_topic_5)
|
|
458
|
-
|
|
459
|
-
print "✅ Neural-Adaptive dialogue generated!"
|
|
460
|
-
print "--------------------------------------------------"
|
|
461
|
-
|
|
462
|
-
// 10. Compile retro 90s HTML Navigator Page
|
|
463
|
-
print "🖥 Compiling retro 90s Netscape Navigator webpage..."
|
|
464
|
-
|
|
465
|
-
let html = "<!DOCTYPE html>\n<html>\n<head>\n"
|
|
466
|
-
html = html + "<title>Netscape Navigator - [Sesi Neural Chatway v2.0]</title>\n"
|
|
467
|
-
html = html + "<style>\n"
|
|
468
|
-
html = html + " body {\n"
|
|
469
|
-
html = html + " background-color: #008080; /* Win95 Teal */\n"
|
|
470
|
-
html = html + " font-family: 'MS Sans Serif', Tahoma, Arial, sans-serif;\n"
|
|
471
|
-
html = html + " color: #000000;\n"
|
|
472
|
-
html = html + " margin: 20px;\n"
|
|
473
|
-
html = html + " }\n"
|
|
474
|
-
html = html + " .netscape-window {\n"
|
|
475
|
-
html = html + " width: 720px;\n"
|
|
476
|
-
html = html + " background-color: #c0c0c0; /* Win95 grey */\n"
|
|
477
|
-
html = html + " border: 3px solid;\n"
|
|
478
|
-
html = html + " border-color: #ffffff #5a5a5a #5a5a5a #ffffff;\n"
|
|
479
|
-
html = html + " box-shadow: 2px 2px 10px rgba(0,0,0,0.5);\n"
|
|
480
|
-
html = html + " margin: 0 auto;\n"
|
|
481
|
-
html = html + " }\n"
|
|
482
|
-
html = html + " .title-bar {\n"
|
|
483
|
-
html = html + " background: linear-gradient(90deg, #000080, #1080d0);\n"
|
|
484
|
-
html = html + " color: #ffffff;\n"
|
|
485
|
-
html = html + " font-weight: bold;\n"
|
|
486
|
-
html = html + " padding: 4px 6px;\n"
|
|
487
|
-
html = html + " display: flex;\n"
|
|
488
|
-
html = html + " justify-content: space-between;\n"
|
|
489
|
-
html = html + " align-items: center;\n"
|
|
490
|
-
html = html + " }\n"
|
|
491
|
-
html = html + " .title-text { font-size: 14px; }\n"
|
|
492
|
-
html = html + " .window-buttons button {\n"
|
|
493
|
-
html = html + " width: 16px;\n"
|
|
494
|
-
html = html + " height: 14px;\n"
|
|
495
|
-
html = html + " font-size: 9px;\n"
|
|
496
|
-
html = html + " font-weight: bold;\n"
|
|
497
|
-
html = html + " background-color: #c0c0c0;\n"
|
|
498
|
-
html = html + " border: 1px solid;\n"
|
|
499
|
-
html = html + " border-color: #ffffff #5a5a5a #5a5a5a #ffffff;\n"
|
|
500
|
-
html = html + " margin-left: 2px;\n"
|
|
501
|
-
html = html + " }\n"
|
|
502
|
-
html = html + " .menu-bar {\n"
|
|
503
|
-
html = html + " background-color: #c0c0c0;\n"
|
|
504
|
-
html = html + " padding: 2px 10px;\n"
|
|
505
|
-
html = html + " border-bottom: 2px solid #808080;\n"
|
|
506
|
-
html = html + " font-size: 12px;\n"
|
|
507
|
-
html = html + " display: flex;\n"
|
|
508
|
-
html = html + " gap: 15px;\n"
|
|
509
|
-
html = html + " }\n"
|
|
510
|
-
html = html + " .menu-item { text-decoration: underline; cursor: pointer; }\n"
|
|
511
|
-
html = html + " .toolbar {\n"
|
|
512
|
-
html = html + " padding: 6px;\n"
|
|
513
|
-
html = html + " background-color: #d8d8d8;\n"
|
|
514
|
-
html = html + " display: flex;\n"
|
|
515
|
-
html = html + " gap: 10px;\n"
|
|
516
|
-
html = html + " border-bottom: 2px solid #808080;\n"
|
|
517
|
-
html = html + " }\n"
|
|
518
|
-
html = html + " .tool-btn {\n"
|
|
519
|
-
html = html + " padding: 3px 8px;\n"
|
|
520
|
-
html = html + " font-size: 12px;\n"
|
|
521
|
-
html = html + " border: 2px solid;\n"
|
|
522
|
-
html = html + " border-color: #ffffff #5a5a5a #5a5a5a #ffffff;\n"
|
|
523
|
-
html = html + " background-color: #c0c0c0;\n"
|
|
524
|
-
html = html + " font-weight: bold;\n"
|
|
525
|
-
html = html + " }\n"
|
|
526
|
-
html = html + " .location-bar {\n"
|
|
527
|
-
html = html + " padding: 6px;\n"
|
|
528
|
-
html = html + " background-color: #c0c0c0;\n"
|
|
529
|
-
html = html + " display: flex;\n"
|
|
530
|
-
html = html + " align-items: center;\n"
|
|
531
|
-
html = html + " gap: 5px;\n"
|
|
532
|
-
html = html + " font-size: 12px;\n"
|
|
533
|
-
html = html + " border-bottom: 2px solid #808080;\n"
|
|
534
|
-
html = html + " }\n"
|
|
535
|
-
html = html + " .location-input {\n"
|
|
536
|
-
html = html + " flex-grow: 1;\n"
|
|
537
|
-
html = html + " background-color: #ffffff;\n"
|
|
538
|
-
html = html + " border: 2px solid #808080;\n"
|
|
539
|
-
html = html + " padding: 2px 4px;\n"
|
|
540
|
-
html = html + " font-family: monospace;\n"
|
|
541
|
-
html = html + " font-size: 12px;\n"
|
|
542
|
-
html = html + " }\n"
|
|
543
|
-
html = html + " .main-content {\n"
|
|
544
|
-
html = html + " background-color: #ffffff;\n"
|
|
545
|
-
html = html + " margin: 10px;\n"
|
|
546
|
-
html = html + " border: 2px inset #ffffff;\n"
|
|
547
|
-
html = html + " padding: 15px;\n"
|
|
548
|
-
html = html + " }\n"
|
|
549
|
-
html = html + " .marquee-ticker {\n"
|
|
550
|
-
html = html + " background-color: #000000;\n"
|
|
551
|
-
html = html + " color: #ff00ff;\n"
|
|
552
|
-
html = html + " font-family: monospace;\n"
|
|
553
|
-
html = html + " padding: 4px;\n"
|
|
554
|
-
html = html + " font-weight: bold;\n"
|
|
555
|
-
html = html + " margin-bottom: 15px;\n"
|
|
556
|
-
html = html + " }\n"
|
|
557
|
-
html = html + " .profile-section {\n"
|
|
558
|
-
html = html + " display: grid;\n"
|
|
559
|
-
html = html + " grid-template-columns: 1fr 1fr;\n"
|
|
560
|
-
html = html + " gap: 15px;\n"
|
|
561
|
-
html = html + " margin-bottom: 20px;\n"
|
|
562
|
-
html = html + " border-bottom: 3px double #808080;\n"
|
|
563
|
-
html = html + " padding-bottom: 15px;\n"
|
|
564
|
-
html = html + " }\n"
|
|
565
|
-
html = html + " .profile-card {\n"
|
|
566
|
-
html = html + " background-color: #e0e0e0;\n"
|
|
567
|
-
html = html + " border: 2px solid;\n"
|
|
568
|
-
html = html + " border-color: #ffffff #808080 #808080 #ffffff;\n"
|
|
569
|
-
html = html + " padding: 10px;\n"
|
|
570
|
-
html = html + " }\n"
|
|
571
|
-
html = html + " .profile-title {\n"
|
|
572
|
-
html = html + " font-weight: bold;\n"
|
|
573
|
-
html = html + " color: #000080;\n"
|
|
574
|
-
html = html + " border-bottom: 1px solid #808080;\n"
|
|
575
|
-
html = html + " margin-bottom: 5px;\n"
|
|
576
|
-
html = html + " font-size: 13px;\n"
|
|
577
|
-
html = html + " }\n"
|
|
578
|
-
html = html + " .profile-detail { font-size: 11px; color: #404040; }\n"
|
|
579
|
-
html = html + " .irc-chat-window {\n"
|
|
580
|
-
html = html + " background-color: #000000;\n"
|
|
581
|
-
html = html + " color: #00ff00;\n"
|
|
582
|
-
html = html + " font-family: 'Courier New', Courier, monospace;\n"
|
|
583
|
-
html = html + " padding: 15px;\n"
|
|
584
|
-
html = html + " height: 340px;\n"
|
|
585
|
-
html = html + " overflow-y: auto;\n"
|
|
586
|
-
html = html + " border: 3px inset #808080;\n"
|
|
587
|
-
html = html + " margin-bottom: 15px;\n"
|
|
588
|
-
html = html + " }\n"
|
|
589
|
-
html = html + " .chat-line {\n"
|
|
590
|
-
html = html + " margin-bottom: 12px;\n"
|
|
591
|
-
html = html + " line-height: 1.4;\n"
|
|
592
|
-
html = html + " }\n"
|
|
593
|
-
html = html + " .prefix-a { color: #00ffff; font-weight: bold; }\n"
|
|
594
|
-
html = html + " .prefix-b { color: #ff00ff; font-weight: bold; }\n"
|
|
595
|
-
html = html + " .neural-tag {\n"
|
|
596
|
-
html = html + " background-color: #333333;\n"
|
|
597
|
-
html = html + " font-size: 9px;\n"
|
|
598
|
-
html = html + " padding: 1px 4px;\n"
|
|
599
|
-
html = html + " border-radius: 3px;\n"
|
|
600
|
-
html = html + " margin-left: 10px;\n"
|
|
601
|
-
html = html + " font-weight: bold;\n"
|
|
602
|
-
html = html + " }\n"
|
|
603
|
-
html = html + " .tag-audio { color: #39ff14; border: 1px solid #39ff14; }\n"
|
|
604
|
-
html = html + " .tag-mech { color: #ffff00; border: 1px solid #ffff00; }\n"
|
|
605
|
-
html = html + " .tag-sys { color: #00ffff; border: 1px solid #00ffff; }\n"
|
|
606
|
-
html = html + " .input-section {\n"
|
|
607
|
-
html = html + " display: flex;\n"
|
|
608
|
-
html = html + " gap: 8px;\n"
|
|
609
|
-
html = html + " align-items: center;\n"
|
|
610
|
-
html = html + " }\n"
|
|
611
|
-
html = html + " .message-input {\n"
|
|
612
|
-
html = html + " flex-grow: 1;\n"
|
|
613
|
-
html = html + " background-color: #e0e0e0;\n"
|
|
614
|
-
html = html + " border: 2px solid #5a5a5a;\n"
|
|
615
|
-
html = html + " padding: 4px;\n"
|
|
616
|
-
html = html + " font-family: monospace;\n"
|
|
617
|
-
html = html + " }\n"
|
|
618
|
-
html = html + " .send-btn {\n"
|
|
619
|
-
html = html + " padding: 4px 15px;\n"
|
|
620
|
-
html = html + " font-weight: bold;\n"
|
|
621
|
-
html = html + " background-color: #c0c0c0;\n"
|
|
622
|
-
html = html + " border: 2px solid;\n"
|
|
623
|
-
html = html + " border-color: #ffffff #5a5a5a #5a5a5a #ffffff;\n"
|
|
624
|
-
html = html + " }\n"
|
|
625
|
-
html = html + " .status-footer {\n"
|
|
626
|
-
html = html + " background-color: #c0c0c0;\n"
|
|
627
|
-
html = html + " padding: 4px 10px;\n"
|
|
628
|
-
html = html + " font-size: 11px;\n"
|
|
629
|
-
html = html + " border-top: 2px solid #808080;\n"
|
|
630
|
-
html = html + " display: flex;\n"
|
|
631
|
-
html = html + " justify-content: space-between;\n"
|
|
632
|
-
html = html + " }\n"
|
|
633
|
-
html = html + "</style>\n"
|
|
634
|
-
html = html + "</head>\n<body>\n"
|
|
635
|
-
|
|
636
|
-
// Window Shell
|
|
637
|
-
html = html + "<div class=\"netscape-window\">\n"
|
|
638
|
-
html = html + " <div class=\"title-bar\">\n"
|
|
639
|
-
html = html + " <div class=\"title-text\">🗖 Netscape Navigator - [Sesi Neural Chatway v2.0]</div>\n"
|
|
640
|
-
html = html + " <div class=\"window-buttons\">\n"
|
|
641
|
-
html = html + " <button>_</button><button>口</button><button>X</button>\n"
|
|
642
|
-
html = html + " </div>\n"
|
|
643
|
-
html = html + " </div>\n"
|
|
644
|
-
|
|
645
|
-
// Menu
|
|
646
|
-
html = html + " <div class=\"menu-bar\">\n"
|
|
647
|
-
html = html + " <div class=\"menu-item\">File</div>\n"
|
|
648
|
-
html = html + " <div class=\"menu-item\">Edit</div>\n"
|
|
649
|
-
html = html + " <div class=\"menu-item\">View</div>\n"
|
|
650
|
-
html = html + " <div class=\"menu-item\">Go</div>\n"
|
|
651
|
-
html = html + " <div class=\"menu-item\">Bookmarks</div>\n"
|
|
652
|
-
html = html + " <div class=\"menu-item\">Options</div>\n"
|
|
653
|
-
html = html + " <div class=\"menu-item\">Help</div>\n"
|
|
654
|
-
html = html + " </div>\n"
|
|
655
|
-
|
|
656
|
-
// Toolbar
|
|
657
|
-
html = html + " <div class=\"toolbar\">\n"
|
|
658
|
-
html = html + " <button class=\"tool-btn\">Back</button>\n"
|
|
659
|
-
html = html + " <button class=\"tool-btn\">Forward</button>\n"
|
|
660
|
-
html = html + " <button class=\"tool-btn\">Home</button>\n"
|
|
661
|
-
html = html + " <button class=\"tool-btn\">Reload</button>\n"
|
|
662
|
-
html = html + " <button class=\"tool-btn\">Images</button>\n"
|
|
663
|
-
html = html + " <button class=\"tool-btn\">Open</button>\n"
|
|
664
|
-
html = html + " <button class=\"tool-btn\">Print</button>\n"
|
|
665
|
-
html = html + " <button class=\"tool-btn\">Stop</button>\n"
|
|
666
|
-
html = html + " </div>\n"
|
|
667
|
-
|
|
668
|
-
// Location
|
|
669
|
-
html = html + " <div class=\"location-bar\">\n"
|
|
670
|
-
html = html + " <span>Netsite:</span>\n"
|
|
671
|
-
html = html + " <input class=\"location-input\" type=\"text\" value=\"http://www.sesi-netscape-chat.net/neural/routed-dialectic-gateway\" readonly>\n"
|
|
672
|
-
html = html + " </div>\n"
|
|
673
|
-
|
|
674
|
-
// Main Content
|
|
675
|
-
html = html + " <div class=\"main-content\">\n"
|
|
676
|
-
html = html + " <div class=\"marquee-ticker\">\n"
|
|
677
|
-
html = html + " <marquee>*** NATIVELY NEURAL-ROUTED DIALECTIC ONLINE *** OFFLINE SYNAPSE DYNAMIC SPEECH BRAIN ACTIVE ***</marquee>\n"
|
|
678
|
-
html = html + " </div>\n"
|
|
679
|
-
|
|
680
|
-
// Profiles
|
|
681
|
-
html = html + " <div class=\"profile-section\">\n"
|
|
682
|
-
html = html + " <div class=\"profile-card\">\n"
|
|
683
|
-
html = html + " <div class=\"profile-title\">🟢 " + char_a["name"] + " (Age: " + str(char_a["age"]) + ") [" + cat_a + " class]</div>\n"
|
|
684
|
-
html = html + " <div class=\"profile-detail\"><b>Personality:</b> " + char_a["personality"] + "</div>\n"
|
|
685
|
-
html = html + " <div class=\"profile-detail\"><b>Conversational Tone:</b> " + char_a["tone"] + "</div>\n"
|
|
686
|
-
html = html + " </div>\n"
|
|
687
|
-
html = html + " <div class=\"profile-card\">\n"
|
|
688
|
-
html = html + " <div class=\"profile-title\">🟣 " + char_b["name"] + " (Age: " + str(char_b["age"]) + ") [" + cat_b + " class]</div>\n"
|
|
689
|
-
html = html + " <div class=\"profile-detail\"><b>Personality:</b> " + char_b["personality"] + "</div>\n"
|
|
690
|
-
html = html + " <div class=\"profile-detail\"><b>Conversational Tone:</b> " + char_b["tone"] + "</div>\n"
|
|
691
|
-
html = html + " </div>\n"
|
|
692
|
-
html = html + " </div>\n"
|
|
693
|
-
|
|
694
|
-
// IRC Chat Window
|
|
695
|
-
html = html + " <div class=\"irc-chat-window\">\n"
|
|
696
|
-
|
|
697
|
-
// Loop and display the generated lines
|
|
698
|
-
let line_idx = 0
|
|
699
|
-
while line_idx < 6 {
|
|
700
|
-
let line = chat_lines[line_idx]
|
|
701
|
-
let topic = neural_categories[line_idx]
|
|
702
|
-
let is_char_a = line_idx % 2 == 0
|
|
703
|
-
|
|
704
|
-
let tag_class = "tag-sys"
|
|
705
|
-
if topic == "audio" { tag_class = "tag-audio" }
|
|
706
|
-
if topic == "mechanical" { tag_class = "tag-mech" }
|
|
707
|
-
|
|
708
|
-
let tag_html = "<span class=\"neural-tag " + tag_class + "\">NEURAL: " + topic + "</span>"
|
|
709
|
-
|
|
710
|
-
if is_char_a {
|
|
711
|
-
let parts = split(line, ": ")
|
|
712
|
-
html = html + " <div class=\"chat-line\"><span class=\"prefix-a\"><" + parts[0] + "></span> " + parts[1] + tag_html + "</div>\n"
|
|
713
|
-
} else {
|
|
714
|
-
let parts = split(line, ": ")
|
|
715
|
-
html = html + " <div class=\"chat-line\"><span class=\"prefix-b\"><" + parts[0] + "></span> " + parts[1] + tag_html + "</div>\n"
|
|
716
|
-
}
|
|
717
|
-
line_idx = line_idx + 1
|
|
718
|
-
}
|
|
719
|
-
|
|
720
|
-
html = html + " </div>\n"
|
|
721
|
-
|
|
722
|
-
// Beveled input section
|
|
723
|
-
html = html + " <div class=\"input-section\">\n"
|
|
724
|
-
html = html + " <input class=\"message-input\" type=\"text\" value=\"Sesi trained neural-network is actively routing...\" disabled>\n"
|
|
725
|
-
html = html + " <button class=\"send-btn\">Send</button>\n"
|
|
726
|
-
html = html + " </div>\n"
|
|
727
|
-
html = html + " </div>\n"
|
|
728
|
-
|
|
729
|
-
// Footer
|
|
730
|
-
html = html + " <div class=\"status-footer\">\n"
|
|
731
|
-
html = html + " <span>Status: Secure Offline Connection Established.</span>\n"
|
|
732
|
-
html = html + " <span>Netscape Navigator 4.0</span>\n"
|
|
733
|
-
html = html + " </div>\n"
|
|
734
|
-
html = html + "</div>\n"
|
|
735
|
-
|
|
736
|
-
html = html + "</body>\n</html>\n"
|
|
737
|
-
|
|
738
|
-
// Write directly to local file system
|
|
739
|
-
print "📂 Writing retro chatroom webpage to main/retro_chat.html..."
|
|
740
|
-
write_file("main/retro_chat.html", html)
|
|
741
|
-
|
|
742
|
-
print "=================================================="
|
|
743
|
-
print "🎉 RETRO PORTAL CREATED SUCCESSFULLY!"
|
|
744
|
-
print "👉 View your generated page at main/retro_chat.html"
|
|
745
|
-
print "=================================================="
|