Update index.html
Browse files- index.html +63 -12
index.html
CHANGED
|
@@ -6,6 +6,9 @@
|
|
| 6 |
<title>Genisi AI</title>
|
| 7 |
<link href="https://fonts.googleapis.com/css2?family=Cairo:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet"/>
|
| 8 |
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
|
|
|
|
|
|
|
|
|
| 9 |
<style>
|
| 10 |
:root {
|
| 11 |
--bg: #0d0f14; --surface: #161920; --surface2: #1e2230; --surface3: #252a3a;
|
|
@@ -96,8 +99,8 @@
|
|
| 96 |
|
| 97 |
.bubble{max-width:min(700px,80vw);padding:16px 22px;border-radius:var(--radius);
|
| 98 |
font-size:.98rem;line-height:1.75;word-break:break-word; box-shadow: 0 4px 15px rgba(0,0,0,0.03);}
|
| 99 |
-
.msg-row.bot .bubble{background:
|
| 100 |
-
[dir="rtl"] .msg-row.bot .bubble { border-top-left-radius:var(--radius); border-top-right-radius:
|
| 101 |
.msg-row.user .bubble{background:var(--user-bubble);border:none; border-top-right-radius:6px}
|
| 102 |
[dir="rtl"] .msg-row.user .bubble { border-top-right-radius:var(--radius); border-top-left-radius:6px; }
|
| 103 |
|
|
@@ -125,17 +128,23 @@
|
|
| 125 |
.bubble p{margin-bottom:12px}.bubble p:last-child{margin-bottom:0}
|
| 126 |
.bubble ul,.bubble ol{padding-inline-start:24px;margin:12px 0}
|
| 127 |
.bubble li {margin-bottom: 6px;}
|
| 128 |
-
.bubble table
|
| 129 |
-
.bubble
|
| 130 |
-
.bubble th {
|
|
|
|
| 131 |
|
| 132 |
/* Code Blocks */
|
| 133 |
-
.code-container
|
| 134 |
-
.code-header
|
| 135 |
-
.copy-btn
|
| 136 |
-
.copy-btn:hover
|
| 137 |
-
.code-container pre
|
| 138 |
-
.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 139 |
|
| 140 |
/* Files */
|
| 141 |
.file-chip {display:inline-flex; align-items:center; gap:6px; background:var(--surface2); border:1px solid var(--border); border-radius:var(--radius-pill); padding:4px 12px; font-size:0.85rem; margin:0 4px 8px 0; color:var(--text);}
|
|
@@ -201,6 +210,20 @@
|
|
| 201 |
.btn-danger{padding:8px 18px;background:rgba(247,95,95,.12);border:1px solid var(--danger);
|
| 202 |
color:var(--danger);border-radius:var(--radius-pill);cursor:pointer;font-size:.9rem;font-weight:600;font-family:'Cairo',sans-serif; transition:all var(--tr);}
|
| 203 |
.btn-danger:hover{background:var(--danger); color:#fff;}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 204 |
</style>
|
| 205 |
</head>
|
| 206 |
<body>
|
|
@@ -341,9 +364,32 @@ renderer.code = function(token) {
|
|
| 341 |
<pre><code class="language-${lang}">${escapedCode}</code></pre>
|
| 342 |
</div>`;
|
| 343 |
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 344 |
renderer.html = function(html) { return html; };
|
| 345 |
marked.setOptions({ renderer: renderer, breaks: true, gfm: true });
|
| 346 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 347 |
function copyCode(btn, encodedCode) {
|
| 348 |
navigator.clipboard.writeText(decodeURIComponent(encodedCode)).then(() => {
|
| 349 |
const originalText = btn.innerHTML;
|
|
@@ -549,6 +595,7 @@ async function sendMessage(){
|
|
| 549 |
botContentDiv.innerHTML = fullBotResponse;
|
| 550 |
} else {
|
| 551 |
botContentDiv.innerHTML = marked.parse(fullBotResponse);
|
|
|
|
| 552 |
}
|
| 553 |
|
| 554 |
chat.history.push({ user: text, bot: fullBotResponse, uiFiles: uiFiles });
|
|
@@ -558,6 +605,7 @@ async function sendMessage(){
|
|
| 558 |
} catch(err){
|
| 559 |
if (err.name === 'AbortError') {
|
| 560 |
botContentDiv.innerHTML = marked.parse(fullBotResponse) + `<br><br><span style="color:var(--text3); font-style:italic;">${i18n[currentLang].stopMsg}</span>`;
|
|
|
|
| 561 |
chat.history.push({ user: text, bot: fullBotResponse + "\n\n*" + i18n[currentLang].stopMsg + "*", uiFiles: uiFiles });
|
| 562 |
saveChats();
|
| 563 |
} else {
|
|
@@ -590,7 +638,10 @@ function appendBubble(role, text, isMarkdown, filesList =[]){
|
|
| 590 |
const contentDiv = document.createElement('div');
|
| 591 |
if(text) {
|
| 592 |
if (text.includes('<div style="text-align:center;')) { contentDiv.innerHTML = text; }
|
| 593 |
-
else {
|
|
|
|
|
|
|
|
|
|
| 594 |
}
|
| 595 |
bub.appendChild(contentDiv);
|
| 596 |
|
|
|
|
| 6 |
<title>Genisi AI</title>
|
| 7 |
<link href="https://fonts.googleapis.com/css2?family=Cairo:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet"/>
|
| 8 |
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
| 9 |
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.10/dist/katex.min.css"/>
|
| 10 |
+
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.10/dist/katex.min.js"></script>
|
| 11 |
+
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.10/dist/contrib/auto-render.min.js"></script>
|
| 12 |
<style>
|
| 13 |
:root {
|
| 14 |
--bg: #0d0f14; --surface: #161920; --surface2: #1e2230; --surface3: #252a3a;
|
|
|
|
| 99 |
|
| 100 |
.bubble{max-width:min(700px,80vw);padding:16px 22px;border-radius:var(--radius);
|
| 101 |
font-size:.98rem;line-height:1.75;word-break:break-word; box-shadow: 0 4px 15px rgba(0,0,0,0.03);}
|
| 102 |
+
.msg-row.bot .bubble{background:transparent;border:none;padding:8px 4px;box-shadow:none;border-top-left-radius:var(--radius);}
|
| 103 |
+
[dir="rtl"] .msg-row.bot .bubble { border-top-left-radius:var(--radius); border-top-right-radius:var(--radius); }
|
| 104 |
.msg-row.user .bubble{background:var(--user-bubble);border:none; border-top-right-radius:6px}
|
| 105 |
[dir="rtl"] .msg-row.user .bubble { border-top-right-radius:var(--radius); border-top-left-radius:6px; }
|
| 106 |
|
|
|
|
| 128 |
.bubble p{margin-bottom:12px}.bubble p:last-child{margin-bottom:0}
|
| 129 |
.bubble ul,.bubble ol{padding-inline-start:24px;margin:12px 0}
|
| 130 |
.bubble li {margin-bottom: 6px;}
|
| 131 |
+
.bubble .table-wrapper{width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;margin:16px 0;border-radius:var(--radius-sm);border:1px solid var(--border);}
|
| 132 |
+
.bubble table{width:100%;border-collapse:collapse;min-width:400px;}
|
| 133 |
+
.bubble th,.bubble td{border:1px solid var(--border);padding:10px 14px;text-align:start;white-space:nowrap;}
|
| 134 |
+
.bubble th{background:var(--surface3);font-weight:600;}
|
| 135 |
|
| 136 |
/* Code Blocks */
|
| 137 |
+
.code-container{position:relative;margin:16px 0;background:var(--surface3);border-radius:var(--radius-sm);border:1px solid var(--border);overflow:hidden;max-width:100%;}
|
| 138 |
+
.code-header{display:flex;justify-content:space-between;align-items:center;background:#12141a;padding:8px 16px;font-size:0.8rem;color:var(--text2);font-family:'JetBrains Mono',monospace;}
|
| 139 |
+
.copy-btn{background:var(--surface2);border:none;color:var(--text);cursor:pointer;display:flex;align-items:center;gap:6px;font-size:0.8rem;padding:4px 10px;border-radius:var(--radius-pill);transition:all 0.2s;}
|
| 140 |
+
.copy-btn:hover{background:var(--accent);color:#fff;}
|
| 141 |
+
.code-container pre{margin:0;padding:16px;overflow-x:auto;-webkit-overflow-scrolling:touch;font-family:'JetBrains Mono',monospace;font-size:0.85rem;max-width:100%;}
|
| 142 |
+
.code-container pre code{white-space:pre;display:block;}
|
| 143 |
+
.bubble code:not(pre code){font-family:'JetBrains Mono',monospace;font-size:.85rem;background:var(--surface3);padding:3px 6px;border-radius:6px;color:var(--accent);}
|
| 144 |
+
|
| 145 |
+
/* KaTeX Math Styles */
|
| 146 |
+
.katex-display{overflow-x:auto;overflow-y:hidden;padding:8px 0;-webkit-overflow-scrolling:touch;}
|
| 147 |
+
.katex{font-size:1.05em;}
|
| 148 |
|
| 149 |
/* Files */
|
| 150 |
.file-chip {display:inline-flex; align-items:center; gap:6px; background:var(--surface2); border:1px solid var(--border); border-radius:var(--radius-pill); padding:4px 12px; font-size:0.85rem; margin:0 4px 8px 0; color:var(--text);}
|
|
|
|
| 210 |
.btn-danger{padding:8px 18px;background:rgba(247,95,95,.12);border:1px solid var(--danger);
|
| 211 |
color:var(--danger);border-radius:var(--radius-pill);cursor:pointer;font-size:.9rem;font-weight:600;font-family:'Cairo',sans-serif; transition:all var(--tr);}
|
| 212 |
.btn-danger:hover{background:var(--danger); color:#fff;}
|
| 213 |
+
|
| 214 |
+
/* ══ RESPONSIVE MOBILE ══ */
|
| 215 |
+
@media (max-width: 640px) {
|
| 216 |
+
.msg-row { padding: 6px 12px; gap: 10px; }
|
| 217 |
+
.bubble { max-width: 92vw; padding: 12px 14px; font-size: .93rem; }
|
| 218 |
+
.msg-row.bot .bubble { padding: 6px 2px; }
|
| 219 |
+
.topbar { height: 56px; padding: 0 14px; }
|
| 220 |
+
.input-area { padding: 0 10px 18px; }
|
| 221 |
+
.code-container pre { font-size: 0.78rem; padding: 12px; }
|
| 222 |
+
.bubble th, .bubble td { font-size: 0.85rem; padding: 8px 10px; }
|
| 223 |
+
.w-title { font-size: 1.8rem; }
|
| 224 |
+
.chips { gap: 8px; }
|
| 225 |
+
.chip { font-size: .82rem; padding: 8px 14px; }
|
| 226 |
+
}
|
| 227 |
</style>
|
| 228 |
</head>
|
| 229 |
<body>
|
|
|
|
| 364 |
<pre><code class="language-${lang}">${escapedCode}</code></pre>
|
| 365 |
</div>`;
|
| 366 |
};
|
| 367 |
+
renderer.table = function(header, body) {
|
| 368 |
+
if (typeof header === 'object' && header !== null && 'header' in header) {
|
| 369 |
+
const token = header;
|
| 370 |
+
const hdr = token.header.map(cell => `<th>${cell.tokens.map(t=>t.raw||'').join('')}</th>`).join('');
|
| 371 |
+
const rows = (token.rows || []).map(row => `<tr>${row.map(cell => `<td>${cell.tokens.map(t=>t.raw||'').join('')}</td>`).join('')}</tr>`).join('');
|
| 372 |
+
return `<div class="table-wrapper"><table><thead><tr>${hdr}</tr></thead><tbody>${rows}</tbody></table></div>`;
|
| 373 |
+
}
|
| 374 |
+
return `<div class="table-wrapper"><table><thead>${header}</thead><tbody>${body}</tbody></table></div>`;
|
| 375 |
+
};
|
| 376 |
renderer.html = function(html) { return html; };
|
| 377 |
marked.setOptions({ renderer: renderer, breaks: true, gfm: true });
|
| 378 |
|
| 379 |
+
function renderKaTeX(el) {
|
| 380 |
+
if (window.renderMathInElement) {
|
| 381 |
+
renderMathInElement(el, {
|
| 382 |
+
delimiters: [
|
| 383 |
+
{left: '$$', right: '$$', display: true},
|
| 384 |
+
{left: '$', right: '$', display: false},
|
| 385 |
+
{left: '\\(', right: '\\)', display: false},
|
| 386 |
+
{left: '\\[', right: '\\]', display: true}
|
| 387 |
+
],
|
| 388 |
+
throwOnError: false
|
| 389 |
+
});
|
| 390 |
+
}
|
| 391 |
+
}
|
| 392 |
+
|
| 393 |
function copyCode(btn, encodedCode) {
|
| 394 |
navigator.clipboard.writeText(decodeURIComponent(encodedCode)).then(() => {
|
| 395 |
const originalText = btn.innerHTML;
|
|
|
|
| 595 |
botContentDiv.innerHTML = fullBotResponse;
|
| 596 |
} else {
|
| 597 |
botContentDiv.innerHTML = marked.parse(fullBotResponse);
|
| 598 |
+
renderKaTeX(botContentDiv);
|
| 599 |
}
|
| 600 |
|
| 601 |
chat.history.push({ user: text, bot: fullBotResponse, uiFiles: uiFiles });
|
|
|
|
| 605 |
} catch(err){
|
| 606 |
if (err.name === 'AbortError') {
|
| 607 |
botContentDiv.innerHTML = marked.parse(fullBotResponse) + `<br><br><span style="color:var(--text3); font-style:italic;">${i18n[currentLang].stopMsg}</span>`;
|
| 608 |
+
renderKaTeX(botContentDiv);
|
| 609 |
chat.history.push({ user: text, bot: fullBotResponse + "\n\n*" + i18n[currentLang].stopMsg + "*", uiFiles: uiFiles });
|
| 610 |
saveChats();
|
| 611 |
} else {
|
|
|
|
| 638 |
const contentDiv = document.createElement('div');
|
| 639 |
if(text) {
|
| 640 |
if (text.includes('<div style="text-align:center;')) { contentDiv.innerHTML = text; }
|
| 641 |
+
else {
|
| 642 |
+
contentDiv.innerHTML = isMarkdown ? marked.parse(text) : esc(text).replace(/\n/g, '<br/>');
|
| 643 |
+
if (isMarkdown) renderKaTeX(contentDiv);
|
| 644 |
+
}
|
| 645 |
}
|
| 646 |
bub.appendChild(contentDiv);
|
| 647 |
|