syntaxmatrix 2.5.5.5__py3-none-any.whl → 2.6.2__py3-none-any.whl
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.
- syntaxmatrix/__init__.py +3 -2
- syntaxmatrix/agentic/agents.py +1220 -169
- syntaxmatrix/agentic/agents_orchestrer.py +326 -0
- syntaxmatrix/agentic/code_tools_registry.py +27 -32
- syntaxmatrix/auth.py +142 -5
- syntaxmatrix/commentary.py +16 -16
- syntaxmatrix/core.py +192 -84
- syntaxmatrix/db.py +460 -4
- syntaxmatrix/{display.py → display_html.py} +2 -6
- syntaxmatrix/gpt_models_latest.py +1 -1
- syntaxmatrix/media/__init__.py +0 -0
- syntaxmatrix/media/media_pixabay.py +277 -0
- syntaxmatrix/models.py +1 -1
- syntaxmatrix/page_builder_defaults.py +183 -0
- syntaxmatrix/page_builder_generation.py +1122 -0
- syntaxmatrix/page_layout_contract.py +644 -0
- syntaxmatrix/page_patch_publish.py +1471 -0
- syntaxmatrix/preface.py +670 -0
- syntaxmatrix/profiles.py +28 -10
- syntaxmatrix/routes.py +1941 -593
- syntaxmatrix/selftest_page_templates.py +360 -0
- syntaxmatrix/settings/client_items.py +28 -0
- syntaxmatrix/settings/model_map.py +1022 -207
- syntaxmatrix/settings/prompts.py +328 -130
- syntaxmatrix/static/assets/hero-default.svg +22 -0
- syntaxmatrix/static/icons/bot-icon.png +0 -0
- syntaxmatrix/static/icons/favicon.png +0 -0
- syntaxmatrix/static/icons/logo.png +0 -0
- syntaxmatrix/static/icons/logo3.png +0 -0
- syntaxmatrix/templates/admin_branding.html +104 -0
- syntaxmatrix/templates/admin_features.html +63 -0
- syntaxmatrix/templates/admin_secretes.html +108 -0
- syntaxmatrix/templates/change_password.html +124 -0
- syntaxmatrix/templates/dashboard.html +296 -131
- syntaxmatrix/templates/dataset_resize.html +535 -0
- syntaxmatrix/templates/edit_page.html +2535 -0
- syntaxmatrix/utils.py +2728 -2835
- {syntaxmatrix-2.5.5.5.dist-info → syntaxmatrix-2.6.2.dist-info}/METADATA +6 -2
- {syntaxmatrix-2.5.5.5.dist-info → syntaxmatrix-2.6.2.dist-info}/RECORD +42 -25
- syntaxmatrix/generate_page.py +0 -634
- syntaxmatrix/static/icons/hero_bg.jpg +0 -0
- {syntaxmatrix-2.5.5.5.dist-info → syntaxmatrix-2.6.2.dist-info}/WHEEL +0 -0
- {syntaxmatrix-2.5.5.5.dist-info → syntaxmatrix-2.6.2.dist-info}/licenses/LICENSE.txt +0 -0
- {syntaxmatrix-2.5.5.5.dist-info → syntaxmatrix-2.6.2.dist-info}/top_level.txt +0 -0
|
@@ -11,52 +11,14 @@
|
|
|
11
11
|
margin: 0;
|
|
12
12
|
padding: 0;
|
|
13
13
|
}
|
|
14
|
-
|
|
15
|
-
position: fixed;
|
|
16
|
-
top: 0; left: 0;
|
|
17
|
-
width: 200px; height: 100vh;
|
|
18
|
-
background: #f1f4f7;
|
|
19
|
-
border-right: 1px solid #ccc;
|
|
20
|
-
padding: 26px 10px 10px 14px;
|
|
21
|
-
box-sizing: border-box;
|
|
22
|
-
overflow-y: auto;
|
|
23
|
-
z-index: 100;
|
|
24
|
-
font-size: clamp(0.95rem, 2vw, 1.09rem);
|
|
25
|
-
}
|
|
26
|
-
.dashboard-sidebar h2 {
|
|
27
|
-
font-size: clamp(1.12rem, 3vw, 1.28rem);
|
|
28
|
-
color: #007acc;
|
|
29
|
-
margin-top: 0;
|
|
30
|
-
margin-bottom: 32px;
|
|
31
|
-
font-weight: bold;
|
|
32
|
-
letter-spacing: 1px;
|
|
33
|
-
}
|
|
34
|
-
.sidebar-links {
|
|
35
|
-
margin-top: 22px;
|
|
36
|
-
}
|
|
37
|
-
.sidebar-links a {
|
|
38
|
-
display: block;
|
|
39
|
-
padding: 12px 10px 12px 0;
|
|
40
|
-
color: #333;
|
|
41
|
-
text-decoration: none;
|
|
42
|
-
font-size: clamp(0.93rem, 2vw, 1.08rem);
|
|
43
|
-
border-radius: 6px;
|
|
44
|
-
margin-bottom: 6px;
|
|
45
|
-
transition: background 0.2s, color 0.2s;
|
|
46
|
-
}
|
|
47
|
-
.sidebar-links a.active,
|
|
48
|
-
.sidebar-links a:hover {
|
|
49
|
-
background: #e0e5ee;
|
|
50
|
-
color: #007acc;
|
|
51
|
-
font-weight: bold;
|
|
52
|
-
}
|
|
14
|
+
|
|
53
15
|
.dashboard-main {
|
|
54
16
|
margin-left: 220px;
|
|
55
17
|
padding: 36px 40px 30px 10px;
|
|
56
18
|
min-height: 100vh;
|
|
57
19
|
box-sizing: border-box;
|
|
58
20
|
overflow-x: auto;
|
|
59
|
-
background: #
|
|
21
|
+
background: #dff0f5ff;
|
|
60
22
|
font-size: clamp(0.98rem, 2vw, 1.07rem);
|
|
61
23
|
}
|
|
62
24
|
.dashboard-tabs {
|
|
@@ -85,7 +47,7 @@
|
|
|
85
47
|
top: 2px;
|
|
86
48
|
}
|
|
87
49
|
.dashboard-content {
|
|
88
|
-
background: #
|
|
50
|
+
background: #bbbbbd;
|
|
89
51
|
width: 100%;
|
|
90
52
|
padding: 10px;
|
|
91
53
|
border-radius: 0 0 10px 10px;
|
|
@@ -95,6 +57,50 @@
|
|
|
95
57
|
overflow-x: auto;
|
|
96
58
|
margin-right: 1vw;
|
|
97
59
|
}
|
|
60
|
+
|
|
61
|
+
textarea#askai{
|
|
62
|
+
background: #e5e5e5cd;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.dashboard-sidebar {
|
|
66
|
+
position: fixed;
|
|
67
|
+
top: 0; left: 0;
|
|
68
|
+
width: 200px; height: 100vh;
|
|
69
|
+
background: #a3a4a5ff;
|
|
70
|
+
border-right: 1px solid #ccc;
|
|
71
|
+
padding: 26px 10px 10px 14px;
|
|
72
|
+
box-sizing: border-box;
|
|
73
|
+
overflow-y: auto;
|
|
74
|
+
z-index: 100;
|
|
75
|
+
font-size: clamp(0.95rem, 2vw, 1.09rem);
|
|
76
|
+
}
|
|
77
|
+
.dashboard-sidebar h2 {
|
|
78
|
+
font-size: clamp(1.12rem, 3vw, 1.28rem);
|
|
79
|
+
color: #007acc;
|
|
80
|
+
margin-top: 0;
|
|
81
|
+
margin-bottom: 32px;
|
|
82
|
+
font-weight: bold;
|
|
83
|
+
letter-spacing: 1px;
|
|
84
|
+
}
|
|
85
|
+
.sidebar-links {
|
|
86
|
+
margin-top: 22px;
|
|
87
|
+
}
|
|
88
|
+
.sidebar-links a {
|
|
89
|
+
display: block;
|
|
90
|
+
padding: 12px 10px 12px 0;
|
|
91
|
+
color: #333;
|
|
92
|
+
text-decoration: none;
|
|
93
|
+
font-size: clamp(0.93rem, 2vw, 1.08rem);
|
|
94
|
+
border-radius: 6px;
|
|
95
|
+
margin-bottom: 6px;
|
|
96
|
+
transition: background 0.2s, color 0.2s;
|
|
97
|
+
}
|
|
98
|
+
.sidebar-links a.active,
|
|
99
|
+
.sidebar-links a:hover {
|
|
100
|
+
background: #e0e5ee;
|
|
101
|
+
color: #007acc;
|
|
102
|
+
font-weight: bold;
|
|
103
|
+
}
|
|
98
104
|
|
|
99
105
|
.smx-table {
|
|
100
106
|
padding: clamp(3px, 1vw, 9px) clamp(4px, 2vw, 13px);
|
|
@@ -156,31 +162,18 @@
|
|
|
156
162
|
padding:0.2rem;
|
|
157
163
|
}
|
|
158
164
|
.del-btn:hover { opacity:0.8; background:red; }
|
|
159
|
-
|
|
160
|
-
/* full-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
width:
|
|
165
|
-
|
|
166
|
-
display:
|
|
165
|
+
|
|
166
|
+
/* Make the Explore Data submit button compact instead of full-width */
|
|
167
|
+
.eda-submit-btn {
|
|
168
|
+
align-self: flex-start; /* stop flex from stretching it to 100% */
|
|
169
|
+
width: auto; /* shrink to content */
|
|
170
|
+
min-width: 7.5rem; /* tweak this if you want it smaller/larger */
|
|
171
|
+
padding: 6px 16px; /* a bit tighter than the global button */
|
|
172
|
+
display: inline-flex;
|
|
167
173
|
align-items: center;
|
|
168
174
|
justify-content: center;
|
|
169
|
-
z-index: 9999;
|
|
170
|
-
}
|
|
171
|
-
/* simple spinner */
|
|
172
|
-
.loader {
|
|
173
|
-
border: 8px solid #eee;
|
|
174
|
-
border-top: 8px solid #333;
|
|
175
|
-
border-radius: 50%;
|
|
176
|
-
width: 60px; height: 60px;
|
|
177
|
-
animation: spin 1s linear infinite;
|
|
178
|
-
}
|
|
179
|
-
@keyframes spin {
|
|
180
|
-
0% { transform: rotate(0deg); }
|
|
181
|
-
100% { transform: rotate(360deg); }
|
|
182
175
|
}
|
|
183
|
-
|
|
176
|
+
|
|
184
177
|
/* --- Mobile fixes --- */
|
|
185
178
|
.dashboard-content img,
|
|
186
179
|
.dashboard-content canvas,
|
|
@@ -206,8 +199,8 @@
|
|
|
206
199
|
.dashboard-sidebar {
|
|
207
200
|
position: fixed !important;
|
|
208
201
|
inset: 0 auto 0 0;
|
|
209
|
-
width:
|
|
210
|
-
max-width:
|
|
202
|
+
width: 48vw !important; /* drawer width */
|
|
203
|
+
max-width: 200px;
|
|
211
204
|
transform: translateX(-100%);
|
|
212
205
|
transition: transform .28s ease;
|
|
213
206
|
z-index: 1000;
|
|
@@ -590,29 +583,150 @@
|
|
|
590
583
|
.eda-card h3{ color: #1f2937 !important; }
|
|
591
584
|
.smx-stat h4{ color: #64748b !important; }
|
|
592
585
|
</style>
|
|
586
|
+
<style>
|
|
587
|
+
div.li li {
|
|
588
|
+
margin-left: 35px;
|
|
589
|
+
}
|
|
590
|
+
/* 1. Style the arrow specifically */
|
|
591
|
+
.toggle-arrow {
|
|
592
|
+
display: inline-block; /* CRITICAL: Allows the element to rotate */
|
|
593
|
+
transition: transform 0.2s; /* Makes the rotation smooth */
|
|
594
|
+
margin-right: 6px; /* Spacing between arrow and text */
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
/* 2. Rotate and color when the menu is OPEN */
|
|
598
|
+
details[open] summary .toggle-arrow {
|
|
599
|
+
transform: rotate(90deg); /* Rotates the arrow downwards */
|
|
600
|
+
color: #007acc; /* Changes color to blue */
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
/* 3. (Optional) Remove default browser markers to avoid double arrows */
|
|
604
|
+
details > summary {
|
|
605
|
+
list-style: none;
|
|
606
|
+
}
|
|
607
|
+
details > summary::-webkit-details-marker {
|
|
608
|
+
display: none;
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
/* Thinking dots that sit inside the Explore Data submit button */
|
|
612
|
+
/* Submit button: keep size constant while swapping text for dots */
|
|
613
|
+
.eda-submit-btn {
|
|
614
|
+
position: relative;
|
|
615
|
+
overflow: hidden;
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
.eda-btn-label {
|
|
619
|
+
display: inline-block;
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
/* Thinking dots overlay, centred in the button */
|
|
623
|
+
.eda-btn-spinner {
|
|
624
|
+
position: absolute;
|
|
625
|
+
top: 50%;
|
|
626
|
+
left: 50%;
|
|
627
|
+
transform: translate(-50%, -50%);
|
|
628
|
+
display: none; /* hidden until loading */
|
|
629
|
+
align-items: center;
|
|
630
|
+
justify-content: center;
|
|
631
|
+
gap: 0.15rem;
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
.eda-btn-spinner .dot {
|
|
635
|
+
width: 0.28rem;
|
|
636
|
+
height: 0.28rem;
|
|
637
|
+
border-radius: 999px;
|
|
638
|
+
background: currentColor;
|
|
639
|
+
opacity: 0.2;
|
|
640
|
+
display: inline-block;
|
|
641
|
+
margin: 0 0.08rem;
|
|
642
|
+
animation: edaBtnDots 1s infinite ease-in-out;
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
.eda-btn-spinner .dot:nth-child(2) {
|
|
646
|
+
animation-delay: 0.15s;
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
.eda-btn-spinner .dot:nth-child(3) {
|
|
650
|
+
animation-delay: 0.30s;
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
/* While loading: keep label in layout, but hide it visually */
|
|
654
|
+
.eda-btn-loading .eda-btn-label {
|
|
655
|
+
visibility: hidden; /* keeps height and width */
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
.eda-btn-loading .eda-btn-spinner {
|
|
659
|
+
display: inline-flex;
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
@keyframes edaBtnDots {
|
|
663
|
+
0%, 60%, 100% {
|
|
664
|
+
opacity: 0.2;
|
|
665
|
+
transform: translateY(0);
|
|
666
|
+
}
|
|
667
|
+
30% {
|
|
668
|
+
opacity: 1;
|
|
669
|
+
transform: translateY(-0.16rem);
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
.sidebar-links {
|
|
674
|
+
margin-top: 22px;
|
|
675
|
+
}
|
|
676
|
+
.sidebar-links a {
|
|
677
|
+
display: block;
|
|
678
|
+
padding: 12px 10px 12px 0;
|
|
679
|
+
color: #333;
|
|
680
|
+
text-decoration: none;
|
|
681
|
+
font-size: clamp(0.93rem, 2vw, 1.08rem);
|
|
682
|
+
border-radius: 6px;
|
|
683
|
+
margin-bottom: 6px;
|
|
684
|
+
transition: background 0.2s, color 0.2s;
|
|
685
|
+
}
|
|
686
|
+
.sidebar-links a.active,
|
|
687
|
+
.sidebar-links a:hover {
|
|
688
|
+
background: #e0e5ee;
|
|
689
|
+
color: #007acc;
|
|
690
|
+
font-weight: bold;
|
|
691
|
+
}
|
|
692
|
+
/* Sub-links under a main section (e.g. Explore → Resize dataset) */
|
|
693
|
+
.sidebar-links a.sidebar-sub-link {
|
|
694
|
+
font-size: clamp(0.80rem, 1.4vw, 0.95rem); /* smaller than main items */
|
|
695
|
+
padding: 6px 10px 6px 14px; /* slight indent to show hierarchy */
|
|
696
|
+
margin-bottom: 4px;
|
|
697
|
+
opacity: 0.95;
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
/* Optional: visual cue arrow for sub-items */
|
|
701
|
+
.sidebar-links a.sidebar-sub-link::before {
|
|
702
|
+
content: "↳ ";
|
|
703
|
+
font-size: 0.8em;
|
|
704
|
+
opacity: 0.7;
|
|
705
|
+
}
|
|
706
|
+
</style>
|
|
593
707
|
|
|
594
708
|
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
|
|
595
709
|
</head>
|
|
596
710
|
<body>
|
|
597
711
|
<div id="sidebarScrim" class="sidebar-scrim" aria-hidden="true"></div>
|
|
598
|
-
<div id="loader-overlay">
|
|
599
|
-
<div class="loader"></div>
|
|
600
|
-
</div>
|
|
601
712
|
<div class="dashboard-sidebar">
|
|
602
|
-
|
|
713
|
+
|
|
603
714
|
<h2>ML Lab</h2>
|
|
604
715
|
<a href="/">return to home</a>
|
|
605
716
|
<div class="sidebar-links">
|
|
606
717
|
<a href="/dashboard?section=explore"{% if section == 'explore' %} class="active"{% endif %}>Explore</a>
|
|
607
|
-
|
|
718
|
+
|
|
719
|
+
<!-- Explore subsets -->
|
|
720
|
+
<a href="{{ url_for('dataset_resize') }}" class="sidebar-sub-link">Resize dataset</a>
|
|
721
|
+
|
|
608
722
|
<!-- Future: more links here -->
|
|
609
723
|
</div>
|
|
724
|
+
|
|
610
725
|
</div>
|
|
611
726
|
<div class="dashboard-main">
|
|
612
727
|
<button id="sidebarToggle" class="sidebar-toggle" aria-label="Open menu"></button>
|
|
613
728
|
<ul class="dashboard-tabs">
|
|
614
|
-
<li class="{{ 'active' if section == 'explore' else '' }}"><a href="/dashboard?section=explore">Explore</a></li>
|
|
615
|
-
|
|
729
|
+
<li class="{{ 'active' if section == 'explore' else '' }}"><a href="/dashboard?section=explore">Explore</a></li>
|
|
616
730
|
</ul>
|
|
617
731
|
<div class="dashboard-content">
|
|
618
732
|
<div class="explore-card">
|
|
@@ -663,11 +777,24 @@
|
|
|
663
777
|
<h2>Explore Data</h2>
|
|
664
778
|
<form id="form-askai" method="post" action="/dashboard?section=explore" style="margin-top:5px;padding:12px; border:1px solid grey;border-radius:5px;width:70vw;">
|
|
665
779
|
<input type="hidden" name="dataset" value="{{ selected_dataset }}">
|
|
666
|
-
<label for="askai"><strong>Ask smxAI:</strong></label>
|
|
667
|
-
<textarea id="askai" name="askai_question" type="text" rows="
|
|
668
|
-
style="position:relative; width:90%; padding:
|
|
669
|
-
placeholder="Ask me about {{ (selected_dataset or 'your dataset.
|
|
670
|
-
<button type="submit" style="font-size:1.2rem; width:8rem; padding:4px;">Submit</button>
|
|
780
|
+
<label for="askai"><strong>Ask {{ smxAI }}:</strong></label>
|
|
781
|
+
<textarea id="askai" name="askai_question" type="text" rows="5"
|
|
782
|
+
style="position:relative; width:90%; padding:16px; font-size:0.8em; border-radius:8px;"
|
|
783
|
+
placeholder="Ask me about {{ (selected_dataset or 'your dataset\n. But upload it first.').replace('_', ' ').replace('.csv', '') }}" required></textarea>
|
|
784
|
+
<!-- <button type="submit" style="font-size:1.2rem; width:8rem; padding:4px;">Submit</button> -->
|
|
785
|
+
<button
|
|
786
|
+
type="submit"
|
|
787
|
+
class="btn btn-primary eda-submit-btn"
|
|
788
|
+
>
|
|
789
|
+
<span class="eda-btn-content">
|
|
790
|
+
<span class="eda-btn-label">Submit</span>
|
|
791
|
+
<span class="eda-btn-spinner" aria-hidden="true">
|
|
792
|
+
<span class="dot"></span>
|
|
793
|
+
<span class="dot"></span>
|
|
794
|
+
<span class="dot"></span>
|
|
795
|
+
</span>
|
|
796
|
+
</span>
|
|
797
|
+
</button>
|
|
671
798
|
</form>
|
|
672
799
|
<div style="margin-bottom: 36px;">
|
|
673
800
|
{% if askai_question %}
|
|
@@ -679,35 +806,49 @@
|
|
|
679
806
|
-->
|
|
680
807
|
<br><br>
|
|
681
808
|
<div class="refined-qblock">
|
|
682
|
-
|
|
683
|
-
<
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
809
|
+
<details>
|
|
810
|
+
<summary class="refined-q-label" style="cursor: pointer; list-style: none;">
|
|
811
|
+
<span class="toggle-arrow">▶</span>
|
|
812
|
+
<b>Thought Process</b>
|
|
813
|
+
</summary>
|
|
814
|
+
<div class="li" style="margin-top: 10px; padding-left: 14px; border-left: 3px solid #e0e5ee;">
|
|
815
|
+
<span class="refined-q">{{ refined_question|safe }}</span>
|
|
816
|
+
<br><br>
|
|
817
|
+
{% if tasks %}
|
|
818
|
+
<b>Tasks Performed: </b>
|
|
819
|
+
{% for task in tasks %}
|
|
820
|
+
<li>{{ task.replace('_', ' ').capitalize() }}</li>
|
|
821
|
+
{% endfor %}
|
|
822
|
+
{% endif %}
|
|
823
|
+
<br><br>
|
|
824
|
+
{% if TOKENS %}
|
|
825
|
+
<b>Refiner Agent: </b><span>{{ TOKENS['Refiner'][0] }} | {{ TOKENS['Refiner'][1] }}</span><br>
|
|
826
|
+
<b>Token Usage: </b>
|
|
827
|
+
<li>Input Tokens: {{ TOKENS['Refiner'][2] }}</li>
|
|
828
|
+
<li>Output Tokens: {{ TOKENS['Refiner'][3] }}</li>
|
|
829
|
+
<li>Total Tokens: {{ TOKENS['Refiner'][4] }}</li>
|
|
830
|
+
<br>
|
|
831
|
+
|
|
832
|
+
<b>Coder Agent: </b><span>{{ TOKENS['Coder'][0] }} | {{ TOKENS['Coder'][1] }}</span><br>
|
|
833
|
+
<b>Token Usage: </b>
|
|
834
|
+
<li>Input Tokens: {{ TOKENS['Coder'][2] }}</li>
|
|
835
|
+
<li>Output Tokens: {{ TOKENS['Coder'][3] }}</li>
|
|
836
|
+
<li>Total Tokens: {{ TOKENS['Coder'][4] }}</li>
|
|
837
|
+
{% endif %}
|
|
838
|
+
</div>
|
|
839
|
+
</details>
|
|
840
|
+
</div>
|
|
701
841
|
{% endif %}
|
|
702
842
|
{% if ai_outputs %}
|
|
703
843
|
<div class="d-flex align-items-center justify-content-between" style="margin: 12px;">
|
|
844
|
+
<br>
|
|
704
845
|
<h3 class="m-0">Result</h3>
|
|
846
|
+
{% for html_block in ai_outputs %}
|
|
847
|
+
<div class="ai-output" style="margin-bottom:18px;overflow-x:auto; max-width:100%;">
|
|
848
|
+
{{ html_block | safe }}
|
|
849
|
+
</div>
|
|
850
|
+
{% endfor %}
|
|
705
851
|
</div>
|
|
706
|
-
{% for html_block in ai_outputs %}
|
|
707
|
-
<div class="ai-output" style="margin-bottom:18px;overflow-x:auto; max-width:100%;">
|
|
708
|
-
{{ html_block | safe }}
|
|
709
|
-
</div>
|
|
710
|
-
{% endfor %}
|
|
711
852
|
{% endif %}
|
|
712
853
|
{% if ai_code %}
|
|
713
854
|
<div>
|
|
@@ -753,31 +894,31 @@
|
|
|
753
894
|
</div>
|
|
754
895
|
</div>
|
|
755
896
|
<script>
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
897
|
+
async function copyCode(btn){
|
|
898
|
+
const pre = btn.parentElement.querySelector('pre');
|
|
899
|
+
if(!pre) return;
|
|
900
|
+
const text = pre.innerText;
|
|
901
|
+
|
|
902
|
+
try {
|
|
903
|
+
if (navigator.clipboard && navigator.clipboard.writeText) {
|
|
904
|
+
await navigator.clipboard.writeText(text);
|
|
905
|
+
} else {
|
|
906
|
+
// fallback
|
|
907
|
+
const range = document.createRange();
|
|
908
|
+
range.selectNodeContents(pre);
|
|
909
|
+
const sel = window.getSelection();
|
|
910
|
+
sel.removeAllRanges(); sel.addRange(range);
|
|
911
|
+
document.execCommand('copy');
|
|
912
|
+
sel.removeAllRanges();
|
|
913
|
+
}
|
|
914
|
+
btn.textContent = 'Copied!';
|
|
915
|
+
setTimeout(()=>btn.textContent='Copy', 1200);
|
|
916
|
+
} catch(e){
|
|
917
|
+
btn.textContent = 'Failed';
|
|
918
|
+
setTimeout(()=>btn.textContent='Copy', 1200);
|
|
919
|
+
}
|
|
778
920
|
}
|
|
779
|
-
|
|
780
|
-
</script>
|
|
921
|
+
</script>
|
|
781
922
|
<script>
|
|
782
923
|
function toggleCodeCell(link) {
|
|
783
924
|
var cell = link.nextElementSibling;
|
|
@@ -790,6 +931,7 @@
|
|
|
790
931
|
link.querySelector("span").innerText = "Show Code";
|
|
791
932
|
}
|
|
792
933
|
}
|
|
934
|
+
|
|
793
935
|
function copyCodeToClipboard(btn) {
|
|
794
936
|
var pre = btn.parentElement.querySelector("pre");
|
|
795
937
|
if (!pre) return;
|
|
@@ -808,13 +950,36 @@
|
|
|
808
950
|
}
|
|
809
951
|
sel.removeAllRanges();
|
|
810
952
|
}
|
|
811
|
-
|
|
812
|
-
document.addEventListener("DOMContentLoaded", ()
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
953
|
+
|
|
954
|
+
document.addEventListener("DOMContentLoaded", function () {
|
|
955
|
+
var form = document.getElementById("form-askai");
|
|
956
|
+
if (!form) return;
|
|
957
|
+
|
|
958
|
+
var submitBtn = form.querySelector(".eda-submit-btn");
|
|
959
|
+
if (!submitBtn) return;
|
|
960
|
+
|
|
961
|
+
// When the form actually submits, show the spinner and disable the button
|
|
962
|
+
form.addEventListener("submit", function () {
|
|
963
|
+
submitBtn.classList.add("eda-btn-loading");
|
|
964
|
+
submitBtn.disabled = true;
|
|
965
|
+
// IMPORTANT: no preventDefault here – the browser/htmx still submits normally
|
|
817
966
|
});
|
|
967
|
+
|
|
968
|
+
// If htmx is used on this form, reset the spinner once the request completes or errors
|
|
969
|
+
if (window.htmx) {
|
|
970
|
+
form.addEventListener("htmx:afterRequest", function () {
|
|
971
|
+
submitBtn.classList.remove("eda-btn-loading");
|
|
972
|
+
submitBtn.disabled = false;
|
|
973
|
+
});
|
|
974
|
+
form.addEventListener("htmx:responseError", function () {
|
|
975
|
+
submitBtn.classList.remove("eda-btn-loading");
|
|
976
|
+
submitBtn.disabled = false;
|
|
977
|
+
});
|
|
978
|
+
form.addEventListener("htmx:sendError", function () {
|
|
979
|
+
submitBtn.classList.remove("eda-btn-loading");
|
|
980
|
+
submitBtn.disabled = false;
|
|
981
|
+
});
|
|
982
|
+
}
|
|
818
983
|
});
|
|
819
984
|
</script>
|
|
820
985
|
<script>
|