drixio 1.2.0 → 1.2.1

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.
@@ -1,10 +1,8 @@
1
- (function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),e.crossOrigin===`use-credentials`?t.credentials=`include`:e.crossOrigin===`anonymous`?t.credentials=`omit`:t.credentials=`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();var e=`
1
+ import{t as e}from"./sql-formatter-B5XS8faB.js";(function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),e.crossOrigin===`use-credentials`?t.credentials=`include`:e.crossOrigin===`anonymous`?t.credentials=`omit`:t.credentials=`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();var t=`
2
2
  <header>
3
3
  <div class="header-left">
4
4
  <div class="header-brand">
5
- <div class="header-brand-icon">
6
- <span class="material-symbols-outlined">database</span>
7
- </div>
5
+ <img src="/icon.svg" id="drixio-logo" />
8
6
  <div class="header-brand-info">
9
7
  <div class="header-brand-text">
10
8
  <span class="header-brand-title">DRIXIO</span>
@@ -35,6 +33,10 @@
35
33
  <span class="material-symbols-outlined connect-icon">settings_ethernet</span>
36
34
  <span class="connect-label">Connect</span>
37
35
  </button>
36
+ <button id="header-readonly-btn" class="header-readonly-pill" title="Toggle Read-Only Protection Mode" type="button">
37
+ <span class="material-symbols-outlined readonly-icon" id="readonly-icon">lock_open</span>
38
+ <span class="readonly-label" id="readonly-label">EDITABLE</span>
39
+ </button>
38
40
  </div>
39
41
  </div>
40
42
 
@@ -94,6 +96,21 @@
94
96
  <span class="dropdown-badge" style="color: var(--color-primary); border-color: rgba(59, 130, 246, 0.3);">JSON</span>
95
97
  </button>
96
98
  </li>
99
+ <li class="dropdown-divider" style="height: 1px; background: var(--color-border); margin: 4px 0;"></li>
100
+ <li>
101
+ <button id="export-data-masked-csv-btn" class="dropdown-item" style="color: #10b981;">
102
+ <span class="material-symbols-outlined" style="color: #10b981;">enhanced_encryption</span>
103
+ <span class="dropdown-item-label">Masked (PII Shield)</span>
104
+ <span class="dropdown-badge" style="color: #10b981; border-color: rgba(16, 185, 129, 0.3);">CSV</span>
105
+ </button>
106
+ </li>
107
+ <li>
108
+ <button id="export-data-masked-json-btn" class="dropdown-item" style="color: #10b981;">
109
+ <span class="material-symbols-outlined" style="color: #10b981;">enhanced_encryption</span>
110
+ <span class="dropdown-item-label">Masked (PII Shield)</span>
111
+ <span class="dropdown-badge" style="color: #10b981; border-color: rgba(16, 185, 129, 0.3);">JSON</span>
112
+ </button>
113
+ </li>
97
114
  </ul>
98
115
  </li>
99
116
 
@@ -149,6 +166,21 @@
149
166
  <span class="dropdown-badge">JSON</span>
150
167
  </button>
151
168
  </li>
169
+ <li class="dropdown-divider" style="height: 1px; background: var(--color-border); margin: 4px 0;"></li>
170
+ <li>
171
+ <button id="export-console-masked-csv-btn" class="dropdown-item" style="color: #10b981;">
172
+ <span class="material-symbols-outlined" style="color: #10b981;">enhanced_encryption</span>
173
+ <span class="dropdown-item-label">Masked Query Result</span>
174
+ <span class="dropdown-badge" style="color: #10b981; border-color: rgba(16, 185, 129, 0.3);">CSV</span>
175
+ </button>
176
+ </li>
177
+ <li>
178
+ <button id="export-console-masked-json-btn" class="dropdown-item" style="color: #10b981;">
179
+ <span class="material-symbols-outlined" style="color: #10b981;">enhanced_encryption</span>
180
+ <span class="dropdown-item-label">Masked Query Result</span>
181
+ <span class="dropdown-badge" style="color: #10b981; border-color: rgba(16, 185, 129, 0.3);">JSON</span>
182
+ </button>
183
+ </li>
152
184
  </ul>
153
185
  </li>
154
186
 
@@ -193,7 +225,7 @@
193
225
  </div>
194
226
  </div>
195
227
  </header>
196
- `,t=`
228
+ `,n=`
197
229
  <aside id="sidebar-panel">
198
230
  <div id="sidebar-header">
199
231
  <div class="sidebar-header-title">
@@ -237,17 +269,31 @@
237
269
  </div>
238
270
 
239
271
  <div id="sidebar-footer">
240
- <div class="sidebar-db-status" title="Database Connection Status">
241
- <span class="status-indicator-dot" id="sidebar-db-status-dot"></span>
242
- <span id="brand-db-type">CONNECTING...</span>
272
+ <div class="sidebar-footer-top">
273
+ <div class="sidebar-db-status" title="Database Connection Status">
274
+ <span class="status-indicator-dot" id="sidebar-db-status-dot"></span>
275
+ <span id="brand-db-type">CONNECTING...</span>
276
+ </div>
277
+ <span class="sidebar-version-tag">v1.2.1</span>
243
278
  </div>
244
279
 
245
280
  <div class="sidebar-footer-actions">
246
- <span class="sidebar-version-tag">v1.2.0</span>
281
+ <button type="button" id="sidebar-app-btn" class="sidebar-footer-btn" title="Install Desktop App Shortcut" aria-label="Install Desktop App Shortcut">
282
+ <span class="material-symbols-outlined" style="font-size: 15px;">install_desktop</span>
283
+ <span class="sidebar-footer-btn-label">App</span>
284
+ </button>
285
+ <button type="button" id="sidebar-health-btn" class="sidebar-footer-btn" title="Schema Health Doctor" aria-label="Schema Health Doctor">
286
+ <span class="material-symbols-outlined" style="font-size: 15px;">health_and_safety</span>
287
+ <span id="sidebar-health-badge" class="sidebar-footer-btn-label">Doctor</span>
288
+ </button>
289
+ <button type="button" id="sidebar-trash-btn" class="sidebar-trash-btn hidden" title="Table Recycle Bin" aria-label="Table Recycle Bin">
290
+ <span class="material-symbols-outlined" style="font-size: 15px;">delete</span>
291
+ <span id="sidebar-trash-count">0</span>
292
+ </button>
247
293
  </div>
248
294
  </div>
249
295
  </aside>
250
- `,n=`
296
+ `,r=`
251
297
  <nav id="tab-nav" role="navigation" aria-label="Views and tools">
252
298
  <!-- Top Navigation Items -->
253
299
  <div class="rail-top">
@@ -341,7 +387,7 @@
341
387
  </button>
342
388
  </div>
343
389
  </nav>
344
- `;async function r(){return await(await fetch(`/api/tables`)).json()}async function i(e,t){return await(await fetch(`/api/tables`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({tableName:e,columns:t})})).json()}async function a(){return await(await fetch(`/api/config`)).json()}async function o(){return await(await fetch(`/api/tables/stats`)).json()}async function s(e,t={}){let{where:n=``,limit:r=50,offset:i=0,orderCol:a,orderAsc:o}=t,s=new URLSearchParams;n&&s.append(`where`,n),s.append(`limit`,r.toString()),s.append(`offset`,i.toString()),a&&(s.append(`orderCol`,a),s.append(`orderAsc`,o===!1?`false`:`true`));let c=`/api/tables/${e}/data?${s.toString()}`;return await(await fetch(c)).json()}async function c(e){return await(await fetch(`/api/tables/${e}/schema`)).json()}async function l(e){return await(await fetch(`/api/tables/${e}/indexes`)).json()}async function u(e){return await(await fetch(`/api/query`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({sql:e})})).json()}async function d(e,t){return await(await fetch(`/api/tables/${encodeURIComponent(e)}/records`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(t)})).json()}async function f(e,t){return await(await fetch(`/api/tables/${encodeURIComponent(e)}/schema`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(t)})).json()}async function p(e){return await(await fetch(`/api/tables/${encodeURIComponent(e)}/truncate`,{method:`POST`})).json()}async function m(e,t=`csv`){let n=await(await fetch(`/api/query/export?format=${t}`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e)})).blob(),r=URL.createObjectURL(n),i=document.createElement(`a`);i.href=r,i.download=`query_result_${new Date().getTime()}.${t}`,document.body.appendChild(i),i.click(),document.body.removeChild(i),URL.revokeObjectURL(r)}async function h(e){return await(await fetch(`/api/query/explain`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({sql:e})})).json()}async function g(e){return await(await fetch(`/api/schema/diff`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e)})).json()}async function _(e){return await(await fetch(`/api/schema/apply-migration`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({sql:e})})).json()}function v(){window.location.href=`/api/schema/snapshot`}async function y(){return await(await fetch(`/api/snippets`)).json()}async function b(e){return await(await fetch(`/api/snippets`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e)})).json()}async function x(e,t){return await(await fetch(`/api/snippets/${encodeURIComponent(e)}`,{method:`PUT`,headers:{"Content-Type":`application/json`},body:JSON.stringify(t)})).json()}async function S(e){return await(await fetch(`/api/snippets/${encodeURIComponent(e)}`,{method:`DELETE`})).json()}async function C(){return await(await fetch(`/api/schemas`)).json()}async function w(e){return await(await fetch(`/api/schemas/switch`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({schema:e})})).json()}async function T(){return await(await fetch(`/api/database/enums`)).json()}var E=null,D=-1;function O(){E||(E=document.createElement(`div`),E.className=`drixio-context-menu`,document.body.appendChild(E),document.addEventListener(`pointerdown`,e=>{E.classList.contains(`visible`)&&!E.contains(e.target)&&j()}),document.addEventListener(`keydown`,e=>{if(!E.classList.contains(`visible`))return;if(e.key===`Escape`){e.preventDefault(),e.stopPropagation(),j();return}let t=Array.from(E.querySelectorAll(`.drixio-context-menu-item:not(.disabled)`));t.length!==0&&(e.key===`ArrowDown`?(e.preventDefault(),e.stopPropagation(),D=(D+1)%t.length,k(t)):e.key===`ArrowUp`?(e.preventDefault(),e.stopPropagation(),D=(D-1+t.length)%t.length,k(t)):e.key===`Enter`&&D>=0&&D<t.length&&(e.preventDefault(),e.stopPropagation(),t[D].click()))}),window.addEventListener(`scroll`,e=>{E.classList.contains(`visible`)&&(E.contains(e.target)||j())},!0))}function k(e){e.forEach((e,t)=>{t===D?(e.classList.add(`focused`),e.scrollIntoView({block:`nearest`})):e.classList.remove(`focused`)})}function A(e,t){e.preventDefault&&e.preventDefault(),e.stopPropagation&&e.stopPropagation(),O(),E.innerHTML=``,E.classList.remove(`visible`),D=-1,t.forEach(e=>{if(e.type===`divider`||e===`divider`){let e=document.createElement(`div`);e.className=`drixio-context-menu-divider`,E.appendChild(e);return}let t=document.createElement(`div`);t.className=`drixio-context-menu-item`,e.danger&&t.classList.add(`danger`),e.disabled&&t.classList.add(`disabled`);let n=e.icon?`<span class="material-symbols-outlined drixio-menu-icon">${e.icon}</span>`:``,r=e.checked?`<span class="material-symbols-outlined drixio-menu-check">check</span>`:``,i=e.shortcut?`<span class="drixio-menu-shortcut">${e.shortcut}</span>`:``,a=e.desc?`<span class="drixio-menu-desc">${e.desc}</span>`:``;t.innerHTML=`
390
+ `;async function i(){return await(await fetch(`/api/tables`)).json()}async function a(e,t){return await(await fetch(`/api/tables`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({tableName:e,columns:t})})).json()}async function o(){return await(await fetch(`/api/config`)).json()}async function s(e){return await(await fetch(`/api/config/readonly`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({readOnly:e})})).json()}async function c(){return await(await fetch(`/api/tables/stats`)).json()}async function l(e,t={}){let{where:n=``,limit:r=50,offset:i=0,orderCol:a,orderAsc:o}=t,s=new URLSearchParams;n&&s.append(`where`,n),s.append(`limit`,r.toString()),s.append(`offset`,i.toString()),a&&(s.append(`orderCol`,a),s.append(`orderAsc`,o===!1?`false`:`true`));let c=`/api/tables/${encodeURIComponent(e)}/data?${s.toString()}`;return await(await fetch(c)).json()}async function u(e){return await(await fetch(`/api/tables/${encodeURIComponent(e)}/schema`)).json()}async function d(e){return await(await fetch(`/api/tables/${encodeURIComponent(e)}/indexes`)).json()}async function f(e){return await(await fetch(`/api/query`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({sql:e})})).json()}async function p(e,t){return await(await fetch(`/api/tables/${encodeURIComponent(e)}/records`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(t)})).json()}async function m(e,t){return await(await fetch(`/api/tables/${encodeURIComponent(e)}/schema`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(t)})).json()}async function h(e,t,n){return await(await fetch(`/api/tables/${encodeURIComponent(e)}/cascade-check`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({colName:t,newType:n})})).json()}async function g(e){return await(await fetch(`/api/tables/${encodeURIComponent(e)}/truncate`,{method:`POST`})).json()}async function _(e,t){return await(await fetch(`/api/tables/${encodeURIComponent(e)}/rename`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({newName:t})})).json()}async function v(e,t=`csv`){let n=await(await fetch(`/api/query/export?format=${t}`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e)})).blob(),r=URL.createObjectURL(n),i=document.createElement(`a`);i.href=r,i.download=`query_result_${new Date().getTime()}.${t}`,document.body.appendChild(i),i.click(),document.body.removeChild(i),URL.revokeObjectURL(r)}async function y(e){return await(await fetch(`/api/query/explain`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({sql:e})})).json()}async function b(e){return await(await fetch(`/api/schema/diff`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e)})).json()}async function x(e){return await(await fetch(`/api/schema/apply-migration`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({sql:e})})).json()}function S(){window.location.href=`/api/schema/snapshot`}async function C(){return await(await fetch(`/api/snippets`)).json()}async function w(e){return await(await fetch(`/api/snippets`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e)})).json()}async function T(e,t){return await(await fetch(`/api/snippets/${encodeURIComponent(e)}`,{method:`PUT`,headers:{"Content-Type":`application/json`},body:JSON.stringify(t)})).json()}async function E(e){return await(await fetch(`/api/snippets/${encodeURIComponent(e)}`,{method:`DELETE`})).json()}async function D(){return await(await fetch(`/api/schemas`)).json()}async function O(e){return await(await fetch(`/api/schemas/switch`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({schema:e})})).json()}async function k(){return await(await fetch(`/api/database/enums`)).json()}async function A(e){return await(await fetch(`/api/ai/generate`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e)})).json()}async function j(e){return await(await fetch(`/api/ai/explain`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e)})).json()}async function M(e){return await(await fetch(`/api/ai/fix`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e)})).json()}async function N(e){return await(await fetch(`/api/ai/test`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({config:e})})).json()}async function ee(e,t=!0){return await(await fetch(`/api/tables/${encodeURIComponent(e)}?soft=${t}`,{method:`DELETE`})).json()}async function te(){return await(await fetch(`/api/trash`)).json()}async function P(e,t){return await(await fetch(`/api/trash/${encodeURIComponent(e)}/restore`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({customName:t})})).json()}async function F(e){return await(await fetch(`/api/trash/${encodeURIComponent(e)}`,{method:`DELETE`})).json()}async function I(){return await(await fetch(`/api/trash/purge-all`,{method:`POST`})).json()}async function L(){return await(await fetch(`/api/health`)).json()}function R(){let e=document.createElement(`a`);e.href=`/api/app/download-launcher`,e.download=`Drixio-Studio.bat`,document.body.appendChild(e),e.click(),e.remove()}async function ne(){R();try{await fetch(`/api/app/create-shortcut`,{method:`POST`})}catch{}return{success:!0,message:`✓ Drixio App Launcher downloaded to your browser! Click it in your browser downloads to launch.`}}var z=null,B=-1;function re(){z||(z=document.createElement(`div`),z.className=`drixio-context-menu`,document.body.appendChild(z),document.addEventListener(`pointerdown`,e=>{z.classList.contains(`visible`)&&!z.contains(e.target)&&ae()}),document.addEventListener(`keydown`,e=>{if(!z.classList.contains(`visible`))return;if(e.key===`Escape`){e.preventDefault(),e.stopPropagation(),ae();return}let t=Array.from(z.querySelectorAll(`.drixio-context-menu-item:not(.disabled)`));t.length!==0&&(e.key===`ArrowDown`?(e.preventDefault(),e.stopPropagation(),B=(B+1)%t.length,ie(t)):e.key===`ArrowUp`?(e.preventDefault(),e.stopPropagation(),B=(B-1+t.length)%t.length,ie(t)):e.key===`Enter`&&B>=0&&B<t.length&&(e.preventDefault(),e.stopPropagation(),t[B].click()))}),window.addEventListener(`scroll`,e=>{z.classList.contains(`visible`)&&(z.contains(e.target)||ae())},!0))}function ie(e){e.forEach((e,t)=>{t===B?(e.classList.add(`focused`),e.scrollIntoView({block:`nearest`})):e.classList.remove(`focused`)})}function V(e,t){e.preventDefault&&e.preventDefault(),e.stopPropagation&&e.stopPropagation(),re(),z.innerHTML=``,z.classList.remove(`visible`),B=-1,t.forEach(e=>{if(e.type===`divider`||e===`divider`){let e=document.createElement(`div`);e.className=`drixio-context-menu-divider`,z.appendChild(e);return}let t=document.createElement(`div`);t.className=`drixio-context-menu-item`,e.danger&&t.classList.add(`danger`),e.disabled&&t.classList.add(`disabled`);let n=e.icon?`<span class="material-symbols-outlined drixio-menu-icon">${e.icon}</span>`:``,r=e.checked?`<span class="material-symbols-outlined drixio-menu-check">check</span>`:``,i=e.shortcut?`<span class="drixio-menu-shortcut">${e.shortcut}</span>`:``,a=e.desc?`<span class="drixio-menu-desc">${e.desc}</span>`:``;t.innerHTML=`
345
391
  ${n}
346
392
  <div class="drixio-menu-content">
347
393
  <span class="drixio-menu-label">${e.label}</span>
@@ -349,7 +395,7 @@
349
395
  </div>
350
396
  ${i}
351
397
  ${r}
352
- `,t.addEventListener(`mouseenter`,()=>{let e=Array.from(E.querySelectorAll(`.drixio-context-menu-item:not(.disabled)`));D=e.indexOf(t),k(e)}),t.addEventListener(`click`,t=>{e.disabled||(t.stopPropagation(),j(),e.action&&e.action())}),E.appendChild(t)}),requestAnimationFrame(()=>{let t=E.getBoundingClientRect(),n=e.clientX??0,r=e.clientY??0,i=`left`,a=`top`;n+t.width>window.innerWidth-8&&(n=Math.max(8,window.innerWidth-t.width-8),i=`right`),r+t.height>window.innerHeight-8&&(r=Math.max(8,window.innerHeight-t.height-8),a=`bottom`),E.style.transformOrigin=`${a} ${i}`,E.style.left=`${n}px`,E.style.top=`${r}px`,E.classList.add(`visible`)})}function j(){E&&(E.classList.remove(`visible`),D=-1)}async function M(e,t,n){let r=document.getElementById(`mock-data-modal-overlay`);r||(r=document.createElement(`div`),r.id=`mock-data-modal-overlay`,r.className=`mock-modal-overlay`,document.body.appendChild(r)),r.innerHTML=`
398
+ `,t.addEventListener(`mouseenter`,()=>{let e=Array.from(z.querySelectorAll(`.drixio-context-menu-item:not(.disabled)`));B=e.indexOf(t),ie(e)}),t.addEventListener(`click`,t=>{e.disabled||(t.stopPropagation(),ae(),e.action&&e.action())}),z.appendChild(t)}),requestAnimationFrame(()=>{let t=z.getBoundingClientRect(),n=e.clientX??0,r=e.clientY??0,i=`left`,a=`top`;n+t.width>window.innerWidth-8&&(n=Math.max(8,window.innerWidth-t.width-8),i=`right`),r+t.height>window.innerHeight-8&&(r=Math.max(8,window.innerHeight-t.height-8),a=`bottom`),z.style.transformOrigin=`${a} ${i}`,z.style.left=`${n}px`,z.style.top=`${r}px`,z.classList.add(`visible`)})}function ae(){z&&(z.classList.remove(`visible`),B=-1)}async function oe(e,t,n){let r=document.getElementById(`mock-data-modal-overlay`);r||(r=document.createElement(`div`),r.id=`mock-data-modal-overlay`,r.className=`mock-modal-overlay`,document.body.appendChild(r)),r.innerHTML=`
353
399
  <div class="mock-modal-container">
354
400
  <div class="mock-modal-header">
355
401
  <div class="mock-modal-title">
@@ -448,7 +494,7 @@
448
494
  </button>
449
495
  </div>
450
496
  </div>
451
- `,r.querySelector(`#btn-mock-close`)?.addEventListener(`click`,i),r.querySelector(`#btn-mock-cancel`)?.addEventListener(`click`,i),r.querySelectorAll(`.mock-pill`).forEach(e=>{e.addEventListener(`click`,()=>{a=parseInt(e.dataset.count,10),s()})});let p=r.querySelector(`#mock-custom-count`);p&&p.addEventListener(`change`,e=>{let t=parseInt(e.target.value,10);t&&t>0&&t<=500&&(a=t,s())}),r.querySelector(`#btn-mock-generate`)?.addEventListener(`click`,async()=>{let t=r.querySelector(`#btn-mock-generate`);if(t){t.disabled=!0,t.innerHTML=`<span class="material-symbols-outlined animate-spin icon-16">progress_activity</span> Inserting...`;try{let t=await(await fetch(`/api/tables/${encodeURIComponent(e)}/mock`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({count:a})})).json();if(!t.success)throw Error(t.error||`Failed to insert mock data`);i(),window.loadTableStats?.(),window.updateSidebarActiveTable?.(e),window.showToast&&window.showToast(`Successfully generated and inserted ${t.count||a} rows into "${e}"!`,`success`),n&&n()}catch(e){alert(`Failed to insert mock data: ${e.message}`),t.disabled=!1,t.innerHTML=`<span>Try Again</span>`}}})}s()}var N=[`INTEGER`,`VARCHAR(255)`,`TEXT`,`BOOLEAN`,`TIMESTAMP`,`DATETIME`,`DATE`,`NUMERIC`,`DECIMAL(10,2)`,`REAL`,`JSON`,`BLOB`,`UUID`,`ENUM`];function P(e){if(e==null)return null;let t=String(e).trim();if(!t||t.toLowerCase()===`null`||t===`-`)return null;for(;t.startsWith(`''`)&&t.endsWith(`''`)&&t.length>4;)t=t.slice(1,-1);if(/^-?\d+(\.\d+)?$/.test(t))return t;let n=t.toLowerCase();if(n===`true`||n===`false`)return n.toUpperCase();let r=t.toUpperCase();if(r===`CURRENT_TIMESTAMP`||r===`CURRENT_DATE`||r===`CURRENT_TIME`||r===`NOW()`||r===`TIMESTAMP`||r.startsWith(`CURRENT_TIMESTAMP`)||r.startsWith(`NOW()`)||r.startsWith(`GEN_RANDOM_UUID(`)||r.startsWith(`UUID_GENERATE_`)||r.startsWith(`UUID(`)||t.startsWith(`(`)&&t.endsWith(`)`))return r===`TIMESTAMP`?`CURRENT_TIMESTAMP`:t;let i=t.match(/^('[\s\S]*')(?:::[\w\s()]+)$/);return i?i[1]:t.startsWith(`'`)&&t.endsWith(`'`)&&t.length>=2?t:t.startsWith(`"`)&&t.endsWith(`"`)&&t.length>=2?`'${t.slice(1,-1).replace(/'/g,`''`)}'`:`'${t.replace(/'/g,`''`)}'`}var F=null;function I({anchorEl:e,title:t=``,placeholder:n=`Search...`,items:r=[],initialValue:i=``,onSelect:a,onCancel:o,width:s=320,maxHeight:c=260,searchable:l=!0,allowCustom:u=!1,emptyText:d=`No matching options found`}){L();let f=r.map(e=>typeof e==`string`||typeof e==`number`?{name:String(e),value:String(e),desc:``,icon:``}:{name:String(e.name??e.value??``),value:e.value===void 0?String(e.name??``):String(e.value),desc:e.desc?String(e.desc):``,icon:e.icon||``,badge:e.badge||``,badgeClass:e.badgeClass||``,group:e.group||``}),p=document.createElement(`div`);p.className=`dropdown-picker-popover`,s&&(p.style.width=typeof s==`number`?`${s}px`:s),p.innerHTML=`
497
+ `,r.querySelector(`#btn-mock-close`)?.addEventListener(`click`,i),r.querySelector(`#btn-mock-cancel`)?.addEventListener(`click`,i),r.querySelectorAll(`.mock-pill`).forEach(e=>{e.addEventListener(`click`,()=>{a=parseInt(e.dataset.count,10),s()})});let p=r.querySelector(`#mock-custom-count`);p&&p.addEventListener(`change`,e=>{let t=parseInt(e.target.value,10);t&&t>0&&t<=500&&(a=t,s())}),r.querySelector(`#btn-mock-generate`)?.addEventListener(`click`,async()=>{let t=r.querySelector(`#btn-mock-generate`);if(t){t.disabled=!0,t.innerHTML=`<span class="material-symbols-outlined animate-spin icon-16">progress_activity</span> Inserting...`;try{let t=await(await fetch(`/api/tables/${encodeURIComponent(e)}/mock`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({count:a})})).json();if(!t.success)throw Error(t.error||`Failed to insert mock data`);i(),window.loadTableStats?.(),window.updateSidebarActiveTable?.(e),window.showToast&&window.showToast(`Successfully generated and inserted ${t.count||a} rows into "${e}"!`,`success`),n&&n()}catch(e){alert(`Failed to insert mock data: ${e.message}`),t.disabled=!1,t.innerHTML=`<span>Try Again</span>`}}})}s()}var se=[`INTEGER`,`VARCHAR(255)`,`TEXT`,`BOOLEAN`,`TIMESTAMP`,`DATETIME`,`DATE`,`NUMERIC`,`DECIMAL(10,2)`,`REAL`,`JSON`,`BLOB`,`UUID`,`ENUM`];function ce(e){if(e==null)return null;let t=String(e).trim();if(!t||t.toLowerCase()===`null`||t===`-`)return null;for(;t.startsWith(`''`)&&t.endsWith(`''`)&&t.length>4;)t=t.slice(1,-1);if(/^-?\d+(\.\d+)?$/.test(t))return t;let n=t.toLowerCase();if(n===`true`||n===`false`)return n.toUpperCase();let r=t.toUpperCase();if(r===`CURRENT_TIMESTAMP`||r===`CURRENT_DATE`||r===`CURRENT_TIME`||r===`NOW()`||r===`TIMESTAMP`||r.startsWith(`CURRENT_TIMESTAMP`)||r.startsWith(`NOW()`)||r.startsWith(`GEN_RANDOM_UUID(`)||r.startsWith(`UUID_GENERATE_`)||r.startsWith(`UUID(`)||t.startsWith(`(`)&&t.endsWith(`)`))return r===`TIMESTAMP`?`CURRENT_TIMESTAMP`:t;let i=t.match(/^('[\s\S]*')(?:::[\w\s()]+)$/);return i?i[1]:t.startsWith(`'`)&&t.endsWith(`'`)&&t.length>=2?t:t.startsWith(`"`)&&t.endsWith(`"`)&&t.length>=2?`'${t.slice(1,-1).replace(/'/g,`''`)}'`:`'${t.replace(/'/g,`''`)}'`}var le=null;function H({anchorEl:e,title:t=``,placeholder:n=`Search...`,items:r=[],initialValue:i=``,onSelect:a,onCancel:o,width:s=320,maxHeight:c=260,searchable:l=!0,allowCustom:u=!1,emptyText:d=`No matching options found`}){ue();let f=r.map(e=>typeof e==`string`||typeof e==`number`?{name:String(e),value:String(e),desc:``,icon:``}:{name:String(e.name??e.value??``),value:e.value===void 0?String(e.name??``):String(e.value),desc:e.desc?String(e.desc):``,icon:e.icon||``,badge:e.badge||``,badgeClass:e.badgeClass||``,group:e.group||``}),p=document.createElement(`div`);p.className=`dropdown-picker-popover`,s&&(p.style.width=typeof s==`number`?`${s}px`:s),p.innerHTML=`
452
498
  ${l?`
453
499
  <div class="dropdown-picker-search-wrap">
454
500
  <span class="material-symbols-outlined dropdown-picker-search-icon">search</span>
@@ -476,7 +522,7 @@
476
522
  ${s}
477
523
  </div>
478
524
  </div>
479
- `}),h.innerHTML=r,h.querySelectorAll(`.dropdown-picker-item`).forEach(e=>{e.addEventListener(`mouseenter`,()=>{g=parseInt(e.dataset.index,10),x()}),e.addEventListener(`click`,t=>{t.stopPropagation();let n=parseInt(e.dataset.index,10);_[n]&&C(_[n])})}),S()},x=()=>{h.querySelectorAll(`.dropdown-picker-item`).forEach((e,t)=>{t===g?e.classList.add(`active`):e.classList.remove(`active`)})},S=()=>{let e=h.querySelector(`.dropdown-picker-item.active`);e&&e.scrollIntoView({block:`nearest`})},C=e=>{L(),a&&a(e.value,e)};(()=>{if(!e)return;let n=e.getBoundingClientRect(),r=s&&typeof s==`number`?s:320,i=c+(l?50:0)+(t?30:0),a=n.bottom+4,o=n.left;a+i>window.innerHeight-8&&(a=Math.max(8,n.top-i-4)),o+r>window.innerWidth-8&&(o=Math.max(8,window.innerWidth-r-8)),p.style.top=`${a}px`,p.style.left=`${o}px`})(),b(),m?(m.focus(),m.addEventListener(`input`,e=>{b(e.target.value)}),m.addEventListener(`keydown`,e=>{e.key===`ArrowDown`?(e.preventDefault(),_.length>0&&(g=(g+1)%_.length,x(),S())):e.key===`ArrowUp`?(e.preventDefault(),_.length>0&&(g=(g-1+_.length)%_.length,x(),S())):e.key===`Enter`?(e.preventDefault(),g>=0&&_[g]?C(_[g]):u&&m.value.trim()&&C({value:m.value.trim(),name:m.value.trim()})):e.key===`Escape`&&(e.preventDefault(),L(),o&&o())})):(p.tabIndex=-1,p.focus(),p.addEventListener(`keydown`,e=>{e.key===`ArrowDown`?(e.preventDefault(),_.length>0&&(g=(g+1)%_.length,x(),S())):e.key===`ArrowUp`?(e.preventDefault(),_.length>0&&(g=(g-1+_.length)%_.length,x(),S())):e.key===`Enter`?(e.preventDefault(),g>=0&&_[g]&&C(_[g])):e.key===`Escape`&&(e.preventDefault(),L(),o&&o())}));let w=t=>{!p.contains(t.target)&&!e.contains(t.target)&&(L(),o&&o())};setTimeout(()=>{document.addEventListener(`click`,w)},50),F={popover:p,cleanup:()=>{document.removeEventListener(`click`,w),p.parentNode&&p.remove(),F=null}}}function L(){F&&F.cleanup()}var R={sqlite:{category:`SQLITE DATA TYPES`,types:[{name:`INTEGER`,value:`INTEGER`,desc:`Signed integer (1 to 8 bytes, auto affinity)`,icon:`#`},{name:`TEXT`,value:`TEXT`,desc:`UTF-8 encoded text string`,icon:`abc`},{name:`VARCHAR(255)`,value:`VARCHAR(255)`,desc:`Variable-length character string`,icon:`abc`},{name:`BOOLEAN`,value:`BOOLEAN`,desc:`Logical boolean (stored as 0 or 1)`,icon:`toggle_on`},{name:`REAL`,value:`REAL`,desc:`Floating point number (8-byte IEEE 754)`,icon:`#`},{name:`NUMERIC`,value:`NUMERIC`,desc:`Exact / flexible numeric representation`,icon:`#`},{name:`DATETIME`,value:`DATETIME`,desc:`Date and time string (YYYY-MM-DD HH:MM:SS)`,icon:`schedule`},{name:`DATE`,value:`DATE`,desc:`Calendar date (YYYY-MM-DD)`,icon:`schedule`},{name:`TIME`,value:`TIME`,desc:`Time of day (HH:MM:SS)`,icon:`schedule`},{name:`JSON`,value:`JSON`,desc:`Textual JSON data (supports JSON functions)`,icon:`{}`},{name:`BLOB`,value:`BLOB`,desc:`Binary Large Object (raw binary data)`,icon:`data_array`},{name:`UUID`,value:`UUID`,desc:`Universally unique identifier (stored as TEXT)`,icon:`key`},{name:`ENUM`,value:`ENUM`,desc:`User-defined enumeration (CHECK constraint)`,icon:`list`}]},mysql:{category:`MYSQL DATA TYPES`,types:[{name:`INT`,value:`INT`,desc:`Standard 4-byte integer (-2.1B to 2.1B)`,icon:`#`},{name:`BIGINT`,value:`BIGINT`,desc:`Large 8-byte integer`,icon:`#`},{name:`TINYINT`,value:`TINYINT`,desc:`1-byte small integer (-128 to 127)`,icon:`#`},{name:`BOOLEAN`,value:`BOOLEAN`,desc:`Logical boolean (alias for TINYINT(1))`,icon:`toggle_on`},{name:`VARCHAR(255)`,value:`VARCHAR(255)`,desc:`Variable-length string with max limit`,icon:`abc`},{name:`TEXT`,value:`TEXT`,desc:`Standard text up to 65,535 bytes`,icon:`abc`},{name:`DECIMAL(10,2)`,value:`DECIMAL(10,2)`,desc:`Exact fixed-point numeric`,icon:`#`},{name:`FLOAT`,value:`FLOAT`,desc:`Single-precision floating-point number`,icon:`#`},{name:`DOUBLE`,value:`DOUBLE`,desc:`Double-precision floating-point number`,icon:`#`},{name:`DATETIME`,value:`DATETIME`,desc:`Date and time (1000-01-01 to 9999-12-31)`,icon:`schedule`},{name:`TIMESTAMP`,value:`TIMESTAMP`,desc:`UTC timestamp with automatic timezone conversion`,icon:`schedule`},{name:`DATE`,value:`DATE`,desc:`Calendar date (YYYY-MM-DD)`,icon:`schedule`},{name:`TIME`,value:`TIME`,desc:`Time value (HH:MM:SS)`,icon:`schedule`},{name:`JSON`,value:`JSON`,desc:`Native binary JSON document type`,icon:`{ }`},{name:`BLOB`,value:`BLOB`,desc:`Binary large object for raw data/files`,icon:`data_array`},{name:`ENUM`,value:`ENUM`,desc:`Enumeration with predefined string list`,icon:`list`}]},postgres:{category:`POSTGRES DATA TYPES`,types:[{name:`int4`,value:`int4`,desc:`Signed four-byte integer (integer)`,icon:`#`},{name:`int8`,value:`int8`,desc:`Signed eight-byte integer (bigint)`,icon:`#`},{name:`int2`,value:`int2`,desc:`Signed two-byte integer (smallint)`,icon:`#`},{name:`numeric`,value:`numeric`,desc:`Exact numeric of selectable precision`,icon:`#`},{name:`float8`,value:`float8`,desc:`Double precision floating-point number (8 bytes)`,icon:`#`},{name:`float4`,value:`float4`,desc:`Single precision floating-point number (4 bytes)`,icon:`#`},{name:`bool`,value:`boolean`,desc:`Logical boolean (true/false)`,icon:`toggle_on`},{name:`varchar(255)`,value:`varchar(255)`,desc:`Variable-length character string with limit`,icon:`abc`},{name:`text`,value:`text`,desc:`Variable-length character string`,icon:`abc`},{name:`uuid`,value:`uuid`,desc:`Universally unique identifier`,icon:`key`},{name:`timestamptz`,value:`timestamptz`,desc:`Date and time with time zone`,icon:`schedule`},{name:`timestamp`,value:`timestamp`,desc:`Date and time without time zone`,icon:`schedule`},{name:`date`,value:`date`,desc:`Calendar date (year, month, day)`,icon:`schedule`},{name:`time`,value:`time`,desc:`Time of day without time zone`,icon:`schedule`},{name:`timetz`,value:`timetz`,desc:`Time of day including time zone`,icon:`schedule`},{name:`jsonb`,value:`jsonb`,desc:`Binary JSON data, decomposed & indexable`,icon:`{ }`},{name:`json`,value:`json`,desc:`Textual JSON data`,icon:`{ }`},{name:`bytea`,value:`bytea`,desc:`Binary data ("byte array")`,icon:`data_array`},{name:`ENUM`,value:`ENUM`,desc:`User-defined enumeration values`,icon:`list`}]}};function ee(e){let t=(e||window.AppState?.dbType||`sqlite`).toLowerCase();return t.includes(`postgres`)||t.includes(`pg`)?`postgres`:t.includes(`mysql`)?`mysql`:`sqlite`}function te({anchorEl:e,initialValue:t=``,dialect:n,extraItems:r=[],onSelect:i,onCancel:a}){let o=R[ee(n)]||R.sqlite,s=[...o.types];Array.isArray(r)&&r.length>0&&s.unshift(...r),t&&!s.some(e=>e.value.toUpperCase()===t.trim().toUpperCase()||e.name.toUpperCase()===t.trim().toUpperCase())&&s.unshift({name:t.trim(),value:t.trim(),desc:`Current column type`,icon:`tune`}),I({anchorEl:e,title:o.category,placeholder:`Search types...`,items:s,initialValue:t,width:380,maxHeight:280,onSelect:i,onCancel:a})}function ne(e){let t=document.getElementById(`create-table-modal`);t&&t.remove();let n=(window.AppState?.dbType||`sqlite`).toLowerCase(),a=N,o=[{name:`id`,type:`INTEGER`,primaryKey:!0,nullable:!1,isUnique:!1,defaultValue:``,fkTarget:null},{name:`name`,type:`VARCHAR(255)`,primaryKey:!1,nullable:!0,isUnique:!1,defaultValue:``,fkTarget:null}],s=[],l=[],u={},d=null;r().then(e=>{Array.isArray(e)&&(s=e)}).catch(e=>console.warn(`Failed to preload tables for FK:`,e)),T().then(e=>{e?.success&&Array.isArray(e.data)&&(l=e.data,E(),w())}).catch(e=>console.warn(`Failed to preload enums:`,e)),t=document.createElement(`div`),t.id=`create-table-modal`,t.className=`modal-overlay`,t.innerHTML=`
525
+ `}),h.innerHTML=r,h.querySelectorAll(`.dropdown-picker-item`).forEach(e=>{e.addEventListener(`mouseenter`,()=>{g=parseInt(e.dataset.index,10),x()}),e.addEventListener(`click`,t=>{t.stopPropagation();let n=parseInt(e.dataset.index,10);_[n]&&C(_[n])})}),S()},x=()=>{h.querySelectorAll(`.dropdown-picker-item`).forEach((e,t)=>{t===g?e.classList.add(`active`):e.classList.remove(`active`)})},S=()=>{let e=h.querySelector(`.dropdown-picker-item.active`);e&&e.scrollIntoView({block:`nearest`})},C=e=>{ue(),a&&a(e.value,e)};(()=>{if(!e)return;let n=e.getBoundingClientRect(),r=s&&typeof s==`number`?s:320,i=c+(l?50:0)+(t?30:0),a=n.bottom+4,o=n.left;a+i>window.innerHeight-8&&(a=Math.max(8,n.top-i-4)),o+r>window.innerWidth-8&&(o=Math.max(8,window.innerWidth-r-8)),p.style.top=`${a}px`,p.style.left=`${o}px`})(),b(),m?(m.focus(),m.addEventListener(`input`,e=>{b(e.target.value)}),m.addEventListener(`keydown`,e=>{e.key===`ArrowDown`?(e.preventDefault(),_.length>0&&(g=(g+1)%_.length,x(),S())):e.key===`ArrowUp`?(e.preventDefault(),_.length>0&&(g=(g-1+_.length)%_.length,x(),S())):e.key===`Enter`?(e.preventDefault(),g>=0&&_[g]?C(_[g]):u&&m.value.trim()&&C({value:m.value.trim(),name:m.value.trim()})):e.key===`Escape`&&(e.preventDefault(),ue(),o&&o())})):(p.tabIndex=-1,p.focus(),p.addEventListener(`keydown`,e=>{e.key===`ArrowDown`?(e.preventDefault(),_.length>0&&(g=(g+1)%_.length,x(),S())):e.key===`ArrowUp`?(e.preventDefault(),_.length>0&&(g=(g-1+_.length)%_.length,x(),S())):e.key===`Enter`?(e.preventDefault(),g>=0&&_[g]&&C(_[g])):e.key===`Escape`&&(e.preventDefault(),ue(),o&&o())}));let w=t=>{!p.contains(t.target)&&!e.contains(t.target)&&(ue(),o&&o())};setTimeout(()=>{document.addEventListener(`click`,w)},50),le={popover:p,cleanup:()=>{document.removeEventListener(`click`,w),p.parentNode&&p.remove(),le=null}}}function ue(){le&&le.cleanup()}var de={sqlite:{category:`SQLITE DATA TYPES`,types:[{name:`INTEGER`,value:`INTEGER`,desc:`Signed integer (1 to 8 bytes, auto affinity)`,icon:`#`},{name:`TEXT`,value:`TEXT`,desc:`UTF-8 encoded text string`,icon:`abc`},{name:`VARCHAR(255)`,value:`VARCHAR(255)`,desc:`Variable-length character string`,icon:`abc`},{name:`BOOLEAN`,value:`BOOLEAN`,desc:`Logical boolean (stored as 0 or 1)`,icon:`toggle_on`},{name:`REAL`,value:`REAL`,desc:`Floating point number (8-byte IEEE 754)`,icon:`#`},{name:`NUMERIC`,value:`NUMERIC`,desc:`Exact / flexible numeric representation`,icon:`#`},{name:`DATETIME`,value:`DATETIME`,desc:`Date and time string (YYYY-MM-DD HH:MM:SS)`,icon:`schedule`},{name:`DATE`,value:`DATE`,desc:`Calendar date (YYYY-MM-DD)`,icon:`schedule`},{name:`TIME`,value:`TIME`,desc:`Time of day (HH:MM:SS)`,icon:`schedule`},{name:`JSON`,value:`JSON`,desc:`Textual JSON data (supports JSON functions)`,icon:`{}`},{name:`BLOB`,value:`BLOB`,desc:`Binary Large Object (raw binary data)`,icon:`data_array`},{name:`UUID`,value:`UUID`,desc:`Universally unique identifier (stored as TEXT)`,icon:`key`},{name:`ENUM`,value:`ENUM`,desc:`User-defined enumeration (CHECK constraint)`,icon:`list`}]},mysql:{category:`MYSQL DATA TYPES`,types:[{name:`INT`,value:`INT`,desc:`Standard 4-byte integer (-2.1B to 2.1B)`,icon:`#`},{name:`BIGINT`,value:`BIGINT`,desc:`Large 8-byte integer`,icon:`#`},{name:`TINYINT`,value:`TINYINT`,desc:`1-byte small integer (-128 to 127)`,icon:`#`},{name:`BOOLEAN`,value:`BOOLEAN`,desc:`Logical boolean (alias for TINYINT(1))`,icon:`toggle_on`},{name:`VARCHAR(255)`,value:`VARCHAR(255)`,desc:`Variable-length string with max limit`,icon:`abc`},{name:`TEXT`,value:`TEXT`,desc:`Standard text up to 65,535 bytes`,icon:`abc`},{name:`DECIMAL(10,2)`,value:`DECIMAL(10,2)`,desc:`Exact fixed-point numeric`,icon:`#`},{name:`FLOAT`,value:`FLOAT`,desc:`Single-precision floating-point number`,icon:`#`},{name:`DOUBLE`,value:`DOUBLE`,desc:`Double-precision floating-point number`,icon:`#`},{name:`DATETIME`,value:`DATETIME`,desc:`Date and time (1000-01-01 to 9999-12-31)`,icon:`schedule`},{name:`TIMESTAMP`,value:`TIMESTAMP`,desc:`UTC timestamp with automatic timezone conversion`,icon:`schedule`},{name:`DATE`,value:`DATE`,desc:`Calendar date (YYYY-MM-DD)`,icon:`schedule`},{name:`TIME`,value:`TIME`,desc:`Time value (HH:MM:SS)`,icon:`schedule`},{name:`JSON`,value:`JSON`,desc:`Native binary JSON document type`,icon:`{ }`},{name:`BLOB`,value:`BLOB`,desc:`Binary large object for raw data/files`,icon:`data_array`},{name:`ENUM`,value:`ENUM`,desc:`Enumeration with predefined string list`,icon:`list`}]},postgres:{category:`POSTGRES DATA TYPES`,types:[{name:`int4`,value:`int4`,desc:`Signed four-byte integer (integer)`,icon:`#`},{name:`int8`,value:`int8`,desc:`Signed eight-byte integer (bigint)`,icon:`#`},{name:`int2`,value:`int2`,desc:`Signed two-byte integer (smallint)`,icon:`#`},{name:`numeric`,value:`numeric`,desc:`Exact numeric of selectable precision`,icon:`#`},{name:`float8`,value:`float8`,desc:`Double precision floating-point number (8 bytes)`,icon:`#`},{name:`float4`,value:`float4`,desc:`Single precision floating-point number (4 bytes)`,icon:`#`},{name:`bool`,value:`boolean`,desc:`Logical boolean (true/false)`,icon:`toggle_on`},{name:`varchar(255)`,value:`varchar(255)`,desc:`Variable-length character string with limit`,icon:`abc`},{name:`text`,value:`text`,desc:`Variable-length character string`,icon:`abc`},{name:`uuid`,value:`uuid`,desc:`Universally unique identifier`,icon:`key`},{name:`timestamptz`,value:`timestamptz`,desc:`Date and time with time zone`,icon:`schedule`},{name:`timestamp`,value:`timestamp`,desc:`Date and time without time zone`,icon:`schedule`},{name:`date`,value:`date`,desc:`Calendar date (year, month, day)`,icon:`schedule`},{name:`time`,value:`time`,desc:`Time of day without time zone`,icon:`schedule`},{name:`timetz`,value:`timetz`,desc:`Time of day including time zone`,icon:`schedule`},{name:`jsonb`,value:`jsonb`,desc:`Binary JSON data, decomposed & indexable`,icon:`{ }`},{name:`json`,value:`json`,desc:`Textual JSON data`,icon:`{ }`},{name:`bytea`,value:`bytea`,desc:`Binary data ("byte array")`,icon:`data_array`},{name:`ENUM`,value:`ENUM`,desc:`User-defined enumeration values`,icon:`list`}]},mssql:{category:`SQL SERVER DATA TYPES`,types:[{name:`INT`,value:`INT`,desc:`Standard 4-byte integer (-2B to +2B)`,icon:`#`},{name:`BIGINT`,value:`BIGINT`,desc:`8-byte integer for large scale IDs`,icon:`#`},{name:`SMALLINT`,value:`SMALLINT`,desc:`2-byte integer (-32,768 to 32,767)`,icon:`#`},{name:`TINYINT`,value:`TINYINT`,desc:`1-byte unsigned integer (0 to 255)`,icon:`#`},{name:`BIT`,value:`BIT`,desc:`Integer with value 1, 0, or NULL (boolean)`,icon:`toggle_on`},{name:`DECIMAL(18,2)`,value:`DECIMAL(18,2)`,desc:`Fixed precision numeric data`,icon:`#`},{name:`FLOAT`,value:`FLOAT`,desc:`Approximate numeric floating point`,icon:`#`},{name:`NVARCHAR(255)`,value:`NVARCHAR(255)`,desc:`Variable-length Unicode string`,icon:`abc`},{name:`NVARCHAR(MAX)`,value:`NVARCHAR(MAX)`,desc:`Variable-length Unicode text (up to 2GB)`,icon:`abc`},{name:`VARCHAR(255)`,value:`VARCHAR(255)`,desc:`Variable-length non-Unicode string`,icon:`abc`},{name:`DATETIME2`,value:`DATETIME2`,desc:`Date and time with high fractional precision`,icon:`schedule`},{name:`DATE`,value:`DATE`,desc:`Calendar date (YYYY-MM-DD)`,icon:`schedule`},{name:`TIME`,value:`TIME`,desc:`Time of day (hh:mm:ss.nnnnnnn)`,icon:`schedule`},{name:`UNIQUEIDENTIFIER`,value:`UNIQUEIDENTIFIER`,desc:`16-byte GUID / UUID`,icon:`key`},{name:`VARBINARY(MAX)`,value:`VARBINARY(MAX)`,desc:`Variable-length binary data (blobs)`,icon:`data_array`}]},mongodb:{category:`MONGODB BSON DATA TYPES`,types:[{name:`ObjectId`,value:`ObjectId`,desc:`12-byte BSON unique identifier (default _id)`,icon:`key`},{name:`String`,value:`String`,desc:`UTF-8 encoded string`,icon:`abc`},{name:`Int32`,value:`Int32`,desc:`32-bit signed integer`,icon:`#`},{name:`Int64`,value:`Int64`,desc:`64-bit signed integer (Long)`,icon:`#`},{name:`Double`,value:`Double`,desc:`64-bit IEEE 754 floating point`,icon:`#`},{name:`Boolean`,value:`Boolean`,desc:`Logical true/false boolean value`,icon:`toggle_on`},{name:`Date`,value:`Date`,desc:`BSON Date/Time in UTC milliseconds`,icon:`schedule`},{name:`Object`,value:`Object`,desc:`Embedded nested BSON document`,icon:`{ }`},{name:`Array`,value:`Array`,desc:`List or set of embedded values/documents`,icon:`[ ]`},{name:`Binary`,value:`Binary`,desc:`BSON binary data payload`,icon:`data_array`}]}};function fe(e){let t=(e||window.AppState?.dbType||`sqlite`).toLowerCase();return t.includes(`postgres`)||t.includes(`pg`)?`postgres`:t.includes(`mysql`)?`mysql`:t.includes(`mssql`)||t.includes(`sqlserver`)?`mssql`:t.includes(`mongo`)?`mongodb`:`sqlite`}function pe({anchorEl:e,initialValue:t=``,dialect:n,extraItems:r=[],onSelect:i,onCancel:a}){let o=de[fe(n)]||de.sqlite,s=[...o.types];Array.isArray(r)&&r.length>0&&s.unshift(...r),t&&!s.some(e=>e.value.toUpperCase()===t.trim().toUpperCase()||e.name.toUpperCase()===t.trim().toUpperCase())&&s.unshift({name:t.trim(),value:t.trim(),desc:`Current column type`,icon:`tune`}),H({anchorEl:e,title:o.category,placeholder:`Search types...`,items:s,initialValue:t,width:380,maxHeight:280,onSelect:i,onCancel:a})}function me(e){let t=document.getElementById(`create-table-modal`);t&&t.remove();let n=(window.AppState?.dbType||`sqlite`).toLowerCase(),r=se,o=[{name:`id`,type:`INTEGER`,primaryKey:!0,nullable:!1,isUnique:!1,defaultValue:``,fkTarget:null},{name:`name`,type:`VARCHAR(255)`,primaryKey:!1,nullable:!0,isUnique:!1,defaultValue:``,fkTarget:null}],s=[],c=[],l={},d=null;i().then(e=>{Array.isArray(e)&&(s=e)}).catch(e=>console.warn(`Failed to preload tables for FK:`,e)),k().then(e=>{e?.success&&Array.isArray(e.data)&&(c=e.data,T(),w())}).catch(e=>console.warn(`Failed to preload enums:`,e)),t=document.createElement(`div`),t.id=`create-table-modal`,t.className=`modal-overlay`,t.innerHTML=`
480
526
  <div class="modal-container create-table-modal-container">
481
527
  <div class="modal-header">
482
528
  <div class="modal-title-wrap">
@@ -582,11 +628,11 @@
582
628
  </button>
583
629
  </div>
584
630
  </div>
585
- `,document.body.appendChild(t);let f=document.getElementById(`create-table-columns-container`),p=document.getElementById(`new-table-name-input`),m=document.getElementById(`column-count-label`),h=document.getElementById(`submit-create-table-btn`),g=document.getElementById(`submit-create-table-text`),_=document.getElementById(`table-name-error`),v=document.getElementById(`table-sql-preview-code`),y=document.getElementById(`table-sql-preview-section`),b=document.getElementById(`table-sql-preview-toggle`),x=document.getElementById(`table-sql-preview-arrow`),S=document.getElementById(`copy-table-sql-btn`);b.onclick=()=>{let e=y.classList.toggle(`collapsed`);x.textContent=e?`expand_more`:`expand_less`},S.onclick=()=>{v.textContent&&(navigator.clipboard.writeText(v.textContent),window.showToast?.(`SQL copied to clipboard!`,`success`))};function C(e){return n===`mysql`?`\`${e}\``:`"${e}"`}function w(){let e=(p.value.trim()||`table_name`).trim(),t=[],r=[];n===`postgres`&&o.forEach(e=>{if(e.isNewEnum&&e.enumValues&&e.enumValues.length>0){let t=(e.newEnumName||e.type||`CustomEnum`).trim(),n=e.enumValues.map(e=>`'${e.replace(/'/g,`''`)}'`).join(`, `);r.push(`CREATE TYPE ${C(t)} AS ENUM (${n});`)}}),o.forEach(e=>{let r=e.name?C(e.name):`"column"`,i=(e.type||`VARCHAR(255)`).toLowerCase(),a=e.type||`VARCHAR(255)`,o=e.enumValues&&e.enumValues.length>0;if(n===`sqlite`?(o?a=`TEXT CHECK(${r} IN (${e.enumValues.map(e=>`'${e.replace(/'/g,`''`)}'`).join(`, `)}))`:i===`integer`||i===`int`?a=`INTEGER`:i===`text`||i===`string`?a=`TEXT`:i.startsWith(`varchar`)?a=e.type.toUpperCase():i===`boolean`||i===`bool`?a=`BOOLEAN`:[`decimal`,`numeric`,`float`,`double`,`real`].includes(i)||i.startsWith(`decimal`)?a=`REAL`:i===`date`?a=`DATE`:i===`datetime`||i===`timestamp`?a=`DATETIME`:i===`blob`?a=`BLOB`:(i===`json`||i===`uuid`)&&(a=`TEXT`),e.primaryKey&&(i.includes(`int`)||a===`INTEGER`)?a=`INTEGER PRIMARY KEY AUTOINCREMENT`:e.primaryKey?a+=` PRIMARY KEY`:(e.nullable||(a+=` NOT NULL`),e.isUnique&&(a+=` UNIQUE`))):n===`postgres`?e.primaryKey&&(i===`integer`||i===`int`)?a=`SERIAL PRIMARY KEY`:(o||e.isExistingEnum||e.isNewEnum?a=C(e.isNewEnum?e.newEnumName||e.type||`CustomEnum`:e.type):i===`integer`||i===`int`?a=`INTEGER`:i===`text`||i===`string`?a=`TEXT`:i.startsWith(`varchar`)?a=e.type.toUpperCase():i===`boolean`||i===`bool`?a=`BOOLEAN`:i===`decimal`||i===`numeric`||i.startsWith(`decimal`)?a=e.type.toUpperCase().includes(`(`)?e.type.toUpperCase():`NUMERIC`:i===`datetime`||i===`timestamp`?a=`TIMESTAMP`:i===`date`?a=`DATE`:i===`real`?a=`REAL`:i===`json`?a=`JSONB`:i===`blob`?a=`BYTEA`:i===`uuid`&&(a=`UUID`),e.primaryKey&&(a+=` PRIMARY KEY`),!e.nullable&&!e.primaryKey&&(a+=` NOT NULL`),e.isUnique&&!e.primaryKey&&(a+=` UNIQUE`)):(o?a=`ENUM(${e.enumValues.map(e=>`'${e.replace(/'/g,`''`)}'`).join(`, `)})`:i===`integer`||i===`int`?a=`INT`:i===`text`||i===`string`?a=`TEXT`:i.startsWith(`varchar`)?a=e.type.toUpperCase():i===`boolean`||i===`bool`?a=`BOOLEAN`:i===`decimal`||i===`numeric`||i.startsWith(`decimal`)?a=e.type.toUpperCase().includes(`(`)?e.type.toUpperCase():`DECIMAL(10,2)`:i===`datetime`||i===`timestamp`?a=`DATETIME`:i===`date`?a=`DATE`:i===`real`?a=`FLOAT`:i===`json`?a=`JSON`:i===`blob`?a=`BLOB`:i===`uuid`&&(a=`VARCHAR(36)`),e.primaryKey&&(i.includes(`int`)||a===`INT`)?a+=` AUTO_INCREMENT PRIMARY KEY`:e.primaryKey&&(a+=` PRIMARY KEY`),!e.nullable&&!e.primaryKey&&(a+=` NOT NULL`),e.isUnique&&!e.primaryKey&&(a+=` UNIQUE`)),e.defaultValue&&!e.defaultValue.startsWith(`FK ->`)){let t=P(e.defaultValue);t!==null&&(a+=` DEFAULT ${t}`)}t.push(` ${r} ${a}`)}),o.forEach(e=>{if(e.fkTarget&&e.fkTarget.table&&e.fkTarget.column){let n=` FOREIGN KEY (${C(e.name||`col`)}) REFERENCES ${C(e.fkTarget.table)}(${C(e.fkTarget.column)})`;e.fkTarget.onDelete&&e.fkTarget.onDelete!==`NO ACTION`&&(n+=` ON DELETE ${e.fkTarget.onDelete}`),e.fkTarget.onUpdate&&e.fkTarget.onUpdate!==`NO ACTION`&&(n+=` ON UPDATE ${e.fkTarget.onUpdate}`),t.push(n)}});let i=``;r.length>0&&(i+=r.join(`
631
+ `,document.body.appendChild(t);let f=document.getElementById(`create-table-columns-container`),p=document.getElementById(`new-table-name-input`),m=document.getElementById(`column-count-label`),h=document.getElementById(`submit-create-table-btn`),g=document.getElementById(`submit-create-table-text`),_=document.getElementById(`table-name-error`),v=document.getElementById(`table-sql-preview-code`),y=document.getElementById(`table-sql-preview-section`),b=document.getElementById(`table-sql-preview-toggle`),x=document.getElementById(`table-sql-preview-arrow`),S=document.getElementById(`copy-table-sql-btn`);b.onclick=()=>{let e=y.classList.toggle(`collapsed`);x.textContent=e?`expand_more`:`expand_less`},S.onclick=()=>{v.textContent&&(navigator.clipboard.writeText(v.textContent),window.showToast?.(`SQL copied to clipboard!`,`success`))};function C(e){return n===`mysql`?`\`${e}\``:n===`mssql`?`[${e}]`:`"${e}"`}function w(){let e=(p.value.trim()||`table_name`).trim(),t=[],r=[];n===`postgres`&&o.forEach(e=>{if(e.isNewEnum&&e.enumValues&&e.enumValues.length>0){let t=(e.newEnumName||e.type||`CustomEnum`).trim(),n=e.enumValues.map(e=>`'${e.replace(/'/g,`''`)}'`).join(`, `);r.push(`CREATE TYPE ${C(t)} AS ENUM (${n});`)}});let i=o.filter(e=>!!e.primaryKey),a=i.length>1;if(o.forEach(e=>{let r=e.name?C(e.name):`"column"`,i=(e.type||`VARCHAR(255)`).toLowerCase(),o=e.type||`VARCHAR(255)`,s=e.enumValues&&e.enumValues.length>0,c=!!(e.fkTarget&&e.fkTarget.table&&e.fkTarget.column);if(n===`sqlite`?(s?o=`TEXT CHECK(${r} IN (${e.enumValues.map(e=>`'${e.replace(/'/g,`''`)}'`).join(`, `)}))`:i===`integer`||i===`int`?o=`INTEGER`:i===`text`||i===`string`?o=`TEXT`:i.startsWith(`varchar`)?o=e.type.toUpperCase():i===`boolean`||i===`bool`?o=`BOOLEAN`:[`decimal`,`numeric`,`float`,`double`,`real`].includes(i)||i.startsWith(`decimal`)?o=`REAL`:i===`date`?o=`DATE`:i===`datetime`||i===`timestamp`?o=`DATETIME`:i===`blob`?o=`BLOB`:(i===`json`||i===`uuid`)&&(o=`TEXT`),e.primaryKey&&!a?!c&&(i.includes(`int`)||o===`INTEGER`)?o=`INTEGER PRIMARY KEY AUTOINCREMENT`:o+=` PRIMARY KEY`:((!e.nullable||e.primaryKey&&a)&&(o+=` NOT NULL`),e.isUnique&&!e.primaryKey&&(o+=` UNIQUE`))):n===`postgres`?e.primaryKey&&!a&&!c&&(i===`integer`||i===`int`)?o=`SERIAL PRIMARY KEY`:(s||e.isExistingEnum||e.isNewEnum?o=C(e.isNewEnum?e.newEnumName||e.type||`CustomEnum`:e.type):i===`integer`||i===`int`?o=`INTEGER`:i===`text`||i===`string`?o=`TEXT`:i.startsWith(`varchar`)?o=e.type.toUpperCase():i===`boolean`||i===`bool`?o=`BOOLEAN`:i===`decimal`||i===`numeric`||i.startsWith(`decimal`)?o=e.type.toUpperCase().includes(`(`)?e.type.toUpperCase():`NUMERIC`:i===`datetime`||i===`timestamp`?o=`TIMESTAMP`:i===`date`?o=`DATE`:i===`real`?o=`REAL`:i===`json`?o=`JSONB`:i===`blob`?o=`BYTEA`:i===`uuid`&&(o=`UUID`),e.primaryKey&&!a&&(o+=` PRIMARY KEY`),(!e.nullable||e.primaryKey&&a)&&(o+=` NOT NULL`),e.isUnique&&!e.primaryKey&&(o+=` UNIQUE`)):n===`mssql`?(s?o=`NVARCHAR(255) CHECK(${r} IN (${e.enumValues.map(e=>`'${e.replace(/'/g,`''`)}'`).join(`, `)}))`:i===`integer`||i===`int`?o=`INT`:i===`text`||i===`string`?o=`NVARCHAR(MAX)`:i.startsWith(`varchar`)?o=e.type.toUpperCase():i===`boolean`||i===`bool`?o=`BIT`:i===`decimal`||i===`numeric`||i.startsWith(`decimal`)?o=e.type.toUpperCase().includes(`(`)?e.type.toUpperCase():`DECIMAL(18,2)`:i===`datetime`||i===`timestamp`?o=`DATETIME2`:i===`date`?o=`DATE`:i===`real`?o=`FLOAT`:i===`uuid`&&(o=`UNIQUEIDENTIFIER`),e.primaryKey&&!a&&(!c&&(i.includes(`int`)||o===`INT`)?o+=` IDENTITY(1,1) PRIMARY KEY`:o+=` PRIMARY KEY`),(!e.nullable||e.primaryKey&&a)&&(o+=` NOT NULL`),e.isUnique&&!e.primaryKey&&(o+=` UNIQUE`)):(s?o=`ENUM(${e.enumValues.map(e=>`'${e.replace(/'/g,`''`)}'`).join(`, `)})`:i===`integer`||i===`int`?o=`INT`:i===`text`||i===`string`?o=`TEXT`:i.startsWith(`varchar`)?o=e.type.toUpperCase():i===`boolean`||i===`bool`?o=`BOOLEAN`:i===`decimal`||i===`numeric`||i.startsWith(`decimal`)?o=e.type.toUpperCase().includes(`(`)?e.type.toUpperCase():`DECIMAL(10,2)`:i===`datetime`||i===`timestamp`?o=`DATETIME`:i===`date`?o=`DATE`:i===`real`?o=`FLOAT`:i===`json`?o=`JSON`:i===`blob`?o=`BLOB`:i===`uuid`&&(o=`VARCHAR(36)`),e.primaryKey&&!a&&(!c&&(i.includes(`int`)||o===`INT`)?o+=` AUTO_INCREMENT PRIMARY KEY`:o+=` PRIMARY KEY`),(!e.nullable||e.primaryKey&&a)&&(o+=` NOT NULL`),e.isUnique&&!e.primaryKey&&(o+=` UNIQUE`)),e.defaultValue&&!e.defaultValue.startsWith(`FK ->`)){let t=ce(e.defaultValue);t!==null&&(o+=` DEFAULT ${t}`)}t.push(` ${r} ${o}`)}),a){let e=i.map(e=>C(e.name||`col`)).join(`, `);t.push(` PRIMARY KEY (${e})`)}o.forEach(e=>{if(e.fkTarget&&e.fkTarget.table&&e.fkTarget.column){let n=` FOREIGN KEY (${C(e.name||`col`)}) REFERENCES ${C(e.fkTarget.table)}(${C(e.fkTarget.column)})`;e.fkTarget.onDelete&&e.fkTarget.onDelete!==`NO ACTION`&&(n+=` ON DELETE ${e.fkTarget.onDelete}`),e.fkTarget.onUpdate&&e.fkTarget.onUpdate!==`NO ACTION`&&(n+=` ON UPDATE ${e.fkTarget.onUpdate}`),t.push(n)}});let s=``;r.length>0&&(s+=r.join(`
586
632
  `)+`
587
633
 
588
- `),i+=`CREATE TABLE ${C(e)} (\n${t.join(`,
589
- `)}\n);`,v.textContent=i}function E(){f.innerHTML=``,m.textContent=o.length.toString(),o.forEach((e,t)=>{let r=document.createElement(`div`);r.className=`table-column-row`;let i=!!(e.fkTarget&&e.fkTarget.table&&e.fkTarget.column),p=i&&e.fkTarget.onDelete&&e.fkTarget.onDelete!==`NO ACTION`?` (${e.fkTarget.onDelete})`:``,m=i?`${e.fkTarget.table}.${e.fkTarget.column}${p}`:`+ FK`,h=e.type||a[0]||`INTEGER`;e.isNewEnum?h=`ENUM (${e.newEnumName||`Custom`})`:e.isExistingEnum&&(h=`${e.type} (Enum)`);let g=``;e.isNewEnum&&(g=`
634
+ `),s+=`CREATE TABLE ${C(e)} (\n${t.join(`,
635
+ `)}\n);`,v.textContent=s}function T(){f.innerHTML=``,m.textContent=o.length.toString(),o.forEach((e,t)=>{let i=document.createElement(`div`);i.className=`table-column-row`;let a=!!(e.fkTarget&&e.fkTarget.table&&e.fkTarget.column),p=a&&e.fkTarget.onDelete&&e.fkTarget.onDelete!==`NO ACTION`?` (${e.fkTarget.onDelete})`:``,m=a?`${e.fkTarget.table}.${e.fkTarget.column}${p}`:`+ FK`,h=e.type||r[0]||`INTEGER`;e.isNewEnum?h=`ENUM (${e.newEnumName||`Custom`})`:e.isExistingEnum&&(h=`${e.type} (Enum)`);let g=``;e.isNewEnum&&(g=`
590
636
  <div class="col-new-enum-panel" data-index="${t}">
591
637
  <div class="col-new-enum-field">
592
638
  <span class="col-new-enum-label">
@@ -602,7 +648,7 @@
602
648
  </span>
603
649
  <input type="text" class="table-col-input new-enum-values-input" data-index="${t}" placeholder="e.g. PENDING, PAID, CANCELLED" value="${e.newEnumValuesStr||(e.enumValues?e.enumValues.join(`, `):``)}" />
604
650
  </div>
605
- </div>`),r.innerHTML=`
651
+ </div>`),i.innerHTML=`
606
652
  <div>
607
653
  <input type="text" class="table-col-input col-name-input" data-index="${t}" value="${e.name}" placeholder="column_name" />
608
654
  </div>
@@ -627,8 +673,8 @@
627
673
  <input type="text" class="table-col-input col-default-input" data-index="${t}" value="${e.defaultValue||``}" placeholder="NULL, 'val'..." />
628
674
  </div>
629
675
  <div class="table-col-fk-wrap" data-index="${t}">
630
- <button type="button" class="table-col-fk-btn col-fk-btn ${i?`is-active`:``}" data-index="${t}" title="${i?`Foreign Key: ${m}`:`Configure Foreign Key`}">
631
- <span class="material-symbols-outlined">${i?`link`:`add_link`}</span>
676
+ <button type="button" class="table-col-fk-btn col-fk-btn ${a?`is-active`:``}" data-index="${t}" title="${a?`Foreign Key: ${m}`:`Configure Foreign Key`}">
677
+ <span class="material-symbols-outlined">${a?`link`:`add_link`}</span>
632
678
  <span style="overflow: hidden; text-overflow: ellipsis;">${m}</span>
633
679
  </button>
634
680
  <div class="table-fk-popover" id="fk-popover-${t}" style="display: ${d===t?`flex`:`none`};">
@@ -672,7 +718,7 @@
672
718
  </div>
673
719
  </div>
674
720
  <div style="display: flex; justify-content: space-between; align-items: center; margin-top: 4px;">
675
- <button type="button" class="btn-secondary fk-clear-btn" style="padding: 3px 8px; font-size: 11px; color: var(--color-error);" ${i?``:`disabled`}>Clear FK</button>
721
+ <button type="button" class="btn-secondary fk-clear-btn" style="padding: 3px 8px; font-size: 11px; color: var(--color-error);" ${a?``:`disabled`}>Clear FK</button>
676
722
  <button type="button" class="btn-primary fk-done-btn" style="padding: 3px 10px; font-size: 11px;">Done</button>
677
723
  </div>
678
724
  </div>
@@ -689,12 +735,351 @@
689
735
  </button>
690
736
  </div>
691
737
  ${g}
692
- `;let _=r.querySelector(`.col-name-input`);_.oninput=e=>{o[t].name=e.target.value.trim(),w()};let v=r.querySelector(`.col-type-trigger`);v.onclick=r=>{r.stopPropagation();let i=l.map(e=>({name:e.name,value:`__ENUM_EXISTING__:${e.name}`,desc:`Existing Enum (${e.values.slice(0,3).join(`, `)}${e.values.length>3?`...`:``})`,icon:`list`,group:`EXISTING DATABASE ENUMS`}));te({anchorEl:v,initialValue:e.isNewEnum?`ENUM`:e.isExistingEnum?`__ENUM_EXISTING__:${e.type}`:e.type,dialect:n,extraItems:i,onSelect:e=>{if(e===`ENUM`||e===`__NEW_ENUM__`){if(o[t].isNewEnum=!0,o[t].isExistingEnum=!1,!o[t].newEnumName){let e=o[t].name?o[t].name.charAt(0).toUpperCase()+o[t].name.slice(1)+`Enum`:`CustomEnum`;o[t].newEnumName=e,o[t].type=e}o[t].enumValues||(o[t].enumValues=[])}else if(e.startsWith(`__ENUM_EXISTING__:`)){let n=e.slice(18);o[t].isNewEnum=!1,o[t].isExistingEnum=!0,o[t].type=n;let r=l.find(e=>e.name===n);o[t].enumValues=r?[...r.values]:[]}else o[t].isNewEnum=!1,o[t].isExistingEnum=!1,o[t].type=e,o[t].enumValues=void 0;E(),w()}})};let y=r.querySelector(`.new-enum-name-input`);y&&(y.oninput=e=>{let n=e.target.value.trim();o[t].newEnumName=n,o[t].type=n||`CustomEnum`,w()});let b=r.querySelector(`.new-enum-values-input`);b&&(b.oninput=e=>{let n=e.target.value;o[t].newEnumValuesStr=n,o[t].enumValues=n.split(`,`).map(e=>e.trim().replace(/^['"]|['"]$/g,``)).filter(Boolean),w()});let x=r.querySelector(`.col-pk-check`);x.onchange=e=>{let n=e.target.checked;o[t].primaryKey=n,n&&(o[t].nullable=!1,o[t].isUnique=!1),E(),w()};let S=r.querySelector(`.col-null-check`);S.onchange=e=>{o[t].nullable=e.target.checked,w()};let C=r.querySelector(`.col-unique-check`);C.onchange=e=>{o[t].isUnique=e.target.checked,w()};let T=r.querySelector(`.col-default-input`);T.oninput=e=>{o[t].defaultValue=e.target.value.trim(),w()};let D=r.querySelector(`.col-fk-btn`),O=r.querySelector(`.table-fk-popover`),k=r.querySelector(`.fk-target-table-select`),A=r.querySelector(`.fk-target-column-select`),j=r.querySelector(`.fk-on-delete-select`),M=r.querySelector(`.fk-on-update-select`),N=r.querySelector(`.fk-popover-close`),P=r.querySelector(`.fk-clear-btn`),F=r.querySelector(`.fk-done-btn`),L=e.fkTarget?.table||``,R=e.fkTarget?.column||``,ee=e.fkTarget?.onDelete||`NO ACTION`,ne=e.fkTarget?.onUpdate||`NO ACTION`;async function re(e){if(!e){if(A){let e=A.querySelector(`.fk-col-display`);e&&(e.textContent=`-- Select Column --`),A.disabled=!0}return}if(A){A.disabled=!1;let e=A.querySelector(`.fk-col-display`);e&&(e.textContent=`Loading...`)}if(!u[e])try{let t=await c(e);Array.isArray(t)?u[e]=t.map(e=>e.name):t&&Array.isArray(t.columns)?u[e]=t.columns.map(e=>e.name):u[e]=[`id`]}catch{u[e]=[`id`]}let t=u[e]||[];if((!R||!t.includes(R))&&(R=t.find(e=>e.toLowerCase()===`id`)||t[0]||``),A){let e=A.querySelector(`.fk-col-display`);e&&(e.textContent=R||`-- Select Column --`)}}k.onclick=e=>{e.stopPropagation(),I({anchorEl:k,title:`Select Target Table`,searchable:!0,placeholder:`Search tables...`,initialValue:L,items:s.map(e=>({name:e,value:e,icon:`table_chart`})),onSelect:async e=>{L=e;let t=k.querySelector(`.fk-table-display`);t&&(t.textContent=e),R=``,await re(e)}})},A.onclick=e=>{if(e.stopPropagation(),!L)return;let t=u[L]||[];I({anchorEl:A,title:`Columns in ${L}`,searchable:!0,placeholder:`Search columns...`,initialValue:R,items:t.map(e=>({name:e,value:e,icon:`tag`})),onSelect:e=>{R=e;let t=A.querySelector(`.fk-col-display`);t&&(t.textContent=e)}})},j.onclick=e=>{e.stopPropagation(),I({anchorEl:j,title:`ON DELETE Action`,searchable:!1,initialValue:ee,items:[`NO ACTION`,`CASCADE`,`SET NULL`,`RESTRICT`],onSelect:e=>{ee=e;let t=j.querySelector(`.fk-on-delete-display`);t&&(t.textContent=e)}})},M.onclick=e=>{e.stopPropagation(),I({anchorEl:M,title:`ON UPDATE Action`,searchable:!1,initialValue:ne,items:[`NO ACTION`,`CASCADE`,`RESTRICT`,`SET NULL`],onSelect:e=>{ne=e;let t=M.querySelector(`.fk-on-update-display`);t&&(t.textContent=e)}})},D.onclick=n=>{if(n.stopPropagation(),d===t)d=null,O.style.display=`none`;else{d=t,E();let n=document.getElementById(`fk-popover-${t}`);if(n){let r=e.fkTarget?.table||``;r&&re(r);let i=document.querySelector(`.col-fk-btn[data-index="${t}"]`);if(i){let e=i.getBoundingClientRect();n.style.top=`${e.bottom+4}px`,n.style.left=`${Math.max(10,Math.min(e.right-270,window.innerWidth-280))}px`}}}},N.onclick=e=>{e.stopPropagation(),d=null,O.style.display=`none`},P.onclick=e=>{e.stopPropagation(),o[t].fkTarget=null,d=null,E(),w()},F.onclick=e=>{e.stopPropagation(),L&&R?o[t].fkTarget={table:L,column:R,onDelete:ee===`NO ACTION`?void 0:ee,onUpdate:ne===`NO ACTION`?void 0:ne}:o[t].fkTarget=null,d=null,E(),w()};let ie=r.querySelector(`.btn-move-up`);ie&&t>0&&(ie.onclick=e=>{e.stopPropagation();let n=o[t];o[t]=o[t-1],o[t-1]=n,d!==null&&(d=null),E(),w()});let ae=r.querySelector(`.btn-move-down`);ae&&t<o.length-1&&(ae.onclick=e=>{e.stopPropagation();let n=o[t];o[t]=o[t+1],o[t+1]=n,d!==null&&(d=null),E(),w()});let oe=r.querySelector(`.btn-del-col`);oe&&o.length>1&&(oe.onclick=e=>{e.stopPropagation(),o.splice(t,1),d===t&&(d=null),E(),w()}),f.appendChild(r)})}E(),w(),p.oninput=()=>{w()},f.onscroll=()=>{d!==null&&(d=null,E())},document.getElementById(`btn-add-column-row`).onclick=()=>{o.push({name:`column_${o.length+1}`,type:`VARCHAR(255)`,primaryKey:!1,nullable:!0,isUnique:!1,defaultValue:``,fkTarget:null}),E(),w(),setTimeout(()=>{f.scrollTop=f.scrollHeight},20)},document.getElementById(`preset-add-timestamps`).onclick=()=>{let e=o.map(e=>e.name.toLowerCase());e.includes(`created_at`)||o.push({name:`created_at`,type:`TIMESTAMP`,primaryKey:!1,nullable:!1,isUnique:!1,defaultValue:`CURRENT_TIMESTAMP`,fkTarget:null}),e.includes(`updated_at`)||o.push({name:`updated_at`,type:`TIMESTAMP`,primaryKey:!1,nullable:!1,isUnique:!1,defaultValue:`CURRENT_TIMESTAMP`,fkTarget:null}),E(),w(),setTimeout(()=>{f.scrollTop=f.scrollHeight},20)},document.getElementById(`preset-add-softdelete`).onclick=()=>{o.map(e=>e.name.toLowerCase()).includes(`deleted_at`)||o.push({name:`deleted_at`,type:`TIMESTAMP`,primaryKey:!1,nullable:!0,isUnique:!1,defaultValue:``,fkTarget:null}),E(),w(),setTimeout(()=>{f.scrollTop=f.scrollHeight},20)},document.getElementById(`preset-add-uuid-pk`).onclick=()=>{let e=o.findIndex(e=>e.primaryKey);e===-1?o.unshift({name:`id`,type:`VARCHAR(36)`,primaryKey:!0,nullable:!1,isUnique:!1,defaultValue:``,fkTarget:null}):(o[e].name=`id`,o[e].type=`VARCHAR(36)`),E(),w()};let D=e=>{d!==null&&!e.target.closest(`.table-col-fk-wrap`)&&!e.target.closest(`.dropdown-picker-popover`)&&(d=null,E())};document.addEventListener(`click`,D);let O=()=>{document.removeEventListener(`keydown`,k),document.removeEventListener(`click`,D),t.remove()},k=e=>{e.key===`Escape`&&O()};document.addEventListener(`keydown`,k),document.getElementById(`close-create-table-modal-btn`).onclick=O,document.getElementById(`cancel-create-table-btn`).onclick=O,h.onclick=async()=>{_.style.display=`none`;let t=p.value.trim();if(!t){_.textContent=`Table name cannot be empty.`,_.style.display=`block`,p.focus();return}if(!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(t)){_.textContent=`Table name must start with a letter/underscore and contain only alphanumeric characters.`,_.style.display=`block`,p.focus();return}let n=new Set;for(let e of o){if(!e.name){alert(`All column names must be non-empty.`);return}let t=e.name.toLowerCase();if(n.has(t)){alert(`Duplicate column name "${e.name}".`);return}n.add(t)}for(let e of o)if(e.isNewEnum&&(!e.enumValues||e.enumValues.length===0)){alert(`Please specify at least one enum value for column "${e.name||`column`}".`);return}h.disabled=!0,g.textContent=`Creating...`;try{let n=await i(t,o.map(e=>({name:e.name,type:e.isNewEnum?(e.newEnumName||e.type||`CustomEnum`).trim():e.type,isPk:!!e.primaryKey,primaryKey:!!e.primaryKey,nullable:!e.primaryKey&&e.nullable!==!1,isUnique:!e.primaryKey&&!!e.isUnique,defaultValue:e.defaultValue||void 0,enumValues:e.enumValues&&e.enumValues.length>0?e.enumValues:void 0,isNewEnum:!!e.isNewEnum,fkTarget:e.fkTarget&&e.fkTarget.table&&e.fkTarget.column?{table:e.fkTarget.table,column:e.fkTarget.column,onDelete:e.fkTarget.onDelete,onUpdate:e.fkTarget.onUpdate}:void 0})));n.success?(O(),window.showToast?.(`Table "${t}" created successfully!`,`success`),window.refreshTableList&&(await window.refreshTableList(!0),setTimeout(()=>{let e=document.querySelector(`.table-btn[data-table="${t}"]`);e?e.click():(window.AppState.currentTable=t,window.handleSwitchTab(`schema-btn`))},100)),e&&e(t)):alert(`Failed to create table: ${n.error||`Unknown error`}`)}catch(e){alert(`Error: ${e.message}`)}finally{h.disabled=!1,g.textContent=`Create Table`}}}window.openCreateTableModal=ne,window.refreshTableList=ie;var re=!1;async function ie(e=!1){try{let t=document.getElementById(`table-nav`);if(!t)return;e&&(t.innerHTML=`
738
+ `;let _=i.querySelector(`.col-name-input`);_.oninput=e=>{o[t].name=e.target.value.trim(),w()};let v=i.querySelector(`.col-type-trigger`);v.onclick=r=>{r.stopPropagation();let i=c.map(e=>({name:e.name,value:`__ENUM_EXISTING__:${e.name}`,desc:`Existing Enum (${e.values.slice(0,3).join(`, `)}${e.values.length>3?`...`:``})`,icon:`list`,group:`EXISTING DATABASE ENUMS`}));pe({anchorEl:v,initialValue:e.isNewEnum?`ENUM`:e.isExistingEnum?`__ENUM_EXISTING__:${e.type}`:e.type,dialect:n,extraItems:i,onSelect:e=>{if(e===`ENUM`||e===`__NEW_ENUM__`){if(o[t].isNewEnum=!0,o[t].isExistingEnum=!1,!o[t].newEnumName){let e=o[t].name?o[t].name.charAt(0).toUpperCase()+o[t].name.slice(1)+`Enum`:`CustomEnum`;o[t].newEnumName=e,o[t].type=e}o[t].enumValues||(o[t].enumValues=[])}else if(e.startsWith(`__ENUM_EXISTING__:`)){let n=e.slice(18);o[t].isNewEnum=!1,o[t].isExistingEnum=!0,o[t].type=n;let r=c.find(e=>e.name===n);o[t].enumValues=r?[...r.values]:[]}else o[t].isNewEnum=!1,o[t].isExistingEnum=!1,o[t].type=e,o[t].enumValues=void 0;T(),w()}})};let y=i.querySelector(`.new-enum-name-input`);y&&(y.oninput=e=>{let n=e.target.value.trim();o[t].newEnumName=n,o[t].type=n||`CustomEnum`,w()});let b=i.querySelector(`.new-enum-values-input`);b&&(b.oninput=e=>{let n=e.target.value;o[t].newEnumValuesStr=n,o[t].enumValues=n.split(`,`).map(e=>e.trim().replace(/^['"]|['"]$/g,``)).filter(Boolean),w()});let x=i.querySelector(`.col-pk-check`);x.onchange=e=>{let n=e.target.checked;o[t].primaryKey=n,n&&(o[t].nullable=!1,o[t].isUnique=!1),T(),w()};let S=i.querySelector(`.col-null-check`);S.onchange=e=>{o[t].nullable=e.target.checked,w()};let C=i.querySelector(`.col-unique-check`);C.onchange=e=>{o[t].isUnique=e.target.checked,w()};let E=i.querySelector(`.col-default-input`);E.oninput=e=>{o[t].defaultValue=e.target.value.trim(),w()};let D=i.querySelector(`.col-fk-btn`),O=i.querySelector(`.table-fk-popover`),k=i.querySelector(`.fk-target-table-select`),A=i.querySelector(`.fk-target-column-select`),j=i.querySelector(`.fk-on-delete-select`),M=i.querySelector(`.fk-on-update-select`),N=i.querySelector(`.fk-popover-close`),ee=i.querySelector(`.fk-clear-btn`),te=i.querySelector(`.fk-done-btn`),P=e.fkTarget?.table||``,F=e.fkTarget?.column||``,I=e.fkTarget?.onDelete||`NO ACTION`,L=e.fkTarget?.onUpdate||`NO ACTION`;async function R(e){if(!e){if(A){let e=A.querySelector(`.fk-col-display`);e&&(e.textContent=`-- Select Column --`),A.disabled=!0}return}if(A){A.disabled=!1;let e=A.querySelector(`.fk-col-display`);e&&(e.textContent=`Loading...`)}if(!l[e])try{let t=await u(e);Array.isArray(t)?l[e]=t.map(e=>e.name):t&&Array.isArray(t.columns)?l[e]=t.columns.map(e=>e.name):l[e]=[`id`]}catch{l[e]=[`id`]}let t=l[e]||[];if((!F||!t.includes(F))&&(F=t.find(e=>e.toLowerCase()===`id`)||t[0]||``),A){let e=A.querySelector(`.fk-col-display`);e&&(e.textContent=F||`-- Select Column --`)}}k.onclick=e=>{e.stopPropagation(),H({anchorEl:k,title:`Select Target Table`,searchable:!0,placeholder:`Search tables...`,initialValue:P,items:s.map(e=>({name:e,value:e,icon:`table_chart`})),onSelect:async e=>{P=e;let t=k.querySelector(`.fk-table-display`);t&&(t.textContent=e),F=``,await R(e)}})},A.onclick=e=>{if(e.stopPropagation(),!P)return;let t=l[P]||[];H({anchorEl:A,title:`Columns in ${P}`,searchable:!0,placeholder:`Search columns...`,initialValue:F,items:t.map(e=>({name:e,value:e,icon:`tag`})),onSelect:e=>{F=e;let t=A.querySelector(`.fk-col-display`);t&&(t.textContent=e)}})},j.onclick=e=>{e.stopPropagation(),H({anchorEl:j,title:`ON DELETE Action`,searchable:!1,initialValue:I,items:[`NO ACTION`,`CASCADE`,`SET NULL`,`RESTRICT`],onSelect:e=>{I=e;let t=j.querySelector(`.fk-on-delete-display`);t&&(t.textContent=e)}})},M.onclick=e=>{e.stopPropagation(),H({anchorEl:M,title:`ON UPDATE Action`,searchable:!1,initialValue:L,items:[`NO ACTION`,`CASCADE`,`RESTRICT`,`SET NULL`],onSelect:e=>{L=e;let t=M.querySelector(`.fk-on-update-display`);t&&(t.textContent=e)}})},D.onclick=n=>{if(n.stopPropagation(),d===t)d=null,O.style.display=`none`;else{d=t,T();let n=document.getElementById(`fk-popover-${t}`);if(n){let r=e.fkTarget?.table||``;r&&R(r);let i=document.querySelector(`.col-fk-btn[data-index="${t}"]`);if(i){let e=i.getBoundingClientRect();n.style.top=`${e.bottom+4}px`,n.style.left=`${Math.max(10,Math.min(e.right-270,window.innerWidth-280))}px`}}}},N.onclick=e=>{e.stopPropagation(),d=null,O.style.display=`none`},ee.onclick=e=>{e.stopPropagation(),o[t].fkTarget=null,d=null,T(),w()},te.onclick=e=>{e.stopPropagation(),P&&F?o[t].fkTarget={table:P,column:F,onDelete:I===`NO ACTION`?void 0:I,onUpdate:L===`NO ACTION`?void 0:L}:o[t].fkTarget=null,d=null,T(),w()};let ne=i.querySelector(`.btn-move-up`);ne&&t>0&&(ne.onclick=e=>{e.stopPropagation();let n=o[t];o[t]=o[t-1],o[t-1]=n,d!==null&&(d=null),T(),w()});let z=i.querySelector(`.btn-move-down`);z&&t<o.length-1&&(z.onclick=e=>{e.stopPropagation();let n=o[t];o[t]=o[t+1],o[t+1]=n,d!==null&&(d=null),T(),w()});let B=i.querySelector(`.btn-del-col`);B&&o.length>1&&(B.onclick=e=>{e.stopPropagation(),o.splice(t,1),d===t&&(d=null),T(),w()}),f.appendChild(i)})}T(),w(),p.oninput=()=>{w()},f.onscroll=()=>{d!==null&&(d=null,T())},document.getElementById(`btn-add-column-row`).onclick=()=>{o.push({name:`column_${o.length+1}`,type:`VARCHAR(255)`,primaryKey:!1,nullable:!0,isUnique:!1,defaultValue:``,fkTarget:null}),T(),w(),setTimeout(()=>{f.scrollTop=f.scrollHeight},20)},document.getElementById(`preset-add-timestamps`).onclick=()=>{let e=o.map(e=>e.name.toLowerCase());e.includes(`created_at`)||o.push({name:`created_at`,type:`TIMESTAMP`,primaryKey:!1,nullable:!1,isUnique:!1,defaultValue:`CURRENT_TIMESTAMP`,fkTarget:null}),e.includes(`updated_at`)||o.push({name:`updated_at`,type:`TIMESTAMP`,primaryKey:!1,nullable:!1,isUnique:!1,defaultValue:`CURRENT_TIMESTAMP`,fkTarget:null}),T(),w(),setTimeout(()=>{f.scrollTop=f.scrollHeight},20)},document.getElementById(`preset-add-softdelete`).onclick=()=>{o.map(e=>e.name.toLowerCase()).includes(`deleted_at`)||o.push({name:`deleted_at`,type:`TIMESTAMP`,primaryKey:!1,nullable:!0,isUnique:!1,defaultValue:``,fkTarget:null}),T(),w(),setTimeout(()=>{f.scrollTop=f.scrollHeight},20)},document.getElementById(`preset-add-uuid-pk`).onclick=()=>{let e=o.findIndex(e=>e.primaryKey);e===-1?o.unshift({name:`id`,type:`VARCHAR(36)`,primaryKey:!0,nullable:!1,isUnique:!1,defaultValue:``,fkTarget:null}):(o[e].name=`id`,o[e].type=`VARCHAR(36)`),T(),w()};let E=e=>{d!==null&&!e.target.closest(`.table-col-fk-wrap`)&&!e.target.closest(`.dropdown-picker-popover`)&&(d=null,T())};document.addEventListener(`click`,E);let D=()=>{document.removeEventListener(`keydown`,O),document.removeEventListener(`click`,E),t.remove()},O=e=>{e.key===`Escape`&&D()};document.addEventListener(`keydown`,O),document.getElementById(`close-create-table-modal-btn`).onclick=D,document.getElementById(`cancel-create-table-btn`).onclick=D,h.onclick=async()=>{_.style.display=`none`;let t=p.value.trim();if(!t){_.textContent=`Table name cannot be empty.`,_.style.display=`block`,p.focus();return}if(!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(t)){_.textContent=`Table name must start with a letter/underscore and contain only alphanumeric characters.`,_.style.display=`block`,p.focus();return}let n=new Set;for(let e of o){if(!e.name){alert(`All column names must be non-empty.`);return}let t=e.name.toLowerCase();if(n.has(t)){alert(`Duplicate column name "${e.name}".`);return}n.add(t)}for(let e of o)if(e.isNewEnum&&(!e.enumValues||e.enumValues.length===0)){alert(`Please specify at least one enum value for column "${e.name||`column`}".`);return}h.disabled=!0,g.textContent=`Creating...`;try{let n=await a(t,o.map(e=>({name:e.name,type:e.isNewEnum?(e.newEnumName||e.type||`CustomEnum`).trim():e.type,isPk:!!e.primaryKey,primaryKey:!!e.primaryKey,nullable:!e.primaryKey&&e.nullable!==!1,isUnique:!e.primaryKey&&!!e.isUnique,defaultValue:e.defaultValue||void 0,enumValues:e.enumValues&&e.enumValues.length>0?e.enumValues:void 0,isNewEnum:!!e.isNewEnum,fkTarget:e.fkTarget&&e.fkTarget.table&&e.fkTarget.column?{table:e.fkTarget.table,column:e.fkTarget.column,onDelete:e.fkTarget.onDelete,onUpdate:e.fkTarget.onUpdate}:void 0})));n.success?(D(),window.showToast?.(`Table "${t}" created successfully!`,`success`),window.refreshTableList&&(await window.refreshTableList(!0),setTimeout(()=>{let e=document.querySelector(`.table-btn[data-table="${t}"]`);e?e.click():(window.AppState.currentTable=t,window.handleSwitchTab(`schema-btn`))},100)),e&&e(t)):alert(`Failed to create table: ${n.error||`Unknown error`}`)}catch(e){alert(`Error: ${e.message}`)}finally{h.disabled=!1,g.textContent=`Create Table`}}}async function he(e={}){if(!window.SchemaGrid)return;let{pendingEdits:t,pendingInserts:n,pendingDeletes:r,pendingIndexEdits:i,schema:a}=window.SchemaGrid,o=window.AppState.currentTable;if(!o)return;let s=r&&r.size>0||Object.keys(t||{}).length>0||n&&n.some(e=>e.name&&e.name.trim()!==``),c=i&&(i.added.length>0||i.dropped.length>0);if(!s&&!c)return;if(!e.cascadeConfirmed){let e=null;if(t&&a){for(let n of a)if(n.isPk&&t[n.name]&&t[n.name].type){let r=t[n.name].type;if(r.toLowerCase()!==(n.type||``).toLowerCase()){e={colName:n.name,oldType:n.type,newType:r};break}}}if(e)try{let t=await h(o,e.colName,e.newType);if(t.success&&t.data&&t.data.hasDependents){Ce({tableName:o,colName:e.colName,oldType:e.oldType,newType:e.newType,dependents:t.data.dependents,needsReindexing:t.data.needsReindexing,onConfirm:()=>{he({cascadeConfirmed:!0,cascadeFkTypes:!0,autoReindex:!0})}});return}}catch(e){console.error(`Failed to check cascade impact:`,e)}}let l=r?Array.from(r):[];try{let r=await m(o,{pendingEdits:t,pendingInserts:n,pendingDeletes:l,pendingIndexEdits:i,columns:a,cascadeFkTypes:e.cascadeFkTypes??!0,autoReindex:e.autoReindex??!0});if(r.success){window.SchemaGrid&&(window.SchemaGrid.pendingEdits={},window.SchemaGrid.pendingInserts=[{}],window.SchemaGrid.pendingDeletes=new Set,window.SchemaGrid.pendingIndexEdits={added:[],dropped:[]},window.SchemaGrid.history=[],window.SchemaGrid.currentTransaction=null),window.TableStates?.[o]&&(window.TableStates[o].dataGrid=null);let e=document.getElementById(`btn-refresh-schema-${o}`);e?e.click():window.renderCurrentView(),window.updateSidebarDirtyState?.(),window.loadTableStats?.(),window.showToast&&window.showToast(`Schema saved successfully!`,`success`)}else{let e=r.error||`Failed to apply schema changes`;window.showToast?window.showToast(`Migration failed: ${e}`,`error`):alert(`Migration failed: ${e}`)}}catch(e){let t=e.message||`Network error`;window.showToast?window.showToast(`Migration failed: ${t}`,`error`):alert(`Migration failed: ${t}`)}}function U(e,t,n,r=!0){if(r&&window.SchemaGrid.currentTransaction){let n=e.textContent;(n===`null`||e.classList.contains(`ghost-row`))&&(n=``),n!==t&&window.SchemaGrid.currentTransaction.push({td:e,oldVal:n,newVal:t})}let i=e.dataset.colKey,a=e.dataset.colIdx===`0`?`<span class="ghost-cell-hint">+ Add Column</span>`:``,o=t;if(i===`isPk`&&t){let e=t.includes(`PK`)||t.includes(`PFK`),n=t.match(/(?:FK|PFK)(?:\s*\(|:\s*|\s*→\s*|\s*->\s*)([a-zA-Z0-9_]+)\.([a-zA-Z0-9_]+)(?:\s*\((CASCADE|SET NULL|RESTRICT|NO ACTION)\))?/i),r=n&&n[3]&&n[3].toUpperCase()!==`NO ACTION`?` (${n[3].toUpperCase()})`:``;e&&n?o=`<span class="col-badge badge-pfk" title="Primary Foreign Key (Composite Key referencing ${n[1]}.${n[2]}${r?` [ON DELETE ${n[3]}]`:``})">PFK &rarr; ${n[1]}.${n[2]}${r}</span>`:e?o=`<span class="col-badge badge-pk">PK</span>`:n&&(o=`<span class="col-badge badge-fk" title="References ${n[1]}.${n[2]}${r?` [ON DELETE ${n[3]}]`:``}">FK &rarr; ${n[1]}.${n[2]}${r}</span>`)}else i===`nullable`&&t?o=t===`Yes`||t===`1`?`<span class="badge-bool bool-true">Yes</span>`:`<span class="badge-bool bool-false">No</span>`:i===`isUnique`&&t&&(o=t===`Yes`||t===`1`?`<span class="badge-unique">Yes</span>`:`<span class="text-soft">-</span>`);if(e.innerHTML=o||(e.dataset.insertIndex===void 0?`<span class="text-soft">-</span>`:a),e.dataset.insertIndex!==void 0){let r=parseInt(e.dataset.insertIndex);if(window.SchemaGrid.pendingInserts[r]||(window.SchemaGrid.pendingInserts[r]={}),t){if(window.SchemaGrid.pendingInserts[r][i]=t,e.classList.add(`cell-edited`),e.classList.remove(`ghost-row`),r===window.SchemaGrid.pendingInserts.length-1){e.closest(`tr`).classList.remove(`ghost-row-tr`),window.SchemaGrid.pendingInserts.push({});let t=document.querySelector(`#schema-grid-table-${window.AppState.currentTable} tbody`),i=document.createElement(`tr`);i.className=`ghost-row-tr`;let a=parseInt(e.dataset.rowIdx)+1;i.innerHTML+=`<td class="row-header" data-row-idx="${a}">*</td>`,n.forEach((e,t)=>{if(e===`indexing`)return;let n=t===0?`<span class="ghost-cell-hint">+ Add Column</span>`:``;i.innerHTML+=`<td class="data-cell ghost-row" data-row-idx="${a}" data-col-idx="${t}" data-insert-index="${r+1}" data-col-key="${e}">${n}</td>`}),t.appendChild(i);let o=document.querySelector(`#schema-grid-table-${window.AppState.currentTable} .manage-indexes-cell`);if(o){let e=parseInt(o.getAttribute(`rowspan`)||`1`,10);o.setAttribute(`rowspan`,String(e+1))}}}else window.SchemaGrid.pendingInserts[r]&&delete window.SchemaGrid.pendingInserts[r][i],e.classList.remove(`cell-edited`),e.classList.add(`ghost-row`)}else{let n=e.dataset.pk,r=e.dataset.original;r===`-`&&(r=``),t===r?(e.classList.remove(`cell-edited`),e.classList.remove(`cell-error`),window.SchemaGrid.pendingEdits[n]&&(delete window.SchemaGrid.pendingEdits[n][i],Object.keys(window.SchemaGrid.pendingEdits[n]).length===0&&delete window.SchemaGrid.pendingEdits[n])):(window.SchemaGrid.pendingEdits[n]||(window.SchemaGrid.pendingEdits[n]={}),window.SchemaGrid.pendingEdits[n][i]=t,e.classList.add(`cell-edited`),e.classList.remove(`cell-error`))}window.updateSidebarDirtyState?.()}function ge(e,t=!0){let n=document.querySelector(`#schema-grid-table-${window.AppState.currentTable} td.data-cell[data-row-idx="${e}"]`)?.closest(`tr`);if(!n||n.classList.contains(`ghost-row-tr`)||n.classList.contains(`row-deleted`))return;let r=n.querySelector(`td.data-cell`)?.dataset.pk;r!==void 0&&(t&&window.SchemaGrid.currentTransaction&&window.SchemaGrid.currentTransaction.push({type:`delete`,rowIdx:e,pk:r}),window.SchemaGrid.pendingDeletes.add(r),n.classList.add(`row-deleted`)),window.updateSidebarDirtyState?.()}function _e(e,t){let n=document.querySelector(`#schema-grid-table-${window.AppState.currentTable} td.data-cell[data-row-idx="${e}"]`)?.closest(`tr`);n&&n.classList.remove(`row-deleted`),window.SchemaGrid.pendingDeletes.delete(t),window.updateSidebarDirtyState?.()}function ve(e,t){e.forEach(e=>{let n=window.AppState.currentTable,r=document.querySelector(`#schema-grid-table-${n} td.data-cell[data-row-idx="${e}"]`)?.closest(`tr`);if(!r||r.classList.contains(`ghost-row-tr`))return;let i=document.querySelector(`#schema-grid-table-${n} .ghost-row-tr`);i&&t.forEach((e,n)=>{let a=r.querySelector(`td.data-cell[data-col-idx="${n}"]`),o=i.querySelector(`td.data-cell[data-col-idx="${n}"]`);if(a&&o){let n=a.dataset.insertIndex===void 0?a.classList.contains(`cell-edited`)?window.SchemaGrid.pendingEdits[a.dataset.pk]?.[e]:a.dataset.original:window.SchemaGrid.pendingInserts[a.dataset.insertIndex][e];n!=null&&n!==`null`&&(e===`name`&&(n+=`_copy`),U(o,n,t,!0))}})})}function ye(){let e=window.SchemaGrid;if(!e)return;let t=document.getElementById(`index-modal`);t&&t.remove();let n=[...e.indexes],r=[...e.pendingIndexEdits.added],i=new Set(e.pendingIndexEdits.dropped),a=n.filter(e=>!i.has(e.name)).concat(r),o=e.schema.map(e=>e.name);e.pendingInserts.forEach(e=>{e.name&&e.name.trim()!==``&&o.push(e.name.trim())});let s=[];t=document.createElement(`div`),t.id=`index-modal`,t.className=`modal-overlay`,t.innerHTML=`
739
+ <div class="modal-container idx-modal-container">
740
+ <div class="modal-header">
741
+ <div class="flex items-center gap-2">
742
+ <span class="material-symbols-outlined text-primary" style="font-size:20px;">key</span>
743
+ <h3 class="m-0 text-15 font-semibold">Manage Indexes</h3>
744
+ </div>
745
+ <button id="close-idx-modal" class="modal-close-btn" title="Close"><span class="material-symbols-outlined">close</span></button>
746
+ </div>
747
+
748
+ <div class="modal-body-scroll" style="max-height: 220px; padding: 16px;">
749
+ <div class="idx-section-title">Current Indexes</div>
750
+ <div id="idx-list-container"></div>
751
+ </div>
752
+
753
+ <div class="modal-section-bg" style="padding: 16px 20px;">
754
+ <div class="idx-section-title" style="margin-bottom: 24px;">+ Create New Index</div>
755
+ <div class="flex flex-col gap-3">
756
+ <div>
757
+ <label class="text-11 text-secondary block mb-1.5">Index Name</label>
758
+ <input type="text" id="new-idx-name" placeholder="Optional (auto-generated if empty)" class="modal-input w-full" style="padding: 8px 12px; font-size: 13px;" />
759
+ </div>
760
+
761
+ <div>
762
+ <div class="flex items-center justify-between mb-1">
763
+ <label class="text-11 text-secondary">Columns (click to select in order)</label>
764
+ <button type="button" id="btn-clear-selected-cols" class="idx-clear-btn hidden" title="Clear column selection">
765
+ <span class="material-symbols-outlined" style="font-size:12px; line-height:1;">close</span>
766
+ <span>Clear selection</span>
767
+ </button>
768
+ </div>
769
+ <div id="idx-chips-container" class="idx-chips-container"></div>
770
+ </div>
771
+
772
+ <div class="flex items-center justify-between pt-1">
773
+ <label class="flex items-center gap-2 cursor-pointer select-none text-13">
774
+ <input type="checkbox" id="new-idx-unique" style="accent-color: var(--color-primary);" />
775
+ <span>Unique Index</span>
776
+ </label>
777
+ <button type="button" id="add-idx-btn" class="btn-add-idx">
778
+ <span class="material-symbols-outlined">add</span>
779
+ <span>Add to List</span>
780
+ </button>
781
+ </div>
782
+ </div>
783
+ </div>
784
+
785
+ <div class="modal-footer">
786
+ <button id="cancel-idx-btn" class="btn-secondary">Cancel</button>
787
+ <button id="save-idx-btn" class="btn-primary">Save Changes</button>
788
+ </div>
789
+ </div>
790
+ `,document.body.appendChild(t);let c=()=>t.remove();document.getElementById(`close-idx-modal`).onclick=c,document.getElementById(`cancel-idx-btn`).onclick=c;let l=()=>{let e=document.getElementById(`idx-chips-container`),t=document.getElementById(`btn-clear-selected-cols`);e&&(t&&(s.length>0?(t.classList.remove(`hidden`),t.onclick=()=>{s=[],l()}):t.classList.add(`hidden`)),e.innerHTML=o.map(e=>{let t=s.indexOf(e),n=t!==-1,r=n?`<span class="idx-chip-badge">${t+1}</span>`:``;return`
791
+ <div class="idx-chip ${n?`selected`:``}" data-col="${e}">
792
+ ${r}
793
+ <span>${e}</span>
794
+ </div>
795
+ `}).join(``),e.querySelectorAll(`.idx-chip`).forEach(e=>{e.onclick=()=>{let t=e.dataset.col,n=s.indexOf(t);n===-1?s.push(t):s.splice(n,1),l()}}))};l();let u=()=>{let e=document.getElementById(`idx-list-container`);if(e){if(a.length===0){e.innerHTML=`
796
+ <div style="display:flex; flex-direction:column; align-items:center; justify-content:center; padding: 24px 0; color: var(--color-text-soft);">
797
+ <span class="material-symbols-outlined" style="font-size:32px; opacity:0.4; margin-bottom:6px;">dataset</span>
798
+ <div style="font-size:12px;">No indexes defined for this table yet.</div>
799
+ </div>
800
+ `;return}e.innerHTML=a.map((e,t)=>`
801
+ <div class="idx-card">
802
+ <div class="idx-card-info">
803
+ <div class="idx-card-header">
804
+ <span class="idx-name">${e.name||`unnamed_idx`}</span>
805
+ ${e.isUnique?`<span class="badge-unique" style="font-size:10px; padding:1px 6px; line-height:14px;">UNIQUE</span>`:``}
806
+ </div>
807
+ <div class="idx-cols-tags">
808
+ ${e.columns.map(e=>`<span class="idx-col-pill">${e}</span>`).join(``)}
809
+ </div>
810
+ </div>
811
+ <button type="button" class="idx-del-btn delete-idx-btn" data-idx="${t}" title="Remove index">
812
+ <span class="material-symbols-outlined">delete</span>
813
+ </button>
814
+ </div>
815
+ `).join(``),e.querySelectorAll(`.delete-idx-btn`).forEach(e=>{e.onclick=e=>{let t=parseInt(e.currentTarget.dataset.idx,10);a.splice(t,1),u()}})}};u(),document.getElementById(`add-idx-btn`).onclick=()=>{if(s.length===0){window.showToast?window.showToast(`Please select at least one column for the index.`,`warning`):alert(`Please select at least one column for the index.`);return}let e=window.AppState?.currentTable||`table`,t=document.getElementById(`new-idx-name`).value.trim()||`idx_${e}_${s.join(`_`)}`,n=document.getElementById(`new-idx-unique`).checked;a.push({name:t,columns:[...s],isUnique:n}),document.getElementById(`new-idx-name`).value=``,document.getElementById(`new-idx-unique`).checked=!1,s=[],l(),u()},document.getElementById(`save-idx-btn`).onclick=()=>{let t=[],r=new Set;n.forEach(e=>{a.find(t=>t.name===e.name&&JSON.stringify(t.columns)===JSON.stringify(e.columns))||r.add(e.name)}),a.forEach(e=>{n.find(t=>t.name===e.name&&JSON.stringify(t.columns)===JSON.stringify(e.columns))||t.push(e)}),e.pendingIndexEdits.added=t,e.pendingIndexEdits.dropped=Array.from(r),window.updateSidebarDirtyState?.(),window.renderSchemaGrid(),c()}}async function be(e,t){if(!window.SchemaGrid)return;let n=document.getElementById(`pkfk-modal`);n&&n.remove();let r=e.dataset.insertIndex!==void 0,i=r?parseInt(e.dataset.insertIndex,10):null,a=e.dataset.pk||e.parentElement?.querySelector(`[data-col-key="name"]`)?.textContent?.trim()||``,o=``;o=r&&i!==null&&window.SchemaGrid?.pendingInserts?.[i]?window.SchemaGrid.pendingInserts[i].isPk||``:a&&window.SchemaGrid?.pendingEdits?.[a]?.isPk!==void 0?window.SchemaGrid.pendingEdits[a].isPk||``:t||e.textContent?.trim()||e.dataset.original||``;let s=o.includes(`PK`)||o.includes(`PFK`),c=!1,l=``,u=``,d=`NO ACTION`,f=`NO ACTION`,p=(window.SchemaGrid?.schema||[]).find(e=>e.name===a);p?.fkTarget&&(l=p.fkTarget.table||``,u=p.fkTarget.column||``,p.fkTarget.onDelete&&(d=p.fkTarget.onDelete),p.fkTarget.onUpdate&&(f=p.fkTarget.onUpdate),c=!0);let m=r&&i!==null?window.SchemaGrid?.pendingInserts?.[i]?.fkTarget:a?window.SchemaGrid?.pendingEdits?.[a]?.fkTarget:void 0;m&&(m.table&&(l=m.table),m.column&&(u=m.column),m.onDelete&&(d=m.onDelete),m.onUpdate&&(f=m.onUpdate),c=!0);let h=o.match(/(?:FK|PFK)(?:\s*\(|:\s*|\s*→\s*|\s*->\s*)([a-zA-Z0-9_]+)\.([a-zA-Z0-9_]+)(?:\s*\((CASCADE|SET NULL|RESTRICT|NO ACTION)\))?/i);h?(l=h[1],u=h[2],h[3]&&(d=h[3].toUpperCase()),c=!0):(o.includes(`FK`)||o.includes(`PFK`))&&(c=!0),n=document.createElement(`div`),n.id=`pkfk-modal`,n.className=`modal-overlay`,n.innerHTML=`
816
+ <div class="keys-modal-container">
817
+ <div class="modal-header">
818
+ <div class="flex items-center gap-2">
819
+ <span class="material-symbols-outlined text-primary" style="font-size:20px;">vpn_key</span>
820
+ <h3 class="m-0 text-15 font-semibold">Manage Keys</h3>
821
+ ${a?`<span class="keys-col-badge">${a}</span>`:``}
822
+ </div>
823
+ <button id="close-pkfk-modal" class="modal-close-btn" title="Close"><span class="material-symbols-outlined">close</span></button>
824
+ </div>
825
+
826
+ <div class="key-cards-list">
827
+ <!-- Primary Key Card -->
828
+ <div class="key-card ${s?`active`:``}" id="pk-card">
829
+ <div class="key-card-header" id="pk-card-toggle">
830
+ <div class="key-card-icon pk">
831
+ <span class="material-symbols-outlined">key</span>
832
+ </div>
833
+ <div class="key-card-content">
834
+ <div class="key-card-title">Primary Key (PK)</div>
835
+ <div class="key-card-desc">Uniquely identifies each record in this table</div>
836
+ </div>
837
+ <label class="key-switch" id="pk-switch-label">
838
+ <input type="checkbox" id="modal-is-pk" ${s?`checked`:``} />
839
+ <span class="key-slider"></span>
840
+ </label>
841
+ </div>
842
+ </div>
843
+
844
+ <!-- Foreign Key Card -->
845
+ <div class="key-card ${c?`active`:``}" id="fk-card">
846
+ <div class="key-card-header" id="fk-card-toggle">
847
+ <div class="key-card-icon fk">
848
+ <span class="material-symbols-outlined">link</span>
849
+ </div>
850
+ <div class="key-card-content">
851
+ <div class="key-card-title">Foreign Key (FK)</div>
852
+ <div class="key-card-desc">Reference a column in another table</div>
853
+ </div>
854
+ <label class="key-switch" id="fk-switch-label">
855
+ <input type="checkbox" id="modal-is-fk" ${c?`checked`:``} />
856
+ <span class="key-slider"></span>
857
+ </label>
858
+ </div>
859
+
860
+ <!-- FK Configuration Drawer -->
861
+ <div id="fk-settings-container" class="key-fk-drawer ${c?`open`:``}">
862
+ <div class="key-field-group">
863
+ <label class="key-field-label">Target Table</label>
864
+ <button type="button" id="modal-fk-table" class="key-select" style="display: flex; justify-content: space-between; align-items: center; width: 100%; height: 32px; cursor: pointer; text-align: left; padding: 0 10px;">
865
+ <span id="modal-fk-table-display" style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">${l||`Select a table...`}</span>
866
+ <span class="material-symbols-outlined key-select-arrow" style="font-size: 16px;">expand_more</span>
867
+ </button>
868
+ </div>
869
+
870
+ <div class="key-field-group">
871
+ <label class="key-field-label">Target Column</label>
872
+ <button type="button" id="modal-fk-col" class="key-select" ${l?``:`disabled`} style="display: flex; justify-content: space-between; align-items: center; width: 100%; height: 32px; cursor: pointer; text-align: left; padding: 0 10px;">
873
+ <span id="modal-fk-col-display" style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">${u||(l?`Select column...`:`Select a table first`)}</span>
874
+ <span class="material-symbols-outlined key-select-arrow" style="font-size: 16px;">expand_more</span>
875
+ </button>
876
+ </div>
877
+
878
+ <div class="key-field-group" style="display: grid; grid-template-columns: 1fr 1fr; gap: 10px;">
879
+ <div>
880
+ <label class="key-field-label">On Delete</label>
881
+ <button type="button" id="modal-fk-ondelete" class="key-select" style="display: flex; justify-content: space-between; align-items: center; width: 100%; height: 32px; cursor: pointer; text-align: left; padding: 0 10px;">
882
+ <span id="modal-fk-ondelete-display">${d||`NO ACTION`}</span>
883
+ <span class="material-symbols-outlined key-select-arrow" style="font-size: 16px;">expand_more</span>
884
+ </button>
885
+ </div>
886
+ <div>
887
+ <label class="key-field-label">On Update</label>
888
+ <button type="button" id="modal-fk-onupdate" class="key-select" style="display: flex; justify-content: space-between; align-items: center; width: 100%; height: 32px; cursor: pointer; text-align: left; padding: 0 10px;">
889
+ <span id="modal-fk-onupdate-display">${f||`NO ACTION`}</span>
890
+ <span class="material-symbols-outlined key-select-arrow" style="font-size: 16px;">expand_more</span>
891
+ </button>
892
+ </div>
893
+ </div>
894
+ </div>
895
+ </div>
896
+ </div>
897
+
898
+ <div class="modal-footer">
899
+ <button id="cancel-pkfk-btn" class="btn-secondary">Cancel</button>
900
+ <button id="save-pkfk-btn" class="btn-primary flex items-center gap-1.5">
901
+ <span class="material-symbols-outlined" style="font-size:16px;">check</span>
902
+ <span>Save Changes</span>
903
+ </button>
904
+ </div>
905
+ </div>
906
+ `,document.body.appendChild(n);let g=e=>{e.key===`Escape`&&_()};document.addEventListener(`keydown`,g);let _=()=>{document.removeEventListener(`keydown`,g),n.remove()};document.getElementById(`close-pkfk-modal`).onclick=_,document.getElementById(`cancel-pkfk-btn`).onclick=_,n.addEventListener(`click`,e=>{e.target===n&&_()});let v=document.getElementById(`pk-card`),y=document.getElementById(`modal-is-pk`),b=document.getElementById(`fk-card`),x=document.getElementById(`modal-is-fk`),S=document.getElementById(`fk-settings-container`),C=document.getElementById(`modal-fk-table`),w=document.getElementById(`modal-fk-col`);document.getElementById(`pk-card-toggle`).addEventListener(`click`,e=>{e.target.closest(`.key-switch`)||(y.checked=!y.checked,y.dispatchEvent(new Event(`change`)))}),y.addEventListener(`change`,()=>{v.classList.toggle(`active`,y.checked)}),document.getElementById(`fk-card-toggle`).addEventListener(`click`,e=>{e.target.closest(`.key-switch`)||(x.checked=!x.checked,x.dispatchEvent(new Event(`change`)))});let T=[],E=l||``,D=u||``,O=d||`NO ACTION`,k=f||`NO ACTION`,A=[];x.addEventListener(`change`,()=>{let e=x.checked;if(e&&T.length===0){x.checked=!1,b.classList.remove(`active`),S.classList.remove(`open`),window.showToast?window.showToast(`No other tables available in the database to link as a foreign key.`,`warning`):alert(`No other tables available in the database to link as a foreign key.`);return}if(b.classList.toggle(`active`,e),e){if(S.classList.add(`open`),!E&&T.length>0){let e=T[0];E=e;let t=document.getElementById(`modal-fk-table-display`);t&&(t.textContent=e),j(e)}}else S.classList.remove(`open`)});try{let e=await(await fetch(`/api/tables`)).json();e.success&&e.data&&(T=e.data,E&&T.includes(E)&&j(E,D))}catch{}async function j(e,t=``){w.disabled=!0;let n=document.getElementById(`modal-fk-col-display`);n&&(n.textContent=`Loading columns...`);try{let r=await(await fetch(`/api/tables/${encodeURIComponent(e)}/schema`)).json();if(r.success&&r.data){let i=e===window.AppState?.currentTable?r.data.filter(e=>e.name!==a):r.data;A=i;let o=t;if(!o||!i.some(e=>e.name===o)){let e=i.find(e=>e.isPk||e.name.toLowerCase()===`id`);o=e?e.name:i[0]?.name||``}D=o,n&&(n.textContent=o||`Select column...`),w.disabled=!1}}catch{n&&(n.textContent=`Error loading columns`)}}C.onclick=e=>{e.stopPropagation(),H({anchorEl:C,title:`Select Target Table`,searchable:!0,placeholder:`Search tables...`,initialValue:E,items:T.map(e=>({name:e,value:e,icon:`table_chart`})),onSelect:e=>{E=e;let t=document.getElementById(`modal-fk-table-display`);t&&(t.textContent=e),j(e)}})},w.onclick=e=>{e.stopPropagation(),!(!E||A.length===0)&&H({anchorEl:w,title:`Columns in ${E}`,searchable:!0,placeholder:`Search columns...`,initialValue:D,items:A.map(e=>({name:e.name,value:e.name,icon:`tag`,desc:e.type||``})),onSelect:e=>{D=e;let t=document.getElementById(`modal-fk-col-display`);t&&(t.textContent=e)}})};let M=document.getElementById(`modal-fk-ondelete`),N=document.getElementById(`modal-fk-onupdate`);M&&(M.onclick=e=>{e.stopPropagation(),H({anchorEl:M,title:`ON DELETE Action`,searchable:!1,initialValue:O,items:[`NO ACTION`,`CASCADE`,`RESTRICT`,`SET NULL`],onSelect:e=>{O=e;let t=document.getElementById(`modal-fk-ondelete-display`);t&&(t.textContent=e)}})}),N&&(N.onclick=e=>{e.stopPropagation(),H({anchorEl:N,title:`ON UPDATE Action`,searchable:!1,initialValue:k,items:[`NO ACTION`,`CASCADE`,`RESTRICT`,`SET NULL`],onSelect:e=>{k=e;let t=document.getElementById(`modal-fk-onupdate-display`);t&&(t.textContent=e)}})}),document.getElementById(`save-pkfk-btn`).onclick=()=>{let t=y.checked,n=x.checked,o=E,p=D,m=O||`NO ACTION`,h=k||`NO ACTION`;if(t===s&&n===c&&(!n||o===l&&p===u&&m===d&&h===f)){_();return}let g=m&&m!==`NO ACTION`?` (${m})`:``,v=``;if(t&&n){if(!o||!p){window.showToast?window.showToast(`Please select both Target Table and Target Column for the Foreign Key.`,`warning`):alert(`Please select both Target Table and Target Column for the Foreign Key.`);return}v=`PFK: ${o}.${p}${g}`}else if(t)v=`PK`;else if(n){if(!o||!p){window.showToast?window.showToast(`Please select both Target Table and Target Column for the Foreign Key.`,`warning`):alert(`Please select both Target Table and Target Column for the Foreign Key.`);return}v=`FK: ${o}.${p}${g}`}let b=n&&o&&p?{table:o,column:p,onDelete:m===`NO ACTION`?void 0:m,onUpdate:h===`NO ACTION`?void 0:h}:null;r&&i!==null?(window.SchemaGrid.pendingInserts[i]||(window.SchemaGrid.pendingInserts[i]={}),window.SchemaGrid.pendingInserts[i].fkTarget=b,window.SchemaGrid.pendingInserts[i].isPk=t):a&&(window.SchemaGrid.pendingEdits[a]||(window.SchemaGrid.pendingEdits[a]={}),window.SchemaGrid.pendingEdits[a].fkTarget=b,window.SchemaGrid.pendingEdits[a].isPk=t),window.SchemaGrid.currentTransaction=[],U(e,v,[`name`,`type`,`isPk`,`nullable`,`defaultValue`,`indexing`]),window.SchemaGrid.currentTransaction.length>0&&window.SchemaGrid.history.push(window.SchemaGrid.currentTransaction),window.SchemaGrid.currentTransaction=null,_()}}async function xe(e,t){let n=window.SchemaGrid;if(!n)return;let r=document.getElementById(`enum-modal`);r&&r.remove();let i=e.dataset.insertIndex!==void 0,a=i?parseInt(e.dataset.insertIndex,10):null,o=e.dataset.pk||e.parentElement?.querySelector(`[data-col-key="name"]`)?.textContent?.trim()||`column`,s=(window.AppState?.dbType||`sqlite`).toLowerCase(),c=[],l=``,u=i?n.pendingInserts?.[a]:n.pendingEdits?.[o];u?.enumValues&&u.enumValues.length>0?(c=[...u.enumValues],l=u.type||``,u.isNewEnum):t?.enumValues&&t.enumValues.length>0&&(c=[...t.enumValues],l=t.type||``,t.isExistingEnum),l||=o&&o!==`column`?o.charAt(0).toUpperCase()+o.slice(1)+`Enum`:`CustomEnum`;let d=[];try{let e=await k();e?.success&&Array.isArray(e.data)&&(d=e.data)}catch(e){console.warn(`Failed to load database enums:`,e)}r=document.createElement(`div`),r.id=`enum-modal`,r.className=`modal-overlay`;let f=s===`sqlite`?`SQLite enforces enums using a <code>CHECK(col IN (...))</code> table constraint.`:s===`postgres`?`PostgreSQL creates custom ENUM types using <code>CREATE TYPE ... AS ENUM (...)</code>.`:`MySQL stores enums as native <code>ENUM(...)</code> column types.`,p=d.length>0,m=d.find(e=>e.name.toLowerCase()===l.toLowerCase());r.innerHTML=`
907
+ <div class="keys-modal-container" style="width: 520px;">
908
+ <div class="modal-header">
909
+ <div class="flex items-center gap-2">
910
+ <span class="material-symbols-outlined text-primary" style="font-size:20px;">list_alt</span>
911
+ <h3 class="m-0 text-15 font-semibold">Configure ENUM Column</h3>
912
+ <span class="keys-col-badge">${o}</span>
913
+ <span class="snippet-param-badge">${s}</span>
914
+ </div>
915
+ <button id="close-enum-modal" class="modal-close-btn" title="Close"><span class="material-symbols-outlined">close</span></button>
916
+ </div>
917
+
918
+ <div class="key-cards-list" style="gap: 14px;">
919
+ <div style="font-size: 11.5px; color: var(--color-text-secondary); line-height: 1.5; background: var(--color-bg-secondary-dark); padding: 8px 12px; border-radius: 6px; border: 1px solid var(--color-border);">
920
+ ${f}
921
+ </div>
922
+
923
+ ${p?`
924
+ <div class="table-fk-popover-field">
925
+ <label style="font-size: 11px; font-weight: 500; color: var(--color-text-secondary);">Enum Source</label>
926
+ <button type="button" id="modal-enum-source" class="table-col-select" style="display: flex; justify-content: space-between; align-items: center; width: 100%; height: 32px; cursor: pointer; text-align: left; padding: 0 10px;">
927
+ <span id="modal-enum-source-display" style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">${m?m.name:`+ Define New Enum...`}</span>
928
+ <span class="material-symbols-outlined table-col-select-arrow" style="font-size: 16px;">expand_more</span>
929
+ </button>
930
+ </div>
931
+ `:``}
932
+
933
+ <div id="modal-enum-custom-fields" class="flex flex-col gap-3">
934
+ <div>
935
+ <label style="font-size: 11px; font-weight: 500; color: var(--color-text-secondary); display: block; margin-bottom: 5px;">
936
+ Enum Name ${s===`postgres`?`<span style="color: var(--color-error);">*</span>`:`(Optional)`}
937
+ </label>
938
+ <input type="text" id="modal-enum-name" class="modal-input w-full" style="padding: 7px 10px; font-size: 12px; font-family: var(--font-mono);" placeholder="e.g. OrderStatus" value="${l}" />
939
+ </div>
940
+
941
+ <div>
942
+ <label style="font-size: 11px; font-weight: 500; color: var(--color-text-secondary); display: block; margin-bottom: 5px;">
943
+ Allowed Values (comma separated) <span style="color: var(--color-error);">*</span>
944
+ </label>
945
+ <input type="text" id="modal-enum-values" class="modal-input w-full" style="padding: 7px 10px; font-size: 12px; font-family: var(--font-mono);" placeholder="e.g. PENDING, PAID, CANCELLED, REFUNDED" value="${c.join(`, `)}" />
946
+ <span style="font-size: 10.5px; color: var(--color-text-soft); margin-top: 4px; display: block;">Separate values with commas. Quotes are optional.</span>
947
+ </div>
948
+ </div>
949
+
950
+ <!-- SQL DDL Preview -->
951
+ <div>
952
+ <label style="font-size: 11px; font-weight: 500; color: var(--color-text-secondary); display: block; margin-bottom: 5px;">
953
+ Preview
954
+ </label>
955
+ <div style="background: var(--color-bg-secondary-dark); border: 1px solid var(--color-border); border-radius: 6px; padding: 10px 12px; font-family: var(--font-mono); font-size: 11.5px; color: var(--color-text); word-break: break-all; min-height: 38px; display: flex; align-items: center;" id="modal-enum-preview">
956
+ -
957
+ </div>
958
+ </div>
959
+ </div>
960
+
961
+ <div class="modal-footer">
962
+ <button id="cancel-enum-btn" class="btn-secondary">Cancel</button>
963
+ <button id="save-enum-btn" class="btn-primary flex items-center gap-1.5">
964
+ <span class="material-symbols-outlined" style="font-size:16px;">check</span>
965
+ <span>Apply Enum</span>
966
+ </button>
967
+ </div>
968
+ </div>
969
+ `,document.body.appendChild(r);let h=()=>{document.removeEventListener(`keydown`,g),r.remove()},g=e=>{e.key===`Escape`&&h()};document.addEventListener(`keydown`,g),document.getElementById(`close-enum-modal`).onclick=h,document.getElementById(`cancel-enum-btn`).onclick=h,r.addEventListener(`click`,e=>{e.target===r&&h()});let _=document.getElementById(`modal-enum-source`),v=document.getElementById(`modal-enum-custom-fields`),y=document.getElementById(`modal-enum-name`),b=document.getElementById(`modal-enum-values`),x=document.getElementById(`modal-enum-preview`),S=m?m.name:`__NEW__`;function C(){if(_&&S!==`__NEW__`){let e=d.find(e=>e.name===S);return e?[...e.values]:[]}return b.value.split(`,`).map(e=>e.trim().replace(/^['"]|['"]$/g,``)).filter(Boolean)}function w(){let e=C(),t=(y.value.trim()||l||`CustomEnum`).trim(),n=e.map(e=>`'${e.replace(/'/g,`''`)}'`).join(`, `);if(e.length===0){x.textContent=`Enter enum values above to see SQL preview`;return}s===`sqlite`?x.textContent=`TEXT CHECK("${o}" IN (${n}))`:s===`postgres`?_&&S!==`__NEW__`?x.textContent=`Type: "${S}" (Values: ${n})`:x.textContent=`CREATE TYPE "${t}" AS ENUM (${n});`:x.textContent=`ENUM(${n})`}_&&(_.onclick=e=>{e.stopPropagation();let t=[{name:`+ Define New Enum...`,value:`__NEW__`,icon:`add_circle`},...d.map(e=>({name:e.name,value:e.name,desc:e.values.slice(0,3).join(`, `)+(e.values.length>3?`...`:``),icon:`list`,group:`Existing Database Enums`}))];H({anchorEl:_,title:`Select Enum Source`,searchable:!0,placeholder:`Search enum types...`,initialValue:S,items:t,onSelect:e=>{S=e;let t=document.getElementById(`modal-enum-source-display`);t&&(t.textContent=e===`__NEW__`?`+ Define New Enum...`:e),e===`__NEW__`?v.style.display=`flex`:v.style.display=`none`,w()}})},S!==`__NEW__`&&(v.style.display=`none`)),y.oninput=w,b.oninput=w,w(),document.getElementById(`save-enum-btn`).onclick=()=>{let t=C();if(t.length===0){window.showToast?window.showToast(`Please specify at least one enum value.`,`error`):alert(`Please specify at least one enum value.`),b.focus();return}let r=``,c=!0;_&&S!==`__NEW__`?(r=S,c=!1):(r=(y.value.trim()||l||`CustomEnum`).trim(),c=!0);let u=s===`postgres`?r:r||`ENUM`;i&&a!==null?(n.pendingInserts[a]||(n.pendingInserts[a]={}),n.pendingInserts[a].type=u,n.pendingInserts[a].enumValues=t,n.pendingInserts[a].isNewEnum=c):o&&(n.pendingEdits[o]||(n.pendingEdits[o]={}),n.pendingEdits[o].type=u,n.pendingEdits[o].enumValues=t,n.pendingEdits[o].isNewEnum=c),window.SchemaGrid.currentTransaction=[],U(e,u,[`name`,`type`,`isPk`,`nullable`,`isUnique`,`defaultValue`,`indexing`]),window.SchemaGrid.currentTransaction.length>0&&window.SchemaGrid.history.push(window.SchemaGrid.currentTransaction),window.SchemaGrid.currentTransaction=null,h(),window.updateSidebarDirtyState?.(),window.showToast?.(`Enum column configured!`,`success`)}}function Se(e){if(!e)return;let t=document.getElementById(`rename-table-modal`);t&&t.remove(),t=document.createElement(`div`),t.id=`rename-table-modal`,t.className=`modal-overlay`,t.innerHTML=`
970
+ <div class="keys-modal-container" style="max-width: 440px; width: 100%;">
971
+ <div class="modal-header">
972
+ <div class="flex items-center gap-2">
973
+ <span class="material-symbols-outlined text-primary" style="font-size: 20px;">edit_note</span>
974
+ <h3 class="m-0 text-15 font-semibold">Rename Table</h3>
975
+ </div>
976
+ <button id="close-rename-modal" class="modal-close-btn" title="Close">
977
+ <span class="material-symbols-outlined">close</span>
978
+ </button>
979
+ </div>
980
+
981
+ <div style="padding: 16px 20px 20px; display: flex; flex-direction: column; gap: 14px;">
982
+ <div style="font-size: 13px; color: var(--color-text-soft);">
983
+ Rename table <code style="font-family: monospace; background: rgba(255,255,255,0.08); padding: 2px 6px; border-radius: 4px; color: var(--color-text-main); font-weight: 600;">${e}</code> to a new name.
984
+ </div>
985
+
986
+ <div>
987
+ <label style="display: block; font-size: 12px; font-weight: 500; margin-bottom: 6px; color: var(--color-text-main);">
988
+ New Table Name
989
+ </label>
990
+ <input
991
+ type="text"
992
+ id="input-rename-table"
993
+ class="key-select"
994
+ style="width: 100%; height: 36px; padding: 0 12px; font-size: 13px; font-family: monospace; outline: none;"
995
+ value="${e}"
996
+ placeholder="e.g. new_table_name"
997
+ autocomplete="off"
998
+ spellcheck="false"
999
+ />
1000
+ <div id="rename-table-error" style="color: #ef4444; font-size: 12px; margin-top: 6px; display: none;"></div>
1001
+ </div>
1002
+ </div>
1003
+
1004
+ <div class="modal-footer" style="padding: 12px 20px;">
1005
+ <button id="cancel-rename-btn" class="btn-secondary">Cancel</button>
1006
+ <button id="submit-rename-btn" class="btn-primary flex items-center gap-1.5">
1007
+ <span class="material-symbols-outlined" style="font-size: 16px;">check</span>
1008
+ <span>Rename</span>
1009
+ </button>
1010
+ </div>
1011
+ </div>
1012
+ `,document.body.appendChild(t);let n=document.getElementById(`input-rename-table`),r=document.getElementById(`rename-table-error`),i=document.getElementById(`submit-rename-btn`),a=document.getElementById(`close-rename-modal`),o=document.getElementById(`cancel-rename-btn`),s=()=>{document.removeEventListener(`keydown`,c),t.remove()},c=e=>{e.key===`Escape`&&s(),e.key===`Enter`&&u()};document.addEventListener(`keydown`,c),a.onclick=s,o.onclick=s,t.addEventListener(`click`,e=>{e.target===t&&s()});let l=e=>{r&&(r.textContent=e,r.style.display=`block`)},u=async()=>{let t=n.value.trim();if(!t){l(`Table name cannot be empty`),n.focus();return}if(t===e){l(`New table name must be different`),n.focus();return}if(!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(t)){l(`Table name must start with a letter or underscore and contain only letters, numbers, and underscores`),n.focus();return}i.disabled=!0,i.innerHTML=`<span class="material-symbols-outlined spin" style="font-size:16px;">progress_activity</span><span>Renaming...</span>`;try{let n=await _(e,t);n.success?(s(),window.showToast?.(`Table "${e}" renamed to "${t}" successfully!`,`success`),window.AppState.currentTable===e&&(window.AppState.currentTable=t),window.TableStates?.[e]&&(window.TableStates[t]=window.TableStates[e],delete window.TableStates[e]),window.refreshTableList&&(await window.refreshTableList(!0),setTimeout(()=>{let e=document.querySelector(`.table-btn[data-table="${t}"]`);e?e.click():(window.AppState.currentTable=t,window.renderCurrentView?.())},40))):(l(n.error||`Failed to rename table`),i.disabled=!1,i.innerHTML=`<span class="material-symbols-outlined" style="font-size: 16px;">check</span><span>Rename</span>`)}catch(e){l(e.message||`Network error`),i.disabled=!1,i.innerHTML=`<span class="material-symbols-outlined" style="font-size: 16px;">check</span><span>Rename</span>`}};i.onclick=u,setTimeout(()=>{n.focus(),n.select()},50)}window.openRenameTableModal=Se;function Ce({tableName:e,colName:t,oldType:n,newType:r,dependents:i=[],needsReindexing:a=!1,onConfirm:o}){let s=document.getElementById(`cascade-confirm-modal`);s&&s.remove(),s=document.createElement(`div`),s.id=`cascade-confirm-modal`,s.className=`modal-overlay`;let c=i.map(e=>`
1013
+ <tr style="border-bottom: 1px solid var(--color-border-subtle, rgba(255,255,255,0.06)); font-size: 12px;">
1014
+ <td style="padding: 8px 10px; font-family: monospace; font-weight: 600; color: var(--color-text-main);">
1015
+ ${e.table}.${e.column}
1016
+ </td>
1017
+ <td style="padding: 8px 10px; color: var(--color-text-soft);">
1018
+ <span style="font-family: monospace; background: rgba(255,255,255,0.06); padding: 2px 5px; border-radius: 3px;">${e.currentType||`UNKNOWN`}</span>
1019
+ <span style="margin: 0 4px; color: var(--color-text-subtle);">→</span>
1020
+ <span style="font-family: monospace; background: rgba(99,102,241,0.15); color: #818cf8; padding: 2px 5px; border-radius: 3px; font-weight: 600;">${r}</span>
1021
+ </td>
1022
+ </tr>
1023
+ `).join(``),l=a?`
1024
+ <div style="background: rgba(245, 158, 11, 0.1); border: 1px solid rgba(245, 158, 11, 0.3); border-radius: 6px; padding: 10px 12px; display: flex; gap: 8px; align-items: flex-start; font-size: 12px; color: #fbbf24;">
1025
+ <span class="material-symbols-outlined" style="font-size: 18px; margin-top: 1px; flex-shrink: 0;">swap_vertical_circle</span>
1026
+ <div>
1027
+ <div style="font-weight: 600; margin-bottom: 2px;">Smart Sequential Re-indexing Required</div>
1028
+ <div style="color: var(--color-text-soft); line-height: 1.4;">
1029
+ Existing rows contain non-numeric string values. Drixio will safely map them to sequential IDs (1, 2, 3...) across both <code>${e}</code> and all referencing tables in a single transaction before modifying column types.
1030
+ </div>
1031
+ </div>
1032
+ </div>
1033
+ `:``;s.innerHTML=`
1034
+ <div class="modal-container" style="max-width: 520px; width: 90vw; background: var(--color-surface, #1e1e24); border-radius: 8px; border: 1px solid var(--color-border, #333); box-shadow: 0 10px 30px rgba(0,0,0,0.5); overflow: hidden; display: flex; flex-direction: column;">
1035
+ <div class="modal-header" style="padding: 14px 20px; border-bottom: 1px solid var(--color-border-subtle, rgba(255,255,255,0.06)); display: flex; justify-content: space-between; align-items: center;">
1036
+ <div class="flex items-center gap-2">
1037
+ <span class="material-symbols-outlined text-warning" style="font-size: 20px; color: #f59e0b;">sync_alt</span>
1038
+ <h3 class="m-0 text-15 font-semibold">Cascade Foreign Key Type Migration</h3>
1039
+ </div>
1040
+ <button id="close-cascade-modal" class="modal-close-btn" title="Close">
1041
+ <span class="material-symbols-outlined">close</span>
1042
+ </button>
1043
+ </div>
1044
+
1045
+ <div style="padding: 16px 20px; display: flex; flex-direction: column; gap: 14px; max-height: 400px; overflow-y: auto;">
1046
+ <div style="font-size: 13px; color: var(--color-text-main); line-height: 1.5;">
1047
+ Changing primary key <code style="font-family: monospace; background: rgba(255,255,255,0.08); padding: 2px 6px; border-radius: 4px; font-weight: 600;">${e}.${t}</code> from
1048
+ <span style="font-family: monospace; color: #ef4444;">${n}</span> to <span style="font-family: monospace; color: #10b981; font-weight: 600;">${r}</span>
1049
+ will automatically cascade and update foreign keys in <strong>${i.length}</strong> referencing table(s):
1050
+ </div>
1051
+
1052
+ <div style="border: 1px solid var(--color-border-subtle, rgba(255,255,255,0.08)); border-radius: 6px; overflow: hidden;">
1053
+ <table style="width: 100%; border-collapse: collapse; text-align: left;">
1054
+ <thead>
1055
+ <tr style="background: rgba(255,255,255,0.03); border-bottom: 1px solid var(--color-border-subtle, rgba(255,255,255,0.08)); font-size: 11px; text-transform: uppercase; letter-spacing: 0.05em; color: var(--color-text-subtle);">
1056
+ <th style="padding: 8px 10px;">Referencing Foreign Key</th>
1057
+ <th style="padding: 8px 10px;">Type Update</th>
1058
+ </tr>
1059
+ </thead>
1060
+ <tbody>
1061
+ ${c}
1062
+ </tbody>
1063
+ </table>
1064
+ </div>
1065
+
1066
+ ${l}
1067
+ </div>
1068
+
1069
+ <div class="modal-footer" style="padding: 12px 20px; display: flex; justify-content: flex-end; gap: 10px; border-top: 1px solid var(--color-border-subtle, rgba(255,255,255,0.06)); background: rgba(0,0,0,0.1);">
1070
+ <button id="cancel-cascade-btn" class="btn-secondary">Cancel</button>
1071
+ <button id="submit-cascade-btn" class="btn-primary flex items-center gap-1.5" style="background: #4f46e5;">
1072
+ <span class="material-symbols-outlined" style="font-size: 16px;">bolt</span>
1073
+ <span>Confirm & Cascade Migration</span>
1074
+ </button>
1075
+ </div>
1076
+ </div>
1077
+ `,document.body.appendChild(s);let u=document.getElementById(`close-cascade-modal`),d=document.getElementById(`cancel-cascade-btn`),f=document.getElementById(`submit-cascade-btn`),p=()=>s.remove();u.onclick=p,d.onclick=p,s.addEventListener(`click`,e=>{e.target===s&&p()}),f.onclick=()=>{p(),o&&o()}}window.openCascadeConfirmModal=Ce;var we=`modulepreload`,Te=function(e,t){return new URL(e,t).href},Ee={},De=function(e,t,n){let r=Promise.resolve();if(t&&t.length>0){let e=document.getElementsByTagName(`link`),i=document.querySelector(`meta[property=csp-nonce]`),a=i?.nonce||i?.getAttribute(`nonce`);function o(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}))))}function s(e){return import.meta.resolve?import.meta.resolve(e):new URL(e,import.meta.url).href}r=o(t.map(t=>{if(t=Te(t,n),t=s(t),t in Ee)return;Ee[t]=!0;let r=t.endsWith(`.css`);for(let n=e.length-1;n>=0;n--){let i=e[n];if(i.href===t&&(!r||i.rel===`stylesheet`))return}let i=document.createElement(`link`);if(i.rel=r?`stylesheet`:we,r||(i.as=`script`),i.crossOrigin=``,i.href=t,a&&i.setAttribute(`nonce`,a),document.head.appendChild(i),r)return new Promise((e,n)=>{i.addEventListener(`load`,e),i.addEventListener(`error`,()=>n(Error(`Unable to preload CSS for ${t}`)))})}))}function i(e){let t=new Event(`vite:preloadError`,{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return r.then(t=>{for(let e of t||[])e.status===`rejected`&&i(e.reason);return e().catch(i)})};window.openCreateTableModal=me,window.refreshTableList=ke,window.openHealthModal=()=>De(()=>import(`./healthModal-Wc69raxJ.js`).then(e=>e.openHealthModal()),[],import.meta.url),window.openRecycleBinModal=()=>De(()=>import(`./recycleBinModal-CM1yVRKo.js`).then(e=>e.openRecycleBinModal()),[],import.meta.url);var Oe=!1;async function ke(e=!1){try{let t=document.getElementById(`table-nav`);if(!t)return;e&&(t.innerHTML=`
693
1078
  <div class="sidebar-loading-state">
694
1079
  <span class="material-symbols-outlined animate-spin icon-18">progress_activity</span>
695
1080
  <span>Refreshing tables...</span>
696
1081
  </div>
697
- `);let n=await r();if(t.innerHTML=``,await se(),await de(),n.success&&n.data&&n.data.length>0){let r=n.data,i=document.getElementById(`table-count-badge`);i&&(i.textContent=r.length.toString()),r.forEach(e=>{let n=document.createElement(`button`);n.type=`button`,n.className=`table-btn`,n.dataset.table=e,n.title=e,n.innerHTML=`
1082
+ `);let n=await i();if(t.innerHTML=``,await Pe(),await Re(),n.success&&n.data&&n.data.length>0){let r=n.data,i=document.getElementById(`table-count-badge`);i&&(i.textContent=r.length.toString()),r.forEach(e=>{let n=document.createElement(`button`);n.type=`button`,n.className=`table-btn`,n.dataset.table=e,n.title=e,n.innerHTML=`
698
1083
  <div class="table-btn-label">
699
1084
  <i class="material-symbols-outlined table-item-icon">table</i>
700
1085
  <span class="table-item-initial">${(e[0]||`T`).toUpperCase()}</span>
@@ -702,20 +1087,28 @@
702
1087
  <span class="dirty-indicator-dot hidden" title="Unsaved changes"></span>
703
1088
  </div>
704
1089
  <span class="table-btn-badge hidden" id="badge-${e}"></span>
705
- `,n.onclick=()=>{window.fkNavHistory&&window.fkNavHistory.toTable!==e&&(window.fkNavHistory=null),window.AppState.currentTable=e,window.AppState.currentTableBtnElement=n,document.querySelectorAll(`.table-btn`).forEach(e=>e.classList.remove(`active`)),n.classList.add(`active`),window.AppState.currentTab===`erd-btn`||window.AppState.currentTab===`sql-btn`||window.AppState.currentTab===`status-btn`?window.handleSwitchTab(`data-btn`):(window.updateUrlHash?.(window.AppState.currentTab,e),window.renderCurrentView())},n.oncontextmenu=t=>{A(t,[{icon:`content_copy`,label:`Copy Table Name`,action:async()=>{try{await navigator.clipboard.writeText(e)}catch{let t=document.createElement(`textarea`);t.value=e,document.body.appendChild(t),t.select(),document.execCommand(`copy`),t.remove()}window.showToast&&window.showToast(`Copied "${e}"`,`success`)}},{icon:`auto_fix_high`,label:`Generate Mock Data...`,action:async()=>{let t=await c(e);M(e,t.success?t.data:[],()=>{window.AppState.currentTable===e&&window.renderCurrentView()})}},{icon:`table_chart`,label:`View Data`,action:()=>{n.click(),window.handleSwitchTab(`data-btn`)}},{icon:`schema`,label:`View Schema`,action:()=>{n.click(),window.handleSwitchTab(`schema-btn`)}},{type:`divider`},{icon:`download`,label:`Export as CSV`,action:()=>{window.open(`/api/tables/${e}/export?format=csv`,`_blank`)}},{icon:`download`,label:`Export as JSON`,action:()=>{window.open(`/api/tables/${e}/export?format=json`,`_blank`)}},{type:`divider`},{icon:`mop`,label:`Truncate Table (Clear Rows)`,danger:!0,action:async()=>{if(confirm(`Are you sure you want to delete ALL data from table "${e}"? This cannot be undone!`)){let t=await p(e);t.success?(window.showToast&&window.showToast(`Cleared all rows from "${e}"`,`info`),window.AppState.currentTable===e&&window.renderCurrentView(),ae()):alert(`Failed to clear table: ${t.error}`)}}}])},t.appendChild(n)});let a=(window.parseHash?window.parseHash():{route:null,table:null}).table||window.AppState.currentTable;if(a){let e=document.querySelector(`.table-btn[data-table="${a}"]`);e&&(e.classList.add(`active`),window.AppState.currentTable=a,window.AppState.currentTableBtnElement=e)}if(!e){let e=window.getInitialRouteTab?window.getInitialRouteTab():null;window.handleSwitchTab(e||`data-btn`)}ae();let o=document.getElementById(`search-input`);o&&o.value.trim()&&fe(o.value.trim())}else{let n=document.getElementById(`table-count-badge`);n&&(n.textContent=`0`),t.innerHTML=`
706
- <div id="not-found-msg">
707
- <span class="material-symbols-outlined icon-20 text-soft">inventory_2</span>
1090
+ `,n.onclick=()=>{window.fkNavHistory&&window.fkNavHistory.toTable!==e&&(window.fkNavHistory=null),window.AppState.currentTable=e,window.AppState.currentTableBtnElement=n,document.querySelectorAll(`.table-btn`).forEach(e=>e.classList.remove(`active`)),n.classList.add(`active`),window.AppState.currentTab===`erd-btn`||window.AppState.currentTab===`sql-btn`||window.AppState.currentTab===`status-btn`?window.handleSwitchTab(`data-btn`):(window.updateUrlHash?.(window.AppState.currentTab,e),window.renderCurrentView())},n.oncontextmenu=t=>{V(t,[{icon:`content_copy`,label:`Copy Table Name`,action:async()=>{try{await navigator.clipboard.writeText(e)}catch{let t=document.createElement(`textarea`);t.value=e,document.body.appendChild(t),t.select(),document.execCommand(`copy`),t.remove()}window.showToast&&window.showToast(`Copied "${e}"`,`success`)}},{icon:`edit`,label:`Rename Table...`,action:()=>{Se(e)}},{icon:`auto_fix_high`,label:`Generate Mock Data...`,action:async()=>{let t=await u(e);oe(e,t.success?t.data:[],()=>{window.AppState.currentTable===e&&window.renderCurrentView()})}},{icon:`table_chart`,label:`View Data`,action:()=>{n.click(),window.handleSwitchTab(`data-btn`)}},{icon:`schema`,label:`View Schema`,action:()=>{n.click(),window.handleSwitchTab(`schema-btn`)}},{type:`divider`},{icon:`download`,label:`Export as CSV`,action:()=>{window.open(`/api/tables/${encodeURIComponent(e)}/export?format=csv`,`_blank`)}},{icon:`download`,label:`Export as JSON`,action:()=>{window.open(`/api/tables/${encodeURIComponent(e)}/export?format=json`,`_blank`)}},{type:`divider`},{icon:`mop`,label:`Truncate Table (Clear Rows)`,danger:!0,action:async()=>{if(confirm(`Are you sure you want to delete ALL data from table "${e}"? This cannot be undone!`)){let t=await g(e);t.success?(window.showToast&&window.showToast(`Cleared all rows from "${e}"`,`info`),window.AppState.currentTable===e&&window.renderCurrentView(),Ae()):alert(`Failed to clear table: ${t.error}`)}}},{icon:`delete`,label:`Move to Recycle Bin`,danger:!0,action:async()=>{if(!confirm(`Move table "${e}" to Recycle Bin?\n\n• The table will be soft-deleted and safely preserved in the Recycle Bin.\n• A local backup snapshot will be saved in .drixio/backups/.\n• You can restore it anytime in 1 click.\n\nClick OK to confirm, or Cancel to abort.`))return;let t=await ee(e,!0);t.success?(window.showToast&&window.showToast(`Table "${e}" moved to Recycle Bin`,`success`),window.AppState.currentTable===e&&(window.AppState.currentTable=null),await ke(!0),je()):alert(`Failed to delete table: ${t.error}`)}}])},t.appendChild(n)});let a=(window.parseHash?window.parseHash():{route:null,table:null}).table||window.AppState.currentTable;if(a){let e=document.querySelector(`.table-btn[data-table="${a}"]`);e&&(e.classList.add(`active`),window.AppState.currentTable=a,window.AppState.currentTableBtnElement=e)}if(!e){let e=window.getInitialRouteTab?window.getInitialRouteTab():null;window.handleSwitchTab(e||`data-btn`)}Ae();let o=document.getElementById(`search-input`);o&&o.value.trim()&&ze(o.value.trim())}else{let n=document.getElementById(`table-count-badge`);n&&(n.textContent=`0`),t.innerHTML=`
1091
+ <div id="not-found-msg" class="sidebar-empty-state">
1092
+ <span class="material-symbols-outlined icon-24 text-soft" style="font-size: 24px;">inventory_2</span>
708
1093
  <span>No Tables Found</span>
1094
+ <button type="button" class="sidebar-empty-cta-btn" id="sidebar-empty-create-btn">
1095
+ <span class="material-symbols-outlined" style="font-size: 14px;">add</span>
1096
+ <span>New Table</span>
1097
+ </button>
709
1098
  </div>
710
- `,e||(window.AppState.dbType===`none`?window.handleSwitchTab(`connect-btn`):window.handleSwitchTab(`sql-btn`))}re||=(pe(),!0)}catch(e){console.error(`Failed to fetch tables:`,e);let t=document.getElementById(`table-nav`);t&&(t.innerHTML=`
711
- <div id="not-found-msg" class="text-error">
712
- <span class="material-symbols-outlined icon-20">warning</span>
1099
+ `;let r=document.getElementById(`sidebar-empty-create-btn`);r&&(r.onclick=()=>{window.openCreateTableModal?.()}),e||(window.AppState.dbType===`none`?window.handleSwitchTab(`connect-btn`):window.handleSwitchTab(`sql-btn`))}je(),Oe||=(Be(),!0)}catch(e){console.error(`Failed to fetch tables:`,e);let t=document.getElementById(`table-nav`);if(t){t.innerHTML=`
1100
+ <div id="not-found-msg" class="sidebar-empty-state text-error">
1101
+ <span class="material-symbols-outlined icon-24" style="font-size: 24px;">warning</span>
713
1102
  <span>Failed to load tables</span>
1103
+ <button type="button" class="sidebar-empty-cta-btn" id="sidebar-empty-retry-btn">
1104
+ <span class="material-symbols-outlined" style="font-size: 14px;">refresh</span>
1105
+ <span>Retry</span>
1106
+ </button>
714
1107
  </div>
715
- `);let n=document.getElementById(`sidebar-db-status-dot`),r=document.getElementById(`brand-db-type`);n&&(n.classList.remove(`status-connected`),n.classList.add(`status-error`)),r&&(r.textContent=`ERROR`)}}async function ae(){try{let e=await o();e.success&&e.data&&Object.entries(e.data).forEach(([e,t])=>{let n=document.getElementById(`badge-${e}`);n&&(n.textContent=Number(t).toLocaleString(),n.classList.remove(`hidden`),n.style.display=`inline-flex`)})}catch(e){console.error(`Failed to load table stats:`,e)}}window.loadTableStats=ae;function oe(e){let t=e||window.AppState?.currentTable;if(!t)return;document.querySelectorAll(`.table-btn`).forEach(e=>e.classList.remove(`active`));let n=document.querySelector(`.table-btn[data-table="${t}"]`);n&&(n.classList.add(`active`),window.AppState&&(window.AppState.currentTableBtnElement=n))}window.updateSidebarActiveTable=oe,window.initSidebar=ie;async function se(){let e=document.getElementById(`sidebar-db-status-dot`),t=document.getElementById(`brand-db-type`);try{if(!t)return;let n=await a();n?.success&&n.data?.connected&&n.data?.dbType&&n.data.dbType!==`none`?(window.AppState.dbType=n.data.dbType,t.textContent=n.data.dbType.toUpperCase(),e&&(e.classList.remove(`status-error`,`status-warning`),e.classList.add(`status-connected`)),window.setStudioConnectionMode?.(!0)):(window.AppState.dbType=`none`,t.textContent=`NO DATABASE`,e&&(e.classList.remove(`status-connected`,`status-error`),e.classList.add(`status-warning`)),window.setStudioConnectionMode?.(!1))}catch{e&&(e.classList.remove(`status-connected`,`status-warning`),e.classList.add(`status-error`)),t&&(t.textContent=`DISCONNECTED`),window.setStudioConnectionMode?.(!1)}}var ce=!1,le=`public`,ue=[];async function de(){let e=document.getElementById(`schema-selector-wrap`),t=document.getElementById(`schema-select-box`);if(!(!e||!t))try{let n=await C();if(!n?.success||!n.data?.supported){e.classList.add(`hidden`);return}let{schemas:r,currentSchema:i}=n.data;ue=r||[],le=i||`public`;let a=document.getElementById(`schema-current-display`);a&&(a.textContent=le),e.classList.remove(`hidden`),ce||(ce=!0,t.addEventListener(`click`,e=>{e.stopPropagation(),I({anchorEl:t,title:`Database Schemas`,searchable:ue.length>4,placeholder:`Search schemas...`,initialValue:le,items:ue.map(e=>({name:e,value:e,icon:`folder`,badge:e===le?`active`:``})),onSelect:async e=>{if(e!==le){a&&(a.textContent=e);try{let t=await w(e);t.success?(le=e,window.AppState.currentTable=null,window.AppState.currentTableBtnElement=null,await ie(!0),window.showToast&&window.showToast(`Switched to schema "${e}" (${t.data?.tableCount??0} tables)`,`success`)):(window.showToast&&window.showToast(`Failed to switch schema: ${t.error}`,`error`),await de())}catch(e){window.showToast&&window.showToast(`Schema switch error: ${e.message}`,`error`),await de()}}}})}))}catch{e.classList.add(`hidden`)}}function fe(e){if(document.getElementById(`sidebar-panel`)?.classList.contains(`collapsed`)){document.querySelectorAll(`.table-btn`).forEach(e=>e.style.display=`flex`),document.getElementById(`sidebar-no-match`)?.remove();return}let t=e.toLowerCase().trim(),n=document.querySelectorAll(`.table-btn`),r=0;n.forEach(e=>{let n=(e.dataset.table||``).toLowerCase();!t||n.includes(t)?(e.style.display=`flex`,r++):e.style.display=`none`});let i=document.getElementById(`table-nav`),a=document.getElementById(`sidebar-no-match`);r===0&&n.length>0?a||(a=document.createElement(`div`),a.id=`sidebar-no-match`,a.className=`sidebar-empty-state`,a.innerHTML=`
1108
+ `;let e=document.getElementById(`sidebar-empty-retry-btn`);e&&(e.onclick=()=>{ke(!0)})}let n=document.getElementById(`sidebar-db-status-dot`),r=document.getElementById(`brand-db-type`);n&&(n.classList.remove(`status-connected`),n.classList.add(`status-error`)),r&&(r.textContent=`ERROR`)}}async function Ae(){try{let e=await c();e.success&&e.data&&Object.entries(e.data).forEach(([e,t])=>{let n=document.getElementById(`badge-${e}`);n&&(n.textContent=Number(t).toLocaleString(),n.classList.remove(`hidden`),n.style.display=`inline-flex`)})}catch(e){console.error(`Failed to load table stats:`,e)}}window.loadTableStats=Ae;async function je(){try{let e=await te();Me(e.success&&Array.isArray(e.data)?e.data.length:0)}catch{}}window.refreshTrashBadge=je;function Me(e){let t=document.getElementById(`sidebar-trash-btn`),n=document.getElementById(`sidebar-trash-count`);t&&n&&(n.textContent=e.toString(),e>0?t.classList.remove(`hidden`):t.classList.add(`hidden`))}window.updateSidebarTrashBadge=Me;function Ne(e){let t=e||window.AppState?.currentTable;if(!t)return;document.querySelectorAll(`.table-btn`).forEach(e=>e.classList.remove(`active`));let n=document.querySelector(`.table-btn[data-table="${t}"]`);n&&(n.classList.add(`active`),window.AppState&&(window.AppState.currentTableBtnElement=n))}window.updateSidebarActiveTable=Ne,window.initSidebar=ke;async function Pe(){let e=document.getElementById(`sidebar-db-status-dot`),t=document.getElementById(`brand-db-type`);try{if(!t)return;let n=await o();n?.success&&n.data?.connected&&n.data?.dbType&&n.data.dbType!==`none`?(window.AppState.dbType=n.data.dbType,t.textContent=n.data.dbType.toUpperCase(),e&&(e.classList.remove(`status-error`,`status-warning`),e.classList.add(`status-connected`)),window.setStudioConnectionMode?.(!0)):(window.AppState.dbType=`none`,t.textContent=`NO DATABASE`,e&&(e.classList.remove(`status-connected`,`status-error`),e.classList.add(`status-warning`)),window.setStudioConnectionMode?.(!1))}catch{e&&(e.classList.remove(`status-connected`,`status-warning`),e.classList.add(`status-error`)),t&&(t.textContent=`DISCONNECTED`),window.setStudioConnectionMode?.(!1)}}var Fe=!1,Ie=`public`,Le=[];async function Re(){let e=document.getElementById(`schema-selector-wrap`),t=document.getElementById(`schema-select-box`);if(!(!e||!t))try{let n=await D();if(!n?.success||!n.data?.supported){e.classList.add(`hidden`);return}let{schemas:r,currentSchema:i}=n.data;Le=r||[],Ie=i||`public`;let a=document.getElementById(`schema-current-display`);a&&(a.textContent=Ie),e.classList.remove(`hidden`),Fe||(Fe=!0,t.addEventListener(`click`,e=>{e.stopPropagation(),H({anchorEl:t,title:`Database Schemas`,searchable:Le.length>4,placeholder:`Search schemas...`,initialValue:Ie,items:Le.map(e=>({name:e,value:e,icon:`folder`,badge:e===Ie?`active`:``})),onSelect:async e=>{if(e!==Ie){a&&(a.textContent=e);try{let t=await O(e);t.success?(Ie=e,window.AppState.currentTable=null,window.AppState.currentTableBtnElement=null,await ke(!0),window.showToast&&window.showToast(`Switched to schema "${e}" (${t.data?.tableCount??0} tables)`,`success`)):(window.showToast&&window.showToast(`Failed to switch schema: ${t.error}`,`error`),await Re())}catch(e){window.showToast&&window.showToast(`Schema switch error: ${e.message}`,`error`),await Re()}}}})}))}catch{e.classList.add(`hidden`)}}function ze(e){if(document.getElementById(`sidebar-panel`)?.classList.contains(`collapsed`)){document.querySelectorAll(`.table-btn`).forEach(e=>e.style.display=`flex`),document.getElementById(`sidebar-no-match`)?.remove();return}let t=e.toLowerCase().trim(),n=document.querySelectorAll(`.table-btn`),r=0;n.forEach(e=>{let n=(e.dataset.table||``).toLowerCase();!t||n.includes(t)?(e.style.display=`flex`,r++):e.style.display=`none`});let i=document.getElementById(`table-nav`),a=document.getElementById(`sidebar-no-match`);r===0&&n.length>0?a||(a=document.createElement(`div`),a.id=`sidebar-no-match`,a.className=`sidebar-empty-state`,a.innerHTML=`
716
1109
  <span class="material-symbols-outlined icon-20 text-soft">search_off</span>
717
1110
  <span>No matching tables</span>
718
- `,i?.appendChild(a)):a&&a.remove();let o=document.getElementById(`table-count-badge`);o&&(o.textContent=r.toString())}function pe(){let e=document.getElementById(`search-input`),t=document.getElementById(`search-clear-btn`),n=document.getElementById(`refresh-tables-btn`),r=document.getElementById(`sidebar-collapse-btn`),i=document.getElementById(`sidebar-panel`);e&&(e.addEventListener(`input`,e=>{let n=e.target.value;t&&(n?t.classList.remove(`hidden`):t.classList.add(`hidden`)),fe(n)}),e.addEventListener(`keydown`,t=>{if(t.key===`Enter`){t.preventDefault();let n=document.querySelector(`.table-btn:not([style*="display: none"])`);n&&(n.click(),e.blur())}}),t&&t.addEventListener(`click`,()=>{e.value=``,t.classList.add(`hidden`),fe(``),e.focus()}));let a=document.getElementById(`add-table-btn`);if(a&&a.addEventListener(`click`,()=>{ne()}),n&&n.addEventListener(`click`,async()=>{n.classList.add(`animate-spin`),await ie(!0),setTimeout(()=>{n.classList.remove(`animate-spin`),window.showToast&&window.showToast(`Tables refreshed`,`success`)},300)}),i){localStorage.getItem(`drixio_sidebar_collapsed`)===`true`&&(i.classList.add(`collapsed`),me(!0)),r&&r.addEventListener(`click`,n=>{n.stopPropagation(),i.classList.toggle(`collapsed`);let r=i.classList.contains(`collapsed`);localStorage.setItem(`drixio_sidebar_collapsed`,r.toString()),me(r),r&&e&&(e.value=``,t?.classList.add(`hidden`),fe(``))});let n=document.getElementById(`sidebar-header`);n&&n.addEventListener(`click`,()=>{i.classList.contains(`collapsed`)&&(i.classList.remove(`collapsed`),localStorage.setItem(`drixio_sidebar_collapsed`,`false`),me(!1))})}document.addEventListener(`keydown`,n=>{if(n.key===`/`&&document.activeElement?.tagName!==`INPUT`&&document.activeElement?.tagName!==`TEXTAREA`){if(n.preventDefault(),window.AppState?.currentTab===`erd-btn`){let e=document.getElementById(`erd-search-input`);if(e){e.focus(),e.select();return}}e?.focus(),e?.select()}else n.key===`Escape`&&document.activeElement===e&&(e.value&&(e.value=``,t?.classList.add(`hidden`),fe(``)),e.blur())})}function me(e){let t=document.getElementById(`sidebar-collapse-icon`),n=document.getElementById(`sidebar-collapse-btn`),r=document.getElementById(`sidebar-header`);t&&(t.textContent=e?`menu`:`menu_open`),n&&(n.title=e?`Expand sidebar`:`Collapse sidebar`),r&&(r.title=e?`Click to expand sidebar`:``)}function he(e,t){document.querySelectorAll(`#${e} .cell-in-range, #${e} .cell-selected, #${e} .range-top, #${e} .range-bottom, #${e} .range-left, #${e} .range-right, #${e} .row-header-selected`).forEach(e=>{e.classList.remove(`cell-in-range`,`cell-selected`,`range-top`,`range-bottom`,`range-left`,`range-right`,`row-header-selected`)});let n=t.selection;if(!n||n.startRow===-1)return;let r=Math.min(n.startRow,n.endRow),i=Math.max(n.startRow,n.endRow),a=Math.min(n.startCol,n.endCol),o=Math.max(n.startCol,n.endCol);document.querySelectorAll(`#${e} td.data-cell`).forEach(e=>{let s=parseInt(e.dataset.rowIdx),c=parseInt(e.dataset.colIdx);s>=r&&s<=i&&c>=a&&c<=o&&(e.classList.add(`cell-in-range`),s===r&&e.classList.add(`range-top`),s===i&&e.classList.add(`range-bottom`),c===a&&e.classList.add(`range-left`),c===o&&e.classList.add(`range-right`),s===n.startRow&&c===n.startCol&&(e.classList.add(`cell-selected`),t.selectedCell=e))}),(n.isRowSelection||n.isDraggingRow)&&document.querySelectorAll(`#${e} td.row-header`).forEach(e=>{let t=parseInt(e.dataset.rowIdx);t>=r&&t<=i&&e.classList.add(`row-header-selected`)})}function ge(e,t,n){let r=document.querySelectorAll(`#${e} tbody tr:not(.ghost-row-tr)`).length;r!==0&&(t.selection={isDragging:!1,isDraggingRow:!1,isRowSelection:!0,startRow:0,endRow:r-1,startCol:0,endCol:Math.max(0,n-1)},he(e,t))}function _e(e,t,n,r){e.addEventListener(`mousedown`,e=>{if(e.target.tagName===`INPUT`||e.target.tagName===`SELECT`)return;let i=e.target.closest(`td.row-header`);if(i&&e.button!==2){let a=parseInt(i.dataset.rowIdx);if(isNaN(a))return;e.shiftKey&&n.selection&&n.selection.startRow!==-1?(n.selection.isDragging=!1,n.selection.isDraggingRow=!1,n.selection.isRowSelection=!0,n.selection.endRow=a,n.selection.startCol=0,n.selection.endCol=r-1):n.selection={isDragging:!1,isDraggingRow:!0,isRowSelection:!0,startRow:a,endRow:a,startCol:0,endCol:r-1},he(t,n);return}let a=e.target.closest(`td.data-cell`);if(!a)return;let o=parseInt(a.dataset.rowIdx),s=parseInt(a.dataset.colIdx);isNaN(o)||isNaN(s)||(e.shiftKey&&n.selection&&n.selection.startRow!==-1?(n.selection.isDragging=!1,n.selection.isDraggingRow=!1,n.selection.isRowSelection=!1,n.selection.endRow=o,n.selection.endCol=s):n.selection={isDragging:!0,isRowSelection:!1,startRow:o,startCol:s,endRow:o,endCol:s},he(t,n))}),e.addEventListener(`mouseover`,e=>{if(n.selection.isDraggingRow){let r=e.target.closest(`td.row-header`);if(!r)return;n.selection.endRow=parseInt(r.dataset.rowIdx),he(t,n);return}if(!n.selection.isDragging)return;let r=e.target.closest(`td.data-cell`);r&&(n.selection.endRow=parseInt(r.dataset.rowIdx),n.selection.endCol=parseInt(r.dataset.colIdx),he(t,n))}),e.addEventListener(`mouseup`,()=>{n.selection&&(n.selection.isDragging=!1,n.selection.isDraggingRow=!1)})}function ve(e,t){let n=document.createElement(`div`);n.className=`resizer`,e.appendChild(n),n.addEventListener(`click`,e=>e.stopPropagation()),n.addEventListener(`dblclick`,t=>{t.preventDefault(),t.stopPropagation(),e.style.width=``,e.style.minWidth=``,e.style.maxWidth=``}),n.addEventListener(`mousedown`,n=>{n.preventDefault(),n.stopPropagation();let r=n.pageX,i=e.offsetWidth,a=!1;document.body.style.userSelect=`none`;let o=n=>{a=!0,t&&(t.isResizing=!0);let o=Math.max(60,i+(n.pageX-r));e.style.width=o+`px`,e.style.minWidth=o+`px`,e.style.maxWidth=o+`px`},s=()=>{document.removeEventListener(`mousemove`,o),document.removeEventListener(`mouseup`,s),document.body.style.cursor=``,document.body.style.userSelect=``,a&&setTimeout(()=>{t&&(t.isResizing=!1)},100)};document.body.style.cursor=`col-resize`,document.addEventListener(`mousemove`,o),document.addEventListener(`mouseup`,s)})}var ye=[{category:`COMPARISON`,operators:[{label:`Equals`,op:`=`,symbol:`=`},{label:`Not equal`,op:`<>`,symbol:`<>`},{label:`Greater than`,op:`>`,symbol:`>`},{label:`Less than`,op:`<`,symbol:`<`},{label:`Greater or equal`,op:`>=`,symbol:`>=`},{label:`Less or equal`,op:`<=`,symbol:`<=`}]},{category:`PATTERN MATCHING`,operators:[{label:`Like`,op:`LIKE`,symbol:`~~`},{label:`iLike`,op:`ILIKE`,symbol:`~~*`},{label:`Not Like`,op:`NOT LIKE`,symbol:`!~~`}]},{category:`NULL CHECKS`,operators:[{label:`Is null`,op:`IS NULL`,symbol:`is null`,isUnary:!0},{label:`Is not null`,op:`IS NOT NULL`,symbol:`is not null`,isUnary:!0},{label:`In list`,op:`IN`,symbol:`in`}]}],be=new Map;function xe(e){return be.has(e)||be.set(e,{activeFilters:[],freeTextSearch:``,draft:null}),be.get(e)}function Se(e){let t=xe(e);t.activeFilters=[],t.freeTextSearch=``,t.draft=null}function Ce(e){let t=xe(e);return t.activeFilters.length>0||!!t.freeTextSearch}function we(e,t=[]){let n=xe(e),r=[],i=e=>`"${(e||``).replace(/"/g,`""`)}"`,a=e=>(e||``).replace(/'/g,`''`);for(let e of n.activeFilters){if(e.type===`sql`||e.op===`RAW`){e.val&&e.val.trim()&&r.push(`(${e.val.trim()})`);continue}let{col:t,op:n,val:o}=e;if(!t||!n)continue;if(n===`IS NULL`||n===`IS NOT NULL`){r.push(`${i(t)} ${n}`);continue}if(n===`IN`){let e=(o||``).trim();e.startsWith(`(`)||(e=`(${e})`),r.push(`${i(t)} IN ${e}`);continue}let s=a(o);if(n===`LIKE`){let e=s.includes(`%`)||s.includes(`_`)?s:`%${s}%`;r.push(`${i(t)} LIKE '${e}'`);continue}if(n===`ILIKE`){let e=s.includes(`%`)||s.includes(`_`)?s:`%${s}%`;r.push(`LOWER(${i(t)}) LIKE LOWER('${e}')`);continue}if(n===`NOT LIKE`){let e=s.includes(`%`)||s.includes(`_`)?s:`%${s}%`;r.push(`${i(t)} NOT LIKE '${e}'`);continue}let c=!isNaN(Number(o))&&o.trim()!==``?o.trim():`'${s}'`,l=n===`!=`?`<>`:n;r.push(`${i(t)} ${l} ${c}`)}if(n.freeTextSearch&&n.freeTextSearch.trim()){let e=a(n.freeTextSearch.trim()),o=t.filter(e=>{let t=(e.type||``).toUpperCase();return t.includes(`CHAR`)||t.includes(`TEXT`)||t.includes(`VARCHAR`)||t.includes(`STRING`)||!t}).map(e=>e.name),s=o.length>0?o:t.map(e=>e.name);if(s.length>0){let t=s.map(t=>`LOWER(${i(t)}) LIKE LOWER('%${e}%')`);r.push(`(${t.join(` OR `)})`)}}return r.join(` AND `)}function Te({container:e,tableName:t,schema:n=[],onFilterChange:r}){let i=xe(t),a=n.map(e=>e.name),o=a[0]||`id`,s=`Filter table (e.g. ${o} = 1, status = 'active') or search...`;e.innerHTML=`
1111
+ `,i?.appendChild(a)):a&&a.remove();let o=document.getElementById(`table-count-badge`);o&&(o.textContent=r.toString())}function Be(){let e=document.getElementById(`search-input`),t=document.getElementById(`search-clear-btn`),n=document.getElementById(`refresh-tables-btn`),r=document.getElementById(`sidebar-collapse-btn`),i=document.getElementById(`sidebar-panel`);e&&(e.addEventListener(`input`,e=>{let n=e.target.value;t&&(n?t.classList.remove(`hidden`):t.classList.add(`hidden`)),ze(n)}),e.addEventListener(`keydown`,t=>{if(t.key===`Enter`){t.preventDefault();let n=document.querySelector(`.table-btn:not([style*="display: none"])`);n&&(n.click(),e.blur())}}),t&&t.addEventListener(`click`,()=>{e.value=``,t.classList.add(`hidden`),ze(``),e.focus()}));let a=document.getElementById(`add-table-btn`);a&&a.addEventListener(`click`,()=>{me()}),n&&n.addEventListener(`click`,async()=>{n.classList.add(`animate-spin`),await ke(!0),setTimeout(()=>{n.classList.remove(`animate-spin`),window.showToast&&window.showToast(`Tables refreshed`,`success`)},300)});let o=document.getElementById(`sidebar-app-btn`);o&&o.addEventListener(`click`,async()=>{let e=await ne();e.success?window.showToast?.(e.message,`success`):window.showToast?.(`Failed: ${e.error}`,`error`)});let s=document.getElementById(`sidebar-health-btn`);s&&s.addEventListener(`click`,()=>{De(()=>import(`./healthModal-Wc69raxJ.js`).then(e=>e.openHealthModal()),[],import.meta.url)});let c=document.getElementById(`sidebar-trash-btn`);if(c&&c.addEventListener(`click`,()=>{De(()=>import(`./recycleBinModal-CM1yVRKo.js`).then(e=>e.openRecycleBinModal()),[],import.meta.url)}),i){localStorage.getItem(`drixio_sidebar_collapsed`)===`true`&&(i.classList.add(`collapsed`),Ve(!0)),r&&r.addEventListener(`click`,n=>{n.stopPropagation(),i.classList.toggle(`collapsed`);let r=i.classList.contains(`collapsed`);localStorage.setItem(`drixio_sidebar_collapsed`,r.toString()),Ve(r),r&&e&&(e.value=``,t?.classList.add(`hidden`),ze(``))});let n=document.getElementById(`sidebar-header`);n&&n.addEventListener(`click`,()=>{i.classList.contains(`collapsed`)&&(i.classList.remove(`collapsed`),localStorage.setItem(`drixio_sidebar_collapsed`,`false`),Ve(!1))})}document.addEventListener(`keydown`,n=>{if(n.key===`/`&&document.activeElement?.tagName!==`INPUT`&&document.activeElement?.tagName!==`TEXTAREA`){if(n.preventDefault(),window.AppState?.currentTab===`erd-btn`){let e=document.getElementById(`erd-search-input`);if(e){e.focus(),e.select();return}}e?.focus(),e?.select()}else n.key===`Escape`&&document.activeElement===e&&(e.value&&(e.value=``,t?.classList.add(`hidden`),ze(``)),e.blur())})}function Ve(e){let t=document.getElementById(`sidebar-collapse-icon`),n=document.getElementById(`sidebar-collapse-btn`),r=document.getElementById(`sidebar-header`);t&&(t.textContent=e?`menu`:`menu_open`),n&&(n.title=e?`Expand sidebar`:`Collapse sidebar`),r&&(r.title=e?`Click to expand sidebar`:``)}function He(e,t){document.querySelectorAll(`#${e} .cell-in-range, #${e} .cell-selected, #${e} .range-top, #${e} .range-bottom, #${e} .range-left, #${e} .range-right, #${e} .row-header-selected`).forEach(e=>{e.classList.remove(`cell-in-range`,`cell-selected`,`range-top`,`range-bottom`,`range-left`,`range-right`,`row-header-selected`)});let n=t.selection;if(!n||n.startRow===-1)return;let r=Math.min(n.startRow,n.endRow),i=Math.max(n.startRow,n.endRow),a=Math.min(n.startCol,n.endCol),o=Math.max(n.startCol,n.endCol);document.querySelectorAll(`#${e} td.data-cell`).forEach(e=>{let s=parseInt(e.dataset.rowIdx),c=parseInt(e.dataset.colIdx);s>=r&&s<=i&&c>=a&&c<=o&&(e.classList.add(`cell-in-range`),s===r&&e.classList.add(`range-top`),s===i&&e.classList.add(`range-bottom`),c===a&&e.classList.add(`range-left`),c===o&&e.classList.add(`range-right`),s===n.startRow&&c===n.startCol&&(e.classList.add(`cell-selected`),t.selectedCell=e))}),(n.isRowSelection||n.isDraggingRow)&&document.querySelectorAll(`#${e} td.row-header`).forEach(e=>{let t=parseInt(e.dataset.rowIdx);t>=r&&t<=i&&e.classList.add(`row-header-selected`)})}function Ue(e,t,n){let r=document.querySelectorAll(`#${e} tbody tr:not(.ghost-row-tr)`).length;r!==0&&(t.selection={isDragging:!1,isDraggingRow:!1,isRowSelection:!0,startRow:0,endRow:r-1,startCol:0,endCol:Math.max(0,n-1)},He(e,t))}function We(e,t,n,r){e.addEventListener(`mousedown`,e=>{if(e.target.tagName===`INPUT`||e.target.tagName===`SELECT`)return;let i=e.target.closest(`td.row-header`);if(i&&e.button!==2){let a=parseInt(i.dataset.rowIdx);if(isNaN(a))return;e.shiftKey&&n.selection&&n.selection.startRow!==-1?(n.selection.isDragging=!1,n.selection.isDraggingRow=!1,n.selection.isRowSelection=!0,n.selection.endRow=a,n.selection.startCol=0,n.selection.endCol=r-1):n.selection={isDragging:!1,isDraggingRow:!0,isRowSelection:!0,startRow:a,endRow:a,startCol:0,endCol:r-1},He(t,n);return}let a=e.target.closest(`td.data-cell`);if(!a)return;let o=parseInt(a.dataset.rowIdx),s=parseInt(a.dataset.colIdx);isNaN(o)||isNaN(s)||(e.shiftKey&&n.selection&&n.selection.startRow!==-1?(n.selection.isDragging=!1,n.selection.isDraggingRow=!1,n.selection.isRowSelection=!1,n.selection.endRow=o,n.selection.endCol=s):n.selection={isDragging:!0,isRowSelection:!1,startRow:o,startCol:s,endRow:o,endCol:s},He(t,n))}),e.addEventListener(`mouseover`,e=>{if(n.selection.isDraggingRow){let r=e.target.closest(`td.row-header`);if(!r)return;n.selection.endRow=parseInt(r.dataset.rowIdx),He(t,n);return}if(!n.selection.isDragging)return;let r=e.target.closest(`td.data-cell`);r&&(n.selection.endRow=parseInt(r.dataset.rowIdx),n.selection.endCol=parseInt(r.dataset.colIdx),He(t,n))}),e.addEventListener(`mouseup`,()=>{n.selection&&(n.selection.isDragging=!1,n.selection.isDraggingRow=!1)})}function Ge(e,t){let n=document.createElement(`div`);n.className=`resizer`,e.appendChild(n),n.addEventListener(`click`,e=>e.stopPropagation()),n.addEventListener(`dblclick`,t=>{t.preventDefault(),t.stopPropagation(),e.style.width=``,e.style.minWidth=``,e.style.maxWidth=``}),n.addEventListener(`mousedown`,n=>{n.preventDefault(),n.stopPropagation();let r=n.pageX,i=e.offsetWidth,a=!1;document.body.style.userSelect=`none`;let o=n=>{a=!0,t&&(t.isResizing=!0);let o=Math.max(60,i+(n.pageX-r));e.style.width=o+`px`,e.style.minWidth=o+`px`,e.style.maxWidth=o+`px`},s=()=>{document.removeEventListener(`mousemove`,o),document.removeEventListener(`mouseup`,s),document.body.style.cursor=``,document.body.style.userSelect=``,a&&setTimeout(()=>{t&&(t.isResizing=!1)},100)};document.body.style.cursor=`col-resize`,document.addEventListener(`mousemove`,o),document.addEventListener(`mouseup`,s)})}var Ke=[{category:`COMPARISON`,operators:[{label:`Equals`,op:`=`,symbol:`=`},{label:`Not equal`,op:`<>`,symbol:`<>`},{label:`Greater than`,op:`>`,symbol:`>`},{label:`Less than`,op:`<`,symbol:`<`},{label:`Greater or equal`,op:`>=`,symbol:`>=`},{label:`Less or equal`,op:`<=`,symbol:`<=`}]},{category:`PATTERN MATCHING`,operators:[{label:`Like`,op:`LIKE`,symbol:`~~`},{label:`iLike`,op:`ILIKE`,symbol:`~~*`},{label:`Not Like`,op:`NOT LIKE`,symbol:`!~~`}]},{category:`NULL CHECKS`,operators:[{label:`Is null`,op:`IS NULL`,symbol:`is null`,isUnary:!0},{label:`Is not null`,op:`IS NOT NULL`,symbol:`is not null`,isUnary:!0},{label:`In list`,op:`IN`,symbol:`in`}]}],qe=new Map;function Je(e){return qe.has(e)||qe.set(e,{activeFilters:[],freeTextSearch:``,draft:null}),qe.get(e)}function Ye(e){let t=Je(e);t.activeFilters=[],t.freeTextSearch=``,t.draft=null}function Xe(e){let t=Je(e);return t.activeFilters.length>0||!!t.freeTextSearch}function Ze(e,t=[]){let n=Je(e),r=[],i=e=>`"${(e||``).replace(/"/g,`""`)}"`,a=e=>(e||``).replace(/'/g,`''`);for(let e of n.activeFilters){if(e.type===`sql`||e.op===`RAW`){e.val&&e.val.trim()&&r.push(`(${e.val.trim()})`);continue}let{col:t,op:n,val:o}=e;if(!t||!n)continue;if(n===`IS NULL`||n===`IS NOT NULL`){r.push(`${i(t)} ${n}`);continue}if(n===`IN`){let e=(o||``).trim();e.startsWith(`(`)||(e=`(${e})`),r.push(`${i(t)} IN ${e}`);continue}let s=a(o);if(n===`LIKE`){let e=s.includes(`%`)||s.includes(`_`)?s:`%${s}%`;r.push(`${i(t)} LIKE '${e}'`);continue}if(n===`ILIKE`){let e=s.includes(`%`)||s.includes(`_`)?s:`%${s}%`;r.push(`LOWER(${i(t)}) LIKE LOWER('${e}')`);continue}if(n===`NOT LIKE`){let e=s.includes(`%`)||s.includes(`_`)?s:`%${s}%`;r.push(`${i(t)} NOT LIKE '${e}'`);continue}let c=!isNaN(Number(o))&&o.trim()!==``?o.trim():`'${s}'`,l=n===`!=`?`<>`:n;r.push(`${i(t)} ${l} ${c}`)}if(n.freeTextSearch&&n.freeTextSearch.trim()){let e=a(n.freeTextSearch.trim()),o=t.filter(e=>{let t=(e.type||``).toUpperCase();return t.includes(`CHAR`)||t.includes(`TEXT`)||t.includes(`VARCHAR`)||t.includes(`STRING`)||!t}).map(e=>e.name),s=o.length>0?o:t.map(e=>e.name);if(s.length>0){let t=s.map(t=>`LOWER(${i(t)}) LIKE LOWER('%${e}%')`);r.push(`(${t.join(` OR `)})`)}}return r.join(` AND `)}function Qe({container:e,tableName:t,schema:n=[],onFilterChange:r}){let i=Je(t),a=n.map(e=>e.name),o=a[0]||`id`,s=`Filter table (e.g. ${o} = 1, status = 'active') or search...`;e.innerHTML=`
719
1112
  <div class="filter-bar-container" id="filter-bar-container-${t}">
720
1113
  <div class="filter-bar-input-box" id="filter-bar-box-${t}">
721
1114
  <span class="material-symbols-outlined filter-bar-search-icon">search</span>
@@ -732,7 +1125,7 @@
732
1125
  <button
733
1126
  type="button"
734
1127
  id="filter-bar-clear-all-${t}"
735
- class="filter-bar-clear-btn ${Ce(t)?``:`hidden`}"
1128
+ class="filter-bar-clear-btn ${Xe(t)?``:`hidden`}"
736
1129
  title="Clear all filters"
737
1130
  >
738
1131
  <span class="material-symbols-outlined">close</span>
@@ -740,7 +1133,7 @@
740
1133
  </div>
741
1134
  <div class="filter-popover hidden" id="filter-popover-${t}"></div>
742
1135
  </div>
743
- `;let c=document.getElementById(`filter-bar-pills-${t}`),l=document.getElementById(`filter-bar-input-${t}`),u=document.getElementById(`filter-bar-clear-all-${t}`),d=document.getElementById(`filter-popover-${t}`),f=document.getElementById(`filter-bar-box-${t}`),p=()=>{i.activeFilters.length>0?l.placeholder=`Add more filters or SQL conditions...`:l.placeholder=s,u&&(Ce(t)?u.classList.remove(`hidden`):u.classList.add(`hidden`))},m=()=>{c.innerHTML=``,i.activeFilters.forEach(e=>{let t=document.createElement(`div`);if(t.className=`filter-pill`,t.dataset.filterId=e.id,i.draft&&i.draft.id===e.id&&t.classList.add(`is-editing`),e.type===`sql`||e.op===`RAW`)t.innerHTML=`
1136
+ `;let c=document.getElementById(`filter-bar-pills-${t}`),l=document.getElementById(`filter-bar-input-${t}`),u=document.getElementById(`filter-bar-clear-all-${t}`),d=document.getElementById(`filter-popover-${t}`),f=document.getElementById(`filter-bar-box-${t}`),p=()=>{i.activeFilters.length>0?l.placeholder=`Add more filters or SQL conditions...`:l.placeholder=s,u&&(Xe(t)?u.classList.remove(`hidden`):u.classList.add(`hidden`))},m=()=>{c.innerHTML=``,i.activeFilters.forEach(e=>{let t=document.createElement(`div`);if(t.className=`filter-pill`,t.dataset.filterId=e.id,i.draft&&i.draft.id===e.id&&t.classList.add(`is-editing`),e.type===`sql`||e.op===`RAW`)t.innerHTML=`
744
1137
  <span class="material-symbols-outlined" style="font-size: 14px; color: var(--color-primary); line-height: 1;">code</span>
745
1138
  <span class="filter-pill-val" title="${h(e.val)}">${h(e.val)}</span>
746
1139
  <button type="button" class="filter-pill-remove" title="Remove condition">&times;</button>
@@ -791,7 +1184,7 @@
791
1184
  <div class="filter-popover-scroll">
792
1185
  ${u}
793
1186
  </div>
794
- `;let f=d.querySelector(`[data-smart-action="true"]`);f&&(f.addEventListener(`mouseenter`,()=>{d.querySelectorAll(`.filter-popover-item`).forEach(e=>e.classList.remove(`active`)),f.classList.add(`active`)}),f.onclick=e=>{e.stopPropagation(),x(s)});let p=d.querySelector(`[data-sql-action="true"]`);p&&c&&(p.addEventListener(`mouseenter`,()=>{d.querySelectorAll(`.filter-popover-item`).forEach(e=>e.classList.remove(`active`)),p.classList.add(`active`)}),p.onclick=e=>{e.stopPropagation(),x({id:`sql-${Date.now()}`,type:`sql`,col:`SQL`,op:`RAW`,symbol:`SQL`,val:c.val})}),d.querySelectorAll(`.filter-popover-item:not([data-smart-action="true"]):not([data-sql-action="true"])`).forEach(e=>{e.addEventListener(`mouseenter`,()=>{d.querySelectorAll(`.filter-popover-item`).forEach(e=>e.classList.remove(`active`)),e.classList.add(`active`)}),e.onclick=t=>{t.stopPropagation();let n=e.dataset.col;i.draft={id:i.draft?.id||null,col:n,op:i.draft?.op||`=`,val:i.draft?.val||``,step:`operator`},l.value=``,y(),l.focus(),w()}})},y=()=>{let e=``,t=!0;ye.forEach(n=>{e+=`<div class="filter-category-title">${n.category}</div>`,n.operators.forEach(n=>{let r=i.draft?.op?i.draft.op===n.op:t;r&&(t=!1),e+=`
1187
+ `;let f=d.querySelector(`[data-smart-action="true"]`);f&&(f.addEventListener(`mouseenter`,()=>{d.querySelectorAll(`.filter-popover-item`).forEach(e=>e.classList.remove(`active`)),f.classList.add(`active`)}),f.onclick=e=>{e.stopPropagation(),x(s)});let p=d.querySelector(`[data-sql-action="true"]`);p&&c&&(p.addEventListener(`mouseenter`,()=>{d.querySelectorAll(`.filter-popover-item`).forEach(e=>e.classList.remove(`active`)),p.classList.add(`active`)}),p.onclick=e=>{e.stopPropagation(),x({id:`sql-${Date.now()}`,type:`sql`,col:`SQL`,op:`RAW`,symbol:`SQL`,val:c.val})}),d.querySelectorAll(`.filter-popover-item:not([data-smart-action="true"]):not([data-sql-action="true"])`).forEach(e=>{e.addEventListener(`mouseenter`,()=>{d.querySelectorAll(`.filter-popover-item`).forEach(e=>e.classList.remove(`active`)),e.classList.add(`active`)}),e.onclick=t=>{t.stopPropagation();let n=e.dataset.col;i.draft={id:i.draft?.id||null,col:n,op:i.draft?.op||`=`,val:i.draft?.val||``,step:`operator`},l.value=``,y(),l.focus(),w()}})},y=()=>{let e=``,t=!0;Ke.forEach(n=>{e+=`<div class="filter-category-title">${n.category}</div>`,n.operators.forEach(n=>{let r=i.draft?.op?i.draft.op===n.op:t;r&&(t=!1),e+=`
795
1188
  <div class="filter-popover-item ${r?`active`:``}" data-op="${n.op}" data-symbol="${n.symbol}" data-unary="${!!n.isUnary}">
796
1189
  <span>${n.label}</span>
797
1190
  <span class="filter-op-badge">${n.symbol}</span>
@@ -835,15 +1228,15 @@
835
1228
  </button>
836
1229
  </div>
837
1230
  </div>
838
- `;let a=document.getElementById(`filter-popover-val-input`),o=document.getElementById(`filter-popover-apply-btn`),s=document.getElementById(`filter-popover-cancel-btn`),c=document.getElementById(`filter-popover-back-op`);c&&(c.onclick=e=>{e.stopPropagation(),i.draft.step=`operator`,y(),l.focus(),w()}),s&&(s.onclick=e=>{e.stopPropagation(),E()});let u=()=>{let e=a.value.trim();x({...i.draft,val:e})};o&&(o.onclick=u),a&&(a.focus(),a.onkeydown=e=>{e.key===`Enter`?(e.preventDefault(),u()):e.key===`Escape`?(e.preventDefault(),E()):e.key===`Backspace`&&!a.value&&(e.preventDefault(),i.draft.step=`operator`,y(),l.focus(),w())})},x=e=>{if(e.id&&i.activeFilters.some(t=>t.id===e.id)){let t=i.activeFilters.findIndex(t=>t.id===e.id);i.activeFilters[t]={...i.activeFilters[t],...e}}else{let t={id:e.id||`filter-${Date.now()}-${Math.random().toString(36).slice(2,6)}`,type:e.type||`standard`,col:e.col,op:e.op,symbol:e.symbol||e.op,val:e.val};i.activeFilters.push(t)}i.draft=null,E(),m(),l.value=``,i.freeTextSearch=``,r()},S=null,C=(e,t)=>{if(!e)return 0;S||=document.createElement(`canvas`);let n=S.getContext(`2d`);return n?(n.font=t||`12px Inter, sans-serif`,n.measureText(e).width):e.length*7},w=()=>{if(!d||d.classList.contains(`hidden`))return;let e=document.getElementById(`filter-bar-container-${t}`);if(!e)return;let n=14;if(i.draft&&i.draft.id){let e=c.querySelector(`[data-filter-id="${i.draft.id}"]`);e&&(n=e.offsetLeft)}else if(l){let e=window.getComputedStyle(l),t=`${e.fontSize||`12px`} ${e.fontFamily||`Inter, sans-serif`}`,r=l.selectionStart??l.value.length,i=l.value.slice(0,r),a=C(i,t);n=l.offsetLeft+a}let r=e.clientWidth||600,a=d.offsetWidth||280,o=Math.max(14,r-a-16),s=Math.max(14,Math.min(n,o));d.style.left=`${s}px`},T=()=>{d.classList.remove(`hidden`),i.draft?i.draft.step===`column`?v(l.value):i.draft.step===`operator`?y():i.draft.step===`value`&&b():(i.draft={step:`column`},v(l.value)),requestAnimationFrame(w)},E=()=>{d.classList.add(`hidden`),i.draft=null,m()};l.addEventListener(`focus`,()=>{T()}),l.addEventListener(`input`,()=>{let e=l.value;i.freeTextSearch=e,p(),!d.classList.contains(`hidden`)&&(!i.draft||i.draft.step===`column`)&&v(e),w()}),l.addEventListener(`keyup`,()=>{w()}),l.addEventListener(`click`,()=>{w()}),l.addEventListener(`keydown`,e=>{let t=!d.classList.contains(`hidden`);if(t&&(e.key===`ArrowDown`||e.key===`ArrowUp`)){e.preventDefault();let t=Array.from(d.querySelectorAll(`.filter-popover-item`));if(t.length>0){let n=t.findIndex(e=>e.classList.contains(`active`));n=e.key===`ArrowDown`?n===-1?0:(n+1)%t.length:n===-1?t.length-1:(n-1+t.length)%t.length,t.forEach((e,t)=>{e.classList.toggle(`active`,t===n)}),t[n].scrollIntoView({block:`nearest`})}return}if(e.key===`Escape`){E(),l.blur();return}if(e.key===`Enter`){if(e.preventDefault(),t){let e=d.querySelector(`.filter-popover-item.active`)||d.querySelector(`.filter-popover-item`);if(e){e.click();return}}let n=l.value.trim(),i=g(n);if(i){x(i);return}let a=_(n);if(a&&a.type===`sql`){x({id:`sql-${Date.now()}`,type:`sql`,col:`SQL`,op:`RAW`,symbol:`SQL`,val:a.val});return}E(),r();return}if(e.key===`Backspace`&&!l.value){if(t&&i.draft&&i.draft.step===`operator`){e.preventDefault(),i.draft.step=`column`,v(``),l.focus(),w();return}i.activeFilters.length>0&&(i.activeFilters.pop(),m(),r(),w())}}),f.addEventListener(`click`,e=>{e.target.closest(`.filter-pill`)||e.target.closest(`.filter-bar-clear-btn`)||l.focus()}),u&&(u.onclick=e=>{e.stopPropagation(),Se(t),l.value=``,m(),E(),r()});let D=e=>{let n=document.getElementById(`filter-bar-container-${t}`);if(!n){document.removeEventListener(`click`,D);return}n.contains(e.target)||E()};document.addEventListener(`click`,D),m()}function Ee(e){let t=e||window.AppState?.currentTable;if(!t)return``;let n=we(t,window.TableStates?.[t]?.dataGrid?.schema||window.DataGrid?.schema||[]);if(n)return n;let r=e=>`"${(e||``).replace(/"/g,`""`)}"`,i=e=>(e||``).replace(/'/g,`''`),a=document.getElementById(`filter-val-${t}`)?.value.trim(),o=document.getElementById(`filter-op-${t}`)?.value,s=document.getElementById(`filter-col-${t}`)?.value;if(!s||!o)return``;if(o===`IS NULL`||o===`IS NOT NULL`)return`${r(s)} ${o}`;if(!a)return``;if(o===`IN`){let e=a;return e.startsWith(`(`)||(e=`(${e})`),`${r(s)} IN ${e}`}let c=!isNaN(Number(a))&&a.trim()!==``?a:`'${i(a)}'`;return`${r(s)} ${o} ${c}`}function De(e,t){if(e==null||e===`null`||e===``)return{html:`<em>NULL</em>`,title:``};let n=(t?.type||``).toUpperCase(),r=n===`DATE`,i=n.includes(`DATETIME`)||n.includes(`TIMESTAMP`),a=n.includes(`BOOL`)||n===`TINYINT(1)`,o=String(e).trim(),s=n.match(/(?:NUMERIC|DECIMAL|FLOAT|DOUBLE)\s*\(\s*\d+\s*,\s*(\d+)\s*\)/);if(s&&!isNaN(Number(o))&&!o.toLowerCase().includes(`e`)){let e=parseInt(s[1],10);if(e>0){let[t,n=``]=o.split(`.`);if(n.length<e){n=n.padEnd(e,`0`);let r=`${t}.${n}`;return{html:r,title:o===r?``:`Raw: ${o}`}}}}if(a){let e=o===`1`||o.toLowerCase()===`true`,t=o===`0`||o.toLowerCase()===`false`;if(e)return{html:`<span class="badge-bool bool-true">true</span>`,title:`Boolean: ${o}`};if(t)return{html:`<span class="badge-bool bool-false">false</span>`,title:`Boolean: ${o}`}}if((r||i)&&o){let e=null,t=!1;if(/^\d{13}$/.test(o)?(e=new Date(parseInt(o,10)),t=!0):/^\d{10}$/.test(o)?(e=new Date(parseInt(o,10)*1e3),t=!0):(o.includes(`T`)||o.includes(`Z`)||r&&o.length>10&&o.includes(` `))&&(e=new Date(o.includes(` `)&&!o.includes(`T`)?o.replace(` `,`T`):o)),e&&!isNaN(e.getTime())){let n=`${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,`0`)}-${String(e.getDate()).padStart(2,`0`)}`;if(i){let t=String(e.getHours()).padStart(2,`0`),r=String(e.getMinutes()).padStart(2,`0`),i=String(e.getSeconds()).padStart(2,`0`);n+=` ${t}:${r}:${i}`}return{html:n.replace(/</g,`&lt;`),title:t?`Raw Timestamp: ${o}`:o===n?``:`Raw: ${o}`}}}return{html:o.replace(/</g,`&lt;`),title:``}}function Oe(e,t,n,r,i=[]){let a=`<td class="row-header" data-row-idx="${t}">${t+1}</td>`,o=n?e[n]:t;return r.forEach((n,r)=>{let s=i.find(e=>e.name===n),c=e[n];typeof c==`object`&&c&&(c=c.type===`Buffer`&&Array.isArray(c.data)?`[BLOB ${c.data.length} B]`:JSON.stringify(c));let l=c==null?`null`:String(c),u=l.replace(/"/g,`&quot;`),{html:d,title:f}=De(l,s),p=f?` title="${f}"`:``;if(s&&s.fkTarget&&l!==`null`){let e=s.fkTarget.table,i=s.fkTarget.column;a+=`<td class="data-cell is-fk-cell" data-row-idx="${t}" data-col-idx="${r}" data-pk="${o}" data-col="${n}" data-original="${u}" data-fk-table="${e}" data-fk-col="${i}"${p}><span class="cell-text">${d}</span><button type="button" class="fk-jump-btn" title="View & jump to ${e} (${i} = ${u})" data-fk-table="${e}" data-fk-col="${i}" data-fk-val="${u}"><span class="material-symbols-outlined">open_in_new</span></button></td>`}else a+=`<td class="data-cell" data-row-idx="${t}" data-col-idx="${r}" data-pk="${o}" data-col="${n}" data-original="${u}"${p}><span class="cell-text">${d}</span></td>`}),a}async function ke(){if(!window.DataGrid)return;let{pendingEdits:e,pendingInserts:t,pendingDeletes:n,pkColumn:r,schema:i}=window.DataGrid,a=window.AppState.currentTable;if(!a||!r){alert(`Cannot save: No Primary Key detected for this table.`);return}let o=Object.keys(e||{}).length>0,s=t?.some(e=>Object.values(e).some(e=>e!==``&&e!=null)),c=n&&n.size>0;if(!o&&!s&&!c)return;let l=n?Array.from(n):[];try{let n=await d(a,{pkColumn:r,edits:e,inserts:t,deletes:l,schema:i||[]});if(n.success)window.DataGrid&&(window.DataGrid.pendingEdits={},window.DataGrid.pendingInserts=[{}],window.DataGrid.pendingDeletes=new Set,window.DataGrid.history=[],window.DataGrid.currentTransaction=null,window.DataGrid.refreshData?window.DataGrid.refreshData():window.renderCurrentView()),window.updateSidebarActiveTable?.(),window.loadTableStats?.(),window.showToast&&window.showToast(`Data saved successfully!`);else{let e=n.error||`Failed to save changes`;window.showToast?window.showToast(`Save failed: `+e,`error`):alert(`Save failed:
1231
+ `;let a=document.getElementById(`filter-popover-val-input`),o=document.getElementById(`filter-popover-apply-btn`),s=document.getElementById(`filter-popover-cancel-btn`),c=document.getElementById(`filter-popover-back-op`);c&&(c.onclick=e=>{e.stopPropagation(),i.draft.step=`operator`,y(),l.focus(),w()}),s&&(s.onclick=e=>{e.stopPropagation(),E()});let u=()=>{let e=a.value.trim();x({...i.draft,val:e})};o&&(o.onclick=u),a&&(a.focus(),a.onkeydown=e=>{e.key===`Enter`?(e.preventDefault(),u()):e.key===`Escape`?(e.preventDefault(),E()):e.key===`Backspace`&&!a.value&&(e.preventDefault(),i.draft.step=`operator`,y(),l.focus(),w())})},x=e=>{if(e.id&&i.activeFilters.some(t=>t.id===e.id)){let t=i.activeFilters.findIndex(t=>t.id===e.id);i.activeFilters[t]={...i.activeFilters[t],...e}}else{let t={id:e.id||`filter-${Date.now()}-${Math.random().toString(36).slice(2,6)}`,type:e.type||`standard`,col:e.col,op:e.op,symbol:e.symbol||e.op,val:e.val};i.activeFilters.push(t)}i.draft=null,E(),m(),l.value=``,i.freeTextSearch=``,r()},S=null,C=(e,t)=>{if(!e)return 0;S||=document.createElement(`canvas`);let n=S.getContext(`2d`);return n?(n.font=t||`12px Inter, sans-serif`,n.measureText(e).width):e.length*7},w=()=>{if(!d||d.classList.contains(`hidden`))return;let e=document.getElementById(`filter-bar-container-${t}`);if(!e)return;let n=14;if(i.draft&&i.draft.id){let e=c.querySelector(`[data-filter-id="${i.draft.id}"]`);e&&(n=e.offsetLeft)}else if(l){let e=window.getComputedStyle(l),t=`${e.fontSize||`12px`} ${e.fontFamily||`Inter, sans-serif`}`,r=l.selectionStart??l.value.length,i=l.value.slice(0,r),a=C(i,t);n=l.offsetLeft+a}let r=e.clientWidth||600,a=d.offsetWidth||280,o=Math.max(14,r-a-16),s=Math.max(14,Math.min(n,o));d.style.left=`${s}px`},T=()=>{d.classList.remove(`hidden`),i.draft?i.draft.step===`column`?v(l.value):i.draft.step===`operator`?y():i.draft.step===`value`&&b():(i.draft={step:`column`},v(l.value)),requestAnimationFrame(w)},E=()=>{d.classList.add(`hidden`),i.draft=null,m()};l.addEventListener(`focus`,()=>{T()}),l.addEventListener(`input`,()=>{let e=l.value;i.freeTextSearch=e,p(),!d.classList.contains(`hidden`)&&(!i.draft||i.draft.step===`column`)&&v(e),w()}),l.addEventListener(`keyup`,()=>{w()}),l.addEventListener(`click`,()=>{w()}),l.addEventListener(`keydown`,e=>{let t=!d.classList.contains(`hidden`);if(t&&(e.key===`ArrowDown`||e.key===`ArrowUp`)){e.preventDefault();let t=Array.from(d.querySelectorAll(`.filter-popover-item`));if(t.length>0){let n=t.findIndex(e=>e.classList.contains(`active`));n=e.key===`ArrowDown`?n===-1?0:(n+1)%t.length:n===-1?t.length-1:(n-1+t.length)%t.length,t.forEach((e,t)=>{e.classList.toggle(`active`,t===n)}),t[n].scrollIntoView({block:`nearest`})}return}if(e.key===`Escape`){E(),l.blur();return}if(e.key===`Enter`){if(e.preventDefault(),t){let e=d.querySelector(`.filter-popover-item.active`)||d.querySelector(`.filter-popover-item`);if(e){e.click();return}}let n=l.value.trim(),i=g(n);if(i){x(i);return}let a=_(n);if(a&&a.type===`sql`){x({id:`sql-${Date.now()}`,type:`sql`,col:`SQL`,op:`RAW`,symbol:`SQL`,val:a.val});return}E(),r();return}if(e.key===`Backspace`&&!l.value){if(t&&i.draft&&i.draft.step===`operator`){e.preventDefault(),i.draft.step=`column`,v(``),l.focus(),w();return}i.activeFilters.length>0&&(i.activeFilters.pop(),m(),r(),w())}}),f.addEventListener(`click`,e=>{e.target.closest(`.filter-pill`)||e.target.closest(`.filter-bar-clear-btn`)||l.focus()}),u&&(u.onclick=e=>{e.stopPropagation(),Ye(t),l.value=``,m(),E(),r()});let D=e=>{let n=document.getElementById(`filter-bar-container-${t}`);if(!n){document.removeEventListener(`click`,D);return}n.contains(e.target)||E()};document.addEventListener(`click`,D),m()}function $e(e){let t=e||window.AppState?.currentTable;if(!t)return``;let n=Ze(t,window.TableStates?.[t]?.dataGrid?.schema||window.DataGrid?.schema||[]);if(n)return n;let r=e=>`"${(e||``).replace(/"/g,`""`)}"`,i=e=>(e||``).replace(/'/g,`''`),a=document.getElementById(`filter-val-${t}`)?.value.trim(),o=document.getElementById(`filter-op-${t}`)?.value,s=document.getElementById(`filter-col-${t}`)?.value;if(!s||!o)return``;if(o===`IS NULL`||o===`IS NOT NULL`)return`${r(s)} ${o}`;if(!a)return``;if(o===`IN`){let e=a;return e.startsWith(`(`)||(e=`(${e})`),`${r(s)} IN ${e}`}let c=!isNaN(Number(a))&&a.trim()!==``?a:`'${i(a)}'`;return`${r(s)} ${o} ${c}`}function et(e,t){if(e==null||e===`null`||e===``)return{html:`<em>NULL</em>`,title:``};let n=(t?.type||``).toUpperCase(),r=n===`DATE`,i=n.includes(`DATETIME`)||n.includes(`TIMESTAMP`),a=n.includes(`BOOL`)||n===`TINYINT(1)`,o=String(e).trim(),s=n.match(/(?:NUMERIC|DECIMAL|FLOAT|DOUBLE)\s*\(\s*\d+\s*,\s*(\d+)\s*\)/);if(s&&!isNaN(Number(o))&&!o.toLowerCase().includes(`e`)){let e=parseInt(s[1],10);if(e>0){let[t,n=``]=o.split(`.`);if(n.length<e){n=n.padEnd(e,`0`);let r=`${t}.${n}`;return{html:r,title:o===r?``:`Raw: ${o}`}}}}if(a){let e=o===`1`||o.toLowerCase()===`true`,t=o===`0`||o.toLowerCase()===`false`;if(e)return{html:`<span class="badge-bool bool-true">true</span>`,title:`Boolean: ${o}`};if(t)return{html:`<span class="badge-bool bool-false">false</span>`,title:`Boolean: ${o}`}}if((r||i)&&o){let e=null,t=!1;if(/^\d{13}$/.test(o)?(e=new Date(parseInt(o,10)),t=!0):/^\d{10}$/.test(o)?(e=new Date(parseInt(o,10)*1e3),t=!0):(o.includes(`T`)||o.includes(`Z`)||r&&o.length>10&&o.includes(` `))&&(e=new Date(o.includes(` `)&&!o.includes(`T`)?o.replace(` `,`T`):o)),e&&!isNaN(e.getTime())){let n=`${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,`0`)}-${String(e.getDate()).padStart(2,`0`)}`;if(i){let t=String(e.getHours()).padStart(2,`0`),r=String(e.getMinutes()).padStart(2,`0`),i=String(e.getSeconds()).padStart(2,`0`);n+=` ${t}:${r}:${i}`}return{html:n.replace(/</g,`&lt;`),title:t?`Raw Timestamp: ${o}`:o===n?``:`Raw: ${o}`}}}return{html:o.replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`),title:``}}function tt(e,t,n,r,i=[]){let a=`<td class="row-header" data-row-idx="${t}"><span class="row-num">${t+1}</span><input type="checkbox" class="row-select-checkbox" data-row-idx="${t}" /></td>`,o=i.filter(e=>e.isPk).map(e=>e.name),s;if(o.length>1){let t={};for(let n of o)t[n]=e[n];s=JSON.stringify(t)}else s=n?e[n]:t;let c=String(s??t).replace(/"/g,`&quot;`);return r.forEach((n,r)=>{let o=i.find(e=>e.name===n),s=e[n];typeof s==`object`&&s&&(s=s.type===`Buffer`&&Array.isArray(s.data)?`[BLOB ${s.data.length} B]`:JSON.stringify(s));let l=s==null?`null`:String(s),u=l.replace(/"/g,`&quot;`),{html:d,title:f}=et(l,o),p=f?` title="${f}"`:``;if(o&&o.fkTarget&&l!==`null`){let e=o.fkTarget.table,i=o.fkTarget.column;a+=`<td class="data-cell is-fk-cell" data-row-idx="${t}" data-col-idx="${r}" data-pk="${c}" data-col="${n}" data-original="${u}" data-fk-table="${e}" data-fk-col="${i}"${p}><span class="cell-text">${d}</span><button type="button" class="fk-jump-btn" title="View & jump to ${e} (${i} = ${u})" data-fk-table="${e}" data-fk-col="${i}" data-fk-val="${u}"><span class="material-symbols-outlined">open_in_new</span></button></td>`}else a+=`<td class="data-cell" data-row-idx="${t}" data-col-idx="${r}" data-pk="${c}" data-col="${n}" data-original="${u}"${p}><span class="cell-text">${d}</span><button type="button" class="cell-drawer-trigger-btn" title="Inspect in Cell Drawer"><span class="material-symbols-outlined">open_in_full</span></button></td>`}),a}async function nt(){if(!window.DataGrid)return;let{pendingEdits:e,pendingInserts:t,pendingDeletes:n,pkColumn:r,pkColumns:i,schema:a}=window.DataGrid,o=window.AppState.currentTable,s=i&&i.length>0?i:r?[r]:[];if(!o||s.length===0){alert(`Cannot save: No Primary Key detected for this table.`);return}let c=Object.keys(e||{}).length>0,l=t?.some(e=>Object.values(e).some(e=>e!==``&&e!=null)),u=n&&n.size>0;if(!c&&!l&&!u)return;let d=n?Array.from(n):[];try{let n=await p(o,{pkColumn:s[0],pkColumns:s,edits:e,inserts:t,deletes:d,schema:a||[]});if(n.success)window.DataGrid&&(window.DataGrid.pendingEdits={},window.DataGrid.pendingInserts=[{}],window.DataGrid.pendingDeletes=new Set,window.DataGrid.history=[],window.DataGrid.currentTransaction=null,window.DataGrid.refreshData?window.DataGrid.refreshData():window.renderCurrentView()),window.updateSidebarActiveTable?.(),window.loadTableStats?.(),window.showToast&&window.showToast(`Data saved successfully!`);else{let e=n.error||`Failed to save changes`;window.showToast?window.showToast(`Save failed: `+e,`error`):alert(`Save failed:
839
1232
  `+e),document.querySelectorAll(`.cell-edited`).forEach(e=>{e.classList.remove(`cell-edited`),e.classList.add(`cell-error`)})}}catch(e){let t=e.message||`Network error`;window.showToast?window.showToast(`Save failed: `+t,`error`):alert(`Save failed:
840
- `+t),document.querySelectorAll(`.cell-edited`).forEach(e=>{e.classList.remove(`cell-edited`),e.classList.add(`cell-error`)})}window.updateSidebarDirtyState?.()}function Ae(e,t,n,r=!0){if(r&&window.DataGrid.currentTransaction){let n=e.textContent;(n===`null`||e.classList.contains(`ghost-row`))&&(n=``),n!==t&&window.DataGrid.currentTransaction.push({td:e,oldVal:n,newVal:t})}let i=e.dataset.col,a=e.dataset.colIdx===`0`?`<span class="ghost-cell-hint">+ Add Row</span>`:``,o=De(t,(window.DataGrid?.schema||[]).find(e=>e.name===i));if(e.innerHTML=t?`<span class="cell-text">${o.html}</span>`:e.dataset.insertIndex===void 0?`<em>NULL</em>`:a,o.title?e.title=o.title:e.removeAttribute(`title`),e.dataset.insertIndex!==void 0){let r=parseInt(e.dataset.insertIndex);if(window.DataGrid.pendingInserts[r]||(window.DataGrid.pendingInserts[r]={}),t){if(window.DataGrid.pendingInserts[r][i]=t,e.classList.add(`cell-edited`),e.classList.remove(`ghost-row`),r===window.DataGrid.pendingInserts.length-1){e.closest(`tr`).classList.remove(`ghost-row-tr`),window.DataGrid.pendingInserts.push({});let t=document.querySelector(`#data-grid-table-${window.AppState.currentTable} tbody`),i=document.createElement(`tr`);i.className=`ghost-row-tr`;let a=parseInt(e.dataset.rowIdx)+1;i.innerHTML+=`<td class="row-header" data-row-idx="${a}">*</td>`,n.forEach((e,t)=>{let n=t===0?`<span class="ghost-cell-hint">+ Add Row</span>`:``;i.innerHTML+=`<td class="data-cell ghost-row" data-row-idx="${a}" data-col-idx="${t}" data-insert-index="${r+1}" data-col="${e}">${n}</td>`}),t.appendChild(i)}}else window.DataGrid.pendingInserts[r]&&delete window.DataGrid.pendingInserts[r][i],e.classList.remove(`cell-edited`),e.classList.add(`ghost-row`)}else{let n=e.dataset.pk;t===e.dataset.original?(e.classList.remove(`cell-edited`),e.classList.remove(`cell-error`),window.DataGrid.pendingEdits[n]&&(delete window.DataGrid.pendingEdits[n][i],Object.keys(window.DataGrid.pendingEdits[n]).length===0&&delete window.DataGrid.pendingEdits[n])):(window.DataGrid.pendingEdits[n]||(window.DataGrid.pendingEdits[n]={}),window.DataGrid.pendingEdits[n][i]=t,e.classList.add(`cell-edited`),e.classList.remove(`cell-error`))}window.updateSidebarDirtyState?.()}function je(e,t=!0){let n=document.querySelector(`#data-grid-table-${window.AppState.currentTable} td.data-cell[data-row-idx="${e}"]`)?.closest(`tr`);if(!n||n.classList.contains(`ghost-row-tr`)||n.classList.contains(`row-deleted`))return;let r=n.querySelector(`td.data-cell`),i=r?.dataset.pk;if(i!==void 0)t&&window.DataGrid.currentTransaction&&window.DataGrid.currentTransaction.push({type:`delete`,rowIdx:e,pk:i}),window.DataGrid.pendingDeletes.add(i),n.classList.add(`row-deleted`);else if(r?.dataset.insertIndex!==void 0){let e=parseInt(r.dataset.insertIndex);window.DataGrid.pendingInserts[e]&&delete window.DataGrid.pendingInserts[e],n.remove()}window.updateSidebarDirtyState?.()}function Me(e,t){let n=document.querySelector(`#data-grid-table-${window.AppState.currentTable} td.data-cell[data-row-idx="${e}"]`)?.closest(`tr`);n&&n.classList.remove(`row-deleted`),window.DataGrid.pendingDeletes.delete(t),window.updateSidebarDirtyState?.()}function Ne(e,t){e.forEach(e=>{let n=window.AppState.currentTable,r=document.querySelector(`#data-grid-table-${n} td.data-cell[data-row-idx="${e}"]`)?.closest(`tr`);if(!r||r.classList.contains(`ghost-row-tr`))return;let i=document.querySelector(`#data-grid-table-${n} .ghost-row-tr`);i&&t.forEach((e,n)=>{let a=r.querySelector(`td.data-cell[data-col-idx="${n}"]`),o=i.querySelector(`td.data-cell[data-col-idx="${n}"]`);if(a&&o){let n=a.dataset.insertIndex===void 0?a.classList.contains(`cell-edited`)?window.DataGrid.pendingEdits[a.dataset.pk]?.[e]:a.dataset.original:window.DataGrid.pendingInserts[a.dataset.insertIndex][e];n!=null&&n!==`null`&&Ae(o,n,t,!0)}})})}var Pe=null;function Fe({td:e,colName:t,colType:n=``,initialValue:r=``,onSave:i,onCancel:a}){Pe&&Pe.close(!0);let o=document.createElement(`div`);o.className=`supabase-editor-backdrop hidden`;let s=document.createElement(`div`);s.className=`supabase-cell-editor-popover`;let c=document.createElement(`textarea`);c.className=`supabase-editor-textarea`,c.placeholder=`Enter value...`,c.value=r;let l=document.createElement(`div`);l.className=`supabase-editor-footer`;let u=document.createElement(`div`);u.className=`supabase-editor-footer-left`;let d=document.createElement(`button`);d.type=`button`,d.className=`supabase-editor-shortcut-btn btn-save`,d.title=`Save changes (Enter or Ctrl+Enter)`,d.innerHTML=`
1233
+ `+t),document.querySelectorAll(`.cell-edited`).forEach(e=>{e.classList.remove(`cell-edited`),e.classList.add(`cell-error`)})}window.updateSidebarDirtyState?.()}function rt(e,t,n,r=!0){if(r&&window.DataGrid.currentTransaction){let n=e.textContent;(n===`null`||e.classList.contains(`ghost-row`))&&(n=``),n!==t&&window.DataGrid.currentTransaction.push({td:e,oldVal:n,newVal:t})}let i=e.dataset.col,a=e.dataset.colIdx===`0`?`<span class="ghost-cell-hint">+ Add Row</span>`:``,o=(window.DataGrid?.schema||[]).find(e=>e.name===i),s=et(t,o),c=o&&o.fkTarget&&t,l=``;if(c){let e=o.fkTarget.table,n=o.fkTarget.column,r=String(t).replace(/"/g,`&quot;`);l=`<button type="button" class="fk-jump-btn" title="View & jump to ${e} (${n} = ${r})" data-fk-table="${e}" data-fk-col="${n}" data-fk-val="${r}"><span class="material-symbols-outlined">open_in_new</span></button>`}else(e.dataset.insertIndex===void 0||t)&&(l=`<button type="button" class="cell-drawer-trigger-btn" title="Inspect in Cell Drawer"><span class="material-symbols-outlined">open_in_full</span></button>`);if(e.innerHTML=t?`<span class="cell-text">${s.html}</span>${l}`:e.dataset.insertIndex===void 0?`<em>NULL</em>${l}`:a,s.title?e.title=s.title:e.removeAttribute(`title`),e.dataset.insertIndex!==void 0){let r=parseInt(e.dataset.insertIndex);if(window.DataGrid.pendingInserts[r]||(window.DataGrid.pendingInserts[r]={}),t){if(window.DataGrid.pendingInserts[r][i]=t,e.classList.add(`cell-edited`),e.classList.remove(`ghost-row`),r===window.DataGrid.pendingInserts.length-1){e.closest(`tr`).classList.remove(`ghost-row-tr`),window.DataGrid.pendingInserts.push({});let t=document.querySelector(`#data-grid-table-${window.AppState.currentTable} tbody`),i=document.createElement(`tr`);i.className=`ghost-row-tr`;let a=parseInt(e.dataset.rowIdx)+1;i.innerHTML+=`<td class="row-header" data-row-idx="${a}">*</td>`,n.forEach((e,t)=>{let n=t===0?`<span class="ghost-cell-hint">+ Add Row</span>`:``;i.innerHTML+=`<td class="data-cell ghost-row" data-row-idx="${a}" data-col-idx="${t}" data-insert-index="${r+1}" data-col="${e}">${n}</td>`}),t.appendChild(i)}}else window.DataGrid.pendingInserts[r]&&delete window.DataGrid.pendingInserts[r][i],e.classList.remove(`cell-edited`),e.classList.add(`ghost-row`)}else{let n=e.dataset.pk;t===e.dataset.original?(e.classList.remove(`cell-edited`),e.classList.remove(`cell-error`),window.DataGrid.pendingEdits[n]&&(delete window.DataGrid.pendingEdits[n][i],Object.keys(window.DataGrid.pendingEdits[n]).length===0&&delete window.DataGrid.pendingEdits[n])):(window.DataGrid.pendingEdits[n]||(window.DataGrid.pendingEdits[n]={}),window.DataGrid.pendingEdits[n][i]=t,e.classList.add(`cell-edited`),e.classList.remove(`cell-error`))}window.updateSidebarDirtyState?.()}function it(e,t=!0){let n=document.querySelector(`#data-grid-table-${window.AppState.currentTable} td.data-cell[data-row-idx="${e}"]`)?.closest(`tr`);if(!n||n.classList.contains(`ghost-row-tr`)||n.classList.contains(`row-deleted`))return;let r=n.querySelector(`td.data-cell`),i=r?.dataset.pk;if(i!==void 0)t&&window.DataGrid.currentTransaction&&window.DataGrid.currentTransaction.push({type:`delete`,rowIdx:e,pk:i}),window.DataGrid.pendingDeletes.add(i),n.classList.add(`row-deleted`);else if(r?.dataset.insertIndex!==void 0){let e=parseInt(r.dataset.insertIndex);window.DataGrid.pendingInserts[e]&&delete window.DataGrid.pendingInserts[e],n.remove()}window.updateSidebarDirtyState?.()}function at(e,t){let n=document.querySelector(`#data-grid-table-${window.AppState.currentTable} td.data-cell[data-row-idx="${e}"]`)?.closest(`tr`);n&&n.classList.remove(`row-deleted`),window.DataGrid.pendingDeletes.delete(t),window.updateSidebarDirtyState?.()}function ot(e,t){e.forEach(e=>{let n=window.AppState.currentTable,r=document.querySelector(`#data-grid-table-${n} td.data-cell[data-row-idx="${e}"]`)?.closest(`tr`);if(!r||r.classList.contains(`ghost-row-tr`))return;let i=document.querySelector(`#data-grid-table-${n} .ghost-row-tr`);i&&t.forEach((e,n)=>{let a=r.querySelector(`td.data-cell[data-col-idx="${n}"]`),o=i.querySelector(`td.data-cell[data-col-idx="${n}"]`);if(a&&o){let n=a.dataset.insertIndex===void 0?a.classList.contains(`cell-edited`)?window.DataGrid.pendingEdits[a.dataset.pk]?.[e]:a.dataset.original:window.DataGrid.pendingInserts[a.dataset.insertIndex][e];n!=null&&n!==`null`&&rt(o,n,t,!0)}})})}var st=null;function ct({td:e,colName:t,colType:n=``,initialValue:r=``,onSave:i,onCancel:a}){st&&st.close(!0);let o=document.createElement(`div`);o.className=`supabase-editor-backdrop hidden`;let s=document.createElement(`div`);s.className=`supabase-cell-editor-popover`;let c=document.createElement(`textarea`);c.className=`supabase-editor-textarea`,c.placeholder=`Enter value...`,c.value=r;let l=document.createElement(`div`);l.className=`supabase-editor-footer`;let u=document.createElement(`div`);u.className=`supabase-editor-footer-left`;let d=document.createElement(`button`);d.type=`button`,d.className=`supabase-editor-shortcut-btn btn-save`,d.title=`Save changes (Enter or Ctrl+Enter)`,d.innerHTML=`
841
1234
  <span class="supabase-kbd-badge">↵</span>
842
1235
  <span>Save changes</span>
843
1236
  `;let f=document.createElement(`button`);f.type=`button`,f.className=`supabase-editor-shortcut-btn btn-cancel`,f.title=`Cancel changes (Esc)`,f.innerHTML=`
844
1237
  <span class="supabase-kbd-badge">Esc</span>
845
1238
  <span>Cancel changes</span>
846
- `,u.appendChild(d),u.appendChild(f);let p=document.createElement(`div`);p.className=`supabase-editor-footer-right`;let m=document.createElement(`button`);m.type=`button`,m.className=`supabase-editor-expand-btn`,m.title=`Toggle Fullscreen Editor`,m.innerHTML=`<span class="material-symbols-outlined supabase-expand-icon">fullscreen</span>`,p.appendChild(m),l.appendChild(u),l.appendChild(p),s.appendChild(c),s.appendChild(l),document.body.appendChild(o),document.body.appendChild(s);let h=()=>{if(g)return;let t=e.getBoundingClientRect(),n=Math.max(t.width,360),r=t.top,i=t.left;r+240>window.innerHeight-12&&(r=Math.max(12,window.innerHeight-240-12)),i+n>window.innerWidth-12&&(i=Math.max(12,window.innerWidth-n-12)),s.style.top=`${r}px`,s.style.left=`${i}px`,s.style.width=`${n}px`,s.style.height=`240px`},g=!1,_=!1;h();let v=()=>{g=!g,g?(s.classList.add(`is-expanded`),o.classList.remove(`hidden`),m.innerHTML=`<span class="material-symbols-outlined supabase-expand-icon">fullscreen_exit</span>`,m.title=`Collapse Editor`):(s.classList.remove(`is-expanded`),o.classList.add(`hidden`),m.innerHTML=`<span class="material-symbols-outlined supabase-expand-icon">fullscreen</span>`,m.title=`Toggle Fullscreen Editor`,h()),c.focus()};m.onclick=e=>{e.stopPropagation(),v()},o.onclick=e=>{e.stopPropagation(),y(!0)};let y=(e=!1)=>{_||(_=!0,document.removeEventListener(`pointerdown`,b),window.removeEventListener(`resize`,h),s.remove(),o.remove(),Pe=null,e?i&&i(c.value):a&&a())},b=e=>{s.contains(e.target)||y(!0)};setTimeout(()=>{_||document.addEventListener(`pointerdown`,b)},80),window.addEventListener(`resize`,h),d.onclick=e=>{e.stopPropagation(),y(!0)},f.onclick=e=>{e.stopPropagation(),y(!1)},c.addEventListener(`keydown`,e=>{if(e.key===`Enter`&&!e.shiftKey)e.preventDefault(),y(!0);else if(e.key===`Enter`&&(e.ctrlKey||e.metaKey))e.preventDefault(),y(!0);else if(e.key===`Escape`)e.preventDefault(),y(!1);else if(e.key===`Tab`){e.preventDefault();let t=c.selectionStart,n=c.selectionEnd;c.value=c.value.substring(0,t)+` `+c.value.substring(n),c.selectionStart=c.selectionEnd=t+2}}),Pe={close:y},requestAnimationFrame(()=>{c.focus(),c.setSelectionRange(c.value.length,c.value.length)})}function Ie(e,t,n){e.addEventListener(`dblclick`,e=>{let r=e.target.closest(`td.data-cell`);if(!r||r.querySelector(`input, select`))return;let i=r.dataset.col,a=t.find(e=>e.name===i),o=a?.type?.toUpperCase()||``;if(o.includes(`BLOB`)||o===`BYTEA`||o.includes(`BINARY`)){window.showToast&&window.showToast(`Binary (BLOB) data cannot be edited directly.`,`info`);return}let c=o.includes(`ENUM`)||a?.enumValues&&a.enumValues.length>0,l=o===`DATE`,u=o.includes(`DATETIME`)||o.includes(`TIMESTAMP`),d=o.includes(`BOOL`)||o===`TINYINT(1)`,f=o===`TIME`||o.startsWith(`TIME(`),p=r.classList.contains(`ghost-row`)||r.dataset.insertIndex!==void 0&&!r.classList.contains(`cell-edited`),m=r.dataset.pk,h=r.dataset.insertIndex,g=h===void 0?m===void 0?void 0:window.DataGrid?.pendingEdits?.[m]?.[i]:window.DataGrid?.pendingInserts?.[parseInt(h,10)]?.[i],_=``;p||(_=g===void 0?r.dataset.original===void 0?r.querySelector(`.cell-text`)?.textContent.trim()||r.textContent.trim():r.dataset.original:String(g)),(_===`null`||_===`+ New`||_===`+ Add Row`)&&(_=``);let v;if(a&&a.fkTarget){let{table:e,column:t}=a.fkTarget;s(e,{limit:200}).then(i=>{if(i.success&&i.data&&i.data.rows){let o=t;if(i.data.columns){let e=[`name`,`title`,`label`,`description`,`username`,`email`],t=i.data.columns.find(t=>e.includes(t.toLowerCase()));t&&(o=t)}let s=[];a.nullable&&s.push({name:`-- None --`,value:``,desc:`Set to NULL`,icon:`block`}),i.data.rows.forEach(n=>{let r=String(n[t]),i=o!==t&&n[o]?String(n[o]):`Row in ${e}`;s.push({name:r,value:r,desc:i,icon:`link`})}),_&&!i.data.rows.find(e=>String(e[t])===_)&&s.unshift({name:_,value:_,desc:`Current value`,icon:`link`}),I({anchorEl:r,title:`REFERENCES ${e.toUpperCase()}.${t.toUpperCase()}`,placeholder:`Search ${e} by ${o}...`,items:s,initialValue:_,width:360,onSelect:e=>{window.DataGrid.currentTransaction=[],Ae(r,e,n),window.DataGrid.currentTransaction.length>0&&window.DataGrid.history.push(window.DataGrid.currentTransaction),window.DataGrid.currentTransaction=null}})}}).catch(e=>{window.showToast&&window.showToast(`Failed to load FK targets: `+e.message,`error`)});return}else if(c){let e=a?.enumValues||[];if(e.length===0&&a?.type){let t=a.type.match(/enum\((.*?)\)/i);t&&(e=t[1].split(`,`).map(e=>e.trim().replace(/^'|'$/g,``)))}let t=[];a?.nullable&&t.push({name:`-- None --`,value:``,desc:`Set to NULL`,icon:`block`}),e.forEach(e=>{t.push({name:e,value:e,desc:`Enum option`,icon:`label`})}),I({anchorEl:r,title:`ENUM VALUES`,placeholder:`Search enum values...`,items:t,initialValue:_,width:300,onSelect:e=>{window.DataGrid.currentTransaction=[],Ae(r,e,n),window.DataGrid.currentTransaction.length>0&&window.DataGrid.history.push(window.DataGrid.currentTransaction),window.DataGrid.currentTransaction=null}});return}else if(l){v=document.createElement(`input`),v.type=`date`;let e=``;if(_)if(/^\d{13}$/.test(_)){let t=new Date(parseInt(_,10));isNaN(t.getTime())||(e=`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,`0`)}-${String(t.getDate()).padStart(2,`0`)}`)}else if(/^\d{10}$/.test(_)){let t=new Date(parseInt(_,10)*1e3);isNaN(t.getTime())||(e=`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,`0`)}-${String(t.getDate()).padStart(2,`0`)}`)}else if(/^\d{4}-\d{2}-\d{2}/.test(_))e=_.slice(0,10);else{let t=new Date(_);isNaN(t.getTime())||(e=`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,`0`)}-${String(t.getDate()).padStart(2,`0`)}`)}v.value=e}else if(u){v=document.createElement(`input`),v.type=`datetime-local`;let e=``;if(_){let t=null;t=/^\d{13}$/.test(_)?new Date(parseInt(_,10)):/^\d{10}$/.test(_)?new Date(parseInt(_,10)*1e3):_.includes(`T`)||_.includes(` `)?new Date(_.replace(` `,`T`)):new Date(_),t&&!isNaN(t.getTime())&&(e=`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,`0`)}-${String(t.getDate()).padStart(2,`0`)}T${String(t.getHours()).padStart(2,`0`)}:${String(t.getMinutes()).padStart(2,`0`)}`)}v.value=e}else if(f)v=document.createElement(`input`),v.type=`time`,v.step=`1`,v.value=_?_.slice(0,8):``;else if(d){let e=!a||a.nullable!==!1,t=_===`1`||_.toLowerCase()===`true`,i=_===`0`||_.toLowerCase()===`false`,o=t?`1`:i?`0`:``,s=[{name:`true`,value:`1`,desc:`Logical True`,icon:`check_circle`,badge:`true`,badgeClass:`bool-true`},{name:`false`,value:`0`,desc:`Logical False`,icon:`cancel`,badge:`false`,badgeClass:`bool-false`}];e&&s.push({name:`null`,value:``,desc:`Empty / NULL value`,icon:`remove`,badge:`null`,badgeClass:`bool-null`}),I({anchorEl:r,title:`BOOLEAN VALUE`,placeholder:`Filter true / false / null...`,items:s,initialValue:o,width:280,onSelect:e=>{window.DataGrid.currentTransaction=[],Ae(r,e,n),window.DataGrid.currentTransaction.length>0&&window.DataGrid.history.push(window.DataGrid.currentTransaction),window.DataGrid.currentTransaction=null}});return}else{if(!c&&!l&&!u&&!f&&!d&&!(a&&a.fkTarget)&&(o===``||o.includes(`TEXT`)||o.includes(`VARCHAR`)||o.includes(`CHAR`)||o.includes(`JSON`)||o.includes(`CLOB`)||o.includes(`STRING`))){Fe({td:r,colName:i,colType:o,initialValue:_,onSave:e=>{window.DataGrid.currentTransaction=[],Ae(r,e,n),window.DataGrid.currentTransaction.length>0&&window.DataGrid.history.push(window.DataGrid.currentTransaction),window.DataGrid.currentTransaction=null}});return}v=document.createElement(`input`),v.type=`text`,v.value=_}let y=!1,b=()=>{y=!0,Fe({td:r,colName:i,colType:o,initialValue:v.value,onSave:e=>{v.value=e,y=!1,x()},onCancel:()=>{y=!1,v.focus()}})};if(r.innerHTML=``,r.classList.add(`cell-editing`),r.appendChild(v),o===``||!c&&!l&&!u&&!f&&!d&&!(a&&a.fkTarget)){let e=document.createElement(`span`);e.className=`material-symbols-outlined cell-expand-btn`,e.textContent=`open_in_full`,e.title=`Open Full Editor (Shift + Enter)`,e.onmousedown=e=>{e.preventDefault(),e.stopPropagation()},e.onclick=e=>{e.preventDefault(),e.stopPropagation(),b()},r.appendChild(e),v.style.paddingRight=`32px`,v.addEventListener(`keydown`,e=>{e.key===`Enter`&&e.shiftKey?(e.preventDefault(),b()):e.key===`Enter`&&v.blur(),e.key===`Tab`&&(e.preventDefault(),v.blur(),document.body.dispatchEvent(new KeyboardEvent(`keydown`,{key:`Tab`,shiftKey:e.shiftKey,bubbles:!0})))})}else v.addEventListener(`keydown`,e=>{if(e.key===`Enter`&&v.blur(),e.key===`Tab`){if(l||u||f)return;e.preventDefault(),v.blur(),document.body.dispatchEvent(new KeyboardEvent(`keydown`,{key:`Tab`,shiftKey:e.shiftKey,bubbles:!0}))}});v.focus();let x=()=>{if(r.classList.remove(`cell-editing`),y)return;let e=v.value,t=o.match(/(?:NUMERIC|DECIMAL|FLOAT|DOUBLE)\s*\(\s*\d+\s*,\s*(\d+)\s*\)/);if(t&&e&&!isNaN(Number(e))&&!e.toLowerCase().includes(`e`)){let n=parseInt(t[1],10);if(n>0){let[t,r=``]=e.split(`.`);r.length<n&&(r=r.padEnd(n,`0`),e=`${t}.${r}`)}}if(f&&e&&/^\d{2}:\d{2}$/.test(e)&&(e+=`:00`),l&&e){if(/^\d{13}$/.test(_)){let t=new Date(e);isNaN(t.getTime())||(e=String(t.getTime()))}else if(/^\d{10}$/.test(_)){let t=new Date(e);isNaN(t.getTime())||(e=String(Math.floor(t.getTime()/1e3)))}}else if(u&&e)if(/^\d{13}$/.test(_)){let t=new Date(e);isNaN(t.getTime())||(e=String(t.getTime()))}else if(/^\d{10}$/.test(_)){let t=new Date(e);isNaN(t.getTime())||(e=String(Math.floor(t.getTime()/1e3)))}else e=e.replace(`T`,` `),/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}$/.test(e)&&(e+=`:00`);window.DataGrid.currentTransaction=[],Ae(r,e,n),window.DataGrid.currentTransaction.length>0&&window.DataGrid.history.push(window.DataGrid.currentTransaction),window.DataGrid.currentTransaction=null};v.addEventListener(`blur`,()=>{setTimeout(()=>{!y&&document.activeElement!==v&&x()},120)})})}var z=null,Le=null,Re=null,ze=null;function Be(){return z||(z=document.createElement(`div`),z.id=`fk-preview-popover`,z.className=`fk-preview-popover hidden`,document.body.appendChild(z),z.addEventListener(`mouseenter`,()=>{Re&&=(clearTimeout(Re),null)}),z.addEventListener(`mouseleave`,e=>{e.relatedTarget&&ze&&ze.contains(e.relatedTarget)||Ve()}),document.addEventListener(`keydown`,e=>{e.key===`Escape`&&z&&!z.classList.contains(`hidden`)&&Ve()}),window.addEventListener(`scroll`,e=>{z&&!z.classList.contains(`hidden`)&&(z.contains(e.target)||Ve())},!0),z)}function Ve(){Le&&=(clearTimeout(Le),null),z&&z.classList.add(`hidden`),ze=null}function He(e,t,n,r){Ve(),window.fkNavHistory={fromTable:r,toTable:e,timestamp:Date.now()};let i=`"${t}" = ${/^-?\d+(\.\d+)?$/.test(n)?n:`'${n.replace(/'/g,`''`)}'`}`,a=document.querySelector(`.table-btn[data-table="${e}"]`)||Array.from(document.querySelectorAll(`.table-btn`)).find(t=>(t.dataset.table||t.querySelector(`span`)?.textContent.trim())===e);window.AppState.currentTable=e,window.AppState.currentTableBtnElement=a||null,window.AppState.currentTab=`data-btn`,document.querySelectorAll(`.table-btn`).forEach(e=>e.classList.remove(`active`)),a&&a.classList.add(`active`);let o=`view-data-btn-${e}`,s=document.getElementById(o);s&&(s.innerHTML=``),window.renderCurrentView(i),window.showToast&&window.showToast(`Jumped to ${e} (${i})`,`info`)}function Ue(e,t){let n=Be();e.addEventListener(`click`,e=>{let n=e.target.closest(`.fk-jump-btn`);if(!n)return;e.stopPropagation();let r=n.dataset.fkTable,i=n.dataset.fkCol,a=n.dataset.fkVal;r&&i&&a!==void 0&&He(r,i,a,t)}),e.addEventListener(`mouseover`,e=>{let r=e.target.closest(`.is-fk-cell`);r&&(Re&&=(clearTimeout(Re),null),ze!==r&&(ze=r,Le&&clearTimeout(Le),Le=setTimeout(async()=>{let e=r.dataset.fkTable,i=r.dataset.fkCol,a=r.dataset.original;if(!e||!i||a===void 0||a===`null`)return;n.innerHTML=`
1239
+ `,u.appendChild(d),u.appendChild(f);let p=document.createElement(`div`);p.className=`supabase-editor-footer-right`;let m=document.createElement(`button`);m.type=`button`,m.className=`supabase-editor-expand-btn`,m.title=`Toggle Fullscreen Editor`,m.innerHTML=`<span class="material-symbols-outlined supabase-expand-icon">fullscreen</span>`,p.appendChild(m),l.appendChild(u),l.appendChild(p),s.appendChild(c),s.appendChild(l),document.body.appendChild(o),document.body.appendChild(s);let h=()=>{if(g)return;let t=e.getBoundingClientRect(),n=Math.max(t.width,360),r=t.top,i=t.left;r+240>window.innerHeight-12&&(r=Math.max(12,window.innerHeight-240-12)),i+n>window.innerWidth-12&&(i=Math.max(12,window.innerWidth-n-12)),s.style.top=`${r}px`,s.style.left=`${i}px`,s.style.width=`${n}px`,s.style.height=`240px`},g=!1,_=!1;h();let v=()=>{g=!g,g?(s.classList.add(`is-expanded`),o.classList.remove(`hidden`),m.innerHTML=`<span class="material-symbols-outlined supabase-expand-icon">fullscreen_exit</span>`,m.title=`Collapse Editor`):(s.classList.remove(`is-expanded`),o.classList.add(`hidden`),m.innerHTML=`<span class="material-symbols-outlined supabase-expand-icon">fullscreen</span>`,m.title=`Toggle Fullscreen Editor`,h()),c.focus()};m.onclick=e=>{e.stopPropagation(),v()},o.onclick=e=>{e.stopPropagation(),y(!0)};let y=(e=!1)=>{_||(_=!0,document.removeEventListener(`pointerdown`,b),window.removeEventListener(`resize`,h),s.remove(),o.remove(),st=null,e?i&&i(c.value):a&&a())},b=e=>{s.contains(e.target)||y(!0)};setTimeout(()=>{_||document.addEventListener(`pointerdown`,b)},80),window.addEventListener(`resize`,h),d.onclick=e=>{e.stopPropagation(),y(!0)},f.onclick=e=>{e.stopPropagation(),y(!1)},c.addEventListener(`keydown`,e=>{if(e.key===`Enter`&&!e.shiftKey)e.preventDefault(),y(!0);else if(e.key===`Enter`&&(e.ctrlKey||e.metaKey))e.preventDefault(),y(!0);else if(e.key===`Escape`)e.preventDefault(),y(!1);else if(e.key===`Tab`){e.preventDefault();let t=c.selectionStart,n=c.selectionEnd;c.value=c.value.substring(0,t)+` `+c.value.substring(n),c.selectionStart=c.selectionEnd=t+2}}),st={close:y},requestAnimationFrame(()=>{c.focus(),c.setSelectionRange(c.value.length,c.value.length)})}function lt(e,t,n){e.addEventListener(`dblclick`,e=>{let r=e.target.closest(`td.data-cell`);if(!r||r.querySelector(`input, select`)||e.target.closest(`.cell-drawer-trigger-btn, .fk-jump-btn`))return;if(window.AppState?.isReadOnly){window.showToast?.(`Database is in Read-Only protection mode. Editing is disabled.`,`warning`);return}let i=r.dataset.col,a=t.find(e=>e.name===i),o=a?.type?.toUpperCase()||``;if(o.includes(`BLOB`)||o===`BYTEA`||o.includes(`BINARY`)){window.showToast&&window.showToast(`Binary (BLOB) data cannot be edited directly.`,`info`);return}let s=o.includes(`ENUM`)||a?.enumValues&&a.enumValues.length>0,c=o===`DATE`,u=o.includes(`DATETIME`)||o.includes(`TIMESTAMP`),d=o.includes(`BOOL`)||o===`TINYINT(1)`,f=o===`TIME`||o.startsWith(`TIME(`),p=r.classList.contains(`ghost-row`)||r.dataset.insertIndex!==void 0&&!r.classList.contains(`cell-edited`),m=r.dataset.pk,h=r.dataset.insertIndex,g=h===void 0?m===void 0?void 0:window.DataGrid?.pendingEdits?.[m]?.[i]:window.DataGrid?.pendingInserts?.[parseInt(h,10)]?.[i],_=``;p||(_=g===void 0?r.dataset.original===void 0?r.querySelector(`.cell-text`)?.textContent.trim()||r.textContent.trim():r.dataset.original:String(g)),(_===`null`||_===`+ New`||_===`+ Add Row`)&&(_=``);let v;if(a&&a.fkTarget){let{table:e,column:t}=a.fkTarget;l(e,{limit:200}).then(i=>{if(i.success&&i.data&&i.data.rows){let o=t;if(i.data.columns){let e=[`name`,`title`,`label`,`description`,`username`,`email`],t=i.data.columns.find(t=>e.includes(t.toLowerCase()));t&&(o=t)}let s=[];a.nullable&&s.push({name:`-- None --`,value:``,desc:`Set to NULL`,icon:`block`}),i.data.rows.forEach(n=>{let r=String(n[t]),i=o!==t&&n[o]?String(n[o]):`Row in ${e}`;s.push({name:r,value:r,desc:i,icon:`link`})}),_&&!i.data.rows.find(e=>String(e[t])===_)&&s.unshift({name:_,value:_,desc:`Current value`,icon:`link`}),H({anchorEl:r,title:`REFERENCES ${e.toUpperCase()}.${t.toUpperCase()}`,placeholder:`Search ${e} by ${o}...`,items:s,initialValue:_,width:360,onSelect:e=>{window.DataGrid.currentTransaction=[],rt(r,e,n),window.DataGrid.currentTransaction.length>0&&window.DataGrid.history.push(window.DataGrid.currentTransaction),window.DataGrid.currentTransaction=null}})}}).catch(e=>{window.showToast&&window.showToast(`Failed to load FK targets: `+e.message,`error`)});return}else if(s){let e=a?.enumValues||[];if(e.length===0&&a?.type){let t=a.type.match(/enum\((.*?)\)/i);t&&(e=t[1].split(`,`).map(e=>e.trim().replace(/^'|'$/g,``)))}let t=[];a?.nullable&&t.push({name:`-- None --`,value:``,desc:`Set to NULL`,icon:`block`}),e.forEach(e=>{t.push({name:e,value:e,desc:`Enum option`,icon:`label`})}),H({anchorEl:r,title:`ENUM VALUES`,placeholder:`Search enum values...`,items:t,initialValue:_,width:300,onSelect:e=>{window.DataGrid.currentTransaction=[],rt(r,e,n),window.DataGrid.currentTransaction.length>0&&window.DataGrid.history.push(window.DataGrid.currentTransaction),window.DataGrid.currentTransaction=null}});return}else if(c){v=document.createElement(`input`),v.type=`date`;let e=``;if(_)if(/^\d{13}$/.test(_)){let t=new Date(parseInt(_,10));isNaN(t.getTime())||(e=`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,`0`)}-${String(t.getDate()).padStart(2,`0`)}`)}else if(/^\d{10}$/.test(_)){let t=new Date(parseInt(_,10)*1e3);isNaN(t.getTime())||(e=`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,`0`)}-${String(t.getDate()).padStart(2,`0`)}`)}else if(/^\d{4}-\d{2}-\d{2}/.test(_))e=_.slice(0,10);else{let t=new Date(_);isNaN(t.getTime())||(e=`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,`0`)}-${String(t.getDate()).padStart(2,`0`)}`)}v.value=e}else if(u){v=document.createElement(`input`),v.type=`datetime-local`;let e=``;if(_){let t=null;t=/^\d{13}$/.test(_)?new Date(parseInt(_,10)):/^\d{10}$/.test(_)?new Date(parseInt(_,10)*1e3):_.includes(`T`)||_.includes(` `)?new Date(_.replace(` `,`T`)):new Date(_),t&&!isNaN(t.getTime())&&(e=`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,`0`)}-${String(t.getDate()).padStart(2,`0`)}T${String(t.getHours()).padStart(2,`0`)}:${String(t.getMinutes()).padStart(2,`0`)}`)}v.value=e}else if(f)v=document.createElement(`input`),v.type=`time`,v.step=`1`,v.value=_?_.slice(0,8):``;else if(d){let e=!a||a.nullable!==!1,t=_===`1`||_.toLowerCase()===`true`,i=_===`0`||_.toLowerCase()===`false`,o=t?`1`:i?`0`:``,s=[{name:`true`,value:`1`,desc:`Logical True`,icon:`check_circle`,badge:`true`,badgeClass:`bool-true`},{name:`false`,value:`0`,desc:`Logical False`,icon:`cancel`,badge:`false`,badgeClass:`bool-false`}];e&&s.push({name:`null`,value:``,desc:`Empty / NULL value`,icon:`remove`,badge:`null`,badgeClass:`bool-null`}),H({anchorEl:r,title:`BOOLEAN VALUE`,placeholder:`Filter true / false / null...`,items:s,initialValue:o,width:280,onSelect:e=>{window.DataGrid.currentTransaction=[],rt(r,e,n),window.DataGrid.currentTransaction.length>0&&window.DataGrid.history.push(window.DataGrid.currentTransaction),window.DataGrid.currentTransaction=null}});return}else{if(!s&&!c&&!u&&!f&&!d&&!(a&&a.fkTarget)&&(o===``||o.includes(`TEXT`)||o.includes(`VARCHAR`)||o.includes(`CHAR`)||o.includes(`JSON`)||o.includes(`CLOB`)||o.includes(`STRING`))){ct({td:r,colName:i,colType:o,initialValue:_,onSave:e=>{window.DataGrid.currentTransaction=[],rt(r,e,n),window.DataGrid.currentTransaction.length>0&&window.DataGrid.history.push(window.DataGrid.currentTransaction),window.DataGrid.currentTransaction=null}});return}v=document.createElement(`input`),v.type=`text`,v.value=_}let y=!1,b=()=>{y=!0,ct({td:r,colName:i,colType:o,initialValue:v.value,onSave:e=>{v.value=e,y=!1,x()},onCancel:()=>{y=!1,v.focus()}})};if(r.innerHTML=``,r.classList.add(`cell-editing`),r.appendChild(v),o===``||!s&&!c&&!u&&!f&&!d&&!(a&&a.fkTarget)){let e=document.createElement(`span`);e.className=`material-symbols-outlined cell-expand-btn`,e.textContent=`open_in_full`,e.title=`Open Full Editor (Shift + Enter)`,e.onmousedown=e=>{e.preventDefault(),e.stopPropagation()},e.onclick=e=>{e.preventDefault(),e.stopPropagation(),b()},r.appendChild(e),v.style.paddingRight=`32px`,v.addEventListener(`keydown`,e=>{e.key===`Enter`&&e.shiftKey?(e.preventDefault(),b()):e.key===`Enter`&&v.blur(),e.key===`Tab`&&(e.preventDefault(),v.blur(),document.body.dispatchEvent(new KeyboardEvent(`keydown`,{key:`Tab`,shiftKey:e.shiftKey,bubbles:!0})))})}else v.addEventListener(`keydown`,e=>{if(e.key===`Enter`&&v.blur(),e.key===`Tab`){if(c||u||f)return;e.preventDefault(),v.blur(),document.body.dispatchEvent(new KeyboardEvent(`keydown`,{key:`Tab`,shiftKey:e.shiftKey,bubbles:!0}))}});v.focus();let x=()=>{if(r.classList.remove(`cell-editing`),y)return;let e=v.value,t=o.match(/(?:NUMERIC|DECIMAL|FLOAT|DOUBLE)\s*\(\s*\d+\s*,\s*(\d+)\s*\)/);if(t&&e&&!isNaN(Number(e))&&!e.toLowerCase().includes(`e`)){let n=parseInt(t[1],10);if(n>0){let[t,r=``]=e.split(`.`);r.length<n&&(r=r.padEnd(n,`0`),e=`${t}.${r}`)}}if(f&&e&&/^\d{2}:\d{2}$/.test(e)&&(e+=`:00`),c&&e){if(/^\d{13}$/.test(_)){let t=new Date(e);isNaN(t.getTime())||(e=String(t.getTime()))}else if(/^\d{10}$/.test(_)){let t=new Date(e);isNaN(t.getTime())||(e=String(Math.floor(t.getTime()/1e3)))}}else if(u&&e)if(/^\d{13}$/.test(_)){let t=new Date(e);isNaN(t.getTime())||(e=String(t.getTime()))}else if(/^\d{10}$/.test(_)){let t=new Date(e);isNaN(t.getTime())||(e=String(Math.floor(t.getTime()/1e3)))}else e=e.replace(`T`,` `),/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}$/.test(e)&&(e+=`:00`);window.DataGrid.currentTransaction=[],rt(r,e,n),window.DataGrid.currentTransaction.length>0&&window.DataGrid.history.push(window.DataGrid.currentTransaction),window.DataGrid.currentTransaction=null};v.addEventListener(`blur`,()=>{setTimeout(()=>{!y&&document.activeElement!==v&&x()},120)})})}var W=null,ut=null,dt=null,ft=null;function pt(){return W||(W=document.createElement(`div`),W.id=`fk-preview-popover`,W.className=`fk-preview-popover hidden`,document.body.appendChild(W),W.addEventListener(`mouseenter`,()=>{dt&&=(clearTimeout(dt),null)}),W.addEventListener(`mouseleave`,e=>{e.relatedTarget&&ft&&ft.contains(e.relatedTarget)||mt()}),document.addEventListener(`keydown`,e=>{e.key===`Escape`&&W&&!W.classList.contains(`hidden`)&&mt()}),window.addEventListener(`scroll`,e=>{W&&!W.classList.contains(`hidden`)&&(W.contains(e.target)||mt())},!0),W)}function mt(){ut&&=(clearTimeout(ut),null),W&&W.classList.add(`hidden`),ft=null}function ht(e,t,n,r){mt(),window.fkNavHistory={fromTable:r,toTable:e,timestamp:Date.now()};let i=`"${t}" = ${/^-?\d+(\.\d+)?$/.test(n)?n:`'${n.replace(/'/g,`''`)}'`}`,a=document.querySelector(`.table-btn[data-table="${e}"]`)||Array.from(document.querySelectorAll(`.table-btn`)).find(t=>(t.dataset.table||t.querySelector(`span`)?.textContent.trim())===e);window.AppState.currentTable=e,window.AppState.currentTableBtnElement=a||null,window.AppState.currentTab=`data-btn`,document.querySelectorAll(`.table-btn`).forEach(e=>e.classList.remove(`active`)),a&&a.classList.add(`active`);let o=`view-data-btn-${e}`,s=document.getElementById(o);s&&(s.innerHTML=``),window.renderCurrentView(i),window.showToast&&window.showToast(`Jumped to ${e} (${i})`,`info`)}function gt(e,t){let n=pt();e.addEventListener(`click`,e=>{let n=e.target.closest(`.fk-jump-btn`);if(!n)return;e.stopPropagation();let r=n.dataset.fkTable,i=n.dataset.fkCol,a=n.dataset.fkVal;r&&i&&a!==void 0&&ht(r,i,a,t)}),e.addEventListener(`mouseover`,e=>{let r=e.target.closest(`.is-fk-cell`);r&&(dt&&=(clearTimeout(dt),null),ft!==r&&(ft=r,ut&&clearTimeout(ut),ut=setTimeout(async()=>{let e=r.dataset.fkTable,i=r.dataset.fkCol,a=r.dataset.original;if(!e||!i||a===void 0||a===`null`)return;n.innerHTML=`
847
1240
  <div class="fk-popover-header">
848
1241
  <div class="fk-popover-title">
849
1242
  <span class="material-symbols-outlined icon-16" style="color: var(--color-primary);">table_chart</span>
@@ -857,7 +1250,7 @@
857
1250
  <span>Loading relation...</span>
858
1251
  </div>
859
1252
  </div>
860
- `,We(r,n),n.classList.remove(`hidden`);let o=/^-?\d+(\.\d+)?$/.test(a)?a:`'${a.replace(/'/g,`''`)}'`;try{let c=await s(e,{where:`"${i}" = ${o}`,limit:1});if(ze!==r)return;if(c.success&&c.data&&c.data.rows&&c.data.rows.length>0){let o=c.data.rows[0],s=Object.keys(o).slice(0,7),l=``;s.forEach(e=>{let t=o[e];t=t==null?`null`:typeof t==`object`?JSON.stringify(t):String(t),l+=`
1253
+ `,_t(r,n),n.classList.remove(`hidden`);let o=/^-?\d+(\.\d+)?$/.test(a)?a:`'${a.replace(/'/g,`''`)}'`;try{let s=await l(e,{where:`"${i}" = ${o}`,limit:1});if(ft!==r)return;if(s.success&&s.data&&s.data.rows&&s.data.rows.length>0){let o=s.data.rows[0],c=Object.keys(o).slice(0,7),l=``;c.forEach(e=>{let t=o[e];t=t==null?`null`:typeof t==`object`?JSON.stringify(t):String(t),l+=`
861
1254
  <div class="fk-field-row">
862
1255
  <span class="fk-field-name">${e}</span>
863
1256
  <span class="fk-field-value ${t===`null`?`is-null`:``}" title="${t.replace(/"/g,`&quot;`)}">${t}</span>
@@ -881,318 +1274,241 @@
881
1274
  <span class="material-symbols-outlined icon-14">touch_app</span>
882
1275
  <span>Click to inspect full record</span>
883
1276
  </div>
884
- `,n.querySelector(`#btn-fk-popover-jump`)?.addEventListener(`click`,n=>{n.stopPropagation(),He(e,i,a,t)}),n.onclick=()=>{He(e,i,a,t)},We(r,n)}else n.innerHTML=`
1277
+ `,n.querySelector(`#btn-fk-popover-jump`)?.addEventListener(`click`,n=>{n.stopPropagation(),ht(e,i,a,t)}),n.onclick=()=>{ht(e,i,a,t)},_t(r,n)}else n.innerHTML=`
885
1278
  <div class="fk-popover-header">
886
1279
  <div class="fk-popover-title">
887
- <span class="material-symbols-outlined icon-16" style="color: var(--color-primary);">table_chart</span>
888
- <span class="fk-popover-table">${e}</span>
889
- </div>
890
- </div>
891
- <div class="fk-popover-body">
892
- <div class="fk-popover-empty">
893
- <span class="material-symbols-outlined icon-18">error_outline</span>
894
- <span>No matching row found for ${i} = ${a}</span>
895
- </div>
896
- </div>
897
- `,We(r,n)}catch(e){if(ze!==r)return;n.innerHTML=`
898
- <div class="fk-popover-body">
899
- <div class="fk-popover-empty">
900
- <span>Failed to fetch preview: ${e.message}</span>
901
- </div>
902
- </div>
903
- `,We(r,n)}},250)))}),e.addEventListener(`mouseout`,e=>{let t=e.target.closest(`.is-fk-cell`);t&&(e.relatedTarget&&(t.contains(e.relatedTarget)||n&&n.contains(e.relatedTarget))||(Le&&=(clearTimeout(Le),null),Re=setTimeout(()=>{Ve()},350)))})}function We(e,t){let n=e.getBoundingClientRect(),r=t.getBoundingClientRect(),i=n.bottom+2,a=n.left;i+r.height>window.innerHeight-10&&(i=Math.max(10,n.top-r.height-2)),a+r.width>window.innerWidth-10&&(a=Math.max(10,window.innerWidth-r.width-10)),t.style.top=`${i}px`,t.style.left=`${a}px`}async function Ge(e,t,n=``,r=!1,i=null){if(window.updateSidebarActiveTable)window.updateSidebarActiveTable(e);else{document.querySelectorAll(`.table-btn`).forEach(e=>e.classList.remove(`active`));let n=t||document.querySelector(`.table-btn[data-table="${e}"]`);n&&(n.classList.add(`active`),window.AppState&&(window.AppState.currentTableBtnElement=n))}let a=document.getElementById(`table-name`);a&&(a.textContent=e);let o=i||document.getElementById(`main-content`);r||(o.innerHTML=`<div class='p-6'>Loading...</div>`);try{let i=await c(e);if(!i.success)throw Error(i.error);let a=i.data,l=a.find(e=>e.isPk)?.name;(!r||!window.DataGrid)&&(window.DataGrid={schema:a,pkColumn:l,pendingEdits:{},pendingInserts:[{}],pendingDeletes:new Set,selectedCell:null,history:[],currentTransaction:null,sortState:{col:l||a[0].name,asc:!0},pagination:{limit:50,offset:0,isLoading:!1,hasMore:!0},selection:{isDragging:!1,isDraggingRow:!1,startRow:-1,startCol:-1,endRow:-1,endCol:-1}}),window.TableStates&&window.TableStates[e]&&(window.TableStates[e].dataGrid=window.DataGrid);let u=await s(e,{where:n,limit:window.DataGrid.pagination.limit,offset:window.DataGrid.pagination.offset,orderCol:window.DataGrid.sortState.col,orderAsc:window.DataGrid.sortState.asc});if(u.success&&u.data){window.loadTableStats?.();let i=u.data.rows,c=u.data.columns;if(window.DataGrid.rows=i,window.DataGrid.columns=c,window.DataGrid.pagination.hasMore=i.length===window.DataGrid.pagination.limit,!r){o.innerHTML=`
904
- <div class="toolbar">
905
- ${window.fkNavHistory&&window.fkNavHistory.toTable===e?`<button type="button" id="btn-fk-back-${e}" class="fk-back-btn" title="Back to table '${window.fkNavHistory.fromTable}'">
906
- <span class="material-symbols-outlined icon-14">arrow_back</span>
907
- <span>Back to ${window.fkNavHistory.fromTable}</span>
908
- </button>`:``}
909
- <div id="filter-bar-mount-${e}" class="flex-1" style="height: 100%; display: flex; align-items: center; min-width: 0;"></div>
910
- <button id="btn-refresh-data-${e}" class="refresh-btn" title="Refresh Data (F5)">
911
- <span class="material-symbols-outlined">refresh</span>
912
- </button>
913
- </div>
914
- <div class="table-container" id="data-grid-container-${e}"></div>
915
- `;let n=document.getElementById(`filter-bar-mount-${e}`);n&&Te({container:n,tableName:e,schema:a,onFilterChange:()=>{window.DataGrid&&(window.DataGrid.pagination.offset=0),Ge(e,t,Ee(e),!0)}})}let d=document.getElementById(`data-grid-container-${e}`);if(!d)return;if((!i||i.length===0)&&!window.forceEmptyGrid)if(n){d.innerHTML=`
916
- <div class="table-empty-container">
917
- <div class="table-empty-card">
918
- <div class="table-empty-icon-wrap">
919
- <span class="material-symbols-outlined table-empty-icon">search_off</span>
920
- </div>
921
- <h3 class="table-empty-title">No matching records found</h3>
922
- <p class="table-empty-desc">No records in "${e}" matched the current filter conditions.</p>
923
- <div class="table-empty-actions">
924
- <button type="button" class="table-empty-btn-primary" id="btn-empty-clear-filter-${e}">
925
- <span class="material-symbols-outlined icon-16">filter_alt_off</span>
926
- <span>Clear Filter</span>
927
- </button>
928
- </div>
929
- </div>
930
- </div>
931
- `;let n=document.getElementById(`btn-empty-clear-filter-${e}`);n&&(n.onclick=()=>{Se(e),Ge(e,t,``,!1)})}else{d.innerHTML=`
932
- <div class="table-empty-container">
933
- <div class="table-empty-card">
934
- <div class="table-empty-icon-wrap">
935
- <span class="material-symbols-outlined table-empty-icon">dataset</span>
936
- </div>
937
- <h3 class="table-empty-title">Table "${e}" is empty</h3>
938
- <p class="table-empty-desc">This table currently contains 0 records. You can insert a new row manually or generate realistic mock data with one click.</p>
939
- <div class="table-empty-actions">
940
- <button type="button" class="table-empty-btn-secondary" id="btn-empty-add-row-${e}">
941
- <span class="material-symbols-outlined icon-16">add</span>
942
- <span>Insert Row</span>
943
- </button>
944
- <button type="button" class="table-empty-btn-primary" id="btn-empty-mock-${e}">
945
- <span class="material-symbols-outlined icon-16">auto_fix_high</span>
946
- <span>Generate Mock Data</span>
947
- </button>
948
- </div>
949
- </div>
950
- </div>
951
- `;let n=document.getElementById(`btn-empty-mock-${e}`);n&&(n.onclick=()=>{M(e,a,()=>{window.forceEmptyGrid=!1,Ge(e,t,``,!0)})});let r=document.getElementById(`btn-empty-add-row-${e}`);r&&(r.onclick=()=>{window.forceEmptyGrid=!0,Ge(e,t,``,!0)})}else{let n=`<table class="data-table" id="data-grid-table-${e}"><thead><tr>`;n+=`<th class="row-header table-corner-header" id="th-row-header-${e}" title="Click to select all, right-click for table actions">#</th>`,c.forEach(e=>{let t=a.find(t=>t.name===e),r=``,i=t?.type||``;if(t){let e=!!t.isPk,n=!!t.fkTarget;e?r=`<span class="material-symbols-outlined col-pk-key-icon" title="Primary Key">key</span>`:(n||t.name.toLowerCase().includes(`id`))&&(r=`<span class="material-symbols-outlined col-fk-icon" title="Foreign Key">link</span>`)}let o=window.DataGrid.sortState.col===e;n+=`<th class="sortable ${o?`sorted`:``}" data-col="${e}" title="Click for column options">
952
- <div class="th-content-wrapper">
953
- <div class="th-main-group">
954
- ${r}
955
- <span class="th-col-name">${e}</span>
956
- ${i?`<span class="th-col-type">${i.toLowerCase()}</span>`:``}
957
- </div>
958
- <div class="th-actions-group">
959
- <button type="button" class="th-menu-trigger ${o?`is-sorted`:``}" title="Column actions">
960
- <span class="material-symbols-outlined th-chevron-icon">keyboard_arrow_down</span>
961
- </button>
962
- </div>
963
- </div>
964
- </th>`}),n+=`</tr></thead><tbody>`,i&&i.length>0&&i.forEach((e,t)=>{n+=`<tr>${Oe(e,t,l,c,a)}</tr>`}),n+=`<tr class="ghost-row-tr">`;let r=i?i.length:0;n+=`<td class="row-header" data-row-idx="${r}">*</td>`,c.forEach((e,t)=>{n+=`<td class="data-cell ghost-row" data-row-idx="${r}" data-col-idx="${t}" data-insert-index="0" data-col="${e}">${t===0?`<span class="ghost-cell-hint">+ Add Row</span>`:``}</td>`}),n+=`</tr></tbody></table>`,d.innerHTML=n,d.querySelectorAll(`th.sortable`).forEach(n=>{let r=n.dataset.col,i=e,o=e=>{if(window.DataGrid&&window.DataGrid.isResizing||e.target.closest(`.resizer`))return;let o=window.TableStates?.[i]?.dataGrid||window.DataGrid,s=o?.sortState?.col===r,c=s&&o?.sortState?.asc,l=()=>Object.keys(window.DataGrid.pendingEdits||{}).length>0||(window.DataGrid.pendingInserts||[]).length>1||window.DataGrid.pendingDeletes&&window.DataGrid.pendingDeletes.size>0?(window.showToast?window.showToast(`You have unsaved changes. Please save changes before sorting.`,`warning`):alert(`You have unsaved changes. Please save changes before sorting.`),!1):!0,u=e=>{l()&&(o&&(o.sortState.col=r,o.sortState.asc=e,o.pagination.offset=0),Ge(i,t,Ee(i),!0),window.showToast&&window.showToast(`Sorted by ${r} (${e?`Ascending`:`Descending`})`,`info`))},d=()=>{l()&&(o&&(o.sortState.col=null,o.sortState.asc=!0,o.pagination.offset=0),Ge(i,t,Ee(i),!0),window.showToast&&window.showToast(`Cleared sort on "${r}"`,`info`))},p=[{icon:`arrow_upward`,label:`Sort Ascending`,checked:s&&c,action:()=>u(!0)},{icon:`arrow_downward`,label:`Sort Descending`,checked:s&&!c,action:()=>u(!1)}];s&&p.push({icon:`restart_alt`,label:`Clear Sort`,action:()=>d()}),p.push(`divider`,{icon:`content_copy`,label:`Copy name`,action:async()=>{try{await navigator.clipboard.writeText(r)}catch{let e=document.createElement(`textarea`);e.value=r,document.body.appendChild(e),e.select(),document.execCommand(`copy`),e.remove()}window.showToast&&window.showToast(`Copied "${r}" to clipboard!`,`success`)}},{icon:`edit`,label:`Edit column`,action:()=>{typeof window.handleSwitchTab==`function`&&(window.handleSwitchTab(`schema-btn`),window.showToast&&window.showToast(`Switched to Schema Editor for "${r}"`,`info`))}},{icon:`filter_alt`,label:`Filter by this column`,action:()=>{let e=document.getElementById(`filter-bar-input-${i}`);e&&(e.focus(),e.value=`${r} = `,e.dispatchEvent(new Event(`input`,{bubbles:!0})))}},`divider`,{icon:`delete`,label:`Delete column`,danger:!0,action:async()=>{if(confirm(`Are you sure you want to delete column "${r}" from table "${i}"?\nThis action cannot be undone!`))try{let e=await f(i,{pendingDeletes:[r],columns:a});e.success?(window.showToast&&window.showToast(`Deleted column "${r}"`,`success`),Ge(i,t,``,!0)):alert(`Failed to delete column: ${e.error}`)}catch(e){alert(`Error deleting column: ${e.message}`)}}});let m=n.querySelector(`.th-menu-trigger`),h=m?m.getBoundingClientRect():n.getBoundingClientRect();A({clientX:h.left,clientY:h.bottom+4,preventDefault:()=>{},stopPropagation:()=>{}},p)};n.onclick=o,n.oncontextmenu=e=>{e.preventDefault(),o(e)},ve(n,window.DataGrid)}),_e(d,`data-grid-table-${e}`,window.DataGrid,c.length),Ie(d,a,c),Ue(d,e);let o=document.getElementById(`th-row-header-${e}`);o&&(o.addEventListener(`click`,t=>{t.preventDefault(),t.stopPropagation(),ge(`data-grid-table-${e}`,window.DataGrid,c.length)}),o.addEventListener(`contextmenu`,n=>{n.preventDefault&&n.preventDefault(),n.stopPropagation&&n.stopPropagation();let r=Ee(e),i=window.DataGrid?.sortState,o=!!r,s=t=>{let n=`/api/tables/${encodeURIComponent(e)}/export?format=${t}`;return r&&(n+=`&where=${encodeURIComponent(r)}`),i&&i.col&&(n+=`&orderCol=${encodeURIComponent(i.col)}&orderAsc=${i.asc}`),n};A(n,[{icon:`select_all`,label:`Select All Cells`,shortcut:`Ctrl+A`,action:()=>{ge(`data-grid-table-${e}`,window.DataGrid,c.length)}},`divider`,{icon:`auto_fix_high`,label:`Generate Mock Data...`,action:()=>{M(e,a,()=>{Ge(e,t,Ee(e),!0)})}},{icon:`content_copy`,label:`Copy Table Name`,action:async()=>{try{await navigator.clipboard.writeText(e)}catch{let t=document.createElement(`textarea`);t.value=e,document.body.appendChild(t),t.select(),document.execCommand(`copy`),t.remove()}window.showToast&&window.showToast(`Copied "${e}"`,`success`)}},{type:`divider`},{icon:`download`,label:o?`Export as CSV (Filtered)`:`Export as CSV`,action:()=>{window.open(s(`csv`),`_blank`)}},{icon:`download`,label:o?`Export as JSON (Filtered)`:`Export as JSON`,action:()=>{window.open(s(`json`),`_blank`)}},{type:`divider`},{icon:`mop`,label:`Truncate Table (Clear Rows)`,danger:!0,action:async()=>{if(confirm(`Are you sure you want to delete ALL rows from table "${e}"? This cannot be undone!`)){let n=await p(e);n.success?(window.showToast&&window.showToast(`Cleared all rows from "${e}"`,`info`),Ge(e,t,``,!0)):alert(`Failed to clear table: ${n.error}`)}}}])}))}let m=document.getElementById(`btn-fk-back-${e}`);if(m&&(m.onclick=()=>{let e=window.fkNavHistory?.fromTable;if(window.fkNavHistory=null,e){let t=document.querySelector(`.table-btn[data-table="${e}"]`)||Array.from(document.querySelectorAll(`.table-btn`)).find(t=>t.textContent.includes(e));window.AppState.currentTable=e,window.AppState.currentTableBtnElement=t||null,document.querySelectorAll(`.table-btn`).forEach(e=>e.classList.remove(`active`)),t&&t.classList.add(`active`);let n=`view-data-btn-${e}`,r=document.getElementById(n);r&&(r.innerHTML=``),window.renderCurrentView()}}),!r){let n=()=>{(Object.keys(window.DataGrid.pendingEdits).length>0||window.DataGrid.pendingInserts.length>1||window.DataGrid.pendingDeletes.size>0)&&!confirm(`You have unsaved changes. Are you sure you want to refresh and discard them?`)||(window.DataGrid.pendingEdits={},window.DataGrid.pendingInserts=[{}],window.DataGrid.pendingDeletes=new Set,window.DataGrid.history=[],window.DataGrid.currentTransaction=null,window.updateSidebarDirtyState?.(),window.DataGrid&&(window.DataGrid.pagination.offset=0),Ge(e,t,Ee(e),!0))},r=document.getElementById(`btn-refresh-data-${e}`);r&&(r.onclick=n),window.DataGrid.refreshData=n;let i=async()=>{if(window.DataGrid.pagination.isLoading||!window.DataGrid.pagination.hasMore)return;window.DataGrid.pagination.isLoading=!0,window.DataGrid.pagination.offset+=window.DataGrid.pagination.limit;let t={where:Ee(e),limit:window.DataGrid.pagination.limit,offset:window.DataGrid.pagination.offset,orderCol:window.DataGrid.sortState.col,orderAsc:window.DataGrid.sortState.asc};try{let n=await s(e,t);if(window.DataGrid.pagination.isLoading=!1,n.success&&n.data){let t=n.data.rows;window.DataGrid.pagination.hasMore=t.length===window.DataGrid.pagination.limit;let r=document.querySelector(`#data-grid-table-${e} tbody`);if(!r)return;let i=r.querySelector(`td[data-insert-index]`)?.closest(`tr`),o=window.DataGrid.pagination.offset;t.forEach((e,t)=>{let n=document.createElement(`tr`);n.innerHTML=Oe(e,o+t,l,c,a),i?r.insertBefore(n,i):r.appendChild(n)});let s=o+t.length,u=r.querySelectorAll(`td[data-insert-index]`),d=new Set;u.forEach(e=>{let t=e.closest(`tr`);if(d.has(t))return;d.add(t);let n=t.querySelector(`.row-header`);n&&(n.dataset.rowIdx=s),t.querySelectorAll(`td.data-cell`).forEach(e=>e.dataset.rowIdx=s),s++})}}catch{window.DataGrid.pagination.isLoading=!1}};setTimeout(()=>{let t=document.getElementById(`data-grid-container-${e}`);t&&t.addEventListener(`scroll`,e=>{let{scrollTop:t,scrollHeight:n,clientHeight:r}=e.target;t+r>=n-50&&i()})},50)}}else o.innerHTML=`<div class="p-6 text-error">Error: ${u.error}</div>`}catch(e){o.innerHTML=`<div class="p-6 text-error">Failed to load data: ${e.message}</div>`}}async function Ke(){if(!window.SchemaGrid)return;let{pendingEdits:e,pendingInserts:t,pendingDeletes:n,pendingIndexEdits:r,schema:i}=window.SchemaGrid,a=window.AppState.currentTable;if(!a)return;let o=n&&n.size>0||Object.keys(e||{}).length>0||t&&t.some(e=>e.name&&e.name.trim()!==``),s=r&&(r.added.length>0||r.dropped.length>0);if(!o&&!s)return;let c=n?Array.from(n):[];try{let n=await f(a,{pendingEdits:e,pendingInserts:t,pendingDeletes:c,pendingIndexEdits:r,columns:i});if(n.success){window.SchemaGrid&&(window.SchemaGrid.pendingEdits={},window.SchemaGrid.pendingInserts=[{}],window.SchemaGrid.pendingDeletes=new Set,window.SchemaGrid.pendingIndexEdits={added:[],dropped:[]},window.SchemaGrid.history=[],window.SchemaGrid.currentTransaction=null),window.TableStates?.[a]&&(window.TableStates[a].dataGrid=null);let e=document.getElementById(`btn-refresh-schema-${a}`);e?e.click():window.renderCurrentView(),window.updateSidebarDirtyState?.(),window.loadTableStats?.(),window.showToast&&window.showToast(`Schema saved successfully!`,`success`)}else{let e=n.error||`Failed to apply schema changes`;window.showToast?window.showToast(`Migration failed: ${e}`,`error`):alert(`Migration failed: ${e}`)}}catch(e){let t=e.message||`Network error`;window.showToast?window.showToast(`Migration failed: ${t}`,`error`):alert(`Migration failed: ${t}`)}}function qe(e,t,n,r=!0){if(r&&window.SchemaGrid.currentTransaction){let n=e.textContent;(n===`null`||e.classList.contains(`ghost-row`))&&(n=``),n!==t&&window.SchemaGrid.currentTransaction.push({td:e,oldVal:n,newVal:t})}let i=e.dataset.colKey,a=e.dataset.colIdx===`0`?`<span class="ghost-cell-hint">+ Add Column</span>`:``,o=t;if(i===`isPk`&&t){let e=t.includes(`PK`)||t.includes(`PFK`),n=t.match(/(?:FK|PFK)(?:\s*\(|:\s*|\s*→\s*|\s*->\s*)([a-zA-Z0-9_]+)\.([a-zA-Z0-9_]+)(?:\s*\((CASCADE|SET NULL|RESTRICT|NO ACTION)\))?/i),r=n&&n[3]&&n[3].toUpperCase()!==`NO ACTION`?` (${n[3].toUpperCase()})`:``;e&&n?o=`<span class="col-badge badge-pfk" title="Primary Foreign Key (Composite Key referencing ${n[1]}.${n[2]}${r?` [ON DELETE ${n[3]}]`:``})">PFK &rarr; ${n[1]}.${n[2]}${r}</span>`:e?o=`<span class="col-badge badge-pk">PK</span>`:n&&(o=`<span class="col-badge badge-fk" title="References ${n[1]}.${n[2]}${r?` [ON DELETE ${n[3]}]`:``}">FK &rarr; ${n[1]}.${n[2]}${r}</span>`)}else i===`nullable`&&t?o=t===`Yes`||t===`1`?`<span class="badge-bool bool-true">Yes</span>`:`<span class="badge-bool bool-false">No</span>`:i===`isUnique`&&t&&(o=t===`Yes`||t===`1`?`<span class="badge-unique">Yes</span>`:`<span class="text-soft">-</span>`);if(e.innerHTML=o||(e.dataset.insertIndex===void 0?`<span class="text-soft">-</span>`:a),e.dataset.insertIndex!==void 0){let r=parseInt(e.dataset.insertIndex);if(window.SchemaGrid.pendingInserts[r]||(window.SchemaGrid.pendingInserts[r]={}),t){if(window.SchemaGrid.pendingInserts[r][i]=t,e.classList.add(`cell-edited`),e.classList.remove(`ghost-row`),r===window.SchemaGrid.pendingInserts.length-1){e.closest(`tr`).classList.remove(`ghost-row-tr`),window.SchemaGrid.pendingInserts.push({});let t=document.querySelector(`#schema-grid-table-${window.AppState.currentTable} tbody`),i=document.createElement(`tr`);i.className=`ghost-row-tr`;let a=parseInt(e.dataset.rowIdx)+1;i.innerHTML+=`<td class="row-header" data-row-idx="${a}">*</td>`,n.forEach((e,t)=>{if(e===`indexing`)return;let n=t===0?`<span class="ghost-cell-hint">+ Add Column</span>`:``;i.innerHTML+=`<td class="data-cell ghost-row" data-row-idx="${a}" data-col-idx="${t}" data-insert-index="${r+1}" data-col-key="${e}">${n}</td>`}),t.appendChild(i);let o=document.querySelector(`#schema-grid-table-${window.AppState.currentTable} .manage-indexes-cell`);if(o){let e=parseInt(o.getAttribute(`rowspan`)||`1`,10);o.setAttribute(`rowspan`,String(e+1))}}}else window.SchemaGrid.pendingInserts[r]&&delete window.SchemaGrid.pendingInserts[r][i],e.classList.remove(`cell-edited`),e.classList.add(`ghost-row`)}else{let n=e.dataset.pk,r=e.dataset.original;r===`-`&&(r=``),t===r?(e.classList.remove(`cell-edited`),e.classList.remove(`cell-error`),window.SchemaGrid.pendingEdits[n]&&(delete window.SchemaGrid.pendingEdits[n][i],Object.keys(window.SchemaGrid.pendingEdits[n]).length===0&&delete window.SchemaGrid.pendingEdits[n])):(window.SchemaGrid.pendingEdits[n]||(window.SchemaGrid.pendingEdits[n]={}),window.SchemaGrid.pendingEdits[n][i]=t,e.classList.add(`cell-edited`),e.classList.remove(`cell-error`))}window.updateSidebarDirtyState?.()}function Je(e,t=!0){let n=document.querySelector(`#schema-grid-table-${window.AppState.currentTable} td.data-cell[data-row-idx="${e}"]`)?.closest(`tr`);if(!n||n.classList.contains(`ghost-row-tr`)||n.classList.contains(`row-deleted`))return;let r=n.querySelector(`td.data-cell`)?.dataset.pk;r!==void 0&&(t&&window.SchemaGrid.currentTransaction&&window.SchemaGrid.currentTransaction.push({type:`delete`,rowIdx:e,pk:r}),window.SchemaGrid.pendingDeletes.add(r),n.classList.add(`row-deleted`)),window.updateSidebarDirtyState?.()}function Ye(e,t){let n=document.querySelector(`#schema-grid-table-${window.AppState.currentTable} td.data-cell[data-row-idx="${e}"]`)?.closest(`tr`);n&&n.classList.remove(`row-deleted`),window.SchemaGrid.pendingDeletes.delete(t),window.updateSidebarDirtyState?.()}function Xe(e,t){e.forEach(e=>{let n=window.AppState.currentTable,r=document.querySelector(`#schema-grid-table-${n} td.data-cell[data-row-idx="${e}"]`)?.closest(`tr`);if(!r||r.classList.contains(`ghost-row-tr`))return;let i=document.querySelector(`#schema-grid-table-${n} .ghost-row-tr`);i&&t.forEach((e,n)=>{let a=r.querySelector(`td.data-cell[data-col-idx="${n}"]`),o=i.querySelector(`td.data-cell[data-col-idx="${n}"]`);if(a&&o){let n=a.dataset.insertIndex===void 0?a.classList.contains(`cell-edited`)?window.SchemaGrid.pendingEdits[a.dataset.pk]?.[e]:a.dataset.original:window.SchemaGrid.pendingInserts[a.dataset.insertIndex][e];n!=null&&n!==`null`&&(e===`name`&&(n+=`_copy`),qe(o,n,t,!0))}})})}function Ze(){let e=window.SchemaGrid;if(!e)return;let t=document.getElementById(`index-modal`);t&&t.remove();let n=[...e.indexes],r=[...e.pendingIndexEdits.added],i=new Set(e.pendingIndexEdits.dropped),a=n.filter(e=>!i.has(e.name)).concat(r),o=e.schema.map(e=>e.name);e.pendingInserts.forEach(e=>{e.name&&e.name.trim()!==``&&o.push(e.name.trim())});let s=[];t=document.createElement(`div`),t.id=`index-modal`,t.className=`modal-overlay`,t.innerHTML=`
965
- <div class="modal-container idx-modal-container">
966
- <div class="modal-header">
967
- <div class="flex items-center gap-2">
968
- <span class="material-symbols-outlined text-primary" style="font-size:20px;">key</span>
969
- <h3 class="m-0 text-15 font-semibold">Manage Indexes</h3>
970
- </div>
971
- <button id="close-idx-modal" class="modal-close-btn" title="Close"><span class="material-symbols-outlined">close</span></button>
972
- </div>
973
-
974
- <div class="modal-body-scroll" style="max-height: 220px; padding: 16px;">
975
- <div class="idx-section-title">Current Indexes</div>
976
- <div id="idx-list-container"></div>
977
- </div>
978
-
979
- <div class="modal-section-bg" style="padding: 16px 20px;">
980
- <div class="idx-section-title" style="margin-bottom: 24px;">+ Create New Index</div>
981
- <div class="flex flex-col gap-3">
982
- <div>
983
- <label class="text-11 text-secondary block mb-1.5">Index Name</label>
984
- <input type="text" id="new-idx-name" placeholder="Optional (auto-generated if empty)" class="modal-input w-full" style="padding: 8px 12px; font-size: 13px;" />
985
- </div>
986
-
987
- <div>
988
- <div class="flex items-center justify-between mb-1">
989
- <label class="text-11 text-secondary">Columns (click to select in order)</label>
990
- <button type="button" id="btn-clear-selected-cols" class="idx-clear-btn hidden" title="Clear column selection">
991
- <span class="material-symbols-outlined" style="font-size:12px; line-height:1;">close</span>
992
- <span>Clear selection</span>
993
- </button>
994
- </div>
995
- <div id="idx-chips-container" class="idx-chips-container"></div>
996
- </div>
997
-
998
- <div class="flex items-center justify-between pt-1">
999
- <label class="flex items-center gap-2 cursor-pointer select-none text-13">
1000
- <input type="checkbox" id="new-idx-unique" style="accent-color: var(--color-primary);" />
1001
- <span>Unique Index</span>
1002
- </label>
1003
- <button type="button" id="add-idx-btn" class="btn-add-idx">
1004
- <span class="material-symbols-outlined">add</span>
1005
- <span>Add to List</span>
1006
- </button>
1007
- </div>
1008
- </div>
1009
- </div>
1010
-
1011
- <div class="modal-footer">
1012
- <button id="cancel-idx-btn" class="btn-secondary">Cancel</button>
1013
- <button id="save-idx-btn" class="btn-primary">Save Changes</button>
1014
- </div>
1015
- </div>
1016
- `,document.body.appendChild(t);let c=()=>t.remove();document.getElementById(`close-idx-modal`).onclick=c,document.getElementById(`cancel-idx-btn`).onclick=c;let l=()=>{let e=document.getElementById(`idx-chips-container`),t=document.getElementById(`btn-clear-selected-cols`);e&&(t&&(s.length>0?(t.classList.remove(`hidden`),t.onclick=()=>{s=[],l()}):t.classList.add(`hidden`)),e.innerHTML=o.map(e=>{let t=s.indexOf(e),n=t!==-1,r=n?`<span class="idx-chip-badge">${t+1}</span>`:``;return`
1017
- <div class="idx-chip ${n?`selected`:``}" data-col="${e}">
1018
- ${r}
1019
- <span>${e}</span>
1020
- </div>
1021
- `}).join(``),e.querySelectorAll(`.idx-chip`).forEach(e=>{e.onclick=()=>{let t=e.dataset.col,n=s.indexOf(t);n===-1?s.push(t):s.splice(n,1),l()}}))};l();let u=()=>{let e=document.getElementById(`idx-list-container`);if(e){if(a.length===0){e.innerHTML=`
1022
- <div style="display:flex; flex-direction:column; align-items:center; justify-content:center; padding: 24px 0; color: var(--color-text-soft);">
1023
- <span class="material-symbols-outlined" style="font-size:32px; opacity:0.4; margin-bottom:6px;">dataset</span>
1024
- <div style="font-size:12px;">No indexes defined for this table yet.</div>
1025
- </div>
1026
- `;return}e.innerHTML=a.map((e,t)=>`
1027
- <div class="idx-card">
1028
- <div class="idx-card-info">
1029
- <div class="idx-card-header">
1030
- <span class="idx-name">${e.name||`unnamed_idx`}</span>
1031
- ${e.isUnique?`<span class="badge-unique" style="font-size:10px; padding:1px 6px; line-height:14px;">UNIQUE</span>`:``}
1032
- </div>
1033
- <div class="idx-cols-tags">
1034
- ${e.columns.map(e=>`<span class="idx-col-pill">${e}</span>`).join(``)}
1035
- </div>
1036
- </div>
1037
- <button type="button" class="idx-del-btn delete-idx-btn" data-idx="${t}" title="Remove index">
1038
- <span class="material-symbols-outlined">delete</span>
1039
- </button>
1040
- </div>
1041
- `).join(``),e.querySelectorAll(`.delete-idx-btn`).forEach(e=>{e.onclick=e=>{let t=parseInt(e.currentTarget.dataset.idx,10);a.splice(t,1),u()}})}};u(),document.getElementById(`add-idx-btn`).onclick=()=>{if(s.length===0){window.showToast?window.showToast(`Please select at least one column for the index.`,`warning`):alert(`Please select at least one column for the index.`);return}let e=window.AppState?.currentTable||`table`,t=document.getElementById(`new-idx-name`).value.trim()||`idx_${e}_${s.join(`_`)}`,n=document.getElementById(`new-idx-unique`).checked;a.push({name:t,columns:[...s],isUnique:n}),document.getElementById(`new-idx-name`).value=``,document.getElementById(`new-idx-unique`).checked=!1,s=[],l(),u()},document.getElementById(`save-idx-btn`).onclick=()=>{let t=[],r=new Set;n.forEach(e=>{a.find(t=>t.name===e.name&&JSON.stringify(t.columns)===JSON.stringify(e.columns))||r.add(e.name)}),a.forEach(e=>{n.find(t=>t.name===e.name&&JSON.stringify(t.columns)===JSON.stringify(e.columns))||t.push(e)}),e.pendingIndexEdits.added=t,e.pendingIndexEdits.dropped=Array.from(r),window.updateSidebarDirtyState?.(),window.renderSchemaGrid(),c()}}async function Qe(e,t){if(!window.SchemaGrid)return;let n=document.getElementById(`pkfk-modal`);n&&n.remove();let r=e.dataset.insertIndex!==void 0,i=r?parseInt(e.dataset.insertIndex,10):null,a=e.dataset.pk||e.parentElement?.querySelector(`[data-col-key="name"]`)?.textContent?.trim()||``,o=``;o=r&&i!==null&&window.SchemaGrid?.pendingInserts?.[i]?window.SchemaGrid.pendingInserts[i].isPk||``:a&&window.SchemaGrid?.pendingEdits?.[a]?.isPk!==void 0?window.SchemaGrid.pendingEdits[a].isPk||``:t||e.textContent?.trim()||e.dataset.original||``;let s=o.includes(`PK`)||o.includes(`PFK`),c=!1,l=``,u=``,d=`NO ACTION`,f=`NO ACTION`,p=(window.SchemaGrid?.schema||[]).find(e=>e.name===a);p?.fkTarget&&(l=p.fkTarget.table||``,u=p.fkTarget.column||``,p.fkTarget.onDelete&&(d=p.fkTarget.onDelete),p.fkTarget.onUpdate&&(f=p.fkTarget.onUpdate),c=!0);let m=r&&i!==null?window.SchemaGrid?.pendingInserts?.[i]?.fkTarget:a?window.SchemaGrid?.pendingEdits?.[a]?.fkTarget:void 0;m&&(m.table&&(l=m.table),m.column&&(u=m.column),m.onDelete&&(d=m.onDelete),m.onUpdate&&(f=m.onUpdate),c=!0);let h=o.match(/(?:FK|PFK)(?:\s*\(|:\s*|\s*→\s*|\s*->\s*)([a-zA-Z0-9_]+)\.([a-zA-Z0-9_]+)(?:\s*\((CASCADE|SET NULL|RESTRICT|NO ACTION)\))?/i);h?(l=h[1],u=h[2],h[3]&&(d=h[3].toUpperCase()),c=!0):(o.includes(`FK`)||o.includes(`PFK`))&&(c=!0),n=document.createElement(`div`),n.id=`pkfk-modal`,n.className=`modal-overlay`,n.innerHTML=`
1042
- <div class="keys-modal-container">
1043
- <div class="modal-header">
1044
- <div class="flex items-center gap-2">
1045
- <span class="material-symbols-outlined text-primary" style="font-size:20px;">vpn_key</span>
1046
- <h3 class="m-0 text-15 font-semibold">Manage Keys</h3>
1047
- ${a?`<span class="keys-col-badge">${a}</span>`:``}
1048
- </div>
1049
- <button id="close-pkfk-modal" class="modal-close-btn" title="Close"><span class="material-symbols-outlined">close</span></button>
1050
- </div>
1051
-
1052
- <div class="key-cards-list">
1053
- <!-- Primary Key Card -->
1054
- <div class="key-card ${s?`active`:``}" id="pk-card">
1055
- <div class="key-card-header" id="pk-card-toggle">
1056
- <div class="key-card-icon pk">
1057
- <span class="material-symbols-outlined">key</span>
1058
- </div>
1059
- <div class="key-card-content">
1060
- <div class="key-card-title">Primary Key (PK)</div>
1061
- <div class="key-card-desc">Uniquely identifies each record in this table</div>
1062
- </div>
1063
- <label class="key-switch" id="pk-switch-label">
1064
- <input type="checkbox" id="modal-is-pk" ${s?`checked`:``} />
1065
- <span class="key-slider"></span>
1066
- </label>
1067
- </div>
1068
- </div>
1069
-
1070
- <!-- Foreign Key Card -->
1071
- <div class="key-card ${c?`active`:``}" id="fk-card">
1072
- <div class="key-card-header" id="fk-card-toggle">
1073
- <div class="key-card-icon fk">
1074
- <span class="material-symbols-outlined">link</span>
1075
- </div>
1076
- <div class="key-card-content">
1077
- <div class="key-card-title">Foreign Key (FK)</div>
1078
- <div class="key-card-desc">Reference a column in another table</div>
1079
- </div>
1080
- <label class="key-switch" id="fk-switch-label">
1081
- <input type="checkbox" id="modal-is-fk" ${c?`checked`:``} />
1082
- <span class="key-slider"></span>
1083
- </label>
1084
- </div>
1085
-
1086
- <!-- FK Configuration Drawer -->
1087
- <div id="fk-settings-container" class="key-fk-drawer ${c?`open`:``}">
1088
- <div class="key-field-group">
1089
- <label class="key-field-label">Target Table</label>
1090
- <button type="button" id="modal-fk-table" class="key-select" style="display: flex; justify-content: space-between; align-items: center; width: 100%; height: 32px; cursor: pointer; text-align: left; padding: 0 10px;">
1091
- <span id="modal-fk-table-display" style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">${l||`Select a table...`}</span>
1092
- <span class="material-symbols-outlined key-select-arrow" style="font-size: 16px;">expand_more</span>
1093
- </button>
1094
- </div>
1095
-
1096
- <div class="key-field-group">
1097
- <label class="key-field-label">Target Column</label>
1098
- <button type="button" id="modal-fk-col" class="key-select" ${l?``:`disabled`} style="display: flex; justify-content: space-between; align-items: center; width: 100%; height: 32px; cursor: pointer; text-align: left; padding: 0 10px;">
1099
- <span id="modal-fk-col-display" style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">${u||(l?`Select column...`:`Select a table first`)}</span>
1100
- <span class="material-symbols-outlined key-select-arrow" style="font-size: 16px;">expand_more</span>
1101
- </button>
1102
- </div>
1103
-
1104
- <div class="key-field-group" style="display: grid; grid-template-columns: 1fr 1fr; gap: 10px;">
1105
- <div>
1106
- <label class="key-field-label">On Delete</label>
1107
- <button type="button" id="modal-fk-ondelete" class="key-select" style="display: flex; justify-content: space-between; align-items: center; width: 100%; height: 32px; cursor: pointer; text-align: left; padding: 0 10px;">
1108
- <span id="modal-fk-ondelete-display">${d||`NO ACTION`}</span>
1109
- <span class="material-symbols-outlined key-select-arrow" style="font-size: 16px;">expand_more</span>
1110
- </button>
1111
- </div>
1112
- <div>
1113
- <label class="key-field-label">On Update</label>
1114
- <button type="button" id="modal-fk-onupdate" class="key-select" style="display: flex; justify-content: space-between; align-items: center; width: 100%; height: 32px; cursor: pointer; text-align: left; padding: 0 10px;">
1115
- <span id="modal-fk-onupdate-display">${f||`NO ACTION`}</span>
1116
- <span class="material-symbols-outlined key-select-arrow" style="font-size: 16px;">expand_more</span>
1117
- </button>
1280
+ <span class="material-symbols-outlined icon-16" style="color: var(--color-primary);">table_chart</span>
1281
+ <span class="fk-popover-table">${e}</span>
1282
+ </div>
1283
+ </div>
1284
+ <div class="fk-popover-body">
1285
+ <div class="fk-popover-empty">
1286
+ <span class="material-symbols-outlined icon-18">error_outline</span>
1287
+ <span>No matching row found for ${i} = ${a}</span>
1118
1288
  </div>
1119
1289
  </div>
1290
+ `,_t(r,n)}catch(e){if(ft!==r)return;n.innerHTML=`
1291
+ <div class="fk-popover-body">
1292
+ <div class="fk-popover-empty">
1293
+ <span>Failed to fetch preview: ${e.message}</span>
1294
+ </div>
1120
1295
  </div>
1121
- </div>
1122
- </div>
1123
-
1124
- <div class="modal-footer">
1125
- <button id="cancel-pkfk-btn" class="btn-secondary">Cancel</button>
1126
- <button id="save-pkfk-btn" class="btn-primary flex items-center gap-1.5">
1127
- <span class="material-symbols-outlined" style="font-size:16px;">check</span>
1128
- <span>Save Changes</span>
1296
+ `,_t(r,n)}},250)))}),e.addEventListener(`mouseout`,e=>{let t=e.target.closest(`.is-fk-cell`);t&&(e.relatedTarget&&(t.contains(e.relatedTarget)||n&&n.contains(e.relatedTarget))||(ut&&=(clearTimeout(ut),null),dt=setTimeout(()=>{mt()},350)))})}function _t(e,t){let n=e.getBoundingClientRect(),r=t.getBoundingClientRect(),i=n.bottom+2,a=n.left;i+r.height>window.innerHeight-10&&(i=Math.max(10,n.top-r.height-2)),a+r.width>window.innerWidth-10&&(a=Math.max(10,window.innerWidth-r.width-10)),t.style.top=`${i}px`,t.style.left=`${a}px`}var vt=`drixio_col_vis_`;function yt(e){try{let t=localStorage.getItem(vt+e);if(!t)return new Set;let n=JSON.parse(t);return new Set(Array.isArray(n)?n:[])}catch{return new Set}}function bt(e,t){try{let n=Array.from(t);localStorage.setItem(vt+e,JSON.stringify(n))}catch{}}function xt(e,t){let n=document.getElementById(`data-grid-table-${e}`);n&&(n.querySelectorAll(`th[data-col]`).forEach(e=>{let n=e.dataset.col;e.style.display=t.has(n)?`none`:``}),n.querySelectorAll(`td[data-col]`).forEach(e=>{let n=e.dataset.col;e.style.display=t.has(n)?`none`:``}))}function St({container:e,tableName:t,schema:n,onChanged:r}){if(!e)return;let i=yt(t),a=n.length;e.innerHTML=`
1297
+ <div class="col-visibility-wrap relative" style="position: relative;">
1298
+ <button type="button" id="btn-col-visibility-${t}" class="col-visibility-btn" title="Toggle column visibility">
1299
+ <span class="material-symbols-outlined" style="font-size: 15px; color: var(--color-primary);">view_column</span>
1300
+ <span>Columns</span>
1301
+ <span class="col-vis-badge" id="col-vis-badge-${t}">${a-i.size}/${a}</span>
1129
1302
  </button>
1130
- </div>
1131
- </div>
1132
- `,document.body.appendChild(n);let g=e=>{e.key===`Escape`&&_()};document.addEventListener(`keydown`,g);let _=()=>{document.removeEventListener(`keydown`,g),n.remove()};document.getElementById(`close-pkfk-modal`).onclick=_,document.getElementById(`cancel-pkfk-btn`).onclick=_,n.addEventListener(`click`,e=>{e.target===n&&_()});let v=document.getElementById(`pk-card`),y=document.getElementById(`modal-is-pk`),b=document.getElementById(`fk-card`),x=document.getElementById(`modal-is-fk`),S=document.getElementById(`fk-settings-container`),C=document.getElementById(`modal-fk-table`),w=document.getElementById(`modal-fk-col`);document.getElementById(`pk-card-toggle`).addEventListener(`click`,e=>{e.target.closest(`.key-switch`)||(y.checked=!y.checked,y.dispatchEvent(new Event(`change`)))}),y.addEventListener(`change`,()=>{v.classList.toggle(`active`,y.checked)}),document.getElementById(`fk-card-toggle`).addEventListener(`click`,e=>{e.target.closest(`.key-switch`)||(x.checked=!x.checked,x.dispatchEvent(new Event(`change`)))});let T=[],E=l||``,D=u||``,O=d||`NO ACTION`,k=f||`NO ACTION`,A=[];x.addEventListener(`change`,()=>{let e=x.checked;if(e&&T.length===0){x.checked=!1,b.classList.remove(`active`),S.classList.remove(`open`),window.showToast?window.showToast(`No other tables available in the database to link as a foreign key.`,`warning`):alert(`No other tables available in the database to link as a foreign key.`);return}if(b.classList.toggle(`active`,e),e){if(S.classList.add(`open`),!E&&T.length>0){let e=T[0];E=e;let t=document.getElementById(`modal-fk-table-display`);t&&(t.textContent=e),j(e)}}else S.classList.remove(`open`)});try{let e=await(await fetch(`/api/tables`)).json();if(e.success&&e.data){let t=window.AppState?.currentTable;T=e.data.filter(e=>e!==t),E&&T.includes(E)&&j(E,D)}}catch{}async function j(e,t=``){w.disabled=!0;let n=document.getElementById(`modal-fk-col-display`);n&&(n.textContent=`Loading columns...`);try{let r=await(await fetch(`/api/tables/${e}/schema`)).json();if(r.success&&r.data){let i=e===window.AppState?.currentTable?r.data.filter(e=>e.name!==a):r.data;A=i;let o=t;if(!o||!i.some(e=>e.name===o)){let e=i.find(e=>e.isPk||e.name.toLowerCase()===`id`);o=e?e.name:i[0]?.name||``}D=o,n&&(n.textContent=o||`Select column...`),w.disabled=!1}}catch{n&&(n.textContent=`Error loading columns`)}}C.onclick=e=>{e.stopPropagation(),I({anchorEl:C,title:`Select Target Table`,searchable:!0,placeholder:`Search tables...`,initialValue:E,items:T.map(e=>({name:e,value:e,icon:`table_chart`})),onSelect:e=>{E=e;let t=document.getElementById(`modal-fk-table-display`);t&&(t.textContent=e),j(e)}})},w.onclick=e=>{e.stopPropagation(),!(!E||A.length===0)&&I({anchorEl:w,title:`Columns in ${E}`,searchable:!0,placeholder:`Search columns...`,initialValue:D,items:A.map(e=>({name:e.name,value:e.name,icon:`tag`,desc:e.type||``})),onSelect:e=>{D=e;let t=document.getElementById(`modal-fk-col-display`);t&&(t.textContent=e)}})};let M=document.getElementById(`modal-fk-ondelete`),N=document.getElementById(`modal-fk-onupdate`);M&&(M.onclick=e=>{e.stopPropagation(),I({anchorEl:M,title:`ON DELETE Action`,searchable:!1,initialValue:O,items:[`NO ACTION`,`CASCADE`,`RESTRICT`,`SET NULL`],onSelect:e=>{O=e;let t=document.getElementById(`modal-fk-ondelete-display`);t&&(t.textContent=e)}})}),N&&(N.onclick=e=>{e.stopPropagation(),I({anchorEl:N,title:`ON UPDATE Action`,searchable:!1,initialValue:k,items:[`NO ACTION`,`CASCADE`,`RESTRICT`,`SET NULL`],onSelect:e=>{k=e;let t=document.getElementById(`modal-fk-onupdate-display`);t&&(t.textContent=e)}})}),document.getElementById(`save-pkfk-btn`).onclick=()=>{let t=y.checked,n=x.checked,o=E,p=D,m=O||`NO ACTION`,h=k||`NO ACTION`;if(t===s&&n===c&&(!n||o===l&&p===u&&m===d&&h===f)){_();return}let g=m&&m!==`NO ACTION`?` (${m})`:``,v=``;if(t&&n){if(!o||!p){window.showToast?window.showToast(`Please select both Target Table and Target Column for the Foreign Key.`,`warning`):alert(`Please select both Target Table and Target Column for the Foreign Key.`);return}v=`PFK: ${o}.${p}${g}`}else if(t)v=`PK`;else if(n){if(!o||!p){window.showToast?window.showToast(`Please select both Target Table and Target Column for the Foreign Key.`,`warning`):alert(`Please select both Target Table and Target Column for the Foreign Key.`);return}v=`FK: ${o}.${p}${g}`}let b=n&&o&&p?{table:o,column:p,onDelete:m===`NO ACTION`?void 0:m,onUpdate:h===`NO ACTION`?void 0:h}:null;r&&i!==null?(window.SchemaGrid.pendingInserts[i]||(window.SchemaGrid.pendingInserts[i]={}),window.SchemaGrid.pendingInserts[i].fkTarget=b):a&&(window.SchemaGrid.pendingEdits[a]||(window.SchemaGrid.pendingEdits[a]={}),window.SchemaGrid.pendingEdits[a].fkTarget=b),window.SchemaGrid.currentTransaction=[],qe(e,v,[`name`,`type`,`isPk`,`nullable`,`defaultValue`,`indexing`]),window.SchemaGrid.currentTransaction.length>0&&window.SchemaGrid.history.push(window.SchemaGrid.currentTransaction),window.SchemaGrid.currentTransaction=null,_()}}async function $e(e,t){let n=window.SchemaGrid;if(!n)return;let r=document.getElementById(`enum-modal`);r&&r.remove();let i=e.dataset.insertIndex!==void 0,a=i?parseInt(e.dataset.insertIndex,10):null,o=e.dataset.pk||e.parentElement?.querySelector(`[data-col-key="name"]`)?.textContent?.trim()||`column`,s=(window.AppState?.dbType||`sqlite`).toLowerCase(),c=[],l=``,u=i?n.pendingInserts?.[a]:n.pendingEdits?.[o];u?.enumValues&&u.enumValues.length>0?(c=[...u.enumValues],l=u.type||``,u.isNewEnum):t?.enumValues&&t.enumValues.length>0&&(c=[...t.enumValues],l=t.type||``,t.isExistingEnum),l||=o&&o!==`column`?o.charAt(0).toUpperCase()+o.slice(1)+`Enum`:`CustomEnum`;let d=[];try{let e=await T();e?.success&&Array.isArray(e.data)&&(d=e.data)}catch(e){console.warn(`Failed to load database enums:`,e)}r=document.createElement(`div`),r.id=`enum-modal`,r.className=`modal-overlay`;let f=s===`sqlite`?`SQLite enforces enums using a <code>CHECK(col IN (...))</code> table constraint.`:s===`postgres`?`PostgreSQL creates custom ENUM types using <code>CREATE TYPE ... AS ENUM (...)</code>.`:`MySQL stores enums as native <code>ENUM(...)</code> column types.`,p=d.length>0,m=d.find(e=>e.name.toLowerCase()===l.toLowerCase());r.innerHTML=`
1133
- <div class="keys-modal-container" style="width: 520px;">
1134
- <div class="modal-header">
1135
- <div class="flex items-center gap-2">
1136
- <span class="material-symbols-outlined text-primary" style="font-size:20px;">list_alt</span>
1137
- <h3 class="m-0 text-15 font-semibold">Configure ENUM Column</h3>
1138
- <span class="keys-col-badge">${o}</span>
1139
- <span class="snippet-param-badge">${s}</span>
1140
- </div>
1141
- <button id="close-enum-modal" class="modal-close-btn" title="Close"><span class="material-symbols-outlined">close</span></button>
1142
- </div>
1143
-
1144
- <div class="key-cards-list" style="gap: 14px;">
1145
- <div style="font-size: 11.5px; color: var(--color-text-secondary); line-height: 1.5; background: var(--color-bg-secondary-dark); padding: 8px 12px; border-radius: 6px; border: 1px solid var(--color-border);">
1146
- ${f}
1147
- </div>
1303
+ <div id="col-vis-dropdown-${t}" class="col-vis-dropdown hidden" role="menu">
1304
+ <div class="col-vis-header">
1305
+ <input type="text" id="col-vis-search-${t}" placeholder="Search columns..." class="col-vis-search-input" autocomplete="off" spellcheck="false" />
1306
+ <div class="col-vis-quick-actions">
1307
+ <button type="button" id="btn-col-vis-show-all-${t}" class="col-vis-action-link">Show All</button>
1308
+ <span class="col-vis-divider">&middot;</span>
1309
+ <button type="button" id="btn-col-vis-hide-all-${t}" class="col-vis-action-link">Hide Non-PK</button>
1310
+ </div>
1311
+ </div>
1312
+ <div class="col-vis-list" id="col-vis-list-${t}"></div>
1313
+ </div>
1314
+ </div>
1315
+ `;let o=document.getElementById(`btn-col-visibility-${t}`),s=document.getElementById(`col-vis-dropdown-${t}`),c=document.getElementById(`col-vis-search-${t}`),l=document.getElementById(`col-vis-list-${t}`),u=document.getElementById(`btn-col-vis-show-all-${t}`),d=document.getElementById(`btn-col-vis-hide-all-${t}`),f=document.getElementById(`col-vis-badge-${t}`),p=()=>{f&&(f.textContent=`${a-i.size}/${a}`)},m=(e=``)=>{let a=e.toLowerCase().trim(),o=n.filter(e=>!a||e.name.toLowerCase().includes(a));l.innerHTML=o.map(e=>{let t=!!e.isPk,n=!i.has(e.name),r=String(e.name).replace(/&/g,`&amp;`).replace(/"/g,`&quot;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`);return`
1316
+ <label class="col-vis-item ${t?`is-pk`:``}">
1317
+ <input type="checkbox" data-col="${r}" ${n?`checked`:``} ${t?`disabled`:``} />
1318
+ <span class="col-vis-col-name">${r}</span>
1319
+ ${t?`<span class="col-vis-pk-tag">PK</span>`:`<span class="col-vis-type-tag">${(e.type||``).toLowerCase()}</span>`}
1320
+ </label>
1321
+ `}).join(``),l.querySelectorAll(`input[type="checkbox"]`).forEach(e=>{e.onchange=e=>{let n=e.target.dataset.col;e.target.checked?i.delete(n):i.add(n),bt(t,i),xt(t,i),p(),r&&r(i)}})};m(),xt(t,i),o.onclick=e=>{e.stopPropagation();let t=s.classList.contains(`hidden`);document.querySelectorAll(`.col-vis-dropdown`).forEach(e=>e.classList.add(`hidden`)),t&&(s.classList.remove(`hidden`),m(c?c.value:``),setTimeout(()=>c?.focus(),50))},c.oninput=e=>{m(e.target.value)},u.onclick=e=>{e.stopPropagation(),i.clear(),bt(t,i),m(c.value),xt(t,i),p(),r&&r(i)},d.onclick=e=>{e.stopPropagation(),n.forEach(e=>{e.isPk||i.add(e.name)}),bt(t,i),m(c.value),xt(t,i),p(),r&&r(i)},document.addEventListener(`click`,e=>{!s.contains(e.target)&&!o.contains(e.target)&&s.classList.add(`hidden`)})}var Ct=null,wt=null;function Tt(){if(Ct)return Ct;Ct=document.createElement(`div`),Ct.id=`cell-drawer-overlay`,Ct.className=`cell-drawer-overlay hidden`,Ct.innerHTML=`
1322
+ <div class="cell-drawer-backdrop" id="cell-drawer-backdrop"></div>
1323
+ <div class="cell-drawer-panel" id="cell-drawer-panel">
1324
+ <div class="cell-drawer-header">
1325
+ <div class="cell-drawer-title-group">
1326
+ <div class="flex items-center gap-2">
1327
+ <span class="material-symbols-outlined text-primary icon-20" id="cell-drawer-type-icon">code</span>
1328
+ <h3 class="cell-drawer-title" id="cell-drawer-col-title">Column Inspector</h3>
1329
+ </div>
1330
+ <div class="cell-drawer-meta" id="cell-drawer-meta">
1331
+ <span class="cell-drawer-type-badge" id="cell-drawer-type-badge">TEXT</span>
1332
+ <span class="cell-drawer-row-badge" id="cell-drawer-row-badge">Row #0</span>
1333
+ </div>
1334
+ </div>
1335
+ <button type="button" class="modal-close-btn" id="cell-drawer-close-btn" title="Close Drawer (Esc)">
1336
+ <span class="material-symbols-outlined">close</span>
1337
+ </button>
1338
+ </div>
1339
+
1340
+ <!-- Toolbar Actions -->
1341
+ <div class="cell-drawer-toolbar">
1342
+ <div class="flex items-center gap-2" id="cell-drawer-json-tools">
1343
+ <button type="button" class="cell-drawer-tool-btn" id="btn-drawer-prettify" title="Format JSON">
1344
+ <span class="material-symbols-outlined icon-14">auto_fix_high</span>
1345
+ <span>Prettify</span>
1346
+ </button>
1347
+ <button type="button" class="cell-drawer-tool-btn" id="btn-drawer-minify" title="Minify JSON">
1348
+ <span class="material-symbols-outlined icon-14">compress</span>
1349
+ <span>Minify</span>
1350
+ </button>
1351
+ <span class="json-valid-badge" id="json-valid-badge">Valid JSON</span>
1352
+ </div>
1353
+ <div class="flex items-center gap-2 ml-auto">
1354
+ <button type="button" class="cell-drawer-tool-btn" id="btn-drawer-wrap" title="Toggle Word Wrap">
1355
+ <span class="material-symbols-outlined icon-14">wrap_text</span>
1356
+ <span id="btn-drawer-wrap-text">Wrap: ON</span>
1357
+ </button>
1358
+ <button type="button" class="cell-drawer-tool-btn" id="btn-drawer-copy" title="Copy to clipboard">
1359
+ <span class="material-symbols-outlined icon-14">content_copy</span>
1360
+ <span>Copy</span>
1361
+ </button>
1362
+ </div>
1363
+ </div>
1148
1364
 
1149
- ${p?`
1150
- <div class="table-fk-popover-field">
1151
- <label style="font-size: 11px; font-weight: 500; color: var(--color-text-secondary);">Enum Source</label>
1152
- <button type="button" id="modal-enum-source" class="table-col-select" style="display: flex; justify-content: space-between; align-items: center; width: 100%; height: 32px; cursor: pointer; text-align: left; padding: 0 10px;">
1153
- <span id="modal-enum-source-display" style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">${m?m.name:`+ Define New Enum...`}</span>
1154
- <span class="material-symbols-outlined table-col-select-arrow" style="font-size: 16px;">expand_more</span>
1155
- </button>
1156
- </div>
1157
- `:``}
1365
+ <!-- Content Editor Area -->
1366
+ <div class="cell-drawer-body">
1367
+ <textarea id="cell-drawer-textarea" class="cell-drawer-textarea font-mono" spellcheck="false" autocomplete="off"></textarea>
1368
+ </div>
1158
1369
 
1159
- <div id="modal-enum-custom-fields" class="flex flex-col gap-3">
1160
- <div>
1161
- <label style="font-size: 11px; font-weight: 500; color: var(--color-text-secondary); display: block; margin-bottom: 5px;">
1162
- Enum Name ${s===`postgres`?`<span style="color: var(--color-error);">*</span>`:`(Optional)`}
1163
- </label>
1164
- <input type="text" id="modal-enum-name" class="modal-input w-full" style="padding: 7px 10px; font-size: 12px; font-family: var(--font-mono);" placeholder="e.g. OrderStatus" value="${l}" />
1165
- </div>
1370
+ <!-- Footer Stats & Actions -->
1371
+ <div class="cell-drawer-footer">
1372
+ <div class="cell-drawer-stats text-12 text-secondary" id="cell-drawer-stats">
1373
+ 0 characters &middot; 0 lines
1374
+ </div>
1375
+ <div class="flex items-center gap-2">
1376
+ <button type="button" class="btn-secondary" id="btn-drawer-cancel">Cancel</button>
1377
+ <button type="button" class="btn-primary flex items-center gap-1.5" id="btn-drawer-apply">
1378
+ <span class="material-symbols-outlined icon-16">check</span>
1379
+ <span>Apply to Cell</span>
1380
+ </button>
1381
+ </div>
1382
+ </div>
1383
+ </div>
1384
+ `,document.body.appendChild(Ct);let e=document.getElementById(`cell-drawer-close-btn`),t=document.getElementById(`btn-drawer-cancel`),n=document.getElementById(`cell-drawer-backdrop`),r=document.getElementById(`btn-drawer-apply`),i=document.getElementById(`btn-drawer-prettify`),a=document.getElementById(`btn-drawer-minify`),o=document.getElementById(`btn-drawer-copy`),s=document.getElementById(`btn-drawer-wrap`),c=document.getElementById(`btn-drawer-wrap-text`),l=document.getElementById(`cell-drawer-textarea`),u=()=>{Ct.classList.add(`hidden`),wt=null};e.onclick=u,t.onclick=u,n.onclick=u,document.addEventListener(`keydown`,e=>{e.key===`Escape`&&!Ct.classList.contains(`hidden`)&&u()});let d=!0;return s.onclick=()=>{d=!d,l.style.whiteSpace=d?`pre-wrap`:`pre`,c.textContent=d?`Wrap: ON`:`Wrap: OFF`},o.onclick=async()=>{try{await navigator.clipboard.writeText(l.value),window.showToast?.(`Copied content to clipboard`,`success`)}catch{window.showToast?.(`Failed to copy`,`error`)}},i.onclick=()=>{try{let e=JSON.parse(l.value);l.value=JSON.stringify(e,null,2),Et()}catch(e){window.showToast?.(`Cannot prettify invalid JSON: `+e.message,`warning`)}},a.onclick=()=>{try{let e=JSON.parse(l.value);l.value=JSON.stringify(e),Et()}catch(e){window.showToast?.(`Cannot minify invalid JSON: `+e.message,`warning`)}},l.oninput=()=>{Et()},r.onclick=()=>{if(window.AppState?.isReadOnly){window.showToast?.(`Database is in Read-Only protection mode.`,`warning`);return}if(!wt)return;let e=l.value,t=window.DataGrid?.columns||[];window.DataGrid&&(window.DataGrid.currentTransaction=[]),rt(wt,e,t,!0),window.DataGrid?.currentTransaction?.length>0&&window.DataGrid.history.push(window.DataGrid.currentTransaction),window.DataGrid&&(window.DataGrid.currentTransaction=null),window.updateSidebarDirtyState?.(),window.showToast?.(`Cell updated`,`success`),u()},Ct}function Et(){let e=document.getElementById(`cell-drawer-textarea`),t=document.getElementById(`cell-drawer-stats`),n=document.getElementById(`json-valid-badge`);if(!e)return;let r=e.value,i=r.length,a=r?r.split(`
1385
+ `).length:0,o=new Blob([r]).size;if(t&&(t.textContent=`${i.toLocaleString()} chars · ${a.toLocaleString()} lines · ${o.toLocaleString()} bytes`),n){let e=r.trim();if(!(e.startsWith(`{`)&&e.endsWith(`}`)||e.startsWith(`[`)&&e.endsWith(`]`))&&e!==``)n.style.display=`none`;else{n.style.display=`inline-flex`;try{JSON.parse(r),n.textContent=`Valid JSON`,n.className=`json-valid-badge is-valid`}catch{n.textContent=`Invalid JSON`,n.className=`json-valid-badge is-invalid`}}}}function Dt(e,t){let n=Tt();wt=e;let r=e.dataset.col||`Cell`,i=e.dataset.rowIdx===void 0?0:e.dataset.rowIdx,a=(t?.type||`TEXT`).toUpperCase(),o=``,s=e.dataset.pk,c=e.dataset.insertIndex,l=c===void 0?s===void 0?void 0:window.DataGrid?.pendingEdits?.[s]?.[r]:window.DataGrid?.pendingInserts?.[parseInt(c,10)]?.[r];o=l===void 0?e.dataset.original===void 0?e.textContent===`null`?``:e.textContent:e.dataset.original:String(l),document.getElementById(`cell-drawer-col-title`).textContent=r,document.getElementById(`cell-drawer-type-badge`).textContent=a,document.getElementById(`cell-drawer-row-badge`).textContent=`Row #${parseInt(i,10)+1}`;let u=document.getElementById(`cell-drawer-type-icon`),d=a.includes(`JSON`)||o.trim().startsWith(`{`)||o.trim().startsWith(`[`);u&&(u.textContent=d?`data_object`:`notes`);let f=document.getElementById(`cell-drawer-json-tools`);f&&(f.style.display=d?`flex`:`none`);let p=document.getElementById(`cell-drawer-textarea`);if(p)if(d)try{let e=JSON.parse(o);p.value=JSON.stringify(e,null,2)}catch{p.value=o}else p.value=o;let m=document.getElementById(`btn-drawer-apply`);m&&(window.AppState?.isReadOnly?(m.disabled=!0,m.innerHTML=`<span class="material-symbols-outlined icon-16">lock</span><span>Read-Only Mode</span>`):(m.disabled=!1,m.innerHTML=`<span class="material-symbols-outlined icon-16">check</span><span>Apply to Cell</span>`)),Et(),n.classList.remove(`hidden`),setTimeout(()=>p?.focus(),80)}function Ot(e){if(!window.DataGrid)return[];let t=window.DataGrid.selectedRowIndices||new Set,n=window.DataGrid.rows||[];return Array.from(t).filter(e=>e>=0&&e<n.length).map(e=>({index:e,data:n[e]}))}function kt(e){if(!window.DataGrid)return;window.DataGrid.selectedRowIndices=new Set,window.DataGrid.lastSelectedRowIndex=null;let t=document.getElementById(`data-grid-table-${e}`);if(t){t.querySelectorAll(`.row-select-checkbox`).forEach(e=>{e.checked=!1,e.closest(`tr`)?.classList.remove(`row-selected`)});let n=document.getElementById(`select-all-rows-${e}`);n&&(n.checked=!1,n.indeterminate=!1),document.getElementById(`th-row-header-${e}`)?.classList.remove(`has-selection`)}Nt(e)}function At(e,t){if(!window.DataGrid)return;let n=window.DataGrid.rows||[],r=new Set;if(t)for(let e=0;e<n.length;e++)r.add(e);window.DataGrid.selectedRowIndices=r;let i=document.getElementById(`data-grid-table-${e}`);if(i){i.querySelectorAll(`.row-select-checkbox`).forEach(e=>{e.checked=t,t?e.closest(`tr`)?.classList.add(`row-selected`):e.closest(`tr`)?.classList.remove(`row-selected`)});let r=document.getElementById(`th-row-header-${e}`);t&&n.length>0?r?.classList.add(`has-selection`):r?.classList.remove(`has-selection`)}Nt(e)}function jt(e,t,n,r){if(!window.DataGrid)return;window.DataGrid.selectedRowIndices||(window.DataGrid.selectedRowIndices=new Set);let i=window.DataGrid.selectedRowIndices,a=window.DataGrid.lastSelectedRowIndex;if(r&&a!=null){let r=Math.min(a,t),o=Math.max(a,t),s=document.getElementById(`data-grid-table-${e}`);for(let e=r;e<=o;e++){n?i.add(e):i.delete(e);let t=s?.querySelector(`.row-select-checkbox[data-row-idx="${e}"]`);t&&(t.checked=n,n?t.closest(`tr`)?.classList.add(`row-selected`):t.closest(`tr`)?.classList.remove(`row-selected`))}}else{n?i.add(t):i.delete(t);let r=document.getElementById(`data-grid-table-${e}`)?.querySelector(`.row-select-checkbox[data-row-idx="${t}"]`);r&&(r.checked=n,n?r.closest(`tr`)?.classList.add(`row-selected`):r.closest(`tr`)?.classList.remove(`row-selected`))}window.DataGrid.lastSelectedRowIndex=t,Mt(e),Nt(e)}function Mt(e){let t=document.getElementById(`select-all-rows-${e}`),n=document.getElementById(`th-row-header-${e}`);if(!t||!window.DataGrid)return;let r=(window.DataGrid.rows||[]).length,i=(window.DataGrid.selectedRowIndices||new Set).size;i===0?(t.checked=!1,t.indeterminate=!1,n?.classList.remove(`has-selection`)):i===r?(t.checked=!0,t.indeterminate=!1,n?.classList.add(`has-selection`)):(t.checked=!1,t.indeterminate=!0,n?.classList.add(`has-selection`))}function Nt(e){let t=document.getElementById(`bulk-bar-mount-${e}`);if(!t)return;let n=Ot(e),r=n.length;if(r===0){t.innerHTML=``;return}t.innerHTML=`
1386
+ <div class="bulk-actions-floating-bar" id="bulk-bar-${e}">
1387
+ <div class="bulk-bar-info">
1388
+ <span class="bulk-bar-count-badge">${r}</span>
1389
+ <span class="bulk-bar-label">row${r>1?`s`:``} selected</span>
1390
+ </div>
1391
+
1392
+ <div class="bulk-bar-actions">
1393
+ <button type="button" class="bulk-bar-btn" id="bulk-export-csv-${e}" title="Export selected rows as CSV">
1394
+ <span class="material-symbols-outlined icon-16">description</span>
1395
+ <span>Export CSV</span>
1396
+ </button>
1397
+ <button type="button" class="bulk-bar-btn" id="bulk-export-json-${e}" title="Export selected rows as JSON">
1398
+ <span class="material-symbols-outlined icon-16">data_object</span>
1399
+ <span>Export JSON</span>
1400
+ </button>
1401
+ <button type="button" class="bulk-bar-btn" id="bulk-export-masked-${e}" title="Export selected rows with PII Data Masking">
1402
+ <span class="material-symbols-outlined icon-16" style="color: #10b981;">enhanced_encryption</span>
1403
+ <span>Masked CSV</span>
1404
+ </button>
1405
+
1406
+ <div class="bulk-bar-divider"></div>
1166
1407
 
1167
- <div>
1168
- <label style="font-size: 11px; font-weight: 500; color: var(--color-text-secondary); display: block; margin-bottom: 5px;">
1169
- Allowed Values (comma separated) <span style="color: var(--color-error);">*</span>
1170
- </label>
1171
- <input type="text" id="modal-enum-values" class="modal-input w-full" style="padding: 7px 10px; font-size: 12px; font-family: var(--font-mono);" placeholder="e.g. PENDING, PAID, CANCELLED, REFUNDED" value="${c.join(`, `)}" />
1172
- <span style="font-size: 10.5px; color: var(--color-text-soft); margin-top: 4px; display: block;">Separate values with commas. Quotes are optional.</span>
1173
- </div>
1174
- </div>
1408
+ <button type="button" class="bulk-bar-btn bulk-btn-delete" id="bulk-delete-${e}" title="Delete selected rows">
1409
+ <span class="material-symbols-outlined icon-16">delete</span>
1410
+ <span>Delete (${r})</span>
1411
+ </button>
1175
1412
 
1176
- <!-- SQL DDL Preview -->
1177
- <div>
1178
- <label style="font-size: 11px; font-weight: 500; color: var(--color-text-secondary); display: block; margin-bottom: 5px;">
1179
- Preview
1180
- </label>
1181
- <div style="background: var(--color-bg-secondary-dark); border: 1px solid var(--color-border); border-radius: 6px; padding: 10px 12px; font-family: var(--font-mono); font-size: 11.5px; color: var(--color-text); word-break: break-all; min-height: 38px; display: flex; align-items: center;" id="modal-enum-preview">
1182
- -
1413
+ <button type="button" class="bulk-bar-btn bulk-btn-cancel" id="bulk-cancel-${e}" title="Clear selection">
1414
+ <span class="material-symbols-outlined icon-16">close</span>
1415
+ </button>
1416
+ </div>
1417
+ </div>
1418
+ `;let i=document.getElementById(`bulk-cancel-${e}`);i&&(i.onclick=()=>kt(e));let a=document.getElementById(`bulk-export-csv-${e}`);a&&(a.onclick=()=>{Pt(e,n.map(e=>e.data),`csv`)});let o=document.getElementById(`bulk-export-json-${e}`);o&&(o.onclick=()=>{Pt(e,n.map(e=>e.data),`json`)});let s=document.getElementById(`bulk-export-masked-${e}`);s&&(s.onclick=()=>{Pt(e,n.map(e=>e.data),`csv`,!0)});let c=document.getElementById(`bulk-delete-${e}`);c&&(window.AppState?.isReadOnly?(c.disabled=!0,c.title=`Read-Only Mode Active`):c.onclick=async()=>{if(!confirm(`Are you sure you want to permanently delete these ${r} selected row(s)?`))return;let t=window.DataGrid,i=t?.pkColumn,a=t?.pkColumns,o=t?.isCompositePk,s=[];for(let e of n)if(o&&a){let t={};a.forEach(n=>{t[n]=e.data[n]}),s.push(JSON.stringify(t))}else i&&s.push(e.data[i]);c.disabled=!0,c.innerHTML=`<span class="material-symbols-outlined animate-spin icon-16">progress_activity</span><span>Deleting...</span>`;try{let n=await p(e,{pkColumn:i,pkColumns:a,deletes:s,schema:t.schema});if(n.success){window.showToast?.(`Successfully deleted ${r} row(s)`,`success`),kt(e);let t=document.getElementById(`btn-refresh-data-${e}`);t&&t.click()}else window.showToast?.(n.error||`Failed to delete rows`,`error`),c.disabled=!1,c.innerHTML=`<span class="material-symbols-outlined icon-16">delete</span><span>Delete (${r})</span>`}catch(e){window.showToast?.(e.message||`Network error`,`error`),c.disabled=!1,c.innerHTML=`<span class="material-symbols-outlined icon-16">delete</span><span>Delete (${r})</span>`}})}function Pt(e,t,n,r=!1){if(!t||t.length===0)return;let i=r?Ft(t):t,a=``,o=`text/plain`,s=`txt`;if(n===`json`)a=JSON.stringify(i,null,2),o=`application/json`,s=`json`;else{let e=Object.keys(i[0]),t=[e.map(e=>`"${String(e).replace(/"/g,`""`)}"`).join(`,`)];for(let n of i){let r=e.map(e=>{let t=n[e];return t==null?``:`"${String(t).replace(/"/g,`""`)}"`});t.push(r.join(`,`))}a=t.join(`
1419
+ `),o=`text/csv`,s=`csv`}let c=new Blob([a],{type:o}),l=URL.createObjectURL(c),u=document.createElement(`a`);u.href=l,u.download=`${e}_selected_${r?`masked_`:``}${Date.now()}.${s}`,u.click(),URL.revokeObjectURL(l),window.showToast?.(`Exported ${i.length} ${r?`masked `:``}rows as ${s.toUpperCase()}`,`success`)}function Ft(e){if(!e||e.length===0)return e;let t=/^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$/,n=/^(\+?\d{1,4}[-.\s]?)?(\(?\d{2,4}\)?[-.\s]?)?\d{3,4}[-.\s]?\d{3,4}$/,r=/^(\d{1,3}\.){3}\d{1,3}$/,i=/password|secret|token|hash|salt|api_key|credit_card|card_num|ssn/i;function a(e){let t=5381;for(let n=0;n<e.length;n++)t=(t<<5)+t+e.charCodeAt(n),t&=t;return Math.abs(t).toString(36)}return e.map(e=>{let o={...e};for(let[e,s]of Object.entries(o)){if(s==null)continue;let c=String(s).trim();i.test(e)?o[e]=`[PROTECTED]`:t.test(c)?o[e]=`user_${a(c).slice(0,6)}@example.test`:r.test(c)?o[e]=`10.0.${parseInt(a(c).slice(0,2)||`0`,36)%255}.${parseInt(a(c).slice(2,4)||`0`,36)%255}`:n.test(c)&&c.length>=7&&(o[e]=`+1-555-${a(c).slice(0,4)}`)}return o})}async function G(e,t,n=``,r=!1,i=null){if(window.updateSidebarActiveTable)window.updateSidebarActiveTable(e);else{document.querySelectorAll(`.table-btn`).forEach(e=>e.classList.remove(`active`));let n=t||document.querySelector(`.table-btn[data-table="${e}"]`);n&&(n.classList.add(`active`),window.AppState&&(window.AppState.currentTableBtnElement=n))}let a=document.getElementById(`table-name`);a&&(a.textContent=e);let o=i||document.getElementById(`main-content`);r||(o.innerHTML=`<div class='p-6'>Loading...</div>`);try{let i=await u(e);if(!i.success)throw Error(i.error);let a=i.data,s=a.filter(e=>e.isPk).map(e=>e.name),c=s[0],d=s.length>1;(!r||!window.DataGrid)&&(window.DataGrid={schema:a,pkColumn:c,pkColumns:s,isCompositePk:d,pendingEdits:{},pendingInserts:[{}],pendingDeletes:new Set,selectedCell:null,history:[],currentTransaction:null,sortState:{col:c||a[0]?.name||``,asc:!0},pagination:{limit:50,offset:0,isLoading:!1,hasMore:!0},selection:{isDragging:!1,isDraggingRow:!1,startRow:-1,startCol:-1,endRow:-1,endCol:-1}}),window.TableStates&&window.TableStates[e]&&(window.TableStates[e].dataGrid=window.DataGrid);let f=await l(e,{where:n,limit:window.DataGrid.pagination.limit,offset:window.DataGrid.pagination.offset,orderCol:window.DataGrid.sortState.col,orderAsc:window.DataGrid.sortState.asc});if(f.success&&f.data){window.loadTableStats?.();let i=f.data.rows,s=f.data.columns;if(window.DataGrid.rows=i,window.DataGrid.columns=s,window.DataGrid.pagination.hasMore=i.length===window.DataGrid.pagination.limit,!r){o.innerHTML=`
1420
+ <div class="toolbar">
1421
+ ${window.fkNavHistory&&window.fkNavHistory.toTable===e?`<button type="button" id="btn-fk-back-${e}" class="fk-back-btn" title="Back to table '${window.fkNavHistory.fromTable}'">
1422
+ <span class="material-symbols-outlined icon-14" style="color: var(--color-primary);">arrow_back</span>
1423
+ <span>Back to ${window.fkNavHistory.fromTable}</span>
1424
+ </button>`:``}
1425
+ <div id="filter-bar-mount-${e}" class="flex-1" style="height: 100%; display: flex; align-items: center; min-width: 0;"></div>
1426
+ <div id="col-visibility-mount-${e}" class="toolbar-item" style="display: flex; align-items: center;"></div>
1427
+ <div class="page-size-picker flex items-center gap-1.5" title="Rows per page">
1428
+ <span class="material-symbols-outlined icon-14" style="font-size: 15px; color: var(--color-primary);">table_rows</span>
1429
+ <select id="select-page-size-${e}" class="page-size-select">
1430
+ <option value="25">25 / page</option>
1431
+ <option value="50" selected>50 / page</option>
1432
+ <option value="100">100 / page</option>
1433
+ <option value="200">200 / page</option>
1434
+ </select>
1435
+ </div>
1436
+ <button id="btn-refresh-data-${e}" class="refresh-btn" title="Refresh Data (F5)">
1437
+ <span class="material-symbols-outlined" style="color: #10b981;">refresh</span>
1438
+ </button>
1183
1439
  </div>
1184
- </div>
1185
- </div>
1186
-
1187
- <div class="modal-footer">
1188
- <button id="cancel-enum-btn" class="btn-secondary">Cancel</button>
1189
- <button id="save-enum-btn" class="btn-primary flex items-center gap-1.5">
1190
- <span class="material-symbols-outlined" style="font-size:16px;">check</span>
1191
- <span>Apply Enum</span>
1192
- </button>
1440
+ <div id="bulk-bar-mount-${e}"></div>
1441
+ <div class="table-container" id="data-grid-container-${e}"></div>
1442
+ `;let n=document.getElementById(`filter-bar-mount-${e}`);n&&Qe({container:n,tableName:e,schema:a,onFilterChange:()=>{window.DataGrid&&(window.DataGrid.pagination.offset=0),G(e,t,$e(e),!0)}});let r=document.getElementById(`col-visibility-mount-${e}`);r&&St({container:r,tableName:e,schema:a});let i=document.getElementById(`select-page-size-${e}`);i&&(i.value=String(window.DataGrid.pagination.limit||50),i.onchange=n=>{let r=parseInt(n.target.value,10);r&&window.DataGrid&&(window.DataGrid.pagination.limit=r,window.DataGrid.pagination.offset=0,G(e,t,$e(e),!0))})}let u=document.getElementById(`data-grid-container-${e}`);if(!u)return;if((!i||i.length===0)&&!window.forceEmptyGrid)if(n){u.innerHTML=`
1443
+ <div class="table-empty-container">
1444
+ <div class="table-empty-card">
1445
+ <div class="table-empty-icon-wrap">
1446
+ <span class="material-symbols-outlined table-empty-icon">search_off</span>
1447
+ </div>
1448
+ <h3 class="table-empty-title">No matching records found</h3>
1449
+ <p class="table-empty-desc">No records in "${e}" matched the current filter conditions.</p>
1450
+ <div class="table-empty-actions">
1451
+ <button type="button" class="table-empty-btn-primary" id="btn-empty-clear-filter-${e}">
1452
+ <span class="material-symbols-outlined icon-16">filter_alt_off</span>
1453
+ <span>Clear Filter</span>
1454
+ </button>
1455
+ </div>
1456
+ </div>
1457
+ </div>
1458
+ `;let n=document.getElementById(`btn-empty-clear-filter-${e}`);n&&(n.onclick=()=>{Ye(e),G(e,t,``,!1)})}else{u.innerHTML=`
1459
+ <div class="table-empty-container">
1460
+ <div class="table-empty-card">
1461
+ <div class="table-empty-icon-wrap">
1462
+ <span class="material-symbols-outlined table-empty-icon">dataset</span>
1463
+ </div>
1464
+ <h3 class="table-empty-title">Table "${e}" is empty</h3>
1465
+ <p class="table-empty-desc">This table currently contains 0 records. You can insert a new row manually or generate realistic mock data with one click.</p>
1466
+ <div class="table-empty-actions">
1467
+ <button type="button" class="table-empty-btn-secondary" id="btn-empty-add-row-${e}">
1468
+ <span class="material-symbols-outlined icon-16">add</span>
1469
+ <span>Insert Row</span>
1470
+ </button>
1471
+ <button type="button" class="table-empty-btn-primary" id="btn-empty-mock-${e}">
1472
+ <span class="material-symbols-outlined icon-16">auto_fix_high</span>
1473
+ <span>Generate Mock Data</span>
1474
+ </button>
1475
+ </div>
1476
+ </div>
1477
+ </div>
1478
+ `;let n=document.getElementById(`btn-empty-mock-${e}`);n&&(n.onclick=()=>{oe(e,a,()=>{window.forceEmptyGrid=!1,G(e,t,``,!0)})});let r=document.getElementById(`btn-empty-add-row-${e}`);r&&(r.onclick=()=>{window.forceEmptyGrid=!0,G(e,t,``,!0)})}else{let n=`<table class="data-table" id="data-grid-table-${e}"><thead><tr>`;if(n+=`<th class="row-header table-corner-header" id="th-row-header-${e}" title="Click to select all cells, right-click for table actions"><span class="corner-num">#</span><input type="checkbox" id="select-all-rows-${e}" class="row-select-checkbox corner-checkbox" title="Select all rows" /></th>`,s.forEach(e=>{let t=a.find(t=>t.name===e),r=``,i=t?.type||``;if(t){let e=!!t.isPk,n=!!t.fkTarget;e?r=`<span class="material-symbols-outlined col-pk-key-icon" title="Primary Key">key</span>`:(n||t.name.toLowerCase().includes(`id`))&&(r=`<span class="material-symbols-outlined col-fk-icon" title="Foreign Key">link</span>`)}let o=window.DataGrid.sortState.col===e;n+=`<th class="sortable ${o?`sorted`:``}" data-col="${e}" title="Click for column options">
1479
+ <div class="th-content-wrapper">
1480
+ <div class="th-main-group">
1481
+ ${r}
1482
+ <span class="th-col-name">${e}</span>
1483
+ ${i?`<span class="th-col-type">${i.toLowerCase()}</span>`:``}
1484
+ </div>
1485
+ <div class="th-actions-group">
1486
+ <button type="button" class="th-menu-trigger ${o?`is-sorted`:``}" title="Column actions">
1487
+ <span class="material-symbols-outlined th-chevron-icon">keyboard_arrow_down</span>
1488
+ </button>
1489
+ </div>
1490
+ </div>
1491
+ </th>`}),n+=`</tr></thead><tbody>`,i&&i.length>0&&i.forEach((e,t)=>{n+=`<tr>${tt(e,t,c,s,a)}</tr>`}),!window.AppState?.isReadOnly){n+=`<tr class="ghost-row-tr">`;let e=i?i.length:0;n+=`<td class="row-header" data-row-idx="${e}">*</td>`,s.forEach((t,r)=>{n+=`<td class="data-cell ghost-row" data-row-idx="${e}" data-col-idx="${r}" data-insert-index="0" data-col="${t}">${r===0?`<span class="ghost-cell-hint">+ Add Row</span>`:``}</td>`}),n+=`</tr>`}n+=`</tbody></table>`,u.innerHTML=n;let r=yt(e);r.size>0&&xt(e,r),u.querySelectorAll(`th.sortable`).forEach(n=>{let r=n.dataset.col,i=e,o=e=>{if(window.DataGrid&&window.DataGrid.isResizing||e.target.closest(`.resizer`))return;let o=window.TableStates?.[i]?.dataGrid||window.DataGrid,s=o?.sortState?.col===r,c=s&&o?.sortState?.asc,l=()=>Object.keys(window.DataGrid.pendingEdits||{}).length>0||(window.DataGrid.pendingInserts||[]).length>1||window.DataGrid.pendingDeletes&&window.DataGrid.pendingDeletes.size>0?(window.showToast?window.showToast(`You have unsaved changes. Please save changes before sorting.`,`warning`):alert(`You have unsaved changes. Please save changes before sorting.`),!1):!0,u=e=>{l()&&(o&&(o.sortState.col=r,o.sortState.asc=e,o.pagination.offset=0),G(i,t,$e(i),!0),window.showToast&&window.showToast(`Sorted by ${r} (${e?`Ascending`:`Descending`})`,`info`))},d=()=>{l()&&(o&&(o.sortState.col=null,o.sortState.asc=!0,o.pagination.offset=0),G(i,t,$e(i),!0),window.showToast&&window.showToast(`Cleared sort on "${r}"`,`info`))},f=[{icon:`arrow_upward`,label:`Sort Ascending`,checked:s&&c,action:()=>u(!0)},{icon:`arrow_downward`,label:`Sort Descending`,checked:s&&!c,action:()=>u(!1)}];s&&f.push({icon:`restart_alt`,label:`Clear Sort`,action:()=>d()}),f.push(`divider`,{icon:`content_copy`,label:`Copy name`,action:async()=>{try{await navigator.clipboard.writeText(r)}catch{let e=document.createElement(`textarea`);e.value=r,document.body.appendChild(e),e.select(),document.execCommand(`copy`),e.remove()}window.showToast&&window.showToast(`Copied "${r}" to clipboard!`,`success`)}},{icon:`edit`,label:`Edit column`,action:()=>{typeof window.handleSwitchTab==`function`&&(window.handleSwitchTab(`schema-btn`),window.showToast&&window.showToast(`Switched to Schema Editor for "${r}"`,`info`))}},{icon:`filter_alt`,label:`Filter by this column`,action:()=>{let e=document.getElementById(`filter-bar-input-${i}`);e&&(e.focus(),e.value=`${r} = `,e.dispatchEvent(new Event(`input`,{bubbles:!0})))}},`divider`,{icon:`delete`,label:`Delete column`,danger:!0,action:async()=>{if(confirm(`Are you sure you want to delete column "${r}" from table "${i}"?\nThis action cannot be undone!`))try{let e=await m(i,{pendingDeletes:[r],columns:a});e.success?(window.showToast&&window.showToast(`Deleted column "${r}"`,`success`),G(i,t,``,!0)):alert(`Failed to delete column: ${e.error}`)}catch(e){alert(`Error deleting column: ${e.message}`)}}});let p=n.querySelector(`.th-menu-trigger`),h=p?p.getBoundingClientRect():n.getBoundingClientRect();V({clientX:h.left,clientY:h.bottom+4,preventDefault:()=>{},stopPropagation:()=>{}},f)};n.onclick=o,n.oncontextmenu=e=>{e.preventDefault(),o(e)},Ge(n,window.DataGrid)}),We(u,`data-grid-table-${e}`,window.DataGrid,s.length),lt(u,a,s),gt(u,e);let o=document.getElementById(`th-row-header-${e}`);if(o){o.addEventListener(`click`,t=>{t.target.closest(`.row-select-checkbox`)||(t.preventDefault(),t.stopPropagation(),Ue(`data-grid-table-${e}`,window.DataGrid,s.length))}),o.addEventListener(`contextmenu`,n=>{n.preventDefault&&n.preventDefault(),n.stopPropagation&&n.stopPropagation();let r=$e(e),i=window.DataGrid?.sortState,o=!!r,c=t=>{let n=`/api/tables/${encodeURIComponent(e)}/export?format=${t}`;return r&&(n+=`&where=${encodeURIComponent(r)}`),i&&i.col&&(n+=`&orderCol=${encodeURIComponent(i.col)}&orderAsc=${i.asc}`),n};V(n,[{icon:`select_all`,label:`Select All Cells`,shortcut:`Ctrl+A`,action:()=>{Ue(`data-grid-table-${e}`,window.DataGrid,s.length)}},`divider`,{icon:`auto_fix_high`,label:`Generate Mock Data...`,action:()=>{oe(e,a,()=>{G(e,t,$e(e),!0)})}},{icon:`content_copy`,label:`Copy Table Name`,action:async()=>{try{await navigator.clipboard.writeText(e)}catch{let t=document.createElement(`textarea`);t.value=e,document.body.appendChild(t),t.select(),document.execCommand(`copy`),t.remove()}window.showToast&&window.showToast(`Copied "${e}"`,`success`)}},{type:`divider`},{icon:`download`,label:o?`Export as CSV (Filtered)`:`Export as CSV`,action:()=>{window.open(c(`csv`),`_blank`)}},{icon:`download`,label:o?`Export as JSON (Filtered)`:`Export as JSON`,action:()=>{window.open(c(`json`),`_blank`)}},{type:`divider`},{icon:`mop`,label:`Truncate Table (Clear Rows)`,danger:!0,action:async()=>{if(confirm(`Are you sure you want to delete ALL rows from table "${e}"? This cannot be undone!`)){let n=await g(e);n.success?(window.showToast&&window.showToast(`Cleared all rows from "${e}"`,`info`),G(e,t,``,!0)):alert(`Failed to clear table: ${n.error}`)}}}])});let n=document.getElementById(`select-all-rows-${e}`);n&&(n.onclick=t=>{t.stopPropagation(),At(e,n.checked)})}u.addEventListener(`change`,t=>{let n=t.target.closest(`.row-select-checkbox`);n&&n.dataset.rowIdx!==void 0&&jt(e,parseInt(n.dataset.rowIdx,10),n.checked,t.shiftKey||window.DataGrid?._lastShiftKey)}),u.addEventListener(`click`,e=>{let t=e.target.closest(`.row-select-checkbox`);t&&t.dataset.rowIdx!==void 0&&window.DataGrid&&(window.DataGrid._lastShiftKey=e.shiftKey)}),u.addEventListener(`click`,e=>{let t=e.target.closest(`.cell-drawer-trigger-btn`);if(t){e.stopPropagation(),e.preventDefault();let n=t.closest(`td.data-cell`);if(n){let e=n.dataset.col;Dt(n,a.find(t=>t.name===e))}}}),u.addEventListener(`contextmenu`,t=>{let n=t.target.closest(`td.data-cell`);if(!n)return;t.preventDefault(),t.stopPropagation();let r=n.dataset.col,i=a.find(e=>e.name===r),o=n.dataset.original===void 0?n.querySelector(`.cell-text`)?.textContent.trim()||``:n.dataset.original;o===`null`&&(o=``),V(t,[{icon:`open_in_full`,label:`Inspect in Cell Drawer`,action:()=>Dt(n,i)},`divider`,{icon:`content_copy`,label:`Copy Cell Value`,action:async()=>{try{await navigator.clipboard.writeText(o)}catch{let e=document.createElement(`textarea`);e.value=o,document.body.appendChild(e),e.select(),document.execCommand(`copy`),e.remove()}window.showToast?.(`Copied cell value to clipboard`,`info`)}},{icon:`filter_alt`,label:`Filter by "${o.length>20?o.slice(0,20)+`...`:o}"`,action:()=>{let t=document.getElementById(`filter-bar-input-${e}`);t&&(t.value=`${r} = '${o.replace(/'/g,`''`)}'`,t.dispatchEvent(new Event(`input`,{bubbles:!0})))}},`divider`,{icon:`block`,label:`Set to NULL`,danger:!0,disabled:window.AppState?.isReadOnly||i&&i.isPk,action:()=>{window.AppState?.isReadOnly||(window.DataGrid.currentTransaction=[],rt(n,``,s),window.DataGrid.currentTransaction.length>0&&window.DataGrid.history.push(window.DataGrid.currentTransaction),window.DataGrid.currentTransaction=null)}}])})}let d=document.getElementById(`btn-fk-back-${e}`);if(d&&(d.onclick=()=>{let e=window.fkNavHistory?.fromTable;if(window.fkNavHistory=null,e){let t=document.querySelector(`.table-btn[data-table="${e}"]`)||Array.from(document.querySelectorAll(`.table-btn`)).find(t=>t.textContent.includes(e));window.AppState.currentTable=e,window.AppState.currentTableBtnElement=t||null,document.querySelectorAll(`.table-btn`).forEach(e=>e.classList.remove(`active`)),t&&t.classList.add(`active`);let n=`view-data-btn-${e}`,r=document.getElementById(n);r&&(r.innerHTML=``),window.renderCurrentView()}}),!r){let n=()=>{(Object.keys(window.DataGrid.pendingEdits).length>0||window.DataGrid.pendingInserts.length>1||window.DataGrid.pendingDeletes.size>0)&&!confirm(`You have unsaved changes. Are you sure you want to refresh and discard them?`)||(window.DataGrid.pendingEdits={},window.DataGrid.pendingInserts=[{}],window.DataGrid.pendingDeletes=new Set,window.DataGrid.history=[],window.DataGrid.currentTransaction=null,kt(e),window.updateSidebarDirtyState?.(),window.DataGrid&&(window.DataGrid.pagination.offset=0),G(e,t,$e(e),!0))},r=document.getElementById(`btn-refresh-data-${e}`);r&&(r.onclick=n),window.DataGrid.refreshData=n;let i=async()=>{if(window.DataGrid.pagination.isLoading||!window.DataGrid.pagination.hasMore)return;window.DataGrid.pagination.isLoading=!0,window.DataGrid.pagination.offset+=window.DataGrid.pagination.limit;let t={where:$e(e),limit:window.DataGrid.pagination.limit,offset:window.DataGrid.pagination.offset,orderCol:window.DataGrid.sortState.col,orderAsc:window.DataGrid.sortState.asc};try{let n=await l(e,t);if(window.DataGrid.pagination.isLoading=!1,n.success&&n.data){let t=n.data.rows;window.DataGrid.pagination.hasMore=t.length===window.DataGrid.pagination.limit;let r=document.querySelector(`#data-grid-table-${e} tbody`);if(!r)return;let i=r.querySelector(`td[data-insert-index]`)?.closest(`tr`),o=window.DataGrid.pagination.offset;t.forEach((e,t)=>{let n=document.createElement(`tr`);n.innerHTML=tt(e,o+t,c,s,a),i?r.insertBefore(n,i):r.appendChild(n)});let l=o+t.length,u=r.querySelectorAll(`td[data-insert-index]`),d=new Set;u.forEach(e=>{let t=e.closest(`tr`);if(d.has(t))return;d.add(t);let n=t.querySelector(`.row-header`);n&&(n.dataset.rowIdx=l),t.querySelectorAll(`td.data-cell`).forEach(e=>e.dataset.rowIdx=l),l++});let f=yt(e);f.size>0&&xt(e,f)}}catch{window.DataGrid.pagination.isLoading=!1}};setTimeout(()=>{let t=document.getElementById(`data-grid-container-${e}`);t&&t.addEventListener(`scroll`,e=>{let{scrollTop:t,scrollHeight:n,clientHeight:r}=e.target;t+r>=n-50&&i()})},50)}}else It(o,f.error||`Unknown error occurred`,e,t,n)}catch(r){It(o,r.message||`Failed to load table data`,e,t,n)}}function It(e,t,n,r,i){let a=/not found|failed to find/i.test(t);e.innerHTML=`
1492
+ <div class="data-error-container">
1493
+ <div class="data-error-card">
1494
+ <div class="data-error-icon-wrap">
1495
+ <span class="material-symbols-outlined data-error-icon">${a?`database_off`:`error_outline`}</span>
1496
+ </div>
1497
+ <h3 class="data-error-title">${a?`Database File Not Found`:`Failed to Load Data`}</h3>
1498
+ <p class="data-error-desc">${t.replace(/</g,`&lt;`).replace(/>/g,`&gt;`)}</p>
1499
+ <div class="data-error-actions">
1500
+ <button type="button" class="data-error-btn-primary" id="btn-data-error-retry">
1501
+ <span class="material-symbols-outlined icon-16" style="font-size: 16px;">refresh</span>
1502
+ <span>Retry Connection</span>
1503
+ </button>
1504
+ <button type="button" class="data-error-btn-secondary" id="btn-data-error-switch-db">
1505
+ <span class="material-symbols-outlined icon-16" style="font-size: 16px;">dns</span>
1506
+ <span>Connect / Switch Database</span>
1507
+ </button>
1508
+ </div>
1509
+ </div>
1193
1510
  </div>
1194
- </div>
1195
- `,document.body.appendChild(r);let h=()=>{document.removeEventListener(`keydown`,g),r.remove()},g=e=>{e.key===`Escape`&&h()};document.addEventListener(`keydown`,g),document.getElementById(`close-enum-modal`).onclick=h,document.getElementById(`cancel-enum-btn`).onclick=h,r.addEventListener(`click`,e=>{e.target===r&&h()});let _=document.getElementById(`modal-enum-source`),v=document.getElementById(`modal-enum-custom-fields`),y=document.getElementById(`modal-enum-name`),b=document.getElementById(`modal-enum-values`),x=document.getElementById(`modal-enum-preview`),S=m?m.name:`__NEW__`;function C(){if(_&&S!==`__NEW__`){let e=d.find(e=>e.name===S);return e?[...e.values]:[]}return b.value.split(`,`).map(e=>e.trim().replace(/^['"]|['"]$/g,``)).filter(Boolean)}function w(){let e=C(),t=(y.value.trim()||l||`CustomEnum`).trim(),n=e.map(e=>`'${e.replace(/'/g,`''`)}'`).join(`, `);if(e.length===0){x.textContent=`Enter enum values above to see SQL preview`;return}s===`sqlite`?x.textContent=`TEXT CHECK("${o}" IN (${n}))`:s===`postgres`?_&&S!==`__NEW__`?x.textContent=`Type: "${S}" (Values: ${n})`:x.textContent=`CREATE TYPE "${t}" AS ENUM (${n});`:x.textContent=`ENUM(${n})`}_&&(_.onclick=e=>{e.stopPropagation();let t=[{name:`+ Define New Enum...`,value:`__NEW__`,icon:`add_circle`},...d.map(e=>({name:e.name,value:e.name,desc:e.values.slice(0,3).join(`, `)+(e.values.length>3?`...`:``),icon:`list`,group:`Existing Database Enums`}))];I({anchorEl:_,title:`Select Enum Source`,searchable:!0,placeholder:`Search enum types...`,initialValue:S,items:t,onSelect:e=>{S=e;let t=document.getElementById(`modal-enum-source-display`);t&&(t.textContent=e===`__NEW__`?`+ Define New Enum...`:e),e===`__NEW__`?v.style.display=`flex`:v.style.display=`none`,w()}})},S!==`__NEW__`&&(v.style.display=`none`)),y.oninput=w,b.oninput=w,w(),document.getElementById(`save-enum-btn`).onclick=()=>{let t=C();if(t.length===0){window.showToast?window.showToast(`Please specify at least one enum value.`,`error`):alert(`Please specify at least one enum value.`),b.focus();return}let r=``,c=!0;_&&S!==`__NEW__`?(r=S,c=!1):(r=(y.value.trim()||l||`CustomEnum`).trim(),c=!0);let u=s===`postgres`?r:r||`ENUM`;i&&a!==null?(n.pendingInserts[a]||(n.pendingInserts[a]={}),n.pendingInserts[a].type=u,n.pendingInserts[a].enumValues=t,n.pendingInserts[a].isNewEnum=c):o&&(n.pendingEdits[o]||(n.pendingEdits[o]={}),n.pendingEdits[o].type=u,n.pendingEdits[o].enumValues=t,n.pendingEdits[o].isNewEnum=c),window.SchemaGrid.currentTransaction=[],qe(e,u,[`name`,`type`,`isPk`,`nullable`,`isUnique`,`defaultValue`,`indexing`]),window.SchemaGrid.currentTransaction.length>0&&window.SchemaGrid.history.push(window.SchemaGrid.currentTransaction),window.SchemaGrid.currentTransaction=null,h(),window.updateSidebarDirtyState?.(),window.showToast?.(`Enum column configured!`,`success`)}}function et(e,t){e.addEventListener(`click`,e=>{if(e.target.closest(`.btn-manage-indexes`)||e.target.closest(`.manage-indexes-cell`)){Ze();return}let t=e.target.closest(`.badge-enum`);if(t){let e=t.closest(`td.data-cell`);if(e){let t=e.dataset.pk,n=window.SchemaGrid?.schema?.find(e=>e.name===t);$e(e,n);return}}}),e.addEventListener(`dblclick`,e=>{let n=e.target.closest(`td.data-cell`);if(!n||n.querySelector(`input, select, textarea`))return;let r=n.dataset.colKey;if(r===`indexing`){Ze();return}let i=n.dataset.insertIndex!==void 0,a=i||n.textContent===`-`||n.textContent===`+ New`||n.textContent.includes(`Add column`)||n.textContent.includes(`Add Column`)||n.textContent===`+ Add Row`||n.textContent===`null`?``:n.dataset.original!==void 0&&n.dataset.original!==`-`?n.dataset.original:n.textContent.trim().startsWith(`Yes`)?`1`:n.textContent.trim()===`No`?``:n.textContent.trim();if(r===`name`||r===`defaultValue`){Fe({td:n,colName:r===`name`?`Column Name`:`Default Value`,colType:r===`name`?`VARCHAR`:`DEFAULT`,initialValue:a,onSave:e=>{window.SchemaGrid.currentTransaction=[],qe(n,e,t),window.SchemaGrid.currentTransaction.length>0&&window.SchemaGrid.history.push(window.SchemaGrid.currentTransaction),window.SchemaGrid.currentTransaction=null}});return}let o;if(r===`isPk`){Qe(n,n.textContent);return}else if(r===`nullable`){let e=n.dataset.pk,r=window.SchemaGrid?.schema?.find(t=>t.name===e),o=window.SchemaGrid?.pendingEdits?.[e]?.isPk,s=o===void 0?r?r.isPk:!1:typeof o==`string`?o.includes(`PK`)||o.includes(`PFK`):!!o,c=i&&window.SchemaGrid?.pendingInserts?.[parseInt(n.dataset.insertIndex,10)]?.isPk,l=typeof c==`string`?c.includes(`PK`)||c.includes(`PFK`):!!c;if(s||l){window.showToast?window.showToast(`Primary Key cannot be nullable.`,`error`):alert(`Primary Key cannot be nullable.`);return}I({anchorEl:n,title:`Nullable Constraint`,placeholder:`Search constraint...`,items:[{name:`No`,value:`No`,desc:`NOT NULL constraint (Cannot be empty)`,icon:`lock`},{name:`Yes`,value:`Yes`,desc:`Allows NULL / empty values`,icon:`check`}],initialValue:a===`1`||a===`Yes`?`Yes`:`No`,onSelect:e=>{window.SchemaGrid.currentTransaction=[],qe(n,e,t),window.SchemaGrid.currentTransaction.length>0&&window.SchemaGrid.history.push(window.SchemaGrid.currentTransaction),window.SchemaGrid.currentTransaction=null}});return}else if(r===`isUnique`){let e=n.dataset.pk,r=window.SchemaGrid?.schema?.find(t=>t.name===e),o=window.SchemaGrid?.pendingEdits?.[e]?.isPk,s=o===void 0?r?r.isPk:!1:typeof o==`string`?o.includes(`PK`)||o.includes(`PFK`):!!o,c=i&&window.SchemaGrid?.pendingInserts?.[parseInt(n.dataset.insertIndex,10)]?.isPk,l=typeof c==`string`?c.includes(`PK`)||c.includes(`PFK`):!!c;if(s||l){window.showToast?window.showToast(`Primary Key is always unique and locked.`,`error`):alert(`Primary Key is always unique and locked.`);return}I({anchorEl:n,title:`Unique Constraint`,placeholder:`Search constraint...`,items:[{name:`No`,value:`No`,desc:`Duplicate values allowed`,icon:`close`},{name:`Yes`,value:`Yes`,desc:`Enforces UNIQUE constraint`,icon:`verified`}],initialValue:a===`1`||a===`Yes`?`Yes`:`No`,onSelect:e=>{window.SchemaGrid.currentTransaction=[],qe(n,e,t),window.SchemaGrid.currentTransaction.length>0&&window.SchemaGrid.history.push(window.SchemaGrid.currentTransaction),window.SchemaGrid.currentTransaction=null}});return}else if(r===`type`){let e=n.dataset.pk,r=window.SchemaGrid?.schema?.find(t=>t.name===e);te({anchorEl:n,initialValue:a,dialect:window.AppState?.dbType,onSelect:e=>{if(e===`ENUM`){setTimeout(()=>$e(n,r),10);return}window.SchemaGrid.currentTransaction=[],qe(n,e,t),window.SchemaGrid.currentTransaction.length>0&&window.SchemaGrid.history.push(window.SchemaGrid.currentTransaction),window.SchemaGrid.currentTransaction=null}});return}else o=document.createElement(`input`),o.type=`text`,o.value=a;n.innerHTML=``,n.classList.add(`cell-editing`),n.appendChild(o),o.addEventListener(`keydown`,e=>{e.key===`Enter`&&o.blur(),e.key===`Tab`&&(e.preventDefault(),o.blur(),document.body.dispatchEvent(new KeyboardEvent(`keydown`,{key:`Tab`,shiftKey:e.shiftKey,bubbles:!0})))}),o.focus();let s=()=>{n.classList.remove(`cell-editing`);let e=o.value;r===`type`&&e===`ENUM`||(window.SchemaGrid.currentTransaction=[],qe(n,e,t),window.SchemaGrid.currentTransaction.length>0&&window.SchemaGrid.history.push(window.SchemaGrid.currentTransaction),window.SchemaGrid.currentTransaction=null)};o.addEventListener(`blur`,()=>{s()})})}async function tt(e){let t=document.getElementById(`orm-export-modal`);t&&t.remove();let n=`prisma`,r=e||`*`,i=``;t=document.createElement(`div`),t.id=`orm-export-modal`,t.className=`modal-overlay`;let a=(window.AppState?.dbType||`database`).toUpperCase();t.innerHTML=`
1511
+ `;let o=e.querySelector(`#btn-data-error-retry`);o&&(o.onclick=()=>{G(n,r,i,!1,e)});let s=e.querySelector(`#btn-data-error-switch-db`);s&&(s.onclick=()=>{if(window.handleSwitchTab)window.handleSwitchTab(`connect-btn`);else{let e=document.getElementById(`connect-btn`)||document.getElementById(`header-connect-btn`);e&&e.click()}})}function Lt(e,t){e.addEventListener(`click`,e=>{if(e.target.closest(`.btn-manage-indexes`)||e.target.closest(`.manage-indexes-cell`)){ye();return}let t=e.target.closest(`.badge-enum`);if(t){let e=t.closest(`td.data-cell`);if(e){let t=e.dataset.pk,n=window.SchemaGrid?.schema?.find(e=>e.name===t);xe(e,n);return}}}),e.addEventListener(`dblclick`,e=>{let n=e.target.closest(`td.data-cell`);if(!n||n.querySelector(`input, select, textarea`))return;let r=n.dataset.colKey;if(r===`indexing`){ye();return}let i=n.dataset.insertIndex!==void 0,a=i||n.textContent===`-`||n.textContent===`+ New`||n.textContent.includes(`Add column`)||n.textContent.includes(`Add Column`)||n.textContent===`+ Add Row`||n.textContent===`null`?``:n.dataset.original!==void 0&&n.dataset.original!==`-`?n.dataset.original:n.textContent.trim().startsWith(`Yes`)?`1`:n.textContent.trim()===`No`?``:n.textContent.trim();if(r===`name`||r===`defaultValue`){ct({td:n,colName:r===`name`?`Column Name`:`Default Value`,colType:r===`name`?`VARCHAR`:`DEFAULT`,initialValue:a,onSave:e=>{window.SchemaGrid.currentTransaction=[],U(n,e,t),window.SchemaGrid.currentTransaction.length>0&&window.SchemaGrid.history.push(window.SchemaGrid.currentTransaction),window.SchemaGrid.currentTransaction=null}});return}let o;if(r===`isPk`){be(n,n.textContent);return}else if(r===`nullable`){let e=n.dataset.pk,r=window.SchemaGrid?.schema?.find(t=>t.name===e),o=window.SchemaGrid?.pendingEdits?.[e]?.isPk,s=o===void 0?r?r.isPk:!1:typeof o==`string`?o.includes(`PK`)||o.includes(`PFK`):!!o,c=i&&window.SchemaGrid?.pendingInserts?.[parseInt(n.dataset.insertIndex,10)]?.isPk,l=typeof c==`string`?c.includes(`PK`)||c.includes(`PFK`):!!c;if(s||l){window.showToast?window.showToast(`Primary Key cannot be nullable.`,`error`):alert(`Primary Key cannot be nullable.`);return}H({anchorEl:n,title:`Nullable Constraint`,placeholder:`Search constraint...`,items:[{name:`No`,value:`No`,desc:`NOT NULL constraint (Cannot be empty)`,icon:`lock`},{name:`Yes`,value:`Yes`,desc:`Allows NULL / empty values`,icon:`check`}],initialValue:a===`1`||a===`Yes`?`Yes`:`No`,onSelect:e=>{window.SchemaGrid.currentTransaction=[],U(n,e,t),window.SchemaGrid.currentTransaction.length>0&&window.SchemaGrid.history.push(window.SchemaGrid.currentTransaction),window.SchemaGrid.currentTransaction=null}});return}else if(r===`isUnique`){let e=n.dataset.pk,r=window.SchemaGrid?.schema?.find(t=>t.name===e),o=window.SchemaGrid?.pendingEdits?.[e]?.isPk,s=o===void 0?r?r.isPk:!1:typeof o==`string`?o.includes(`PK`)||o.includes(`PFK`):!!o,c=i&&window.SchemaGrid?.pendingInserts?.[parseInt(n.dataset.insertIndex,10)]?.isPk,l=typeof c==`string`?c.includes(`PK`)||c.includes(`PFK`):!!c;if(s||l){window.showToast?window.showToast(`Primary Key is always unique and locked.`,`error`):alert(`Primary Key is always unique and locked.`);return}H({anchorEl:n,title:`Unique Constraint`,placeholder:`Search constraint...`,items:[{name:`No`,value:`No`,desc:`Duplicate values allowed`,icon:`close`},{name:`Yes`,value:`Yes`,desc:`Enforces UNIQUE constraint`,icon:`verified`}],initialValue:a===`1`||a===`Yes`?`Yes`:`No`,onSelect:e=>{window.SchemaGrid.currentTransaction=[],U(n,e,t),window.SchemaGrid.currentTransaction.length>0&&window.SchemaGrid.history.push(window.SchemaGrid.currentTransaction),window.SchemaGrid.currentTransaction=null}});return}else if(r===`type`){let e=n.dataset.pk,r=window.SchemaGrid?.schema?.find(t=>t.name===e);pe({anchorEl:n,initialValue:a,dialect:window.AppState?.dbType,onSelect:e=>{if(e===`ENUM`){setTimeout(()=>xe(n,r),10);return}window.SchemaGrid.currentTransaction=[],U(n,e,t),window.SchemaGrid.currentTransaction.length>0&&window.SchemaGrid.history.push(window.SchemaGrid.currentTransaction),window.SchemaGrid.currentTransaction=null}});return}else o=document.createElement(`input`),o.type=`text`,o.value=a;n.innerHTML=``,n.classList.add(`cell-editing`),n.appendChild(o),o.addEventListener(`keydown`,e=>{e.key===`Enter`&&o.blur(),e.key===`Tab`&&(e.preventDefault(),o.blur(),document.body.dispatchEvent(new KeyboardEvent(`keydown`,{key:`Tab`,shiftKey:e.shiftKey,bubbles:!0})))}),o.focus();let s=()=>{n.classList.remove(`cell-editing`);let e=o.value;r===`type`&&e===`ENUM`||(window.SchemaGrid.currentTransaction=[],U(n,e,t),window.SchemaGrid.currentTransaction.length>0&&window.SchemaGrid.history.push(window.SchemaGrid.currentTransaction),window.SchemaGrid.currentTransaction=null)};o.addEventListener(`blur`,()=>{s()})})}async function Rt(e){let t=document.getElementById(`orm-export-modal`);t&&t.remove();let n=`prisma`,r=e||`*`,i=``;t=document.createElement(`div`),t.id=`orm-export-modal`,t.className=`modal-overlay`;let a=(window.AppState?.dbType||`database`).toUpperCase();t.innerHTML=`
1196
1512
  <div class="orm-modal-container">
1197
1513
  <div class="modal-header">
1198
1514
  <div class="flex items-center gap-2">
@@ -1248,7 +1564,7 @@
1248
1564
  <button type="button" id="close-orm-btn" class="btn-secondary">Close</button>
1249
1565
  </div>
1250
1566
  </div>
1251
- `,document.body.appendChild(t);let o=()=>{document.removeEventListener(`keydown`,s),t.remove()},s=e=>{e.key===`Escape`&&o()};document.addEventListener(`keydown`,s),t.addEventListener(`click`,e=>{e.target===t&&o()}),document.getElementById(`close-orm-modal-btn`).onclick=o,document.getElementById(`close-orm-btn`).onclick=o;let c=document.getElementById(`orm-code-display`),l=document.getElementById(`orm-file-name-label`),u=document.getElementById(`orm-copy-code-btn`),d=document.getElementById(`orm-copy-btn-text`),f=document.getElementById(`tab-orm-prisma`),p=document.getElementById(`tab-orm-drizzle`),m=document.getElementById(`orm-scope-select`),h=[];try{let e=await(await fetch(`/api/tables`)).json();e.success&&e.data&&(h=e.data)}catch{}let g=async()=>{c.textContent=`// Loading ${n===`prisma`?`Prisma`:`Drizzle`} schema...`,l.textContent=n===`prisma`?`schema.prisma`:`schema.ts`;try{let e=await(await fetch(`/api/generate-orm?target=${encodeURIComponent(n)}&table=${encodeURIComponent(r)}`)).json();e.success&&e.data?(i=e.data.code||``,c.textContent=i):c.textContent=`// Error generating schema:\n// ${e.error||`Unknown error`}`}catch(e){c.textContent=`// Failed to fetch ORM schema: ${e.message}`}};f.onclick=()=>{n!==`prisma`&&(n=`prisma`,f.classList.add(`active`),p.classList.remove(`active`),g())},p.onclick=()=>{n!==`drizzle`&&(n=`drizzle`,p.classList.add(`active`),f.classList.remove(`active`),g())},m.onclick=e=>{e.stopPropagation();let t=[{name:`All Tables (Database)`,value:`*`,icon:`database`},...h.map(e=>({name:`Table: ${e}`,value:e,icon:`table_chart`}))];I({anchorEl:m,title:`ORM Generation Scope`,searchable:h.length>4,placeholder:`Search tables...`,initialValue:r,items:t,onSelect:e=>{r=e;let t=document.getElementById(`orm-scope-display`);t&&(t.textContent=e===`*`?`All Tables (Database)`:`Table: ${e}`),g()}})},u.onclick=()=>{i&&(navigator.clipboard.writeText(i),d.textContent=`Copied!`,window.showToast&&window.showToast(`${n===`prisma`?`Prisma`:`Drizzle`} schema copied to clipboard!`,`success`),setTimeout(()=>{d.textContent=`Copy Code`},1800))},g()}function nt(){let e=document.getElementById(`schema-diff-modal`);e&&e.remove();let t=(window.AppState?.dbType||`database`).toUpperCase(),n=window.AppState?.dbName||`Current DB`,i=document.createElement(`div`);i.id=`schema-diff-modal`,i.className=`modal-overlay`,i.innerHTML=`
1567
+ `,document.body.appendChild(t);let o=()=>{document.removeEventListener(`keydown`,s),t.remove()},s=e=>{e.key===`Escape`&&o()};document.addEventListener(`keydown`,s),t.addEventListener(`click`,e=>{e.target===t&&o()}),document.getElementById(`close-orm-modal-btn`).onclick=o,document.getElementById(`close-orm-btn`).onclick=o;let c=document.getElementById(`orm-code-display`),l=document.getElementById(`orm-file-name-label`),u=document.getElementById(`orm-copy-code-btn`),d=document.getElementById(`orm-copy-btn-text`),f=document.getElementById(`tab-orm-prisma`),p=document.getElementById(`tab-orm-drizzle`),m=document.getElementById(`orm-scope-select`),h=[];try{let e=await(await fetch(`/api/tables`)).json();e.success&&e.data&&(h=e.data)}catch{}let g=async()=>{c.textContent=`// Loading ${n===`prisma`?`Prisma`:`Drizzle`} schema...`,l.textContent=n===`prisma`?`schema.prisma`:`schema.ts`;try{let e=await(await fetch(`/api/generate-orm?target=${encodeURIComponent(n)}&table=${encodeURIComponent(r)}`)).json();e.success&&e.data?(i=e.data.code||``,c.textContent=i):c.textContent=`// Error generating schema:\n// ${e.error||`Unknown error`}`}catch(e){c.textContent=`// Failed to fetch ORM schema: ${e.message}`}};f.onclick=()=>{n!==`prisma`&&(n=`prisma`,f.classList.add(`active`),p.classList.remove(`active`),g())},p.onclick=()=>{n!==`drizzle`&&(n=`drizzle`,p.classList.add(`active`),f.classList.remove(`active`),g())},m.onclick=e=>{e.stopPropagation();let t=[{name:`All Tables (Database)`,value:`*`,icon:`database`},...h.map(e=>({name:`Table: ${e}`,value:e,icon:`table_chart`}))];H({anchorEl:m,title:`ORM Generation Scope`,searchable:h.length>4,placeholder:`Search tables...`,initialValue:r,items:t,onSelect:e=>{r=e;let t=document.getElementById(`orm-scope-display`);t&&(t.textContent=e===`*`?`All Tables (Database)`:`Table: ${e}`),g()}})},u.onclick=()=>{i&&(navigator.clipboard.writeText(i),d.textContent=`Copied!`,window.showToast&&window.showToast(`${n===`prisma`?`Prisma`:`Drizzle`} schema copied to clipboard!`,`success`),setTimeout(()=>{d.textContent=`Copy Code`},1800))},g()}function zt(){let e=document.getElementById(`schema-diff-modal`);e&&e.remove();let t=(window.AppState?.dbType||`database`).toUpperCase(),n=window.AppState?.dbName||`Current DB`,r=document.createElement(`div`);r.id=`schema-diff-modal`,r.className=`modal-overlay`,r.innerHTML=`
1252
1568
  <div class="diff-modal-container" id="diff-container-box">
1253
1569
  <div class="modal-header">
1254
1570
  <div class="flex items-center gap-2">
@@ -1361,7 +1677,7 @@
1361
1677
  </div>
1362
1678
  </div>
1363
1679
  </div>
1364
- `,document.body.appendChild(i);let a=null,o=null,s=!1,c=document.getElementById(`diff-container-box`),l=document.getElementById(`close-diff-modal-btn`),u=document.getElementById(`close-diff-footer-btn`),d=document.getElementById(`tab-diff-file`),f=document.getElementById(`tab-diff-url`),p=document.getElementById(`diff-panel-file`),m=document.getElementById(`diff-panel-url`),h=document.getElementById(`diff-dropzone`),y=document.getElementById(`diff-file-input`),b=document.getElementById(`diff-file-info`),x=document.getElementById(`diff-target-url-input`),S=document.getElementById(`btn-run-diff`),C=document.getElementById(`btn-save-current-snapshot`),w=document.getElementById(`diff-results-wrap`),T=document.getElementById(`diff-stats-bar`),E=document.getElementById(`diff-tree-content`),D=document.getElementById(`diff-sql-preview`),O=document.getElementById(`btn-toggle-sql-direction`),k=document.getElementById(`btn-copy-diff-sql`),A=document.getElementById(`btn-download-diff-sql`),j=document.getElementById(`btn-apply-diff-migration`),M=document.getElementById(`diff-footer-hint`),N=()=>{document.removeEventListener(`keydown`,P),i.remove()},P=e=>{e.key===`Escape`&&N()};document.addEventListener(`keydown`,P),i.addEventListener(`click`,e=>{e.target===i&&N()}),l.onclick=N,u.onclick=N,C.onclick=()=>{v()},d.onclick=()=>{d.classList.add(`active`),f.classList.remove(`active`),p.classList.remove(`hidden`),m.classList.add(`hidden`)},f.onclick=()=>{f.classList.add(`active`),d.classList.remove(`active`),m.classList.remove(`hidden`),p.classList.add(`hidden`)},h.onclick=()=>y.click(),h.ondragover=e=>{e.preventDefault(),h.classList.add(`dragover`)},h.ondragleave=()=>h.classList.remove(`dragover`),h.ondrop=e=>{e.preventDefault(),h.classList.remove(`dragover`),e.dataTransfer.files&&e.dataTransfer.files.length>0&&F(e.dataTransfer.files[0])},y.onchange=e=>{e.target.files&&e.target.files.length>0&&F(e.target.files[0])};function F(e){if(!e.name.endsWith(`.json`)){alert(`Please select a valid .json schema snapshot file.`);return}let t=new FileReader;t.onload=async t=>{try{let n=JSON.parse(t.target.result);if(!n.tables||!Array.isArray(n.tables)){alert(`Invalid schema snapshot format. Missing tables array.`);return}a=n,b.textContent=`✔ Loaded "${e.name}" (${(e.size/1024).toFixed(1)} KB, ${n.tables.length} tables)`,b.classList.remove(`hidden`),await I({snapshot:a})}catch(e){alert(`Failed to parse snapshot JSON: ${e.message}`)}},t.readAsText(e)}x.oninput=()=>{S.disabled=!x.value.trim()},x.onkeydown=e=>{e.key===`Enter`&&x.value.trim()&&S.click()},S.onclick=async()=>{let e=x.value.trim();if(e){S.disabled=!0,S.innerHTML=`<span class="material-symbols-outlined spin" style="font-size: 16px;">sync</span><span>Comparing...</span>`;try{await I({targetUrl:e})}finally{S.disabled=!1,S.innerHTML=`<span class="material-symbols-outlined" style="font-size: 16px;">play_arrow</span><span>Compare</span>`}}};async function I(e){w.classList.remove(`hidden`),c.classList.add(`has-results`),T.innerHTML=`<div class="p-2 text-13" style="color: var(--color-text-secondary);">Comparing schemas...</div>`,E.innerHTML=`<div class="p-4 text-center text-13" style="color: var(--color-text-secondary);">Computing differences...</div>`,D.textContent=`-- Computing diff...`;try{let t=await g(e);if(!t.success){T.innerHTML=`<div class="diff-stat-error">✘ Diff Error: ${t.error}</div>`,E.innerHTML=``,D.textContent=`-- Diff failed:\n-- ${t.error}`;return}o=t.data,s=!1,L(o)}catch(e){T.innerHTML=`<div class="diff-stat-error">✘ Request failed: ${e.message}</div>`}}function L(e){let{diff:t,migrationSql:n,rollbackSql:r}=e,{stats:i}=t;if(!t.hasChanges){T.innerHTML=`
1680
+ `,document.body.appendChild(r);let a=null,o=null,s=!1,c=document.getElementById(`diff-container-box`),l=document.getElementById(`close-diff-modal-btn`),u=document.getElementById(`close-diff-footer-btn`),d=document.getElementById(`tab-diff-file`),f=document.getElementById(`tab-diff-url`),p=document.getElementById(`diff-panel-file`),m=document.getElementById(`diff-panel-url`),h=document.getElementById(`diff-dropzone`),g=document.getElementById(`diff-file-input`),_=document.getElementById(`diff-file-info`),v=document.getElementById(`diff-target-url-input`),y=document.getElementById(`btn-run-diff`),C=document.getElementById(`btn-save-current-snapshot`),w=document.getElementById(`diff-results-wrap`),T=document.getElementById(`diff-stats-bar`),E=document.getElementById(`diff-tree-content`),D=document.getElementById(`diff-sql-preview`),O=document.getElementById(`btn-toggle-sql-direction`),k=document.getElementById(`btn-copy-diff-sql`),A=document.getElementById(`btn-download-diff-sql`),j=document.getElementById(`btn-apply-diff-migration`),M=document.getElementById(`diff-footer-hint`),N=()=>{document.removeEventListener(`keydown`,ee),r.remove()},ee=e=>{e.key===`Escape`&&N()};document.addEventListener(`keydown`,ee),r.addEventListener(`click`,e=>{e.target===r&&N()}),l.onclick=N,u.onclick=N,C.onclick=()=>{S()},d.onclick=()=>{d.classList.add(`active`),f.classList.remove(`active`),p.classList.remove(`hidden`),m.classList.add(`hidden`)},f.onclick=()=>{f.classList.add(`active`),d.classList.remove(`active`),m.classList.remove(`hidden`),p.classList.add(`hidden`)},h.onclick=()=>g.click(),h.ondragover=e=>{e.preventDefault(),h.classList.add(`dragover`)},h.ondragleave=()=>h.classList.remove(`dragover`),h.ondrop=e=>{e.preventDefault(),h.classList.remove(`dragover`),e.dataTransfer.files&&e.dataTransfer.files.length>0&&te(e.dataTransfer.files[0])},g.onchange=e=>{e.target.files&&e.target.files.length>0&&te(e.target.files[0])};function te(e){if(!e.name.endsWith(`.json`)){alert(`Please select a valid .json schema snapshot file.`);return}let t=new FileReader;t.onload=async t=>{try{let n=JSON.parse(t.target.result);if(!n.tables||!Array.isArray(n.tables)){alert(`Invalid schema snapshot format. Missing tables array.`);return}a=n,_.textContent=`✔ Loaded "${e.name}" (${(e.size/1024).toFixed(1)} KB, ${n.tables.length} tables)`,_.classList.remove(`hidden`),await P({snapshot:a})}catch(e){alert(`Failed to parse snapshot JSON: ${e.message}`)}},t.readAsText(e)}v.oninput=()=>{y.disabled=!v.value.trim()},v.onkeydown=e=>{e.key===`Enter`&&v.value.trim()&&y.click()},y.onclick=async()=>{let e=v.value.trim();if(e){y.disabled=!0,y.innerHTML=`<span class="material-symbols-outlined spin" style="font-size: 16px;">sync</span><span>Comparing...</span>`;try{await P({targetUrl:e})}finally{y.disabled=!1,y.innerHTML=`<span class="material-symbols-outlined" style="font-size: 16px;">play_arrow</span><span>Compare</span>`}}};async function P(e){w.classList.remove(`hidden`),c.classList.add(`has-results`),T.innerHTML=`<div class="p-2 text-13" style="color: var(--color-text-secondary);">Comparing schemas...</div>`,E.innerHTML=`<div class="p-4 text-center text-13" style="color: var(--color-text-secondary);">Computing differences...</div>`,D.textContent=`-- Computing diff...`;try{let t=await b(e);if(!t.success){T.innerHTML=`<div class="diff-stat-error">✘ Diff Error: ${t.error}</div>`,E.innerHTML=``,D.textContent=`-- Diff failed:\n-- ${t.error}`;return}o=t.data,s=!1,F(o)}catch(e){T.innerHTML=`<div class="diff-stat-error">✘ Request failed: ${e.message}</div>`}}function F(e){let{diff:t,migrationSql:n,rollbackSql:r}=e,{stats:i}=t;if(!t.hasChanges){T.innerHTML=`
1365
1681
  <div class="diff-stat-item clean">
1366
1682
  <span class="material-symbols-outlined" style="color: #10b981;">check_circle</span>
1367
1683
  <span>Schemas are identical! No migration required.</span>
@@ -1408,7 +1724,7 @@
1408
1724
  ${e.droppedIndexes.map(e=>`<div class="diff-item dropped">- DROP INDEX ${e.name||`unnamed`}</div>`).join(``)}
1409
1725
  </div>
1410
1726
  </div>
1411
- `);E.innerHTML=a,R()}function R(){if(!o)return;let e=s?o.rollbackSql:o.migrationSql;D.textContent=e,document.getElementById(`diff-sql-title`).textContent=s?`Rollback SQL (Down)`:`Migration SQL (Up)`,document.getElementById(`sql-direction-label`).textContent=s?`Migration (Up)`:`Rollback (Down)`}O.onclick=()=>{s=!s,R()},k.onclick=async()=>{let e=D.textContent;try{await navigator.clipboard.writeText(e);let t=k.querySelector(`span:last-child`),n=t.textContent;t.textContent=`Copied!`,setTimeout(()=>{t.textContent=n},1800)}catch{alert(`Failed to copy to clipboard.`)}},A.onclick=()=>{let e=D.textContent,t=new Blob([e],{type:`application/sql`}),n=URL.createObjectURL(t),r=document.createElement(`a`);r.href=n,r.download=`migration_${new Date().toISOString().replace(/[:.]/g,`-`)}.sql`,document.body.appendChild(r),r.click(),document.body.removeChild(r),URL.revokeObjectURL(n)},j.onclick=async()=>{let e=D.textContent;if(!(!e||!o?.diff?.hasChanges)&&confirm(`Are you sure you want to execute this ${s?`ROLLBACK`:`MIGRATION`} script against the current database?\n\nThis will execute DDL statements immediately!`)){j.disabled=!0,j.innerHTML=`<span class="material-symbols-outlined spin" style="font-size: 16px;">sync</span><span>Applying...</span>`;try{let t=await _(e);t.success?(alert(`✔ Migration applied successfully to the database!`),await r(),i.remove(),window.renderSchemaGrid&&window.location.reload()):alert(`✘ Migration execution failed: ${t.error}`)}catch(e){alert(`✘ Migration failed: ${e.message}`)}finally{j.disabled=!1,j.innerHTML=`<span class="material-symbols-outlined" style="font-size: 16px;">bolt</span><span>Apply Migration</span>`}}}}async function rt(e,t,n=null){document.querySelectorAll(`.table-btn`).forEach(e=>e.classList.remove(`active`)),t&&t.classList.add(`active`);let r=document.getElementById(`table-name`);r&&(r.textContent=e+` (Schema)`);let i=n||document.getElementById(`main-content`);i.innerHTML=`<div class='p-6'>Loading Schema...</div>`;try{let[r,a]=await Promise.all([c(e),l(e)]);if(r.success&&r.data){let o=r.data,s=a.success&&a.data?a.data:[];window.SchemaGrid={schema:o,indexes:s,pendingEdits:{},pendingIndexEdits:{added:[],dropped:[]},pendingInserts:[{}],pendingDeletes:new Set,selectedCell:null,history:[],currentTransaction:null,sortState:{colKey:null,asc:!0},filterText:``,isResizing:!1,selection:{startRow:-1,startCol:-1,endRow:-1,endCol:-1,isDragging:!1}},window.TableStates&&window.TableStates[e]&&(window.TableStates[e].schemaGrid=window.SchemaGrid),i.innerHTML=`
1727
+ `);E.innerHTML=a,I()}function I(){if(!o)return;let e=s?o.rollbackSql:o.migrationSql;D.textContent=e,document.getElementById(`diff-sql-title`).textContent=s?`Rollback SQL (Down)`:`Migration SQL (Up)`,document.getElementById(`sql-direction-label`).textContent=s?`Migration (Up)`:`Rollback (Down)`}O.onclick=()=>{s=!s,I()},k.onclick=async()=>{let e=D.textContent;try{await navigator.clipboard.writeText(e);let t=k.querySelector(`span:last-child`),n=t.textContent;t.textContent=`Copied!`,setTimeout(()=>{t.textContent=n},1800)}catch{alert(`Failed to copy to clipboard.`)}},A.onclick=()=>{let e=D.textContent,t=new Blob([e],{type:`application/sql`}),n=URL.createObjectURL(t),r=document.createElement(`a`);r.href=n,r.download=`migration_${new Date().toISOString().replace(/[:.]/g,`-`)}.sql`,document.body.appendChild(r),r.click(),document.body.removeChild(r),URL.revokeObjectURL(n)},j.onclick=async()=>{let e=D.textContent;if(!(!e||!o?.diff?.hasChanges)&&confirm(`Are you sure you want to execute this ${s?`ROLLBACK`:`MIGRATION`} script against the current database?\n\nThis will execute DDL statements immediately!`)){j.disabled=!0,j.innerHTML=`<span class="material-symbols-outlined spin" style="font-size: 16px;">sync</span><span>Applying...</span>`;try{let t=await x(e);t.success?(alert(`✔ Migration applied successfully to the database!`),await i(),r.remove(),window.renderSchemaGrid&&window.location.reload()):alert(`✘ Migration execution failed: ${t.error}`)}catch(e){alert(`✘ Migration failed: ${e.message}`)}finally{j.disabled=!1,j.innerHTML=`<span class="material-symbols-outlined" style="font-size: 16px;">bolt</span><span>Apply Migration</span>`}}}}async function Bt(e,t,n=null){document.querySelectorAll(`.table-btn`).forEach(e=>e.classList.remove(`active`)),t&&t.classList.add(`active`);let r=document.getElementById(`table-name`);r&&(r.textContent=e+` (Schema)`);let i=n||document.getElementById(`main-content`);i.innerHTML=`<div class='p-6'>Loading Schema...</div>`;try{let[r,a]=await Promise.all([u(e),d(e)]);if(r.success&&r.data){let o=r.data,s=a.success&&a.data?a.data:[];window.SchemaGrid={schema:o,indexes:s,pendingEdits:{},pendingIndexEdits:{added:[],dropped:[]},pendingInserts:[{}],pendingDeletes:new Set,selectedCell:null,history:[],currentTransaction:null,sortState:{colKey:null,asc:!0},filterText:``,isResizing:!1,selection:{startRow:-1,startCol:-1,endRow:-1,endCol:-1,isDragging:!1}},window.TableStates&&window.TableStates[e]&&(window.TableStates[e].schemaGrid=window.SchemaGrid),i.innerHTML=`
1412
1728
  <div class="toolbar">
1413
1729
  <div class="filter-bar-container" style="max-width: 320px; position: relative;">
1414
1730
  <div class="filter-bar-input-box" id="schema-search-box-${e}">
@@ -1434,6 +1750,10 @@
1434
1750
  <div class="schema-autocomplete-popover hidden" id="schema-search-popover-${e}"></div>
1435
1751
  </div>
1436
1752
  <div class="flex-1"></div>
1753
+ <button type="button" id="btn-rename-table-${e}" class="header-btn secondary" style="height: 30px; font-size: 12px; gap: 6px; padding: 0 12px;" title="Rename Table">
1754
+ <span class="material-symbols-outlined" style="font-size: 16px; color: var(--color-primary);">edit_note</span>
1755
+ <span>Rename Table</span>
1756
+ </button>
1437
1757
  <button type="button" id="btn-export-orm-${e}" class="header-btn secondary" style="height: 30px; font-size: 12px; gap: 6px; padding: 0 12px;" title="Export Prisma / Drizzle ORM Schema">
1438
1758
  <span class="material-symbols-outlined" style="font-size: 16px; color: var(--color-primary);">bolt</span>
1439
1759
  <span>Export ORM</span>
@@ -1486,7 +1806,7 @@
1486
1806
  <span class="index-count-pill">${Math.max(0,o)}</span>
1487
1807
  </button>
1488
1808
  </div>
1489
- </td>`}return}let o=``,s=``;if(r===`name`)s=String(e.name||``).replace(/"/g,`&quot;`),o=`<span class="cell-text">${String(e.name||``).replace(/</g,`&lt;`)}</span>`;else if(r===`type`){s=String(e.type||``).replace(/"/g,`&quot;`);let t=e.enumValues&&e.enumValues.length>0?` <span class="badge-enum" style="font-size: 10px; padding: 1px 5px; border-radius: 4px; background: rgba(59, 130, 246, 0.15); color: var(--color-primary); border: 1px solid rgba(59, 130, 246, 0.3); margin-left: 4px; cursor: pointer;" title="Configured Enum values: ${e.enumValues.join(`, `)}">ENUM</span>`:``;o=`<span class="schema-type-mono">${String(e.type||``).replace(/</g,`&lt;`)}</span>${t}`}else if(r===`isPk`){let t=!!e.isPk,n=!!e.fkTarget;if(t&&n){let t=e.fkTarget.onDelete&&e.fkTarget.onDelete!==`NO ACTION`?` (${e.fkTarget.onDelete})`:``,n=[e.fkTarget.onDelete?`ON DELETE ${e.fkTarget.onDelete}`:``,e.fkTarget.onUpdate?`ON UPDATE ${e.fkTarget.onUpdate}`:``].filter(Boolean).join(`, `),r=`Primary Foreign Key (Composite Key referencing ${e.fkTarget.table}.${e.fkTarget.column}${n?` [${n}]`:``})`;s=`PFK: ${e.fkTarget.table}.${e.fkTarget.column}${t}`,o=`<span class="col-badge badge-pfk" title="${r}">PFK &rarr; ${e.fkTarget.table}.${e.fkTarget.column}${t}</span>`}else if(t)s=`PK`,o=`<span class="col-badge badge-pk">PK</span>`;else if(n){let t=e.fkTarget.onDelete&&e.fkTarget.onDelete!==`NO ACTION`?` (${e.fkTarget.onDelete})`:``,n=[e.fkTarget.onDelete?`ON DELETE ${e.fkTarget.onDelete}`:``,e.fkTarget.onUpdate?`ON UPDATE ${e.fkTarget.onUpdate}`:``].filter(Boolean).join(`, `),r=`References ${e.fkTarget.table}.${e.fkTarget.column}${n?` [${n}]`:``}`;s=`FK: ${e.fkTarget.table}.${e.fkTarget.column}${t}`,o=`<span class="col-badge badge-fk" title="${r}">FK &rarr; ${e.fkTarget.table}.${e.fkTarget.column}${t}</span>`}else s=`-`,o=`<span class="text-soft">-</span>`}else if(r===`nullable`){let t=!!e.isPk,n=!t&&!!e.nullable;s=n?`Yes`:`No`,o=t?`<span class="badge-bool bool-false badge-locked" title="Primary Key cannot be nullable"><span class="material-symbols-outlined" style="font-size: 11px;">lock</span> No</span>`:n?`<span class="badge-bool bool-true">Yes</span>`:`<span class="badge-bool bool-false">No</span>`}else if(r===`isUnique`){let t=!!e.isPk,n=t||!!e.isUnique;s=n?`Yes`:`No`,o=t?`<span class="badge-unique-pk" title="Primary Key is always unique"><span class="material-symbols-outlined" style="font-size: 11px;">lock</span> Yes</span>`:n?`<span class="badge-unique">Yes</span>`:`<span class="text-soft">-</span>`}else if(r===`defaultValue`){let t=e.defaultValue;typeof t==`string`&&t.startsWith(`'''`)&&t.endsWith(`'''`)&&(t=t.slice(2,-2)),s=String(t??``).replace(/"/g,`&quot;`),o=t!=null&&t!==``?`<span class="cell-text text-soft">${String(t).replace(/</g,`&lt;`)}</span>`:`<span class="text-soft">-</span>`}a+=`<td class="data-cell" data-row-idx="${t}" data-col-idx="${i}" data-pk="${e.name}" data-col-key="${r}" data-original="${s}">${o}</td>`}),a+=`</tr>`}),a+=`<tr class="ghost-row-tr">`;let o=n?n.length:0;a+=`<td class="row-header" data-row-idx="${o}">*</td>`,i.forEach((e,t)=>{e!==`indexing`&&(a+=`<td class="data-cell ghost-row" data-row-idx="${o}" data-col-idx="${t}" data-insert-index="0" data-col-key="${e}">${t===0?`<span class="ghost-cell-hint">+ Add Column</span>`:``}</td>`)}),a+=`</tr></tbody></table>`,t.innerHTML=a,document.querySelectorAll(`#schema-grid-table-${e} th.sortable`).forEach(e=>{let t=e.dataset.colKey,n=r.find(e=>e.key===t),i=()=>Object.keys(window.SchemaGrid.pendingEdits||{}).length>0||(window.SchemaGrid.pendingInserts||[]).length>1||window.SchemaGrid.pendingDeletes&&window.SchemaGrid.pendingDeletes.size>0||(window.SchemaGrid.pendingIndexEdits?.added||[]).length>0||(window.SchemaGrid.pendingIndexEdits?.dropped||[]).length>0?(window.showToast?window.showToast(`You have unsaved changes! Please press Ctrl+S to save them before sorting.`,`warning`):alert(`You have unsaved changes! Please press Ctrl+S to save them before sorting.`),!1):!0,a=e=>{i()&&(window.SchemaGrid.sortState.colKey=t,window.SchemaGrid.sortState.asc=e,window.SchemaGrid.selection={startRow:-1,startCol:-1,endRow:-1,endCol:-1,isDragging:!1},window.renderSchemaGrid(),window.showToast&&window.showToast(`Sorted by ${n?n.label:t} (${e?`Ascending`:`Descending`})`,`info`))},o=()=>{i()&&(window.SchemaGrid.sortState.colKey=null,window.SchemaGrid.sortState.asc=!0,window.SchemaGrid.selection={startRow:-1,startCol:-1,endRow:-1,endCol:-1,isDragging:!1},window.renderSchemaGrid(),window.showToast&&window.showToast(`Cleared sort on "${n?n.label:t}"`,`info`))},s=r=>{if(window.SchemaGrid.isResizing||r.target.closest(`.resizer`))return;let i=window.SchemaGrid.sortState.colKey===t,s=i&&window.SchemaGrid.sortState.asc,c=[{icon:`arrow_upward`,label:`Sort Ascending`,checked:i&&s,action:()=>a(!0)},{icon:`arrow_downward`,label:`Sort Descending`,checked:i&&!s,action:()=>a(!1)}];i&&c.push({icon:`restart_alt`,label:`Clear Sort`,action:()=>o()}),c.push(`divider`,{icon:`content_copy`,label:`Copy name`,action:async()=>{let e=n?n.label:t;try{await navigator.clipboard.writeText(e)}catch{let t=document.createElement(`textarea`);t.value=e,document.body.appendChild(t),t.select(),document.execCommand(`copy`),t.remove()}window.showToast&&window.showToast(`Copied "${e}" to clipboard!`,`success`)}});let l=e.querySelector(`.th-menu-trigger`),u=e.getBoundingClientRect(),d=r&&r.type===`contextmenu`,f=u.left,p=u.bottom+4;if(l){let e=l.getBoundingClientRect();f=e.left,p=e.bottom+4}d&&r&&typeof r.clientX==`number`&&(f=r.clientX,p=r.clientY),A({clientX:f,clientY:p,preventDefault:()=>{},stopPropagation:()=>{}},c)};e.onclick=s,e.oncontextmenu=e=>{e.preventDefault(),s(e)},ve(e,window.SchemaGrid)}),_e(t,`schema-grid-table-${e}`,window.SchemaGrid,i.length-1),et(t,i);let s=document.getElementById(`th-schema-row-header-${e}`);s&&s.addEventListener(`click`,t=>{t.preventDefault(),t.stopPropagation(),ge(`schema-grid-table-${e}`,window.SchemaGrid,i.length-1)})},window.renderSchemaGrid();let c=document.getElementById(`schema-search-val-${e}`),l=document.getElementById(`btn-clear-schema-search-${e}`),u=document.getElementById(`schema-search-popover-${e}`),d=-1,f=[],p=()=>{!l||!c||(c.value.trim()===``?l.classList.add(`hidden`):l.classList.remove(`hidden`))},m=()=>{u&&(u.classList.add(`hidden`),u.innerHTML=``),d=-1,f=[]},h=e=>String(e).replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`).replace(/"/g,`&quot;`),g=(e,t)=>{if(!t)return h(e);let n=e.toLowerCase(),r=t.toLowerCase(),i=n.indexOf(r);return i===-1?h(e):`${h(e.slice(0,i))}<span class="schema-autocomplete-match-highlight">${h(e.slice(i,i+t.length))}</span>${h(e.slice(i+t.length))}`},_=e=>{c&&(c.value=e,window.SchemaGrid.filterText=e,p(),window.SchemaGrid.selection={startRow:-1,startCol:-1,endRow:-1,endCol:-1,isDragging:!1},window.renderSchemaGrid(),m(),c.focus())},v=()=>{if(!u||!c)return;let e=c.value.trim().toLowerCase(),t=window.SchemaGrid?.schema||[],n=Array.from(new Set(t.map(e=>e.name).filter(Boolean))),r=Array.from(new Set(t.map(e=>e.type).filter(Boolean))),i=e?n.filter(t=>t.toLowerCase().includes(e)):n.slice(0,6),a=e?r.filter(t=>t.toLowerCase().includes(e)):r.slice(0,4);if(f=[...i.map(e=>({text:e,type:`column`,icon:`view_column`,badge:`Column`})),...a.map(e=>({text:e,type:`type`,icon:`data_object`,badge:`Type`}))],f.length===0){u.innerHTML=`
1809
+ </td>`}return}let o=``,s=``;if(r===`name`)s=String(e.name||``).replace(/"/g,`&quot;`),o=`<span class="cell-text">${String(e.name||``).replace(/</g,`&lt;`)}</span>`;else if(r===`type`){s=String(e.type||``).replace(/"/g,`&quot;`);let t=e.enumValues&&e.enumValues.length>0?` <span class="badge-enum" style="font-size: 10px; padding: 1px 5px; border-radius: 4px; background: rgba(59, 130, 246, 0.15); color: var(--color-primary); border: 1px solid rgba(59, 130, 246, 0.3); margin-left: 4px; cursor: pointer;" title="Configured Enum values: ${e.enumValues.join(`, `)}">ENUM</span>`:``;o=`<span class="schema-type-mono">${String(e.type||``).replace(/</g,`&lt;`)}</span>${t}`}else if(r===`isPk`){let t=!!e.isPk,n=!!e.fkTarget;if(t&&n){let t=e.fkTarget.onDelete&&e.fkTarget.onDelete!==`NO ACTION`?` (${e.fkTarget.onDelete})`:``,n=[e.fkTarget.onDelete?`ON DELETE ${e.fkTarget.onDelete}`:``,e.fkTarget.onUpdate?`ON UPDATE ${e.fkTarget.onUpdate}`:``].filter(Boolean).join(`, `),r=`Primary Foreign Key (Composite Key referencing ${e.fkTarget.table}.${e.fkTarget.column}${n?` [${n}]`:``})`;s=`PFK: ${e.fkTarget.table}.${e.fkTarget.column}${t}`,o=`<span class="col-badge badge-pfk" title="${r}">PFK &rarr; ${e.fkTarget.table}.${e.fkTarget.column}${t}</span>`}else if(t)s=`PK`,o=`<span class="col-badge badge-pk">PK</span>`;else if(n){let t=e.fkTarget.onDelete&&e.fkTarget.onDelete!==`NO ACTION`?` (${e.fkTarget.onDelete})`:``,n=[e.fkTarget.onDelete?`ON DELETE ${e.fkTarget.onDelete}`:``,e.fkTarget.onUpdate?`ON UPDATE ${e.fkTarget.onUpdate}`:``].filter(Boolean).join(`, `),r=`References ${e.fkTarget.table}.${e.fkTarget.column}${n?` [${n}]`:``}`;s=`FK: ${e.fkTarget.table}.${e.fkTarget.column}${t}`,o=`<span class="col-badge badge-fk" title="${r}">FK &rarr; ${e.fkTarget.table}.${e.fkTarget.column}${t}</span>`}else s=`-`,o=`<span class="text-soft">-</span>`}else if(r===`nullable`){let t=!!e.isPk,n=!t&&!!e.nullable;s=n?`Yes`:`No`,o=t?`<span class="badge-bool bool-false badge-locked" title="Primary Key cannot be nullable"><span class="material-symbols-outlined" style="font-size: 11px;">lock</span> No</span>`:n?`<span class="badge-bool bool-true">Yes</span>`:`<span class="badge-bool bool-false">No</span>`}else if(r===`isUnique`){let t=!!e.isPk,n=t||!!e.isUnique;s=n?`Yes`:`No`,o=t?`<span class="badge-unique-pk" title="Primary Key is always unique"><span class="material-symbols-outlined" style="font-size: 11px;">lock</span> Yes</span>`:n?`<span class="badge-unique">Yes</span>`:`<span class="text-soft">-</span>`}else if(r===`defaultValue`){let t=e.defaultValue;typeof t==`string`&&t.startsWith(`'''`)&&t.endsWith(`'''`)&&(t=t.slice(2,-2)),s=String(t??``).replace(/"/g,`&quot;`),o=t!=null&&t!==``?`<span class="cell-text text-soft">${String(t).replace(/</g,`&lt;`)}</span>`:`<span class="text-soft">-</span>`}a+=`<td class="data-cell" data-row-idx="${t}" data-col-idx="${i}" data-pk="${e.name}" data-col-key="${r}" data-original="${s}">${o}</td>`}),a+=`</tr>`}),a+=`<tr class="ghost-row-tr">`;let o=n?n.length:0;a+=`<td class="row-header" data-row-idx="${o}">*</td>`,i.forEach((e,t)=>{e!==`indexing`&&(a+=`<td class="data-cell ghost-row" data-row-idx="${o}" data-col-idx="${t}" data-insert-index="0" data-col-key="${e}">${t===0?`<span class="ghost-cell-hint">+ Add Column</span>`:``}</td>`)}),a+=`</tr></tbody></table>`,t.innerHTML=a,document.querySelectorAll(`#schema-grid-table-${e} th.sortable`).forEach(e=>{let t=e.dataset.colKey,n=r.find(e=>e.key===t),i=()=>Object.keys(window.SchemaGrid.pendingEdits||{}).length>0||(window.SchemaGrid.pendingInserts||[]).length>1||window.SchemaGrid.pendingDeletes&&window.SchemaGrid.pendingDeletes.size>0||(window.SchemaGrid.pendingIndexEdits?.added||[]).length>0||(window.SchemaGrid.pendingIndexEdits?.dropped||[]).length>0?(window.showToast?window.showToast(`You have unsaved changes! Please press Ctrl+S to save them before sorting.`,`warning`):alert(`You have unsaved changes! Please press Ctrl+S to save them before sorting.`),!1):!0,a=e=>{i()&&(window.SchemaGrid.sortState.colKey=t,window.SchemaGrid.sortState.asc=e,window.SchemaGrid.selection={startRow:-1,startCol:-1,endRow:-1,endCol:-1,isDragging:!1},window.renderSchemaGrid(),window.showToast&&window.showToast(`Sorted by ${n?n.label:t} (${e?`Ascending`:`Descending`})`,`info`))},o=()=>{i()&&(window.SchemaGrid.sortState.colKey=null,window.SchemaGrid.sortState.asc=!0,window.SchemaGrid.selection={startRow:-1,startCol:-1,endRow:-1,endCol:-1,isDragging:!1},window.renderSchemaGrid(),window.showToast&&window.showToast(`Cleared sort on "${n?n.label:t}"`,`info`))},s=r=>{if(window.SchemaGrid.isResizing||r.target.closest(`.resizer`))return;let i=window.SchemaGrid.sortState.colKey===t,s=i&&window.SchemaGrid.sortState.asc,c=[{icon:`arrow_upward`,label:`Sort Ascending`,checked:i&&s,action:()=>a(!0)},{icon:`arrow_downward`,label:`Sort Descending`,checked:i&&!s,action:()=>a(!1)}];i&&c.push({icon:`restart_alt`,label:`Clear Sort`,action:()=>o()}),c.push(`divider`,{icon:`content_copy`,label:`Copy name`,action:async()=>{let e=n?n.label:t;try{await navigator.clipboard.writeText(e)}catch{let t=document.createElement(`textarea`);t.value=e,document.body.appendChild(t),t.select(),document.execCommand(`copy`),t.remove()}window.showToast&&window.showToast(`Copied "${e}" to clipboard!`,`success`)}});let l=e.querySelector(`.th-menu-trigger`),u=e.getBoundingClientRect(),d=r&&r.type===`contextmenu`,f=u.left,p=u.bottom+4;if(l){let e=l.getBoundingClientRect();f=e.left,p=e.bottom+4}d&&r&&typeof r.clientX==`number`&&(f=r.clientX,p=r.clientY),V({clientX:f,clientY:p,preventDefault:()=>{},stopPropagation:()=>{}},c)};e.onclick=s,e.oncontextmenu=e=>{e.preventDefault(),s(e)},Ge(e,window.SchemaGrid)}),We(t,`schema-grid-table-${e}`,window.SchemaGrid,i.length-1),Lt(t,i);let s=document.getElementById(`th-schema-row-header-${e}`);s&&s.addEventListener(`click`,t=>{t.preventDefault(),t.stopPropagation(),Ue(`schema-grid-table-${e}`,window.SchemaGrid,i.length-1)})},window.renderSchemaGrid();let c=document.getElementById(`schema-search-val-${e}`),l=document.getElementById(`btn-clear-schema-search-${e}`),u=document.getElementById(`schema-search-popover-${e}`),d=-1,f=[],p=()=>{!l||!c||(c.value.trim()===``?l.classList.add(`hidden`):l.classList.remove(`hidden`))},m=()=>{u&&(u.classList.add(`hidden`),u.innerHTML=``),d=-1,f=[]},h=e=>String(e).replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`).replace(/"/g,`&quot;`),g=(e,t)=>{if(!t)return h(e);let n=e.toLowerCase(),r=t.toLowerCase(),i=n.indexOf(r);return i===-1?h(e):`${h(e.slice(0,i))}<span class="schema-autocomplete-match-highlight">${h(e.slice(i,i+t.length))}</span>${h(e.slice(i+t.length))}`},_=e=>{c&&(c.value=e,window.SchemaGrid.filterText=e,p(),window.SchemaGrid.selection={startRow:-1,startCol:-1,endRow:-1,endCol:-1,isDragging:!1},window.renderSchemaGrid(),m(),c.focus())},v=()=>{if(!u||!c)return;let e=c.value.trim().toLowerCase(),t=window.SchemaGrid?.schema||[],n=Array.from(new Set(t.map(e=>e.name).filter(Boolean))),r=Array.from(new Set(t.map(e=>e.type).filter(Boolean))),i=e?n.filter(t=>t.toLowerCase().includes(e)):n.slice(0,6),a=e?r.filter(t=>t.toLowerCase().includes(e)):r.slice(0,4);if(f=[...i.map(e=>({text:e,type:`column`,icon:`view_column`,badge:`Column`})),...a.map(e=>({text:e,type:`type`,icon:`data_object`,badge:`Type`}))],f.length===0){u.innerHTML=`
1490
1810
  <div class="schema-autocomplete-empty">
1491
1811
  <span>No matching columns or data types</span>
1492
1812
  </div>
@@ -1506,7 +1826,7 @@
1506
1826
  </div>
1507
1827
  <span class="schema-autocomplete-type-badge">Type</span>
1508
1828
  </div>
1509
- `})),o+=`</div>`,u.innerHTML=o,u.classList.remove(`hidden`),u.querySelectorAll(`.schema-autocomplete-item`).forEach(e=>{e.addEventListener(`mousedown`,t=>{t.preventDefault();let n=parseInt(e.dataset.suggestionIdx,10);f[n]&&_(f[n].text)})})},y=()=>{u&&u.querySelectorAll(`.schema-autocomplete-item`).forEach((e,t)=>{t===d?(e.classList.add(`active`),e.scrollIntoView({block:`nearest`})):e.classList.remove(`active`)})};c&&(c.addEventListener(`input`,e=>{window.SchemaGrid.filterText=e.target.value,p(),window.SchemaGrid.selection={startRow:-1,startCol:-1,endRow:-1,endCol:-1,isDragging:!1},window.renderSchemaGrid(),v()}),c.addEventListener(`focus`,()=>{v()}),c.addEventListener(`keydown`,e=>{u&&!u.classList.contains(`hidden`)&&f.length>0&&(e.key===`ArrowDown`?(e.preventDefault(),d=(d+1)%f.length,y()):e.key===`ArrowUp`?(e.preventDefault(),d=(d-1+f.length)%f.length,y()):e.key===`Enter`?d>=0&&f[d]&&(e.preventDefault(),_(f[d].text)):e.key===`Escape`&&(e.preventDefault(),m()))}));let b=c?.closest(`.filter-bar-input-box`);b&&c&&b.addEventListener(`click`,e=>{e.target.closest(`.filter-bar-clear-btn`)||c.focus()}),l&&(l.onclick=()=>{c&&(c.value=``,window.SchemaGrid.filterText=``,p(),m(),window.renderSchemaGrid(),c.focus())}),document.addEventListener(`click`,e=>{u&&!u.contains(e.target)&&c&&!c.contains(e.target)&&m()});let x=document.getElementById(`btn-export-orm-${e}`);x&&(x.onclick=()=>tt(e));let S=document.getElementById(`btn-schema-diff-${e}`);S&&(S.onclick=()=>nt());let C=document.getElementById(`btn-refresh-schema-${e}`);C&&(C.onclick=()=>{(Object.keys(window.SchemaGrid.pendingEdits).length>0||window.SchemaGrid.pendingInserts.length>1||window.SchemaGrid.pendingDeletes.size>0||window.SchemaGrid.pendingIndexEdits.added.length>0||window.SchemaGrid.pendingIndexEdits.dropped.length>0)&&!confirm(`You have unsaved changes. Are you sure you want to refresh and discard them?`)||(window.SchemaGrid.pendingEdits={},window.SchemaGrid.pendingInserts=[{}],window.SchemaGrid.pendingDeletes.clear(),window.SchemaGrid.pendingIndexEdits={added:[],dropped:[]},window.SchemaGrid.history=[],window.SchemaGrid.currentTransaction=null,window.updateSidebarDirtyState?.(),rt(e,t,n))})}else i.innerHTML=`<div class="p-6 text-error">Error: ${r.error}</div>`}catch(e){i.innerHTML=`<div class="p-6 text-error">Failed to load schema: ${e.message}</div>`}}var it=()=>localStorage.getItem(`drixio_safe_mode_disabled`)!==`true`,at=e=>{e?localStorage.removeItem(`drixio_safe_mode_disabled`):localStorage.setItem(`drixio_safe_mode_disabled`,`true`),window.dispatchEvent(new CustomEvent(`drixio-safemode-changed`,{detail:{enabled:e}}))},ot=async e=>{if(!e)return{isDangerous:!1};try{let t=await(await fetch(`/api/query/analyze`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({sql:e})})).json();return t.success?{isDangerous:t.isDangerous,type:t.type,title:t.title,description:t.description,sql:t.sql}:{isDangerous:!1}}catch(e){return console.error(e),{isDangerous:!1}}},st=({dangerInfo:e,fullSql:t,onConfirm:n,onCancel:r})=>{let i=document.getElementById(`safe-mode-modal`);i&&i.remove();let a=document.createElement(`div`);a.id=`safe-mode-modal`,a.className=`modal-overlay`;let o=(e?.sql||t||``).trim();a.innerHTML=`
1829
+ `})),o+=`</div>`,u.innerHTML=o,u.classList.remove(`hidden`),u.querySelectorAll(`.schema-autocomplete-item`).forEach(e=>{e.addEventListener(`mousedown`,t=>{t.preventDefault();let n=parseInt(e.dataset.suggestionIdx,10);f[n]&&_(f[n].text)})})},y=()=>{u&&u.querySelectorAll(`.schema-autocomplete-item`).forEach((e,t)=>{t===d?(e.classList.add(`active`),e.scrollIntoView({block:`nearest`})):e.classList.remove(`active`)})};c&&(c.addEventListener(`input`,e=>{window.SchemaGrid.filterText=e.target.value,p(),window.SchemaGrid.selection={startRow:-1,startCol:-1,endRow:-1,endCol:-1,isDragging:!1},window.renderSchemaGrid(),v()}),c.addEventListener(`focus`,()=>{v()}),c.addEventListener(`keydown`,e=>{u&&!u.classList.contains(`hidden`)&&f.length>0&&(e.key===`ArrowDown`?(e.preventDefault(),d=(d+1)%f.length,y()):e.key===`ArrowUp`?(e.preventDefault(),d=(d-1+f.length)%f.length,y()):e.key===`Enter`?d>=0&&f[d]&&(e.preventDefault(),_(f[d].text)):e.key===`Escape`&&(e.preventDefault(),m()))}));let b=c?.closest(`.filter-bar-input-box`);b&&c&&b.addEventListener(`click`,e=>{e.target.closest(`.filter-bar-clear-btn`)||c.focus()}),l&&(l.onclick=()=>{c&&(c.value=``,window.SchemaGrid.filterText=``,p(),m(),window.renderSchemaGrid(),c.focus())}),document.addEventListener(`click`,e=>{u&&!u.contains(e.target)&&c&&!c.contains(e.target)&&m()});let x=document.getElementById(`btn-rename-table-${e}`);x&&(x.onclick=()=>Se(e));let S=document.getElementById(`btn-export-orm-${e}`);S&&(S.onclick=()=>Rt(e));let C=document.getElementById(`btn-schema-diff-${e}`);C&&(C.onclick=()=>zt());let w=document.getElementById(`btn-refresh-schema-${e}`);w&&(w.onclick=()=>{(Object.keys(window.SchemaGrid.pendingEdits).length>0||window.SchemaGrid.pendingInserts.length>1||window.SchemaGrid.pendingDeletes.size>0||window.SchemaGrid.pendingIndexEdits.added.length>0||window.SchemaGrid.pendingIndexEdits.dropped.length>0)&&!confirm(`You have unsaved changes. Are you sure you want to refresh and discard them?`)||(window.SchemaGrid.pendingEdits={},window.SchemaGrid.pendingInserts=[{}],window.SchemaGrid.pendingDeletes.clear(),window.SchemaGrid.pendingIndexEdits={added:[],dropped:[]},window.SchemaGrid.history=[],window.SchemaGrid.currentTransaction=null,window.updateSidebarDirtyState?.(),Bt(e,t,n))})}else i.innerHTML=`<div class="p-6 text-error">Error: ${r.error}</div>`}catch(e){i.innerHTML=`<div class="p-6 text-error">Failed to load schema: ${e.message}</div>`}}var Vt=()=>localStorage.getItem(`drixio_safe_mode_disabled`)!==`true`,Ht=e=>{e?localStorage.removeItem(`drixio_safe_mode_disabled`):localStorage.setItem(`drixio_safe_mode_disabled`,`true`),window.dispatchEvent(new CustomEvent(`drixio-safemode-changed`,{detail:{enabled:e}}))},Ut=async e=>{if(!e)return{isDangerous:!1};try{let t=await(await fetch(`/api/query/analyze`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({sql:e})})).json();return t.success?{isDangerous:t.isDangerous,type:t.type,title:t.title,description:t.description,sql:t.sql}:{isDangerous:!1}}catch(e){return console.error(e),{isDangerous:!1}}},Wt=({dangerInfo:e,fullSql:t,onConfirm:n,onCancel:r})=>{let i=document.getElementById(`safe-mode-modal`);i&&i.remove();let a=document.createElement(`div`);a.id=`safe-mode-modal`,a.className=`modal-overlay`;let o=(e?.sql||t||``).trim();a.innerHTML=`
1510
1830
  <div class="modal-container safe-modal-container">
1511
1831
  <div class="modal-header">
1512
1832
  <div class="modal-title-wrap">
@@ -1553,7 +1873,7 @@
1553
1873
  </button>
1554
1874
  </div>
1555
1875
  </div>
1556
- `,document.body.appendChild(a);let s=()=>{document.removeEventListener(`keydown`,c),a.remove()},c=e=>{e.key===`Escape`&&(s(),r&&r())};document.addEventListener(`keydown`,c),a.addEventListener(`click`,e=>{e.target===a&&(s(),r&&r())}),document.getElementById(`safe-modal-close-btn`).onclick=()=>{s(),r&&r()},document.getElementById(`safe-modal-cancel-btn`).onclick=()=>{s(),r&&r()},document.getElementById(`safe-modal-confirm-btn`).onclick=()=>{document.getElementById(`safe-dont-warn-checkbox`)?.checked&&(at(!1),window.showToast&&window.showToast(`Safe Mode disabled. Future queries will run without confirmation.`,`info`)),s(),n&&n()}},ct=0;function lt(){window.AppState.consoleMessages=[],dt()}function ut(e){window.AppState.consoleMessages||(window.AppState.consoleMessages=[]);let t=new Date,n=t.toTimeString().split(` `)[0]+`.`+String(t.getMilliseconds()).padStart(3,`0`),r={id:`msg-`+Date.now()+`-`+Math.random().toString(36).substring(2,6),time:n,...e};window.AppState.consoleMessages.push(r),window.AppState.consoleMessages.length>200&&window.AppState.consoleMessages.shift(),dt()}function dt(){let e=document.getElementById(`console-messages-content`);if(!e)return;let t=window.AppState.consoleMessages||[];if(t.length===0){e.innerHTML=`
1876
+ `,document.body.appendChild(a);let s=()=>{document.removeEventListener(`keydown`,c),a.remove()},c=e=>{e.key===`Escape`&&(s(),r&&r())};document.addEventListener(`keydown`,c),a.addEventListener(`click`,e=>{e.target===a&&(s(),r&&r())}),document.getElementById(`safe-modal-close-btn`).onclick=()=>{s(),r&&r()},document.getElementById(`safe-modal-cancel-btn`).onclick=()=>{s(),r&&r()},document.getElementById(`safe-modal-confirm-btn`).onclick=()=>{document.getElementById(`safe-dont-warn-checkbox`)?.checked&&(Ht(!1),window.showToast&&window.showToast(`Safe Mode disabled. Future queries will run without confirmation.`,`info`)),s(),n&&n()}},Gt=0;function Kt(){window.AppState.consoleMessages=[],Jt()}function qt(e){window.AppState.consoleMessages||(window.AppState.consoleMessages=[]);let t=new Date,n=t.toTimeString().split(` `)[0]+`.`+String(t.getMilliseconds()).padStart(3,`0`),r={id:`msg-`+Date.now()+`-`+Math.random().toString(36).substring(2,6),time:n,...e};window.AppState.consoleMessages.push(r),window.AppState.consoleMessages.length>200&&window.AppState.consoleMessages.shift(),Jt()}function Jt(){let e=document.getElementById(`console-messages-content`);if(!e)return;let t=window.AppState.consoleMessages||[];if(t.length===0){e.innerHTML=`
1557
1877
  <div class="messages-empty-state">
1558
1878
  <span class="material-symbols-outlined messages-empty-icon">info</span>
1559
1879
  <p class="messages-empty-text">No messages yet. Query execution logs, rows affected, and error details will appear here.</p>
@@ -1569,7 +1889,7 @@
1569
1889
  ${e.sql?`<pre class="messages-sql">${e.sql.trim()}</pre>`:``}
1570
1890
  ${e.details?`<div class="messages-detail">${e.details}</div>`:``}
1571
1891
  </div>
1572
- `}).join(``);let n=document.getElementById(`console-messages-body`);n&&(n.scrollTop=n.scrollHeight)}function ft(e,t){if(!t)return;let n=document.getElementById(`results-meta-count`),r=document.getElementById(`results-export-wrapper`);if(!e){n&&(n.textContent=`Ready to run query`),r&&(r.style.display=`none`),t.innerHTML=`
1892
+ `}).join(``);let n=document.getElementById(`console-messages-body`);n&&(n.scrollTop=n.scrollHeight)}function K(e,t){if(!t)return;let n=document.getElementById(`results-meta-count`),r=document.getElementById(`results-export-wrapper`);if(!e){n&&(n.textContent=`Ready to run query`),r&&(r.style.display=`none`),t.innerHTML=`
1573
1893
  <div class="console-welcome-msg" id="console-welcome-msg">
1574
1894
  <div class="console-welcome-icon-box">
1575
1895
  <span class="material-symbols-outlined">terminal</span>
@@ -1588,15 +1908,40 @@
1588
1908
  <span class="material-symbols-outlined animate-spin icon-20">sync</span>
1589
1909
  <span>Executing query...</span>
1590
1910
  </div>
1591
- `;return}if(e.type===`error`){n&&(n.innerHTML=`<span style="color: var(--color-error);">Error &middot; ${e.ms||0}ms</span>`),r&&(r.style.display=`none`),t.innerHTML=`
1911
+ `;return}if(e.type===`error`){n&&(n.innerHTML=`<span style="color: var(--color-error);">Error &middot; ${e.ms||0}ms</span>`),r&&(r.style.display=`none`);let i=/database.*not found|no database connected|failed to find.*database|connection lost|connect.*failed|sqlite_error.*no such file/i.test(e.error||``),a=``;a=i?`
1912
+ <div style="display: flex; align-items: center; gap: 8px;">
1913
+ <button type="button" class="btn-ai-fix-error" id="btn-console-switch-db" style="background: linear-gradient(135deg, #10b981 0%, #059669 100%);" title="Open Connection Switcher">
1914
+ <span class="material-symbols-outlined" style="font-size: 14px;">dns</span>
1915
+ <span>Connect / Switch DB</span>
1916
+ </button>
1917
+ <button type="button" class="btn-ai-fix-error" id="btn-console-retry-query" style="background: rgba(255,255,255,0.08); border-color: rgba(255,255,255,0.15); color: var(--color-text);" title="Retry executing current query">
1918
+ <span class="material-symbols-outlined" style="font-size: 14px;">refresh</span>
1919
+ <span>Retry</span>
1920
+ </button>
1921
+ </div>
1922
+ `:`
1923
+ <button type="button" class="btn-ai-fix-error" id="btn-fix-with-ai" title="Diagnose error & generate fix with AI">
1924
+ <span class="material-symbols-outlined" style="font-size: 14px;">auto_fix_high</span>
1925
+ <span>Fix with AI</span>
1926
+ </button>
1927
+ `,t.innerHTML=`
1592
1928
  <div class="console-result-error">
1593
1929
  <div class="console-result-error-header">
1594
- <span class="material-symbols-outlined">error</span>
1595
- <span>Query Execution Failed</span>
1930
+ <div class="console-result-error-title">
1931
+ <span class="material-symbols-outlined">${i?`database_off`:`error`}</span>
1932
+ <span>${i?`Database Connection Error`:`Query Execution Failed`}</span>
1933
+ </div>
1934
+ ${a}
1596
1935
  </div>
1597
1936
  <pre class="console-result-error-msg">${e.error}</pre>
1937
+ ${i?`
1938
+ <div class="console-result-error-hint" style="margin-top: 10px; font-size: 12px; color: var(--color-text-soft); display: flex; align-items: center; gap: 6px;">
1939
+ <span class="material-symbols-outlined" style="font-size: 15px; color: #f59e0b;">info</span>
1940
+ <span>The query syntax is valid, but the database file or server was unreachable. Please verify connection credentials or file path.</span>
1941
+ </div>
1942
+ `:``}
1598
1943
  </div>
1599
- `;return}if(e.type===`connection`){n&&(n.innerHTML=`<span style="color: #10b981;">Connected &middot; ${e.ms}ms</span>`),r&&(r.style.display=`none`),t.innerHTML=`
1944
+ `;let o=t.querySelector(`#btn-fix-with-ai`);o&&(o.dataset.sql=e.sql||window.AppState?.lastQuery||``,o.dataset.error=e.error||``);let s=t.querySelector(`#btn-console-switch-db`);s&&(s.onclick=()=>{if(window.handleSwitchTab)window.handleSwitchTab(`connect-btn`);else{let e=document.getElementById(`connect-btn`)||document.getElementById(`header-connect-btn`);e&&e.click()}});let c=t.querySelector(`#btn-console-retry-query`);c&&(c.onclick=()=>{let e=document.getElementById(`run-sql-btn`);e&&e.click()});return}if(e.type===`connection`){n&&(n.innerHTML=`<span style="color: #10b981;">Connected &middot; ${e.ms}ms</span>`),r&&(r.style.display=`none`),t.innerHTML=`
1600
1945
  <div class="console-mutation-banner" style="background: rgba(16, 185, 129, 0.08); border-color: rgba(16, 185, 129, 0.25);">
1601
1946
  <div class="console-mutation-info" style="color: #10b981;">
1602
1947
  <span class="material-symbols-outlined icon">check_circle</span>
@@ -1614,7 +1959,7 @@
1614
1959
  <span class="text-soft">${e.ms}ms</span>
1615
1960
  </div>
1616
1961
  </div>
1617
- `;return}if(e.type===`table`){let i=e.rows||[],a=e.rowCount||i.length,o=e.ms||`0.0`,s=e.cols||(i.length>0?Object.keys(i[0]):[]);if(n&&(n.innerHTML=`<b>${a}</b> row${a===1?``:`s`}${a>1e3?` (Showing first 1000)`:``} &middot; ${o}ms`),r){r.style.display=`flex`;let e=document.getElementById(`console-export-btn`);e&&(e.onclick=e=>{A(e,[{icon:`description`,label:`Export as CSV`,action:()=>m({rows:i},`csv`)},{icon:`data_object`,label:`Export as JSON`,action:()=>m({rows:i},`json`)}])})}if(i.length===0){t.innerHTML=`
1962
+ `;return}if(e.type===`table`){let i=e.rows||[],a=e.rowCount||i.length,o=e.ms||`0.0`,s=e.cols||(i.length>0?Object.keys(i[0]):[]);if(n&&(n.innerHTML=`<b>${a}</b> row${a===1?``:`s`}${a>1e3?` (Showing first 1000)`:``} &middot; ${o}ms`),r){r.style.display=`flex`;let e=document.getElementById(`console-export-btn`);e&&(e.onclick=e=>{V(e,[{icon:`description`,label:`Export as CSV`,action:()=>v({rows:i},`csv`)},{icon:`data_object`,label:`Export as JSON`,action:()=>v({rows:i},`json`)}])})}if(i.length===0){t.innerHTML=`
1618
1963
  <div class="console-mutation-banner">
1619
1964
  <div class="console-mutation-info">
1620
1965
  <span class="material-symbols-outlined icon">task_alt</span>
@@ -1625,7 +1970,7 @@
1625
1970
  <div class="th-content-wrapper">
1626
1971
  <span class="th-col-name">${e}</span>
1627
1972
  </div>
1628
- `,d.appendChild(t)}),u.appendChild(d),l.appendChild(u);let p=document.createElement(`tbody`);i.slice(0,1e3).forEach((e,t)=>{let n=document.createElement(`tr`),r=document.createElement(`td`);r.className=`row-header`,r.textContent=String(t+1),n.appendChild(r),s.forEach(t=>{let r=document.createElement(`td`);r.className=`data-cell data-cell-truncate`;let a=e[t];if(a==null)r.innerHTML=`<em>NULL</em>`;else if(typeof a==`boolean`)r.innerHTML=`<span class="badge-bool ${a?`bool-true`:`bool-false`}">${a?`true`:`false`}</span>`;else{let e=String(a);r.textContent=e,e.length>50&&(r.title=e)}r.ondblclick=async e=>{e.stopPropagation();let t=a==null?`NULL`:String(a);try{await navigator.clipboard.writeText(t),window.showToast&&window.showToast(`Copied cell value`,`info`)}catch{}},r.oncontextmenu=t=>{t.preventDefault(),t.stopPropagation();let n=a==null?`NULL`:String(a);A(t,[{icon:`content_copy`,label:`Copy Cell Value`,action:async()=>{await navigator.clipboard.writeText(n),window.showToast&&window.showToast(`Copied cell value`,`info`)}},{icon:`data_object`,label:`Copy Row as JSON`,action:async()=>{await navigator.clipboard.writeText(JSON.stringify(e,null,2)),window.showToast&&window.showToast(`Copied row as JSON`,`info`)}},`divider`,{icon:`download`,label:`Export All as CSV`,action:()=>m({rows:i},`csv`)}])},n.appendChild(r)}),p.appendChild(n)}),l.appendChild(p),c.appendChild(l),t.appendChild(c);return}if(e.type===`explain`){let i=e.rows||[],a=e.cols||[],o=e.ms||`0.0`;n&&(n.innerHTML=`Execution Plan &middot; <b>${i.length}</b> line${i.length===1?``:`s`} &middot; ${o}ms`),r&&(r.style.display=`none`),t.innerHTML=``;let s=document.createElement(`div`);s.className=`table-container console-results-table-container`;let c=document.createElement(`table`);c.className=`data-table`;let l=document.createElement(`thead`),u=document.createElement(`tr`),d=document.createElement(`th`);d.className=`row-header`,d.textContent=`#`,u.appendChild(d),a.forEach(e=>{let t=document.createElement(`th`);t.textContent=e,u.appendChild(t)}),l.appendChild(u),c.appendChild(l);let f=document.createElement(`tbody`);i.forEach((e,t)=>{let n=document.createElement(`tr`),r=document.createElement(`td`);r.className=`row-header`,r.textContent=String(t+1),n.appendChild(r),a.forEach(t=>{let r=document.createElement(`td`);r.className=`data-cell font-mono text-12`;let i=e[t];r.textContent=i==null?`NULL`:String(i),n.appendChild(r)}),f.appendChild(n)}),c.appendChild(f),s.appendChild(c),t.appendChild(s)}}async function pt(e,t,n,r=!1,i=null){let a=e||(t?t.value.substring(t.selectionStart,t.selectionEnd).trim():``);if(!a&&t&&(a=t.value.trim()),!a)return null;if(a.toLowerCase()===`clear`||a.toLowerCase()===`clear;`)return ft(null,n),null;if(!r&&it()){let e=ot(a);if(e.isDangerous)return st({dangerInfo:e,fullSql:a,onConfirm:()=>{pt(a,t,n,!0,i)}}),null}window.AppState.lastQuery=a,window.AppState.queryHistory||(window.AppState.queryHistory=[]);let o=window.AppState.queryHistory;o.includes(a)||(o.unshift(a),o.length>20&&o.pop(),window.dispatchEvent(new Event(`query-history-updated`))),ct++,ft({type:`executing`},n);try{let e=performance.now(),t=await u(a),r=(performance.now()-e).toFixed(1);if(!t.success){let e={type:`error`,error:t.error,ms:r,sql:a};return ut({type:`error`,title:`Query Execution Failed`,sql:a,ms:r,details:t.error}),ft(e,n),i&&i(e),e}let o=t.data.rows||[],s=o.length,c=o.length===1&&o[0].Result===`Success`&&o[0].AffectedRows!==void 0||s===0&&t.data.affectedRows!==void 0;if(t.data?.connectionChanged){window.showToast&&window.showToast(`Database updated: ${t.data.dbConfig?.dbName||`Connected`}`,`success`),window.initSidebar&&window.initSidebar(!0);let e=t.data.dbConfig?.type&&t.data.dbConfig.type!==`none`;if(window.setStudioConnectionMode&&window.setStudioConnectionMode(!!e),t.data.dbConfig?.type){window.AppState.dbType=t.data.dbConfig.type;let e=document.getElementById(`brand-db-type`);e&&(e.textContent=t.data.dbConfig.type===`none`?`NO DATABASE`:t.data.dbConfig.type.toUpperCase());let n=document.getElementById(`sidebar-db-status-dot`);n&&(t.data.dbConfig.type===`none`?(n.classList.remove(`status-connected`,`status-error`),n.classList.add(`status-warning`)):(n.classList.remove(`status-error`,`status-warning`),n.classList.add(`status-connected`)))}let s=o[0]?.Result||`Connected`,c=o[0]?.Database||o[0]?.Target||o[0]?.Path||`Database ready`,l={type:`connection`,title:s,detail:c,ms:r,sql:a};return ut({type:`info`,title:`Database: ${s}`,sql:a,ms:r,details:c}),ft(l,n),i&&i(l),l}if(/^\s*(CREATE|DROP|ALTER)\s+(TABLE|VIEW)/i.test(a)&&window.initSidebar?.(!0),c){let e=t.data.affectedRows??o[0]?.AffectedRows??0,s={type:`mutation`,affectedRows:e,ms:r,sql:a};return ut({type:`mutation`,title:`Query OK, ${e} row${e===1?``:`s`} affected`,sql:a,ms:r,details:`${e} row(s) updated/deleted/inserted`}),ft(s,n),i&&i(s),s}let l={type:`table`,rows:o,rowCount:s,cols:o.length>0?Object.keys(o[0]):[],ms:r,sql:a};return ut({type:`success`,title:`Query OK, returned ${s} row${s===1?``:`s`}`,sql:a,ms:r,details:`Successfully fetched ${s} row(s) with ${l.cols.length} column(s)`}),ft(l,n),i&&i(l),l}catch(e){let t={type:`error`,error:e.message,ms:`0.0`,sql:a};return ut({type:`error`,title:`Query Exception`,sql:a,ms:`0.0`,details:e.message}),ft(t,n),i&&i(t),t}}async function mt(e,t,n,r=null){let i=e||(t?t.value.substring(t.selectionStart,t.selectionEnd).trim():``);if(!i&&t&&(i=t.value.trim()),!i)return null;ft({type:`executing`},n);try{let e=await h(i);if(!e.success)throw Error(e.error||`Failed to explain query`);let t={type:`explain`,rows:e.data.rows||[],cols:e.data.columns||[],ms:e.data.durationMs,dialect:e.data.dialect,sql:i};return ut({type:`info`,title:`Execution Plan (EXPLAIN)`,sql:i,ms:e.data.durationMs,details:`${t.rows.length} plan node(s) (Dialect: ${t.dialect||`SQL`})`}),ft(t,n),r&&r(t),t}catch(e){let t={type:`error`,error:e.message,ms:`0.0`,sql:i};return ut({type:`error`,title:`EXPLAIN Failed`,sql:i,ms:`0.0`,details:e.message}),ft(t,n),r&&r(t),t}}function ht(e){if(!e)return[];let t=new Set,n=/\{\{\s*([a-zA-Z0-9_]+)\s*\}\}/g,r;for(;(r=n.exec(e))!==null;)r[1]&&t.add(r[1]);let i=/(?:^|[^:]):([a-zA-Z0-9_]+)/g;for(;(r=i.exec(e))!==null;)r[1]&&t.add(r[1]);return Array.from(t)}function gt({snippetId:e=null,defaultTitle:t=``,defaultSql:n=``,defaultDescription:r=``,defaultTags:i=[],onSaved:a=null}){let o=document.getElementById(`snippet-save-modal`);o&&o.remove();let s=document.createElement(`div`);s.id=`snippet-save-modal`,s.className=`modal-overlay`;let c=!!e,l=ht(n);s.innerHTML=`
1973
+ `,d.appendChild(t)}),u.appendChild(d),l.appendChild(u);let p=document.createElement(`tbody`);i.slice(0,1e3).forEach((e,t)=>{let n=document.createElement(`tr`),r=document.createElement(`td`);r.className=`row-header`,r.textContent=String(t+1),n.appendChild(r),s.forEach(t=>{let r=document.createElement(`td`);r.className=`data-cell data-cell-truncate`;let a=e[t];if(a==null)r.innerHTML=`<em>NULL</em>`;else if(typeof a==`boolean`)r.innerHTML=`<span class="badge-bool ${a?`bool-true`:`bool-false`}">${a?`true`:`false`}</span>`;else{let e=String(a);r.textContent=e,e.length>50&&(r.title=e)}r.ondblclick=async e=>{e.stopPropagation();let t=a==null?`NULL`:String(a);try{await navigator.clipboard.writeText(t),window.showToast&&window.showToast(`Copied cell value`,`info`)}catch{}},r.oncontextmenu=t=>{t.preventDefault(),t.stopPropagation();let n=a==null?`NULL`:String(a);V(t,[{icon:`content_copy`,label:`Copy Cell Value`,action:async()=>{await navigator.clipboard.writeText(n),window.showToast&&window.showToast(`Copied cell value`,`info`)}},{icon:`data_object`,label:`Copy Row as JSON`,action:async()=>{await navigator.clipboard.writeText(JSON.stringify(e,null,2)),window.showToast&&window.showToast(`Copied row as JSON`,`info`)}},`divider`,{icon:`download`,label:`Export All as CSV`,action:()=>v({rows:i},`csv`)}])},n.appendChild(r)}),p.appendChild(n)}),l.appendChild(p),c.appendChild(l),t.appendChild(c);return}if(e.type===`explain`){let i=e.rows||[],a=e.cols||[],o=e.ms||`0.0`;n&&(n.innerHTML=`Execution Plan &middot; <b>${i.length}</b> line${i.length===1?``:`s`} &middot; ${o}ms`),r&&(r.style.display=`none`),t.innerHTML=``;let s=document.createElement(`div`);s.className=`table-container console-results-table-container`;let c=document.createElement(`table`);c.className=`data-table`;let l=document.createElement(`thead`),u=document.createElement(`tr`),d=document.createElement(`th`);d.className=`row-header`,d.textContent=`#`,u.appendChild(d),a.forEach(e=>{let t=document.createElement(`th`);t.textContent=e,u.appendChild(t)}),l.appendChild(u),c.appendChild(l);let f=document.createElement(`tbody`);i.forEach((e,t)=>{let n=document.createElement(`tr`),r=document.createElement(`td`);r.className=`row-header`,r.textContent=String(t+1),n.appendChild(r),a.forEach(t=>{let r=document.createElement(`td`);r.className=`data-cell font-mono text-12`;let i=e[t];r.textContent=i==null?`NULL`:String(i),n.appendChild(r)}),f.appendChild(n)}),c.appendChild(f),s.appendChild(c),t.appendChild(s)}}async function Yt(e,t,n,r=!1,i=null){let a=e||(t?t.value.substring(t.selectionStart,t.selectionEnd).trim():``);if(!a&&t&&(a=t.value.trim()),!a)return null;if(a.toLowerCase()===`clear`||a.toLowerCase()===`clear;`)return K(null,n),null;if(!r&&Vt()){let e=Ut(a);if(e.isDangerous)return Wt({dangerInfo:e,fullSql:a,onConfirm:()=>{Yt(a,t,n,!0,i)}}),null}window.AppState.lastQuery=a,window.AppState.queryHistory||(window.AppState.queryHistory=[]);let o=window.AppState.queryHistory;o.includes(a)||(o.unshift(a),o.length>20&&o.pop(),window.dispatchEvent(new Event(`query-history-updated`))),Gt++,K({type:`executing`},n);try{let e=performance.now(),t=await f(a),r=(performance.now()-e).toFixed(1);if(!t.success){let e={type:`error`,error:t.error,ms:r,sql:a};return qt({type:`error`,title:`Query Execution Failed`,sql:a,ms:r,details:t.error}),K(e,n),i&&i(e),e}let o=t.data.rows||[],s=o.length,c=o.length===1&&o[0].Result===`Success`&&o[0].AffectedRows!==void 0||s===0&&t.data.affectedRows!==void 0;if(t.data?.connectionChanged){window.showToast&&window.showToast(`Database updated: ${t.data.dbConfig?.dbName||`Connected`}`,`success`),window.initSidebar&&window.initSidebar(!0);let e=t.data.dbConfig?.type&&t.data.dbConfig.type!==`none`;if(window.setStudioConnectionMode&&window.setStudioConnectionMode(!!e),t.data.dbConfig?.type){window.AppState.dbType=t.data.dbConfig.type;let e=document.getElementById(`brand-db-type`);e&&(e.textContent=t.data.dbConfig.type===`none`?`NO DATABASE`:t.data.dbConfig.type.toUpperCase());let n=document.getElementById(`sidebar-db-status-dot`);n&&(t.data.dbConfig.type===`none`?(n.classList.remove(`status-connected`,`status-error`),n.classList.add(`status-warning`)):(n.classList.remove(`status-error`,`status-warning`),n.classList.add(`status-connected`)))}let s=o[0]?.Result||`Connected`,c=o[0]?.Database||o[0]?.Target||o[0]?.Path||`Database ready`,l={type:`connection`,title:s,detail:c,ms:r,sql:a};return qt({type:`info`,title:`Database: ${s}`,sql:a,ms:r,details:c}),K(l,n),i&&i(l),l}if(/^\s*(CREATE|DROP|ALTER)\s+(TABLE|VIEW)/i.test(a)&&window.initSidebar?.(!0),c){let e=t.data.affectedRows??o[0]?.AffectedRows??0,s={type:`mutation`,affectedRows:e,ms:r,sql:a};return qt({type:`mutation`,title:`Query OK, ${e} row${e===1?``:`s`} affected`,sql:a,ms:r,details:`${e} row(s) updated/deleted/inserted`}),K(s,n),i&&i(s),s}let l={type:`table`,rows:o,rowCount:s,cols:o.length>0?Object.keys(o[0]):[],ms:r,sql:a};return qt({type:`success`,title:`Query OK, returned ${s} row${s===1?``:`s`}`,sql:a,ms:r,details:`Successfully fetched ${s} row(s) with ${l.cols.length} column(s)`}),K(l,n),i&&i(l),l}catch(e){let t={type:`error`,error:e.message,ms:`0.0`,sql:a};return qt({type:`error`,title:`Query Exception`,sql:a,ms:`0.0`,details:e.message}),K(t,n),i&&i(t),t}}async function Xt(e,t,n,r=null){let i=e||(t?t.value.substring(t.selectionStart,t.selectionEnd).trim():``);if(!i&&t&&(i=t.value.trim()),!i)return null;K({type:`executing`},n);try{let e=await y(i);if(!e.success)throw Error(e.error||`Failed to explain query`);let t={type:`explain`,rows:e.data.rows||[],cols:e.data.columns||[],ms:e.data.durationMs,dialect:e.data.dialect,sql:i};return qt({type:`info`,title:`Execution Plan (EXPLAIN)`,sql:i,ms:e.data.durationMs,details:`${t.rows.length} plan node(s) (Dialect: ${t.dialect||`SQL`})`}),K(t,n),r&&r(t),t}catch(e){let t={type:`error`,error:e.message,ms:`0.0`,sql:i};return qt({type:`error`,title:`EXPLAIN Failed`,sql:i,ms:`0.0`,details:e.message}),K(t,n),r&&r(t),t}}function Zt(e){if(!e)return[];let t=new Set,n=/\{\{\s*([a-zA-Z0-9_]+)\s*\}\}/g,r;for(;(r=n.exec(e))!==null;)r[1]&&t.add(r[1]);let i=/(?:^|[^:]):([a-zA-Z0-9_]+)/g;for(;(r=i.exec(e))!==null;)r[1]&&t.add(r[1]);return Array.from(t)}function Qt({snippetId:e=null,defaultTitle:t=``,defaultSql:n=``,defaultDescription:r=``,defaultTags:i=[],onSaved:a=null}){let o=document.getElementById(`snippet-save-modal`);o&&o.remove();let s=document.createElement(`div`);s.id=`snippet-save-modal`,s.className=`modal-overlay`;let c=!!e,l=Zt(n);s.innerHTML=`
1629
1974
  <div class="modal-container snippet-modal-container">
1630
1975
  <div class="modal-header">
1631
1976
  <div class="modal-title-wrap">
@@ -1691,7 +2036,7 @@
1691
2036
  </div>
1692
2037
  </div>
1693
2038
  </div>
1694
- `,document.body.appendChild(s);let u=()=>{document.removeEventListener(`keydown`,d),s.remove()},d=e=>{e.key===`Escape`&&u(),(e.ctrlKey||e.metaKey)&&e.key===`Enter`&&(e.preventDefault(),_.click())};document.addEventListener(`keydown`,d),s.addEventListener(`click`,e=>{e.target===s&&u()}),document.getElementById(`close-save-snippet-btn`).onclick=u,document.getElementById(`cancel-save-snippet-btn`).onclick=u;let f=document.getElementById(`save-snippet-title`),p=document.getElementById(`save-snippet-desc`),m=document.getElementById(`save-snippet-tags`),h=document.getElementById(`save-snippet-sql`),g=document.getElementById(`save-snippet-param-badges`),_=document.getElementById(`confirm-save-snippet-btn`),v=document.getElementById(`confirm-save-snippet-btn-text`);h.oninput=()=>{let e=ht(h.value);g.innerHTML=e.map(e=>`<span class="snippet-param-badge">:${e}</span>`).join(``)},_.onclick=async()=>{let t=f.value.trim(),n=h.value.trim();if(!n){window.showToast?window.showToast(`SQL query cannot be empty.`,`error`):alert(`SQL query cannot be empty.`),h.focus();return}let r=p.value.trim(),i=m.value.split(`,`).map(e=>e.trim()).filter(Boolean);_.disabled=!0,v&&(v.textContent=`Saving...`);try{let o;o=c?await x(e,{title:t||`Untitled Snippet`,sql:n,description:r,tags:i}):await b({title:t||`Untitled Snippet`,sql:n,description:r,tags:i}),o.success?(window.showToast&&window.showToast(c?`Snippet updated`:`Snippet saved to .drixio/snippets.json`,`success`),a&&a(o.data),u()):window.showToast?window.showToast(`Failed to save snippet: ${o.error}`,`error`):alert(`Failed to save snippet: ${o.error}`)}catch(e){window.showToast?window.showToast(`Error saving snippet: ${e.message}`,`error`):alert(`Error saving snippet: ${e.message}`)}finally{_.disabled=!1,v&&(v.textContent=c?`Update Snippet`:`Save Snippet`)}},f.focus()}function _t(e={}){let{id:t=`modal-${Date.now()}`,className:n=``,icon:r=``,iconColor:i=`primary`,title:a=``,subtitle:o=``,badge:s=``,width:c=`520px`,maxWidth:l=`92vw`,body:u=``,footer:d=null,showCloseBtn:f=!0,closeOnEsc:p=!0,closeOnBackdrop:m=!0,onClose:h=null,onOpen:g=null}=e,_=document.getElementById(t);_&&_.remove();let v=document.createElement(`div`);v.id=t,v.className=`modal-overlay`;let y=[`primary`,`warning`,`error`,`success`].includes(i),b=y?`modal-icon-badge ${i}`:`modal-icon-badge`,x=!y&&i?`color: ${i};`:``;v.innerHTML=`
2039
+ `,document.body.appendChild(s);let u=()=>{document.removeEventListener(`keydown`,d),s.remove()},d=e=>{e.key===`Escape`&&u(),(e.ctrlKey||e.metaKey)&&e.key===`Enter`&&(e.preventDefault(),_.click())};document.addEventListener(`keydown`,d),s.addEventListener(`click`,e=>{e.target===s&&u()}),document.getElementById(`close-save-snippet-btn`).onclick=u,document.getElementById(`cancel-save-snippet-btn`).onclick=u;let f=document.getElementById(`save-snippet-title`),p=document.getElementById(`save-snippet-desc`),m=document.getElementById(`save-snippet-tags`),h=document.getElementById(`save-snippet-sql`),g=document.getElementById(`save-snippet-param-badges`),_=document.getElementById(`confirm-save-snippet-btn`),v=document.getElementById(`confirm-save-snippet-btn-text`);h.oninput=()=>{let e=Zt(h.value);g.innerHTML=e.map(e=>`<span class="snippet-param-badge">:${e}</span>`).join(``)},_.onclick=async()=>{let t=f.value.trim(),n=h.value.trim();if(!n){window.showToast?window.showToast(`SQL query cannot be empty.`,`error`):alert(`SQL query cannot be empty.`),h.focus();return}let r=p.value.trim(),i=m.value.split(`,`).map(e=>e.trim()).filter(Boolean);_.disabled=!0,v&&(v.textContent=`Saving...`);try{let o;o=c?await T(e,{title:t||`Untitled Snippet`,sql:n,description:r,tags:i}):await w({title:t||`Untitled Snippet`,sql:n,description:r,tags:i}),o.success?(window.showToast&&window.showToast(c?`Snippet updated`:`Snippet saved to .drixio/snippets.json`,`success`),a&&a(o.data),u()):window.showToast?window.showToast(`Failed to save snippet: ${o.error}`,`error`):alert(`Failed to save snippet: ${o.error}`)}catch(e){window.showToast?window.showToast(`Error saving snippet: ${e.message}`,`error`):alert(`Error saving snippet: ${e.message}`)}finally{_.disabled=!1,v&&(v.textContent=c?`Update Snippet`:`Save Snippet`)}},f.focus()}function $t(e={}){let{id:t=`modal-${Date.now()}`,className:n=``,icon:r=``,iconColor:i=`primary`,title:a=``,subtitle:o=``,badge:s=``,width:c=`520px`,maxWidth:l=`92vw`,body:u=``,footer:d=null,showCloseBtn:f=!0,closeOnEsc:p=!0,closeOnBackdrop:m=!0,onClose:h=null,onOpen:g=null}=e,_=document.getElementById(t);_&&_.remove();let v=document.createElement(`div`);v.id=t,v.className=`modal-overlay`;let y=[`primary`,`warning`,`error`,`success`].includes(i),b=y?`modal-icon-badge ${i}`:`modal-icon-badge`,x=!y&&i?`color: ${i};`:``;v.innerHTML=`
1695
2040
  <div class="modal-container ${n}" style="width: ${c}; max-width: ${l};">
1696
2041
  <div class="modal-header">
1697
2042
  <div class="modal-title-wrap">
@@ -1713,35 +2058,299 @@
1713
2058
  <div class="modal-body"></div>
1714
2059
  ${d?`<div class="modal-footer"></div>`:``}
1715
2060
  </div>
1716
- `;let S=v.querySelector(`.modal-container`),C=v.querySelector(`.modal-header`),w=v.querySelector(`.modal-body`),T=v.querySelector(`.modal-footer`),E=v.querySelector(`.modal-close-btn`);w&&(typeof u==`string`?w.innerHTML=u:u instanceof HTMLElement&&w.appendChild(u)),T&&d&&(typeof d==`string`?T.innerHTML=d:d instanceof HTMLElement&&T.appendChild(d));let D=!1,O=()=>{D||(D=!0,window.removeEventListener(`keydown`,k),v.remove(),typeof h==`function`&&h())},k=e=>{p&&e.key===`Escape`&&(e.preventDefault(),O())};return E&&(E.onclick=e=>{e.stopPropagation(),O()}),m&&(v.onclick=e=>{e.target===v&&O()}),window.addEventListener(`keydown`,k),document.body.appendChild(v),typeof g==`function`&&g(v),{overlay:v,container:S,header:C,body:w,footer:T,close:O,destroy:O,setTitle:e=>{let t=C.querySelector(`.modal-title-text`);t&&(t.textContent=e)},setSubtitle:e=>{let t=C.querySelector(`.modal-subtitle-text`);if(!t&&e){let e=C.querySelector(`.modal-title-col`);e&&(t=document.createElement(`p`),t.className=`modal-subtitle-text`,e.appendChild(t))}t&&(t.textContent=e)}}}function vt(e){return e==null?``:String(e).replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`).replace(/"/g,`&quot;`).replace(/'/g,`&#039;`)}function yt(e){if(e===0||!e)return`0 B`;let t=1024,n=[`B`,`KB`,`MB`,`GB`,`TB`],r=Math.floor(Math.log(e)/Math.log(t));return parseFloat((e/t**r).toFixed(2))+` `+n[r]}function bt(e){if(!e||e<=0)return`N/A`;let t=Math.floor(e/(3600*24)),n=Math.floor(e%(3600*24)/3600),r=Math.floor(e%3600/60),i=``;return t>0&&(i+=`${t}d `),n>0&&(i+=`${n}h `),i+=`${r}m`,i||`< 1m`}var xt=`drixio_query_history`;function St(){try{let e=localStorage.getItem(xt);if(e){let t=JSON.parse(e);if(Array.isArray(t))return t}}catch{}return[]}function Ct(e){try{localStorage.setItem(xt,JSON.stringify(e||[]))}catch(e){console.warn(`Failed to save query history to localStorage:`,e)}}var wt=null;function Tt(e){wt=e,window.AppState.queryHistory=St();let t=document.getElementById(`console-clear-history-btn`);t&&(t.onclick=()=>{confirm(`Clear all recent query history?`)&&(window.AppState.queryHistory=[],Ct([]),Dt())}),window.removeEventListener(`query-history-updated`,Et),window.addEventListener(`query-history-updated`,Et),Dt()}function Et(){Ct(window.AppState.queryHistory),Dt()}function Dt(){let e=document.getElementById(`console-recent-history-list`),t=document.getElementById(`console-clear-history-btn`);if(!e)return;let n=window.AppState.queryHistory||[];if(t&&(n.length>0?t.classList.remove(`hidden`):t.classList.add(`hidden`)),n.length===0){e.innerHTML=`<div class="sidebar-tree-empty">No recent queries</div>`;return}e.innerHTML=n.slice(0,20).map((e,t)=>`
1717
- <button type="button" class="table-btn query-item-btn history-item" data-idx="${t}" title="${vt(e)}">
2061
+ `;let S=v.querySelector(`.modal-container`),C=v.querySelector(`.modal-header`),w=v.querySelector(`.modal-body`),T=v.querySelector(`.modal-footer`),E=v.querySelector(`.modal-close-btn`);w&&(typeof u==`string`?w.innerHTML=u:u instanceof HTMLElement&&w.appendChild(u)),T&&d&&(typeof d==`string`?T.innerHTML=d:d instanceof HTMLElement&&T.appendChild(d));let D=!1,O=()=>{D||(D=!0,window.removeEventListener(`keydown`,k),v.remove(),typeof h==`function`&&h())},k=e=>{p&&e.key===`Escape`&&(e.preventDefault(),O())};return E&&(E.onclick=e=>{e.stopPropagation(),O()}),m&&(v.onclick=e=>{e.target===v&&O()}),window.addEventListener(`keydown`,k),document.body.appendChild(v),typeof g==`function`&&g(v),{overlay:v,container:S,header:C,body:w,footer:T,close:O,destroy:O,setTitle:e=>{let t=C.querySelector(`.modal-title-text`);t&&(t.textContent=e)},setSubtitle:e=>{let t=C.querySelector(`.modal-subtitle-text`);if(!t&&e){let e=C.querySelector(`.modal-title-col`);e&&(t=document.createElement(`p`),t.className=`modal-subtitle-text`,e.appendChild(t))}t&&(t.textContent=e)}}}function en(e){return e==null?``:String(e).replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`).replace(/"/g,`&quot;`).replace(/'/g,`&#039;`)}function tn(e){if(e===0||!e)return`0 B`;let t=1024,n=[`B`,`KB`,`MB`,`GB`,`TB`],r=Math.floor(Math.log(e)/Math.log(t));return parseFloat((e/t**r).toFixed(2))+` `+n[r]}function nn(e){if(!e||e<=0)return`N/A`;let t=Math.floor(e/(3600*24)),n=Math.floor(e%(3600*24)/3600),r=Math.floor(e%3600/60),i=``;return t>0&&(i+=`${t}d `),n>0&&(i+=`${n}h `),i+=`${r}m`,i||`< 1m`}var rn=`drixio_query_history`;function an(){try{let e=localStorage.getItem(rn);if(e){let t=JSON.parse(e);if(Array.isArray(t))return t}}catch{}return[]}function on(e){try{localStorage.setItem(rn,JSON.stringify(e||[]))}catch(e){console.warn(`Failed to save query history to localStorage:`,e)}}var sn=null;function cn(e){sn=e,window.AppState.queryHistory=an();let t=document.getElementById(`console-clear-history-btn`),n=document.getElementById(`console-clear-history-footer-btn`),r=()=>{confirm(`Clear all recent query history?`)&&(window.AppState.queryHistory=[],on([]),un())};t&&(t.onclick=r),n&&(n.onclick=r),window.removeEventListener(`query-history-updated`,ln),window.addEventListener(`query-history-updated`,ln),un()}function ln(){on(window.AppState.queryHistory),un()}function un(){let e=document.getElementById(`console-recent-history-list`),t=document.getElementById(`console-clear-history-btn`);if(!e)return;let n=window.AppState.queryHistory||[];if(t&&(n.length>0?t.classList.remove(`hidden`):t.classList.add(`hidden`)),n.length===0){e.innerHTML=`<div class="sidebar-tree-empty">No recent queries</div>`;return}e.innerHTML=n.slice(0,20).map((e,t)=>`
2062
+ <button type="button" class="table-btn query-item-btn history-item" data-idx="${t}" title="${en(e)}">
1718
2063
  <div class="table-btn-label">
1719
2064
  <i class="material-symbols-outlined table-item-icon">history</i>
1720
- <span class="table-name-text">${vt(e.replace(/\s+/g,` `))}</span>
2065
+ <span class="table-name-text">${en(e.replace(/\s+/g,` `))}</span>
1721
2066
  </div>
1722
2067
  <span class="query-item-delete-btn" title="Remove from history">
1723
2068
  <span class="material-symbols-outlined">close</span>
1724
2069
  </span>
1725
2070
  </button>
1726
- `).join(``),e.querySelectorAll(`.history-item`).forEach(e=>{let t=parseInt(e.getAttribute(`data-idx`)||`0`,10),r=n[t];if(!r)return;e.onclick=e=>{e.target.closest(`.query-item-delete-btn`)||wt&&wt(r)};let i=e.querySelector(`.query-item-delete-btn`);i&&(i.onclick=e=>{e.stopPropagation(),window.AppState.queryHistory.splice(t,1),Ct(window.AppState.queryHistory),Dt()})})}var Ot=(e,t)=>{let n=window.AppState.lastQuery||`SELECT 1 + 1 AS ping;`,r=[];try{let e=localStorage.getItem(`drixio_sql_tabs`);e&&(r=JSON.parse(e))}catch{r=[]}(!Array.isArray(r)||r.length===0)&&(r=[{id:`tab-1`,title:`Untitled query 1`,sql:n,isDirty:!1,lastResult:null}]);let i=localStorage.getItem(`drixio_active_tab_id`)||r[0].id;r.find(e=>e.id===i)||(i=r[0].id);let a=()=>{try{let e=r.map(e=>{let t=e.lastResult;return t&&t.data&&t.data.rows&&t.data.rows.length>100&&(t={...t,data:{...t.data,rows:t.data.rows.slice(0,100)}}),{id:e.id,title:e.title,sql:e.sql,isDirty:e.isDirty,isPreview:!!e.isPreview,lastResult:t}});localStorage.setItem(`drixio_sql_tabs`,JSON.stringify(e)),localStorage.setItem(`drixio_active_tab_id`,i)}catch(e){console.warn(`Failed to save tabs to localStorage`,e)}},o=()=>r.find(e=>e.id===i)||r[0],s=document.getElementById(`console-tabs-container`);s&&s.addEventListener(`wheel`,e=>{e.deltaY!==0&&(e.preventDefault(),s.scrollLeft+=e.deltaY)},{passive:!1});let c=()=>{s&&(s.innerHTML=``,r.forEach(e=>{let t=e.id===i,n=document.createElement(`div`);n.className=`console-tab ${t?`active`:``} ${e.isPreview?`preview`:``}`,n.dataset.tabId=e.id;let o=document.createElement(`span`);o.className=`material-symbols-outlined console-tab-icon`,o.textContent=`terminal`;let d=document.createElement(`span`);if(d.className=`console-tab-title`,d.textContent=e.title,d.title=e.isPreview?`Preview tab (double click or edit to keep)`:`Double click to rename, right click for options`,n.appendChild(o),n.appendChild(d),e.isDirty){let e=document.createElement(`span`);e.className=`tab-dirty-dot`,e.title=`Unsaved changes`,n.appendChild(e)}if(r.length>1){let t=document.createElement(`button`);t.type=`button`,t.className=`tab-close-btn`,t.title=`Close tab (Ctrl+W)`,t.innerHTML=`<span class="material-symbols-outlined" style="font-size: 14px;">close</span>`,t.onclick=t=>{t.stopPropagation(),f(e.id)},n.appendChild(t)}n.onclick=()=>{i!==e.id&&l(e.id)},n.addEventListener(`mousedown`,t=>{t.button===1&&(t.preventDefault(),t.stopPropagation(),f(e.id))}),n.oncontextmenu=t=>{t.preventDefault(),t.stopPropagation(),A(t,[{icon:`edit`,label:`Rename Tab`,shortcut:`Double Click`,action:()=>{d.dispatchEvent(new MouseEvent(`dblclick`,{bubbles:!0}))}},{icon:`content_copy`,label:`Duplicate Tab`,action:()=>{u(`${e.title} (Copy)`,e.sql)}},`divider`,{icon:`close`,label:`Close Tab`,shortcut:`Ctrl+W`,action:()=>{f(e.id)}},{icon:`close_fullscreen`,label:`Close Other Tabs`,disabled:r.length<=1,action:()=>{r=[e],i=e.id,a(),c()}},{icon:`playlist_remove`,label:`Close Tabs to Right`,disabled:r.indexOf(e)===r.length-1,action:()=>{let t=r.indexOf(e);r=r.slice(0,t+1),r.find(e=>e.id===i)||(i=e.id),a(),c()}}])},d.ondblclick=t=>{t.stopPropagation(),e.isPreview&&(e.isPreview=!1,a());let n=document.createElement(`input`);n.type=`text`,n.className=`console-tab-rename-input`,n.value=e.title,n.onblur=()=>{let t=n.value.trim();t&&(e.title=t),a(),c()},n.onkeydown=e=>{e.key===`Enter`?(e.preventDefault(),n.blur()):e.key===`Escape`&&(e.preventDefault(),c())},d.replaceWith(n),n.focus(),n.select()},s.appendChild(n),t&&setTimeout(()=>{n.scrollIntoView({behavior:`smooth`,block:`nearest`,inline:`nearest`})},0)}))},l=n=>{let r=o();r&&(r.sql=e.value),i=n;let s=o();s&&(e.value=s.sql,P(),v(),ft(s.lastResult,t)),a(),c(),e.focus({preventScroll:!0})},u=(n=null,s=``,l=!1)=>{let u=o();u&&(u.sql=e.value);let d=`tab-${Date.now()}`,f={id:d,title:n||`Untitled query ${r.length+1}`,sql:s||`SELECT * FROM users LIMIT 50;`,isDirty:!1,isPreview:!!l,lastResult:null};r.push(f),i=d,e.value=f.sql,P(),v(),ft(null,t),a(),c(),e.focus({preventScroll:!0})},d=(n,i,s=!1)=>{let d=o(),f=d&&!d.isDirty&&d.title.startsWith(`Untitled query`)&&(d.sql.trim()===``||d.sql.trim()===`SELECT 1 + 1 AS ping;`),p=r.find(e=>e.isPreview);if(s&&p){p.title=n,p.sql=i,p.lastResult=null,p.isDirty=!1,l(p.id);return}f?(d.title=n||d.title,d.sql=i,d.lastResult=null,d.isPreview=!!s,e.value=i,P(),v(),ft(null,t),a(),c(),e.focus({preventScroll:!0})):u(n,i,s)},f=n=>{let s=r.findIndex(e=>e.id===n);if(s===-1)return;if(r.splice(s,1),r.length===0)r.push({id:`tab-${Date.now()}`,title:`Untitled query 1`,sql:`SELECT 1 + 1 AS ping;`,isDirty:!1,lastResult:null}),i=r[0].id;else if(i===n){let e=Math.max(0,s-1);i=r[e].id}let l=o();e.value=l.sql,P(),v(),ft(l.lastResult,t),a(),c(),e.focus({preventScroll:!0})},p=document.getElementById(`console-add-tab-btn`);p&&(p.onclick=()=>u());let m=document.getElementById(`console-new-query-btn`);m&&(m.onclick=()=>u());let h=document.getElementById(`sql-line-numbers`),g=e=>{let t=e.split(`
1727
- `),n=[],r=[],i=0;for(let e=0;e<t.length;e++){n.push(i);let a=t[e].length;i+=a,e<t.length-1&&(i+=1),r.push(i)}return{lines:t,starts:n,ends:r}},_=()=>{if(!h)return;let t=e.selectionStart,n=e.selectionEnd,{starts:r,ends:i}=g(e.value);h.querySelectorAll(`.sql-line-num`).forEach((e,a)=>{let o=r[a],s=i[a];t!==n&&Math.max(t,o)<Math.min(n,s)?e.classList.add(`selected`):e.classList.remove(`selected`)})},v=()=>{if(!h)return;let t=e.value.split(`
1728
- `).length,n=``;for(let e=1;e<=t;e++)n+=`<div class="sql-line-num" data-line="${e}">${e}</div>`;h.innerHTML=n,_()};if(e.addEventListener(`scroll`,()=>{h&&(h.scrollTop=e.scrollTop)}),h){let t=!1,n=1,r=t=>{let n=h.getBoundingClientRect(),r=t.clientY-n.top+h.scrollTop-12,i=e.value.split(`
1729
- `).length,a=Math.floor(r/19.5)+1;return Math.max(1,Math.min(i,a))},i=i=>{if(i.button!==0)return;i.preventDefault();let s=r(i);n=s,t=!0;let{starts:c,ends:l}=g(e.value),u=c[s-1]??0,d=l[s-1]??e.value.length;e.focus({preventScroll:!0}),e.setSelectionRange(u,d),C(),window.addEventListener(`mousemove`,a),window.addEventListener(`mouseup`,o)},a=i=>{if(!t)return;let a=r(i),{starts:o,ends:s}=g(e.value);if(a>=n){let t=o[n-1]??0,r=s[a-1]??e.value.length;e.setSelectionRange(t,r,`forward`)}else{let t=o[a-1]??0,r=s[n-1]??e.value.length;e.setSelectionRange(t,r,`backward`)}C()},o=()=>{t&&(t=!1,window.removeEventListener(`mousemove`,a),window.removeEventListener(`mouseup`,o))};h.addEventListener(`mousedown`,i)}let b=``,x=(e,t)=>{if(!e||!e.includes(`;`))return e.trim();let n=[],r=0,i=!1,a=!1;for(let t=0;t<e.length;t++){let o=e[t],s=t>0?e[t-1]:``;o===`'`&&!a&&s!==`\\`?i=!i:o===`"`&&!i&&s!==`\\`?a=!a:o===`;`&&!i&&!a&&(n.push({start:r,end:t+1,sql:e.slice(r,t+1).trim()}),r=t+1)}if(r<e.length){let t=e.slice(r).trim();t&&n.push({start:r,end:e.length,sql:t})}return n.find(e=>t>=e.start&&t<=e.end)?.sql||n[n.length-1]?.sql||e.trim()},C=()=>{let t=e.selectionStart,n=e.selectionEnd,r=document.getElementById(`run-sql-btn-text`);if(_(),typeof t==`number`&&typeof n==`number`&&t!==n){let i=e.value.substring(t,n).trim();if(i){b=i,r&&(r.textContent=`Run Selection`);return}}b=``,r&&(r.textContent=`Run`)},w=async()=>{let n=b;if(!n){let t=e.selectionStart,r=e.selectionEnd;typeof t==`number`&&typeof r==`number`&&t!==r&&(n=e.value.substring(t,r).trim())}if(!n){let t=e.value.trim();t&&(n=x(e.value,e.selectionStart)||t)}if(n){let r=o();r&&r.isPreview&&(r.isPreview=!1,a(),c());let i=await pt(n,e,t,!1,e=>{r&&(r.lastResult=e,r.isDirty=!1,a(),c())});i&&r&&(r.lastResult=i,r.isDirty=!1,a(),c()),loadAndRenderHistory()}P()},T=document.getElementById(`run-sql-btn`);T&&(T.onclick=()=>w());let E=document.getElementById(`explain-sql-btn`);E&&(E.onclick=async()=>{let n=b;if(!n){let t=e.selectionStart,r=e.selectionEnd;typeof t==`number`&&typeof r==`number`&&t!==r&&(n=e.value.substring(t,r).trim())}if(!n){let t=e.value.trim();t&&(n=x(e.value,e.selectionStart)||t)}if(n){let r=o(),i=await mt(n,e,t,e=>{r&&(r.lastResult=e,a())});i&&r&&(r.lastResult=i,a())}});let D=document.getElementById(`console-safe-toggle-btn`),O=document.getElementById(`console-safe-text`),k=()=>{D&&(it()?(D.className=`console-safe-shield-btn active`,D.title=`Safe Mode: Protection ON (Destructive queries will prompt for confirmation)`,O&&(O.textContent=`Safe Mode ON`)):(D.className=`console-safe-shield-btn disabled`,D.title=`Safe Mode: Protection OFF (Click to re-enable guard)`,O&&(O.textContent=`Safe Mode OFF`)))};D&&(k(),D.onclick=()=>{let e=it();at(!e),k(),window.showToast&&window.showToast(e?`Safe Mode disabled (Guard OFF)`:`Safe Mode enabled (Destructive query guard ON)`,e?`info`:`success`)},window.addEventListener(`drixio-safemode-changed`,k));let j=document.getElementById(`console-save-snippet-btn`),M=()=>{let t=o();gt({defaultTitle:t?.title||`Untitled query`,defaultSql:e.value,onSaved:()=>{t&&(t.isDirty=!1,t.isPreview=!1,a(),c()),Ee()}})};j&&(j.onclick=M);let N=document.getElementById(`sql-highlight-layer`),P=()=>{let t=e.value;if(t===``){N&&(N.innerHTML=``);return}t=t.replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`);let n=RegExp(`('.*?'|".*?")|\\b(\\d+)\\b|\\b(${`SELECT.FROM.WHERE.AND.OR.IN.NOT.NULL.IS.ORDER.BY.GROUP.ASC.DESC.LIMIT.OFFSET.JOIN.INNER.LEFT.RIGHT.ON.AS.CREATE.TABLE.DROP.ALTER.INSERT.INTO.VALUES.UPDATE.SET.DELETE.PRAGMA.EXPLAIN.QUERY.PLAN.WITH.UNION.ALL.HAVING.LIKE.BETWEEN.EXISTS.CASE.WHEN.THEN.ELSE.END.CAST.DEFAULT.PRIMARY.KEY.FOREIGN.UNIQUE.CHECK.REFERENCES.AUTOINCREMENT.COUNT.SUM.AVG.MIN.MAX.COALESCE.BEGIN.COMMIT.ROLLBACK.INDEX.VIEW.TRIGGER.REPLACE.CROSS.FULL.OUTER`.split(`.`).join(`|`)})\\b`,`gi`);t=t.replace(n,(e,t,n,r)=>t?`<span class="hl-string">${t}</span>`:n?`<span class="hl-number">${n}</span>`:r?`<span class="hl-keyword">${r.toUpperCase()}</span>`:e),t.endsWith(`
1730
- `)&&(t+=` `),N&&(N.innerHTML=t)},F=document.getElementById(`console-autocomplete-popup`),I=0,L=[],R=null,ee=`SELECT.FROM.WHERE.INSERT INTO.UPDATE.SET.DELETE FROM.JOIN.LEFT JOIN.RIGHT JOIN.INNER JOIN.ON.ORDER BY.GROUP BY.HAVING.LIMIT.OFFSET.AND.OR.NOT.IN.IS NULL.IS NOT NULL.LIKE.BETWEEN.EXISTS.CREATE TABLE.ALTER TABLE.DROP TABLE.PRIMARY KEY.FOREIGN KEY.COUNT(*).SUM().AVG().DISTINCT.VALUES.EXPLAIN`.split(`.`),te=()=>{let e=document.querySelectorAll(`.table-btn[data-table]`);return Array.from(e).map(e=>e.getAttribute(`data-table`)).filter(Boolean)},ne=()=>{F&&(F.classList.add(`hidden`),F.innerHTML=``),L=[],I=0,R=null},re=()=>{if(!F||L.length===0){ne();return}F.innerHTML=L.map((e,t)=>`
1731
- <div class="autocomplete-item ${t===I?`active`:``}" data-idx="${t}">
2071
+ `).join(``),e.querySelectorAll(`.history-item`).forEach(e=>{let t=parseInt(e.getAttribute(`data-idx`)||`0`,10),r=n[t];if(!r)return;e.onclick=e=>{e.target.closest(`.query-item-delete-btn`)||sn&&sn(r)};let i=e.querySelector(`.query-item-delete-btn`);i&&(i.onclick=e=>{e.stopPropagation(),window.AppState.queryHistory.splice(t,1),on(window.AppState.queryHistory),un()})})}var dn=`drixio_ai_config`,fn={deepseek:{name:`DeepSeek`,baseUrl:`https://api.deepseek.com/v1`,model:`deepseek-chat`,placeholderKey:`sk-... (DeepSeek API Key)`,badge:`Recommended`},ollama:{name:`Ollama (Local Offline)`,baseUrl:`http://localhost:11434/v1`,model:`llama3`,placeholderKey:`ollama (no key needed)`,badge:`100% Free`},openai:{name:`OpenAI`,baseUrl:`https://api.openai.com/v1`,model:`gpt-4o-mini`,placeholderKey:`sk-... (OpenAI API Key)`},custom:{name:`Custom OpenAI-Compatible`,baseUrl:`https://your-api.com/v1`,model:`gpt-3.5-turbo`,placeholderKey:`Your API key`}};function pn(){try{let e=localStorage.getItem(dn);if(e)return JSON.parse(e)}catch{}return{provider:`deepseek`,baseUrl:fn.deepseek.baseUrl,apiKey:``,model:fn.deepseek.model}}function mn(e){try{localStorage.setItem(dn,JSON.stringify(e))}catch{}}function hn(e){let t=pn(),n=t.provider||`deepseek`,r=$t({id:`ai-config-modal-overlay`,className:`ai-config-modal`,icon:`smart_toy`,iconColor:`primary`,title:`AI Assistant Settings`,subtitle:`Configure AI models for Text-to-SQL, query explain, and auto-repair`,badge:`OPT-IN`,width:`560px`,body:`
2072
+ <div style="display: flex; flex-direction: column; gap: 16px;">
2073
+ <!-- Provider Presets -->
2074
+ <div>
2075
+ <label class="form-label" style="font-size: 11px; font-weight: 700; color: var(--color-text-secondary); text-transform: uppercase; letter-spacing: 0.05em; display: block; margin-bottom: 8px;">Select Provider</label>
2076
+ <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 8px;" id="ai-provider-options">
2077
+ ${Object.entries(fn).map(([e,t])=>`
2078
+ <button type="button" class="ai-provider-card ${e===n?`selected`:``}" data-provider="${e}">
2079
+ <div class="flex items-center justify-between">
2080
+ <span class="font-medium text-13">${t.name}</span>
2081
+ ${t.badge?`<span class="ai-provider-badge">${t.badge}</span>`:``}
2082
+ </div>
2083
+ <div class="text-11 text-secondary mt-1 font-mono" style="opacity: 0.8;">${t.model}</div>
2084
+ </button>
2085
+ `).join(``)}
2086
+ </div>
2087
+ </div>
2088
+
2089
+ <!-- Base URL Input -->
2090
+ <div>
2091
+ <label class="form-label" for="ai-base-url-input" style="font-size: 12px; font-weight: 600; color: var(--color-text-secondary); display: block; margin-bottom: 6px;">Base URL</label>
2092
+ <input type="text" id="ai-base-url-input" class="modal-input font-mono" value="${t.baseUrl||``}" placeholder="https://api.deepseek.com/v1" style="width: 100%; height: 36px; padding: 0 10px; font-size: 12.5px;" spellcheck="false" autocomplete="off" />
2093
+ </div>
2094
+
2095
+ <!-- API Key Input -->
2096
+ <div>
2097
+ <label class="form-label" for="ai-api-key-input" style="font-size: 12px; font-weight: 600; color: var(--color-text-secondary); display: block; margin-bottom: 6px;">API Key</label>
2098
+ <div style="position: relative; display: flex; align-items: center;">
2099
+ <input type="password" id="ai-api-key-input" class="modal-input font-mono" value="${t.apiKey||``}" placeholder="Enter your API Key..." style="width: 100%; height: 36px; padding: 0 38px 0 10px; font-size: 12.5px;" spellcheck="false" autocomplete="off" />
2100
+ <button type="button" id="btn-toggle-key-visibility" class="modal-input-icon-btn" style="position: absolute; right: 6px; background: transparent; border: none; color: var(--color-text-soft); cursor: pointer; display: flex; align-items: center;" title="Show/hide key">
2101
+ <span class="material-symbols-outlined" style="font-size: 16px;">visibility</span>
2102
+ </button>
2103
+ </div>
2104
+ <div class="text-11 text-secondary mt-2" style="opacity: 0.75;">Stored safely in your local browser storage. Never sent to any third party.</div>
2105
+ </div>
2106
+
2107
+ <!-- Model Name Input -->
2108
+ <div>
2109
+ <label class="form-label" for="ai-model-input" style="font-size: 12px; font-weight: 600; color: var(--color-text-secondary); display: block; margin-bottom: 6px;">Model Name</label>
2110
+ <input type="text" id="ai-model-input" class="modal-input font-mono" value="${t.model||``}" placeholder="deepseek-chat" style="width: 100%; height: 36px; padding: 0 10px; font-size: 12.5px;" spellcheck="false" autocomplete="off" />
2111
+ </div>
2112
+
2113
+ <!-- Test Connection Diagnostic Bar -->
2114
+ <div id="ai-test-status" class="ai-test-status hidden" style="padding: 10px 14px; border-radius: 6px; font-size: 12px;"></div>
2115
+ </div>
2116
+ `,footer:`
2117
+ <div class="flex items-center justify-between w-full">
2118
+ <button type="button" id="btn-ai-test-connection" class="btn-secondary flex items-center gap-1.5" style="padding: 6px 12px; font-size: 12px;">
2119
+ <span class="material-symbols-outlined" style="font-size: 15px;">wifi_tethering</span>
2120
+ <span>Test Connection</span>
2121
+ </button>
2122
+ <div class="flex items-center gap-2">
2123
+ <button type="button" id="cancel-ai-config-btn" class="btn-secondary">Cancel</button>
2124
+ <button type="button" id="save-ai-config-btn" class="btn-primary flex items-center gap-1.5">
2125
+ <span class="material-symbols-outlined" style="font-size: 16px;">check</span>
2126
+ <span>Save Settings</span>
2127
+ </button>
2128
+ </div>
2129
+ </div>
2130
+ `}),i=document.getElementById(`cancel-ai-config-btn`),a=document.getElementById(`save-ai-config-btn`),o=document.getElementById(`btn-ai-test-connection`),s=document.getElementById(`btn-toggle-key-visibility`),c=document.getElementById(`ai-api-key-input`),l=document.getElementById(`ai-base-url-input`),u=document.getElementById(`ai-model-input`),d=document.getElementById(`ai-test-status`);i&&(i.onclick=()=>r.close()),s&&c&&(s.onclick=()=>{let e=c.type===`password`;c.type=e?`text`:`password`;let t=s.querySelector(`.material-symbols-outlined`);t&&(t.textContent=e?`visibility_off`:`visibility`)});let f=n,p=document.getElementById(`ai-config-modal-overlay`);p&&p.querySelectorAll(`.ai-provider-card`).forEach(e=>{e.onclick=()=>{p.querySelectorAll(`.ai-provider-card`).forEach(e=>e.classList.remove(`selected`)),e.classList.add(`selected`),f=e.dataset.provider;let t=fn[f];t&&(l&&(l.value=t.baseUrl),u&&(u.value=t.model),c&&(c.placeholder=t.placeholderKey,f===`ollama`&&!c.value&&(c.value=`ollama`)))}}),o&&(o.onclick=async()=>{let e={provider:f,baseUrl:l?l.value.trim():``,apiKey:c?c.value.trim():``,model:u?u.value.trim():``};o.disabled=!0,o.innerHTML=`<span class="material-symbols-outlined animate-spin" style="font-size: 15px;">progress_activity</span><span>Testing...</span>`,d&&(d.className=`ai-test-status hidden`);try{let t=await N(e);o.disabled=!1,o.innerHTML=`<span class="material-symbols-outlined" style="font-size: 15px;">wifi_tethering</span><span>Test Connection</span>`,d&&(d.classList.remove(`hidden`),t.success?(d.className=`ai-test-status success`,d.innerHTML=`✓ ${t.message||`Connected successfully!`}`):(d.className=`ai-test-status error`,d.innerHTML=`✕ Test failed: ${t.error||`Check Base URL and API Key`}`))}catch(e){o.disabled=!1,o.innerHTML=`<span class="material-symbols-outlined" style="font-size: 15px;">wifi_tethering</span><span>Test Connection</span>`,d&&(d.classList.remove(`hidden`),d.className=`ai-test-status error`,d.innerHTML=`✕ Test error: ${e.message}`)}}),a&&(a.onclick=()=>{let t={provider:f,baseUrl:l?l.value.trim():``,apiKey:c?c.value.trim():``,model:u?u.value.trim():``};mn(t),window.showToast?.(`AI settings saved successfully!`,`success`),r.close(),e&&e(t)})}var gn=null,_n=null,vn=null,q=[],yn=!1,bn=``;function xn({editorTextarea:e,highlightLayer:t,currentTable:n,onRunQuery:r,onInsertSql:i}){if(gn){Sn();return}Cn({editorTextarea:e,highlightLayer:t,currentTable:n,onRunQuery:r,onInsertSql:i})}function Sn(){vn&&=(document.removeEventListener(`keydown`,vn),null),_n&&=(_n.remove(),null),gn&&=(gn.remove(),null);let e=document.getElementById(`console-ai-btn`);e&&e.classList.remove(`active`)}function Cn({editorTextarea:e,highlightLayer:t,currentTable:n,onRunQuery:r,onInsertSql:i,initialPrompt:a=``}){Sn();let o=document.querySelector(`.sql-editor-wrapper`);if(!o)return;let s=document.createElement(`div`);s.id=`console-ai-chat-panel`,s.className=`console-ai-chat-panel`;let c=localStorage.getItem(`drixio_ai_panel_width`);if(c){let e=parseInt(c,10);!isNaN(e)&&e>=280&&e<=800&&(s.style.width=`${e}px`)}let l=document.createElement(`div`);l.id=`console-ai-v-resizer`,l.className=`console-ai-v-resizer`,l.title=`Drag to resize AI Assistant width (Double click to reset)`,l.innerHTML=`<div class="console-ai-v-pill"></div>`,wn(l,s),_n=l,gn=s,o.appendChild(l),o.appendChild(s);let u=document.getElementById(`console-ai-btn`);u&&u.classList.add(`active`),Dn({editorTextarea:e,highlightLayer:t,currentTable:n,onRunQuery:r,onInsertSql:i}),vn=e=>{if(e.key===`Escape`&&gn){if(document.querySelector(`.modal-overlay:not(.hidden), .command-palette-container.is-open`))return;window.AppState?.currentTab===`sql-btn`&&Sn()}},document.addEventListener(`keydown`,vn),a&&jn(a,{editorTextarea:e,currentTable:n,onRunQuery:r,onInsertSql:i})}function wn(e,t){let n=!1,r=0,i=0,a=a=>{a.button===0&&(n=!0,r=a.clientX,i=t.getBoundingClientRect().width,e.classList.add(`is-dragging`),document.body.style.userSelect=`none`,document.body.style.cursor=`col-resize`,window.addEventListener(`mousemove`,o),window.addEventListener(`mouseup`,s))},o=e=>{if(!n)return;let a=r-e.clientX,o=i+a,s=Math.min(800,window.innerWidth*.65);o=Math.max(280,Math.min(o,s)),t.style.width=`${o}px`},s=()=>{if(!n)return;n=!1,e.classList.remove(`is-dragging`),document.body.style.userSelect=``,document.body.style.cursor=``,window.removeEventListener(`mousemove`,o),window.removeEventListener(`mouseup`,s);let r=Math.round(t.getBoundingClientRect().width);localStorage.setItem(`drixio_ai_panel_width`,r.toString())};e.addEventListener(`mousedown`,a),e.addEventListener(`dblclick`,()=>{t.style.width=`380px`,localStorage.setItem(`drixio_ai_panel_width`,`380`),window.showToast?.(`Reset AI panel width to 380px`,`info`)})}function Tn(){let e=pn();return e.model?e.model:e.provider===`deepseek`?`deepseek-chat`:e.provider===`ollama`?`llama3`:e.provider===`openai`?`gpt-4o-mini`:`AI Copilot`}function En(e){return e?[{icon:`bar_chart`,label:`Count total records in ${e}`,prompt:`Count total records in ${e}`},{icon:`schedule`,label:`Recent records in ${e}`,prompt:`Find the most recent 10 records from ${e} ordered by primary key or created date`},{icon:`filter_alt`,label:`Select non-null active records`,prompt:`Select all columns from ${e} where status is active or non-null limit 50`}]:[{icon:`table_rows`,label:`Count all tables and rows`,prompt:`Count rows for all tables and summarize record counts`},{icon:`query_stats`,label:`Summary stats of database`,prompt:`Select summary statistics from primary data tables`},{icon:`join_inner`,label:`Join primary tables`,prompt:`Write a JOIN query between the main tables based on foreign keys`}]}function Dn(e){if(!gn)return;let t=Tn(),n=En(e.currentTable||window.AppState?.currentTable);gn.innerHTML=`
2131
+ <!-- Panel Header -->
2132
+ <div class="ai-panel-header">
2133
+ <div class="ai-panel-header-left">
2134
+ <div class="ai-panel-title-icon">
2135
+ <span class="material-symbols-outlined">auto_awesome</span>
2136
+ </div>
2137
+ <span class="ai-panel-title">AI Assistant</span>
2138
+ <button type="button" class="ai-panel-model-pill" id="ai-panel-model-pill" title="Configure AI Model & API Key">
2139
+ <span>${Nn(t)}</span>
2140
+ <span class="material-symbols-outlined" style="font-size: 11px;">tune</span>
2141
+ </button>
2142
+ </div>
2143
+ <div class="ai-panel-header-right">
2144
+ <button type="button" id="btn-ai-panel-reset" class="ai-panel-icon-btn" title="New Chat (Clear Conversation)">
2145
+ <span class="material-symbols-outlined" style="font-size: 15px;">restart_alt</span>
2146
+ </button>
2147
+ <button type="button" id="btn-ai-panel-settings" class="ai-panel-icon-btn" title="AI Settings">
2148
+ <span class="material-symbols-outlined" style="font-size: 15px;">settings</span>
2149
+ </button>
2150
+ <button type="button" id="btn-ai-panel-close" class="ai-panel-icon-btn" title="Close Panel (Esc)">
2151
+ <span class="material-symbols-outlined" style="font-size: 16px;">close</span>
2152
+ </button>
2153
+ </div>
2154
+ </div>
2155
+
2156
+ <!-- Messages Area -->
2157
+ <div class="ai-panel-messages" id="ai-panel-messages">
2158
+ ${q.length===0?`
2159
+ <div class="ai-panel-welcome">
2160
+ <div class="ai-panel-welcome-card">
2161
+ <div class="ai-panel-welcome-badge">
2162
+ <span class="material-symbols-outlined" style="font-size: 14px;">psychology</span>
2163
+ <span>Ready to Assist</span>
2164
+ </div>
2165
+ <h4>Ask AI to write or fix SQL</h4>
2166
+ <p>Type your query request in plain English or Chinese. Contextual suggestions below:</p>
2167
+ <div class="ai-panel-chips">
2168
+ ${n.map(e=>`
2169
+ <button type="button" class="ai-panel-chip" data-prompt="${Pn(e.prompt)}">
2170
+ <span class="material-symbols-outlined">${e.icon}</span>
2171
+ <span>${Nn(e.label)}</span>
2172
+ </button>
2173
+ `).join(``)}
2174
+ </div>
2175
+ </div>
2176
+ </div>
2177
+ `:On()}
2178
+
2179
+ ${yn?`
2180
+ <div class="ai-panel-msg-loading">
2181
+ <span class="material-symbols-outlined animate-spin">progress_activity</span>
2182
+ <span>${Nn(bn||`Generating SQL query...`)}</span>
2183
+ </div>
2184
+ `:``}
2185
+ </div>
2186
+
2187
+ <!-- Footer / Input Area -->
2188
+ <div class="ai-panel-footer">
2189
+ <div class="ai-panel-input-container">
2190
+ <textarea
2191
+ id="ai-panel-textarea"
2192
+ class="ai-panel-textarea"
2193
+ placeholder="${q.length>0?`Ask follow-up or refine query...`:`Describe query to generate...`}"
2194
+ rows="1"
2195
+ ></textarea>
2196
+ <button
2197
+ type="button"
2198
+ id="btn-ai-panel-send"
2199
+ class="ai-panel-send-btn"
2200
+ title="Send message (Enter)"
2201
+ ${yn?`disabled`:``}
2202
+ >
2203
+ <span class="material-symbols-outlined" style="font-size: 16px;">arrow_upward</span>
2204
+ </button>
2205
+ </div>
2206
+ <div class="ai-panel-hints">
2207
+ <span><b>↵</b> to send &middot; <b>Shift+↵</b> newline</span>
2208
+ <span><b>Esc</b> close</span>
2209
+ </div>
2210
+ </div>
2211
+ `,kn(e),An()}function On(){return q.map((e,t)=>e.role===`user`?`
2212
+ <div class="ai-panel-msg-row ai-panel-msg-user">
2213
+ <div class="ai-panel-msg-bubble">
2214
+ <div class="ai-panel-msg-text">${Nn(e.content)}</div>
2215
+ </div>
2216
+ </div>
2217
+ `:`
2218
+ <div class="ai-panel-msg-row ai-panel-msg-assistant" data-msg-idx="${t}">
2219
+ <div class="ai-panel-msg-bubble">
2220
+ ${e.explanation?`<div class="ai-panel-msg-text">${Nn(e.explanation)}</div>`:``}
2221
+ ${e.sql?`
2222
+ <div class="ai-panel-code-block">
2223
+ <div class="ai-panel-code-header">
2224
+ <span class="ai-panel-code-lang">SQL</span>
2225
+ <button type="button" class="ai-panel-copy-btn" data-sql="${Pn(e.sql)}">
2226
+ <span class="material-symbols-outlined" style="font-size: 13px;">content_copy</span>
2227
+ <span>Copy</span>
2228
+ </button>
2229
+ </div>
2230
+ <pre class="ai-panel-code-pre"><code>${Nn(e.sql)}</code></pre>
2231
+ <div class="ai-panel-code-actions">
2232
+ <button type="button" class="ai-panel-action-btn" data-action="save" data-sql="${Pn(e.sql)}" title="Save as reusable query snippet">
2233
+ <span class="material-symbols-outlined" style="font-size: 13px;">bookmark_add</span>
2234
+ <span>Save</span>
2235
+ </button>
2236
+ <button type="button" class="ai-panel-action-btn" data-action="insert" data-sql="${Pn(e.sql)}" title="Insert query into editor">
2237
+ <span class="material-symbols-outlined" style="font-size: 13px;">input</span>
2238
+ <span>Insert</span>
2239
+ </button>
2240
+ <button type="button" class="ai-panel-action-btn primary" data-action="run" data-sql="${Pn(e.sql)}" title="Execute query directly">
2241
+ <span class="material-symbols-outlined" style="font-size: 13px;">play_arrow</span>
2242
+ <span>Run</span>
2243
+ </button>
2244
+ </div>
2245
+ </div>
2246
+ `:``}
2247
+ ${e.isError?`
2248
+ <div class="ai-panel-msg-error">
2249
+ <span class="material-symbols-outlined">error</span>
2250
+ <span>${Nn(e.content)}</span>
2251
+ </div>
2252
+ `:``}
2253
+ </div>
2254
+ </div>
2255
+ `).join(``)}function kn(e){if(!gn)return;let t=document.getElementById(`btn-ai-panel-close`),n=document.getElementById(`btn-ai-panel-settings`),r=document.getElementById(`ai-panel-model-pill`),i=document.getElementById(`btn-ai-panel-reset`),a=document.getElementById(`ai-panel-textarea`),o=document.getElementById(`btn-ai-panel-send`);t?.addEventListener(`click`,Sn);let s=()=>{hn(()=>{Dn(e)})};n?.addEventListener(`click`,s),r?.addEventListener(`click`,s),i?.addEventListener(`click`,()=>{q=[],Dn(e)}),gn.querySelectorAll(`.ai-panel-chip`).forEach(t=>{t.addEventListener(`click`,()=>{let n=t.getAttribute(`data-prompt`);n&&jn(n,e)})}),gn.querySelectorAll(`.ai-panel-copy-btn`).forEach(e=>{e.addEventListener(`click`,()=>{let t=e.getAttribute(`data-sql`);t&&navigator.clipboard?.writeText(t).then(()=>{let t=e.innerHTML;e.innerHTML=`<span class="material-symbols-outlined" style="font-size: 13px; color: #10b981;">check</span><span style="color: #10b981;">Copied</span>`,setTimeout(()=>{e.innerHTML=t},1600)})})}),gn.querySelectorAll(`.ai-panel-action-btn`).forEach(t=>{let n=t.getAttribute(`data-action`),r=t.getAttribute(`data-sql`);r&&(n===`save`?t.addEventListener(`click`,()=>{let e=t.closest(`.ai-panel-msg-assistant`)?.dataset.msgIdx,n=((e===void 0?null:q[parseInt(e,10)])?.explanation||`AI Query`).replace(/[`*#\r\n]/g,` `).replace(/\s+/g,` `).trim().slice(0,36)||`AI Query`;Qt({defaultSql:r,defaultTitle:n,onSaved:()=>{window.showToast?.(`Saved query to Saved Queries`,`success`)}})}):n===`insert`?t.addEventListener(`click`,()=>{e.onInsertSql?e.onInsertSql(r):e.editorTextarea&&(e.editorTextarea.value=r,e.editorTextarea.dispatchEvent(new Event(`input`,{bubbles:!0}))),window.showToast?.(`SQL inserted into editor`,`success`);let n=t.innerHTML;t.innerHTML=`<span class="material-symbols-outlined" style="font-size: 13px; color: #10b981;">check</span><span>Inserted</span>`,setTimeout(()=>{t.innerHTML=n},1600)}):n===`run`&&t.addEventListener(`click`,()=>{e.editorTextarea&&(e.editorTextarea.value=r,e.editorTextarea.dispatchEvent(new Event(`input`,{bubbles:!0}))),e.onRunQuery&&e.onRunQuery(r),window.showToast?.(`Running SQL query...`,`info`)}))}),a&&(a.addEventListener(`input`,()=>{a.style.height=`auto`,a.style.height=`${Math.min(a.scrollHeight,100)}px`}),a.addEventListener(`keydown`,t=>{if(t.key===`Enter`&&!t.shiftKey){t.preventDefault();let n=a.value.trim();n&&!yn&&jn(n,e)}else t.key===`Escape`&&Sn()}),setTimeout(()=>a.focus(),60)),o?.addEventListener(`click`,()=>{if(a){let t=a.value.trim();t&&!yn&&jn(t,e)}})}function An(){requestAnimationFrame(()=>{let e=document.getElementById(`ai-panel-messages`);e&&(e.scrollTop=e.scrollHeight)})}async function jn(e,t){if(!e||yn)return;let n=pn();if(!n.apiKey&&n.provider!==`ollama`){hn(()=>{jn(e,t)});return}q.push({role:`user`,content:e,timestamp:Date.now()}),yn=!0,bn=`Generating SQL query...`,Dn(t);let r=q.slice(0,-1).filter(e=>e.content||e.sql).map(e=>({role:e.role,content:e.sql?`SQL: ${e.sql}\nExplanation: ${e.explanation||``}`:e.content}));try{let i=await A({prompt:e,currentTable:t.currentTable||window.AppState?.currentTable,history:r,config:n});yn=!1,i.success&&i.data?q.push({role:`assistant`,explanation:i.data.explanation||``,sql:i.data.sql||``,model:i.data.model||n.model||`AI`,timestamp:Date.now()}):q.push({role:`assistant`,content:i.error||`Failed to generate query. Please check your AI API key and provider configuration.`,isError:!0,timestamp:Date.now()})}catch(e){yn=!1,q.push({role:`assistant`,content:e.message||`Network error while contacting AI API.`,isError:!0,timestamp:Date.now()})}Dn(t)}async function Mn({sql:e,error:t,editorTextarea:n,highlightLayer:r,currentTable:i,onRunQuery:a,onInsertSql:o}){let s=pn();if(!s.apiKey&&s.provider!==`ollama`){hn(()=>{Mn({sql:e,error:t,editorTextarea:n,highlightLayer:r,currentTable:i,onRunQuery:a,onInsertSql:o})});return}Cn({editorTextarea:n,highlightLayer:r,currentTable:i,onRunQuery:a,onInsertSql:o});let c=t?String(t).replace(/\s+/g,` `).trim():`Unknown error`,l=`Fix error in SQL query:\n${c}`;q.push({role:`user`,content:l,timestamp:Date.now()}),yn=!0,bn=`Diagnosing error and generating fix...`,Dn({editorTextarea:n,highlightLayer:r,currentTable:i,onRunQuery:a,onInsertSql:o});try{let t=await M({sql:e,error:c,currentTable:i||window.AppState?.currentTable,config:s});yn=!1,t.success&&t.data?q.push({role:`assistant`,explanation:t.data.explanation||`Fixed query error based on schema.`,sql:t.data.fixedSql||``,model:t.data.model||s.model||`AI`,timestamp:Date.now()}):q.push({role:`assistant`,content:t.error||`Failed to fix SQL error automatically.`,isError:!0,timestamp:Date.now()})}catch(e){yn=!1,q.push({role:`assistant`,content:e.message||`Network error while generating fix.`,isError:!0,timestamp:Date.now()})}Dn({editorTextarea:n,highlightLayer:r,currentTable:i,onRunQuery:a,onInsertSql:o})}function Nn(e){return e?String(e).replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`):``}function Pn(e){return e?String(e).replace(/&/g,`&amp;`).replace(/"/g,`&quot;`).replace(/'/g,`&#39;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`):``}function Fn({sql:e,currentTable:t,onApplyOptimized:n}){let r=(e||``).trim();if(!r){window.showToast?.(`Please enter or select a SQL query first`,`warning`);return}let i=pn();if(!i.apiKey&&i.provider!==`ollama`){hn(()=>{Fn({sql:e,currentTable:t,onApplyOptimized:n})});return}let a=!1,o=$t({id:`ai-explain-modal-overlay`,className:`ai-explain-modal`,icon:`auto_awesome`,iconColor:`primary`,title:`AI Query Explain & Optimize`,subtitle:`Analyzing execution logic, index utilization, and performance bottlenecks`,badge:(i.model||i.provider||`AI`).toUpperCase(),width:`680px`,onClose:()=>{a=!0},body:`
2256
+ <div class="ai-explain-loading" id="ai-explain-loading">
2257
+ <div class="ai-loading-spinner-wrap">
2258
+ <span class="material-symbols-outlined animate-spin" style="font-size: 28px; color: var(--primary, #2563eb);">progress_activity</span>
2259
+ </div>
2260
+ <div class="ai-loading-text">
2261
+ <h4>Analyzing query with ${In(i.model||`AI`)}...</h4>
2262
+ <p>Inspecting table schema, unindexed scans, and potential rewrites.</p>
2263
+ </div>
2264
+ </div>
2265
+ <div class="ai-explain-content hidden" id="ai-explain-content"></div>
2266
+ `,footer:`
2267
+ <div class="flex items-center justify-between w-full">
2268
+ <div class="ai-explain-footer-meta text-xs text-muted">
2269
+ Target Dialect: <strong>${In(window.AppState?.dialect||`sqlite`).toUpperCase()}</strong>
2270
+ </div>
2271
+ <div class="flex items-center gap-2">
2272
+ <button type="button" class="btn-secondary" id="btn-ai-explain-close">Close</button>
2273
+ <button type="button" class="btn-primary hidden" id="btn-ai-explain-apply">
2274
+ <span class="material-symbols-outlined icon-14">check</span>
2275
+ <span>Apply Optimized Query</span>
2276
+ </button>
2277
+ </div>
2278
+ </div>
2279
+ `}),s=document.getElementById(`btn-ai-explain-close`),c=document.getElementById(`btn-ai-explain-apply`),l=document.getElementById(`ai-explain-loading`),u=document.getElementById(`ai-explain-content`);s&&(s.onclick=()=>o.close()),j({sql:r,currentTable:t||window.AppState?.currentTable,config:i}).then(e=>{if(a||!l||!u)return;if(l.classList.add(`hidden`),u.classList.remove(`hidden`),!e.success||!e.data){u.innerHTML=`
2280
+ <div class="ai-explain-error">
2281
+ <span class="material-symbols-outlined" style="color: var(--color-error, #ef4444); font-size: 22px;">error</span>
2282
+ <div>
2283
+ <div class="font-semibold text-sm">Failed to analyze query</div>
2284
+ <div class="text-xs text-muted mt-0.5">${In(e.error||`Unknown error occurred`)}</div>
2285
+ </div>
2286
+ </div>
2287
+ `;return}let{explanation:t,performanceTips:i,optimizedSql:s}=e.data,d=Array.isArray(i)&&i.length>0?i.map(e=>`
2288
+ <li class="ai-tip-item">
2289
+ <span class="material-symbols-outlined ai-tip-icon">lightbulb</span>
2290
+ <span>${In(e)}</span>
2291
+ </li>
2292
+ `).join(``):`<li class="ai-tip-item text-muted">No obvious performance bottlenecks detected.</li>`,f=``;s&&s.trim()!==r&&(f=`
2293
+ <div class="ai-explain-section">
2294
+ <div class="ai-explain-section-title flex items-center justify-between">
2295
+ <span class="flex items-center gap-1.5 font-semibold text-xs text-primary">
2296
+ <span class="material-symbols-outlined icon-14">tune</span>
2297
+ <span>Optimized Query</span>
2298
+ </span>
2299
+ <button type="button" class="btn-copy-code" id="btn-copy-optimized" title="Copy SQL">
2300
+ <span class="material-symbols-outlined icon-12">content_copy</span>
2301
+ <span>Copy</span>
2302
+ </button>
2303
+ </div>
2304
+ <pre class="ai-optimized-sql font-mono">${In(s)}</pre>
2305
+ </div>
2306
+ `,c&&(c.classList.remove(`hidden`),c.onclick=()=>{n&&n(s),o.close(),window.showToast?.(`Applied optimized SQL to editor`,`success`)})),u.innerHTML=`
2307
+ <div class="ai-explain-section">
2308
+ <div class="ai-explain-section-title font-semibold text-xs text-muted uppercase tracking-wider">
2309
+ Query Explanation
2310
+ </div>
2311
+ <div class="ai-explain-body-text">
2312
+ ${In(t||`Analyzed query based on current schema.`)}
2313
+ </div>
2314
+ </div>
2315
+
2316
+ <div class="ai-explain-section">
2317
+ <div class="ai-explain-section-title font-semibold text-xs text-muted uppercase tracking-wider">
2318
+ Performance Diagnostics
2319
+ </div>
2320
+ <ul class="ai-tips-list">
2321
+ ${d}
2322
+ </ul>
2323
+ </div>
2324
+
2325
+ ${f}
2326
+ `;let p=document.getElementById(`btn-copy-optimized`);p&&(p.onclick=async()=>{try{await navigator.clipboard.writeText(s),window.showToast?.(`Optimized SQL copied to clipboard`,`success`)}catch{window.showToast?.(`Failed to copy SQL`,`error`)}})}).catch(e=>{a||!l||!u||(l.classList.add(`hidden`),u.classList.remove(`hidden`),u.innerHTML=`
2327
+ <div class="ai-explain-error">
2328
+ <span class="material-symbols-outlined" style="color: var(--color-error, #ef4444); font-size: 22px;">error</span>
2329
+ <div>
2330
+ <div class="font-semibold text-sm">Network or service error</div>
2331
+ <div class="text-xs text-muted mt-0.5">${In(e.message||`Check your AI connection or API key`)}</div>
2332
+ </div>
2333
+ </div>
2334
+ `)})}function In(e){return e?String(e).replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`).replace(/"/g,`&quot;`).replace(/'/g,`&#039;`):``}var Ln=(t,n)=>{let r=window.AppState.lastQuery||`SELECT 1 + 1 AS ping;`,i=[];try{let e=localStorage.getItem(`drixio_sql_tabs`);e&&(i=JSON.parse(e))}catch{i=[]}(!Array.isArray(i)||i.length===0)&&(i=[{id:`tab-1`,title:`Untitled query 1`,sql:r,isDirty:!1,lastResult:null}]);let a=localStorage.getItem(`drixio_active_tab_id`)||i[0].id;i.find(e=>e.id===a)||(a=i[0].id);let o=()=>{try{let e=i.map(e=>{let t=e.lastResult;return t&&t.data&&t.data.rows&&t.data.rows.length>100&&(t={...t,data:{...t.data,rows:t.data.rows.slice(0,100)}}),{id:e.id,title:e.title,sql:e.sql,isDirty:e.isDirty,isPreview:!!e.isPreview,lastResult:t}});localStorage.setItem(`drixio_sql_tabs`,JSON.stringify(e)),localStorage.setItem(`drixio_active_tab_id`,a)}catch(e){console.warn(`Failed to save tabs to localStorage`,e)}},s=()=>i.find(e=>e.id===a)||i[0],c=document.getElementById(`console-tabs-container`);c&&c.addEventListener(`wheel`,e=>{e.deltaY!==0&&(e.preventDefault(),c.scrollLeft+=e.deltaY)},{passive:!1});let l=()=>{c&&(c.innerHTML=``,i.forEach(e=>{let t=e.id===a,n=document.createElement(`div`);n.className=`console-tab ${t?`active`:``} ${e.isPreview?`preview`:``}`,n.dataset.tabId=e.id;let r=document.createElement(`span`);r.className=`material-symbols-outlined console-tab-icon`,r.textContent=`terminal`;let s=document.createElement(`span`);if(s.className=`console-tab-title`,s.textContent=e.title,s.title=e.isPreview?`Preview tab (double click or edit to keep)`:`Double click to rename, right click for options`,n.appendChild(r),n.appendChild(s),e.isDirty){let e=document.createElement(`span`);e.className=`tab-dirty-dot`,e.title=`Unsaved changes`,n.appendChild(e)}if(i.length>1){let t=document.createElement(`button`);t.type=`button`,t.className=`tab-close-btn`,t.title=`Close tab (Ctrl+W)`,t.innerHTML=`<span class="material-symbols-outlined" style="font-size: 14px;">close</span>`,t.onclick=t=>{t.stopPropagation(),p(e.id)},n.appendChild(t)}n.onclick=()=>{a!==e.id&&u(e.id)},n.addEventListener(`mousedown`,t=>{t.button===1&&(t.preventDefault(),t.stopPropagation(),p(e.id))}),n.oncontextmenu=t=>{t.preventDefault(),t.stopPropagation(),V(t,[{icon:`edit`,label:`Rename Tab`,shortcut:`Double Click`,action:()=>{s.dispatchEvent(new MouseEvent(`dblclick`,{bubbles:!0}))}},{icon:`content_copy`,label:`Duplicate Tab`,action:()=>{d(`${e.title} (Copy)`,e.sql)}},`divider`,{icon:`close`,label:`Close Tab`,shortcut:`Ctrl+W`,action:()=>{p(e.id)}},{icon:`close_fullscreen`,label:`Close Other Tabs`,disabled:i.length<=1,action:()=>{i=[e],a=e.id,o(),l()}},{icon:`playlist_remove`,label:`Close Tabs to Right`,disabled:i.indexOf(e)===i.length-1,action:()=>{let t=i.indexOf(e);i=i.slice(0,t+1),i.find(e=>e.id===a)||(a=e.id),o(),l()}}])},s.ondblclick=t=>{t.stopPropagation(),e.isPreview&&(e.isPreview=!1,o());let n=document.createElement(`input`);n.type=`text`,n.className=`console-tab-rename-input`,n.value=e.title,n.onblur=()=>{let t=n.value.trim();t&&(e.title=t),o(),l()},n.onkeydown=e=>{e.key===`Enter`?(e.preventDefault(),n.blur()):e.key===`Escape`&&(e.preventDefault(),l())},s.replaceWith(n),n.focus(),n.select()},c.appendChild(n),t&&setTimeout(()=>{n.scrollIntoView({behavior:`smooth`,block:`nearest`,inline:`nearest`})},0)}))},u=e=>{let r=s();r&&(r.sql=t.value),a=e;let i=s();i&&(t.value=i.sql,F(),y(),K(i.lastResult,n)),o(),l(),t.focus({preventScroll:!0})},d=(e=null,r=``,c=!1)=>{let u=s();u&&(u.sql=t.value);let d=`tab-${Date.now()}`,f={id:d,title:e||`Untitled query ${i.length+1}`,sql:r||`SELECT * FROM users LIMIT 50;`,isDirty:!1,isPreview:!!c,lastResult:null};i.push(f),a=d,t.value=f.sql,F(),y(),K(null,n),o(),l(),t.focus({preventScroll:!0})},f=(e,r,a=!1)=>{let c=s(),f=c&&!c.isDirty&&c.title.startsWith(`Untitled query`)&&(c.sql.trim()===``||c.sql.trim()===`SELECT 1 + 1 AS ping;`),p=i.find(e=>e.isPreview);if(a&&p){p.title=e,p.sql=r,p.lastResult=null,p.isDirty=!1,u(p.id);return}f?(c.title=e||c.title,c.sql=r,c.lastResult=null,c.isPreview=!!a,t.value=r,F(),y(),K(null,n),o(),l(),t.focus({preventScroll:!0})):d(e,r,a)},p=e=>{let r=i.findIndex(t=>t.id===e);if(r===-1)return;if(i.splice(r,1),i.length===0)i.push({id:`tab-${Date.now()}`,title:`Untitled query 1`,sql:`SELECT 1 + 1 AS ping;`,isDirty:!1,lastResult:null}),a=i[0].id;else if(a===e){let e=Math.max(0,r-1);a=i[e].id}let c=s();t.value=c.sql,F(),y(),K(c.lastResult,n),o(),l(),t.focus({preventScroll:!0})},m=document.getElementById(`console-add-tab-btn`);m&&(m.onclick=()=>d());let h=document.getElementById(`console-new-query-btn`);h&&(h.onclick=()=>d());let g=document.getElementById(`sql-line-numbers`),_=e=>{let t=e.split(`
2335
+ `),n=[],r=[],i=0;for(let e=0;e<t.length;e++){n.push(i);let a=t[e].length;i+=a,e<t.length-1&&(i+=1),r.push(i)}return{lines:t,starts:n,ends:r}},v=()=>{if(!g)return;let e=t.selectionStart,n=t.selectionEnd,{starts:r,ends:i}=_(t.value);g.querySelectorAll(`.sql-line-num`).forEach((t,a)=>{let o=r[a],s=i[a];e!==n&&Math.max(e,o)<Math.min(n,s)?t.classList.add(`selected`):t.classList.remove(`selected`)})},y=()=>{if(!g)return;let e=t.value.split(`
2336
+ `).length,n=``;for(let t=1;t<=e;t++)n+=`<div class="sql-line-num" data-line="${t}">${t}</div>`;g.innerHTML=n,v()};if(t.addEventListener(`scroll`,()=>{g&&(g.scrollTop=t.scrollTop)}),g){let e=!1,n=1,r=e=>{let n=g.getBoundingClientRect(),r=e.clientY-n.top+g.scrollTop-12,i=t.value.split(`
2337
+ `).length,a=Math.floor(r/19.5)+1;return Math.max(1,Math.min(i,a))},i=i=>{if(i.button!==0)return;i.preventDefault();let s=r(i);n=s,e=!0;let{starts:c,ends:l}=_(t.value),u=c[s-1]??0,d=l[s-1]??t.value.length;t.focus({preventScroll:!0}),t.setSelectionRange(u,d),S(),window.addEventListener(`mousemove`,a),window.addEventListener(`mouseup`,o)},a=i=>{if(!e)return;let a=r(i),{starts:o,ends:s}=_(t.value);if(a>=n){let e=o[n-1]??0,r=s[a-1]??t.value.length;t.setSelectionRange(e,r,`forward`)}else{let e=o[a-1]??0,r=s[n-1]??t.value.length;t.setSelectionRange(e,r,`backward`)}S()},o=()=>{e&&(e=!1,window.removeEventListener(`mousemove`,a),window.removeEventListener(`mouseup`,o))};g.addEventListener(`mousedown`,i)}let b=``,x=(e,t)=>{if(!e||!e.includes(`;`))return e.trim();let n=[],r=0,i=!1,a=!1;for(let t=0;t<e.length;t++){let o=e[t],s=t>0?e[t-1]:``;o===`'`&&!a&&s!==`\\`?i=!i:o===`"`&&!i&&s!==`\\`?a=!a:o===`;`&&!i&&!a&&(n.push({start:r,end:t+1,sql:e.slice(r,t+1).trim()}),r=t+1)}if(r<e.length){let t=e.slice(r).trim();t&&n.push({start:r,end:e.length,sql:t})}return n.find(e=>t>=e.start&&t<=e.end)?.sql||n[n.length-1]?.sql||e.trim()},S=()=>{let e=t.selectionStart,n=t.selectionEnd,r=document.getElementById(`run-sql-btn-text`);if(v(),typeof e==`number`&&typeof n==`number`&&e!==n){let i=t.value.substring(e,n).trim();if(i){b=i,r&&(r.textContent=`Run Selection`);return}}b=``,r&&(r.textContent=`Run`)},w=async(e=null)=>{let r=typeof e==`string`&&e.trim()?e.trim():b;if(!r){let e=t.selectionStart,n=t.selectionEnd;typeof e==`number`&&typeof n==`number`&&e!==n&&(r=t.value.substring(e,n).trim())}if(!r){let e=t.value.trim();e&&(r=x(t.value,t.selectionStart)||e)}if(r){let e=s();e&&e.isPreview&&(e.isPreview=!1,o(),l());let i=await Yt(r,t,n,!1,t=>{e&&(e.lastResult=t,e.isDirty=!1,o(),l())});i&&e&&(e.lastResult=i,e.isDirty=!1,o(),l()),loadAndRenderHistory()}F()},T=()=>{xn({editorTextarea:t,highlightLayer:document.getElementById(`sql-highlight-layer`),currentTable:window.AppState?.currentTable,onRunQuery:e=>w(e),onInsertSql:e=>{t.value=e,t.dispatchEvent(new Event(`input`,{bubbles:!0})),F(),y()}})};window.runQueryInConsole=(e,t=!0)=>{window.handleSwitchTab&&window.handleSwitchTab(`sql-btn`),f(`Console Query`,e,!1),t&&setTimeout(()=>{w(e)},100)},window.toggleConsoleAiBar=T;let D=document.getElementById(`console-ai-btn`);D&&(D.onclick=()=>T());let O=document.getElementById(`console-ai-explain-btn`);O&&(O.onclick=()=>{let e=b;if(!e){let n=t.selectionStart,r=t.selectionEnd;typeof n==`number`&&typeof r==`number`&&n!==r&&(e=t.value.substring(n,r).trim())}if(!e){let n=t.value.trim();n&&(e=x(t.value,t.selectionStart)||n)}Fn({sql:e,currentTable:window.AppState?.currentTable,onApplyOptimized:e=>{t.value=e,t.dispatchEvent(new Event(`input`,{bubbles:!0})),F(),y()}})}),n&&n.addEventListener(`click`,e=>{let n=e.target.closest(`#btn-fix-with-ai`);n&&(e.preventDefault(),Mn({sql:n.dataset.sql||t.value.trim(),error:n.dataset.error||``,editorTextarea:t,highlightLayer:document.getElementById(`sql-highlight-layer`),currentTable:window.AppState?.currentTable,onRunQuery:e=>w(e),onInsertSql:e=>{t.value=e,t.dispatchEvent(new Event(`input`,{bubbles:!0})),F(),y()}}))});let k=document.getElementById(`run-sql-btn`);k&&(k.onclick=()=>w());let A=document.getElementById(`explain-sql-btn`);A&&(A.onclick=async()=>{let e=b;if(!e){let n=t.selectionStart,r=t.selectionEnd;typeof n==`number`&&typeof r==`number`&&n!==r&&(e=t.value.substring(n,r).trim())}if(!e){let n=t.value.trim();n&&(e=x(t.value,t.selectionStart)||n)}if(e){let r=s(),i=await Xt(e,t,n,e=>{r&&(r.lastResult=e,o())});i&&r&&(r.lastResult=i,o())}});let j=document.getElementById(`console-safe-toggle-btn`),M=document.getElementById(`console-safe-text`),N=()=>{j&&(Vt()?(j.className=`console-safe-shield-btn active`,j.title=`Safe Mode: Protection ON (Destructive queries will prompt for confirmation)`,M&&(M.textContent=`Safe Mode ON`)):(j.className=`console-safe-shield-btn disabled`,j.title=`Safe Mode: Protection OFF (Click to re-enable guard)`,M&&(M.textContent=`Safe Mode OFF`)))};j&&(N(),j.onclick=()=>{let e=Vt();Ht(!e),N(),window.showToast&&window.showToast(e?`Safe Mode disabled (Guard OFF)`:`Safe Mode enabled (Destructive query guard ON)`,e?`info`:`success`)},window.addEventListener(`drixio-safemode-changed`,N));let ee=document.getElementById(`console-save-snippet-btn`),te=()=>{let e=s();Qt({defaultTitle:e?.title||`Untitled query`,defaultSql:t.value,onSaved:()=>{e&&(e.isDirty=!1,e.isPreview=!1,o(),l()),Ee()}})};ee&&(ee.onclick=te);let P=document.getElementById(`sql-highlight-layer`),F=()=>{let e=t.value;if(e===``){P&&(P.innerHTML=``);return}e=e.replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`);let n=RegExp(`('.*?'|".*?")|\\b(\\d+)\\b|\\b(${`SELECT.FROM.WHERE.AND.OR.IN.NOT.NULL.IS.ORDER.BY.GROUP.ASC.DESC.LIMIT.OFFSET.JOIN.INNER.LEFT.RIGHT.ON.AS.CREATE.TABLE.DROP.ALTER.INSERT.INTO.VALUES.UPDATE.SET.DELETE.PRAGMA.EXPLAIN.QUERY.PLAN.WITH.UNION.ALL.HAVING.LIKE.BETWEEN.EXISTS.CASE.WHEN.THEN.ELSE.END.CAST.DEFAULT.PRIMARY.KEY.FOREIGN.UNIQUE.CHECK.REFERENCES.AUTOINCREMENT.COUNT.SUM.AVG.MIN.MAX.COALESCE.BEGIN.COMMIT.ROLLBACK.INDEX.VIEW.TRIGGER.REPLACE.CROSS.FULL.OUTER`.split(`.`).join(`|`)})\\b`,`gi`);e=e.replace(n,(e,t,n,r)=>t?`<span class="hl-string">${t}</span>`:n?`<span class="hl-number">${n}</span>`:r?`<span class="hl-keyword">${r.toUpperCase()}</span>`:e),e.endsWith(`
2338
+ `)&&(e+=` `),P&&(P.innerHTML=e)},I=document.getElementById(`console-autocomplete-popup`),L=0,R=[],ne=null,z=`SELECT.FROM.WHERE.INSERT INTO.UPDATE.SET.DELETE FROM.JOIN.LEFT JOIN.RIGHT JOIN.INNER JOIN.ON.ORDER BY.GROUP BY.HAVING.LIMIT.OFFSET.AND.OR.NOT.IN.IS NULL.IS NOT NULL.LIKE.BETWEEN.EXISTS.CREATE TABLE.ALTER TABLE.DROP TABLE.PRIMARY KEY.FOREIGN KEY.COUNT(*).SUM().AVG().DISTINCT.VALUES.EXPLAIN`.split(`.`),B=()=>{let e=document.querySelectorAll(`.table-btn[data-table]`);return Array.from(e).map(e=>e.getAttribute(`data-table`)).filter(Boolean)},re=()=>{I&&(I.classList.add(`hidden`),I.innerHTML=``),R=[],L=0,ne=null},ie=()=>{if(!I||R.length===0){re();return}I.innerHTML=R.map((e,t)=>`
2339
+ <div class="autocomplete-item ${t===L?`active`:``}" data-idx="${t}">
1732
2340
  <div class="autocomplete-item-left">
1733
2341
  <span class="material-symbols-outlined autocomplete-item-icon">${e.icon}</span>
1734
2342
  <span class="autocomplete-item-text">${e.text}</span>
1735
2343
  </div>
1736
2344
  <span class="autocomplete-item-type">${e.type}</span>
1737
2345
  </div>
1738
- `).join(``),F.classList.remove(`hidden`),F.querySelectorAll(`.autocomplete-item`).forEach(e=>{e.onmousedown=t=>{t.preventDefault();let n=parseInt(e.dataset.idx,10);ae(n)}})},ie=()=>{let t=e.selectionStart,n=e.value.slice(0,t).match(/([a-zA-Z0-9_]+)$/);if(!n){ne();return}let r=n[1];R={prefix:r,start:t-r.length,end:t};let i=r.toLowerCase(),a=[];te().forEach(e=>{e.toLowerCase().startsWith(i)&&e.toLowerCase()!==i&&a.push({text:e,type:`table`,icon:`table_chart`})}),ee.forEach(e=>{e.toLowerCase().startsWith(i)&&e.toLowerCase()!==i&&a.push({text:e,type:`keyword`,icon:`code`})}),L=a.slice(0,8),I=0,L.length>0?re():ne()},ae=(t=I)=>{let n=L[t];if(!n||!R)return;let r=e.value.slice(0,R.start),i=e.value.slice(R.end),a=n.text+` `;e.value=r+a+i;let o=R.start+a.length;e.selectionStart=o,e.selectionEnd=o,ne(),P(),v(),e.focus({preventScroll:!0})},oe=document.getElementById(`console-cursor-pos`),se=document.getElementById(`console-sel-separator`),ce=document.getElementById(`console-selection-info`),le=document.getElementById(`console-status-dialect`),ue=document.getElementById(`console-format-sql-btn`),de=document.getElementById(`console-shortcuts-btn`),fe=()=>{if(!e)return;let t=e.selectionStart,n=e.selectionEnd,r=e.value,i=r.substring(0,n).split(`
1739
- `),a=i.length,o=i[i.length-1].length+1;if(oe&&(oe.textContent=`Ln ${a}, Col ${o}`),ce)if(typeof t==`number`&&typeof n==`number`&&t!==n){let e=Math.abs(n-t),i=r.substring(t,n).split(`
1740
- `).length;ce.textContent=i>1?`${e} selected (${i} lines)`:`${e} selected`,ce.classList.remove(`hidden`),se&&se.classList.remove(`hidden`)}else ce.classList.add(`hidden`),se&&se.classList.add(`hidden`);if(le){let e=window.AppState?.dbType||`SQLITE`;le.textContent=(e===`none`?`SQL`:e).toUpperCase()}},pe=e=>{if(!e||!e.trim())return e;let t=e.trim().replace(/\r\n/g,`
1741
- `),n=`SELECT.FROM.WHERE.AND.OR.ORDER BY.GROUP BY.LEFT JOIN.RIGHT JOIN.INNER JOIN.CROSS JOIN.FULL JOIN.JOIN.ON.AS.INSERT INTO.VALUES.UPDATE.SET.DELETE FROM.CREATE TABLE.DROP TABLE.ALTER TABLE.HAVING.LIMIT.OFFSET.UNION ALL.UNION.CASE.WHEN.THEN.ELSE.END.PRIMARY KEY.FOREIGN KEY.NOT NULL.DEFAULT.DESC.ASC.IN.IS NULL.IS NOT NULL.IS.LIKE.BETWEEN.EXISTS.COUNT.SUM.AVG.MIN.MAX.PRAGMA.EXPLAIN`.split(`.`),r=t.split(/('(?:''|[^'])*'|"(?:""|[^"])*")/g);for(let e=0;e<r.length;e+=2)r[e]&&n.forEach(t=>{let n=RegExp(`\\b${t}\\b`,`gi`);r[e]=r[e].replace(n,t)});return t=r.join(``),[`FROM`,`WHERE`,`GROUP BY`,`HAVING`,`ORDER BY`,`LIMIT`,`OFFSET`,`LEFT JOIN`,`RIGHT JOIN`,`INNER JOIN`,`CROSS JOIN`,`JOIN`,`SET`,`VALUES`].forEach(e=>{let n=RegExp(`[ \\t]+(${e}\\b)`,`g`);t=t.replace(n,`
1742
- $1`)}),t=t.replace(/[ \t]+(AND\b|OR\b)/g,`
1743
- $1`),t},me=()=>{let t=e.value,n=e.selectionStart,r=e.selectionEnd,i=!1;if(typeof n==`number`&&typeof r==`number`&&n!==r){let t=e.value.substring(n,r),a=pe(t);a!==t&&(e.setRangeText(a,n,r,`select`),i=!0)}else{let n=pe(e.value);n!==t&&(e.value=n,i=!0)}let s=o();s&&(s.sql=e.value,i&&(s.isDirty=!0,s.isPreview&&=!1,a(),c())),P(),v(),fe(),window.showToast&&window.showToast(i?`SQL Formatted`:`Already formatted`,`info`)};ue&&(ue.onclick=me),de&&(de.onclick=()=>{_t({id:`console-shortcuts-modal`,icon:`keyboard`,iconColor:`primary`,title:`SQL Console Shortcuts`,subtitle:`Keyboard shortcuts for query editing and execution`,badge:`Editor`,width:`480px`,body:`
2346
+ `).join(``),I.classList.remove(`hidden`),I.querySelectorAll(`.autocomplete-item`).forEach(e=>{e.onmousedown=t=>{t.preventDefault();let n=parseInt(e.dataset.idx,10);oe(n)}})},ae=()=>{let e=t.selectionStart,n=t.value.slice(0,e).match(/([a-zA-Z0-9_]+)$/);if(!n){re();return}let r=n[1];ne={prefix:r,start:e-r.length,end:e};let i=r.toLowerCase(),a=[];B().forEach(e=>{e.toLowerCase().startsWith(i)&&e.toLowerCase()!==i&&a.push({text:e,type:`table`,icon:`table_chart`})}),z.forEach(e=>{e.toLowerCase().startsWith(i)&&e.toLowerCase()!==i&&a.push({text:e,type:`keyword`,icon:`code`})}),R=a.slice(0,8),L=0,R.length>0?ie():re()},oe=(e=L)=>{let n=R[e];if(!n||!ne)return;let r=t.value.slice(0,ne.start),i=t.value.slice(ne.end),a=n.text+` `;t.value=r+a+i;let o=ne.start+a.length;t.selectionStart=o,t.selectionEnd=o,re(),F(),y(),t.focus({preventScroll:!0})},se=document.getElementById(`console-cursor-pos`),ce=document.getElementById(`console-sel-separator`),le=document.getElementById(`console-selection-info`),H=document.getElementById(`console-status-dialect`),ue=document.getElementById(`console-format-sql-btn`),de=document.getElementById(`console-shortcuts-btn`),fe=()=>{if(!t)return;let e=t.selectionStart,n=t.selectionEnd,r=t.value,i=r.substring(0,n).split(`
2347
+ `),a=i.length,o=i[i.length-1].length+1;if(se&&(se.textContent=`Ln ${a}, Col ${o}`),le)if(typeof e==`number`&&typeof n==`number`&&e!==n){let t=Math.abs(n-e),i=r.substring(e,n).split(`
2348
+ `).length;le.textContent=i>1?`${t} selected (${i} lines)`:`${t} selected`,le.classList.remove(`hidden`),ce&&ce.classList.remove(`hidden`)}else le.classList.add(`hidden`),ce&&ce.classList.add(`hidden`);if(H){let e=window.AppState?.dbType||`SQLITE`;H.textContent=(e===`none`?`SQL`:e).toUpperCase()}},pe=t=>{if(!t||!t.trim())return t;let n=(window.AppState?.dbType||`sqlite`).toLowerCase(),r=`sql`;n===`postgres`||n===`postgresql`?r=`postgresql`:n===`mysql`?r=`mysql`:n===`mssql`?r=`tsql`:n===`sqlite`&&(r=`sqlite`);try{return e(t.trim(),{language:r,tabWidth:2,keywordCase:`upper`,linesBetweenQueries:2})}catch{return t}},me=()=>{let e=t.value,n=t.selectionStart,r=t.selectionEnd,i=!1;if(typeof n==`number`&&typeof r==`number`&&n!==r){let e=t.value.substring(n,r),a=pe(e);a!==e&&(t.setRangeText(a,n,r,`select`),i=!0)}else{let n=pe(t.value);n!==e&&(t.value=n,i=!0)}let a=s();a&&(a.sql=t.value,i&&(a.isDirty=!0,a.isPreview&&=!1,o(),l())),F(),y(),fe(),window.showToast&&window.showToast(i?`SQL Formatted`:`Already formatted`,`info`)};ue&&(ue.onclick=me);let he=document.getElementById(`console-top-format-btn`);he&&(he.onclick=me),de&&(de.onclick=()=>{$t({id:`console-shortcuts-modal`,icon:`keyboard`,iconColor:`primary`,title:`SQL Console Shortcuts`,subtitle:`Keyboard shortcuts for query editing and execution`,badge:`Editor`,width:`480px`,body:`
1744
2349
  <div class="shortcuts-modal-body" style="padding: 0;">
2350
+ <div class="shortcut-row">
2351
+ <span class="shortcut-row-label">Ask AI Assistant</span>
2352
+ <div class="shortcut-row-keys"><kbd>Ctrl</kbd> + <kbd>I</kbd></div>
2353
+ </div>
1745
2354
  <div class="shortcut-row">
1746
2355
  <span class="shortcut-row-label">Run Query / Run Selection</span>
1747
2356
  <div class="shortcut-row-keys"><kbd>Ctrl</kbd> + <kbd>↵ Enter</kbd></div>
@@ -1771,11 +2380,11 @@ $1`)}),t=t.replace(/[ \t]+(AND\b|OR\b)/g,`
1771
2380
  <div class="shortcut-row-keys"><kbd>Esc</kbd> to exit</div>
1772
2381
  </div>
1773
2382
  </div>
1774
- `})}),e.addEventListener(`input`,()=>{let t=o();t&&(t.sql=e.value,t.isDirty=!0,t.isPreview&&=!1,c()),P(),v(),ie(),C(),fe()}),e.addEventListener(`select`,()=>{C(),fe()}),e.addEventListener(`mouseup`,()=>{C(),fe()}),e.addEventListener(`click`,fe),e.addEventListener(`keyup`,e=>{fe(),(e.key.startsWith(`Arrow`)||e.key===`Home`||e.key===`End`||e.shiftKey)&&C()}),e.addEventListener(`blur`,()=>{setTimeout(ne,150)}),e.addEventListener(`scroll`,()=>{N&&(N.scrollTop=e.scrollTop,N.scrollLeft=e.scrollLeft)}),e.addEventListener(`keydown`,t=>{if(F&&!F.classList.contains(`hidden`)&&L.length>0){if(t.key===`ArrowDown`){t.preventDefault(),I=(I+1)%L.length,re();return}else if(t.key===`ArrowUp`){t.preventDefault(),I=(I-1+L.length)%L.length,re();return}else if(t.key===`Tab`||t.key===`Enter`&&!t.ctrlKey&&!t.metaKey){t.preventDefault(),ae(I);return}else if(t.key===`Escape`){t.preventDefault(),ne();return}}if((t.ctrlKey||t.metaKey)&&t.key===`Enter`){t.preventDefault(),ne(),w();return}if(t.shiftKey&&t.altKey&&t.key.toLowerCase()===`f`){t.preventDefault(),me();return}if((t.ctrlKey||t.metaKey)&&t.key.toLowerCase()===`s`){t.preventDefault(),M();return}if((t.ctrlKey||t.metaKey)&&t.key.toLowerCase()===`w`){t.preventDefault(),f(i);return}if((t.ctrlKey||t.metaKey)&&t.altKey&&t.key.toLowerCase()===`n`){t.preventDefault(),u();return}if(t.key===`Tab`){t.preventDefault();let n=e.selectionStart,r=e.selectionEnd,i=e.value;if(n===r)document.queryCommandSupported?.(`insertText`)?document.execCommand(`insertText`,!1,` `):(e.value=i.substring(0,n)+` `+i.substring(r),e.selectionStart=e.selectionEnd=n+2);else{let a=i.substring(0,n),o=i.substring(r),s=a.lastIndexOf(`
2383
+ `})}),t.addEventListener(`input`,()=>{let e=s();e&&(e.sql=t.value,e.isDirty=!0,e.isPreview&&=!1,l()),F(),y(),ae(),S(),fe()}),t.addEventListener(`select`,()=>{S(),fe()}),t.addEventListener(`mouseup`,()=>{S(),fe()}),t.addEventListener(`click`,fe),t.addEventListener(`keyup`,e=>{fe(),(e.key.startsWith(`Arrow`)||e.key===`Home`||e.key===`End`||e.shiftKey)&&S()}),t.addEventListener(`blur`,()=>{setTimeout(re,150)}),t.addEventListener(`scroll`,()=>{P&&(P.scrollTop=t.scrollTop,P.scrollLeft=t.scrollLeft)}),t.addEventListener(`keydown`,e=>{if(I&&!I.classList.contains(`hidden`)&&R.length>0){if(e.key===`ArrowDown`){e.preventDefault(),L=(L+1)%R.length,ie();return}else if(e.key===`ArrowUp`){e.preventDefault(),L=(L-1+R.length)%R.length,ie();return}else if(e.key===`Tab`||e.key===`Enter`&&!e.ctrlKey&&!e.metaKey){e.preventDefault(),oe(L);return}else if(e.key===`Escape`){e.preventDefault(),re();return}}if((e.ctrlKey||e.metaKey)&&e.key.toLowerCase()===`i`){e.preventDefault(),re(),T();return}if((e.ctrlKey||e.metaKey)&&e.key===`Enter`){e.preventDefault(),re(),w();return}if(e.shiftKey&&e.altKey&&e.key.toLowerCase()===`f`){e.preventDefault(),me();return}if((e.ctrlKey||e.metaKey)&&e.key.toLowerCase()===`s`){e.preventDefault(),te();return}if((e.ctrlKey||e.metaKey)&&e.key.toLowerCase()===`w`){e.preventDefault(),p(a);return}if((e.ctrlKey||e.metaKey)&&e.altKey&&e.key.toLowerCase()===`n`){e.preventDefault(),d();return}if(e.key===`Tab`){e.preventDefault();let n=t.selectionStart,r=t.selectionEnd,i=t.value;if(n===r)document.queryCommandSupported?.(`insertText`)?document.execCommand(`insertText`,!1,` `):(t.value=i.substring(0,n)+` `+i.substring(r),t.selectionStart=t.selectionEnd=n+2);else{let a=i.substring(0,n),o=i.substring(r),s=a.lastIndexOf(`
1775
2384
  `)+1,c=i.substring(s,r).split(`
1776
- `);if(t.shiftKey){let t=c.map(e=>e.replace(/^(?: | )/,``)).join(`
1777
- `);e.value=i.substring(0,s)+t+o,e.selectionStart=s,e.selectionEnd=s+t.length}else{let t=c.map(e=>` `+e).join(`
1778
- `);e.value=i.substring(0,s)+t+o,e.selectionStart=s,e.selectionEnd=s+t.length}}P(),v()}});let he=document.getElementById(`console-sidebar`),ge=document.getElementById(`console-toggle-sidebar-btn`),_e=document.getElementById(`console-new-query-btn`),ve=document.getElementById(`console-sidebar-search-input`),ye=document.getElementById(`console-search-clear-btn`),be=document.getElementById(`console-db-type`),xe=document.getElementById(`brand-db-type`);be&&xe&&(be.textContent=xe.textContent||`CONNECTED`);let Se=e=>{he&&(e?he.classList.add(`collapsed`):he.classList.remove(`collapsed`),localStorage.setItem(`drixio_console_sidebar_collapsed`,e?`true`:`false`))};localStorage.getItem(`drixio_console_sidebar_collapsed`)===`true`&&Se(!0),ge&&(ge.onclick=()=>{let e=he?.classList.contains(`collapsed`)||!1;Se(!e)}),_e&&(_e.onclick=()=>{u()}),document.querySelectorAll(`.console-tree-section-header`).forEach(e=>{e.onclick=()=>{let t=e.closest(`.console-tree-section`);t&&t.classList.toggle(`collapsed`)}});let Ce=document.getElementById(`console-saved-queries-list`),we=document.getElementById(`saved-queries-count`),Te=[],Ee=async()=>{if(Ce)try{let e=await y();e.success&&Array.isArray(e.data)?(Te=e.data,we&&(we.textContent=String(Te.length)),De()):Ce.innerHTML=`<div class="sidebar-tree-empty">No saved queries</div>`}catch{Ce.innerHTML=`<div class="sidebar-tree-empty">Error loading</div>`}},De=()=>{if(!Ce)return;let e=(ve?.value||``).trim().toLowerCase(),t=Te;if(e&&(t=Te.filter(t=>(t.title||``).toLowerCase().includes(e)||(t.sql||``).toLowerCase().includes(e))),t.length===0){Ce.innerHTML=`<div class="sidebar-tree-empty">No queries found</div>`;return}Ce.innerHTML=t.map(e=>`
2385
+ `);if(e.shiftKey){let e=c.map(e=>e.replace(/^(?: | )/,``)).join(`
2386
+ `);t.value=i.substring(0,s)+e+o,t.selectionStart=s,t.selectionEnd=s+e.length}else{let e=c.map(e=>` `+e).join(`
2387
+ `);t.value=i.substring(0,s)+e+o,t.selectionStart=s,t.selectionEnd=s+e.length}}F(),y()}});let U=document.getElementById(`console-sidebar`),ge=document.getElementById(`console-toggle-sidebar-btn`),_e=document.getElementById(`console-new-query-btn`),ve=document.getElementById(`console-sidebar-search-input`),ye=document.getElementById(`console-search-clear-btn`),be=document.getElementById(`console-db-type`),xe=document.getElementById(`brand-db-type`);be&&xe&&(be.textContent=xe.textContent||`CONNECTED`);let Se=e=>{U&&(e?U.classList.add(`collapsed`):U.classList.remove(`collapsed`),localStorage.setItem(`drixio_console_sidebar_collapsed`,e?`true`:`false`))};localStorage.getItem(`drixio_console_sidebar_collapsed`)===`true`&&Se(!0),ge&&(ge.onclick=()=>{let e=U?.classList.contains(`collapsed`)||!1;Se(!e)}),_e&&(_e.onclick=()=>{d()}),document.querySelectorAll(`.console-tree-section-header`).forEach(e=>{e.onclick=()=>{let t=e.closest(`.console-tree-section`);t&&t.classList.toggle(`collapsed`)}});let Ce=document.getElementById(`console-saved-queries-list`),we=document.getElementById(`saved-queries-count`),Te=[],Ee=async()=>{if(Ce)try{let e=await C();e.success&&Array.isArray(e.data)?(Te=e.data,we&&(we.textContent=String(Te.length)),De()):Ce.innerHTML=`<div class="sidebar-tree-empty">No saved queries</div>`}catch{Ce.innerHTML=`<div class="sidebar-tree-empty">Error loading</div>`}},De=()=>{if(!Ce)return;let e=(ve?.value||``).trim().toLowerCase(),t=Te;if(e&&(t=Te.filter(t=>(t.title||``).toLowerCase().includes(e)||(t.sql||``).toLowerCase().includes(e))),t.length===0){Ce.innerHTML=`<div class="sidebar-tree-empty">No queries found</div>`;return}Ce.innerHTML=t.map(e=>`
1779
2388
  <button type="button" class="table-btn query-item-btn" data-id="${e.id}" title="${e.title}">
1780
2389
  <div class="table-btn-label">
1781
2390
  <i class="material-symbols-outlined table-item-icon">description</i>
@@ -1785,18 +2394,18 @@ $1`)}),t=t.replace(/[ \t]+(AND\b|OR\b)/g,`
1785
2394
  <span class="material-symbols-outlined">delete</span>
1786
2395
  </span>`}
1787
2396
  </button>
1788
- `).join(``),Ce.querySelectorAll(`.query-item-btn`).forEach(e=>{let t=e.getAttribute(`data-id`),n=Te.find(e=>e.id===t);if(!n)return;e.onclick=e=>{e.target.closest(`.query-item-delete-btn`)||d(n.title,n.sql)};let r=e.querySelector(`.query-item-delete-btn`);r&&(r.onclick=async e=>{e.stopPropagation(),confirm(`Delete query "${n.title}"?`)&&(await S(n.id)).success&&Ee()})})};ve&&(ve.oninput=()=>{let e=ve.value.trim();ye&&(e?ye.classList.remove(`hidden`):ye.classList.add(`hidden`)),De(),Ae()},ye&&(ye.onclick=()=>{ve.value=``,ye.classList.add(`hidden`),De(),Ae(),ve.focus()}));let Oe=document.getElementById(`console-templates-list`),ke=[{title:`Select all users`,sql:`SELECT * FROM user LIMIT 50;`},{title:`Count rows in table`,sql:`SELECT count(*) AS total_rows FROM user;`},{title:`Show database tables`,sql:`SELECT * FROM sqlite_master WHERE type='table';`},{title:`Create table blueprint`,sql:`CREATE TABLE example (
2397
+ `).join(``),Ce.querySelectorAll(`.query-item-btn`).forEach(e=>{let t=e.getAttribute(`data-id`),n=Te.find(e=>e.id===t);if(!n)return;e.onclick=e=>{e.target.closest(`.query-item-delete-btn`)||f(n.title,n.sql)};let r=e.querySelector(`.query-item-delete-btn`);r&&(r.onclick=async e=>{e.stopPropagation(),confirm(`Delete query "${n.title}"?`)&&(await E(n.id)).success&&Ee()})})};ve&&(ve.oninput=()=>{let e=ve.value.trim();ye&&(e?ye.classList.remove(`hidden`):ye.classList.add(`hidden`)),De(),Ae()},ye&&(ye.onclick=()=>{ve.value=``,ye.classList.add(`hidden`),De(),Ae(),ve.focus()}));let Oe=document.getElementById(`console-templates-list`),ke=[{title:`Select all users`,sql:`SELECT * FROM user LIMIT 50;`,icon:`group`,color:`#3b82f6`},{title:`Count rows in table`,sql:`SELECT count(*) AS total_rows FROM user;`,icon:`tag`,color:`#10b981`},{title:`Show database tables`,sql:`SELECT * FROM sqlite_master WHERE type='table';`,icon:`table_chart`,color:`#8b5cf6`},{title:`Create table blueprint`,sql:`CREATE TABLE example (
1789
2398
  id INTEGER PRIMARY KEY AUTOINCREMENT,
1790
2399
  name VARCHAR(255) NOT NULL,
1791
2400
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
1792
- );`},{title:`Inspect table schema`,sql:`PRAGMA table_info('user');`},{title:`Check index coverage`,sql:`PRAGMA index_list('user');`},{title:`Ping / Health check`,sql:`SELECT 1 + 1 AS ping;`}],Ae=()=>{if(!Oe)return;let e=document.getElementById(`templates-count`),t=(ve?.value||``).trim().toLowerCase(),n=ke;if(t&&(n=ke.filter(e=>e.title.toLowerCase().includes(t)||e.sql.toLowerCase().includes(t))),e&&(e.textContent=n.length),n.length===0){Oe.innerHTML=`<div class="sidebar-tree-empty">No templates match</div>`;return}Oe.innerHTML=n.map(e=>`
2401
+ );`,icon:`add_box`,color:`#ec4899`},{title:`Inspect table schema`,sql:`PRAGMA table_info('user');`,icon:`account_tree`,color:`#06b6d4`},{title:`Check index coverage`,sql:`PRAGMA index_list('user');`,icon:`bolt`,color:`#f59e0b`},{title:`Ping / Health check`,sql:`SELECT 1 + 1 AS ping;`,icon:`vital_signs`,color:`#10b981`}],Ae=()=>{if(!Oe)return;let e=document.getElementById(`templates-count`),t=(ve?.value||``).trim().toLowerCase(),n=ke;if(t&&(n=ke.filter(e=>e.title.toLowerCase().includes(t)||e.sql.toLowerCase().includes(t))),e&&(e.textContent=n.length),n.length===0){Oe.innerHTML=`<div class="sidebar-tree-empty">No templates match</div>`;return}Oe.innerHTML=n.map(e=>`
1793
2402
  <button type="button" class="table-btn query-item-btn template-item" data-title="${e.title}" title="${e.title}">
1794
2403
  <div class="table-btn-label">
1795
- <i class="material-symbols-outlined table-item-icon" style="color: #f59e0b;">lightbulb</i>
2404
+ <i class="material-symbols-outlined table-item-icon" style="color: ${e.color||`#f59e0b`};">${e.icon||`lightbulb`}</i>
1796
2405
  <span class="table-name-text">${e.title}</span>
1797
2406
  </div>
1798
2407
  </button>
1799
- `).join(``),Oe.querySelectorAll(`.template-item`).forEach(e=>{let t=e.getAttribute(`data-title`),n=ke.find(e=>e.title===t);n&&(e.onclick=()=>{d(n.title,n.sql,!0)})})};Tt(e=>{d(`Recent query`,e,!0)});let je=document.getElementById(`console-clear-results-btn`);je&&(je.onclick=()=>{let e=o();e&&(e.lastResult=null,a()),ft(null,t)});let Me=document.querySelector(`.console-h-resizer .console-resizer-handle`),Ne=document.getElementById(`console-editor-pane`);if(Me&&Ne){let e=!1,t=0,n=0,r=r=>{r.button===0&&(e=!0,t=r.clientY,n=Ne.getBoundingClientRect().height,Me.classList.add(`is-dragging`),document.body.style.userSelect=`none`,document.body.style.cursor=`row-resize`,window.addEventListener(`mousemove`,i),window.addEventListener(`mouseup`,a))},i=r=>{if(!e)return;let i=r.clientY-t,a=n+i,o=Math.max(120,window.innerHeight*.75);a=Math.max(120,Math.min(a,o)),Ne.style.height=`${a}px`},a=()=>{if(!e)return;e=!1,Me.classList.remove(`is-dragging`),document.body.style.userSelect=``,document.body.style.cursor=``,window.removeEventListener(`mousemove`,i),window.removeEventListener(`mouseup`,a);let t=Ne.getBoundingClientRect().height;localStorage.setItem(`drixio_console_editor_height`,Math.round(t).toString())};Me.addEventListener(`mousedown`,r)}let Pe=document.getElementById(`console-expand-editor-btn`),Fe=document.getElementById(`console-expand-btn-icon`),Ie=()=>{if(!Ne)return;let t=Ne.classList.toggle(`is-fullscreen`);Fe&&(Fe.textContent=t?`close_fullscreen`:`open_in_full`),Pe&&(Pe.title=t?`Exit Fullscreen (Esc)`:`Toggle Fullscreen Editor (Esc to exit)`),setTimeout(()=>{e.focus({preventScroll:!0}),P(),v()},50)};Pe&&(Pe.onclick=Ie),window.addEventListener(`keydown`,e=>{e.key===`Escape`&&Ne?.classList.contains(`is-fullscreen`)&&(e.preventDefault(),Ie())});let z=document.querySelectorAll(`.results-tab-btn`),Le=document.getElementById(`console-results-body`),Re=document.getElementById(`console-messages-body`),ze=document.getElementById(`console-clear-messages-btn`);z.forEach(e=>{e.onclick=()=>{z.forEach(e=>e.classList.remove(`active`)),e.classList.add(`active`);let t=e.getAttribute(`data-tab`);t===`results`?(Le?.classList.remove(`hidden`),Re?.classList.add(`hidden`)):t===`messages`&&(Le?.classList.add(`hidden`),Re?.classList.remove(`hidden`),dt())}}),ze&&(ze.onclick=()=>{lt()});let Be=o();e.value=Be.sql,c(),P(),v(),ft(Be.lastResult,t),Ee(),Ae(),fe(),e.focus({preventScroll:!0})};function kt(e,t,n){document.querySelectorAll(`.table-btn`).forEach(e=>e.classList.remove(`active`)),t&&t.classList.add(`active`);let r=document.getElementById(`table-name`);r&&(r.textContent=`SQL Editor`),n.innerHTML=`
2408
+ `).join(``),Oe.querySelectorAll(`.template-item`).forEach(e=>{let t=e.getAttribute(`data-title`),n=ke.find(e=>e.title===t);n&&(e.onclick=()=>{f(n.title,n.sql,!0)})})};cn(e=>{f(`Recent query`,e,!0)});let je=document.getElementById(`console-clear-results-btn`);je&&(je.onclick=()=>{let e=s();e&&(e.lastResult=null,o()),K(null,n)});let Me=document.querySelector(`.console-h-resizer .console-resizer-handle`),Ne=document.getElementById(`console-editor-pane`);if(Me&&Ne){let e=!1,t=0,n=0,r=r=>{r.button===0&&(e=!0,t=r.clientY,n=Ne.getBoundingClientRect().height,Me.classList.add(`is-dragging`),document.body.style.userSelect=`none`,document.body.style.cursor=`row-resize`,window.addEventListener(`mousemove`,i),window.addEventListener(`mouseup`,a))},i=r=>{if(!e)return;let i=r.clientY-t,a=n+i,o=Ne.parentElement.clientHeight-250;a=Math.max(250,Math.min(a,o)),Ne.style.height=`${a}px`},a=()=>{if(!e)return;e=!1,Me.classList.remove(`is-dragging`),document.body.style.userSelect=``,document.body.style.cursor=``,window.removeEventListener(`mousemove`,i),window.removeEventListener(`mouseup`,a);let t=Ne.getBoundingClientRect().height;localStorage.setItem(`drixio_console_editor_height`,Math.round(t).toString())};Me.addEventListener(`mousedown`,r)}let Pe=document.getElementById(`console-expand-editor-btn`),Fe=document.getElementById(`console-expand-btn-icon`),Ie=()=>{if(!Ne)return;let e=Ne.classList.toggle(`is-fullscreen`);Fe&&(Fe.textContent=e?`close_fullscreen`:`open_in_full`),Pe&&(Pe.title=e?`Exit Fullscreen (Esc)`:`Toggle Fullscreen Editor (Esc to exit)`),setTimeout(()=>{t.focus({preventScroll:!0}),F(),y()},50)};Pe&&(Pe.onclick=Ie),window.addEventListener(`keydown`,e=>{e.key===`Escape`&&Ne?.classList.contains(`is-fullscreen`)&&(e.preventDefault(),Ie())});let Le=document.querySelectorAll(`.results-tab-btn`),Re=document.getElementById(`console-results-body`),ze=document.getElementById(`console-messages-body`),Be=document.getElementById(`console-clear-messages-btn`);Le.forEach(e=>{e.onclick=()=>{Le.forEach(e=>e.classList.remove(`active`)),e.classList.add(`active`);let t=e.getAttribute(`data-tab`);t===`results`?(Re?.classList.remove(`hidden`),ze?.classList.add(`hidden`)):t===`messages`&&(Re?.classList.add(`hidden`),ze?.classList.remove(`hidden`),Jt())}}),Be&&(Be.onclick=()=>{Kt()});let Ve=s();t.value=Ve.sql,l(),F(),y(),K(Ve.lastResult,n),Ee(),Ae(),fe(),t.focus({preventScroll:!0})};function Rn(e,t,n){document.querySelectorAll(`.table-btn`).forEach(e=>e.classList.remove(`active`)),t&&t.classList.add(`active`);let r=document.getElementById(`table-name`);r&&(r.textContent=`SQL Editor`),n.innerHTML=`
1800
2409
  <div class="sql-console-wrapper">
1801
2410
  <!-- 1. Left Query SideNav (Matching Table Editor SideNav Layout) -->
1802
2411
  <aside id="console-sidebar" class="console-sidebar">
@@ -1875,9 +2484,9 @@ $1`)}),t=t.replace(/[ \t]+(AND\b|OR\b)/g,`
1875
2484
  <span class="status-indicator-dot status-connected" id="console-db-status-dot"></span>
1876
2485
  <span id="console-db-type">CONNECTED</span>
1877
2486
  </div>
1878
- <button type="button" id="console-clear-results-btn" class="console-sidebar-clear-btn" title="Clear current results">
1879
- <span class="material-symbols-outlined" style="font-size: 14px;">cleaning_services</span>
1880
- <span>Clear</span>
2487
+ <button type="button" id="console-clear-history-footer-btn" class="console-sidebar-clear-btn" title="Clear recent query execution history">
2488
+ <span class="material-symbols-outlined" style="font-size: 14px;">delete_sweep</span>
2489
+ <span>Clear History</span>
1881
2490
  </button>
1882
2491
  </div>
1883
2492
  </aside>
@@ -1906,6 +2515,20 @@ $1`)}),t=t.replace(/[ \t]+(AND\b|OR\b)/g,`
1906
2515
  <span class="safe-indicator-dot"></span>
1907
2516
  </button>
1908
2517
 
2518
+ <!-- Ask AI Button (Option C) -->
2519
+ <button type="button" id="console-ai-btn" class="console-action-btn secondary console-ai-trigger-btn" title="Ask AI to write SQL (Ctrl+I)">
2520
+ <span class="material-symbols-outlined icon" style="color: var(--primary, #2563eb);">auto_awesome</span>
2521
+ <span>Ask AI</span>
2522
+ <kbd class="console-kbd-hint">Ctrl I</kbd>
2523
+ </button>
2524
+
2525
+ <!-- Format SQL Button -->
2526
+ <button type="button" id="console-top-format-btn" class="console-action-btn secondary" title="Format SQL Query (Shift+Alt+F)">
2527
+ <span class="material-symbols-outlined icon">format_align_left</span>
2528
+ <span>Format</span>
2529
+ <kbd class="console-kbd-hint">Shift Alt F</kbd>
2530
+ </button>
2531
+
1909
2532
  <!-- Save Button -->
1910
2533
  <button type="button" id="console-save-snippet-btn" class="console-action-btn secondary" title="Save Query (Ctrl+S)">
1911
2534
  <span class="material-symbols-outlined icon">bookmark_add</span>
@@ -1956,6 +2579,10 @@ $1`)}),t=t.replace(/[ \t]+(AND\b|OR\b)/g,`
1956
2579
  <span class="material-symbols-outlined" style="font-size: 13px;">psychology</span>
1957
2580
  <span>Explain</span>
1958
2581
  </button>
2582
+ <button type="button" id="console-ai-explain-btn" class="status-bar-btn" title="AI Explain & Optimize Query">
2583
+ <span class="material-symbols-outlined" style="font-size: 13px; color: var(--primary, #2563eb);">auto_awesome</span>
2584
+ <span>AI Optimize</span>
2585
+ </button>
1959
2586
  <button type="button" id="console-expand-editor-btn" class="status-bar-btn" title="Toggle Fullscreen Editor (Esc to exit)">
1960
2587
  <span class="material-symbols-outlined" id="console-expand-btn-icon" style="font-size: 13px;">open_in_full</span>
1961
2588
  </button>
@@ -1983,6 +2610,10 @@ $1`)}),t=t.replace(/[ \t]+(AND\b|OR\b)/g,`
1983
2610
  </div>
1984
2611
  <div class="console-results-meta" id="console-results-meta">
1985
2612
  <span class="results-meta-text" id="results-meta-count">Ready to run query</span>
2613
+ <button type="button" id="console-clear-results-btn" class="console-action-btn secondary" style="height: 24px; padding: 0 8px; font-size: 11px; gap: 4px;" title="Clear results pane">
2614
+ <span class="material-symbols-outlined" style="font-size: 13px;">cleaning_services</span>
2615
+ <span>Clear</span>
2616
+ </button>
1986
2617
  <div class="results-export-wrapper" id="results-export-wrapper" style="display: none;">
1987
2618
  <button type="button" id="console-export-btn" class="console-export-btn" title="Export Results">
1988
2619
  <span class="material-symbols-outlined" style="font-size: 14px;">download</span>
@@ -2033,10 +2664,10 @@ $1`)}),t=t.replace(/[ \t]+(AND\b|OR\b)/g,`
2033
2664
  </div>
2034
2665
  </div>
2035
2666
  </div>
2036
- `;let i=document.getElementById(`sql-editor`),a=document.getElementById(`console-results-body`),o=localStorage.getItem(`drixio_console_editor_height`)||localStorage.getItem(`drixio_console_pane_height`),s=n.querySelector(`#console-editor-pane`);if(o&&s){let e=parseInt(o,10);!isNaN(e)&&e>=120&&e<=800&&(s.style.height=`${e}px`)}let c=document.querySelector(`main`);c&&(c.scrollTop=0),window.scrollTo(0,0),Ot(i,a)}var B={erdData:[],undoStack:[],selectedTables:new Set,clipboard:[],draggingNode:null,draggingColInfo:null,draggedNodesStart:[],dragStartMouse:{x:0,y:0},targetColForDelete:null,zoom:1,isPanning:!1,panStart:{x:0,y:0},scrollStart:{left:0,top:0},drawingFkStartCol:null,drawingFkStartCoords:null,contextMenuPos:{x:0,y:0},snapToGrid:!0,pushUndoState(){this.undoStack.push(JSON.parse(JSON.stringify(this.erdData))),this.undoStack.length>50&&this.undoStack.shift()},undo(){return this.undoStack.length>0?(this.erdData=this.undoStack.pop(),!0):!1},clearSelection(){this.selectedTables.clear()},toggleSelection(e){this.selectedTables.has(e)?this.selectedTables.delete(e):this.selectedTables.add(e)},setSelection(e){this.selectedTables.clear(),this.selectedTables.add(e)}};async function At(){let e=await r();if(!e||!e.success||!e.data)return[];let t=Array.isArray(e.data)?[...e.data].sort():[];return(await Promise.all(t.map(async e=>{let t=await c(e);return t&&t.success?{table:e,columns:t.data}:null}))).filter(Boolean)}function jt(){try{let e=localStorage.getItem(`drixio-erd-positions`);return e?JSON.parse(e):{}}catch{return{}}}function Mt(e){localStorage.setItem(`drixio-erd-positions`,JSON.stringify(e))}async function Nt(e){if(!e)return!0;try{for(let t of e)if(t.isDraft){let e=await f(t.table,{columns:t.columns});if(!e.success)throw Error(e.error||`Failed to create table`)}else{let e=t.columns.filter(e=>e.isDraft);if(e.length>0){let n=await f(t.table,{pendingInserts:e});if(!n.success)throw Error(n.error||`Failed to add column`)}}return!0}catch(e){return window.showToast?.(`Failed to save: `+e.message,`error`),!1}}function Pt(e){if(!e)return 0;let t=0;return e.forEach(e=>{e.isDraft?t++:e.columns.forEach(e=>{e.isDraft&&t++})}),t}function Ft(e){if(!e||e.length===0)return;let t={};e.forEach(e=>t[e.table]=new Set),e.forEach(e=>{e.columns.forEach(n=>{n.fkTarget&&n.fkTarget.table&&t[e.table]&&n.fkTarget.table!==e.table&&t[e.table].add(n.fkTarget.table)})});let n={};e.forEach(e=>n[e.table]=0);let r=!0,i=0;for(;r&&i<e.length+5;){r=!1,i++;for(let i of e){let e=n[i.table];for(let a of t[i.table])n[a]!==void 0&&n[a]>=e&&(n[i.table]=n[a]+1,r=!0)}}let a={};for(let t of e){let e=n[t.table]||0;a[e]||(a[e]=[]),a[e].push(t.table)}let o=jt()||{};return Object.keys(a).forEach(e=>{let t=parseInt(e);a[e].forEach((e,n)=>{o[e]={x:600+t*360,y:400+n*260}})}),Mt(o),o}function It(e){if(!e||e.length===0)return``;let t=(window.AppState?.dbType||`sqlite`).toLowerCase()===`mysql`?"`":`"`,n=[];return e.forEach(e=>{let r=e.columns.map(e=>{let n=` ${t}${e.name}${t} ${e.type}`;return e.isPk&&(n+=` PRIMARY KEY`),!e.nullable&&!e.isPk&&(n+=` NOT NULL`),e.isUnique&&!e.isPk&&(n+=` UNIQUE`),n});e.columns.forEach(e=>{e.fkTarget&&e.fkTarget.table&&e.fkTarget.column&&r.push(` FOREIGN KEY (${t}${e.name}${t}) REFERENCES ${t}${e.fkTarget.table}${t}(${t}${e.fkTarget.column}${t})`)}),n.push(`CREATE TABLE ${t}${e.table}${t} (\n${r.join(`,
2037
- `)}\n);`)}),n.join(`
2667
+ `;let i=document.getElementById(`sql-editor`),a=document.getElementById(`console-results-body`),o=localStorage.getItem(`drixio_console_editor_height`)||localStorage.getItem(`drixio_console_pane_height`),s=n.querySelector(`#console-editor-pane`);if(o&&s){let e=parseInt(o,10);!isNaN(e)&&e>=120&&e<=800&&(s.style.height=`${e}px`)}let c=document.querySelector(`main`);c&&(c.scrollTop=0),window.scrollTo(0,0),Ln(i,a)}var J={erdData:[],undoStack:[],selectedTables:new Set,clipboard:[],draggingNode:null,draggingColInfo:null,draggedNodesStart:[],dragStartMouse:{x:0,y:0},targetColForDelete:null,zoom:1,isPanning:!1,panStart:{x:0,y:0},scrollStart:{left:0,top:0},drawingFkStartCol:null,drawingFkStartCoords:null,contextMenuPos:{x:0,y:0},snapToGrid:!0,pushUndoState(){this.undoStack.push(JSON.parse(JSON.stringify(this.erdData))),this.undoStack.length>50&&this.undoStack.shift()},undo(){return this.undoStack.length>0?(this.erdData=this.undoStack.pop(),!0):!1},clearSelection(){this.selectedTables.clear()},toggleSelection(e){this.selectedTables.has(e)?this.selectedTables.delete(e):this.selectedTables.add(e)},setSelection(e){this.selectedTables.clear(),this.selectedTables.add(e)}};async function zn(){let e=await i();if(!e||!e.success||!e.data)return[];let t=Array.isArray(e.data)?[...e.data].sort():[];return(await Promise.all(t.map(async e=>{let t=await u(e);return t&&t.success?{table:e,columns:t.data}:null}))).filter(Boolean)}function Bn(){try{let e=localStorage.getItem(`drixio-erd-positions`);return e?JSON.parse(e):{}}catch{return{}}}function Vn(e){localStorage.setItem(`drixio-erd-positions`,JSON.stringify(e))}async function Hn(e){if(!e)return!0;try{for(let t of e)if(t.isDraft){let e=await m(t.table,{columns:t.columns});if(!e.success)throw Error(e.error||`Failed to create table`)}else{let e=t.columns.filter(e=>e.isDraft);if(e.length>0){let n=await m(t.table,{pendingInserts:e});if(!n.success)throw Error(n.error||`Failed to add column`)}}return!0}catch(e){return window.showToast?.(`Failed to save: `+e.message,`error`),!1}}function Un(e){if(!e)return 0;let t=0;return e.forEach(e=>{e.isDraft?t++:e.columns.forEach(e=>{e.isDraft&&t++})}),t}function Wn(e){if(!e||e.length===0)return;let t={};e.forEach(e=>t[e.table]=new Set),e.forEach(e=>{e.columns.forEach(n=>{n.fkTarget&&n.fkTarget.table&&t[e.table]&&n.fkTarget.table!==e.table&&t[e.table].add(n.fkTarget.table)})});let n={};e.forEach(e=>n[e.table]=0);let r=!0,i=0;for(;r&&i<e.length+5;){r=!1,i++;for(let i of e){let e=n[i.table];for(let a of t[i.table])n[a]!==void 0&&n[a]>=e&&(n[i.table]=n[a]+1,r=!0)}}let a={};for(let t of e){let e=n[t.table]||0;a[e]||(a[e]=[]),a[e].push(t.table)}let o=Bn()||{};return Object.keys(a).forEach(e=>{let t=parseInt(e);a[e].forEach((e,n)=>{o[e]={x:600+t*360,y:400+n*260}})}),Vn(o),o}function Gn(e){if(!e||e.length===0)return``;let t=(window.AppState?.dbType||`sqlite`).toLowerCase(),n=e=>t===`mysql`?`\`${e}\``:t===`mssql`?`[${e}]`:`"${e}"`,r=[];return e.forEach(e=>{let t=e.columns.filter(e=>e.isPk),i=t.length>1,a=e.columns.map(e=>{let t=` ${n(e.name)} ${e.type}`;return e.isPk&&!i&&(t+=` PRIMARY KEY`),!e.nullable&&(!e.isPk||i)&&(t+=` NOT NULL`),e.isUnique&&(!e.isPk||i)&&(t+=` UNIQUE`),t});if(i){let e=t.map(e=>n(e.name)).join(`, `);a.push(` PRIMARY KEY (${e})`)}e.columns.forEach(e=>{if(e.fkTarget&&e.fkTarget.table&&e.fkTarget.column){let t=` FOREIGN KEY (${n(e.name)}) REFERENCES ${n(e.fkTarget.table)}(${n(e.fkTarget.column)})`;e.fkTarget.onDelete&&e.fkTarget.onDelete.toUpperCase()!==`NO ACTION`&&(t+=` ON DELETE ${e.fkTarget.onDelete.toUpperCase()}`),e.fkTarget.onUpdate&&e.fkTarget.onUpdate.toUpperCase()!==`NO ACTION`&&(t+=` ON UPDATE ${e.fkTarget.onUpdate.toUpperCase()}`),a.push(t)}}),r.push(`CREATE TABLE ${n(e.table)} (\n${a.join(`,
2668
+ `)}\n);`)}),r.join(`
2038
2669
 
2039
- `)}function Lt(){let e=document.querySelectorAll(`.erd-node`),t=document.getElementById(`erd-svg-layer`);if(!e||e.length===0||!t)return null;let n=1/0,r=1/0,i=-1/0,a=-1/0;e.forEach(e=>{let t=parseFloat(e.style.left)||0,o=parseFloat(e.style.top)||0,s=e.offsetWidth||290,c=e.offsetHeight||150;t<n&&(n=t),o<r&&(r=o),t+s>i&&(i=t+s),o+c>a&&(a=o+c)});let o=Math.max(400,Math.round(i-n+120)),s=Math.max(300,Math.round(a-r+120)),c=n-60,l=r-60,u=document.documentElement.getAttribute(`data-theme`)!==`light`,d=u?`#111113`:`#f8fafc`,f=u?`#18181b`:`#ffffff`,p=u?`#27272a`:`#e2e8f0`,m=u?`#f4f4f5`:`#0f172a`,h=u?`#a1a1aa`:`#64748b`,g=``;e.forEach(e=>{let t=(parseFloat(e.style.left)||0)-c,n=(parseFloat(e.style.top)||0)-l,r=e.offsetWidth||290,i=e.offsetHeight||150,a=e.querySelector(`.erd-node-name`)?.textContent||``,o=Array.from(e.querySelectorAll(`.erd-column`)).map(e=>{let t=e.querySelector(`.erd-col-name`)?.textContent||``,n=e.querySelector(`.erd-col-type`)?.textContent||``,r=!!e.querySelector(`.erd-badge-pk`),i=!!e.querySelector(`.erd-badge-pfk`);return{name:t,type:n,isPk:r,isPfk:i,isFk:!i&&!!e.querySelector(`.erd-badge-fk`),isUq:!!e.querySelector(`.erd-badge-unique`)}}),s=``;o.forEach((e,t)=>{let n=40+t*32,i=``;i=e.isPfk?`<rect x="12" y="${n+6}" width="26" height="15" rx="3" fill="rgba(99,102,241,0.2)" stroke="#818cf8" stroke-width="0.8"/><text x="25" y="${n+17}" font-size="9" font-family="monospace" font-weight="700" fill="#a5b4fc" text-anchor="middle">PFK</text>`:e.isPk?`<rect x="12" y="${n+6}" width="20" height="15" rx="3" fill="rgba(245,158,11,0.2)" stroke="#f59e0b" stroke-width="0.8"/><text x="22" y="${n+17}" font-size="9" font-family="monospace" font-weight="700" fill="#fbbf24" text-anchor="middle">PK</text>`:e.isFk?`<rect x="12" y="${n+6}" width="20" height="15" rx="3" fill="rgba(59,130,246,0.2)" stroke="#3b82f6" stroke-width="0.8"/><text x="22" y="${n+17}" font-size="9" font-family="monospace" font-weight="700" fill="#60a5fa" text-anchor="middle">FK</text>`:e.isUq?`<rect x="12" y="${n+6}" width="20" height="15" rx="3" fill="rgba(14,165,233,0.2)" stroke="#0ea5e9" stroke-width="0.8"/><text x="22" y="${n+17}" font-size="9" font-family="monospace" font-weight="700" fill="#38bdf8" text-anchor="middle">UQ</text>`:`<circle cx="18" cy="${n+14}" r="2" fill="${h}"/>`;let a=e.isPfk?44:e.isPk||e.isFk||e.isUq?38:28;s+=`
2670
+ `)}function Kn(){let e=document.querySelectorAll(`.erd-node`),t=document.getElementById(`erd-svg-layer`);if(!e||e.length===0||!t)return null;let n=1/0,r=1/0,i=-1/0,a=-1/0;e.forEach(e=>{let t=parseFloat(e.style.left)||0,o=parseFloat(e.style.top)||0,s=e.offsetWidth||290,c=e.offsetHeight||150;t<n&&(n=t),o<r&&(r=o),t+s>i&&(i=t+s),o+c>a&&(a=o+c)});let o=Math.max(400,Math.round(i-n+120)),s=Math.max(300,Math.round(a-r+120)),c=n-60,l=r-60,u=document.documentElement.getAttribute(`data-theme`)!==`light`,d=u?`#111113`:`#f8fafc`,f=u?`#18181b`:`#ffffff`,p=u?`#27272a`:`#e2e8f0`,m=u?`#f4f4f5`:`#0f172a`,h=u?`#a1a1aa`:`#64748b`,g=``;e.forEach(e=>{let t=(parseFloat(e.style.left)||0)-c,n=(parseFloat(e.style.top)||0)-l,r=e.offsetWidth||290,i=e.offsetHeight||150,a=e.querySelector(`.erd-node-name`)?.textContent||``,o=Array.from(e.querySelectorAll(`.erd-column`)).map(e=>{let t=e.querySelector(`.erd-col-name`)?.textContent||``,n=e.querySelector(`.erd-col-type`)?.textContent||``,r=!!e.querySelector(`.erd-badge-pk`),i=!!e.querySelector(`.erd-badge-pfk`);return{name:t,type:n,isPk:r,isPfk:i,isFk:!i&&!!e.querySelector(`.erd-badge-fk`),isUq:!!e.querySelector(`.erd-badge-unique`)}}),s=``;o.forEach((e,t)=>{let n=40+t*32,i=``;i=e.isPfk?`<rect x="12" y="${n+6}" width="26" height="15" rx="3" fill="rgba(99,102,241,0.2)" stroke="#818cf8" stroke-width="0.8"/><text x="25" y="${n+17}" font-size="9" font-family="monospace" font-weight="700" fill="#a5b4fc" text-anchor="middle">PFK</text>`:e.isPk?`<rect x="12" y="${n+6}" width="20" height="15" rx="3" fill="rgba(245,158,11,0.2)" stroke="#f59e0b" stroke-width="0.8"/><text x="22" y="${n+17}" font-size="9" font-family="monospace" font-weight="700" fill="#fbbf24" text-anchor="middle">PK</text>`:e.isFk?`<rect x="12" y="${n+6}" width="20" height="15" rx="3" fill="rgba(59,130,246,0.2)" stroke="#3b82f6" stroke-width="0.8"/><text x="22" y="${n+17}" font-size="9" font-family="monospace" font-weight="700" fill="#60a5fa" text-anchor="middle">FK</text>`:e.isUq?`<rect x="12" y="${n+6}" width="20" height="15" rx="3" fill="rgba(14,165,233,0.2)" stroke="#0ea5e9" stroke-width="0.8"/><text x="22" y="${n+17}" font-size="9" font-family="monospace" font-weight="700" fill="#38bdf8" text-anchor="middle">UQ</text>`:`<circle cx="18" cy="${n+14}" r="2" fill="${h}"/>`;let a=e.isPfk?44:e.isPk||e.isFk||e.isUq?38:28;s+=`
2040
2671
  <line x1="0" y1="${n}" x2="${r}" y2="${n}" stroke="${p}" stroke-width="0.5"/>
2041
2672
  ${i}
2042
2673
  <text x="${a}" y="${n+18}" font-size="12" font-family="monospace" font-weight="${e.isPk?`700`:`500`}" fill="${m}">${e.name}</text>
@@ -2069,11 +2700,11 @@ $1`)}),t=t.replace(/[ \t]+(AND\b|OR\b)/g,`
2069
2700
  <rect width="100%" height="100%" fill="url(#grid)" />
2070
2701
  <g>${v}</g>
2071
2702
  <g>${g}</g>
2072
- </svg>`,width:o,height:s}}function Rt(){let e=Lt();if(!e){window.showToast?.(`No tables to export`,`warning`);return}let t=new Blob([e.svgStr],{type:`image/svg+xml;charset=utf-8`}),n=URL.createObjectURL(t),r=document.createElement(`a`);r.href=n,r.download=`erd-diagram-${new Date().toISOString().slice(0,10)}.svg`,r.click(),URL.revokeObjectURL(n),window.showToast?.(`Exported ERD as SVG!`,`success`)}function zt(){let e=Lt();if(!e){window.showToast?.(`No tables to export`,`warning`);return}let t=new Blob([e.svgStr],{type:`image/svg+xml;charset=utf-8`}),n=URL.createObjectURL(t),r=new Image;r.onload=()=>{let t=document.createElement(`canvas`);t.width=e.width*2,t.height=e.height*2;let i=t.getContext(`2d`);if(!i){URL.revokeObjectURL(n),window.showToast?.(`Failed to create canvas context`,`error`);return}i.scale(2,2),i.drawImage(r,0,0),URL.revokeObjectURL(n),t.toBlob(e=>{if(!e){window.showToast?.(`Failed to generate PNG blob`,`error`);return}let t=URL.createObjectURL(e),n=document.createElement(`a`);n.href=t,n.download=`erd-diagram-${new Date().toISOString().slice(0,10)}.png`,n.click(),URL.revokeObjectURL(t),window.showToast?.(`Exported ERD as PNG (2x HiDPI)!`,`success`)},`image/png`)},r.onerror=()=>{URL.revokeObjectURL(n),window.showToast?.(`Failed to render ERD PNG`,`error`)},r.src=n}function Bt(){if(B.selectedTables.size===0)return;let e=[];B.selectedTables.forEach(t=>{let n=B.erdData.find(e=>e.table===t);if(n){let t=JSON.parse(JSON.stringify(n));t.columns.forEach(e=>{e.fkTarget&&delete e.fkTarget}),e.push(t)}}),B.clipboard=e,window.showToast(`Copied ${e.length} table(s)`,`success`)}function Vt(){B.selectedTables.size!==0&&(B.pushUndoState(),B.erdData.forEach(e=>{e.columns.forEach(e=>{e.fkTarget&&B.selectedTables.has(e.fkTarget.table)&&delete e.fkTarget})}),B.erdData=B.erdData.filter(e=>!B.selectedTables.has(e.table)),B.clearSelection(),V(),window.showToast(`Deleted selected table(s)`,`success`))}function Ht(){if(!B.clipboard||B.clipboard.length===0)return;B.pushUndoState(),B.clearSelection();let e=jt();B.clipboard.forEach((t,n)=>{let r=JSON.parse(JSON.stringify(t)),i=`_copy`,a=r.table+i,o=1;for(;B.erdData.some(e=>e.table===a);)o++,a=r.table+i+o;r.table=a,r.isDraft=!0,r.columns.forEach(e=>e.isDraft=!0),e[t.table]?e[a]={x:e[t.table].x+40+n*20,y:e[t.table].y+40+n*20}:e[a]={x:100+n*20,y:100+n*20},B.erdData.push(r),B.selectedTables.add(a)}),Mt(e),V(),window.showToast(`Pasted ${B.clipboard.length} table(s)`,`success`)}function Ut(){document.addEventListener(`keydown`,async e=>{window.AppState&&window.AppState.currentTab!==`erd-btn`||e.target.tagName===`INPUT`||e.target.tagName===`SELECT`||e.target.tagName===`TEXTAREA`||((e.ctrlKey||e.metaKey)&&e.key===`s`&&(e.preventDefault(),await Nt(B.erdData)&&(window.showToast(`ERD Schema saved successfully!`,`success`),pn(document.getElementById(`main-content`)))),(e.ctrlKey||e.metaKey)&&e.key===`z`&&(e.preventDefault(),B.undo()?(V(),window.showToast(`Undid last action`,`success`)):window.showToast(`Nothing to undo`,`info`)),e.ctrlKey&&e.key===`c`&&(e.preventDefault(),Bt()),e.ctrlKey&&e.key===`v`&&(e.preventDefault(),Ht()),e.key===`Delete`&&(e.preventDefault(),Vt()))})}function Wt(){let e=document.getElementById(`erd-workspace`);document.querySelectorAll(`.erd-node`).forEach(t=>{let n=B.erdData.find(e=>e.table===t.dataset.table);if(!n)return;let r=t.querySelector(`.erd-node-header`);if(r.addEventListener(`mousedown`,r=>{if(r.button===1||r.target.tagName===`INPUT`)return;if(!B.selectedTables.has(n.table))!r.ctrlKey&&!r.metaKey&&B.clearSelection(),B.selectedTables.add(n.table),document.querySelectorAll(`.erd-node`).forEach(e=>{B.selectedTables.has(e.dataset.table)?e.classList.add(`is-selected`):e.classList.remove(`is-selected`)});else if(r.ctrlKey||r.metaKey){B.selectedTables.delete(n.table),t.classList.remove(`is-selected`);return}B.draggingNode=t;let i=e.getBoundingClientRect();B.dragStartMouse={x:r.clientX,y:r.clientY},B.draggedNodesStart=[],B.selectedTables.forEach(e=>{let t=document.querySelector(`.erd-node[data-table="${e}"]`);if(t){let e=t.getBoundingClientRect();B.draggedNodesStart.push({node:t,startX:(e.left-i.left)/B.zoom,startY:(e.top-i.top)/B.zoom}),t.style.zIndex=`10`}}),document.body.style.cursor=`grabbing`}),t.addEventListener(`contextmenu`,e=>{e.preventDefault(),e.stopPropagation(),B.selectedTables.has(n.table)||(B.setSelection(n.table),document.querySelectorAll(`.erd-node`).forEach(e=>{B.selectedTables.has(e.dataset.table)?e.classList.add(`is-selected`):e.classList.remove(`is-selected`)})),A(e,[{label:`Copy`,icon:`content_copy`,action:Bt},{label:`Cut`,icon:`content_cut`,action:()=>{Bt(),Vt()}},`divider`,{label:`Delete`,icon:`delete`,danger:!0,action:Vt}])}),t.querySelector(`.erd-add-col-btn`).addEventListener(`click`,()=>{B.pushUndoState(),n.columns.push({name:`new_col_${n.columns.length}`,type:`TEXT`,isDraft:!0,nullable:!0}),V()}),n.isDraft){let e=r.querySelector(`.erd-node-name`);r.addEventListener(`dblclick`,t=>{if(t.target.tagName===`INPUT`)return;t.stopPropagation();let r=document.createElement(`input`);r.value=n.table,r.className=`erd-inline-input`,e.replaceWith(r),r.focus(),r.addEventListener(`blur`,()=>{let e=n.table,t=r.value.trim()||e;if(e!==t){B.pushUndoState(),n.table=t;let r=jt();r[e]&&(r[t]=r[e],delete r[e],Mt(r)),B.erdData.forEach(n=>{n.columns.forEach(n=>{n.fkTarget&&n.fkTarget.table===e&&(n.fkTarget.table=t)})}),B.selectedTables.has(e)&&(B.selectedTables.delete(e),B.selectedTables.add(t))}V()}),r.addEventListener(`keydown`,e=>{e.key===`Enter`&&r.blur()})})}else r.addEventListener(`dblclick`,e=>{e.stopPropagation(),window.AppState.currentTable=t.dataset.table;let n=document.querySelector(`.table-btn[data-table="${t.dataset.table}"]`);n&&(window.AppState.currentTableBtnElement=n,document.querySelectorAll(`.table-btn`).forEach(e=>e.classList.remove(`active`)),n.classList.add(`active`)),window.handleSwitchTab?window.handleSwitchTab(`schema-btn`):window.renderCurrentView&&(window.AppState.currentTab=`schema-btn`,window.renderCurrentView())});let i=t.querySelectorAll(`.erd-column`);i.forEach(t=>{let r=parseInt(t.dataset.index),i=n.columns[r];if(t.addEventListener(`contextmenu`,e=>{i.isPk||!i.isDraft&&!n.isDraft||(e.preventDefault(),e.stopPropagation(),A(e,[{label:`Delete Column`,icon:`delete`,danger:!0,action:()=>{B.pushUndoState(),B.erdData.forEach(e=>{e.columns.forEach(e=>{e.fkTarget&&e.fkTarget.table===n.table&&e.fkTarget.column===i.name&&delete e.fkTarget})}),n.columns.splice(r,1),V()}}]))}),!i.isDraft&&!n.isDraft)return;t.querySelectorAll(`.editable-field`).forEach(e=>{e.addEventListener(`dblclick`,t=>{if(t.target.tagName===`INPUT`||t.target.tagName===`SELECT`)return;t.stopPropagation();let r=e.dataset.field;if(r===`type`){te({anchorEl:e,initialValue:i.type,dialect:window.AppState?.dbType,onSelect:e=>{e&&e!==i.type&&(B.pushUndoState(),i.type=e,V())}});return}let a=document.createElement(`input`);a.value=r===`name`&&i.nullable?i.name+` ?`:i[r],a.className=`erd-inline-input`,e.replaceWith(a),a.focus(),a.addEventListener(`blur`,()=>{let e=i[r],t=r===`type`?a.value.toUpperCase():a.value;if(t=t.trim()||e,e===t&&!t.endsWith(`?`)&&!t.endsWith(`!`)){V();return}B.pushUndoState(),r===`name`&&(t.endsWith(`?`)?(i.nullable=!0,t=t.slice(0,-1).trim()):(i.nullable=!1,t.endsWith(`!`)&&(t=t.slice(0,-1).trim()))),r===`name`&&i.isPk&&e!==t&&B.erdData.forEach(r=>{r.columns.forEach(r=>{r.fkTarget&&r.fkTarget.table===n.table&&r.fkTarget.column===e&&(r.fkTarget.column=t)})}),i[r]=t,V()}),a.addEventListener(`keydown`,e=>{e.key===`Enter`&&a.blur()})})});let a=t.querySelector(`.erd-drag-handle`);a&&a.addEventListener(`mousedown`,t=>{t.stopPropagation(),B.drawingFkStartCol={table:n.table,col:i.name,colIndex:r};let o=a.getBoundingClientRect(),s=e.getBoundingClientRect();B.drawingFkStartCoords={x:(o.right-s.left)/B.zoom,y:(o.top+o.height/2-s.top)/B.zoom}})}),t.querySelectorAll(`.erd-reorder-handle`).forEach(e=>{e.addEventListener(`dragstart`,t=>{let r=e.closest(`.erd-column`);B.draggingColInfo={table:n.table,colIndex:parseInt(r.dataset.index)},t.dataTransfer.effectAllowed=`move`,t.dataTransfer.setData(`text/plain`,n.table)})}),i.forEach(e=>{e.addEventListener(`dragover`,e=>{!B.draggingColInfo||B.draggingColInfo.table!==n.table||(e.preventDefault(),e.dataTransfer.dropEffect=`move`)}),e.addEventListener(`drop`,t=>{if(t.preventDefault(),!B.draggingColInfo||B.draggingColInfo.table!==n.table)return;let r=B.draggingColInfo.colIndex,i=parseInt(e.dataset.index);if(r!==i){B.pushUndoState();let[e]=n.columns.splice(r,1);n.columns.splice(i,0,e),V()}B.draggingColInfo=null})})})}var Gt=!1;function Kt(){Gt||(Gt=!0,document.addEventListener(`mousemove`,e=>{if(B.drawingFkStartCol){let t=document.getElementById(`erd-workspace`);if(!t)return;let n=t.getBoundingClientRect(),r=(e.clientX-n.left)/B.zoom,i=(e.clientY-n.top)/B.zoom,a=document.getElementById(`erd-temp-path`),o=document.getElementById(`erd-svg-layer`);a||(a=document.createElementNS(`http://www.w3.org/2000/svg`,`path`),a.id=`erd-temp-path`,a.setAttribute(`fill`,`none`),a.setAttribute(`stroke`,`var(--color-primary)`),a.setAttribute(`stroke-width`,`2`),a.setAttribute(`stroke-dasharray`,`5,5`),o&&o.appendChild(a)),a&&a.setAttribute(`d`,`M ${B.drawingFkStartCoords.x} ${B.drawingFkStartCoords.y} L ${r} ${i}`);return}if(!B.draggingNode)return;let t=(e.clientX-B.dragStartMouse.x)/B.zoom,n=(e.clientY-B.dragStartMouse.y)/B.zoom;B.draggedNodesStart.forEach(e=>{let r=e.startX+t,i=e.startY+n;r<0&&(r=0),i<0&&(i=0),B.snapToGrid&&(r=Math.round(r/20)*20,i=Math.round(i/20)*20),e.node.style.left=`${r}px`,e.node.style.top=`${i}px`}),nn()}),document.addEventListener(`mouseup`,e=>{if(B.drawingFkStartCol){let t=document.elementFromPoint(e.clientX,e.clientY),n=t?t.closest(`.erd-node`):null;if(n){let e=n.dataset.table;if(e!==B.drawingFkStartCol.table){let t=B.erdData.find(t=>t.table===e).columns.find(e=>e.isPk);if(t){let n=confirm(`Create Foreign Key to ${e}?\n\nClick OK for Nullable (0..N)\nClick Cancel for Not Nullable (1..N)`);B.pushUndoState();let r=B.erdData.find(e=>e.table===B.drawingFkStartCol.table),i=r.columns[B.drawingFkStartCol.colIndex];i.fkTarget={table:e,column:t.name},i.nullable=n,r.columns.splice(B.drawingFkStartCol.colIndex,1),r.columns.push(i),V()}else window.showToast(`Target table has no Primary Key!`,`error`)}}else{let e=B.erdData.find(e=>e.table===B.drawingFkStartCol.table).columns[B.drawingFkStartCol.colIndex];e.fkTarget&&(B.pushUndoState(),delete e.fkTarget,V())}let r=document.getElementById(`erd-temp-path`);r&&r.remove(),B.drawingFkStartCol=null}if(B.draggingNode){document.body.style.cursor=``;let e=jt();B.draggedNodesStart.forEach(t=>{t.node.style.zIndex=``,e[t.node.dataset.table]={x:parseFloat(t.node.style.left),y:parseFloat(t.node.style.top)}}),Mt(e),dn(),B.draggingNode=null,B.draggedNodesStart=[]}}))}var qt=!1,Jt={x:0,y:0},Yt=null;function Xt(e){let t=()=>{if(!e)return;let t=20*B.zoom,n=Math.max(1,1.25*B.zoom);e.style.backgroundSize=`${t}px ${t}px`,e.style.backgroundImage=`radial-gradient(var(--color-border) ${n}px, transparent ${n}px)`,e.style.backgroundPosition=`${-(e.scrollLeft%t)}px ${-(e.scrollTop%t)}px`};e.addEventListener(`scroll`,()=>{dn(),t()}),e.addEventListener(`mousedown`,t=>{t.button===1||t.button===0&&t.altKey?(t.preventDefault(),B.isPanning=!0,B.panStart.x=t.clientX,B.panStart.y=t.clientY,B.scrollStart.left=e.scrollLeft,B.scrollStart.top=e.scrollTop,document.body.style.cursor=`grabbing`):t.button===0&&(t.target.id===`erd-workspace`||t.target.id===`erd-svg-layer`||t.target.id===`erd-nodes-layer`||t.target.id===`erd-wrapper`)&&(qt=!0,Jt={x:t.clientX,y:t.clientY},!t.ctrlKey&&!t.metaKey&&(B.clearSelection(),V()),Yt=document.createElement(`div`),Yt.style.position=`fixed`,Yt.style.border=`1px solid var(--color-primary)`,Yt.style.backgroundColor=`rgba(59, 130, 246, 0.12)`,Yt.style.borderRadius=`4px`,Yt.style.zIndex=`1000`,Yt.style.pointerEvents=`none`,document.body.appendChild(Yt))});let n=()=>{let e=document.getElementById(`btn-erd-zoom-reset`);e&&(e.textContent=Math.round(B.zoom*100)+`%`)},r=e=>{B.zoom=Math.max(.2,Math.min(e,2.5));let r=document.getElementById(`erd-workspace`);r&&(r.style.transform=`scale(${B.zoom})`,nn(),dn(),n(),t())},i=document.getElementById(`btn-erd-zoom-in`);i&&(i.onclick=()=>r(B.zoom+.15));let a=document.getElementById(`btn-erd-zoom-out`);a&&(a.onclick=()=>r(B.zoom-.15));let o=document.getElementById(`btn-erd-zoom-reset`);o&&(o.onclick=()=>r(1));let s=()=>{let n=document.querySelectorAll(`.erd-node`);if(!n||n.length===0)return;let i=1/0,a=1/0,o=-1/0,s=-1/0;if(n.forEach(e=>{let t=parseFloat(e.style.left)||0,n=parseFloat(e.style.top)||0,r=e.offsetWidth||290,c=e.offsetHeight||150;t<i&&(i=t),n<a&&(a=n),t+r>o&&(o=t+r),n+c>s&&(s=n+c)}),i===1/0)return;let c=o-i+240,l=s-a+240,u=e.clientWidth,d=e.clientHeight,f=u/c,p=d/l,m=Math.min(1.1,Math.max(.35,Math.min(f,p)));r(m);let h=(i+o)/2,g=(a+s)/2;e.scrollLeft=h*m-u/2,e.scrollTop=g*m-d/2,t()},c=document.getElementById(`btn-erd-fit-view`);c&&(c.onclick=s);let l=document.getElementById(`btn-erd-fullscreen`);l&&(l.onclick=()=>{let e=document.getElementById(`erd-main-viewport`);if(e)if(document.fullscreenElement){document.exitFullscreen?.().catch(()=>{}),l.classList.remove(`active`);let e=l.querySelector(`.material-symbols-outlined`);e&&(e.textContent=`fullscreen`)}else{e.requestFullscreen?.().catch(()=>{}),l.classList.add(`active`);let t=l.querySelector(`.material-symbols-outlined`);t&&(t.textContent=`fullscreen_exit`)}},document.addEventListener(`fullscreenchange`,()=>{if(!document.fullscreenElement&&l){l.classList.remove(`active`);let e=l.querySelector(`.material-symbols-outlined`);e&&(e.textContent=`fullscreen`)}}));let u=document.getElementById(`btn-erd-toggle-minimap`),d=document.getElementById(`btn-erd-close-minimap`),f=document.getElementById(`erd-minimap-container`),p=e=>{if(!f)return;let t=f.classList.contains(`hidden`)||f.style.display===`none`;(e===void 0?t:e)?(f.classList.remove(`hidden`),f.style.display=`block`,u&&u.classList.add(`active`),dn()):(f.classList.add(`hidden`),f.style.display=`none`,u&&u.classList.remove(`active`))};u&&(u.onclick=()=>p()),d&&(d.onclick=e=>{e.stopPropagation(),p(!1)});let m=document.getElementById(`btn-erd-add-table`);m&&(m.onclick=()=>{let t=e.scrollLeft/B.zoom,n=e.scrollTop/B.zoom,r=e.clientWidth/B.zoom,i=e.clientHeight/B.zoom;fn(Math.max(60,t+r/2-150),Math.max(60,n+i/2-100)),window.showToast(`Created new table draft`,`success`)});let h=document.getElementById(`btn-erd-auto-layout`);h&&(h.onclick=()=>{B.pushUndoState(),Ft(B.erdData),V(),setTimeout(s,50),window.showToast(`Auto Layout Applied`,`success`)});let g=document.getElementById(`btn-erd-snap-grid`);g&&(g.onclick=()=>{B.snapToGrid=!B.snapToGrid,B.snapToGrid?(g.classList.add(`active`),window.showToast(`Grid Snapping: ON (20px)`,`info`)):(g.classList.remove(`active`),window.showToast(`Grid Snapping: OFF (Free)`,`info`))});let _=document.getElementById(`btn-erd-export`);_&&(_.onclick=e=>{e.stopPropagation(),A(e,[{label:`Export as SVG Diagram`,icon:`image`,action:()=>Rt()},{label:`Export as PNG (2x HiDPI)`,icon:`photo_camera`,action:()=>zt()},{label:`Copy SQL Schema (DDL)`,icon:`code`,action:()=>{let e=It(B.erdData);e&&(navigator.clipboard.writeText(e),window.showToast?.(`SQL schema copied to clipboard!`,`success`))}}])});let v=document.getElementById(`btn-erd-save-drafts`);v&&(v.onclick=async()=>{await Nt(B.erdData)&&(window.showToast(`ERD Schema saved successfully!`,`success`),pn(document.getElementById(`main-content`)))}),e.addEventListener(`wheel`,e=>{(e.ctrlKey||e.metaKey)&&(e.preventDefault(),r(B.zoom-e.deltaY*.001))},{passive:!1}),document.addEventListener(`mousemove`,n=>{if(qt&&Yt){let e=Math.min(n.clientX,Jt.x),t=Math.min(n.clientY,Jt.y),r=Math.abs(n.clientX-Jt.x),i=Math.abs(n.clientY-Jt.y);Yt.style.left=e+`px`,Yt.style.top=t+`px`,Yt.style.width=r+`px`,Yt.style.height=i+`px`;return}if(B.isPanning){if(e){let r=n.clientX-B.panStart.x,i=n.clientY-B.panStart.y;e.scrollLeft=B.scrollStart.left-r,e.scrollTop=B.scrollStart.top-i,t()}return}}),document.addEventListener(`mouseup`,e=>{if(qt&&(qt=!1,Yt)){let e=Yt.getBoundingClientRect();Yt.remove(),Yt=null;let t=document.querySelectorAll(`.erd-node`),n=!1;t.forEach(t=>{let r=t.getBoundingClientRect();e.right<r.left||e.left>r.right||e.bottom<r.top||e.top>r.bottom||(B.selectedTables.add(t.dataset.table),n=!0)}),n&&V()}B.isPanning&&(B.isPanning=!1,document.body.style.cursor=``)}),e.addEventListener(`contextmenu`,e=>{(e.target.id===`erd-workspace`||e.target.id===`erd-svg-layer`||e.target.id===`erd-nodes-layer`||e.target.id===`erd-wrapper`)&&(e.preventDefault(),e.stopPropagation(),A(e,[{label:`Add Table`,icon:`add_box`,action:()=>{m&&m.click()}},`divider`,{label:`Auto Layout`,icon:`account_tree`,action:()=>{h&&h.click()}},{label:`Export as SVG`,icon:`image`,action:()=>Rt()},{label:`Export as PNG`,icon:`photo_camera`,action:()=>zt()}]))});let y=document.getElementById(`erd-search-input`),b=document.getElementById(`erd-search-results`);if(y&&b){y.addEventListener(`input`,n=>{let r=n.target.value.toLowerCase().trim();if(b.innerHTML=``,!r){b.classList.add(`hidden`);return}let i=B.erdData.filter(e=>e.table.toLowerCase().includes(r));if(i.length===0){b.innerHTML=`<div class="erd-search-item" style="color: var(--color-text-soft);">No tables found</div>`,b.classList.remove(`hidden`);return}i.forEach(n=>{let r=document.createElement(`div`);r.className=`erd-search-item`,r.innerHTML=`
2703
+ </svg>`,width:o,height:s}}function qn(){let e=Kn();if(!e){window.showToast?.(`No tables to export`,`warning`);return}let t=new Blob([e.svgStr],{type:`image/svg+xml;charset=utf-8`}),n=URL.createObjectURL(t),r=document.createElement(`a`);r.href=n,r.download=`erd-diagram-${new Date().toISOString().slice(0,10)}.svg`,r.click(),URL.revokeObjectURL(n),window.showToast?.(`Exported ERD as SVG!`,`success`)}function Jn(){let e=Kn();if(!e){window.showToast?.(`No tables to export`,`warning`);return}let t=new Blob([e.svgStr],{type:`image/svg+xml;charset=utf-8`}),n=URL.createObjectURL(t),r=new Image;r.onload=()=>{let t=document.createElement(`canvas`);t.width=e.width*2,t.height=e.height*2;let i=t.getContext(`2d`);if(!i){URL.revokeObjectURL(n),window.showToast?.(`Failed to create canvas context`,`error`);return}i.scale(2,2),i.drawImage(r,0,0),URL.revokeObjectURL(n),t.toBlob(e=>{if(!e){window.showToast?.(`Failed to generate PNG blob`,`error`);return}let t=URL.createObjectURL(e),n=document.createElement(`a`);n.href=t,n.download=`erd-diagram-${new Date().toISOString().slice(0,10)}.png`,n.click(),URL.revokeObjectURL(t),window.showToast?.(`Exported ERD as PNG (2x HiDPI)!`,`success`)},`image/png`)},r.onerror=()=>{URL.revokeObjectURL(n),window.showToast?.(`Failed to render ERD PNG`,`error`)},r.src=n}function Yn(){if(J.selectedTables.size===0)return;let e=[];J.selectedTables.forEach(t=>{let n=J.erdData.find(e=>e.table===t);if(n){let t=JSON.parse(JSON.stringify(n));t.columns.forEach(e=>{e.fkTarget&&delete e.fkTarget}),e.push(t)}}),J.clipboard=e,window.showToast(`Copied ${e.length} table(s)`,`success`)}function Xn(){J.selectedTables.size!==0&&(J.pushUndoState(),J.erdData.forEach(e=>{e.columns.forEach(e=>{e.fkTarget&&J.selectedTables.has(e.fkTarget.table)&&delete e.fkTarget})}),J.erdData=J.erdData.filter(e=>!J.selectedTables.has(e.table)),J.clearSelection(),X(),window.showToast(`Deleted selected table(s)`,`success`))}function Zn(){if(!J.clipboard||J.clipboard.length===0)return;J.pushUndoState(),J.clearSelection();let e=Bn();J.clipboard.forEach((t,n)=>{let r=JSON.parse(JSON.stringify(t)),i=`_copy`,a=r.table+i,o=1;for(;J.erdData.some(e=>e.table===a);)o++,a=r.table+i+o;r.table=a,r.isDraft=!0,r.columns.forEach(e=>e.isDraft=!0),e[t.table]?e[a]={x:e[t.table].x+40+n*20,y:e[t.table].y+40+n*20}:e[a]={x:100+n*20,y:100+n*20},J.erdData.push(r),J.selectedTables.add(a)}),Vn(e),X(),window.showToast(`Pasted ${J.clipboard.length} table(s)`,`success`)}function Qn(){document.addEventListener(`keydown`,async e=>{window.AppState&&window.AppState.currentTab!==`erd-btn`||e.target.tagName===`INPUT`||e.target.tagName===`SELECT`||e.target.tagName===`TEXTAREA`||((e.ctrlKey||e.metaKey)&&e.key===`s`&&(e.preventDefault(),await Hn(J.erdData)&&(window.showToast(`ERD Schema saved successfully!`,`success`),br(document.getElementById(`main-content`)))),(e.ctrlKey||e.metaKey)&&e.key===`z`&&(e.preventDefault(),J.undo()?(X(),window.showToast(`Undid last action`,`success`)):window.showToast(`Nothing to undo`,`info`)),e.ctrlKey&&e.key===`c`&&(e.preventDefault(),Yn()),e.ctrlKey&&e.key===`v`&&(e.preventDefault(),Zn()),e.key===`Delete`&&(e.preventDefault(),Xn()))})}function $n(){let e=document.getElementById(`erd-workspace`);document.querySelectorAll(`.erd-node`).forEach(t=>{let n=J.erdData.find(e=>e.table===t.dataset.table);if(!n)return;let r=t.querySelector(`.erd-node-header`);if(r.addEventListener(`mousedown`,r=>{if(r.button===1||r.target.tagName===`INPUT`)return;if(!J.selectedTables.has(n.table))!r.ctrlKey&&!r.metaKey&&J.clearSelection(),J.selectedTables.add(n.table),document.querySelectorAll(`.erd-node`).forEach(e=>{J.selectedTables.has(e.dataset.table)?e.classList.add(`is-selected`):e.classList.remove(`is-selected`)});else if(r.ctrlKey||r.metaKey){J.selectedTables.delete(n.table),t.classList.remove(`is-selected`);return}J.draggingNode=t;let i=e.getBoundingClientRect();J.dragStartMouse={x:r.clientX,y:r.clientY},J.draggedNodesStart=[],J.selectedTables.forEach(e=>{let t=document.querySelector(`.erd-node[data-table="${e}"]`);if(t){let e=t.getBoundingClientRect();J.draggedNodesStart.push({node:t,startX:(e.left-i.left)/J.zoom,startY:(e.top-i.top)/J.zoom}),t.style.zIndex=`10`}}),document.body.style.cursor=`grabbing`}),t.addEventListener(`contextmenu`,e=>{e.preventDefault(),e.stopPropagation(),J.selectedTables.has(n.table)||(J.setSelection(n.table),document.querySelectorAll(`.erd-node`).forEach(e=>{J.selectedTables.has(e.dataset.table)?e.classList.add(`is-selected`):e.classList.remove(`is-selected`)})),V(e,[{label:`Copy`,icon:`content_copy`,action:Yn},{label:`Cut`,icon:`content_cut`,action:()=>{Yn(),Xn()}},`divider`,{label:`Delete`,icon:`delete`,danger:!0,action:Xn}])}),t.querySelector(`.erd-add-col-btn`).addEventListener(`click`,()=>{J.pushUndoState(),n.columns.push({name:`new_col_${n.columns.length}`,type:`TEXT`,isDraft:!0,nullable:!0}),X()}),n.isDraft){let e=r.querySelector(`.erd-node-name`);r.addEventListener(`dblclick`,t=>{if(t.target.tagName===`INPUT`)return;t.stopPropagation();let r=document.createElement(`input`);r.value=n.table,r.className=`erd-inline-input`,e.replaceWith(r),r.focus(),r.addEventListener(`blur`,()=>{let e=n.table,t=r.value.trim()||e;if(e!==t){J.pushUndoState(),n.table=t;let r=Bn();r[e]&&(r[t]=r[e],delete r[e],Vn(r)),J.erdData.forEach(n=>{n.columns.forEach(n=>{n.fkTarget&&n.fkTarget.table===e&&(n.fkTarget.table=t)})}),J.selectedTables.has(e)&&(J.selectedTables.delete(e),J.selectedTables.add(t))}X()}),r.addEventListener(`keydown`,e=>{e.key===`Enter`&&r.blur()})})}else r.addEventListener(`dblclick`,e=>{e.stopPropagation(),window.AppState.currentTable=t.dataset.table;let n=document.querySelector(`.table-btn[data-table="${t.dataset.table}"]`);n&&(window.AppState.currentTableBtnElement=n,document.querySelectorAll(`.table-btn`).forEach(e=>e.classList.remove(`active`)),n.classList.add(`active`)),window.handleSwitchTab?window.handleSwitchTab(`schema-btn`):window.renderCurrentView&&(window.AppState.currentTab=`schema-btn`,window.renderCurrentView())});let i=t.querySelectorAll(`.erd-column`);i.forEach(t=>{let r=parseInt(t.dataset.index),i=n.columns[r];if(t.addEventListener(`contextmenu`,e=>{i.isPk||!i.isDraft&&!n.isDraft||(e.preventDefault(),e.stopPropagation(),V(e,[{label:`Delete Column`,icon:`delete`,danger:!0,action:()=>{J.pushUndoState(),J.erdData.forEach(e=>{e.columns.forEach(e=>{e.fkTarget&&e.fkTarget.table===n.table&&e.fkTarget.column===i.name&&delete e.fkTarget})}),n.columns.splice(r,1),X()}}]))}),!i.isDraft&&!n.isDraft)return;t.querySelectorAll(`.editable-field`).forEach(e=>{e.addEventListener(`dblclick`,t=>{if(t.target.tagName===`INPUT`||t.target.tagName===`SELECT`)return;t.stopPropagation();let r=e.dataset.field;if(r===`type`){pe({anchorEl:e,initialValue:i.type,dialect:window.AppState?.dbType,onSelect:e=>{e&&e!==i.type&&(J.pushUndoState(),i.type=e,X())}});return}let a=document.createElement(`input`);a.value=r===`name`&&i.nullable?i.name+` ?`:i[r],a.className=`erd-inline-input`,e.replaceWith(a),a.focus(),a.addEventListener(`blur`,()=>{let e=i[r],t=r===`type`?a.value.toUpperCase():a.value;if(t=t.trim()||e,e===t&&!t.endsWith(`?`)&&!t.endsWith(`!`)){X();return}J.pushUndoState(),r===`name`&&(t.endsWith(`?`)?(i.nullable=!0,t=t.slice(0,-1).trim()):(i.nullable=!1,t.endsWith(`!`)&&(t=t.slice(0,-1).trim()))),r===`name`&&i.isPk&&e!==t&&J.erdData.forEach(r=>{r.columns.forEach(r=>{r.fkTarget&&r.fkTarget.table===n.table&&r.fkTarget.column===e&&(r.fkTarget.column=t)})}),i[r]=t,X()}),a.addEventListener(`keydown`,e=>{e.key===`Enter`&&a.blur()})})});let a=t.querySelector(`.erd-drag-handle`);a&&a.addEventListener(`mousedown`,t=>{t.stopPropagation(),J.drawingFkStartCol={table:n.table,col:i.name,colIndex:r};let o=a.getBoundingClientRect(),s=e.getBoundingClientRect();J.drawingFkStartCoords={x:(o.right-s.left)/J.zoom,y:(o.top+o.height/2-s.top)/J.zoom}})}),t.querySelectorAll(`.erd-reorder-handle`).forEach(e=>{e.addEventListener(`dragstart`,t=>{let r=e.closest(`.erd-column`);J.draggingColInfo={table:n.table,colIndex:parseInt(r.dataset.index)},t.dataTransfer.effectAllowed=`move`,t.dataTransfer.setData(`text/plain`,n.table)})}),i.forEach(e=>{e.addEventListener(`dragover`,e=>{!J.draggingColInfo||J.draggingColInfo.table!==n.table||(e.preventDefault(),e.dataTransfer.dropEffect=`move`)}),e.addEventListener(`drop`,t=>{if(t.preventDefault(),!J.draggingColInfo||J.draggingColInfo.table!==n.table)return;let r=J.draggingColInfo.colIndex,i=parseInt(e.dataset.index);if(r!==i){J.pushUndoState();let[e]=n.columns.splice(r,1);n.columns.splice(i,0,e),X()}J.draggingColInfo=null})})})}var er=!1;function tr(){er||(er=!0,document.addEventListener(`mousemove`,e=>{if(J.drawingFkStartCol){let t=document.getElementById(`erd-workspace`);if(!t)return;let n=t.getBoundingClientRect(),r=(e.clientX-n.left)/J.zoom,i=(e.clientY-n.top)/J.zoom,a=document.getElementById(`erd-temp-path`),o=document.getElementById(`erd-svg-layer`);a||(a=document.createElementNS(`http://www.w3.org/2000/svg`,`path`),a.id=`erd-temp-path`,a.setAttribute(`fill`,`none`),a.setAttribute(`stroke`,`var(--color-primary)`),a.setAttribute(`stroke-width`,`2`),a.setAttribute(`stroke-dasharray`,`5,5`),o&&o.appendChild(a)),a&&a.setAttribute(`d`,`M ${J.drawingFkStartCoords.x} ${J.drawingFkStartCoords.y} L ${r} ${i}`);return}if(!J.draggingNode)return;let t=(e.clientX-J.dragStartMouse.x)/J.zoom,n=(e.clientY-J.dragStartMouse.y)/J.zoom;J.draggedNodesStart.forEach(e=>{let r=e.startX+t,i=e.startY+n;r<0&&(r=0),i<0&&(i=0),J.snapToGrid&&(r=Math.round(r/20)*20,i=Math.round(i/20)*20),e.node.style.left=`${r}px`,e.node.style.top=`${i}px`}),ur()}),document.addEventListener(`mouseup`,e=>{if(J.drawingFkStartCol){let t=document.elementFromPoint(e.clientX,e.clientY),n=t?t.closest(`.erd-node`):null;if(n){let e=n.dataset.table;if(e!==J.drawingFkStartCol.table){let t=J.erdData.find(t=>t.table===e).columns.find(e=>e.isPk);if(t){let n=confirm(`Create Foreign Key to ${e}?\n\nClick OK for Nullable (0..N)\nClick Cancel for Not Nullable (1..N)`);J.pushUndoState();let r=J.erdData.find(e=>e.table===J.drawingFkStartCol.table),i=r.columns[J.drawingFkStartCol.colIndex];i.fkTarget={table:e,column:t.name},i.nullable=n,r.columns.splice(J.drawingFkStartCol.colIndex,1),r.columns.push(i),X()}else window.showToast(`Target table has no Primary Key!`,`error`)}}else{let e=J.erdData.find(e=>e.table===J.drawingFkStartCol.table).columns[J.drawingFkStartCol.colIndex];e.fkTarget&&(J.pushUndoState(),delete e.fkTarget,X())}let r=document.getElementById(`erd-temp-path`);r&&r.remove(),J.drawingFkStartCol=null}if(J.draggingNode){document.body.style.cursor=``;let e=Bn();J.draggedNodesStart.forEach(t=>{t.node.style.zIndex=``,e[t.node.dataset.table]={x:parseFloat(t.node.style.left),y:parseFloat(t.node.style.top)}}),Vn(e),vr(),J.draggingNode=null,J.draggedNodesStart=[]}}))}var nr=!1,rr={x:0,y:0},Y=null;function ir(e){let t=()=>{if(!e)return;let t=20*J.zoom,n=Math.max(1,1.25*J.zoom);e.style.backgroundSize=`${t}px ${t}px`,e.style.backgroundImage=`radial-gradient(var(--color-border) ${n}px, transparent ${n}px)`,e.style.backgroundPosition=`${-(e.scrollLeft%t)}px ${-(e.scrollTop%t)}px`};e.addEventListener(`scroll`,()=>{vr(),t()}),e.addEventListener(`mousedown`,t=>{t.button===1||t.button===0&&t.altKey?(t.preventDefault(),J.isPanning=!0,J.panStart.x=t.clientX,J.panStart.y=t.clientY,J.scrollStart.left=e.scrollLeft,J.scrollStart.top=e.scrollTop,document.body.style.cursor=`grabbing`):t.button===0&&(t.target.id===`erd-workspace`||t.target.id===`erd-svg-layer`||t.target.id===`erd-nodes-layer`||t.target.id===`erd-wrapper`)&&(nr=!0,rr={x:t.clientX,y:t.clientY},!t.ctrlKey&&!t.metaKey&&(J.clearSelection(),X()),Y=document.createElement(`div`),Y.style.position=`fixed`,Y.style.border=`1px solid var(--color-primary)`,Y.style.backgroundColor=`rgba(59, 130, 246, 0.12)`,Y.style.borderRadius=`4px`,Y.style.zIndex=`1000`,Y.style.pointerEvents=`none`,document.body.appendChild(Y))});let n=()=>{let e=document.getElementById(`btn-erd-zoom-reset`);e&&(e.textContent=Math.round(J.zoom*100)+`%`)},r=e=>{J.zoom=Math.max(.2,Math.min(e,2.5));let r=document.getElementById(`erd-workspace`);r&&(r.style.transform=`scale(${J.zoom})`,ur(),vr(),n(),t())},i=document.getElementById(`btn-erd-zoom-in`);i&&(i.onclick=()=>r(J.zoom+.15));let a=document.getElementById(`btn-erd-zoom-out`);a&&(a.onclick=()=>r(J.zoom-.15));let o=document.getElementById(`btn-erd-zoom-reset`);o&&(o.onclick=()=>r(1));let s=()=>{let n=document.querySelectorAll(`.erd-node`);if(!n||n.length===0)return;let i=1/0,a=1/0,o=-1/0,s=-1/0;if(n.forEach(e=>{let t=parseFloat(e.style.left)||0,n=parseFloat(e.style.top)||0,r=e.offsetWidth||290,c=e.offsetHeight||150;t<i&&(i=t),n<a&&(a=n),t+r>o&&(o=t+r),n+c>s&&(s=n+c)}),i===1/0)return;let c=o-i+240,l=s-a+240,u=e.clientWidth,d=e.clientHeight,f=u/c,p=d/l,m=Math.min(1.1,Math.max(.35,Math.min(f,p)));r(m);let h=(i+o)/2,g=(a+s)/2;e.scrollLeft=h*m-u/2,e.scrollTop=g*m-d/2,t()},c=document.getElementById(`btn-erd-fit-view`);c&&(c.onclick=s);let l=document.getElementById(`btn-erd-fullscreen`);l&&(l.onclick=()=>{let e=document.getElementById(`erd-main-viewport`);if(e)if(document.fullscreenElement){document.exitFullscreen?.().catch(()=>{}),l.classList.remove(`active`);let e=l.querySelector(`.material-symbols-outlined`);e&&(e.textContent=`fullscreen`)}else{e.requestFullscreen?.().catch(()=>{}),l.classList.add(`active`);let t=l.querySelector(`.material-symbols-outlined`);t&&(t.textContent=`fullscreen_exit`)}},document.addEventListener(`fullscreenchange`,()=>{if(!document.fullscreenElement&&l){l.classList.remove(`active`);let e=l.querySelector(`.material-symbols-outlined`);e&&(e.textContent=`fullscreen`)}}));let u=document.getElementById(`btn-erd-toggle-minimap`),d=document.getElementById(`btn-erd-close-minimap`),f=document.getElementById(`erd-minimap-container`),p=e=>{if(!f)return;let t=f.classList.contains(`hidden`)||f.style.display===`none`;(e===void 0?t:e)?(f.classList.remove(`hidden`),f.style.display=`block`,u&&u.classList.add(`active`),vr()):(f.classList.add(`hidden`),f.style.display=`none`,u&&u.classList.remove(`active`))};u&&(u.onclick=()=>p()),d&&(d.onclick=e=>{e.stopPropagation(),p(!1)});let m=document.getElementById(`btn-erd-add-table`);m&&(m.onclick=()=>{let t=e.scrollLeft/J.zoom,n=e.scrollTop/J.zoom,r=e.clientWidth/J.zoom,i=e.clientHeight/J.zoom;yr(Math.max(60,t+r/2-150),Math.max(60,n+i/2-100)),window.showToast(`Created new table draft`,`success`)});let h=document.getElementById(`btn-erd-auto-layout`);h&&(h.onclick=()=>{J.pushUndoState(),Wn(J.erdData),X(),setTimeout(s,50),window.showToast(`Auto Layout Applied`,`success`)});let g=document.getElementById(`btn-erd-snap-grid`);g&&(g.onclick=()=>{J.snapToGrid=!J.snapToGrid,J.snapToGrid?(g.classList.add(`active`),window.showToast(`Grid Snapping: ON (20px)`,`info`)):(g.classList.remove(`active`),window.showToast(`Grid Snapping: OFF (Free)`,`info`))});let _=document.getElementById(`btn-erd-export`);_&&(_.onclick=e=>{e.stopPropagation(),V(e,[{label:`Export as SVG Diagram`,icon:`image`,action:()=>qn()},{label:`Export as PNG (2x HiDPI)`,icon:`photo_camera`,action:()=>Jn()},{label:`Copy SQL Schema (DDL)`,icon:`code`,action:()=>{let e=Gn(J.erdData);e&&(navigator.clipboard.writeText(e),window.showToast?.(`SQL schema copied to clipboard!`,`success`))}}])});let v=document.getElementById(`btn-erd-save-drafts`);v&&(v.onclick=async()=>{await Hn(J.erdData)&&(window.showToast(`ERD Schema saved successfully!`,`success`),br(document.getElementById(`main-content`)))}),e.addEventListener(`wheel`,e=>{(e.ctrlKey||e.metaKey)&&(e.preventDefault(),r(J.zoom-e.deltaY*.001))},{passive:!1}),document.addEventListener(`mousemove`,n=>{if(nr&&Y){let e=Math.min(n.clientX,rr.x),t=Math.min(n.clientY,rr.y),r=Math.abs(n.clientX-rr.x),i=Math.abs(n.clientY-rr.y);Y.style.left=e+`px`,Y.style.top=t+`px`,Y.style.width=r+`px`,Y.style.height=i+`px`;return}if(J.isPanning){if(e){let r=n.clientX-J.panStart.x,i=n.clientY-J.panStart.y;e.scrollLeft=J.scrollStart.left-r,e.scrollTop=J.scrollStart.top-i,t()}return}}),document.addEventListener(`mouseup`,e=>{if(nr&&(nr=!1,Y)){let e=Y.getBoundingClientRect();Y.remove(),Y=null;let t=document.querySelectorAll(`.erd-node`),n=!1;t.forEach(t=>{let r=t.getBoundingClientRect();e.right<r.left||e.left>r.right||e.bottom<r.top||e.top>r.bottom||(J.selectedTables.add(t.dataset.table),n=!0)}),n&&X()}J.isPanning&&(J.isPanning=!1,document.body.style.cursor=``)}),e.addEventListener(`contextmenu`,e=>{(e.target.id===`erd-workspace`||e.target.id===`erd-svg-layer`||e.target.id===`erd-nodes-layer`||e.target.id===`erd-wrapper`)&&(e.preventDefault(),e.stopPropagation(),V(e,[{label:`Add Table`,icon:`add_box`,action:()=>{m&&m.click()}},`divider`,{label:`Auto Layout`,icon:`account_tree`,action:()=>{h&&h.click()}},{label:`Export as SVG`,icon:`image`,action:()=>qn()},{label:`Export as PNG`,icon:`photo_camera`,action:()=>Jn()}]))});let y=document.getElementById(`erd-search-input`),b=document.getElementById(`erd-search-results`);if(y&&b){y.addEventListener(`input`,n=>{let r=n.target.value.toLowerCase().trim();if(b.innerHTML=``,!r){b.classList.add(`hidden`);return}let i=J.erdData.filter(e=>e.table.toLowerCase().includes(r));if(i.length===0){b.innerHTML=`<div class="erd-search-item" style="color: var(--color-text-soft);">No tables found</div>`,b.classList.remove(`hidden`);return}i.forEach(n=>{let r=document.createElement(`div`);r.className=`erd-search-item`,r.innerHTML=`
2073
2704
  <span class="material-symbols-outlined icon-16" style="color: var(--color-primary);">table_chart</span>
2074
2705
  <span>${n.table}</span>
2075
2706
  <span class="erd-search-col-badge">${n.columns.length} cols</span>
2076
- `,r.onclick=()=>{B.setSelection(n.table);let r=document.querySelector(`.erd-node[data-table="${n.table}"]`);if(r){let n=r.getBoundingClientRect(),i=e.getBoundingClientRect(),a=parseFloat(r.style.left),o=parseFloat(r.style.top);e.scrollLeft=a*B.zoom-i.width/2+n.width/2,e.scrollTop=o*B.zoom-i.height/2+n.height/2,t()}V(),b.classList.add(`hidden`),y.value=``},b.appendChild(r)}),b.classList.remove(`hidden`)}),document.addEventListener(`click`,e=>{!y.contains(e.target)&&!b.contains(e.target)&&b.classList.add(`hidden`)});let n=document.querySelector(`.erd-search-shortcut`);n&&(n.onclick=()=>y.focus(),n.style.cursor=`pointer`)}e.addEventListener(`mouseover`,e=>{let t=e.target.closest(`.erd-relationship-path`);if(t){sn(t.dataset.fromTable,t.dataset.fromCol,t.dataset.toTable,t.dataset.toCol);return}let n=e.target.closest(`.erd-column.is-fk`);if(n){let e=n.closest(`.erd-node`),t=n.dataset.col;if(e){let n=document.querySelector(`.erd-relationship-path[data-from-table="${e.dataset.table}"][data-from-col="${t}"]`);if(n){sn(n.dataset.fromTable,n.dataset.fromCol,n.dataset.toTable,n.dataset.toCol);return}}}let r=e.target.closest(`.erd-node-header`);if(r){let e=r.closest(`.erd-node`);e&&cn(e.dataset.table)}}),e.addEventListener(`mouseout`,e=>{let t=e.target.closest(`.erd-relationship-path`),n=e.target.closest(`.erd-column.is-fk`),r=e.target.closest(`.erd-node-header`);(t||n||r)&&ln()}),e.addEventListener(`click`,e=>{let t=e.target.closest(`.erd-relationship-path`);t&&(e.stopPropagation(),on({fromTable:t.dataset.fromTable,fromCol:t.dataset.fromCol,toTable:t.dataset.toTable,toCol:t.dataset.toCol,onDelete:t.dataset.onDelete,onUpdate:t.dataset.onUpdate,x:e.clientX,y:e.clientY}))}),t()}function Zt(e){let t=document.getElementById(`erd-minimap`);if(!t)return;let n=!1,r=n=>{let r=t.getBoundingClientRect(),i=n.clientX-r.left,a=n.clientY-r.top,{scale:o,offsetX:s,offsetY:c,minX:l,minY:u,vW:d,vH:f}=un(e,Array.from(document.querySelectorAll(`.erd-node`))),p=l+(i-s)/o,m=u+(a-c)/o;e.scrollLeft=(p-d/2)*B.zoom,e.scrollTop=(m-f/2)*B.zoom};t.addEventListener(`mousedown`,e=>{if(e.stopPropagation(),e.button!==0)return;n=!0,r(e);let t=e=>{n&&r(e)},i=()=>{n=!1,document.removeEventListener(`mousemove`,t),document.removeEventListener(`mouseup`,i)};document.addEventListener(`mousemove`,t),document.addEventListener(`mouseup`,i)})}var Qt=!1;function $t(){if(Qt)return;let e=document.getElementById(`erd-wrapper`);e&&(Xt(e),Zt(e),Ut(),Kt(),Qt=!0)}function en(){let e=document.getElementById(`btn-erd-save-drafts`);if(!e)return;let t=Pt(B.erdData),n=e.querySelector(`.erd-draft-count-badge`);t>0?(e.classList.remove(`disabled`),e.classList.add(`has-drafts`),n&&(n.textContent=t,n.style.display=`inline-flex`)):(e.classList.remove(`has-drafts`),n&&(n.style.display=`none`))}function V(){let e=document.getElementById(`erd-nodes-layer`);if(!e)return;if(e.innerHTML=``,!B.erdData||B.erdData.length===0){e.innerHTML=`
2707
+ `,r.onclick=()=>{J.setSelection(n.table);let r=document.querySelector(`.erd-node[data-table="${n.table}"]`);if(r){let n=r.getBoundingClientRect(),i=e.getBoundingClientRect(),a=parseFloat(r.style.left),o=parseFloat(r.style.top);e.scrollLeft=a*J.zoom-i.width/2+n.width/2,e.scrollTop=o*J.zoom-i.height/2+n.height/2,t()}X(),b.classList.add(`hidden`),y.value=``},b.appendChild(r)}),b.classList.remove(`hidden`)}),document.addEventListener(`click`,e=>{!y.contains(e.target)&&!b.contains(e.target)&&b.classList.add(`hidden`)});let n=document.querySelector(`.erd-search-shortcut`);n&&(n.onclick=()=>y.focus(),n.style.cursor=`pointer`)}e.addEventListener(`mouseover`,e=>{let t=e.target.closest(`.erd-relationship-path`);if(t){mr(t.dataset.fromTable,t.dataset.fromCol,t.dataset.toTable,t.dataset.toCol);return}let n=e.target.closest(`.erd-column.is-fk`);if(n){let e=n.closest(`.erd-node`),t=n.dataset.col;if(e){let n=document.querySelector(`.erd-relationship-path[data-from-table="${e.dataset.table}"][data-from-col="${t}"]`);if(n){mr(n.dataset.fromTable,n.dataset.fromCol,n.dataset.toTable,n.dataset.toCol);return}}}let r=e.target.closest(`.erd-node-header`);if(r){let e=r.closest(`.erd-node`);e&&hr(e.dataset.table)}}),e.addEventListener(`mouseout`,e=>{let t=e.target.closest(`.erd-relationship-path`),n=e.target.closest(`.erd-column.is-fk`),r=e.target.closest(`.erd-node-header`);(t||n||r)&&gr()}),e.addEventListener(`click`,e=>{let t=e.target.closest(`.erd-relationship-path`);t&&(e.stopPropagation(),pr({fromTable:t.dataset.fromTable,fromCol:t.dataset.fromCol,toTable:t.dataset.toTable,toCol:t.dataset.toCol,onDelete:t.dataset.onDelete,onUpdate:t.dataset.onUpdate,x:e.clientX,y:e.clientY}))}),t()}function ar(e){let t=document.getElementById(`erd-minimap`);if(!t)return;let n=!1,r=n=>{let r=t.getBoundingClientRect(),i=n.clientX-r.left,a=n.clientY-r.top,{scale:o,offsetX:s,offsetY:c,minX:l,minY:u,vW:d,vH:f}=_r(e,Array.from(document.querySelectorAll(`.erd-node`))),p=l+(i-s)/o,m=u+(a-c)/o;e.scrollLeft=(p-d/2)*J.zoom,e.scrollTop=(m-f/2)*J.zoom};t.addEventListener(`mousedown`,e=>{if(e.stopPropagation(),e.button!==0)return;n=!0,r(e);let t=e=>{n&&r(e)},i=()=>{n=!1,document.removeEventListener(`mousemove`,t),document.removeEventListener(`mouseup`,i)};document.addEventListener(`mousemove`,t),document.addEventListener(`mouseup`,i)})}var or=!1;function sr(){if(or)return;let e=document.getElementById(`erd-wrapper`);e&&(ir(e),ar(e),Qn(),tr(),or=!0)}function cr(){let e=document.getElementById(`btn-erd-save-drafts`);if(!e)return;let t=Un(J.erdData),n=e.querySelector(`.erd-draft-count-badge`);t>0?(e.classList.remove(`disabled`),e.classList.add(`has-drafts`),n&&(n.textContent=t,n.style.display=`inline-flex`)):(e.classList.remove(`has-drafts`),n&&(n.style.display=`none`))}function X(){let e=document.getElementById(`erd-nodes-layer`);if(!e)return;if(e.innerHTML=``,!J.erdData||J.erdData.length===0){e.innerHTML=`
2077
2708
  <div class="erd-empty-workspace">
2078
2709
  <div class="erd-empty-icon-box">
2079
2710
  <span class="material-symbols-outlined">account_tree</span>
@@ -2081,7 +2712,7 @@ $1`)}),t=t.replace(/[ \t]+(AND\b|OR\b)/g,`
2081
2712
  <h3>No tables in this database</h3>
2082
2713
  <p>Right-click the canvas or click "+ Add Table" above to create an entity.</p>
2083
2714
  </div>
2084
- `,en();return}let t=jt(),n=600,r=400,i=0;B.erdData.forEach(a=>{let o,s;t[a.table]?(o=t[a.table].x,s=t[a.table].y):(o=n,s=r,n+=340,n>1800&&(n=600,r+=i+60,i=0));let c=tn(a,o,s);B.selectedTables.has(a.table)&&c.classList.add(`is-selected`),e.appendChild(c);let l=44+a.columns.length*34+36;l>i&&(i=l)}),Wt(),en(),setTimeout(()=>{nn(),dn()},10)}function tn(e,t,n){let r=document.createElement(`div`);r.className=`erd-node ${e.isDraft?`is-draft`:``}`,r.dataset.table=e.table,r.style.left=`${t}px`,r.style.top=`${n}px`;let i=e.columns.filter(e=>e.isPk).length,a=e.columns.filter(e=>e.fkTarget).length,o=e.columns.map((t,n)=>{let r=t.fkTarget?`is-fk`:``,i=t.isDraft?`is-draft`:``,a=(t.type||`TEXT`).toUpperCase(),o=`<span class="erd-col-bullet"></span>`;t.isPk&&t.fkTarget?o=`<span class="erd-badge-pfk" title="Primary Foreign Key referencing ${t.fkTarget.table}.${t.fkTarget.column}">PFK</span>`:t.isPk?o=`<span class="erd-badge-pk" title="Primary Key">PK</span>`:t.fkTarget?o=`<span class="erd-badge-fk" title="Foreign Key referencing ${t.fkTarget.table}.${t.fkTarget.column}">FK</span>`:t.isUnique&&(o=`<span class="erd-badge-unique" title="Unique Constraint">UQ</span>`);let s=t.nullable?`<span class="erd-col-nullable" title="Nullable column">null</span>`:``;return`
2715
+ `,cr();return}let t=Bn(),n=600,r=400,i=0;J.erdData.forEach(a=>{let o,s;t[a.table]?(o=t[a.table].x,s=t[a.table].y):(o=n,s=r,n+=340,n>1800&&(n=600,r+=i+60,i=0));let c=lr(a,o,s);J.selectedTables.has(a.table)&&c.classList.add(`is-selected`),e.appendChild(c);let l=44+a.columns.length*34+36;l>i&&(i=l)}),$n(),cr(),setTimeout(()=>{ur(),vr()},10)}function lr(e,t,n){let r=document.createElement(`div`);r.className=`erd-node ${e.isDraft?`is-draft`:``}`,r.dataset.table=e.table,r.style.left=`${t}px`,r.style.top=`${n}px`;let i=e.columns.filter(e=>e.isPk).length,a=e.columns.filter(e=>e.fkTarget).length,o=e.columns.map((t,n)=>{let r=t.fkTarget?`is-fk`:``,i=t.isDraft?`is-draft`:``,a=(t.type||`TEXT`).toUpperCase(),o=`<span class="erd-col-bullet"></span>`;t.isPk&&t.fkTarget?o=`<span class="erd-badge-pfk" title="Primary Foreign Key referencing ${t.fkTarget.table}.${t.fkTarget.column}">PFK</span>`:t.isPk?o=`<span class="erd-badge-pk" title="Primary Key">PK</span>`:t.fkTarget?o=`<span class="erd-badge-fk" title="Foreign Key referencing ${t.fkTarget.table}.${t.fkTarget.column}">FK</span>`:t.isUnique&&(o=`<span class="erd-badge-unique" title="Unique Constraint">UQ</span>`);let s=t.nullable?`<span class="erd-col-nullable" title="Nullable column">null</span>`:``;return`
2085
2716
  <div class="erd-column ${r} ${i}" data-col="${t.name}" data-index="${n}">
2086
2717
  <div class="erd-col-left">
2087
2718
  <span class="erd-reorder-handle" draggable="true" title="Drag to reorder column">
@@ -2118,7 +2749,7 @@ $1`)}),t=t.replace(/[ \t]+(AND\b|OR\b)/g,`
2118
2749
  <span class="material-symbols-outlined" style="font-size: 15px;">add</span>
2119
2750
  <span>Add Column</span>
2120
2751
  </div>
2121
- `,r}function nn(){let e=document.getElementById(`erd-svg-layer`);if(!e)return;let t=``;B.erdData.forEach(e=>{let n=e.table,r=document.querySelector(`.erd-node[data-table="${n}"]`);r&&e.columns.forEach(e=>{if(e.fkTarget){let i=e.fkTarget.table,a=e.fkTarget.column,o=document.querySelector(`.erd-node[data-table="${i}"]`);if(!o)return;let s=r.querySelector(`.erd-column[data-col="${e.name}"]`),c=o.querySelector(`.erd-column[data-col="${a}"]`);if(!s||!c)return;let l=s.getBoundingClientRect(),u=c.getBoundingClientRect(),d=document.getElementById(`erd-workspace`).getBoundingClientRect(),f,p,m,h;l.right<u.left+20?(f=(l.right-d.left)/B.zoom,m=(u.left-d.left)/B.zoom):(f=(l.left-d.left)/B.zoom,m=(u.right-d.left)/B.zoom),p=(l.top+l.height/2-d.top)/B.zoom,h=(u.top+u.height/2-d.top)/B.zoom;let g=Math.abs(m-f),_=Math.max(g*.45,50),v=f<m?f+_:f-_,y=p,b=f<m?m-_:m+_,x=h,S=e.nullable?`url(#zero-or-one)`:`url(#one-and-only-one)`;t+=`
2752
+ `,r}function ur(){let e=document.getElementById(`erd-svg-layer`);if(!e)return;let t=``;J.erdData.forEach(e=>{let n=e.table,r=document.querySelector(`.erd-node[data-table="${n}"]`);r&&e.columns.forEach(e=>{if(e.fkTarget){let i=e.fkTarget.table,a=e.fkTarget.column,o=document.querySelector(`.erd-node[data-table="${i}"]`);if(!o)return;let s=r.querySelector(`.erd-column[data-col="${e.name}"]`),c=o.querySelector(`.erd-column[data-col="${a}"]`);if(!s||!c)return;let l=s.getBoundingClientRect(),u=c.getBoundingClientRect(),d=document.getElementById(`erd-workspace`).getBoundingClientRect(),f,p,m,h;l.right<u.left+20?(f=(l.right-d.left)/J.zoom,m=(u.left-d.left)/J.zoom):(f=(l.left-d.left)/J.zoom,m=(u.right-d.left)/J.zoom),p=(l.top+l.height/2-d.top)/J.zoom,h=(u.top+u.height/2-d.top)/J.zoom;let g=Math.abs(m-f),_=Math.max(g*.45,50),v=f<m?f+_:f-_,y=p,b=f<m?m-_:m+_,x=h,S=e.nullable?`url(#zero-or-one)`:`url(#one-and-only-one)`;t+=`
2122
2753
  <g class="erd-relationship-group">
2123
2754
  <path
2124
2755
  class="erd-relationship-path"
@@ -2156,7 +2787,7 @@ $1`)}),t=t.replace(/[ \t]+(AND\b|OR\b)/g,`
2156
2787
  </marker>
2157
2788
  </defs>
2158
2789
  ${t}
2159
- `}var rn=null;function an(){rn&&=(rn.remove(),null)}function on({fromTable:e,fromCol:t,toTable:n,toCol:r,onDelete:i,onUpdate:a,x:o,y:s}){an();let c=document.createElement(`div`);c.className=`erd-rel-popover`,c.style.left=`${Math.min(window.innerWidth-300,Math.max(16,o-130))}px`,c.style.top=`${Math.min(window.innerHeight-180,Math.max(16,s-40))}px`,c.innerHTML=`
2790
+ `}var dr=null;function fr(){dr&&=(dr.remove(),null)}function pr({fromTable:e,fromCol:t,toTable:n,toCol:r,onDelete:i,onUpdate:a,x:o,y:s}){fr();let c=document.createElement(`div`);c.className=`erd-rel-popover`,c.style.left=`${Math.min(window.innerWidth-300,Math.max(16,o-130))}px`,c.style.top=`${Math.min(window.innerHeight-180,Math.max(16,s-40))}px`,c.innerHTML=`
2160
2791
  <div class="erd-rel-pop-header">
2161
2792
  <div class="erd-rel-pop-title">
2162
2793
  <span class="material-symbols-outlined" style="font-size:16px; color:var(--color-primary);">link</span>
@@ -2183,7 +2814,7 @@ $1`)}),t=t.replace(/[ \t]+(AND\b|OR\b)/g,`
2183
2814
  <div class="erd-rel-pop-footer">
2184
2815
  <button type="button" class="btn-secondary erd-rel-pop-focus-btn">Focus Tables</button>
2185
2816
  </div>
2186
- `,document.body.appendChild(c),rn=c,c.querySelector(`.erd-rel-pop-close`).onclick=e=>{e.stopPropagation(),an()},c.querySelector(`.erd-rel-pop-focus-btn`).onclick=i=>{i.stopPropagation(),sn(e,t,n,r),an()};let l=e=>{c.contains(e.target)||(an(),document.removeEventListener(`pointerdown`,l))};setTimeout(()=>{document.addEventListener(`pointerdown`,l)},50)}function sn(e,t,n,r){let i=document.querySelectorAll(`.erd-node`),a=document.querySelectorAll(`.erd-relationship-path`),o=document.querySelectorAll(`.erd-column`);i.forEach(t=>{let r=t.dataset.table;r===e||r===n?(t.classList.remove(`is-dimmed`),t.classList.add(`is-focused`)):(t.classList.add(`is-dimmed`),t.classList.remove(`is-focused`))}),a.forEach(i=>{i.dataset.fromTable===e&&i.dataset.fromCol===t&&i.dataset.toTable===n&&i.dataset.toCol===r?(i.classList.remove(`is-dimmed`),i.classList.add(`is-focused`)):(i.classList.add(`is-dimmed`),i.classList.remove(`is-focused`))}),o.forEach(i=>{let a=i.closest(`.erd-node`)?.dataset.table,o=i.dataset.col;a===e&&o===t||a===n&&o===r?i.classList.add(`is-focused-col`):i.classList.remove(`is-focused-col`)})}function cn(e){let t=document.querySelectorAll(`.erd-node`),n=document.querySelectorAll(`.erd-relationship-path`),r=new Set([e]);n.forEach(t=>{t.dataset.fromTable===e&&r.add(t.dataset.toTable),t.dataset.toTable===e&&r.add(t.dataset.fromTable)}),t.forEach(t=>{let n=t.dataset.table;r.has(n)?(t.classList.remove(`is-dimmed`),n===e&&t.classList.add(`is-focused`)):(t.classList.add(`is-dimmed`),t.classList.remove(`is-focused`))}),n.forEach(t=>{t.dataset.fromTable===e||t.dataset.toTable===e?(t.classList.remove(`is-dimmed`),t.classList.add(`is-focused`)):(t.classList.add(`is-dimmed`),t.classList.remove(`is-focused`))})}function ln(){document.querySelectorAll(`.erd-node`).forEach(e=>{e.classList.remove(`is-dimmed`,`is-focused`,`is-relationship-highlight`)}),document.querySelectorAll(`.erd-relationship-path`).forEach(e=>{e.classList.remove(`is-dimmed`,`is-focused`,`is-hovered`)}),document.querySelectorAll(`.erd-column`).forEach(e=>{e.classList.remove(`is-focused-col`)})}function un(e,t){if(!e||!t||t.length===0)return{mapW:180,mapH:120,scale:.1,offsetX:0,offsetY:0,minX:0,minY:0,vW:800,vH:600,vLeft:0,vTop:0};let n=e.clientWidth/B.zoom,r=e.clientHeight/B.zoom,i=e.scrollLeft/B.zoom,a=e.scrollTop/B.zoom,o=1/0,s=1/0,c=-1/0,l=-1/0;t.forEach(e=>{let t=parseFloat(e.style.left)||0,n=parseFloat(e.style.top)||0,r=e.offsetWidth||290,i=e.offsetHeight||150;t<o&&(o=t),n<s&&(s=n),t+r>c&&(c=t+r),n+i>l&&(l=n+i)}),o===1/0&&(o=0,s=0,c=800,l=600),o-=200,s-=200,c+=200,l+=200;let u=c-o,d=l-s,f=Math.max(u,n),p=Math.max(d,r),m=o+u/2,h=s+d/2,g=m-f/2,_=h-p/2,v=Math.min(180/f,120/p);return{mapW:180,mapH:120,scale:v,offsetX:(180-f*v)/2,offsetY:(120-p*v)/2,minX:g,minY:_,vW:n,vH:r,vLeft:i,vTop:a}}function dn(){let e=document.getElementById(`erd-minimap-content`);if(!e)return;e.innerHTML=``;let t=document.getElementById(`erd-nodes-layer`),n=document.getElementById(`erd-wrapper`);if(!t||!n)return;let r=Array.from(t.querySelectorAll(`.erd-node`));if(r.length===0)return;let{scale:i,offsetX:a,offsetY:o,minX:s,minY:c,vW:l,vH:u,vLeft:d,vTop:f}=un(n,r);r.forEach(t=>{let n=parseFloat(t.style.left)||0,r=parseFloat(t.style.top)||0,l=t.offsetWidth||290,u=t.offsetHeight||150,d=t.dataset.table,f=document.createElement(`div`);f.style.position=`absolute`,f.style.left=`${a+(n-s)*i}px`,f.style.top=`${o+(r-c)*i}px`,f.style.width=`${Math.max(l*i,8)}px`,f.style.height=`${Math.max(u*i,6)}px`,f.style.backgroundColor=`var(--color-primary)`,f.style.opacity=B.selectedTables.has(d)?`1`:`0.6`,f.style.borderRadius=`2px`,e.appendChild(f)});let p=document.getElementById(`erd-minimap-viewport`);p&&(p.style.left=`${a+(d-s)*i}px`,p.style.top=`${o+(f-c)*i}px`,p.style.width=`${l*i}px`,p.style.height=`${u*i}px`)}function fn(e=120,t=120){let n=`new_table_${Math.floor(Math.random()*1e3)}`,r={table:n,isDraft:!0,columns:[{name:`id`,type:`INTEGER`,isPk:!0,isDraft:!0,nullable:!1}]},i=jt();i[n]={x:e,y:t},Mt(i),B.pushUndoState(),B.erdData.push(r),B.setSelection(n),V()}async function pn(e){let t=document.getElementById(`table-name`);t&&(t.textContent=`Entity Relationship Diagram`);let n=document.getElementById(`table-icon`);n&&(n.textContent=`account_tree`),document.getElementById(`erd-main-viewport`)||(e.innerHTML=`
2817
+ `,document.body.appendChild(c),dr=c,c.querySelector(`.erd-rel-pop-close`).onclick=e=>{e.stopPropagation(),fr()},c.querySelector(`.erd-rel-pop-focus-btn`).onclick=i=>{i.stopPropagation(),mr(e,t,n,r),fr()};let l=e=>{c.contains(e.target)||(fr(),document.removeEventListener(`pointerdown`,l))};setTimeout(()=>{document.addEventListener(`pointerdown`,l)},50)}function mr(e,t,n,r){let i=document.querySelectorAll(`.erd-node`),a=document.querySelectorAll(`.erd-relationship-path`),o=document.querySelectorAll(`.erd-column`);i.forEach(t=>{let r=t.dataset.table;r===e||r===n?(t.classList.remove(`is-dimmed`),t.classList.add(`is-focused`)):(t.classList.add(`is-dimmed`),t.classList.remove(`is-focused`))}),a.forEach(i=>{i.dataset.fromTable===e&&i.dataset.fromCol===t&&i.dataset.toTable===n&&i.dataset.toCol===r?(i.classList.remove(`is-dimmed`),i.classList.add(`is-focused`)):(i.classList.add(`is-dimmed`),i.classList.remove(`is-focused`))}),o.forEach(i=>{let a=i.closest(`.erd-node`)?.dataset.table,o=i.dataset.col;a===e&&o===t||a===n&&o===r?i.classList.add(`is-focused-col`):i.classList.remove(`is-focused-col`)})}function hr(e){let t=document.querySelectorAll(`.erd-node`),n=document.querySelectorAll(`.erd-relationship-path`),r=new Set([e]);n.forEach(t=>{t.dataset.fromTable===e&&r.add(t.dataset.toTable),t.dataset.toTable===e&&r.add(t.dataset.fromTable)}),t.forEach(t=>{let n=t.dataset.table;r.has(n)?(t.classList.remove(`is-dimmed`),n===e&&t.classList.add(`is-focused`)):(t.classList.add(`is-dimmed`),t.classList.remove(`is-focused`))}),n.forEach(t=>{t.dataset.fromTable===e||t.dataset.toTable===e?(t.classList.remove(`is-dimmed`),t.classList.add(`is-focused`)):(t.classList.add(`is-dimmed`),t.classList.remove(`is-focused`))})}function gr(){document.querySelectorAll(`.erd-node`).forEach(e=>{e.classList.remove(`is-dimmed`,`is-focused`,`is-relationship-highlight`)}),document.querySelectorAll(`.erd-relationship-path`).forEach(e=>{e.classList.remove(`is-dimmed`,`is-focused`,`is-hovered`)}),document.querySelectorAll(`.erd-column`).forEach(e=>{e.classList.remove(`is-focused-col`)})}function _r(e,t){if(!e||!t||t.length===0)return{mapW:180,mapH:120,scale:.1,offsetX:0,offsetY:0,minX:0,minY:0,vW:800,vH:600,vLeft:0,vTop:0};let n=e.clientWidth/J.zoom,r=e.clientHeight/J.zoom,i=e.scrollLeft/J.zoom,a=e.scrollTop/J.zoom,o=1/0,s=1/0,c=-1/0,l=-1/0;t.forEach(e=>{let t=parseFloat(e.style.left)||0,n=parseFloat(e.style.top)||0,r=e.offsetWidth||290,i=e.offsetHeight||150;t<o&&(o=t),n<s&&(s=n),t+r>c&&(c=t+r),n+i>l&&(l=n+i)}),o===1/0&&(o=0,s=0,c=800,l=600),o-=200,s-=200,c+=200,l+=200;let u=c-o,d=l-s,f=Math.max(u,n),p=Math.max(d,r),m=o+u/2,h=s+d/2,g=m-f/2,_=h-p/2,v=Math.min(180/f,120/p);return{mapW:180,mapH:120,scale:v,offsetX:(180-f*v)/2,offsetY:(120-p*v)/2,minX:g,minY:_,vW:n,vH:r,vLeft:i,vTop:a}}function vr(){let e=document.getElementById(`erd-minimap-content`);if(!e)return;e.innerHTML=``;let t=document.getElementById(`erd-nodes-layer`),n=document.getElementById(`erd-wrapper`);if(!t||!n)return;let r=Array.from(t.querySelectorAll(`.erd-node`));if(r.length===0)return;let{scale:i,offsetX:a,offsetY:o,minX:s,minY:c,vW:l,vH:u,vLeft:d,vTop:f}=_r(n,r);r.forEach(t=>{let n=parseFloat(t.style.left)||0,r=parseFloat(t.style.top)||0,l=t.offsetWidth||290,u=t.offsetHeight||150,d=t.dataset.table,f=document.createElement(`div`);f.style.position=`absolute`,f.style.left=`${a+(n-s)*i}px`,f.style.top=`${o+(r-c)*i}px`,f.style.width=`${Math.max(l*i,8)}px`,f.style.height=`${Math.max(u*i,6)}px`,f.style.backgroundColor=`var(--color-primary)`,f.style.opacity=J.selectedTables.has(d)?`1`:`0.6`,f.style.borderRadius=`2px`,e.appendChild(f)});let p=document.getElementById(`erd-minimap-viewport`);p&&(p.style.left=`${a+(d-s)*i}px`,p.style.top=`${o+(f-c)*i}px`,p.style.width=`${l*i}px`,p.style.height=`${u*i}px`)}function yr(e=120,t=120){let n=`new_table_${Math.floor(Math.random()*1e3)}`,r={table:n,isDraft:!0,columns:[{name:`id`,type:`INTEGER`,isPk:!0,isDraft:!0,nullable:!1}]},i=Bn();i[n]={x:e,y:t},Vn(i),J.pushUndoState(),J.erdData.push(r),J.setSelection(n),X()}async function br(e){let t=document.getElementById(`table-name`);t&&(t.textContent=`Entity Relationship Diagram`);let n=document.getElementById(`table-icon`);n&&(n.textContent=`account_tree`),document.getElementById(`erd-main-viewport`)||(e.innerHTML=`
2187
2818
  <div id="erd-main-viewport" class="erd-main-viewport">
2188
2819
  <!-- Canvas Scrollable Workspace -->
2189
2820
  <div id="erd-wrapper" class="erd-grid-bg erd-workspace-container">
@@ -2285,7 +2916,7 @@ $1`)}),t=t.replace(/[ \t]+(AND\b|OR\b)/g,`
2285
2916
  </div>
2286
2917
  </div>
2287
2918
  </div>
2288
- `,document.getElementById(`erd-wrapper`).addEventListener(`contextmenu`,e=>{if(e.preventDefault(),e.target.closest(`.erd-node`))return;let t=document.getElementById(`erd-workspace`).getBoundingClientRect(),n=(e.clientX-t.left)/B.zoom,r=(e.clientY-t.top)/B.zoom;A(e,[{label:`Add Table`,icon:`table_chart`,action:()=>fn(n,r)},{label:`Paste`,icon:`content_paste`,action:Ht}])}),$t());let r=document.getElementById(`erd-nodes-layer`);r&&(r.innerHTML=`<div class="erd-loading-state"><span class="material-symbols-outlined animate-spin icon-24">progress_activity</span><span>Loading Schema Diagrams...</span></div>`),B.erdData=await At()||[],B.erdData.forEach(e=>{e.columns.sort((e,t)=>e.isPk&&!t.isPk?-1:!e.isPk&&t.isPk||e.fkTarget&&!t.fkTarget?1:!e.fkTarget&&t.fkTarget?-1:0),e.columns.forEach(e=>{e.isPk&&(e.nullable=!1)})}),B.undoStack=[],B.clearSelection(),V(),setTimeout(()=>{let e=document.getElementById(`erd-wrapper`);if(e&&e.scrollLeft===0&&e.scrollTop===0){let t=document.querySelectorAll(`.erd-node`);if(t.length>0){let n=1/0,r=1/0,i=-1/0,a=-1/0;t.forEach(e=>{let t=parseFloat(e.style.left)||0,o=parseFloat(e.style.top)||0,s=e.offsetWidth||290,c=e.offsetHeight||150;t<n&&(n=t),o<r&&(r=o),t+s>i&&(i=t+s),o+c>a&&(a=o+c)});let o=(n+i)/2,s=(r+a)/2;e.scrollLeft=o*B.zoom-e.clientWidth/2,e.scrollTop=s*B.zoom-e.clientHeight/2}}},40)}var mn=null,hn=null;function gn({icon:e,label:t,value:n,badge:r=``,badgeClass:i=`badge-neutral`}){return`
2919
+ `,document.getElementById(`erd-wrapper`).addEventListener(`contextmenu`,e=>{if(e.preventDefault(),e.target.closest(`.erd-node`))return;let t=document.getElementById(`erd-workspace`).getBoundingClientRect(),n=(e.clientX-t.left)/J.zoom,r=(e.clientY-t.top)/J.zoom;V(e,[{label:`Add Table`,icon:`table_chart`,action:()=>yr(n,r)},{label:`Paste`,icon:`content_paste`,action:Zn}])}),sr());let r=document.getElementById(`erd-nodes-layer`);r&&(r.innerHTML=`<div class="erd-loading-state"><span class="material-symbols-outlined animate-spin icon-24">progress_activity</span><span>Loading Schema Diagrams...</span></div>`),J.erdData=await zn()||[],J.erdData.forEach(e=>{e.columns.sort((e,t)=>e.isPk&&!t.isPk?-1:!e.isPk&&t.isPk||e.fkTarget&&!t.fkTarget?1:!e.fkTarget&&t.fkTarget?-1:0),e.columns.forEach(e=>{e.isPk&&(e.nullable=!1)})}),J.undoStack=[],J.clearSelection(),X(),setTimeout(()=>{let e=document.getElementById(`erd-wrapper`);if(e&&e.scrollLeft===0&&e.scrollTop===0){let t=document.querySelectorAll(`.erd-node`);if(t.length>0){let n=1/0,r=1/0,i=-1/0,a=-1/0;t.forEach(e=>{let t=parseFloat(e.style.left)||0,o=parseFloat(e.style.top)||0,s=e.offsetWidth||290,c=e.offsetHeight||150;t<n&&(n=t),o<r&&(r=o),t+s>i&&(i=t+s),o+c>a&&(a=o+c)});let o=(n+i)/2,s=(r+a)/2;e.scrollLeft=o*J.zoom-e.clientWidth/2,e.scrollTop=s*J.zoom-e.clientHeight/2}}},40)}var xr=null,Sr=null;function Cr({icon:e,label:t,value:n,badge:r=``,badgeClass:i=`badge-neutral`}){return`
2289
2920
  <div class="status-dashboard-status-tile">
2290
2921
  <div class="status-dashboard-tile-icon">
2291
2922
  <span class="material-symbols-outlined">${e}</span>
@@ -2298,7 +2929,7 @@ $1`)}),t=t.replace(/[ \t]+(AND\b|OR\b)/g,`
2298
2929
  </div>
2299
2930
  </div>
2300
2931
  </div>
2301
- `}function _n(e,t=0){let n=document.getElementById(`status-cards-container`);if(!n)return;let r=``,i=Date.now(),a=e.status===`connected`;r+=gn({icon:`apps`,label:`STATUS`,value:a?`Healthy`:`Disconnected`,badge:a?`NORMAL`:`OFFLINE`,badgeClass:a?`badge-status-ok`:`badge-status-err`});let o=(e.dbType||`UNKNOWN`).toUpperCase(),s=e.version?`v${e.version}`:`NANO`;r+=gn({icon:`memory`,label:`COMPUTE`,value:o,badge:s,badgeClass:`badge-primary`}),r+=gn({icon:`database`,label:`STORAGE`,value:yt(e.sizeBytes)});let c=e.activeConnections||(e.dbType,1);r+=gn({icon:`hub`,label:`CONNECTIONS`,value:`${c} Active`,badge:e.dbType===`sqlite`?`LOCAL`:`POOLED`,badgeClass:`badge-neutral`}),r+=gn({icon:`table_rows`,label:`TABLES`,value:`${e.totalTables??0} Tables`});let l=`${(t||0).toLocaleString()} Rows`;if(e.dbType===`mysql`&&e.queries){if(mn&&hn){let t=(i-hn)/1e3;l=`${(Math.max(0,e.queries-(mn.queries||0))/t).toFixed(1)} QPS`}}else if(e.dbType===`postgres`&&e.transactions&&mn&&hn){let t=(i-hn)/1e3;l=`${(Math.max(0,e.transactions-(mn.transactions||0))/t).toFixed(1)} TPS`}r+=gn({icon:`inventory_2`,label:`DATABASE RECORDS`,value:l}),n.innerHTML=r,mn=e,hn=i}window.navigateToTableData=function(e){let t=document.querySelector(`.table-btn[data-table="${e}"]`);t&&(window.AppState.currentTable=e,window.AppState.currentTableBtnElement=t,window.handleSwitchTab(`data-btn`))};function vn(e={}){let t=document.getElementById(`status-distribution-container`),n=document.getElementById(`status-toptables-container`);if(!t||!n)return 0;let r=Object.entries(e).sort((e,t)=>t[1]-e[1]),i=r.reduce((e,[t,n])=>e+n,0);if(r.length===0)return n.classList.remove(`hidden`),t.classList.add(`hidden`),n.style.gridColumn=`1 / -1`,n.innerHTML=`
2932
+ `}function wr(e,t=0){let n=document.getElementById(`status-cards-container`);if(!n)return;let r=``,i=Date.now(),a=e.status===`connected`;r+=Cr({icon:`apps`,label:`STATUS`,value:a?`Healthy`:`Disconnected`,badge:a?`NORMAL`:`OFFLINE`,badgeClass:a?`badge-status-ok`:`badge-status-err`});let o=(e.dbType||`UNKNOWN`).toUpperCase(),s=e.version?`v${e.version}`:`NANO`;r+=Cr({icon:`memory`,label:`COMPUTE`,value:o,badge:s,badgeClass:`badge-primary`}),r+=Cr({icon:`database`,label:`STORAGE`,value:tn(e.sizeBytes)});let c=e.activeConnections||(e.dbType,1);r+=Cr({icon:`hub`,label:`CONNECTIONS`,value:`${c} Active`,badge:e.dbType===`sqlite`?`LOCAL`:`POOLED`,badgeClass:`badge-neutral`}),r+=Cr({icon:`table_rows`,label:`TABLES`,value:`${e.totalTables??0} Tables`});let l=`${(t||0).toLocaleString()} Rows`;if(e.dbType===`mysql`&&e.queries){if(xr&&Sr){let t=(i-Sr)/1e3;l=`${(Math.max(0,e.queries-(xr.queries||0))/t).toFixed(1)} QPS`}}else if(e.dbType===`postgres`&&e.transactions&&xr&&Sr){let t=(i-Sr)/1e3;l=`${(Math.max(0,e.transactions-(xr.transactions||0))/t).toFixed(1)} TPS`}r+=Cr({icon:`inventory_2`,label:`DATABASE RECORDS`,value:l}),n.innerHTML=r,xr=e,Sr=i}window.navigateToTableData=function(e){let t=document.querySelector(`.table-btn[data-table="${e}"]`);t&&(window.AppState.currentTable=e,window.AppState.currentTableBtnElement=t,window.handleSwitchTab(`data-btn`))};function Tr(e={}){let t=document.getElementById(`status-distribution-container`),n=document.getElementById(`status-toptables-container`);if(!t||!n)return 0;let r=Object.entries(e).sort((e,t)=>t[1]-e[1]),i=r.reduce((e,[t,n])=>e+n,0);if(r.length===0)return n.classList.remove(`hidden`),t.classList.add(`hidden`),n.style.gridColumn=`1 / -1`,n.innerHTML=`
2302
2933
  <div class="drixio-empty-analytics">
2303
2934
  <div class="drixio-empty-icon">
2304
2935
  <span class="material-symbols-outlined">table_chart_view</span>
@@ -2384,10 +3015,74 @@ $1`)}),t=t.replace(/[ \t]+(AND\b|OR\b)/g,`
2384
3015
  <span class="donut-total-label">No Rows</span>
2385
3016
  </div>
2386
3017
  </div>
2387
- `,u+=`<div class="text-soft" style="font-size: 13px;">No data rows found</div>`;u+=`</div>`,l+=u+`</div>`,t.innerHTML=l,t.classList.remove(`hidden`),t.classList.add(`block`);let d=n.querySelectorAll(`.top-table-item`),f=t.querySelectorAll(`.legend-item[data-table]`),p=t.querySelectorAll(`.donut-slice[data-table]`),m=(e,r)=>{n.querySelector(`.top-table-item[data-table="${e}"]`)?.classList.toggle(`is-hovered`,r),t.querySelector(`.legend-item[data-table="${e}"]`)?.classList.toggle(`is-hovered`,r),p.length>0&&(r?p.forEach(t=>{t.dataset.table===e?t.style.opacity=`1`:t.style.opacity=`0.3`}):p.forEach(e=>e.style.opacity=`1`))};return d.forEach(e=>{let t=e.dataset.table;e.addEventListener(`mouseenter`,()=>m(t,!0)),e.addEventListener(`mouseleave`,()=>m(t,!1))}),f.forEach(e=>{let t=e.dataset.table;e.addEventListener(`mouseenter`,()=>m(t,!0)),e.addEventListener(`mouseleave`,()=>m(t,!1))}),p.forEach(e=>{let t=e.dataset.table;e.addEventListener(`mouseenter`,()=>m(t,!0)),e.addEventListener(`mouseleave`,()=>m(t,!1))}),i}var yn=null,bn=`records`,xn=null;function Sn(e=`records`){bn=e,xn=null,yn||On(),Tn(),yn.classList.remove(`hidden`)}function Cn(){yn&&(yn.classList.add(`hidden`),xn=null,wn())}function wn(){let e=document.getElementById(`import-file-input`);e&&(e.value=``);let t=document.getElementById(`import-file-preview`);t&&t.classList.add(`hidden`);let n=document.getElementById(`import-dropzone`);n&&n.classList.remove(`has-file`,`drag-over`);let r=document.getElementById(`import-modal-submit-btn`);r&&(r.disabled=!0)}function Tn(){let e=window.AppState?.currentTable||``,t=document.getElementById(`import-target-table-wrap`),n=document.getElementById(`import-target-table-name`),r=document.getElementById(`import-format-hint`),i=document.getElementById(`import-file-input`),a=document.getElementById(`import-modal-submit-btn`);document.querySelectorAll(`.import-type-tab`).forEach(e=>{e.getAttribute(`data-type`)===bn?e.classList.add(`active`):e.classList.remove(`active`)}),bn===`records`?(t&&(t.style.display=`flex`),n&&(n.textContent=e||`No table selected`,e?n.classList.remove(`empty`):n.classList.add(`empty`)),r&&(r.textContent=`Accepts .csv or .json files`),i&&(i.accept=`.csv,.json`)):bn===`erd`?(t&&(t.style.display=`none`),r&&(r.textContent=`Accepts canvas layout JSON files (.json)`),i&&(i.accept=`.json`)):bn===`database`&&(t&&(t.style.display=`none`),r&&(r.textContent=`Accepts SQL dumps (.sql) or schema JSON`),i&&(i.accept=`.sql,.json`)),a&&(a.disabled=!xn)}function En(e){if(!e)return;let t=e.name.split(`.`).pop()?.toLowerCase(),n={records:[`csv`,`json`],erd:[`json`],database:[`sql`,`json`]}[bn]||[];if(!n.includes(t)){typeof window.showToast==`function`&&window.showToast(`Invalid file format for ${bn}. Please select a .${n.join(` or .`)} file.`,`error`);return}xn=e;let r=document.getElementById(`import-file-name`),i=document.getElementById(`import-file-size`),a=document.getElementById(`import-file-preview`),o=document.getElementById(`import-dropzone`),s=document.getElementById(`import-modal-submit-btn`);if(r&&(r.textContent=e.name),i){let t=e.size/1024;i.textContent=t>1024?`${(t/1024).toFixed(2)} MB`:`${t.toFixed(1)} KB`}a&&a.classList.remove(`hidden`),o&&o.classList.add(`has-file`),s&&(s.disabled=!1)}async function Dn(){if(!xn)return;let e=document.getElementById(`import-modal-submit-btn`),t=e?.innerHTML;e&&(e.disabled=!0,e.innerHTML=`
3018
+ `,u+=`<div class="text-soft" style="font-size: 13px;">No data rows found</div>`;u+=`</div>`,l+=u+`</div>`,t.innerHTML=l,t.classList.remove(`hidden`),t.classList.add(`block`);let d=n.querySelectorAll(`.top-table-item`),f=t.querySelectorAll(`.legend-item[data-table]`),p=t.querySelectorAll(`.donut-slice[data-table]`),m=(e,r)=>{n.querySelector(`.top-table-item[data-table="${e}"]`)?.classList.toggle(`is-hovered`,r),t.querySelector(`.legend-item[data-table="${e}"]`)?.classList.toggle(`is-hovered`,r),p.length>0&&(r?p.forEach(t=>{t.dataset.table===e?t.style.opacity=`1`:t.style.opacity=`0.3`}):p.forEach(e=>e.style.opacity=`1`))};return d.forEach(e=>{let t=e.dataset.table;e.addEventListener(`mouseenter`,()=>m(t,!0)),e.addEventListener(`mouseleave`,()=>m(t,!1))}),f.forEach(e=>{let t=e.dataset.table;e.addEventListener(`mouseenter`,()=>m(t,!0)),e.addEventListener(`mouseleave`,()=>m(t,!1))}),p.forEach(e=>{let t=e.dataset.table;e.addEventListener(`mouseenter`,()=>m(t,!0)),e.addEventListener(`mouseleave`,()=>m(t,!1))}),i}function Er({tableName:e,schema:t,file:n,onComplete:r}){let i=document.getElementById(`import-wizard-modal`);i&&i.remove(),i=document.createElement(`div`),i.id=`import-wizard-modal`,i.className=`modal-overlay`;let a=new FileReader;a.onload=a=>{let o=a.target.result,s=n.name.endsWith(`.json`),c=[],l=[],u=0,d=[];try{if(s){let e=JSON.parse(o);d=Array.isArray(e)?e:[e],u=d.length,u>0&&(c=Object.keys(d[0]),l=d.slice(0,3))}else{let e=Dr(o);e.length>0&&(c=e[0],u=e.length-1,l=e.slice(1,4))}}catch(e){alert(`Failed to parse file: `+e.message);return}if(c.length===0){alert(`No columns detected in the uploaded file.`);return}Or(i,e,t,n.name,u,c,l,s,o,d,r)},a.readAsText(n)}function Dr(e){let t=[],n=[],r=``,i=!1,a=0;for(;a<e.length;){let o=e[a];if(o===`"`){if(i&&e[a+1]===`"`){r+=`"`,a+=2;continue}i=!i,a++;continue}if(o===`,`&&!i){n.push(r.trim()),r=``,a++;continue}if((o===`\r`||o===`
3019
+ `)&&!i){o===`\r`&&e[a+1]===`
3020
+ `&&a++,n.push(r.trim()),r=``,(n.length>1||n.length===1&&n[0]!==``)&&t.push(n),n=[],a++;continue}r+=o,a++}return(r.length>0||n.length>0)&&(n.push(r.trim()),(n.length>1||n.length===1&&n[0]!==``)&&t.push(n)),t}function Or(e,t,n,r,i,a,o,s,c,l,u){n.map(e=>e.name);let d=e=>{let t=e.toLowerCase().replace(/[-_ ]/g,``);for(let e of n)if(t===e.name.toLowerCase().replace(/[-_ ]/g,``))return e.name;return``},f=a.map((e,t)=>{let r=d(e),i=o.map(n=>{let r=s?n[e]:n[t];return r==null?``:String(r)}).filter(e=>e!==``).slice(0,2),a=i.length>0?i.map(e=>`<code class="import-sample-pill">${kr(e)}</code>`).join(` `):`<span style="color: var(--color-text-subtle); font-size: 11px;">(empty)</span>`,c=[`<option value="">-- Skip this column (跳过) --</option>`,...n.map(e=>{let t=e.name===r;return`<option value="${e.name}" ${t?`selected`:``}>${e.name} (${(e.type||`text`).toLowerCase()})${e.isPk?` [PK]`:``}</option>`})].join(``);return`
3021
+ <tr style="border-bottom: 1px solid var(--color-border-subtle, rgba(255,255,255,0.06));">
3022
+ <td style="padding: 10px 12px; font-weight: 600; font-family: monospace; color: var(--color-text-main);">
3023
+ <div>${kr(e)}</div>
3024
+ <div style="margin-top: 4px; display: flex; gap: 4px; flex-wrap: wrap;">${a}</div>
3025
+ </td>
3026
+ <td style="padding: 10px 8px; text-align: center; color: var(--color-text-subtle);">
3027
+ <span class="material-symbols-outlined" style="font-size: 18px;">arrow_forward</span>
3028
+ </td>
3029
+ <td style="padding: 10px 12px;">
3030
+ <select class="import-mapping-select modal-input" data-src-header="${kr(e)}" data-src-idx="${t}" style="width: 100%; height: 34px; font-size: 12.5px;">
3031
+ ${c}
3032
+ </select>
3033
+ </td>
3034
+ </tr>
3035
+ `}).join(``);e.innerHTML=`
3036
+ <div class="modal-container" style="max-width: 680px; width: 92vw; background: var(--color-surface, #1e1e24); border-radius: 8px; border: 1px solid var(--color-border, #333); box-shadow: 0 10px 30px rgba(0,0,0,0.5); overflow: hidden; display: flex; flex-direction: column;">
3037
+ <div class="modal-header" style="padding: 14px 20px; border-bottom: 1px solid var(--color-border-subtle, rgba(255,255,255,0.06)); display: flex; justify-content: space-between; align-items: center;">
3038
+ <div class="flex items-center gap-2">
3039
+ <span class="material-symbols-outlined text-primary" style="font-size: 20px;">tune</span>
3040
+ <h3 class="m-0 text-15 font-semibold">Import Data: Column Mapping Wizard</h3>
3041
+ </div>
3042
+ <button id="close-import-wizard-btn" class="modal-close-btn" title="Close">
3043
+ <span class="material-symbols-outlined">close</span>
3044
+ </button>
3045
+ </div>
3046
+
3047
+ <div style="padding: 14px 20px; background: rgba(0,0,0,0.15); border-bottom: 1px solid var(--color-border-subtle, rgba(255,255,255,0.06)); font-size: 12.5px; color: var(--color-text-soft); display: flex; align-items: center; justify-content: space-between;">
3048
+ <div>
3049
+ Importing <strong style="color: var(--color-text-main);">${kr(r)}</strong> &middot; ~${i.toLocaleString()} rows into <strong style="color: var(--color-primary);">${t}</strong>
3050
+ </div>
3051
+ <span style="font-size: 11px; background: rgba(255,255,255,0.08); padding: 2px 8px; border-radius: 10px;">${s?`JSON`:`CSV`}</span>
3052
+ </div>
3053
+
3054
+ <div style="padding: 0 20px; max-height: 380px; overflow-y: auto;">
3055
+ <table style="width: 100%; border-collapse: collapse; text-align: left; font-size: 13px;">
3056
+ <thead>
3057
+ <tr style="border-bottom: 1px solid var(--color-border-subtle, rgba(255,255,255,0.08)); font-size: 11px; text-transform: uppercase; letter-spacing: 0.05em; color: var(--color-text-subtle);">
3058
+ <th style="padding: 10px 12px; width: 45%;">Source File Column</th>
3059
+ <th style="padding: 10px 8px; width: 10%; text-align: center;"></th>
3060
+ <th style="padding: 10px 12px; width: 45%;">Destination Table Column</th>
3061
+ </tr>
3062
+ </thead>
3063
+ <tbody>
3064
+ ${f}
3065
+ </tbody>
3066
+ </table>
3067
+ </div>
3068
+
3069
+ <div class="modal-footer" style="padding: 12px 20px; display: flex; justify-content: space-between; align-items: center; border-top: 1px solid var(--color-border-subtle, rgba(255,255,255,0.06)); background: rgba(0,0,0,0.1);">
3070
+ <div style="font-size: 12px; color: var(--color-text-soft);">
3071
+ Check field mappings and click Import to start.
3072
+ </div>
3073
+ <div class="flex items-center gap-2">
3074
+ <button id="cancel-import-wizard-btn" class="btn-secondary">Cancel</button>
3075
+ <button id="submit-import-wizard-btn" class="btn-primary flex items-center gap-1.5">
3076
+ <span class="material-symbols-outlined" style="font-size: 16px;">upload</span>
3077
+ <span>Confirm & Import</span>
3078
+ </button>
3079
+ </div>
3080
+ </div>
3081
+ </div>
3082
+ `,document.body.appendChild(e);let p=document.getElementById(`close-import-wizard-btn`),m=document.getElementById(`cancel-import-wizard-btn`),h=document.getElementById(`submit-import-wizard-btn`),g=()=>e.remove();p.onclick=g,m.onclick=g,h.onclick=async()=>{let n={};if(e.querySelectorAll(`.import-mapping-select`).forEach(e=>{let t=e.dataset.srcHeader,r=e.value;r&&(n[t]=r)}),Object.keys(n).length===0){alert(`Please map at least one column to import.`);return}h.disabled=!0,h.innerHTML=`<span class="material-symbols-outlined animate-spin" style="font-size: 16px;">progress_activity</span><span>Transforming & Importing...</span>`;try{let e=[];if(s)e=l.map(e=>{let t={};for(let[r,i]of Object.entries(n))t[i]=e[r];return t});else{let t=Dr(c);if(t.length>0){let r=t[0];for(let i=1;i<t.length;i++){let a=t[i],o={};r.forEach((e,t)=>{let r=n[e];r&&a[t]!==void 0&&(o[r]=a[t])}),e.push(o)}}}let r=new Blob([JSON.stringify(e)],{type:`application/json`}),i=new FormData;i.append(`file`,r,`${t}_mapped.json`),i.append(`format`,`json`);let a=await(await fetch(`/api/tables/${encodeURIComponent(t)}/import`,{method:`POST`,body:i})).json();a.success?(g(),window.showToast?.(a.message||`Imported ${e.length} rows successfully!`,`success`),u&&u()):(alert(a.error||`Failed to import data`),h.disabled=!1,h.innerHTML=`<span class="material-symbols-outlined" style="font-size: 16px;">upload</span><span>Confirm & Import</span>`)}catch(e){alert(`Import error: `+e.message),h.disabled=!1,h.innerHTML=`<span class="material-symbols-outlined" style="font-size: 16px;">upload</span><span>Confirm & Import</span>`}}}function kr(e){return e?String(e).replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`).replace(/"/g,`&quot;`):``}var Z=null,Ar=`records`,Q=null;function jr(e=`records`){Ar=e,Q=null,Z||Lr(),Pr(),Z.classList.remove(`hidden`)}function Mr(){Z&&(Z.classList.add(`hidden`),Q=null,Nr())}function Nr(){let e=document.getElementById(`import-file-input`);e&&(e.value=``);let t=document.getElementById(`import-file-preview`);t&&t.classList.add(`hidden`);let n=document.getElementById(`import-dropzone`);n&&n.classList.remove(`has-file`,`drag-over`);let r=document.getElementById(`import-modal-submit-btn`);r&&(r.disabled=!0)}function Pr(){let e=window.AppState?.currentTable||``,t=document.getElementById(`import-target-table-wrap`),n=document.getElementById(`import-target-table-name`),r=document.getElementById(`import-format-hint`),i=document.getElementById(`import-file-input`),a=document.getElementById(`import-modal-submit-btn`);document.querySelectorAll(`.import-type-tab`).forEach(e=>{e.getAttribute(`data-type`)===Ar?e.classList.add(`active`):e.classList.remove(`active`)}),Ar===`records`?(t&&(t.style.display=`flex`),n&&(n.textContent=e||`No table selected`,e?n.classList.remove(`empty`):n.classList.add(`empty`)),r&&(r.textContent=`Accepts .csv or .json files`),i&&(i.accept=`.csv,.json`)):Ar===`erd`?(t&&(t.style.display=`none`),r&&(r.textContent=`Accepts canvas layout JSON files (.json)`),i&&(i.accept=`.json`)):Ar===`database`&&(t&&(t.style.display=`none`),r&&(r.textContent=`Accepts SQL dumps (.sql) or schema JSON`),i&&(i.accept=`.sql,.json`)),a&&(a.disabled=!Q)}function Fr(e){if(!e)return;let t=e.name.split(`.`).pop()?.toLowerCase(),n={records:[`csv`,`json`],erd:[`json`],database:[`sql`,`json`]}[Ar]||[];if(!n.includes(t)){typeof window.showToast==`function`&&window.showToast(`Invalid file format for ${Ar}. Please select a .${n.join(` or .`)} file.`,`error`);return}Q=e;let r=document.getElementById(`import-file-name`),i=document.getElementById(`import-file-size`),a=document.getElementById(`import-file-preview`),o=document.getElementById(`import-dropzone`),s=document.getElementById(`import-modal-submit-btn`);if(r&&(r.textContent=e.name),i){let t=e.size/1024;i.textContent=t>1024?`${(t/1024).toFixed(2)} MB`:`${t.toFixed(1)} KB`}a&&a.classList.remove(`hidden`),o&&o.classList.add(`has-file`),s&&(s.disabled=!1)}async function Ir(){if(!Q)return;let e=document.getElementById(`import-modal-submit-btn`),t=e?.innerHTML;e&&(e.disabled=!0,e.innerHTML=`
2388
3083
  <span class="material-symbols-outlined icon-spin" style="font-size: 16px;">progress_activity</span>
2389
3084
  <span>Importing...</span>
2390
- `);try{if(bn===`records`){let e=window.AppState?.currentTable;if(!e){window.showToast?.(`Please select a table from the sidebar first.`,`error`);return}let t=xn.name.split(`.`).pop()?.toLowerCase()===`json`?`json`:`csv`,n=new FormData;n.append(`file`,xn),n.append(`format`,t),window.showToast?.(`Importing ${xn.name} into '${e}'...`,`success`);let r=await(await fetch(`/api/tables/${encodeURIComponent(e)}/import`,{method:`POST`,body:n})).json();if(r.success){if(window.showToast?.(r.message||`Import completed successfully`,`success`),window.AppState?.currentTab===`data-btn`){let t=`view-data-btn-${e}`,n=document.getElementById(t);n&&(n.innerHTML=``),window.renderCurrentView?.(``,!0)}Cn()}else window.showToast?.(r.error||`Import failed`,`error`)}else if(bn===`erd`){let e=await xn.text(),t=JSON.parse(e);if(typeof t!=`object`||!t)throw Error(`Invalid ERD layout JSON structure.`);let n=t.positions||t;localStorage.setItem(`drixio-erd-positions`,JSON.stringify(n)),window.showToast?.(`ERD layout imported successfully!`,`success`);let r=document.getElementById(`view-erd-btn`);r&&(r.innerHTML=``,window.AppState?.currentTab===`erd-btn`&&window.renderCurrentView?.()),Cn()}else if(bn===`database`){if(!confirm(`🚨 HIGH RISK ACTION: DATABASE RESTORE\n\nFile: ${xn.name} (${(xn.size/1024).toFixed(1)} KB)\n\nExecuting this SQL script directly against the database may modify, truncate, or drop existing tables.\n\nAre you sure you want to proceed?`))return;let e=new FormData;e.append(`file`,xn),window.showToast?.(`Executing ${xn.name} on database...`,`success`);let t=await(await fetch(`/api/database/import`,{method:`POST`,body:e})).json();t.success?(window.showToast?.(t.message||`Database restored successfully`,`success`),Cn(),setTimeout(()=>location.reload(),1500)):window.showToast?.(t.error||`Import failed`,`error`)}}catch(e){window.showToast?.(`Import error: ${e.message}`,`error`)}finally{e&&t&&(e.disabled=!xn,e.innerHTML=t)}}function On(){yn=document.createElement(`div`),yn.id=`import-modal-overlay`,yn.className=`modal-overlay hidden`,yn.innerHTML=`
3085
+ `);try{if(Ar===`records`){let e=window.AppState?.currentTable;if(!e){window.showToast?.(`Please select a table from the sidebar first.`,`error`);return}let t=window.TableStates?.[e]?.dataGrid?.schema||window.DataGrid?.schema;if(!t||t.length===0){let n=await u(e);n.success&&(t=n.data)}let n=Q;Mr(),Er({tableName:e,schema:t||[],file:n,onComplete:()=>{if(window.AppState?.currentTab===`data-btn`){let t=`view-data-btn-${e}`,n=document.getElementById(t);n&&(n.innerHTML=``),window.renderCurrentView?.(``,!0)}}});return}else if(Ar===`erd`){let e=await Q.text(),t=JSON.parse(e);if(typeof t!=`object`||!t)throw Error(`Invalid ERD layout JSON structure.`);let n=t.positions||t;localStorage.setItem(`drixio-erd-positions`,JSON.stringify(n)),window.showToast?.(`ERD layout imported successfully!`,`success`);let r=document.getElementById(`view-erd-btn`);r&&(r.innerHTML=``,window.AppState?.currentTab===`erd-btn`&&window.renderCurrentView?.()),Mr()}else if(Ar===`database`){if(!confirm(`🚨 HIGH RISK ACTION: DATABASE RESTORE\n\nFile: ${Q.name} (${(Q.size/1024).toFixed(1)} KB)\n\nExecuting this SQL script directly against the database may modify, truncate, or drop existing tables.\n\nAre you sure you want to proceed?`))return;let e=new FormData;e.append(`file`,Q),window.showToast?.(`Executing ${Q.name} on database...`,`success`);let t=await(await fetch(`/api/database/import`,{method:`POST`,body:e})).json();t.success?(window.showToast?.(t.message||`Database restored successfully`,`success`),Mr(),setTimeout(()=>location.reload(),1500)):window.showToast?.(t.error||`Import failed`,`error`)}}catch(e){window.showToast?.(`Import error: ${e.message}`,`error`)}finally{e&&t&&(e.disabled=!Q,e.innerHTML=t)}}function Lr(){Z=document.createElement(`div`),Z.id=`import-modal-overlay`,Z.className=`modal-overlay hidden`,Z.innerHTML=`
2391
3086
  <div class="modal-container import-modal-card">
2392
3087
  <div class="modal-header">
2393
3088
  <div class="modal-title-wrap">
@@ -2459,7 +3154,7 @@ $1`)}),t=t.replace(/[ \t]+(AND\b|OR\b)/g,`
2459
3154
  </button>
2460
3155
  </div>
2461
3156
  </div>
2462
- `,document.body.appendChild(yn),kn()}function kn(){if(!yn)return;let e=document.getElementById(`import-modal-close-btn`),t=document.getElementById(`import-modal-cancel-btn`),n=document.getElementById(`import-modal-submit-btn`),r=document.getElementById(`import-dropzone`),i=document.getElementById(`import-file-input`),a=document.getElementById(`import-file-remove-btn`);e?.addEventListener(`click`,Cn),t?.addEventListener(`click`,Cn),yn.addEventListener(`click`,e=>{e.target===yn&&Cn()}),document.addEventListener(`keydown`,e=>{e.key===`Escape`&&yn&&!yn.classList.contains(`hidden`)&&Cn()}),document.querySelectorAll(`.import-type-tab`).forEach(e=>{e.addEventListener(`click`,()=>{let t=e.getAttribute(`data-type`);t&&t!==bn&&(bn=t,xn=null,wn(),Tn())})}),r?.addEventListener(`click`,e=>{e.target!==a&&i?.click()}),i?.addEventListener(`change`,e=>{let t=e.target.files?.[0];t&&En(t)}),r?.addEventListener(`dragover`,e=>{e.preventDefault(),e.stopPropagation(),r.classList.add(`drag-over`)}),r?.addEventListener(`dragleave`,e=>{e.preventDefault(),e.stopPropagation(),r.classList.remove(`drag-over`)}),r?.addEventListener(`drop`,e=>{e.preventDefault(),e.stopPropagation(),r.classList.remove(`drag-over`);let t=e.dataTransfer?.files?.[0];t&&En(t)}),a?.addEventListener(`click`,e=>{e.stopPropagation(),xn=null,wn(),Tn()}),n?.addEventListener(`click`,Dn)}function An(){Mn()}async function jn(e){e.innerHTML=`
3157
+ `,document.body.appendChild(Z),Rr()}function Rr(){if(!Z)return;let e=document.getElementById(`import-modal-close-btn`),t=document.getElementById(`import-modal-cancel-btn`),n=document.getElementById(`import-modal-submit-btn`),r=document.getElementById(`import-dropzone`),i=document.getElementById(`import-file-input`),a=document.getElementById(`import-file-remove-btn`);e?.addEventListener(`click`,Mr),t?.addEventListener(`click`,Mr),Z.addEventListener(`click`,e=>{e.target===Z&&Mr()}),document.addEventListener(`keydown`,e=>{e.key===`Escape`&&Z&&!Z.classList.contains(`hidden`)&&Mr()}),document.querySelectorAll(`.import-type-tab`).forEach(e=>{e.addEventListener(`click`,()=>{let t=e.getAttribute(`data-type`);t&&t!==Ar&&(Ar=t,Q=null,Nr(),Pr())})}),r?.addEventListener(`click`,e=>{e.target!==a&&i?.click()}),i?.addEventListener(`change`,e=>{let t=e.target.files?.[0];t&&Fr(t)}),r?.addEventListener(`dragover`,e=>{e.preventDefault(),e.stopPropagation(),r.classList.add(`drag-over`)}),r?.addEventListener(`dragleave`,e=>{e.preventDefault(),e.stopPropagation(),r.classList.remove(`drag-over`)}),r?.addEventListener(`drop`,e=>{e.preventDefault(),e.stopPropagation(),r.classList.remove(`drag-over`);let t=e.dataTransfer?.files?.[0];t&&Fr(t)}),a?.addEventListener(`click`,e=>{e.stopPropagation(),Q=null,Nr(),Pr()}),n?.addEventListener(`click`,Ir)}function zr(){Vr()}async function Br(e){e.innerHTML=`
2463
3158
  <div class="status-dashboard" style="opacity: 0;">
2464
3159
  <!-- Top Section: Left (Title + Endpoint + 6 Cards) | Right (Dotted Matrix Canvas) -->
2465
3160
  <div class="status-dashboard-hero">
@@ -2706,7 +3401,7 @@ $1`)}),t=t.replace(/[ \t]+(AND\b|OR\b)/g,`
2706
3401
  <!-- Feature Prompts (Postgres / MySQL) -->
2707
3402
  <div id="feature-prompts-container" class="flex-col gap-4 hidden"></div>
2708
3403
  </div>
2709
- `,window.gsap?(gsap.to(`.status-dashboard`,{opacity:1,duration:.3,ease:`power2.out`}),gsap.to(`.skeleton-target`,{opacity:.6,yoyo:!0,repeat:-1,duration:1,ease:`sine.inOut`})):document.querySelector(`.status-dashboard`).style.opacity=`1`,await Mn();let t=document.getElementById(`btn-copy-conn-uri`);t&&t.addEventListener(`click`,()=>{let e=document.getElementById(`hero-conn-uri`),t=document.getElementById(`btn-copy-conn-label`);e&&e.textContent&&e.textContent!==`Connecting...`&&(navigator.clipboard.writeText(e.textContent),t&&(t.textContent=`Copied!`,setTimeout(()=>{t&&(t.textContent=`Copy`)},1800)),typeof window.showToast==`function`&&window.showToast(`Connection URI copied to clipboard!`,`success`))});let n=document.getElementById(`btn-quick-export-backup`);n&&n.addEventListener(`click`,()=>{window.open(`/api/database/export`,`_blank`)});let r=document.getElementById(`btn-quick-export-ddl`);r&&r.addEventListener(`click`,()=>{window.open(`/api/database/schema-only`,`_blank`)});let i=document.getElementById(`btn-quick-import-backup`);i&&i.addEventListener(`click`,()=>{Sn(`database`)});let a=document.getElementById(`btn-quick-export-dict`);a&&a.addEventListener(`click`,()=>{window.open(`/api/database/dictionary`,`_blank`)});let o=document.getElementById(`btn-quick-open-console`);o&&o.addEventListener(`click`,()=>{typeof window.handleSwitchTab==`function`&&window.handleSwitchTab(`console-btn`)});let s=document.getElementById(`btn-quick-open-erd`);s&&s.addEventListener(`click`,()=>{typeof window.handleSwitchTab==`function`&&window.handleSwitchTab(`erd-btn`)});let c=document.getElementById(`runtime-toggle-header`),l=document.getElementById(`runtime-details-body`),u=document.getElementById(`runtime-expand-arrow`);c&&l&&c.addEventListener(`click`,()=>{l.classList.contains(`hidden`)?(l.classList.remove(`hidden`),u&&(u.style.transform=`rotate(180deg)`)):(l.classList.add(`hidden`),u&&(u.style.transform=`rotate(0deg)`))});let d=document.getElementById(`status-refresh-btn`);d&&d.addEventListener(`click`,()=>{let e=d.querySelector(`.material-symbols-outlined`);if(e){e.style.transition=`transform 0.4s ease`;let t=parseInt(e.dataset.rot||`0`,10)+360;e.style.transform=`rotate(${t}deg)`,e.dataset.rot=`${t}`}Mn()});let f=!0,p=document.getElementById(`status-live-toggle`);p&&p.addEventListener(`click`,()=>{f=!f;let e=p.querySelector(`.live-dot-icon`),t=document.getElementById(`status-live-text`);f?(e&&(e.style.color=`var(--color-primary)`),t&&(t.textContent=`Live (3s)`)):(e&&(e.style.color=`var(--color-text-soft)`),t&&(t.textContent=`Paused`))}),window.statusPollingInterval&&clearInterval(window.statusPollingInterval),window.statusPollingInterval=setInterval(()=>{window.AppState.currentTab===`status-btn`&&f&&Mn()},3e3)}async function Mn(){let e=performance.now();try{let[t,n]=await Promise.all([fetch(`/api/status`),fetch(`/api/tables/stats`)]),r=await t.json(),i=await n.json(),a=Math.round(performance.now()-e);r.success?Nn(r.data,i.data,a):Pn(r.error||`Failed to load status`)}catch(e){Pn(e instanceof Error?e.message:String(e))}}function Nn(e,t={},n=null){let r=document.getElementById(`hero-db-name`),i=document.getElementById(`hero-conn-uri`);if(!r)return;let a=``;a=e.dbType===`sqlite`?`sqlite://${e.dbName||`drixio.db`}`:e.dbType===`postgres`?`postgresql://localhost:5432/${e.dbName||`postgres`}`:e.dbType===`mysql`?`mysql://localhost:3306/${e.dbName||`mysql`}`:`${e.dbType||`database`}://${e.dbName||``}`,r.textContent=e.dbName||`Database`,i&&(i.textContent=a);let o=document.getElementById(`node-db-title`),s=document.getElementById(`node-db-desc`),c=document.getElementById(`node-db-path`),l=document.getElementById(`node-engine-avatar`),u=document.getElementById(`node-engine-icon`),d=document.getElementById(`node-latency-text`),f=document.getElementById(`node-stat-cpu`),p=document.getElementById(`node-stat-ram`),m=document.getElementById(`node-stat-disk`),h=document.getElementById(`node-stat-conns`);o&&(o.textContent=e.dbName||`Primary Database`),s&&(s.textContent=`${(e.dbType||`SQL`).toUpperCase()} Serverless Engine`),c&&(c.textContent=a),l&&u&&(e.dbType===`sqlite`?(u.textContent=`database`,l.style.background=`rgba(37, 99, 235, 0.12)`,l.style.color=`var(--color-primary)`):e.dbType===`postgres`?(u.textContent=`dns`,l.style.background=`rgba(99, 102, 241, 0.15)`,l.style.color=`#818cf8`):(u.textContent=`database`,l.style.background=`rgba(245, 158, 11, 0.15)`,l.style.color=`#f59e0b`)),d&&(d.textContent=n===null?`< 1ms`:`${n}ms`),f&&(f.textContent=`CPU ${e.osCpuUsage===void 0?`< 1%`:e.osCpuUsage.toFixed(1)+`%`}`),m&&(m.textContent=`Disk ${yt(e.sizeBytes)}`),p&&(e.osMemUsed&&e.osMemTotal?p.textContent=`RAM ${Math.round(e.osMemUsed/e.osMemTotal*100)}%`:p.textContent=`RAM N/A`),h&&(h.textContent=`${e.activeConnections||1} conn`);let g=document.getElementById(`header-last-updated`);if(g){let e=new Date,t=`${e.getHours().toString().padStart(2,`0`)}:${e.getMinutes().toString().padStart(2,`0`)}:${e.getSeconds().toString().padStart(2,`0`)}`;g.textContent=n===null?t:`${t} (${n}ms)`}let _=vn(t),v=document.getElementById(`ribbon-records-count`);v&&(v.textContent=`${(_||0).toLocaleString()} Total Records`),_n(e,_);let y=document.getElementById(`rt-engine`),b=document.getElementById(`rt-version`),x=document.getElementById(`rt-dbname`),S=document.getElementById(`rt-uptime`),C=document.getElementById(`rt-conns`),w=document.getElementById(`rt-tables`),T=document.getElementById(`rt-storage`),E=document.getElementById(`rt-memory`),D=document.getElementById(`runtime-chip-engine`);y&&(y.textContent=(e.dbType||`UNKNOWN`).toUpperCase()),b&&(b.textContent=e.version?`v${e.version}`:`N/A`),x&&(x.textContent=e.dbName||`N/A`),S&&(S.textContent=bt(e.uptime));let O=e.activeConnections||(e.dbType,1);C&&(C.textContent=`${O} active connection(s)`),w&&(w.textContent=`${e.totalTables??0} tables`),T&&(T.textContent=yt(e.sizeBytes)),E&&(e.osMemUsed&&e.osMemTotal?E.textContent=`${yt(e.osMemUsed)} / ${yt(e.osMemTotal)}`:E.textContent=`Managed by host system`),D&&(D.textContent=`${(e.dbType||`SQL`).toUpperCase()} ${e.version?`v${e.version}`:``}`);let k=document.getElementById(`feature-prompts-container`);k&&(e.dbType===`sqlite`?(k.classList.add(`hidden`),k.classList.remove(`flex`),k.innerHTML=``):(k.innerHTML=`
3404
+ `,window.gsap?(gsap.to(`.status-dashboard`,{opacity:1,duration:.3,ease:`power2.out`}),gsap.to(`.skeleton-target`,{opacity:.6,yoyo:!0,repeat:-1,duration:1,ease:`sine.inOut`})):document.querySelector(`.status-dashboard`).style.opacity=`1`,await Vr();let t=document.getElementById(`btn-copy-conn-uri`);t&&t.addEventListener(`click`,()=>{let e=document.getElementById(`hero-conn-uri`),t=document.getElementById(`btn-copy-conn-label`);e&&e.textContent&&e.textContent!==`Connecting...`&&(navigator.clipboard.writeText(e.textContent),t&&(t.textContent=`Copied!`,setTimeout(()=>{t&&(t.textContent=`Copy`)},1800)),typeof window.showToast==`function`&&window.showToast(`Connection URI copied to clipboard!`,`success`))});let n=document.getElementById(`btn-quick-export-backup`);n&&n.addEventListener(`click`,()=>{window.open(`/api/database/export`,`_blank`)});let r=document.getElementById(`btn-quick-export-ddl`);r&&r.addEventListener(`click`,()=>{window.open(`/api/database/schema-only`,`_blank`)});let i=document.getElementById(`btn-quick-import-backup`);i&&i.addEventListener(`click`,()=>{jr(`database`)});let a=document.getElementById(`btn-quick-export-dict`);a&&a.addEventListener(`click`,()=>{window.open(`/api/database/dictionary`,`_blank`)});let o=document.getElementById(`btn-quick-open-console`);o&&o.addEventListener(`click`,()=>{typeof window.handleSwitchTab==`function`&&window.handleSwitchTab(`console-btn`)});let s=document.getElementById(`btn-quick-open-erd`);s&&s.addEventListener(`click`,()=>{typeof window.handleSwitchTab==`function`&&window.handleSwitchTab(`erd-btn`)});let c=document.getElementById(`runtime-toggle-header`),l=document.getElementById(`runtime-details-body`),u=document.getElementById(`runtime-expand-arrow`);c&&l&&c.addEventListener(`click`,()=>{l.classList.contains(`hidden`)?(l.classList.remove(`hidden`),u&&(u.style.transform=`rotate(180deg)`)):(l.classList.add(`hidden`),u&&(u.style.transform=`rotate(0deg)`))});let d=document.getElementById(`status-refresh-btn`);d&&d.addEventListener(`click`,()=>{let e=d.querySelector(`.material-symbols-outlined`);if(e){e.style.transition=`transform 0.4s ease`;let t=parseInt(e.dataset.rot||`0`,10)+360;e.style.transform=`rotate(${t}deg)`,e.dataset.rot=`${t}`}Vr()});let f=!0,p=document.getElementById(`status-live-toggle`);p&&p.addEventListener(`click`,()=>{f=!f;let e=p.querySelector(`.live-dot-icon`),t=document.getElementById(`status-live-text`);f?(e&&(e.style.color=`var(--color-primary)`),t&&(t.textContent=`Live (3s)`)):(e&&(e.style.color=`var(--color-text-soft)`),t&&(t.textContent=`Paused`))}),window.statusPollingInterval&&clearInterval(window.statusPollingInterval),window.statusPollingInterval=setInterval(()=>{window.AppState.currentTab===`status-btn`&&f&&Vr()},3e3)}async function Vr(){let e=performance.now();try{let[t,n]=await Promise.all([fetch(`/api/status`),fetch(`/api/tables/stats`)]),r=await t.json(),i=await n.json(),a=Math.round(performance.now()-e);r.success?Hr(r.data,i.data,a):Ur(r.error||`Failed to load status`)}catch(e){Ur(e instanceof Error?e.message:String(e))}}function Hr(e,t={},n=null){let r=document.getElementById(`hero-db-name`),i=document.getElementById(`hero-conn-uri`);if(!r)return;let a=``;a=e.dbType===`sqlite`?`sqlite://${e.dbName||`drixio.db`}`:e.dbType===`postgres`?`postgresql://localhost:5432/${e.dbName||`postgres`}`:e.dbType===`mysql`?`mysql://localhost:3306/${e.dbName||`mysql`}`:e.dbType===`mssql`?`mssql://localhost:1433/${e.dbName||`master`}`:e.dbType===`mongodb`?`mongodb://localhost:27017/${e.dbName||`test`}`:`${e.dbType||`database`}://${e.dbName||``}`,r.textContent=e.dbName||`Database`,i&&(i.textContent=a);let o=document.getElementById(`node-db-title`),s=document.getElementById(`node-db-desc`),c=document.getElementById(`node-db-path`),l=document.getElementById(`node-engine-avatar`),u=document.getElementById(`node-engine-icon`),d=document.getElementById(`node-latency-text`),f=document.getElementById(`node-stat-cpu`),p=document.getElementById(`node-stat-ram`),m=document.getElementById(`node-stat-disk`),h=document.getElementById(`node-stat-conns`);o&&(o.textContent=e.dbName||`Primary Database`),s&&(s.textContent=`${(e.dbType||`SQL`).toUpperCase()} Serverless Engine`),c&&(c.textContent=a),l&&u&&(e.dbType===`sqlite`?(u.textContent=`database`,l.style.background=`rgba(37, 99, 235, 0.12)`,l.style.color=`var(--color-primary)`):e.dbType===`postgres`?(u.textContent=`dns`,l.style.background=`rgba(99, 102, 241, 0.15)`,l.style.color=`#818cf8`):e.dbType===`mssql`?(u.textContent=`dns`,l.style.background=`rgba(239, 68, 68, 0.15)`,l.style.color=`#f87171`):e.dbType===`mongodb`?(u.textContent=`dataset`,l.style.background=`rgba(16, 185, 129, 0.15)`,l.style.color=`#34d399`):(u.textContent=`storage`,l.style.background=`rgba(245, 158, 11, 0.15)`,l.style.color=`#f59e0b`)),d&&(d.textContent=n===null?`< 1ms`:`${n}ms`),f&&(f.textContent=`CPU ${e.osCpuUsage===void 0?`< 1%`:e.osCpuUsage.toFixed(1)+`%`}`),m&&(m.textContent=`Disk ${tn(e.sizeBytes)}`),p&&(e.osMemUsed&&e.osMemTotal?p.textContent=`RAM ${Math.round(e.osMemUsed/e.osMemTotal*100)}%`:p.textContent=`RAM N/A`),h&&(h.textContent=`${e.activeConnections||1} conn`);let g=document.getElementById(`header-last-updated`);if(g){let e=new Date,t=`${e.getHours().toString().padStart(2,`0`)}:${e.getMinutes().toString().padStart(2,`0`)}:${e.getSeconds().toString().padStart(2,`0`)}`;g.textContent=n===null?t:`${t} (${n}ms)`}let _=Tr(t),v=document.getElementById(`ribbon-records-count`);v&&(v.textContent=`${(_||0).toLocaleString()} Total Records`),wr(e,_);let y=document.getElementById(`rt-engine`),b=document.getElementById(`rt-version`),x=document.getElementById(`rt-dbname`),S=document.getElementById(`rt-uptime`),C=document.getElementById(`rt-conns`),w=document.getElementById(`rt-tables`),T=document.getElementById(`rt-storage`),E=document.getElementById(`rt-memory`),D=document.getElementById(`runtime-chip-engine`);y&&(y.textContent=(e.dbType||`UNKNOWN`).toUpperCase()),b&&(b.textContent=e.version?`v${e.version}`:`N/A`),x&&(x.textContent=e.dbName||`N/A`),S&&(S.textContent=nn(e.uptime));let O=e.activeConnections||(e.dbType,1);C&&(C.textContent=`${O} active connection(s)`),w&&(w.textContent=`${e.totalTables??0} tables`),T&&(T.textContent=tn(e.sizeBytes)),E&&(e.osMemUsed&&e.osMemTotal?E.textContent=`${tn(e.osMemUsed)} / ${tn(e.osMemTotal)}`:E.textContent=`Managed by host system`),D&&(D.textContent=`${(e.dbType||`SQL`).toUpperCase()} ${e.version?`v${e.version}`:``}`);let k=document.getElementById(`feature-prompts-container`);k&&(e.dbType===`sqlite`?(k.classList.add(`hidden`),k.classList.remove(`flex`),k.innerHTML=``):(k.innerHTML=`
2710
3405
  <div class="feature-prompt stagger-in">
2711
3406
  <span class="material-symbols-outlined icon">info</span>
2712
3407
  <div class="feature-prompt-content">
@@ -2717,8 +3412,8 @@ $1`)}),t=t.replace(/[ \t]+(AND\b|OR\b)/g,`
2717
3412
  <span class="material-symbols-outlined">close</span>
2718
3413
  </button>
2719
3414
  </div>
2720
- `,k.classList.remove(`hidden`),k.classList.add(`flex`)));let A=document.getElementById(`ribbon-health-label`);A&&(A.textContent=e.status===`connected`?`100.0% Connection Health`:`Offline / Disconnected`),window.gsap&&!window._statusAnimatedIn&&(window._statusAnimatedIn=!0,gsap.killTweensOf(`.skeleton-target`),gsap.set(`.skeleton-target`,{clearProps:`opacity`}),gsap.fromTo(`.drixio-hero-header`,{opacity:0,x:-20},{opacity:1,x:0,duration:.5,ease:`power2.out`}),gsap.fromTo(`.status-dashboard-status-tile`,{opacity:0,y:15},{opacity:1,y:0,duration:.4,stagger:.05,ease:`back.out(1.2)`}),gsap.to(`#primary-db-node`,{opacity:1,duration:.5,ease:`power2.inOut`}),gsap.fromTo(`.drixio-action-card`,{opacity:0,y:10},{opacity:1,y:0,duration:.4,stagger:.05,ease:`power2.out`,delay:.2}))}function Pn(e){if(document.getElementById(`status-cards-container`)){window.gsap&&gsap.killTweensOf(`.skeleton-target`);let t=document.querySelector(`.status-dashboard`);t&&(t.innerHTML=`
2721
- <div class="drixio-empty-analytics" style="margin-top: 60px;">
3415
+ `,k.classList.remove(`hidden`),k.classList.add(`flex`)));let A=document.getElementById(`ribbon-health-label`);A&&(A.textContent=e.status===`connected`?`100.0% Connection Health`:`Offline / Disconnected`),window.gsap&&!window._statusAnimatedIn&&(window._statusAnimatedIn=!0,gsap.killTweensOf(`.skeleton-target`),gsap.set(`.skeleton-target`,{clearProps:`opacity`}),gsap.fromTo(`.drixio-hero-header`,{opacity:0,x:-20},{opacity:1,x:0,duration:.5,ease:`power2.out`}),gsap.fromTo(`.status-dashboard-status-tile`,{opacity:0,y:15},{opacity:1,y:0,duration:.4,stagger:.05,ease:`back.out(1.2)`}),gsap.to(`#primary-db-node`,{opacity:1,duration:.5,ease:`power2.inOut`}),gsap.fromTo(`.drixio-action-card`,{opacity:0,y:10},{opacity:1,y:0,duration:.4,stagger:.05,ease:`power2.out`,delay:.2}))}function Ur(e){if(document.getElementById(`status-cards-container`)){window.gsap&&gsap.killTweensOf(`.skeleton-target`);let t=document.querySelector(`.status-dashboard`);t&&(t.innerHTML=`
3416
+ <div class="drixio-empty-analytics" style="margin: auto; text-align: center; padding: 40px;">
2722
3417
  <div class="drixio-empty-icon" style="background: rgba(239, 68, 68, 0.1); color: var(--color-error); width: 56px; height: 56px; border-radius: 50%;">
2723
3418
  <span class="material-symbols-outlined" style="font-size: 28px;">error</span>
2724
3419
  </div>
@@ -2734,7 +3429,7 @@ $1`)}),t=t.replace(/[ \t]+(AND\b|OR\b)/g,`
2734
3429
  </button>
2735
3430
  </div>
2736
3431
  </div>
2737
- `)}}var Fn=`drixio_saved_connections`;function In(){try{let e=localStorage.getItem(Fn);if(!e)return[];let t=JSON.parse(e);return Array.isArray(t)?t:[]}catch{return[]}}function Ln(e){if(!e||!e.url)return In();let t=In(),n=e.url.trim(),r=e.name;r||=e.dialect===`sqlite`?n.replace(/^file:/,``).split(/[/\\]/).pop()||`sqlite.db`:n.split(`/`).pop()?.split(`?`)[0]||`database`;let i=t.findIndex(e=>e.url.trim().toLowerCase()===n.toLowerCase()),a={id:i>=0?t[i].id:`conn_${Date.now()}_${Math.random().toString(36).slice(2,6)}`,name:r,dialect:e.dialect||`sqlite`,url:n,isRemote:!!e.isRemote,badgeLabel:e.badgeLabel||(e.isRemote?`REMOTE`:`LOCAL`),lastConnected:Date.now()};return i>=0?t[i]={...t[i],...a}:t.unshift(a),localStorage.setItem(Fn,JSON.stringify(t)),t}function Rn(e){let t=In().filter(t=>t.id!==e);return localStorage.setItem(Fn,JSON.stringify(t)),t}async function zn(e){if(!e||!e.url)return!1;typeof window.showToast==`function`&&window.showToast(`Connecting to ${e.name}...`,`info`);try{let t=await(await fetch(`/api/connect`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({url:e.url,saveToEnv:!1})})).json();if(!t.success)throw Error(t.error||`Failed to connect`);Ln({...e,lastConnected:Date.now()}),window.AppState&&(window.AppState.dbType=t.data.dbType,window.AppState.isRemote=e.isRemote,window.AppState.badgeLabel=e.badgeLabel,window.AppState.currentTable=null,window.AppState.currentTableBtnElement=null);let n=document.getElementById(`db-name`);n&&(n.textContent=t.data.dbName||e.name);let r=document.getElementById(`env-badge`);return r&&(r.textContent=e.badgeLabel,r.className=`env-badge ${e.isRemote?`remote`:`local`}`,r.classList.remove(`hidden`)),typeof window.initSidebar==`function`&&await window.initSidebar(!0),typeof window.setStudioConnectionMode==`function`&&window.setStudioConnectionMode(!0),window.AppState?.currentTab===`connect-btn`&&typeof window.handleSwitchTab==`function`?window.handleSwitchTab(`data-btn`):typeof window.renderCurrentView==`function`&&window.renderCurrentView(``,!0),typeof window.showToast==`function`&&window.showToast(`Switched to database: ${e.name}`,`success`),!0}catch(e){return typeof window.showToast==`function`&&window.showToast(`Connection error: ${e.message}`,`error`),!1}}function Bn(e){let t=`sqlite`,n={sqlite:`create`,postgres:`existing`,mysql:`existing`},r={postgres:`uri`,mysql:`uri`},i={postgres:{uri:`postgresql://postgres:postgres@localhost:5432/postgres`,host:`localhost`,port:`5432`,user:`postgres`,password:``,dbname:`postgres`},mysql:{uri:`mysql://root:password@localhost:3306/mysql`,host:`localhost`,port:`3306`,user:`root`,password:``,dbname:`mysql`}},a={createName:`drixio.sqlite`,existingPath:`./drixio.sqlite`},o=!0,s={state:`idle`,message:`Click "Test Connection" to verify connectivity before proceeding.`,latencyMs:null,error:``},c={sqlite:{name:`SQLite`,badge:`Local File`,icon:`description`,desc:`Zero-config embedded file database.`},postgres:{name:`PostgreSQL`,badge:`Server Instance`,icon:`database`,desc:`Enterprise relational database server.`},mysql:{name:`MySQL`,badge:`Server Instance`,icon:`storage`,desc:`High-performance relational database.`}},l={sqlite:{create:{title:`About Create New (SQLite)`,desc:`Initializes a fresh, zero-configuration SQLite database file directly in your project root. No server setup or credentials required.`,action:`Will initialize a new SQLite database file and prepare schema.`},existing:{title:`About Connect Existing (SQLite)`,desc:`Connects to an existing SQLite database file (.sqlite, .db, .sqlite3) in your workspace to inspect schemas and browse data.`,action:`Will verify existing file on disk and inspect tables.`}},postgres:{create:{title:`About Create New (PostgreSQL)`,desc:`Connects to your PostgreSQL server instance using administrative credentials and executes "CREATE DATABASE" to set up your project database.`,action:`Will connect to PostgreSQL server and run CREATE DATABASE.`},existing:{title:`About Connect Existing (PostgreSQL)`,desc:`Connects to an existing PostgreSQL database instance via connection URI or host parameters. Introspects schemas, tables, and relations.`,action:`Will establish client connection and map schema tables.`}},mysql:{create:{title:`About Create New (MySQL)`,desc:`Connects to your MySQL / MariaDB server instance using administrative credentials and executes "CREATE DATABASE" to initialize your database.`,action:`Will connect to MySQL server and run CREATE DATABASE.`},existing:{title:`About Connect Existing (MySQL)`,desc:`Connects to an existing MySQL / MariaDB database service via connection URI or host parameters. Maps tables and indexes.`,action:`Will connect to MySQL database and inspect tables.`}}},u={sqlite:[{label:`drixio.sqlite`,val:`drixio.sqlite`,path:`./drixio.sqlite`},{label:`data.db`,val:`data.db`,path:`./data.db`}],postgres:[{label:`Local Default`,uri:`postgresql://postgres:postgres@localhost:5432/postgres`},{label:`Supabase Format`,uri:`postgresql://postgres.xxx:secret@aws-0-region.pooler.supabase.com:6543/postgres`}],mysql:[{label:`Local Default`,uri:`mysql://root:password@localhost:3306/mysql`},{label:`No Pass`,uri:`mysql://root:@localhost:3306/mydb`}]},d=e=>{if(!e||typeof e!=`string`)return null;let n=e.trim();n=n.replace(/^["']|["']$/g,``),n.includes(`=`)&&(n=n.split(`=`).slice(1).join(`=`).trim().replace(/^["']|["']$/g,``));try{let e=n;n.includes(`://`)||(e=`${t}://${n}`);let r=new URL(e),i=r.protocol.replace(`:`,``).toLowerCase(),a=i.startsWith(`post`)?`postgres`:i.startsWith(`my`)?`mysql`:i,o=r.hostname||`localhost`,s=a===`mysql`?`3306`:`5432`,c=r.port||s,l=a===`mysql`?`root`:`postgres`,u=decodeURIComponent(r.username||l),d=decodeURIComponent(r.password||``),f=r.pathname.replace(/^\//,``),p=a===`mysql`?`mysql`:`postgres`;return{dialect:a,host:o,port:c,user:u,password:d,dbName:decodeURIComponent(f.split(`?`)[0]||p)}}catch{return null}},f=()=>{let e=n[t];if(t===`sqlite`){if(e===`create`){let e=a.createName.trim()||`drixio.sqlite`;return!e.endsWith(`.sqlite`)&&!e.endsWith(`.db`)&&!e.endsWith(`.sqlite3`)&&(e+=`.sqlite`),`./${e}`}return a.existingPath.trim()||`./drixio.sqlite`}if(t===`postgres`||t===`mysql`){if(r[t]===`uri`){let e=i[t].uri.trim();if(e)return e}let n=i[t],a=n.host.trim()||`localhost`,o=t===`postgres`?`5432`:`3306`,s=n.port.trim()||o,c=t===`postgres`?`postgres`:`root`,l=n.user.trim()||c,u=n.password||``,d=e===`create`?`new_db`:t===`postgres`?`postgres`:`mysql`,f=n.dbname.trim()||d,p=u?`${encodeURIComponent(l)}:${encodeURIComponent(u)}@`:l?`${encodeURIComponent(l)}@`:``;return`${t}://${p}${a}:${s}/${f}`}return``},p=()=>{let e=n[t];if(t===`sqlite`)return e===`create`?a.createName.trim()||`drixio.sqlite`:(a.existingPath.trim()||`drixio.sqlite`).split(/[/\\]/).pop()||`drixio.sqlite`;if(r[t]===`uri`){let e=d(i[t].uri);if(e?.dbName)return e.dbName}let o=e===`create`?`new_db`:t===`postgres`?`postgres`:`mysql`;return i[t].dbname.trim()||o},m=()=>{if(t===`sqlite`)return`<workspace root>/${p()}`;if(r[t]===`uri`){let e=d(i[t].uri);if(e?.host)return`${e.host}:${e.port||(t===`postgres`?`5432`:`3306`)}`}let e=i[t].host.trim()||`localhost`,n=t===`postgres`?`5432`:`3306`;return`${e}:${i[t].port.trim()||n}`},h=()=>{let n=e.querySelector(`#preview-conn-url`),i=e.querySelector(`#preview-db-name`),a=e.querySelector(`#preview-location`),s=e.querySelector(`#preview-env-output`),c=f();n&&(n.textContent=c),i&&(i.textContent=p()),a&&(a.textContent=m()),s&&(o?(s.textContent=`DATABASE_URL="${c}"`,s.classList.remove(`disabled`)):(s.textContent=`(Will not write to .env)`,s.classList.add(`disabled`))),t!==`sqlite`&&r[t]===`uri`&&g()},g=()=>{let n=e.querySelector(`#uri-parsed-chips`);if(!n)return;let r=i[t].uri,a=d(r);if(!a){n.innerHTML=`
3432
+ `)}}var Wr=`drixio_saved_connections`;function Gr(){try{let e=localStorage.getItem(Wr);if(!e)return[];let t=JSON.parse(e);return Array.isArray(t)?t:[]}catch{return[]}}function Kr(e){if(!e||!e.url)return Gr();let t=Gr(),n=e.url.trim(),r=e.name;r||=e.dialect===`sqlite`?n.replace(/^file:/,``).split(/[/\\]/).pop()||`sqlite.db`:n.split(`/`).pop()?.split(`?`)[0]||`database`;let i=t.findIndex(e=>e.url.trim().toLowerCase()===n.toLowerCase()),a={id:i>=0?t[i].id:`conn_${Date.now()}_${Math.random().toString(36).slice(2,6)}`,name:r,dialect:e.dialect||`sqlite`,url:n,isRemote:!!e.isRemote,badgeLabel:e.badgeLabel||(e.isRemote?`REMOTE`:`LOCAL`),lastConnected:Date.now()};return i>=0?t[i]={...t[i],...a}:t.unshift(a),localStorage.setItem(Wr,JSON.stringify(t)),t}function qr(e){let t=Gr().filter(t=>t.id!==e);return localStorage.setItem(Wr,JSON.stringify(t)),t}async function Jr(e){if(!e||!e.url)return!1;typeof window.showToast==`function`&&window.showToast(`Connecting to ${e.name}...`,`info`);try{let t=await(await fetch(`/api/connect`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({url:e.url,saveToEnv:!1})})).json();if(!t.success)throw Error(t.error||`Failed to connect`);Kr({...e,lastConnected:Date.now()}),window.AppState&&(window.AppState.dbType=t.data.dbType,window.AppState.isRemote=e.isRemote,window.AppState.badgeLabel=e.badgeLabel,window.AppState.currentTable=null,window.AppState.currentTableBtnElement=null);let n=document.getElementById(`db-name`);n&&(n.textContent=t.data.dbName||e.name);let r=document.getElementById(`env-badge`);return r&&(r.textContent=e.badgeLabel,r.className=`env-badge ${e.isRemote?`remote`:`local`}`,r.classList.remove(`hidden`)),typeof window.initSidebar==`function`&&await window.initSidebar(!0),typeof window.setStudioConnectionMode==`function`&&window.setStudioConnectionMode(!0),window.AppState?.currentTab===`connect-btn`&&typeof window.handleSwitchTab==`function`?window.handleSwitchTab(`data-btn`):typeof window.renderCurrentView==`function`&&window.renderCurrentView(``,!0),typeof window.showToast==`function`&&window.showToast(`Switched to database: ${e.name}`,`success`),!0}catch(e){return typeof window.showToast==`function`&&window.showToast(`Connection error: ${e.message}`,`error`),!1}}function Yr(e){let t=`sqlite`,n={sqlite:`create`,postgres:`existing`,mysql:`existing`,mssql:`existing`,mongodb:`existing`},r={postgres:`uri`,mysql:`uri`,mssql:`uri`,mongodb:`uri`},i={postgres:{uri:`postgresql://postgres:postgres@localhost:5432/postgres`,host:`localhost`,port:`5432`,user:`postgres`,password:``,dbname:`postgres`},mysql:{uri:`mysql://root:password@localhost:3306/mysql`,host:`localhost`,port:`3306`,user:`root`,password:``,dbname:`mysql`},mssql:{uri:`mssql://sa:Password123!@localhost:1433/master`,host:`localhost`,port:`1433`,user:`sa`,password:``,dbname:`master`},mongodb:{uri:`mongodb://localhost:27017/test`,host:`localhost`,port:`27017`,user:``,password:``,dbname:`test`}},a={createName:`drixio.sqlite`,existingPath:`./drixio.sqlite`},o={enabled:!1,host:``,port:`22`,user:``,password:``,privateKey:``},s=!0,c={state:`idle`,message:`Click "Test Connection" to verify connectivity before proceeding.`,latencyMs:null,error:``},l={sqlite:{name:`SQLite`,badge:`Local File`,icon:`description`,desc:`Zero-config embedded file database.`},postgres:{name:`PostgreSQL`,badge:`Server Instance`,icon:`database`,desc:`Enterprise relational database server.`},mysql:{name:`MySQL`,badge:`Server Instance`,icon:`storage`,desc:`High-performance relational database.`},mssql:{name:`SQL Server`,badge:`MSSQL Instance`,icon:`dns`,desc:`Microsoft SQL Server enterprise database.`},mongodb:{name:`MongoDB`,badge:`NoSQL Document`,icon:`dataset`,desc:`Document-oriented NoSQL database.`}},u={sqlite:{create:{title:`About Create New (SQLite)`,desc:`Initializes a fresh, zero-configuration SQLite database file directly in your project root. No server setup or credentials required.`,action:`Will initialize a new SQLite database file and prepare schema.`},existing:{title:`About Connect Existing (SQLite)`,desc:`Connects to an existing SQLite database file (.sqlite, .db, .sqlite3) in your workspace to inspect schemas and browse data.`,action:`Will verify existing file on disk and inspect tables.`}},postgres:{create:{title:`About Create New (PostgreSQL)`,desc:`Connects to your PostgreSQL server instance using administrative credentials and executes "CREATE DATABASE" to set up your project database.`,action:`Will connect to PostgreSQL server and run CREATE DATABASE.`},existing:{title:`About Connect Existing (PostgreSQL)`,desc:`Connects to an existing PostgreSQL database instance via connection URI or host parameters. Introspects schemas, tables, and relations.`,action:`Will establish client connection and map schema tables.`}},mysql:{create:{title:`About Create New (MySQL)`,desc:`Connects to your MySQL / MariaDB server instance using administrative credentials and executes "CREATE DATABASE" to initialize your database.`,action:`Will connect to MySQL server and run CREATE DATABASE.`},existing:{title:`About Connect Existing (MySQL)`,desc:`Connects to an existing MySQL / MariaDB database service via connection URI or host parameters. Maps tables and indexes.`,action:`Will connect to MySQL database and inspect tables.`}},mssql:{create:{title:`About Create New (SQL Server)`,desc:`Connects to your Microsoft SQL Server instance using administrative credentials and executes "CREATE DATABASE" to initialize your database.`,action:`Will connect to SQL Server and run CREATE DATABASE.`},existing:{title:`About Connect Existing (SQL Server)`,desc:`Connects to an existing Microsoft SQL Server database via connection URI (mssql://) or host parameters. Introspects schemas and tables.`,action:`Will connect to SQL Server database and inspect tables.`}},mongodb:{create:{title:`About Create New (MongoDB)`,desc:`Connects to your MongoDB instance or cluster. MongoDB dynamically creates databases and collections when documents are inserted.`,action:`Will connect to MongoDB instance and initialize database namespace.`},existing:{title:`About Connect Existing (MongoDB)`,desc:`Connects to a MongoDB database (local, Docker, or Atlas SRV) via connection URI. Introspects collections, sampled schema, and indexes.`,action:`Will connect to MongoDB service and sample collection schemas.`}}},d={sqlite:[{label:`drixio.sqlite`,val:`drixio.sqlite`,path:`./drixio.sqlite`},{label:`data.db`,val:`data.db`,path:`./data.db`}],postgres:[{label:`Local Default`,uri:`postgresql://postgres:postgres@localhost:5432/postgres`},{label:`Supabase Format`,uri:`postgresql://postgres.xxx:secret@aws-0-region.pooler.supabase.com:6543/postgres`}],mysql:[{label:`Local Default`,uri:`mysql://root:password@localhost:3306/mysql`},{label:`No Pass`,uri:`mysql://root:@localhost:3306/mydb`}],mssql:[{label:`Local Default`,uri:`mssql://sa:Password123!@localhost:1433/master`},{label:`Azure SQL Format`,uri:`mssql://user:password@server.database.windows.net:1433/mydb?encrypt=true`}],mongodb:[{label:`Local Default`,uri:`mongodb://localhost:27017/test`},{label:`Atlas SRV Format`,uri:`mongodb+srv://user:password@cluster0.mongodb.net/test?retryWrites=true&w=majority`}]},f=e=>{if(!e||typeof e!=`string`)return null;let n=e.trim();n=n.replace(/^["']|["']$/g,``),n.includes(`=`)&&(n=n.split(`=`).slice(1).join(`=`).trim().replace(/^["']|["']$/g,``));try{let e=n;n.includes(`://`)||(e=`${t}://${n}`);let r=new URL(e),i=r.protocol.replace(`:`,``).toLowerCase(),a=i.startsWith(`post`)?`postgres`:i.startsWith(`my`)?`mysql`:i.startsWith(`ms`)||i.startsWith(`sqlserver`)?`mssql`:i.startsWith(`mongo`)?`mongodb`:i,o=r.hostname||`localhost`,s=a===`mysql`?`3306`:a===`mssql`?`1433`:a===`mongodb`?`27017`:`5432`,c=r.port||s,l=a===`mysql`?`root`:a===`mssql`?`sa`:a===`mongodb`?``:`postgres`,u=decodeURIComponent(r.username||l),d=decodeURIComponent(r.password||``),f=r.pathname.replace(/^\//,``),p=a===`mysql`?`mysql`:a===`mssql`?`master`:a===`mongodb`?`test`:`postgres`;return{dialect:a,host:o,port:c,user:u,password:d,dbName:decodeURIComponent(f.split(`?`)[0]||p)}}catch{return null}},p=()=>{let e=n[t];if(t===`sqlite`){if(e===`create`){let e=a.createName.trim()||`drixio.sqlite`;return!e.endsWith(`.sqlite`)&&!e.endsWith(`.db`)&&!e.endsWith(`.sqlite3`)&&(e+=`.sqlite`),`./${e}`}return a.existingPath.trim()||`./drixio.sqlite`}if(t===`postgres`||t===`mysql`||t===`mssql`||t===`mongodb`){if(r[t]===`uri`){let e=i[t].uri.trim();if(e)return e}let n=i[t],a=n.host.trim()||`localhost`,o=t===`postgres`?`5432`:t===`mssql`?`1433`:t===`mongodb`?`27017`:`3306`,s=n.port.trim()||o,c=t===`postgres`?`postgres`:t===`mssql`?`sa`:t===`mongodb`?``:`root`,l=n.user.trim()||c,u=n.password||``,d=e===`create`?`new_db`:t===`postgres`?`postgres`:t===`mssql`?`master`:t===`mongodb`?`test`:`mysql`,f=n.dbname.trim()||d,p=u?`${encodeURIComponent(l)}:${encodeURIComponent(u)}@`:l?`${encodeURIComponent(l)}@`:``;return`${t}://${p}${a}:${s}/${f}`}return``},m=()=>{let e=n[t];if(t===`sqlite`)return e===`create`?a.createName.trim()||`drixio.sqlite`:(a.existingPath.trim()||`drixio.sqlite`).split(/[/\\]/).pop()||`drixio.sqlite`;if(r[t]===`uri`){let e=f(i[t].uri);if(e?.dbName)return e.dbName}let o=e===`create`?`new_db`:t===`postgres`?`postgres`:t===`mssql`?`master`:t===`mongodb`?`test`:`mysql`;return i[t].dbname.trim()||o},h=()=>{if(t===`sqlite`)return`<workspace root>/${m()}`;if(r[t]===`uri`){let e=f(i[t].uri);if(e?.host){let n=t===`postgres`?`5432`:t===`mssql`?`1433`:t===`mongodb`?`27017`:`3306`;return`${e.host}:${e.port||n}`}}let e=i[t].host.trim()||`localhost`,n=t===`postgres`?`5432`:t===`mssql`?`1433`:t===`mongodb`?`27017`:`3306`,a=`${e}:${i[t].port.trim()||n}`;return t!==`sqlite`&&o.enabled&&o.host&&(a+=` (via SSH ${o.host}:${o.port||22})`),a},g=()=>{let n=e.querySelector(`#preview-conn-url`),i=e.querySelector(`#preview-db-name`),a=e.querySelector(`#preview-location`),o=e.querySelector(`#preview-env-output`),c=p();n&&(n.textContent=c),i&&(i.textContent=m()),a&&(a.textContent=h()),o&&(s?(o.textContent=`DATABASE_URL="${c}"`,o.classList.remove(`disabled`)):(o.textContent=`(Will not write to .env)`,o.classList.add(`disabled`))),t!==`sqlite`&&r[t]===`uri`&&_()},_=()=>{let n=e.querySelector(`#uri-parsed-chips`);if(!n)return;let r=i[t].uri,a=f(r);if(!a){n.innerHTML=`
2738
3433
  <span class="parsed-chip error">
2739
3434
  <span class="material-symbols-outlined chip-icon">error</span>
2740
3435
  <span>Invalid or incomplete URI</span>
@@ -2756,19 +3451,71 @@ $1`)}),t=t.replace(/[ \t]+(AND\b|OR\b)/g,`
2756
3451
  <span class="material-symbols-outlined chip-icon">check_circle</span>
2757
3452
  <span>Parsed</span>
2758
3453
  </span>
2759
- `},_=()=>{let t=e.querySelector(`#test-status-badge`),n=e.querySelector(`#test-status-msg`),r=e.querySelector(`#run-test-btn`);!t||!n||!r||(s.state===`testing`?(t.className=`test-badge testing`,t.innerHTML=`
3454
+ `},v=()=>{let t=e.querySelector(`#test-status-badge`),n=e.querySelector(`#test-status-msg`),r=e.querySelector(`#run-test-btn`);!t||!n||!r||(c.state===`testing`?(t.className=`test-badge testing`,t.innerHTML=`
2760
3455
  <span class="material-symbols-outlined animate-spin" style="font-size: 13px;">sync</span>
2761
3456
  <span>Testing Connection...</span>
2762
- `,n.textContent=`Contacting database target...`,r.disabled=!0):s.state===`success`?(t.className=`test-badge success`,t.innerHTML=`
3457
+ `,n.textContent=`Contacting database target...`,r.disabled=!0):c.state===`success`?(t.className=`test-badge success`,t.innerHTML=`
2763
3458
  <span class="status-dot green"></span>
2764
- <span>Reachable ${s.latencyMs===null?``:`(${s.latencyMs}ms)`}</span>
2765
- `,n.textContent=s.message,r.disabled=!1):s.state===`error`?(t.className=`test-badge error`,t.innerHTML=`
3459
+ <span>Reachable ${c.latencyMs===null?``:`(${c.latencyMs}ms)`}</span>
3460
+ `,n.textContent=c.message,r.disabled=!1):c.state===`error`?(t.className=`test-badge error`,t.innerHTML=`
2766
3461
  <span class="status-dot red"></span>
2767
3462
  <span>Connection Failed</span>
2768
- `,n.textContent=s.error||`Unable to establish connection.`,r.disabled=!1):(t.className=`test-badge idle`,t.innerHTML=`
3463
+ `,n.textContent=c.error||`Unable to establish connection.`,r.disabled=!1):(t.className=`test-badge idle`,t.innerHTML=`
2769
3464
  <span class="status-dot gray"></span>
2770
3465
  <span>Not Tested</span>
2771
- `,n.textContent=`Click "Test Connection" to verify connectivity before proceeding.`,r.disabled=!1))},v=async()=>{s={state:`testing`,message:``,latencyMs:null,error:``},_();let e=n[t],r=null;if(e===`create`&&(t===`postgres`||t===`mysql`)){let e=i[t];r={mode:`create`,dbType:t,host:e.host.trim()||`localhost`,port:e.port.trim()||(t===`mysql`?`3306`:`5432`),user:e.user.trim()||(t===`mysql`?`root`:`postgres`),password:e.password||``,dbName:e.dbname.trim()||`new_db`}}else if(t===`sqlite`&&e===`create`){let e=a.createName.trim()||`drixio.sqlite`;!e.endsWith(`.sqlite`)&&!e.endsWith(`.db`)&&!e.endsWith(`.sqlite3`)&&(e+=`.sqlite`),r={mode:`create`,dbType:`sqlite`,url:`./${e}`}}else{let e=``;e=t===`sqlite`?a.existingPath.trim()||`./drixio.sqlite`:f(),r={mode:`existing`,dbType:t,url:e}}try{let e=await(await fetch(`/api/test-connect`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(r)})).json();if(!e.success)throw Error(e.error||`Connection test failed`);s={state:`success`,message:e.data?.message||`Database target reachable and verified.`,latencyMs:e.data?.latencyMs??1,error:``}}catch(e){s={state:`error`,message:``,latencyMs:null,error:e.message}}_()},y=()=>{let r=n[t],i=l[t]?.[r]||{title:``,desc:``,action:``},a=u[t]||[],s=In();e.innerHTML=`
3466
+ `,n.textContent=`Click "Test Connection" to verify connectivity before proceeding.`,r.disabled=!1))},y=async()=>{c={state:`testing`,message:``,latencyMs:null,error:``},v();let e=n[t],r=null;if(e===`create`&&(t===`postgres`||t===`mysql`||t===`mssql`||t===`mongodb`)){let e=i[t];r={mode:`create`,dbType:t,host:e.host.trim()||`localhost`,port:e.port.trim()||(t===`mysql`?`3306`:t===`mssql`?`1433`:t===`mongodb`?`27017`:`5432`),user:e.user.trim()||(t===`mysql`?`root`:t===`mssql`?`sa`:t===`mongodb`?``:`postgres`),password:e.password||``,dbName:e.dbname.trim()||(t===`mongodb`?`test`:`new_db`)}}else if(t===`sqlite`&&e===`create`){let e=a.createName.trim()||`drixio.sqlite`;!e.endsWith(`.sqlite`)&&!e.endsWith(`.db`)&&!e.endsWith(`.sqlite3`)&&(e+=`.sqlite`),r={mode:`create`,dbType:`sqlite`,url:`./${e}`}}else{let e=``;e=t===`sqlite`?a.existingPath.trim()||`./drixio.sqlite`:p(),r={mode:`existing`,dbType:t,url:e}}t!==`sqlite`&&o.enabled&&o.host&&(r.sshTunnel={...o});try{let e=await(await fetch(`/api/test-connect`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(r)})).json();if(!e.success)throw Error(e.error||`Connection test failed`);c={state:`success`,message:e.data?.message||`Database target reachable and verified.`,latencyMs:e.data?.latencyMs??1,error:``}}catch(e){c={state:`error`,message:``,latencyMs:null,error:e.message}}v()},b=()=>{let e=o.enabled;return`
3467
+ <div class="connect-ssh-card ${o.enabled?`active`:``}">
3468
+ <div class="connect-ssh-toggle-header" id="ssh-toggle-header">
3469
+ <div class="connect-ssh-header-left">
3470
+ <input type="checkbox" id="ssh-tunnel-enable" ${o.enabled?`checked`:``} />
3471
+ <span class="connect-ssh-title">SSH Bastion Tunnel</span>
3472
+ <span class="connect-ssh-badge">ssh2</span>
3473
+ </div>
3474
+ <span class="material-symbols-outlined connect-ssh-toggle-icon ${e?`expanded`:``}">expand_more</span>
3475
+ </div>
3476
+ <div class="connect-ssh-body ${e?``:`hidden`}" id="ssh-tunnel-body">
3477
+ <div class="connect-grid-2">
3478
+ <div class="connect-field">
3479
+ <label class="connect-label" for="ssh-host">SSH Host / Bastion IP</label>
3480
+ <div class="connect-input-wrap">
3481
+ <input type="text" id="ssh-host" class="connect-input mono" placeholder="bastion.example.com" value="${o.host}" />
3482
+ </div>
3483
+ <p class="connect-hint">Jump host or bastion server address.</p>
3484
+ </div>
3485
+ <div class="connect-field">
3486
+ <label class="connect-label" for="ssh-port">SSH Port</label>
3487
+ <div class="connect-input-wrap">
3488
+ <input type="text" id="ssh-port" class="connect-input mono" placeholder="22" value="${o.port}" />
3489
+ </div>
3490
+ <p class="connect-hint">Default SSH port is <code>22</code>.</p>
3491
+ </div>
3492
+ </div>
3493
+
3494
+ <div class="connect-grid-2">
3495
+ <div class="connect-field">
3496
+ <label class="connect-label" for="ssh-user">SSH Username</label>
3497
+ <div class="connect-input-wrap">
3498
+ <input type="text" id="ssh-user" class="connect-input mono" placeholder="ubuntu" value="${o.user}" />
3499
+ </div>
3500
+ <p class="connect-hint">Remote user on the bastion server.</p>
3501
+ </div>
3502
+ <div class="connect-field">
3503
+ <label class="connect-label" for="ssh-password">SSH Password (Optional)</label>
3504
+ <div class="connect-input-wrap">
3505
+ <input type="password" id="ssh-password" class="connect-input mono" placeholder="Password if not using key" value="${o.password}" />
3506
+ </div>
3507
+ <p class="connect-hint">Authentication password if not using SSH key.</p>
3508
+ </div>
3509
+ </div>
3510
+
3511
+ <div class="connect-field">
3512
+ <label class="connect-label" for="ssh-key">Private Key (Optional PEM / OpenSSH)</label>
3513
+ <textarea id="ssh-key" class="connect-textarea mono" rows="3" placeholder="-----BEGIN OPENSSH PRIVATE KEY-----...">${o.privateKey}</textarea>
3514
+ <p class="connect-hint">Private key data. If provided, key-based authentication takes priority.</p>
3515
+ </div>
3516
+ </div>
3517
+ </div>
3518
+ `},x=()=>{let r=n[t],i=u[t]?.[r]||{title:``,desc:``,action:``},a=d[t]||[],o=Gr();e.innerHTML=`
2772
3519
  <div class="connect-fullpage">
2773
3520
  <!-- 2-Column Workbench: Left = Configuration, Right = Live Diagnostics, Overview & Recent Connections -->
2774
3521
  <div class="connect-workbench-layout">
@@ -2781,7 +3528,7 @@ $1`)}),t=t.replace(/[ \t]+(AND\b|OR\b)/g,`
2781
3528
  <span>Select Database Dialect</span>
2782
3529
  </div>
2783
3530
  <div class="connect-engine-grid">
2784
- ${[`sqlite`,`postgres`,`mysql`].map(e=>{let n=c[e],r=t===e;return`
3531
+ ${[`sqlite`,`postgres`,`mysql`,`mssql`,`mongodb`].map(e=>{let n=l[e],r=t===e;return`
2785
3532
  <div class="connect-engine-card ${r?`active`:``}" data-type="${e}">
2786
3533
  <div class="connect-engine-card-top">
2787
3534
  <div class="connect-engine-card-icon">
@@ -2830,7 +3577,10 @@ $1`)}),t=t.replace(/[ \t]+(AND\b|OR\b)/g,`
2830
3577
  </div>
2831
3578
 
2832
3579
  <div class="connect-form-body">
2833
- ${b(t,r)}
3580
+ ${S(t,r)}
3581
+
3582
+ <!-- SSH Bastion Tunnel (Server Engines) -->
3583
+ ${t===`sqlite`?``:b()}
2834
3584
 
2835
3585
  <!-- Quick Presets -->
2836
3586
  ${a.length>0?`
@@ -2849,7 +3599,7 @@ $1`)}),t=t.replace(/[ \t]+(AND\b|OR\b)/g,`
2849
3599
 
2850
3600
  <!-- Save to .env Checkbox -->
2851
3601
  <label class="connect-checkbox-row">
2852
- <input type="checkbox" id="connect-save-env" ${o?`checked`:``} />
3602
+ <input type="checkbox" id="connect-save-env" ${s?`checked`:``} />
2853
3603
  <div class="connect-checkbox-info">
2854
3604
  <span class="checkbox-title">Persist connection URL to <code class="env-code">.env</code> (DATABASE_URL)</span>
2855
3605
  <span class="checkbox-desc">Enables automatic connection restoration when Drixio Studio or CLI boots up.</span>
@@ -2910,17 +3660,17 @@ $1`)}),t=t.replace(/[ \t]+(AND\b|OR\b)/g,`
2910
3660
  <div class="card-box-body">
2911
3661
  <div class="overview-item">
2912
3662
  <span class="overview-label">Target URL</span>
2913
- <pre class="overview-code-box"><code id="preview-conn-url">${f()}</code></pre>
3663
+ <pre class="overview-code-box"><code id="preview-conn-url">${p()}</code></pre>
2914
3664
  </div>
2915
3665
 
2916
3666
  <div class="overview-grid-2">
2917
3667
  <div class="overview-item">
2918
3668
  <span class="overview-label">Target Database</span>
2919
- <span id="preview-db-name" class="overview-val">${p()}</span>
3669
+ <span id="preview-db-name" class="overview-val">${m()}</span>
2920
3670
  </div>
2921
3671
  <div class="overview-item">
2922
3672
  <span class="overview-label">Storage / Host</span>
2923
- <span id="preview-location" class="overview-val">${m()}</span>
3673
+ <span id="preview-location" class="overview-val">${h()}</span>
2924
3674
  </div>
2925
3675
  </div>
2926
3676
 
@@ -2931,7 +3681,7 @@ $1`)}),t=t.replace(/[ \t]+(AND\b|OR\b)/g,`
2931
3681
 
2932
3682
  <div class="overview-item">
2933
3683
  <span class="overview-label">.env Integration</span>
2934
- <code id="preview-env-output" class="overview-env-code">DATABASE_URL="${f()}"</code>
3684
+ <code id="preview-env-output" class="overview-env-code">DATABASE_URL="${p()}"</code>
2935
3685
  </div>
2936
3686
  </div>
2937
3687
  </div>
@@ -2943,12 +3693,12 @@ $1`)}),t=t.replace(/[ \t]+(AND\b|OR\b)/g,`
2943
3693
  <span class="material-symbols-outlined icon-blue">history</span>
2944
3694
  <span>Recent Connections</span>
2945
3695
  </div>
2946
- <span class="saved-conn-count-badge">${s.length} saved</span>
3696
+ <span class="saved-conn-count-badge">${o.length} saved</span>
2947
3697
  </div>
2948
3698
  <div class="card-box-body saved-conns-body">
2949
- ${s.length>0?`
3699
+ ${o.length>0?`
2950
3700
  <div class="saved-conn-list">
2951
- ${s.map(e=>{let t=e.dialect===`postgres`?`database`:e.dialect===`mysql`?`storage`:`description`;return`
3701
+ ${o.map(e=>{let t=e.dialect===`postgres`?`database`:e.dialect===`mysql`?`storage`:e.dialect===`mssql`?`dns`:e.dialect===`mongodb`?`dataset`:`description`;return`
2952
3702
  <div class="saved-conn-item" data-id="${e.id}">
2953
3703
  <div class="saved-conn-main">
2954
3704
  <div class="saved-conn-icon">
@@ -2989,7 +3739,7 @@ $1`)}),t=t.replace(/[ \t]+(AND\b|OR\b)/g,`
2989
3739
  </section>
2990
3740
  </div>
2991
3741
  </div>
2992
- `,S()},b=(e,t)=>{if(e===`sqlite`)return t===`create`?`
3742
+ `,w()},S=(e,t)=>{if(e===`sqlite`)return t===`create`?`
2993
3743
  <div class="connect-field">
2994
3744
  <label class="connect-label" for="connect-sqlite-name">Database File Name</label>
2995
3745
  <div class="connect-input-wrap">
@@ -3005,23 +3755,23 @@ $1`)}),t=t.replace(/[ \t]+(AND\b|OR\b)/g,`
3005
3755
  </div>
3006
3756
  <p class="connect-hint">Relative or absolute path (e.g. <code>./drixio.sqlite</code>, <code>./data.db</code>, or <code>file:./test.db</code>).</p>
3007
3757
  </div>
3008
- `;let n=e===`postgres`,o=r[e],s=i[e],c=n?`5432`:`3306`,l=n?`postgres`:`root`,u=t===`create`,d=u?`my_project`:n?`postgres`:`mysql`;return`
3758
+ `;let n=e===`postgres`,o=e===`mssql`,s=e===`mongodb`,c=r[e],l=i[e],u=n?`5432`:o?`1433`:s?`27017`:`3306`,d=n?`postgres`:o?`sa`:s?``:`root`,f=t===`create`,p=f?`my_project`:n?`postgres`:o?`master`:s?`test`:`mysql`;return`
3009
3759
  <!-- Segmented Input Method Selector -->
3010
3760
  <div class="connect-input-method-row">
3011
3761
  <div class="connect-method-segmented">
3012
- <button type="button" class="connect-method-btn ${o===`uri`?`active`:``}" data-method="uri">
3762
+ <button type="button" class="connect-method-btn ${c===`uri`?`active`:``}" data-method="uri">
3013
3763
  <span class="material-symbols-outlined">link</span>
3014
3764
  <span>Connection URI</span>
3015
3765
  </button>
3016
- <button type="button" class="connect-method-btn ${o===`fields`?`active`:``}" data-method="fields">
3766
+ <button type="button" class="connect-method-btn ${c===`fields`?`active`:``}" data-method="fields">
3017
3767
  <span class="material-symbols-outlined">tune</span>
3018
3768
  <span>Host & Parameters</span>
3019
3769
  </button>
3020
3770
  </div>
3021
- <span class="connect-method-hint">${o===`uri`?`Paste URI from Supabase, Neon, or Docker`:`Configure host, port, user and credentials manually`}</span>
3771
+ <span class="connect-method-hint">${c===`uri`?`Paste URI from Supabase, Neon, or Docker`:`Configure host, port, user and credentials manually`}</span>
3022
3772
  </div>
3023
3773
 
3024
- ${o===`uri`?`
3774
+ ${c===`uri`?`
3025
3775
  <!-- Option A: Clean, Single Connection URI Box -->
3026
3776
  <div class="connect-uri-card">
3027
3777
  <div class="connect-field">
@@ -3033,7 +3783,7 @@ $1`)}),t=t.replace(/[ \t]+(AND\b|OR\b)/g,`
3033
3783
  </button>
3034
3784
  </div>
3035
3785
  <div class="connect-input-wrap has-action">
3036
- <input type="text" id="connect-server-uri" class="connect-input mono" placeholder="${n?`postgresql://postgres:password@localhost:5432/mydb`:`mysql://root:password@localhost:3306/mydb`}" value="${s.uri}" />
3786
+ <input type="text" id="connect-server-uri" class="connect-input mono" placeholder="${n?`postgresql://postgres:password@localhost:5432/mydb`:o?`mssql://sa:password@localhost:1433/mydb`:s?`mongodb://localhost:27017/mydb`:`mysql://root:password@localhost:3306/mydb`}" value="${l.uri}" />
3037
3787
  <button type="button" class="connect-input-clear-btn" id="btn-clear-uri" title="Clear input">
3038
3788
  <span class="material-symbols-outlined">close</span>
3039
3789
  </button>
@@ -3054,16 +3804,16 @@ $1`)}),t=t.replace(/[ \t]+(AND\b|OR\b)/g,`
3054
3804
  <div class="connect-field">
3055
3805
  <label class="connect-label" for="connect-server-host">Server Host</label>
3056
3806
  <div class="connect-input-wrap">
3057
- <input type="text" id="connect-server-host" class="connect-input mono" placeholder="localhost" value="${s.host}" />
3807
+ <input type="text" id="connect-server-host" class="connect-input mono" placeholder="localhost" value="${l.host}" />
3058
3808
  </div>
3059
3809
  <p class="connect-hint">Hostname or IP address (e.g. <code>localhost</code>, <code>127.0.0.1</code>).</p>
3060
3810
  </div>
3061
3811
  <div class="connect-field">
3062
3812
  <label class="connect-label" for="connect-server-port">Port</label>
3063
3813
  <div class="connect-input-wrap">
3064
- <input type="text" id="connect-server-port" class="connect-input mono" placeholder="${c}" value="${s.port}" />
3814
+ <input type="text" id="connect-server-port" class="connect-input mono" placeholder="${u}" value="${l.port}" />
3065
3815
  </div>
3066
- <p class="connect-hint">Default is <code>${c}</code>.</p>
3816
+ <p class="connect-hint">Default is <code>${u}</code>.</p>
3067
3817
  </div>
3068
3818
  </div>
3069
3819
 
@@ -3072,14 +3822,14 @@ $1`)}),t=t.replace(/[ \t]+(AND\b|OR\b)/g,`
3072
3822
  <div class="connect-field">
3073
3823
  <label class="connect-label" for="connect-server-user">Username</label>
3074
3824
  <div class="connect-input-wrap">
3075
- <input type="text" id="connect-server-user" class="connect-input mono" placeholder="${l}" value="${s.user}" />
3825
+ <input type="text" id="connect-server-user" class="connect-input mono" placeholder="${d}" value="${l.user}" />
3076
3826
  </div>
3077
3827
  <p class="connect-hint">Database user account name.</p>
3078
3828
  </div>
3079
3829
  <div class="connect-field">
3080
3830
  <label class="connect-label" for="connect-server-pass">Password</label>
3081
3831
  <div class="connect-input-wrap has-action">
3082
- <input type="password" id="connect-server-pass" class="connect-input mono" placeholder="Leave empty if none" value="${s.password}" />
3832
+ <input type="password" id="connect-server-pass" class="connect-input mono" placeholder="Leave empty if none" value="${l.password}" />
3083
3833
  <button type="button" class="connect-input-eye-btn" id="toggle-pass-visibility" title="Toggle password visibility">
3084
3834
  <span class="material-symbols-outlined">visibility</span>
3085
3835
  </button>
@@ -3090,20 +3840,20 @@ $1`)}),t=t.replace(/[ \t]+(AND\b|OR\b)/g,`
3090
3840
 
3091
3841
  <!-- Database Name -->
3092
3842
  <div class="connect-field">
3093
- <label class="connect-label" for="connect-server-dbname">${u?`New Database Name to Create`:`Target Database Name`}</label>
3843
+ <label class="connect-label" for="connect-server-dbname">${f?`New Database Name to Create`:`Target Database Name`}</label>
3094
3844
  <div class="connect-input-wrap">
3095
- <input type="text" id="connect-server-dbname" class="connect-input mono" placeholder="e.g. ${d}" value="${s.dbname}" />
3845
+ <input type="text" id="connect-server-dbname" class="connect-input mono" placeholder="e.g. ${p}" value="${l.dbname}" />
3096
3846
  </div>
3097
- <p class="connect-hint">${u?`Connects to server instance to execute <code>CREATE DATABASE</code>.`:`Target database to inspect and manage.`}</p>
3847
+ <p class="connect-hint">${f?`Connects to server instance to execute <code>CREATE DATABASE</code>.`:`Target database to inspect and manage.`}</p>
3098
3848
  </div>
3099
3849
  </div>
3100
3850
  `}
3101
- `},x=()=>{s.state!==`idle`&&(s={state:`idle`,message:`Click "Test Connection" to verify connectivity before proceeding.`,latencyMs:null,error:``},_())},S=()=>{e.querySelectorAll(`.connect-engine-card`).forEach(e=>{e.onclick=()=>{let n=e.dataset.type;n!==t&&(t=n,x(),y())}}),e.querySelectorAll(`.connect-mode-btn`).forEach(e=>{e.onclick=()=>{let r=e.dataset.mode;n[t]!==r&&(n[t]=r,x(),y())}}),e.querySelectorAll(`.connect-method-btn`).forEach(e=>{e.onclick=()=>{let n=e.dataset.method;r[t]!==n&&(r[t]=n,x(),y())}});let s=e.querySelector(`#connect-sqlite-name`);s&&(s.oninput=()=>{a.createName=s.value,x(),h()});let c=e.querySelector(`#connect-sqlite-path`);c&&(c.oninput=()=>{a.existingPath=c.value,x(),h()});let l=e.querySelector(`#connect-server-uri`);if(l){l.oninput=()=>{let e=l.value;i[t].uri=e;let n=d(e);n&&(i[t].host=n.host,i[t].port=n.port,i[t].user=n.user,i[t].password=n.password,i[t].dbname=n.dbName),x(),h()};let n=e.querySelector(`#btn-paste-uri`);n&&(n.onclick=async()=>{try{if(navigator.clipboard?.readText){let e=await navigator.clipboard.readText();e&&(l.value=e.trim(),l.dispatchEvent(new Event(`input`)),window.showToast&&window.showToast(`Pasted from clipboard!`,`info`))}else l.focus()}catch{l.focus()}});let r=e.querySelector(`#btn-clear-uri`);r&&(r.onclick=()=>{l.value=``,l.dispatchEvent(new Event(`input`)),l.focus()})}let u=e.querySelector(`#connect-server-host`),m=e.querySelector(`#connect-server-port`),g=e.querySelector(`#connect-server-user`),b=e.querySelector(`#connect-server-pass`),S=e.querySelector(`#connect-server-dbname`),C=()=>{u&&(i[t].host=u.value),m&&(i[t].port=m.value),g&&(i[t].user=g.value),b&&(i[t].password=b.value),S&&(i[t].dbname=S.value);let e=i[t],n=e.password?`${encodeURIComponent(e.user)}:${encodeURIComponent(e.password)}@`:e.user?`${encodeURIComponent(e.user)}@`:``;i[t].uri=`${t}://${n}${e.host}:${e.port}/${e.dbname}`,x(),h()};[u,m,g,b,S].forEach(e=>{e&&(e.oninput=C)});let w=e.querySelector(`#toggle-pass-visibility`);w&&b&&(w.onclick=()=>{let e=b.type===`password`;b.type=e?`text`:`password`;let t=w.querySelector(`.material-symbols-outlined`);t&&(t.textContent=e?`visibility_off`:`visibility`)}),e.querySelectorAll(`.connect-preset-chip`).forEach(e=>{e.onclick=()=>{let r=e.dataset.fill,o=n[t];if(t===`sqlite`)o===`create`?(a.createName=r.replace(`./`,``),s&&(s.value=a.createName)):(a.existingPath=r,c&&(c.value=a.existingPath));else{i[t].uri=r;let e=d(r);e&&(i[t].host=e.host,i[t].port=e.port,i[t].user=e.user,i[t].password=e.password,i[t].dbname=e.dbName),l&&(l.value=r),u&&e&&(u.value=e.host),m&&e&&(m.value=e.port),g&&e&&(g.value=e.user),b&&e&&(b.value=e.password),S&&e&&(S.value=e.dbName)}x(),h(),window.showToast&&window.showToast(`Preset loaded!`,`info`)}});let T=e.querySelector(`#connect-save-env`);T&&(T.onchange=()=>{o=T.checked,h()});let E=e.querySelector(`#run-test-btn`);E&&(E.onclick=()=>{v()});let D=e.querySelector(`#copy-preview-btn`);D&&(D.onclick=()=>{let e=f();navigator.clipboard&&(navigator.clipboard.writeText(e),window.showToast&&window.showToast(`Copied connection URL to clipboard!`,`info`))}),e.querySelectorAll(`.btn-use-conn`).forEach(e=>{e.onclick=r=>{r.stopPropagation();let o=e.dataset.id,s=In().find(e=>e.id===o);if(s){if(t=s.dialect||`sqlite`,n[t]=`existing`,t===`sqlite`)a.existingPath=s.url;else{i[t].uri=s.url;let e=d(s.url);e&&(i[t].host=e.host,i[t].port=e.port,i[t].user=e.user,i[t].password=e.password,i[t].dbname=e.dbName)}x(),y(),window.showToast&&window.showToast(`Loaded parameters for "${s.name}"`,`info`)}}}),e.querySelectorAll(`.btn-direct-connect`).forEach(e=>{e.onclick=async t=>{t.stopPropagation();let n=e.dataset.id,r=In().find(e=>e.id===n);r&&(e.disabled=!0,await zn(r),e.disabled=!1)}}),e.querySelectorAll(`.btn-del-conn`).forEach(e=>{e.onclick=t=>{t.stopPropagation();let n=e.dataset.id;Rn(n),y(),window.showToast&&window.showToast(`Removed from saved connections.`,`info`)}});let O=e.querySelector(`#connect-submit-btn`),k=e.querySelector(`#connect-error-msg`);O&&(O.onclick=async()=>{let e=n[t],r=null;if(e===`create`&&(t===`postgres`||t===`mysql`)){let e=i[t],n=e.dbname.trim();if(!n){k&&(k.textContent=`Please enter a new database name to create.`,k.classList.remove(`hidden`));return}r={mode:`create`,dbType:t,host:e.host.trim()||`localhost`,port:e.port.trim()||(t===`mysql`?`3306`:`5432`),user:e.user.trim()||(t===`mysql`?`root`:`postgres`),password:e.password||``,dbName:n,saveToEnv:o}}else if(t===`sqlite`&&e===`create`){let e=a.createName.trim()||`drixio.sqlite`;!e.endsWith(`.sqlite`)&&!e.endsWith(`.db`)&&!e.endsWith(`.sqlite3`)&&(e+=`.sqlite`),r={url:`./${e}`,createIfNotExist:!0,saveToEnv:o}}else{let e=``;if(e=t===`sqlite`?a.existingPath.trim()||``:f(),!e){k&&(k.textContent=`Please enter valid connection parameters.`,k.classList.remove(`hidden`));return}r={url:e,createIfNotExist:!1,saveToEnv:o}}let s=O.innerHTML;O.disabled=!0,O.innerHTML=`
3851
+ `},C=()=>{c.state!==`idle`&&(c={state:`idle`,message:`Click "Test Connection" to verify connectivity before proceeding.`,latencyMs:null,error:``},v())},w=()=>{e.querySelectorAll(`.connect-engine-card`).forEach(e=>{e.onclick=()=>{let n=e.dataset.type;n!==t&&(t=n,C(),x())}}),e.querySelectorAll(`.connect-mode-btn`).forEach(e=>{e.onclick=()=>{let r=e.dataset.mode;n[t]!==r&&(n[t]=r,C(),x())}}),e.querySelectorAll(`.connect-method-btn`).forEach(e=>{e.onclick=()=>{let n=e.dataset.method;r[t]!==n&&(r[t]=n,C(),x())}});let c=e.querySelector(`#connect-sqlite-name`);c&&(c.oninput=()=>{a.createName=c.value,C(),g()});let l=e.querySelector(`#connect-sqlite-path`);l&&(l.oninput=()=>{a.existingPath=l.value,C(),g()});let u=e.querySelector(`#connect-server-uri`);if(u){u.oninput=()=>{let e=u.value;i[t].uri=e;let n=f(e);n&&(i[t].host=n.host,i[t].port=n.port,i[t].user=n.user,i[t].password=n.password,i[t].dbname=n.dbName),C(),g()};let n=e.querySelector(`#btn-paste-uri`);n&&(n.onclick=async()=>{try{if(navigator.clipboard?.readText){let e=await navigator.clipboard.readText();e&&(u.value=e.trim(),u.dispatchEvent(new Event(`input`)),window.showToast&&window.showToast(`Pasted from clipboard!`,`info`))}else u.focus()}catch{u.focus()}});let r=e.querySelector(`#btn-clear-uri`);r&&(r.onclick=()=>{u.value=``,u.dispatchEvent(new Event(`input`)),u.focus()})}let d=e.querySelector(`#connect-server-host`),h=e.querySelector(`#connect-server-port`),_=e.querySelector(`#connect-server-user`),b=e.querySelector(`#connect-server-pass`),S=e.querySelector(`#connect-server-dbname`),w=()=>{d&&(i[t].host=d.value),h&&(i[t].port=h.value),_&&(i[t].user=_.value),b&&(i[t].password=b.value),S&&(i[t].dbname=S.value);let e=i[t],n=e.password?`${encodeURIComponent(e.user)}:${encodeURIComponent(e.password)}@`:e.user?`${encodeURIComponent(e.user)}@`:``;i[t].uri=`${t}://${n}${e.host}:${e.port}/${e.dbname}`,C(),g()};[d,h,_,b,S].forEach(e=>{e&&(e.oninput=w)});let T=e.querySelector(`#toggle-pass-visibility`);T&&b&&(T.onclick=()=>{let e=b.type===`password`;b.type=e?`text`:`password`;let t=T.querySelector(`.material-symbols-outlined`);t&&(t.textContent=e?`visibility_off`:`visibility`)});let E=e.querySelector(`#ssh-tunnel-enable`),D=e.querySelector(`#ssh-toggle-header`),O=e.querySelector(`#ssh-tunnel-body`),k=e.querySelector(`.connect-ssh-toggle-icon`);E&&(E.onchange=()=>{o.enabled=E.checked,O&&O.classList.toggle(`hidden`,!o.enabled),k&&k.classList.toggle(`expanded`,o.enabled);let t=e.querySelector(`.connect-ssh-card`);t&&t.classList.toggle(`active`,o.enabled),C(),g()}),D&&(D.onclick=e=>{e.target===E||e.target.closest(`#ssh-tunnel-enable`)||E&&(E.checked=!E.checked,E.dispatchEvent(new Event(`change`)))});let A=e.querySelector(`#ssh-host`);A&&(A.oninput=()=>{o.host=A.value.trim(),C(),g()});let j=e.querySelector(`#ssh-port`);j&&(j.oninput=()=>{o.port=j.value.trim(),C(),g()});let M=e.querySelector(`#ssh-user`);M&&(M.oninput=()=>{o.user=M.value.trim(),C()});let N=e.querySelector(`#ssh-password`);N&&(N.oninput=()=>{o.password=N.value,C()});let ee=e.querySelector(`#ssh-key`);ee&&(ee.oninput=()=>{o.privateKey=ee.value,C()}),e.querySelectorAll(`.connect-preset-chip`).forEach(e=>{e.onclick=()=>{let r=e.dataset.fill,o=n[t];if(t===`sqlite`)o===`create`?(a.createName=r.replace(`./`,``),c&&(c.value=a.createName)):(a.existingPath=r,l&&(l.value=a.existingPath));else{i[t].uri=r;let e=f(r);e&&(i[t].host=e.host,i[t].port=e.port,i[t].user=e.user,i[t].password=e.password,i[t].dbname=e.dbName),u&&(u.value=r),d&&e&&(d.value=e.host),h&&e&&(h.value=e.port),_&&e&&(_.value=e.user),b&&e&&(b.value=e.password),S&&e&&(S.value=e.dbName)}C(),g(),window.showToast&&window.showToast(`Preset loaded!`,`info`)}});let te=e.querySelector(`#connect-save-env`);te&&(te.onchange=()=>{s=te.checked,g()});let P=e.querySelector(`#run-test-btn`);P&&(P.onclick=()=>{y()});let F=e.querySelector(`#copy-preview-btn`);F&&(F.onclick=()=>{let e=p();navigator.clipboard&&(navigator.clipboard.writeText(e),window.showToast&&window.showToast(`Copied connection URL to clipboard!`,`info`))}),e.querySelectorAll(`.btn-use-conn`).forEach(e=>{e.onclick=r=>{r.stopPropagation();let o=e.dataset.id,s=Gr().find(e=>e.id===o);if(s){if(t=s.dialect||`sqlite`,n[t]=`existing`,t===`sqlite`)a.existingPath=s.url;else{i[t].uri=s.url;let e=f(s.url);e&&(i[t].host=e.host,i[t].port=e.port,i[t].user=e.user,i[t].password=e.password,i[t].dbname=e.dbName)}C(),x(),window.showToast&&window.showToast(`Loaded parameters for "${s.name}"`,`info`)}}}),e.querySelectorAll(`.btn-direct-connect`).forEach(e=>{e.onclick=async t=>{t.stopPropagation();let n=e.dataset.id,r=Gr().find(e=>e.id===n);r&&(e.disabled=!0,await Jr(r),e.disabled=!1)}}),e.querySelectorAll(`.btn-del-conn`).forEach(e=>{e.onclick=t=>{t.stopPropagation();let n=e.dataset.id;qr(n),x(),window.showToast&&window.showToast(`Removed from saved connections.`,`info`)}});let I=e.querySelector(`#connect-submit-btn`),L=e.querySelector(`#connect-error-msg`);I&&(I.onclick=async()=>{let e=n[t],r=null;if(e===`create`&&(t===`postgres`||t===`mysql`||t===`mssql`||t===`mongodb`)){let e=i[t],n=e.dbname.trim();if(!n){L&&(L.textContent=`Please enter a new database name to create.`,L.classList.remove(`hidden`));return}r={mode:`create`,dbType:t,host:e.host.trim()||`localhost`,port:e.port.trim()||(t===`mysql`?`3306`:t===`mssql`?`1433`:t===`mongodb`?`27017`:`5432`),user:e.user.trim()||(t===`mysql`?`root`:t===`mssql`?`sa`:t===`mongodb`?``:`postgres`),password:e.password||``,dbName:n,saveToEnv:s}}else if(t===`sqlite`&&e===`create`){let e=a.createName.trim()||`drixio.sqlite`;!e.endsWith(`.sqlite`)&&!e.endsWith(`.db`)&&!e.endsWith(`.sqlite3`)&&(e+=`.sqlite`),r={url:`./${e}`,createIfNotExist:!0,saveToEnv:s}}else{let e=``;if(e=t===`sqlite`?a.existingPath.trim()||``:p(),!e){L&&(L.textContent=`Please enter valid connection parameters.`,L.classList.remove(`hidden`));return}r={url:e,createIfNotExist:!1,saveToEnv:s}}t!==`sqlite`&&o.enabled&&o.host&&(r.sshTunnel={...o});let c=I.innerHTML;I.disabled=!0,I.innerHTML=`
3102
3852
  <span class="material-symbols-outlined animate-spin" style="font-size: 18px;">sync</span>
3103
3853
  <span>Connecting...</span>
3104
- `,k&&k.classList.add(`hidden`);try{let e=await(await fetch(`/api/connect`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(r)})).json();if(!e.success)throw Error(e.error||`Failed to connect`);let n=t!==`sqlite`,i=n?`REMOTE`:`LOCAL`,a=e.data?.dbName||p(),o=e.data?.targetUrl||r.url;Ln({name:a,dialect:e.data?.dbType||t,url:o,isRemote:n,badgeLabel:i});let s=document.getElementById(`db-name`);s&&(s.textContent=a);let c=document.getElementById(`env-badge`);c&&(c.textContent=i,c.className=`env-badge ${n?`remote`:`local`}`,c.classList.remove(`hidden`)),window.showToast&&window.showToast(`Database connected successfully!`,`success`),typeof window.initSidebar==`function`&&await window.initSidebar(!0),typeof window.setStudioConnectionMode==`function`&&window.setStudioConnectionMode(!0),typeof window.handleSwitchTab==`function`&&window.handleSwitchTab(`data-btn`)}catch(e){O.disabled=!1,O.innerHTML=s,k&&(k.textContent=e.message,k.classList.remove(`hidden`)),window.showToast&&window.showToast(e.message,`error`)}}),h(),_()};y()}var Vn=()=>{let e=localStorage.getItem(`drixio-theme`),t=window.matchMedia&&window.matchMedia(`(prefers-color-scheme: dark)`).matches,n=e=>{let t=document.getElementById(`theme-icon`),n=document.getElementById(`theme-text`);t&&(t.textContent=e?`light_mode`:`dark_mode`),n&&(n.textContent=e?`Light Mode`:`Dark Mode`)};e===`dark`||!e&&t?(document.documentElement.setAttribute(`data-theme`,`dark`),n(!0)):n(!1);let r=document.getElementById(`theme-toggle`);r&&r.addEventListener(`click`,()=>{let e=document.documentElement.getAttribute(`data-theme`)===`dark`,t=e?`light`:`dark`;document.documentElement.setAttribute(`data-theme`,t),localStorage.setItem(`drixio-theme`,t),n(!e)})},Hn=()=>{let e=new Map;window.showToast=function(t,n=`success`){let r=document.getElementById(`toast-container`);if(!r)return;let i=Date.now(),a=`${n}:${t}`,o=e.get(a);if(o&&i-o<1500)return;if(e.set(a,i),e.size>50)for(let[t,n]of e.entries())i-n>1e4&&e.delete(t);for(;r.children.length>=3;){let e=r.firstElementChild;e&&e.remove()}let s=document.createElement(`div`);s.className=`toast ${n}`;let c=`check_circle`;n===`error`?c=`error`:n===`warning`?c=`warning`:n===`info`&&(c=`info`),s.innerHTML=`<span class="material-symbols-outlined">${c}</span> <span>${t}</span>`,r.appendChild(s),setTimeout(()=>{s.parentNode&&s.parentNode.removeChild(s)},3e3)}},Un=()=>{document.addEventListener(`mouseup`,()=>{window.DataGrid&&window.DataGrid.selection&&(window.DataGrid.selection.isDragging=!1),window.SchemaGrid&&window.SchemaGrid.selection&&(window.SchemaGrid.selection.isDragging=!1)}),document.addEventListener(`contextmenu`,e=>{let t=window.AppState?.currentTab===`data-btn`,n=window.AppState?.currentTab===`schema-btn`;if(!t&&!n||t&&!window.DataGrid||n&&!window.SchemaGrid)return;let r=e.target.closest(`td.row-header, td.data-cell`);if(!r||e.target.tagName===`INPUT`||e.target.tagName===`SELECT`||e.target.tagName===`TEXTAREA`)return;e.preventDefault();let i=parseInt(r.dataset.rowIdx);if(isNaN(i))return;let a=[i],o=t?window.DataGrid:window.SchemaGrid;if(o&&o.selection&&o.selection.startRow!==-1){let e=o.selection,t=Math.min(e.startRow,e.endRow),n=Math.max(e.startRow,e.endRow);if(i>=t&&i<=n){a=[];for(let e=t;e<=n;e++)a.push(e)}}let s=e=>{if(!t||!window.DataGrid)return null;let n=window.DataGrid.rows||[],i=window.DataGrid.pkColumn,a=null;if(e<n.length&&n[e]){a={...n[e]};let t=i?a[i]:null;t!=null&&window.DataGrid.pendingEdits?.[t]&&Object.assign(a,window.DataGrid.pendingEdits[t])}else{let t=r.dataset?.insertIndex===void 0?e-n.length:parseInt(r.dataset.insertIndex);window.DataGrid.pendingInserts?.[t]&&(a={...window.DataGrid.pendingInserts[t]})}return a},c=async e=>{let t=e.map(e=>s(e)).filter(Boolean);if(t.length===0)return;let n=t.length===1?t[0]:t,r=JSON.stringify(n,null,2);try{await navigator.clipboard.writeText(r)}catch{let e=document.createElement(`textarea`);e.value=r,document.body.appendChild(e),e.select(),document.execCommand(`copy`),e.remove()}window.showToast?.(`Copied ${t.length} row(s) as JSON!`,`success`)},l=async e=>{let t=e.map(e=>s(e)).filter(Boolean);if(t.length===0)return;let n=window.AppState?.currentTable||`table_name`,r=window.AppState?.dbType||`sqlite`,i=e=>r===`mysql`?`\`${e}\``:`"${e}"`,a=e=>{if(e==null)return`NULL`;if(typeof e==`number`)return String(e);if(typeof e==`boolean`)return e?`TRUE`:`FALSE`;if(typeof e==`object`)return`'${JSON.stringify(e).replace(/'/g,`''`)}'`;let t=String(e);return t.toUpperCase()===`NULL`?`NULL`:`'${t.replace(/'/g,`''`)}'`},o=window.DataGrid?.schema||[],c=o.length>0?o.map(e=>e.name):Object.keys(t[0]),l=t.map(e=>{let t=c.map(t=>a(e[t]));return`INSERT INTO ${i(n)} (${c.map(i).join(`, `)}) VALUES (${t.join(`, `)});`}).join(`
3105
- `);try{await navigator.clipboard.writeText(l)}catch{let e=document.createElement(`textarea`);e.value=l,document.body.appendChild(e),e.select(),document.execCommand(`copy`),e.remove()}window.showToast?.(`Copied ${t.length} row(s) as SQL INSERT!`,`success`)},u=async()=>{let e=r.textContent||``;try{await navigator.clipboard.writeText(e)}catch{let t=document.createElement(`textarea`);t.value=e,document.body.appendChild(t),t.select(),document.execCommand(`copy`),t.remove()}window.showToast?.(`Copied cell value!`,`success`)},d=e=>{t?(window.DataGrid.currentTransaction=[],e===`delete`?a.forEach(e=>je(e)):e===`duplicate`&&(Ne(a,window.DataGrid.schema.map(e=>e.name)),setTimeout(()=>{let e=document.getElementById(`data-grid-container-${window.AppState.currentTable}`);e&&(e.scrollTop=e.scrollHeight)},50)),window.DataGrid.currentTransaction.length>0&&window.DataGrid.history.push(window.DataGrid.currentTransaction),window.DataGrid.currentTransaction=null):n&&(window.SchemaGrid.currentTransaction=[],e===`delete`?a.forEach(e=>Je(e)):e===`duplicate`&&(Xe(a,[`name`,`type`,`isPk`,`nullable`,`defaultValue`,`Index`]),setTimeout(()=>{let e=document.getElementById(`schema-grid-container-${window.AppState.currentTable}`);e&&(e.scrollTop=e.scrollHeight)},50)),window.SchemaGrid.currentTransaction.length>0&&window.SchemaGrid.history.push(window.SchemaGrid.currentTransaction),window.SchemaGrid.currentTransaction=null)},f=[];r.classList.contains(`data-cell`)&&r.textContent?.trim()&&(f.push({label:`Copy Cell Value`,icon:`content_paste`,action:()=>u()}),f.push(`divider`)),t&&f.push({label:a.length>1?`Copy ${a.length} Rows as JSON`:`Copy Row as JSON`,icon:`data_object`,action:()=>c(a)},{label:a.length>1?`Copy ${a.length} Rows as SQL`:`Copy Row as SQL (INSERT)`,icon:`code`,action:()=>l(a)},`divider`),f.push({label:a.length>1?`Duplicate ${a.length} Rows`:`Duplicate Row`,icon:`content_copy`,action:()=>d(`duplicate`)},`divider`,{label:a.length>1?`Delete ${a.length} Rows`:`Delete Row`,icon:`delete`,danger:!0,action:()=>d(`delete`)}),A(e,f)}),document.addEventListener(`keydown`,e=>{let t=window.AppState?.currentTab===`data-btn`,n=window.AppState?.currentTab===`schema-btn`;if(e.key===`F5`){t&&window.DataGrid?.refreshData?(e.preventDefault(),window.DataGrid.refreshData()):n&&document.getElementById(`btn-refresh-schema`)&&(e.preventDefault(),document.getElementById(`btn-refresh-schema`).click());return}if(!t&&!n)return;if(e.key.toLowerCase()===`s`&&(e.ctrlKey||e.metaKey)){e.preventDefault(),(e.target.tagName===`INPUT`||e.target.tagName===`SELECT`||e.target.tagName===`TEXTAREA`)&&e.target.blur(),setTimeout(()=>{t&&window.saveDataGridEdits?.(),n&&window.saveSchemaEdits?.()},50);return}if(e.target.tagName===`INPUT`||e.target.tagName===`SELECT`||e.target.tagName===`TEXTAREA`)return;if(e.key===`Escape`){let e=t?window.DataGrid:window.SchemaGrid;if(!e||!e.selection||e.selection.startRow===-1)return;if(e.selection.startRow!==e.selection.endRow||e.selection.startCol!==e.selection.endCol||e.selection.isRowSelection){e.selection.endRow=e.selection.startRow,e.selection.endCol=e.selection.startCol,e.selection.isRowSelection=!1,e.selection.isDraggingRow=!1;let n=window.AppState?.currentTable;he(t?`data-grid-table-${n}`:`schema-grid-table-${n}`,e);return}}if(e.key.toLowerCase()===`a`&&(e.ctrlKey||e.metaKey)){let n=t?window.DataGrid:window.SchemaGrid;if(!n)return;e.preventDefault();let r=window.AppState?.currentTable;if(!r)return;ge(t?`data-grid-table-${r}`:`schema-grid-table-${r}`,n,t?n.schema?.length||1:6);return}if([`ArrowUp`,`ArrowDown`,`ArrowLeft`,`ArrowRight`].includes(e.key)){let n=t?window.DataGrid:window.SchemaGrid;if(!n||!n.selection)return;e.preventDefault();let r=n.selection;if(r.startRow===-1)return;let i=t?n.schema.length:5,a=window.AppState?.currentTable,o=document.querySelectorAll(t?`#data-grid-table-${a} tbody tr`:`#schema-grid-table-${a} tbody tr`),s=o.length>0?o.length-1:0,c=e.shiftKey?r.endRow:r.startRow,l=e.shiftKey?r.endCol:r.startCol;e.key===`ArrowUp`&&(c=Math.max(0,c-1)),e.key===`ArrowDown`&&(c=Math.min(s,c+1)),e.key===`ArrowLeft`&&(l=Math.max(0,l-1)),e.key===`ArrowRight`&&(l=Math.min(i-1,l+1)),e.shiftKey?(r.endRow=c,r.endCol=l):(r.startRow=c,r.endRow=c,r.startCol=l,r.endCol=l),he(t?`data-grid-table-${a}`:`schema-grid-table-${a}`,n),setTimeout(()=>{let e=document.querySelector(t?`#data-grid-table-${a} td.data-cell[data-row-idx="${c}"][data-col-idx="${l}"]`:`#schema-grid-table-${a} td.data-cell[data-row-idx="${c}"][data-col-idx="${l}"]`);if(e){let n=document.getElementById(t?`data-grid-container-${a}`:`schema-grid-container-${a}`);if(n){let t=e.getBoundingClientRect(),r=n.getBoundingClientRect();t.bottom>r.bottom?n.scrollTop+=t.bottom-r.bottom+5:t.top<r.top+30&&(n.scrollTop-=r.top+30-t.top),t.right>r.right?n.scrollLeft+=t.right-r.right+5:t.left<r.left+50&&(n.scrollLeft-=r.left+50-t.left)}}},5);return}if((e.key===` `||e.code===`Space`)&&t&&window.DataGrid?.selection?.startRow!==-1){let t=window.DataGrid.selection;if(t.startRow===t.endRow&&t.startCol===t.endCol){let n=window.AppState?.currentTable,r=document.querySelector(`#data-grid-table-${n} td.data-cell[data-row-idx="${t.startRow}"][data-col-idx="${t.startCol}"]`);if(r&&!r.querySelector(`input, select`)){let t=r.dataset.col,n=(window.DataGrid.schema?.find(e=>e.name===t))?.type?.toUpperCase()||``;if(n.includes(`BOOL`)||n===`TINYINT(1)`){e.preventDefault();let t=r.dataset.original!==void 0&&r.dataset.original!==`-`?r.dataset.original:r.textContent.trim(),n=t===`1`||t.toLowerCase()===`true`?`0`:`1`;window.DataGrid.currentTransaction=[],Ae(r,n,window.DataGrid.schema.map(e=>e.name)),window.DataGrid.currentTransaction.length>0&&window.DataGrid.history.push(window.DataGrid.currentTransaction),window.DataGrid.currentTransaction=null;return}}}}let r=e.key.length===1&&!e.ctrlKey&&!e.metaKey&&!e.altKey,i=e.key===`F2`;if(e.key===`Enter`||r||i){if(e.repeat)return;let n=t?window.DataGrid:window.SchemaGrid;if(!n||!n.selection||n.selection.startRow===-1)return;let a=window.AppState?.currentTable;if(!a)return;let o=Math.min(n.selection.startRow,n.selection.endRow),s=Math.min(n.selection.startCol,n.selection.endCol),c=document.querySelector(t?`#data-grid-table-${a} td.data-cell[data-row-idx="${o}"][data-col-idx="${s}"]`:`#schema-grid-table-${a} td.data-cell[data-row-idx="${o}"][data-col-idx="${s}"]`);if(c&&!c.classList.contains(`manage-indexes-cell`)&&!c.querySelector(`input, select`)){e.preventDefault();let t=new MouseEvent(`dblclick`,{bubbles:!0,cancelable:!0,view:window});c.dispatchEvent(t);let n=c.querySelector(`input`);if(n){if(r)n.value=e.key,n.setSelectionRange(e.key.length,e.key.length);else if(i){let e=n.value.length;n.setSelectionRange(e,e)}}else{let t=c.querySelector(`select`);if(t&&r){let n=Array.from(t.options).find(t=>t.text.toLowerCase().startsWith(e.key.toLowerCase()));n&&(t.value=n.value,t.dispatchEvent(new Event(`change`,{bubbles:!0})))}}return}}if(e.key===`Tab`){let n=t?window.DataGrid:window.SchemaGrid;if(!n||!n.selection||n.selection.startRow===-1)return;e.preventDefault();let r=window.AppState?.currentTable,i=Math.min(n.selection.startRow,n.selection.endRow),a=Math.min(n.selection.startCol,n.selection.endCol),o=t?n.schema.length:5,s=document.querySelectorAll(t?`#data-grid-table-${r} tbody tr`:`#schema-grid-table-${r} tbody tr`),c=s.length>0?s.length-1:0;e.shiftKey?(--a,a<0&&(a=o-1,i=Math.max(0,i-1))):(a+=1,a>=o&&(a=0,i=Math.min(c,i+1))),n.selection.startRow=i,n.selection.endRow=i,n.selection.startCol=a,n.selection.endCol=a,he(t?`data-grid-table-${r}`:`schema-grid-table-${r}`,n),setTimeout(()=>{let e=document.querySelector(t?`#data-grid-table-${r} td.data-cell[data-row-idx="${i}"][data-col-idx="${a}"]`:`#schema-grid-table-${r} td.data-cell[data-row-idx="${i}"][data-col-idx="${a}"]`);if(e){let n=document.getElementById(t?`data-grid-container-${r}`:`schema-grid-container-${r}`);if(n){let t=e.getBoundingClientRect(),r=n.getBoundingClientRect();t.bottom>r.bottom?n.scrollTop+=t.bottom-r.bottom+5:t.top<r.top+30&&(n.scrollTop-=r.top+30-t.top),t.right>r.right?n.scrollLeft+=t.right-r.right+5:t.left<r.left+50&&(n.scrollLeft-=r.left+50-t.left)}}},5);return}if(e.key===`Delete`||e.key===`Backspace`){let e=t?window.DataGrid:window.SchemaGrid;if(!e||!e.selection||e.selection.startRow===-1)return;let r=e.selection,i=Math.min(r.startRow,r.endRow),a=Math.max(r.startRow,r.endRow),o=Math.min(r.startCol,r.endCol),s=Math.max(r.startCol,r.endCol),c=t?window.DataGrid?.schema?.length||1:6,l=r.isRowSelection===!0||o===0&&s>=c-1;if(t)if(l){window.DataGrid.currentTransaction=[];for(let e=i;e<=a;e++)je(e);window.DataGrid.currentTransaction.length>0&&window.DataGrid.history.push(window.DataGrid.currentTransaction),window.DataGrid.currentTransaction=null,window.updateSidebarDirtyState?.()}else window.DataGrid.currentTransaction=[],document.querySelectorAll(`#data-grid-table-${window.AppState.currentTable} .cell-in-range`).forEach(e=>Ae(e,``,window.DataGrid.schema.map(e=>e.name))),window.DataGrid.currentTransaction.length>0&&window.DataGrid.history.push(window.DataGrid.currentTransaction),window.DataGrid.currentTransaction=null;else if(n)if(l){window.SchemaGrid.currentTransaction=[];for(let e=i;e<=a;e++)Je(e);window.SchemaGrid.currentTransaction.length>0&&window.SchemaGrid.history.push(window.SchemaGrid.currentTransaction),window.SchemaGrid.currentTransaction=null,window.updateSidebarDirtyState?.()}else{window.SchemaGrid.currentTransaction=[];let e=[`name`,`type`,`isPk`,`nullable`,`defaultValue`];document.querySelectorAll(`#schema-grid-table-${window.AppState.currentTable} .cell-in-range`).forEach(t=>{(t.dataset.insertIndex!==void 0||t.dataset.colKey===`name`)&&qe(t,``,e)}),window.SchemaGrid.currentTransaction.length>0&&window.SchemaGrid.history.push(window.SchemaGrid.currentTransaction),window.SchemaGrid.currentTransaction=null}}if(e.key.toLowerCase()===`s`&&(e.ctrlKey||e.metaKey)&&(e.preventDefault(),t&&window.saveDataGridEdits(),n&&window.saveSchemaEdits()),e.key.toLowerCase()===`c`&&(e.ctrlKey||e.metaKey)){let e=(t?window.DataGrid:window.SchemaGrid).selection;if(e.startRow===-1)return;let n=Math.min(e.startRow,e.endRow),r=Math.max(e.startRow,e.endRow),i=Math.min(e.startCol,e.endCol),a=Math.max(e.startCol,e.endCol),o=``;for(let e=n;e<=r;e++){let n=[];for(let r=i;r<=a;r++){let i=document.querySelector(t?`#data-grid-table-${window.AppState.currentTable} td.data-cell[data-row-idx="${e}"][data-col-idx="${r}"]`:`#schema-grid-table-${window.AppState.currentTable} td.data-cell[data-row-idx="${e}"][data-col-idx="${r}"]`);if(i){let e=i.textContent.replace(/^null$|^\+ New$/,``);n.push(e)}}o+=n.join(` `)+`
3106
- `}navigator.clipboard.writeText(o.trimEnd()),document.querySelectorAll(`.cell-in-range`).forEach(e=>{e.style.backgroundColor=`var(--color-copy-flash)`,setTimeout(()=>e.style.backgroundColor=``,150)})}if(e.key===`-`&&(e.ctrlKey||e.metaKey)){e.preventDefault();let r=t?window.DataGrid:window.SchemaGrid,i=r.selection;if(i.startRow===-1)return;let a=Math.min(i.startRow,i.endRow),o=Math.max(i.startRow,i.endRow);if(t){r.currentTransaction=[];for(let e=a;e<=o;e++)je(e);r.currentTransaction.length>0&&r.history.push(r.currentTransaction),r.currentTransaction=null}else if(n){r.currentTransaction=[];for(let e=a;e<=o;e++)Je(e);r.currentTransaction.length>0&&r.history.push(r.currentTransaction),r.currentTransaction=null}}if(e.key.toLowerCase()===`z`&&(e.ctrlKey||e.metaKey)){if(e.preventDefault(),t){let e=window.DataGrid.history?.pop();if(e){let t=window.DataGrid.schema.map(e=>e.name);for(let n=e.length-1;n>=0;n--){let r=e[n];r.type===`delete`?Me(r.rowIdx,r.pk):Ae(r.td,r.oldVal,t,!1)}}}else if(n){let e=window.SchemaGrid.history?.pop();if(e){let t=[`name`,`type`,`isPk`,`nullable`,`defaultValue`];for(let n=e.length-1;n>=0;n--){let r=e[n];r.type===`delete`?Ye(r.rowIdx,r.pk):qe(r.td,r.oldVal,t,!1)}}}}}),document.addEventListener(`paste`,e=>{let t=window.AppState?.currentTab===`data-btn`,n=window.AppState?.currentTab===`schema-btn`;if(!t&&!n)return;let r=t?window.DataGrid:window.SchemaGrid;if(!r||e.target.tagName===`INPUT`||e.target.tagName===`SELECT`||e.target.tagName===`TEXTAREA`)return;let i=r.selection;if(i.startRow===-1)return;let a=e.clipboardData.getData(`text`);if(!a)return;e.preventDefault();let o=a.split(/\r?\n/).map(e=>e.split(` `)),s=Math.min(i.startRow,i.endRow),c=Math.min(i.startCol,i.endCol);if(r.currentTransaction=[],t){let e=r.schema.map(e=>e.name);o.forEach(t=>{t.forEach((t,n)=>{let r=c+n,i=document.querySelector(`#data-grid-table-${window.AppState.currentTable} td.data-cell[data-row-idx="${s}"][data-col-idx="${r}"]`);i&&Ae(i,t,e)}),s++}),r.currentTransaction.length>0&&r.history.push(r.currentTransaction),r.currentTransaction=null}else if(n){let e=[`name`,`type`,`isPk`,`nullable`,`defaultValue`];o.forEach(t=>{t.forEach((t,n)=>{let r=c+n,i=document.querySelector(`#schema-grid-table-${window.AppState.currentTable} td.data-cell[data-row-idx="${s}"][data-col-idx="${r}"]`);i&&(i.dataset.insertIndex!==void 0||i.dataset.colKey===`name`)&&qe(i,t,e)}),s++}),r.currentTransaction.length>0&&r.history.push(r.currentTransaction),r.currentTransaction=null}})},Wn=null;function Gn(){Wn&&Wn.close(),Wn=_t({id:`help-modal-overlay`,icon:`help`,iconColor:`primary`,title:`Shortcuts & Documentation`,subtitle:`Drixio Studio Edition Tips & Resources`,badge:`Help`,width:`640px`,body:`
3854
+ `,L&&L.classList.add(`hidden`);try{let e=await(await fetch(`/api/connect`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(r)})).json();if(!e.success)throw Error(e.error||`Failed to connect`);let n=t!==`sqlite`,i=n?`REMOTE`:`LOCAL`,a=e.data?.dbName||m(),o=e.data?.targetUrl||r.url;Kr({name:a,dialect:e.data?.dbType||t,url:o,isRemote:n,badgeLabel:i});let s=document.getElementById(`db-name`);s&&(s.textContent=a);let c=document.getElementById(`env-badge`);c&&(c.textContent=i,c.className=`env-badge ${n?`remote`:`local`}`,c.classList.remove(`hidden`)),window.showToast&&window.showToast(`Database connected successfully!`,`success`),typeof window.initSidebar==`function`&&await window.initSidebar(!0),typeof window.setStudioConnectionMode==`function`&&window.setStudioConnectionMode(!0),typeof window.handleSwitchTab==`function`&&window.handleSwitchTab(`data-btn`)}catch(e){I.disabled=!1,I.innerHTML=c,L&&(L.textContent=e.message,L.classList.remove(`hidden`)),window.showToast&&window.showToast(e.message,`error`)}}),g(),v()};x()}var Xr=()=>{let e=localStorage.getItem(`drixio-theme`),t=window.matchMedia&&window.matchMedia(`(prefers-color-scheme: dark)`).matches,n=e=>{let t=document.getElementById(`theme-icon`),n=document.getElementById(`theme-text`);t&&(t.textContent=e?`light_mode`:`dark_mode`),n&&(n.textContent=e?`Light Mode`:`Dark Mode`)};e===`dark`||!e&&t?(document.documentElement.setAttribute(`data-theme`,`dark`),n(!0)):n(!1);let r=document.getElementById(`theme-toggle`);r&&r.addEventListener(`click`,()=>{let e=document.documentElement.getAttribute(`data-theme`)===`dark`,t=e?`light`:`dark`;document.documentElement.setAttribute(`data-theme`,t),localStorage.setItem(`drixio-theme`,t),n(!e)})},Zr=()=>{let e=new Map;window.showToast=function(t,n=`success`){let r=document.getElementById(`toast-container`);if(!r)return;let i=Date.now(),a=`${n}:${t}`,o=e.get(a);if(o&&i-o<1500)return;if(e.set(a,i),e.size>50)for(let[t,n]of e.entries())i-n>1e4&&e.delete(t);for(;r.children.length>=3;){let e=r.firstElementChild;e&&e.remove()}let s=document.createElement(`div`);s.className=`toast ${n}`;let c=`check_circle`;n===`error`?c=`error`:n===`warning`?c=`warning`:n===`info`&&(c=`info`),s.innerHTML=`<span class="material-symbols-outlined">${c}</span> <span>${t}</span>`,r.appendChild(s),setTimeout(()=>{s.parentNode&&s.parentNode.removeChild(s)},3e3)}},Qr=()=>{document.addEventListener(`mouseup`,()=>{window.DataGrid&&window.DataGrid.selection&&(window.DataGrid.selection.isDragging=!1),window.SchemaGrid&&window.SchemaGrid.selection&&(window.SchemaGrid.selection.isDragging=!1)}),document.addEventListener(`contextmenu`,e=>{let t=window.AppState?.currentTab===`data-btn`,n=window.AppState?.currentTab===`schema-btn`;if(!t&&!n||t&&!window.DataGrid||n&&!window.SchemaGrid)return;let r=e.target.closest(`td.row-header, td.data-cell`);if(!r||e.target.tagName===`INPUT`||e.target.tagName===`SELECT`||e.target.tagName===`TEXTAREA`)return;e.preventDefault();let i=parseInt(r.dataset.rowIdx);if(isNaN(i))return;let a=[i],o=t?window.DataGrid:window.SchemaGrid;if(o&&o.selection&&o.selection.startRow!==-1){let e=o.selection,t=Math.min(e.startRow,e.endRow),n=Math.max(e.startRow,e.endRow);if(i>=t&&i<=n){a=[];for(let e=t;e<=n;e++)a.push(e)}}let s=e=>{if(!t||!window.DataGrid)return null;let n=window.DataGrid.rows||[],i=window.DataGrid.pkColumn,a=null;if(e<n.length&&n[e]){a={...n[e]};let t=i?a[i]:null;t!=null&&window.DataGrid.pendingEdits?.[t]&&Object.assign(a,window.DataGrid.pendingEdits[t])}else{let t=r.dataset?.insertIndex===void 0?e-n.length:parseInt(r.dataset.insertIndex);window.DataGrid.pendingInserts?.[t]&&(a={...window.DataGrid.pendingInserts[t]})}return a},c=async e=>{let t=e.map(e=>s(e)).filter(Boolean);if(t.length===0)return;let n=t.length===1?t[0]:t,r=JSON.stringify(n,null,2);try{await navigator.clipboard.writeText(r)}catch{let e=document.createElement(`textarea`);e.value=r,document.body.appendChild(e),e.select(),document.execCommand(`copy`),e.remove()}window.showToast?.(`Copied ${t.length} row(s) as JSON!`,`success`)},l=async e=>{let t=e.map(e=>s(e)).filter(Boolean);if(t.length===0)return;let n=window.AppState?.currentTable||`table_name`,r=window.AppState?.dbType||`sqlite`,i=e=>r===`mysql`?`\`${e}\``:r===`mssql`?`[${e}]`:`"${e}"`,a=e=>{if(e==null)return`NULL`;if(typeof e==`number`)return String(e);if(typeof e==`boolean`)return e?`TRUE`:`FALSE`;if(typeof e==`object`)return`'${JSON.stringify(e).replace(/'/g,`''`)}'`;let t=String(e);return t.toUpperCase()===`NULL`?`NULL`:`'${t.replace(/'/g,`''`)}'`},o=window.DataGrid?.schema||[],c=o.length>0?o.map(e=>e.name):Object.keys(t[0]),l=t.map(e=>{let t=c.map(t=>a(e[t]));return`INSERT INTO ${i(n)} (${c.map(i).join(`, `)}) VALUES (${t.join(`, `)});`}).join(`
3855
+ `);try{await navigator.clipboard.writeText(l)}catch{let e=document.createElement(`textarea`);e.value=l,document.body.appendChild(e),e.select(),document.execCommand(`copy`),e.remove()}window.showToast?.(`Copied ${t.length} row(s) as SQL INSERT!`,`success`)},u=async()=>{let e=r.textContent||``;try{await navigator.clipboard.writeText(e)}catch{let t=document.createElement(`textarea`);t.value=e,document.body.appendChild(t),t.select(),document.execCommand(`copy`),t.remove()}window.showToast?.(`Copied cell value!`,`success`)},d=e=>{t?(window.DataGrid.currentTransaction=[],e===`delete`?a.forEach(e=>it(e)):e===`duplicate`&&(ot(a,window.DataGrid.schema.map(e=>e.name)),setTimeout(()=>{let e=document.getElementById(`data-grid-container-${window.AppState.currentTable}`);e&&(e.scrollTop=e.scrollHeight)},50)),window.DataGrid.currentTransaction.length>0&&window.DataGrid.history.push(window.DataGrid.currentTransaction),window.DataGrid.currentTransaction=null):n&&(window.SchemaGrid.currentTransaction=[],e===`delete`?a.forEach(e=>ge(e)):e===`duplicate`&&(ve(a,[`name`,`type`,`isPk`,`nullable`,`defaultValue`,`Index`]),setTimeout(()=>{let e=document.getElementById(`schema-grid-container-${window.AppState.currentTable}`);e&&(e.scrollTop=e.scrollHeight)},50)),window.SchemaGrid.currentTransaction.length>0&&window.SchemaGrid.history.push(window.SchemaGrid.currentTransaction),window.SchemaGrid.currentTransaction=null)},f=[];r.classList.contains(`data-cell`)&&r.textContent?.trim()&&(f.push({label:`Copy Cell Value`,icon:`content_paste`,action:()=>u()}),f.push(`divider`)),t&&f.push({label:a.length>1?`Copy ${a.length} Rows as JSON`:`Copy Row as JSON`,icon:`data_object`,action:()=>c(a)},{label:a.length>1?`Copy ${a.length} Rows as SQL`:`Copy Row as SQL (INSERT)`,icon:`code`,action:()=>l(a)},`divider`),f.push({label:a.length>1?`Duplicate ${a.length} Rows`:`Duplicate Row`,icon:`content_copy`,action:()=>d(`duplicate`)},`divider`,{label:a.length>1?`Delete ${a.length} Rows`:`Delete Row`,icon:`delete`,danger:!0,action:()=>d(`delete`)}),V(e,f)}),document.addEventListener(`keydown`,e=>{let t=window.AppState?.currentTab===`data-btn`,n=window.AppState?.currentTab===`schema-btn`;if(e.key===`F5`){t&&window.DataGrid?.refreshData?(e.preventDefault(),window.DataGrid.refreshData()):n&&document.getElementById(`btn-refresh-schema`)&&(e.preventDefault(),document.getElementById(`btn-refresh-schema`).click());return}if(!t&&!n)return;if(e.key.toLowerCase()===`s`&&(e.ctrlKey||e.metaKey)){e.preventDefault(),(e.target.tagName===`INPUT`||e.target.tagName===`SELECT`||e.target.tagName===`TEXTAREA`)&&e.target.blur(),setTimeout(()=>{t&&window.saveDataGridEdits?.(),n&&window.saveSchemaEdits?.()},50);return}if(e.target.tagName===`INPUT`||e.target.tagName===`SELECT`||e.target.tagName===`TEXTAREA`)return;if(e.key===`Escape`){let e=t?window.DataGrid:window.SchemaGrid;if(!e||!e.selection||e.selection.startRow===-1)return;if(e.selection.startRow!==e.selection.endRow||e.selection.startCol!==e.selection.endCol||e.selection.isRowSelection){e.selection.endRow=e.selection.startRow,e.selection.endCol=e.selection.startCol,e.selection.isRowSelection=!1,e.selection.isDraggingRow=!1;let n=window.AppState?.currentTable;He(t?`data-grid-table-${n}`:`schema-grid-table-${n}`,e);return}}if(e.key.toLowerCase()===`a`&&(e.ctrlKey||e.metaKey)){let n=t?window.DataGrid:window.SchemaGrid;if(!n)return;e.preventDefault();let r=window.AppState?.currentTable;if(!r)return;Ue(t?`data-grid-table-${r}`:`schema-grid-table-${r}`,n,t?n.schema?.length||1:6);return}if([`ArrowUp`,`ArrowDown`,`ArrowLeft`,`ArrowRight`].includes(e.key)){let n=t?window.DataGrid:window.SchemaGrid;if(!n||!n.selection)return;e.preventDefault();let r=n.selection;if(r.startRow===-1)return;let i=t?n.schema.length:5,a=window.AppState?.currentTable,o=document.querySelectorAll(t?`#data-grid-table-${a} tbody tr`:`#schema-grid-table-${a} tbody tr`),s=o.length>0?o.length-1:0,c=e.shiftKey?r.endRow:r.startRow,l=e.shiftKey?r.endCol:r.startCol;e.key===`ArrowUp`&&(c=Math.max(0,c-1)),e.key===`ArrowDown`&&(c=Math.min(s,c+1)),e.key===`ArrowLeft`&&(l=Math.max(0,l-1)),e.key===`ArrowRight`&&(l=Math.min(i-1,l+1)),e.shiftKey?(r.endRow=c,r.endCol=l):(r.startRow=c,r.endRow=c,r.startCol=l,r.endCol=l),He(t?`data-grid-table-${a}`:`schema-grid-table-${a}`,n),setTimeout(()=>{let e=document.querySelector(t?`#data-grid-table-${a} td.data-cell[data-row-idx="${c}"][data-col-idx="${l}"]`:`#schema-grid-table-${a} td.data-cell[data-row-idx="${c}"][data-col-idx="${l}"]`);if(e){let n=document.getElementById(t?`data-grid-container-${a}`:`schema-grid-container-${a}`);if(n){let t=e.getBoundingClientRect(),r=n.getBoundingClientRect();t.bottom>r.bottom?n.scrollTop+=t.bottom-r.bottom+5:t.top<r.top+30&&(n.scrollTop-=r.top+30-t.top),t.right>r.right?n.scrollLeft+=t.right-r.right+5:t.left<r.left+50&&(n.scrollLeft-=r.left+50-t.left)}}},5);return}if((e.key===` `||e.code===`Space`)&&t&&window.DataGrid?.selection?.startRow!==-1){let t=window.DataGrid.selection;if(t.startRow===t.endRow&&t.startCol===t.endCol){let n=window.AppState?.currentTable,r=document.querySelector(`#data-grid-table-${n} td.data-cell[data-row-idx="${t.startRow}"][data-col-idx="${t.startCol}"]`);if(r&&!r.querySelector(`input, select`)){let t=r.dataset.col,n=(window.DataGrid.schema?.find(e=>e.name===t))?.type?.toUpperCase()||``;if(n.includes(`BOOL`)||n===`TINYINT(1)`){e.preventDefault();let t=r.dataset.original!==void 0&&r.dataset.original!==`-`?r.dataset.original:r.textContent.trim(),n=t===`1`||t.toLowerCase()===`true`?`0`:`1`;window.DataGrid.currentTransaction=[],rt(r,n,window.DataGrid.schema.map(e=>e.name)),window.DataGrid.currentTransaction.length>0&&window.DataGrid.history.push(window.DataGrid.currentTransaction),window.DataGrid.currentTransaction=null;return}}}}let r=e.key.length===1&&!e.ctrlKey&&!e.metaKey&&!e.altKey,i=e.key===`F2`;if(e.key===`Enter`||r||i){if(e.repeat)return;let n=t?window.DataGrid:window.SchemaGrid;if(!n||!n.selection||n.selection.startRow===-1)return;let a=window.AppState?.currentTable;if(!a)return;let o=Math.min(n.selection.startRow,n.selection.endRow),s=Math.min(n.selection.startCol,n.selection.endCol),c=document.querySelector(t?`#data-grid-table-${a} td.data-cell[data-row-idx="${o}"][data-col-idx="${s}"]`:`#schema-grid-table-${a} td.data-cell[data-row-idx="${o}"][data-col-idx="${s}"]`);if(c&&!c.classList.contains(`manage-indexes-cell`)&&!c.querySelector(`input, select`)){e.preventDefault();let t=new MouseEvent(`dblclick`,{bubbles:!0,cancelable:!0,view:window});c.dispatchEvent(t);let n=c.querySelector(`input`);if(n){if(r)n.value=e.key,n.setSelectionRange(e.key.length,e.key.length);else if(i){let e=n.value.length;n.setSelectionRange(e,e)}}else{let t=c.querySelector(`select`);if(t&&r){let n=Array.from(t.options).find(t=>t.text.toLowerCase().startsWith(e.key.toLowerCase()));n&&(t.value=n.value,t.dispatchEvent(new Event(`change`,{bubbles:!0})))}}return}}if(e.key===`Tab`){let n=t?window.DataGrid:window.SchemaGrid;if(!n||!n.selection||n.selection.startRow===-1)return;e.preventDefault();let r=window.AppState?.currentTable,i=Math.min(n.selection.startRow,n.selection.endRow),a=Math.min(n.selection.startCol,n.selection.endCol),o=t?n.schema.length:5,s=document.querySelectorAll(t?`#data-grid-table-${r} tbody tr`:`#schema-grid-table-${r} tbody tr`),c=s.length>0?s.length-1:0;e.shiftKey?(--a,a<0&&(a=o-1,i=Math.max(0,i-1))):(a+=1,a>=o&&(a=0,i=Math.min(c,i+1))),n.selection.startRow=i,n.selection.endRow=i,n.selection.startCol=a,n.selection.endCol=a,He(t?`data-grid-table-${r}`:`schema-grid-table-${r}`,n),setTimeout(()=>{let e=document.querySelector(t?`#data-grid-table-${r} td.data-cell[data-row-idx="${i}"][data-col-idx="${a}"]`:`#schema-grid-table-${r} td.data-cell[data-row-idx="${i}"][data-col-idx="${a}"]`);if(e){let n=document.getElementById(t?`data-grid-container-${r}`:`schema-grid-container-${r}`);if(n){let t=e.getBoundingClientRect(),r=n.getBoundingClientRect();t.bottom>r.bottom?n.scrollTop+=t.bottom-r.bottom+5:t.top<r.top+30&&(n.scrollTop-=r.top+30-t.top),t.right>r.right?n.scrollLeft+=t.right-r.right+5:t.left<r.left+50&&(n.scrollLeft-=r.left+50-t.left)}}},5);return}if(e.key===`Delete`||e.key===`Backspace`){let e=t?window.DataGrid:window.SchemaGrid;if(!e||!e.selection||e.selection.startRow===-1)return;let r=e.selection,i=Math.min(r.startRow,r.endRow),a=Math.max(r.startRow,r.endRow),o=Math.min(r.startCol,r.endCol),s=Math.max(r.startCol,r.endCol),c=t?window.DataGrid?.schema?.length||1:6,l=r.isRowSelection===!0||o===0&&s>=c-1;if(t)if(l){window.DataGrid.currentTransaction=[];for(let e=i;e<=a;e++)it(e);window.DataGrid.currentTransaction.length>0&&window.DataGrid.history.push(window.DataGrid.currentTransaction),window.DataGrid.currentTransaction=null,window.updateSidebarDirtyState?.()}else window.DataGrid.currentTransaction=[],document.querySelectorAll(`#data-grid-table-${window.AppState.currentTable} .cell-in-range`).forEach(e=>rt(e,``,window.DataGrid.schema.map(e=>e.name))),window.DataGrid.currentTransaction.length>0&&window.DataGrid.history.push(window.DataGrid.currentTransaction),window.DataGrid.currentTransaction=null;else if(n)if(l){window.SchemaGrid.currentTransaction=[];for(let e=i;e<=a;e++)ge(e);window.SchemaGrid.currentTransaction.length>0&&window.SchemaGrid.history.push(window.SchemaGrid.currentTransaction),window.SchemaGrid.currentTransaction=null,window.updateSidebarDirtyState?.()}else{window.SchemaGrid.currentTransaction=[];let e=[`name`,`type`,`isPk`,`nullable`,`defaultValue`];document.querySelectorAll(`#schema-grid-table-${window.AppState.currentTable} .cell-in-range`).forEach(t=>{(t.dataset.insertIndex!==void 0||t.dataset.colKey===`name`)&&U(t,``,e)}),window.SchemaGrid.currentTransaction.length>0&&window.SchemaGrid.history.push(window.SchemaGrid.currentTransaction),window.SchemaGrid.currentTransaction=null}}if(e.key.toLowerCase()===`s`&&(e.ctrlKey||e.metaKey)&&(e.preventDefault(),t&&window.saveDataGridEdits(),n&&window.saveSchemaEdits()),e.key.toLowerCase()===`c`&&(e.ctrlKey||e.metaKey)){let e=(t?window.DataGrid:window.SchemaGrid).selection;if(e.startRow===-1)return;let n=Math.min(e.startRow,e.endRow),r=Math.max(e.startRow,e.endRow),i=Math.min(e.startCol,e.endCol),a=Math.max(e.startCol,e.endCol),o=``;for(let e=n;e<=r;e++){let n=[];for(let r=i;r<=a;r++){let i=document.querySelector(t?`#data-grid-table-${window.AppState.currentTable} td.data-cell[data-row-idx="${e}"][data-col-idx="${r}"]`:`#schema-grid-table-${window.AppState.currentTable} td.data-cell[data-row-idx="${e}"][data-col-idx="${r}"]`);if(i){let e=i.textContent.replace(/^null$|^\+ New$/,``);n.push(e)}}o+=n.join(` `)+`
3856
+ `}navigator.clipboard.writeText(o.trimEnd()),document.querySelectorAll(`.cell-in-range`).forEach(e=>{e.style.backgroundColor=`var(--color-copy-flash)`,setTimeout(()=>e.style.backgroundColor=``,150)})}if(e.key===`-`&&(e.ctrlKey||e.metaKey)){e.preventDefault();let r=t?window.DataGrid:window.SchemaGrid,i=r.selection;if(i.startRow===-1)return;let a=Math.min(i.startRow,i.endRow),o=Math.max(i.startRow,i.endRow);if(t){r.currentTransaction=[];for(let e=a;e<=o;e++)it(e);r.currentTransaction.length>0&&r.history.push(r.currentTransaction),r.currentTransaction=null}else if(n){r.currentTransaction=[];for(let e=a;e<=o;e++)ge(e);r.currentTransaction.length>0&&r.history.push(r.currentTransaction),r.currentTransaction=null}}if(e.key.toLowerCase()===`z`&&(e.ctrlKey||e.metaKey)){if(e.preventDefault(),t){let e=window.DataGrid.history?.pop();if(e){let t=window.DataGrid.schema.map(e=>e.name);for(let n=e.length-1;n>=0;n--){let r=e[n];r.type===`delete`?at(r.rowIdx,r.pk):rt(r.td,r.oldVal,t,!1)}}}else if(n){let e=window.SchemaGrid.history?.pop();if(e){let t=[`name`,`type`,`isPk`,`nullable`,`defaultValue`];for(let n=e.length-1;n>=0;n--){let r=e[n];r.type===`delete`?_e(r.rowIdx,r.pk):U(r.td,r.oldVal,t,!1)}}}}}),document.addEventListener(`paste`,e=>{let t=window.AppState?.currentTab===`data-btn`,n=window.AppState?.currentTab===`schema-btn`;if(!t&&!n)return;let r=t?window.DataGrid:window.SchemaGrid;if(!r||e.target.tagName===`INPUT`||e.target.tagName===`SELECT`||e.target.tagName===`TEXTAREA`)return;let i=r.selection;if(i.startRow===-1)return;let a=e.clipboardData.getData(`text`);if(!a)return;e.preventDefault();let o=a.split(/\r?\n/).map(e=>e.split(` `)),s=Math.min(i.startRow,i.endRow),c=Math.min(i.startCol,i.endCol);if(r.currentTransaction=[],t){let e=r.schema.map(e=>e.name);o.forEach(t=>{t.forEach((t,n)=>{let r=c+n,i=document.querySelector(`#data-grid-table-${window.AppState.currentTable} td.data-cell[data-row-idx="${s}"][data-col-idx="${r}"]`);i&&rt(i,t,e)}),s++}),r.currentTransaction.length>0&&r.history.push(r.currentTransaction),r.currentTransaction=null}else if(n){let e=[`name`,`type`,`isPk`,`nullable`,`defaultValue`];o.forEach(t=>{t.forEach((t,n)=>{let r=c+n,i=document.querySelector(`#schema-grid-table-${window.AppState.currentTable} td.data-cell[data-row-idx="${s}"][data-col-idx="${r}"]`);i&&(i.dataset.insertIndex!==void 0||i.dataset.colKey===`name`)&&U(i,t,e)}),s++}),r.currentTransaction.length>0&&r.history.push(r.currentTransaction),r.currentTransaction=null}})},$r=null;function ei(){$r&&$r.close(),$r=$t({id:`help-modal-overlay`,icon:`help`,iconColor:`primary`,title:`Shortcuts & Documentation`,subtitle:`Drixio Studio Edition Tips & Resources`,badge:`Help`,width:`640px`,body:`
3107
3857
  <div class="help-modal-body" style="padding: 0;">
3108
3858
  <div class="shortcuts-group">
3109
3859
  <h4 class="shortcuts-group-title">Global Shortcuts</h4>
@@ -3155,7 +3905,7 @@ $1`)}),t=t.replace(/[ \t]+(AND\b|OR\b)/g,`
3155
3905
  `,footer:`
3156
3906
  <span class="help-version-tag">Drixio Studio Edition</span>
3157
3907
  <button type="button" id="help-modal-done-btn" class="btn-secondary" style="padding: 5px 14px; font-size: 12px; cursor: pointer;">Close</button>
3158
- `,onClose:()=>{Wn=null}});let e=Wn.footer.querySelector(`#help-modal-done-btn`);e&&(e.onclick=()=>Wn.close())}var H=null;function Kn(){let e=document.getElementById(`breadcrumb-db-crumb`);H=document.getElementById(`db-switcher-dropdown`),!(!e||!H)&&(e.addEventListener(`click`,t=>{t.stopPropagation(),H.classList.contains(`hidden`)?(qn(),H.classList.remove(`hidden`),e.classList.add(`is-open`)):(H.classList.add(`hidden`),e.classList.remove(`is-open`))}),document.addEventListener(`click`,t=>{H&&!H.contains(t.target)&&!e.contains(t.target)&&(H.classList.add(`hidden`),e.classList.remove(`is-open`))}),document.addEventListener(`keydown`,t=>{t.key===`Escape`&&H&&!H.classList.contains(`hidden`)&&(H.classList.add(`hidden`),e.classList.remove(`is-open`))}))}function qn(){if(!H&&(H=document.getElementById(`db-switcher-dropdown`),!H))return;let e=In(),t=document.getElementById(`db-name`)?.textContent?.trim().toLowerCase()||``,n=e=>{switch(e){case`postgres`:return`dns`;case`mysql`:return`storage`;default:return`data_object`}};H.innerHTML=`
3908
+ `,onClose:()=>{$r=null}});let e=$r.footer.querySelector(`#help-modal-done-btn`);e&&(e.onclick=()=>$r.close())}var $=null;function ti(){let e=document.getElementById(`breadcrumb-db-crumb`);$=document.getElementById(`db-switcher-dropdown`),!(!e||!$)&&(e.addEventListener(`click`,t=>{t.stopPropagation(),$.classList.contains(`hidden`)?(ni(),$.classList.remove(`hidden`),e.classList.add(`is-open`)):($.classList.add(`hidden`),e.classList.remove(`is-open`))}),document.addEventListener(`click`,t=>{$&&!$.contains(t.target)&&!e.contains(t.target)&&($.classList.add(`hidden`),e.classList.remove(`is-open`))}),document.addEventListener(`keydown`,t=>{t.key===`Escape`&&$&&!$.classList.contains(`hidden`)&&($.classList.add(`hidden`),e.classList.remove(`is-open`))}))}function ni(){if(!$&&($=document.getElementById(`db-switcher-dropdown`),!$))return;let e=Gr(),t=document.getElementById(`db-name`)?.textContent?.trim().toLowerCase()||``,n=e=>{switch(e){case`postgres`:return`dns`;case`mysql`:return`storage`;case`mssql`:return`database`;case`mongodb`:return`dataset`;default:return`data_object`}};$.innerHTML=`
3159
3909
  <div class="db-switcher-header">
3160
3910
  <span class="db-switcher-title">DATABASES</span>
3161
3911
  <span class="db-switcher-count">${e.length}</span>
@@ -3169,10 +3919,10 @@ $1`)}),t=t.replace(/[ \t]+(AND\b|OR\b)/g,`
3169
3919
  </div>
3170
3920
  <div class="db-item-info">
3171
3921
  <div class="db-item-name-row">
3172
- <span class="db-item-name">${Jn(e.name)}</span>
3922
+ <span class="db-item-name">${ri(e.name)}</span>
3173
3923
  ${r?`<span class="db-active-badge">Active</span>`:``}
3174
3924
  </div>
3175
- <span class="db-item-meta">${Jn(e.badgeLabel||(e.isRemote?`REMOTE`:`LOCAL`))}</span>
3925
+ <span class="db-item-meta">${ri(e.badgeLabel||(e.isRemote?`REMOTE`:`LOCAL`))}</span>
3176
3926
  </div>
3177
3927
  ${r?`<span class="material-symbols-outlined db-active-check">check</span>`:`<button type="button" class="db-remove-btn" title="Forget database" data-id="${e.id}">✕</button>`}
3178
3928
  </div>
@@ -3187,7 +3937,7 @@ $1`)}),t=t.replace(/[ \t]+(AND\b|OR\b)/g,`
3187
3937
  <span>Connect or Create New Database...</span>
3188
3938
  </button>
3189
3939
  </div>
3190
- `,H.querySelectorAll(`.db-switcher-item`).forEach(t=>{t.addEventListener(`click`,async n=>{if(n.target.closest(`.db-remove-btn`))return;let r=t.getAttribute(`data-id`),i=e.find(e=>e.id===r);i&&(H.classList.add(`hidden`),document.getElementById(`breadcrumb-db-crumb`)?.classList.remove(`is-open`),await zn(i))})}),H.querySelectorAll(`.db-remove-btn`).forEach(e=>{e.addEventListener(`click`,t=>{t.stopPropagation();let n=e.getAttribute(`data-id`);n&&(Rn(n),qn())})});let r=document.getElementById(`db-switcher-new-btn`);r&&r.addEventListener(`click`,e=>{e.stopPropagation(),H.classList.add(`hidden`),document.getElementById(`breadcrumb-db-crumb`)?.classList.remove(`is-open`),typeof window.handleSwitchTab==`function`&&window.handleSwitchTab(`connect-btn`)})}function Jn(e){return e?String(e).replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`).replace(/"/g,`&quot;`):``}function Yn(e){if(e===void 0)throw ReferenceError(`this hasn't been initialised - super() hasn't been called`);return e}function Xn(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,e.__proto__=t}var Zn={autoSleep:120,force3D:`auto`,nullTargetWarn:1,units:{lineHeight:``}},Qn={duration:.5,overwrite:!1,delay:0},$n,er,U,tr=1e8,W=1/tr,nr=Math.PI*2,rr=nr/4,ir=0,ar=Math.sqrt,or=Math.cos,sr=Math.sin,G=function(e){return typeof e==`string`},K=function(e){return typeof e==`function`},cr=function(e){return typeof e==`number`},lr=function(e){return e===void 0},ur=function(e){return typeof e==`object`},dr=function(e){return e!==!1},fr=function(){return typeof window<`u`},pr=function(e){return K(e)||G(e)},mr=typeof ArrayBuffer==`function`&&ArrayBuffer.isView||function(){},hr=Array.isArray,gr=/random\([^)]+\)/g,_r=/,\s*/g,vr=/(?:-?\.?\d|\.)+/gi,yr=/[-+=.]*\d+[.e\-+]*\d*[e\-+]*\d*/g,br=/[-+=.]*\d+[.e-]*\d*[a-z%]*/g,xr=/[-+=.]*\d+\.?\d*(?:e-|e\+)?\d*/gi,Sr=/[+-]=-?[.\d]+/,Cr=/[^,'"\[\]\s]+/gi,wr=/^[+\-=e\s\d]*\d+[.\d]*([a-z]*|%)\s*$/i,q,Tr,Er,Dr,Or={},kr={},Ar,jr=function(e){return(kr=si(e,Or))&&wo},Mr=function(e,t){return console.warn(`Invalid property`,e,`set to`,t,`Missing plugin? gsap.registerPlugin()`)},Nr=function(e,t){return!t&&console.warn(e)},Pr=function(e,t){return e&&(Or[e]=t)&&kr&&(kr[e]=t)||Or},Fr=function(){return 0},Ir={suppressEvents:!0,isStart:!0,kill:!1},Lr={suppressEvents:!0,kill:!1},Rr={suppressEvents:!0},zr={},Br=[],Vr={},Hr,Ur={},Wr={},Gr=30,Kr=[],qr=``,Jr=function(e){var t=e[0],n,r;if(ur(t)||K(t)||(e=[e]),!(n=(t._gsap||{}).harness)){for(r=Kr.length;r--&&!Kr[r].targetTest(t););n=Kr[r]}for(r=e.length;r--;)e[r]&&(e[r]._gsap||(e[r]._gsap=new Pa(e[r],n)))||e.splice(r,1);return e},Yr=function(e){return e._gsap||Jr(Wi(e))[0]._gsap},Xr=function(e,t,n){return(n=e[t])&&K(n)?e[t]():lr(n)&&e.getAttribute&&e.getAttribute(t)||n},Zr=function(e,t){return(e=e.split(`,`)).forEach(t)||e},J=function(e){return Math.round(e*1e5)/1e5||0},Y=function(e){return Math.round(e*1e7)/1e7||0},Qr=function(e,t){var n=t.charAt(0),r=parseFloat(t.substr(2));return e=parseFloat(e),n===`+`?e+r:n===`-`?e-r:n===`*`?e*r:e/r},$r=function(e,t){for(var n=t.length,r=0;e.indexOf(t[r])<0&&++r<n;);return r<n},ei=function(){var e=Br.length,t=Br.slice(0),n,r;for(Vr={},Br.length=0,n=0;n<e;n++)r=t[n],r&&r._lazy&&(r.render(r._lazy[0],r._lazy[1],!0)._lazy=0)},ti=function(e){return!!(e._initted||e._startAt||e.add)},ni=function(e,t,n,r){Br.length&&!er&&ei(),e.render(t,n,r||!!(er&&t<0&&ti(e))),Br.length&&!er&&ei()},ri=function(e){var t=parseFloat(e);return(t||t===0)&&(e+``).match(Cr).length<2?t:G(e)?e.trim():e},ii=function(e){return e},ai=function(e,t){for(var n in t)n in e||(e[n]=t[n]);return e},oi=function(e){return function(t,n){for(var r in n)r in t||r===`duration`&&e||r===`ease`||(t[r]=n[r])}},si=function(e,t){for(var n in t)e[n]=t[n];return e},ci=function e(t,n){for(var r in n)r!==`__proto__`&&r!==`constructor`&&r!==`prototype`&&(t[r]=ur(n[r])?e(t[r]||(t[r]={}),n[r]):n[r]);return t},li=function(e,t){var n={},r;for(r in e)r in t||(n[r]=e[r]);return n},ui=function(e){var t=e.parent||q,n=e.keyframes?oi(hr(e.keyframes)):ai;if(dr(e.inherit))for(;t;)n(e,t.vars.defaults),t=t.parent||t._dp;return e},di=function(e,t){for(var n=e.length,r=n===t.length;r&&n--&&e[n]===t[n];);return n<0},fi=function(e,t,n,r,i){n===void 0&&(n=`_first`),r===void 0&&(r=`_last`);var a=e[r],o;if(i)for(o=t[i];a&&a[i]>o;)a=a._prev;return a?(t._next=a._next,a._next=t):(t._next=e[n],e[n]=t),t._next?t._next._prev=t:e[r]=t,t._prev=a,t.parent=t._dp=e,t},pi=function(e,t,n,r){n===void 0&&(n=`_first`),r===void 0&&(r=`_last`);var i=t._prev,a=t._next;i?i._next=a:e[n]===t&&(e[n]=a),a?a._prev=i:e[r]===t&&(e[r]=i),t._next=t._prev=t.parent=null},mi=function(e,t){e.parent&&(!t||e.parent.autoRemoveChildren)&&e.parent.remove&&e.parent.remove(e),e._act=0},hi=function(e,t){if(e&&(!t||t._end>e._dur||t._start<0))for(var n=e;n;)n._dirty=1,n=n.parent;return e},gi=function(e){for(var t=e.parent;t&&t.parent;)t._dirty=1,t.totalDuration(),t=t.parent;return e},_i=function(e,t,n,r){return e._startAt&&(er?e._startAt.revert(Lr):e.vars.immediateRender&&!e.vars.autoRevert||e._startAt.render(t,!0,r))},vi=function e(t){return!t||t._ts&&e(t.parent)},yi=function(e){return e._repeat?bi(e._tTime,e=e.duration()+e._rDelay)*e:0},bi=function(e,t){var n=Math.floor(e=Y(e/t));return e&&n===e?n-1:n},xi=function(e,t){return(e-t._start)*t._ts+(t._ts>=0?0:t._dirty?t.totalDuration():t._tDur)},Si=function(e){return e._end=Y(e._start+(e._tDur/Math.abs(e._ts||e._rts||W)||0))},Ci=function(e,t){var n=e._dp;return n&&n.smoothChildTiming&&e._ts&&(e._start=Y(n._time-(e._ts>0?t/e._ts:((e._dirty?e.totalDuration():e._tDur)-t)/-e._ts)),Si(e),n._dirty||hi(n,e)),e},wi=function(e,t){var n;if((t._time||!t._dur&&t._initted||t._start<e._time&&(t._dur||!t.add))&&(n=xi(e.rawTime(),t),(!t._dur||Ri(0,t.totalDuration(),n)-t._tTime>W)&&t.render(n,!0)),hi(e,t)._dp&&e._initted&&e._time>=e._dur&&e._ts){if(e._dur<e.duration())for(n=e;n._dp;)n.rawTime()>=0&&n.totalTime(n._tTime),n=n._dp;e._zTime=-W}},Ti=function(e,t,n,r){return t.parent&&mi(t),t._start=Y((cr(n)?n:n||e!==q?Fi(e,n,t):e._time)+t._delay),t._end=Y(t._start+(t.totalDuration()/Math.abs(t.timeScale())||0)),fi(e,t,`_first`,`_last`,e._sort?`_start`:0),ki(t)||(e._recent=t),r||wi(e,t),e._ts<0&&Ci(e,e._tTime),e},Ei=function(e,t){return(Or.ScrollTrigger||Mr(`scrollTrigger`,t))&&Or.ScrollTrigger.create(t,e)},Di=function(e,t,n,r,i){if(Ua(e,t,i),!e._initted)return 1;if(!n&&e._pt&&!er&&(e._dur&&e.vars.lazy!==!1||!e._dur&&e.vars.lazy)&&Hr!==xa.frame)return Br.push(e),e._lazy=[i,r],1},Oi=function e(t){var n=t.parent;return n&&n._ts&&n._initted&&!n._lock&&(n.rawTime()<0||e(n))},ki=function(e){var t=e.data;return t===`isFromStart`||t===`isStart`},Ai=function(e,t,n,r){var i=e.ratio,a=t<0||!t&&(!e._start&&Oi(e)&&!(!e._initted&&ki(e))||(e._ts<0||e._dp._ts<0)&&!ki(e))?0:1,o=e._rDelay,s=0,c,l,u;if(o&&e._repeat&&(s=Ri(0,e._tDur,t),l=bi(s,o),e._yoyo&&l&1&&(a=1-a),l!==bi(e._tTime,o)&&(i=1-a,e.vars.repeatRefresh&&e._initted&&e.invalidate())),a!==i||er||r||e._zTime===W||!t&&e._zTime){if(!e._initted&&Di(e,t,r,n,s))return;for(u=e._zTime,e._zTime=t||(n?W:0),n||=t&&!u,e.ratio=a,e._from&&(a=1-a),e._time=0,e._tTime=s,c=e._pt;c;)c.r(a,c.d),c=c._next;t<0&&_i(e,t,n,!0),e._onUpdate&&!n&&sa(e,`onUpdate`),s&&e._repeat&&!n&&e.parent&&sa(e,`onRepeat`),(t>=e._tDur||t<0)&&e.ratio===a&&(a&&mi(e,1),!n&&!er&&(sa(e,a?`onComplete`:`onReverseComplete`,!0),e._prom&&e._prom()))}else e._zTime||=t},ji=function(e,t,n){var r;if(n>t)for(r=e._first;r&&r._start<=n;){if(r.data===`isPause`&&r._start>t)return r;r=r._next}else for(r=e._last;r&&r._start>=n;){if(r.data===`isPause`&&r._start<t)return r;r=r._prev}},Mi=function(e,t,n,r){var i=e._repeat,a=Y(t)||0,o=e._tTime/e._tDur;return o&&!r&&(e._time*=a/e._dur),e._dur=a,e._tDur=i?i<0?1e10:Y(a*(i+1)+e._rDelay*i):a,o>0&&!r&&Ci(e,e._tTime=e._tDur*o),e.parent&&Si(e),n||hi(e.parent,e),e},Ni=function(e){return e instanceof Ia?hi(e):Mi(e,e._dur)},Pi={_start:0,endTime:Fr,totalDuration:Fr},Fi=function e(t,n,r){var i=t.labels,a=t._recent||Pi,o=t.duration()>=tr?a.endTime(!1):t._dur,s,c,l;return G(n)&&(isNaN(n)||n in i)?(c=n.charAt(0),l=n.substr(-1)===`%`,s=n.indexOf(`=`),c===`<`||c===`>`?(s>=0&&(n=n.replace(/=/,``)),(c===`<`?a._start:a.endTime(a._repeat>=0))+(parseFloat(n.substr(1))||0)*(l?(s<0?a:r).totalDuration()/100:1)):s<0?(n in i||(i[n]=o),i[n]):(c=parseFloat(n.charAt(s-1)+n.substr(s+1)),l&&r&&(c=c/100*(hr(r)?r[0]:r).totalDuration()),s>1?e(t,n.substr(0,s-1),r)+c:o+c)):n==null?o:+n},Ii=function(e,t,n){var r=cr(t[1]),i=(r?2:1)+(e<2?0:1),a=t[i],o,s;if(r&&(a.duration=t[1]),a.parent=n,e){for(o=a,s=n;s&&!(`immediateRender`in o);)o=s.vars.defaults||{},s=dr(s.vars.inherit)&&s.parent;a.immediateRender=dr(o.immediateRender),e<2?a.runBackwards=1:a.startAt=t[i-1]}return new Q(t[0],a,t[i+1])},Li=function(e,t){return e||e===0?t(e):t},Ri=function(e,t,n){return n<e?e:n>t?t:n},zi=function(e,t){return!G(e)||!(t=wr.exec(e))?``:t[1]},Bi=function(e,t,n){return Li(n,function(n){return Ri(e,t,n)})},Vi=[].slice,Hi=function(e,t){return e&&ur(e)&&`length`in e&&(!t&&!e.length||e.length-1 in e&&ur(e[0]))&&!e.nodeType&&e!==Tr},Ui=function(e,t,n){return n===void 0&&(n=[]),e.forEach(function(e){var r;return G(e)&&!t||Hi(e,1)?(r=n).push.apply(r,Wi(e)):n.push(e)})||n},Wi=function(e,t,n){return U&&!t&&U.selector?U.selector(e):G(e)&&!n&&(Er||!Sa())?Vi.call((t||Dr).querySelectorAll(e),0):hr(e)?Ui(e,n):Hi(e)?Vi.call(e,0):e?[e]:[]},Gi=function(e){return e=Wi(e)[0]||Nr(`Invalid scope`)||{},function(t){var n=e.current||e.nativeElement||e;return Wi(t,n.querySelectorAll?n:n===e?Nr(`Invalid scope`)||Dr.createElement(`div`):e)}},Ki=function(e){return e.sort(function(){return .5-Math.random()})},qi=function(e){if(K(e))return e;var t=ur(e)?e:{each:e},n=ka(t.ease),r=t.from||0,i=parseFloat(t.base)||0,a={},o=r>0&&r<1,s=isNaN(r)||o,c=t.axis,l=r,u=r;return G(r)?l=u={center:.5,edges:.5,end:1}[r]||0:!o&&s&&(l=r[0],u=r[1]),function(e,o,d){var f=(d||t).length,p=a[f],m,h,g,_,v,y,b,x,S;if(!p){if(S=t.grid===`auto`?0:(t.grid||[1,tr])[1],!S){for(b=-tr;b<(b=d[S++].getBoundingClientRect().left)&&S<f;);S<f&&S--}for(p=a[f]=[],m=s?Math.min(S,f)*l-.5:r%S,h=S===tr?0:s?f*u/S-.5:r/S|0,b=0,x=tr,y=0;y<f;y++)g=y%S-m,_=h-(y/S|0),p[y]=v=c?Math.abs(c===`y`?_:g):ar(g*g+_*_),v>b&&(b=v),v<x&&(x=v);r===`random`&&Ki(p),p.max=b-x,p.min=x,p.v=f=(parseFloat(t.amount)||parseFloat(t.each)*(S>f?f-1:c?c===`y`?f/S:S:Math.max(S,f/S))||0)*(r===`edges`?-1:1),p.b=f<0?i-f:i,p.u=zi(t.amount||t.each)||0,n=n&&f<0?Oa(n):n}return f=(p[e]-p.min)/p.max||0,Y(p.b+(n?n(f):f)*p.v)+p.u}},Ji=function(e){var t=10**((e+``).split(`.`)[1]||``).length;return function(n){var r=Y(Math.round(parseFloat(n)/e)*e*t);return(r-r%1)/t+(cr(n)?0:zi(n))}},Yi=function(e,t){var n=hr(e),r,i;return!n&&ur(e)&&(r=n=e.radius||tr,e.values?(e=Wi(e.values),(i=!cr(e[0]))&&(r*=r)):e=Ji(e.increment)),Li(t,n?K(e)?function(t){return i=e(t),Math.abs(i-t)<=r?i:t}:function(t){for(var n=parseFloat(i?t.x:t),a=parseFloat(i?t.y:0),o=tr,s=0,c=e.length,l,u;c--;)i?(l=e[c].x-n,u=e[c].y-a,l=l*l+u*u):l=Math.abs(e[c]-n),l<o&&(o=l,s=c);return s=!r||o<=r?e[s]:t,i||s===t||cr(t)?s:s+zi(t)}:Ji(e))},Xi=function(e,t,n,r){return Li(hr(e)?!t:n===!0?!!(n=0):!r,function(){return hr(e)?e[~~(Math.random()*e.length)]:(n||=1e-5)&&(r=n<1?10**((n+``).length-2):1)&&Math.floor(Math.round((e-n/2+Math.random()*(t-e+n*.99))/n)*n*r)/r})},Zi=function(){var e=[...arguments];return function(t){return e.reduce(function(e,t){return t(e)},t)}},Qi=function(e,t){return function(n){return e(parseFloat(n))+(t||zi(n))}},$i=function(e,t,n){return ia(e,t,0,1,n)},ea=function(e,t,n){return Li(n,function(n){return e[~~t(n)]})},ta=function e(t,n,r){var i=n-t;return hr(t)?ea(t,e(0,t.length),n):Li(r,function(e){return(i+(e-t)%i)%i+t})},na=function e(t,n,r){var i=n-t,a=i*2;return hr(t)?ea(t,e(0,t.length-1),n):Li(r,function(e){return e=(a+(e-t)%a)%a||0,t+(e>i?a-e:e)})},ra=function(e){return e.replace(gr,function(e){var t=e.indexOf(`[`)+1,n=e.substring(t||7,t?e.indexOf(`]`):e.length-1).split(_r);return Xi(t?n:+n[0],t?0:+n[1],+n[2]||1e-5)})},ia=function(e,t,n,r,i){var a=t-e,o=r-n;return Li(i,function(t){return n+((t-e)/a*o||0)})},aa=function e(t,n,r,i){var a=isNaN(t+n)?0:function(e){return(1-e)*t+e*n};if(!a){var o=G(t),s={},c,l,u,d,f;if(r===!0&&(i=1)&&(r=null),o)t={p:t},n={p:n};else if(hr(t)&&!hr(n)){for(u=[],d=t.length,f=d-2,l=1;l<d;l++)u.push(e(t[l-1],t[l]));d--,a=function(e){e*=d;var t=Math.min(f,~~e);return u[t](e-t)},r=n}else i||(t=si(hr(t)?[]:{},t));if(!u){for(c in n)Ra.call(s,t,c,`get`,n[c]);a=function(e){return io(e,s)||(o?t.p:t)}}}return Li(r,a)},oa=function(e,t,n){var r=e.labels,i=tr,a,o,s;for(a in r)o=r[a]-t,o<0==!!n&&o&&i>(o=Math.abs(o))&&(s=a,i=o);return s},sa=function(e,t,n){var r=e.vars,i=r[t],a=U,o=e._ctx,s,c,l;if(i)return s=r[t+`Params`],c=r.callbackScope||e,n&&Br.length&&ei(),o&&(U=o),l=s?i.apply(c,s):i.call(c),U=a,l},ca=function(e){return mi(e),e.scrollTrigger&&e.scrollTrigger.kill(!!er),e.progress()<1&&sa(e,`onInterrupt`),e},la,ua=[],da=function(e){if(e)if(e=!e.name&&e.default||e,fr()||e.headless){var t=e.name,n=K(e),r=t&&!n&&e.init?function(){this._props=[]}:e,i={init:Fr,render:io,add:Ra,kill:oo,modifier:ao,rawVars:0},a={targetTest:0,get:0,getSetter:eo,aliases:{},register:0};if(Sa(),e!==r){if(Ur[t])return;ai(r,ai(li(e,i),a)),si(r.prototype,si(i,li(e,a))),Ur[r.prop=t]=r,e.targetTest&&(Kr.push(r),zr[t]=1),t=(t===`css`?`CSS`:t.charAt(0).toUpperCase()+t.substr(1))+`Plugin`}Pr(t,r),e.register&&e.register(wo,r,lo)}else ua.push(e)},X=255,fa={aqua:[0,X,X],lime:[0,X,0],silver:[192,192,192],black:[0,0,0],maroon:[128,0,0],teal:[0,128,128],blue:[0,0,X],navy:[0,0,128],white:[X,X,X],olive:[128,128,0],yellow:[X,X,0],orange:[X,165,0],gray:[128,128,128],purple:[128,0,128],green:[0,128,0],red:[X,0,0],pink:[X,192,203],cyan:[0,X,X],transparent:[X,X,X,0]},pa=function(e,t,n){return e+=e<0?1:e>1?-1:0,(e*6<1?t+(n-t)*e*6:e<.5?n:e*3<2?t+(n-t)*(2/3-e)*6:t)*X+.5|0},ma=function(e,t,n){var r=e?cr(e)?[e>>16,e>>8&X,e&X]:0:fa.black,i,a,o,s,c,l,u,d,f,p;if(!r){if(e.substr(-1)===`,`&&(e=e.substr(0,e.length-1)),fa[e])r=fa[e];else if(e.charAt(0)===`#`){if(e.length<6&&(i=e.charAt(1),a=e.charAt(2),o=e.charAt(3),e=`#`+i+i+a+a+o+o+(e.length===5?e.charAt(4)+e.charAt(4):``)),e.length===9)return r=parseInt(e.substr(1,6),16),[r>>16,r>>8&X,r&X,parseInt(e.substr(7),16)/255];e=parseInt(e.substr(1),16),r=[e>>16,e>>8&X,e&X]}else if(e.substr(0,3)===`hsl`){if(r=p=e.match(vr),!t)s=r[0]%360/360,c=r[1]/100,l=r[2]/100,a=l<=.5?l*(c+1):l+c-l*c,i=l*2-a,r.length>3&&(r[3]*=1),r[0]=pa(s+1/3,i,a),r[1]=pa(s,i,a),r[2]=pa(s-1/3,i,a);else if(~e.indexOf(`=`))return r=e.match(yr),n&&r.length<4&&(r[3]=1),r}else r=e.match(vr)||fa.transparent;r=r.map(Number)}return t&&!p&&(i=r[0]/X,a=r[1]/X,o=r[2]/X,u=Math.max(i,a,o),d=Math.min(i,a,o),l=(u+d)/2,u===d?s=c=0:(f=u-d,c=l>.5?f/(2-u-d):f/(u+d),s=u===i?(a-o)/f+(a<o?6:0):u===a?(o-i)/f+2:(i-a)/f+4,s*=60),r[0]=~~(s+.5),r[1]=~~(c*100+.5),r[2]=~~(l*100+.5)),n&&r.length<4&&(r[3]=1),r},ha=function(e){var t=[],n=[],r=-1;return e.split(_a).forEach(function(e){var i=e.match(br)||[];t.push.apply(t,i),n.push(r+=i.length+1)}),t.c=n,t},ga=function(e,t,n){var r=``,i=(e+r).match(_a),a=t?`hsla(`:`rgba(`,o=0,s,c,l,u;if(!i)return e;if(i=i.map(function(e){return(e=ma(e,t,1))&&a+(t?e[0]+`,`+e[1]+`%,`+e[2]+`%,`+e[3]:e.join(`,`))+`)`}),n&&(l=ha(e),s=n.c,s.join(r)!==l.c.join(r)))for(c=e.replace(_a,`1`).split(br),u=c.length-1;o<u;o++)r+=c[o]+(~s.indexOf(o)?i.shift()||a+`0,0,0,0)`:(l.length?l:i.length?i:n).shift());if(!c)for(c=e.split(_a),u=c.length-1;o<u;o++)r+=c[o]+i[o];return r+c[u]},_a=function(){var e=`(?:\\b(?:(?:rgb|rgba|hsl|hsla)\\(.+?\\))|\\B#(?:[0-9a-f]{3,4}){1,2}\\b`,t;for(t in fa)e+=`|`+t+`\\b`;return RegExp(e+`)`,`gi`)}(),va=/hsl[a]?\(/,ya=function(e){var t=e.join(` `),n;if(_a.lastIndex=0,_a.test(t))return n=va.test(t),e[1]=ga(e[1],n),e[0]=ga(e[0],n,ha(e[1])),!0},ba,xa=function(){var e=Date.now,t=500,n=33,r=e(),i=r,a=1e3/240,o=a,s=[],c,l,u,d,f,p,m=function u(m){var h=e()-i,g=m===!0,_,v,y,b;if((h>t||h<0)&&(r+=h-n),i+=h,y=i-r,_=y-o,(_>0||g)&&(b=++d.frame,f=y-d.time*1e3,d.time=y/=1e3,o+=_+(_>=a?4:a-_),v=1),g||(c=l(u)),v)for(p=0;p<s.length;p++)s[p](y,f,b,m)};return d={time:0,frame:0,tick:function(){m(!0)},deltaRatio:function(e){return f/(1e3/(e||60))},wake:function(){Ar&&(!Er&&fr()&&(Tr=Er=window,Dr=Tr.document||{},Or.gsap=wo,(Tr.gsapVersions||=[]).push(wo.version),jr(kr||Tr.GreenSockGlobals||!Tr.gsap&&Tr||{}),ua.forEach(da)),u=typeof requestAnimationFrame<`u`&&requestAnimationFrame,c&&d.sleep(),l=u||function(e){return setTimeout(e,o-d.time*1e3+1|0)},ba=1,m(2))},sleep:function(){(u?cancelAnimationFrame:clearTimeout)(c),ba=0,l=Fr},lagSmoothing:function(e,r){t=e||1/0,n=Math.min(r||33,t)},fps:function(e){a=1e3/(e||240),o=d.time*1e3+a},add:function(e,t,n){var r=t?function(t,n,i,a){e(t,n,i,a),d.remove(r)}:e;return d.remove(e),s[n?`unshift`:`push`](r),Sa(),r},remove:function(e,t){~(t=s.indexOf(e))&&s.splice(t,1)&&p>=t&&p--},_listeners:s},d}(),Sa=function(){return!ba&&xa.wake()},Z={},Ca=/^[\d.\-M][\d.\-,\s]/,wa=/["']/g,Ta=function(e){for(var t={},n=e.substr(1,e.length-3).split(`:`),r=n[0],i=1,a=n.length,o,s,c;i<a;i++)s=n[i],o=i===a-1?s.length:s.lastIndexOf(`,`),c=s.substr(0,o),t[r]=isNaN(c)?c.replace(wa,``).trim():+c,r=s.substr(o+1).trim();return t},Ea=function(e){var t=e.indexOf(`(`)+1,n=e.indexOf(`)`),r=e.indexOf(`(`,t);return e.substring(t,~r&&r<n?e.indexOf(`)`,n+1):n)},Da=function(e){var t=(e+``).split(`(`),n=Z[t[0]];return n&&t.length>1&&n.config?n.config.apply(null,~e.indexOf(`{`)?[Ta(t[1])]:Ea(e).split(`,`).map(ri)):Z._CE&&Ca.test(e)?Z._CE(``,e):n},Oa=function(e){return function(t){return 1-e(1-t)}},ka=function(e,t){return e&&(K(e)?e:Z[e]||Da(e))||t},Aa=function(e,t,n,r){n===void 0&&(n=function(e){return 1-t(1-e)}),r===void 0&&(r=function(e){return e<.5?t(e*2)/2:1-t((1-e)*2)/2});var i={easeIn:t,easeOut:n,easeInOut:r},a;return Zr(e,function(e){for(var t in Z[e]=Or[e]=i,Z[a=e.toLowerCase()]=n,i)Z[a+(t===`easeIn`?`.in`:t===`easeOut`?`.out`:`.inOut`)]=Z[e+`.`+t]=i[t]}),i},ja=function(e){return function(t){return t<.5?(1-e(1-t*2))/2:.5+e((t-.5)*2)/2}},Ma=function e(t,n,r){var i=n>=1?n:1,a=(r||(t?.3:.45))/(n<1?n:1),o=a/nr*(Math.asin(1/i)||0),s=function(e){return e===1?1:i*2**(-10*e)*sr((e-o)*a)+1},c=t===`out`?s:t===`in`?function(e){return 1-s(1-e)}:ja(s);return a=nr/a,c.config=function(n,r){return e(t,n,r)},c},Na=function e(t,n){n===void 0&&(n=1.70158);var r=function(e){return e?--e*e*((n+1)*e+n)+1:0},i=t===`out`?r:t===`in`?function(e){return 1-r(1-e)}:ja(r);return i.config=function(n){return e(t,n)},i};Zr(`Linear,Quad,Cubic,Quart,Quint,Strong`,function(e,t){var n=t<5?t+1:t;Aa(e+`,Power`+(n-1),t?function(e){return e**+n}:function(e){return e},function(e){return 1-(1-e)**n},function(e){return e<.5?(e*2)**n/2:1-((1-e)*2)**n/2})}),Z.Linear.easeNone=Z.none=Z.Linear.easeIn,Aa(`Elastic`,Ma(`in`),Ma(`out`),Ma()),(function(e,t){var n=1/t,r=2*n,i=2.5*n,a=function(a){return a<n?e*a*a:a<r?e*(a-1.5/t)**2+.75:a<i?e*(a-=2.25/t)*a+.9375:e*(a-2.625/t)**2+.984375};Aa(`Bounce`,function(e){return 1-a(1-e)},a)})(7.5625,2.75),Aa(`Expo`,function(e){return 2**(10*(e-1))*e+e*e*e*e*e*e*(1-e)}),Aa(`Circ`,function(e){return-(ar(1-e*e)-1)}),Aa(`Sine`,function(e){return e===1?1:-or(e*rr)+1}),Aa(`Back`,Na(`in`),Na(`out`),Na()),Z.SteppedEase=Z.steps=Or.SteppedEase={config:function(e,t){e===void 0&&(e=1);var n=1/e,r=e+ +!t,i=+!!t,a=1-W;return function(e){return((r*Ri(0,a,e)|0)+i)*n}}},Qn.ease=Z[`quad.out`],Zr(`onComplete,onUpdate,onStart,onRepeat,onReverseComplete,onInterrupt`,function(e){return qr+=e+`,`+e+`Params,`});var Pa=function(e,t){this.id=ir++,e._gsap=this,this.target=e,this.harness=t,this.get=t?t.get:Xr,this.set=t?t.getSetter:eo},Fa=function(){function e(e){this.vars=e,this._delay=+e.delay||0,(this._repeat=e.repeat===1/0?-2:e.repeat||0)&&(this._rDelay=e.repeatDelay||0,this._yoyo=!!e.yoyo||!!e.yoyoEase),this._ts=1,Mi(this,+e.duration,1,1),this.data=e.data,U&&(this._ctx=U,U.data.push(this)),ba||xa.wake()}var t=e.prototype;return t.delay=function(e){return e||e===0?(this.parent&&this.parent.smoothChildTiming&&this.startTime(this._start+e-this._delay),this._delay=e,this):this._delay},t.duration=function(e){return arguments.length?this.totalDuration(this._repeat>0?e+(e+this._rDelay)*this._repeat:e):this.totalDuration()&&this._dur},t.totalDuration=function(e){return arguments.length?(this._dirty=0,Mi(this,this._repeat<0?e:(e-this._repeat*this._rDelay)/(this._repeat+1))):this._tDur},t.totalTime=function(e,t){if(Sa(),!arguments.length)return this._tTime;var n=this._dp;if(n&&n.smoothChildTiming&&this._ts){for(Ci(this,e),!n._dp||n.parent||wi(n,this);n&&n.parent;)n.parent._time!==n._start+(n._ts>=0?n._tTime/n._ts:(n.totalDuration()-n._tTime)/-n._ts)&&n.totalTime(n._tTime,!0),n=n.parent;!this.parent&&this._dp.autoRemoveChildren&&(this._ts>0&&e<this._tDur||this._ts<0&&e>0||!this._tDur&&!e)&&Ti(this._dp,this,this._start-this._delay)}return(this._tTime!==e||!this._dur&&!t||this._initted&&Math.abs(this._zTime)===W||!this._initted&&this._dur&&e||!e&&!this._initted&&(this.add||this._ptLookup))&&(this._ts||(this._pTime=e),ni(this,e,t)),this},t.time=function(e,t){return arguments.length?this.totalTime(Math.min(this.totalDuration(),e+yi(this))%(this._dur+this._rDelay)||(e?this._dur:0),t):this._time},t.totalProgress=function(e,t){return arguments.length?this.totalTime(this.totalDuration()*e,t):this.totalDuration()?Math.min(1,this._tTime/this._tDur):this.rawTime()>=0&&this._initted?1:0},t.progress=function(e,t){return arguments.length?this.totalTime(this.duration()*(this._yoyo&&!(this.iteration()&1)?1-e:e)+yi(this),t):this.duration()?Math.min(1,this._time/this._dur):+(this.rawTime()>0)},t.iteration=function(e,t){var n=this.duration()+this._rDelay;return arguments.length?this.totalTime(this._time+(e-1)*n,t):this._repeat?bi(this._tTime,n)+1:1},t.timeScale=function(e,t){if(!arguments.length)return this._rts===-W?0:this._rts;if(this._rts===e)return this;var n=this.parent&&this._ts?xi(this.parent._time,this):this._tTime;return this._rts=+e||0,this._ts=this._ps||e===-W?0:this._rts,this.totalTime(Ri(-Math.abs(this._delay),this.totalDuration(),n),t!==!1),Si(this),gi(this)},t.paused=function(e){return arguments.length?(this._ps!==e&&(this._ps=e,e?(this._pTime=this._tTime||Math.max(-this._delay,this.rawTime()),this._ts=this._act=0):(Sa(),this._ts=this._rts,this.totalTime(this.parent&&!this.parent.smoothChildTiming?this.rawTime():this._tTime||this._pTime,this.progress()===1&&Math.abs(this._zTime)!==W&&(this._tTime-=W)))),this):this._ps},t.startTime=function(e){if(arguments.length){this._start=Y(e);var t=this.parent||this._dp;return t&&(t._sort||!this.parent)&&Ti(t,this,this._start-this._delay),this}return this._start},t.endTime=function(e){return this._start+(dr(e)?this.totalDuration():this.duration())/Math.abs(this._ts||1)},t.rawTime=function(e){var t=this.parent||this._dp;return t?e&&(!this._ts||this._repeat&&this._time&&this.totalProgress()<1)?this._tTime%(this._dur+this._rDelay):this._ts?xi(t.rawTime(e),this):this._tTime:this._tTime},t.revert=function(e){e===void 0&&(e=Rr);var t=er;return er=e,ti(this)&&(this.timeline&&this.timeline.revert(e),this.totalTime(-.01,e.suppressEvents)),this.data!==`nested`&&e.kill!==!1&&this.kill(),er=t,this},t.globalTime=function(e){for(var t=this,n=arguments.length?e:t.rawTime();t;)n=t._start+n/(Math.abs(t._ts)||1),t=t._dp;return!this.parent&&this._sat?this._sat.globalTime(e):n},t.repeat=function(e){return arguments.length?(this._repeat=e===1/0?-2:e,Ni(this)):this._repeat===-2?1/0:this._repeat},t.repeatDelay=function(e){if(arguments.length){var t=this._time;return this._rDelay=e,Ni(this),t?this.time(t):this}return this._rDelay},t.yoyo=function(e){return arguments.length?(this._yoyo=e,this):this._yoyo},t.seek=function(e,t){return this.totalTime(Fi(this,e),dr(t))},t.restart=function(e,t){return this.play().totalTime(e?-this._delay:0,dr(t)),this._dur||(this._zTime=-W),this},t.play=function(e,t){return e!=null&&this.seek(e,t),this.reversed(!1).paused(!1)},t.reverse=function(e,t){return e!=null&&this.seek(e||this.totalDuration(),t),this.reversed(!0).paused(!1)},t.pause=function(e,t){return e!=null&&this.seek(e,t),this.paused(!0)},t.resume=function(){return this.paused(!1)},t.reversed=function(e){return arguments.length?(!!e!==this.reversed()&&this.timeScale(-this._rts||(e?-W:0)),this):this._rts<0},t.invalidate=function(){return this._initted=this._act=0,this._zTime=-W,this},t.isActive=function(){var e=this.parent||this._dp,t=this._start,n;return!!(!e||this._ts&&this._initted&&e.isActive()&&(n=e.rawTime(!0))>=t&&n<this.endTime(!0)-W)},t.eventCallback=function(e,t,n){var r=this.vars;return arguments.length>1?(t?(r[e]=t,n&&(r[e+`Params`]=n),e===`onUpdate`&&(this._onUpdate=t)):delete r[e],this):r[e]},t.then=function(e){var t=this,n=t._prom;return new Promise(function(r){var i=K(e)?e:ii,a=function(){var e=t.then;t.then=null,n&&n(),K(i)&&(i=i(t))&&(i.then||i===t)&&(t.then=e),r(i),t.then=e};t._initted&&t.totalProgress()===1&&t._ts>=0||!t._tTime&&t._ts<0?a():t._prom=a})},t.kill=function(){ca(this)},e}();ai(Fa.prototype,{_time:0,_start:0,_end:0,_tTime:0,_tDur:0,_dirty:0,_repeat:0,_yoyo:!1,parent:null,_initted:!1,_rDelay:0,_ts:1,_dp:0,ratio:0,_zTime:-W,_prom:0,_ps:!1,_rts:1});var Ia=function(e){Xn(t,e);function t(t,n){var r;return t===void 0&&(t={}),r=e.call(this,t)||this,r.labels={},r.smoothChildTiming=!!t.smoothChildTiming,r.autoRemoveChildren=!!t.autoRemoveChildren,r._sort=dr(t.sortChildren),q&&Ti(t.parent||q,Yn(r),n),t.reversed&&r.reverse(),t.paused&&r.paused(!0),t.scrollTrigger&&Ei(Yn(r),t.scrollTrigger),r}var n=t.prototype;return n.to=function(e,t,n){return Ii(0,arguments,this),this},n.from=function(e,t,n){return Ii(1,arguments,this),this},n.fromTo=function(e,t,n,r){return Ii(2,arguments,this),this},n.set=function(e,t,n){return t.duration=0,t.parent=this,ui(t).repeatDelay||(t.repeat=0),t.immediateRender=!!t.immediateRender,new Q(e,t,Fi(this,n),1),this},n.call=function(e,t,n){return Ti(this,Q.delayedCall(0,e,t),n)},n.staggerTo=function(e,t,n,r,i,a,o){return n.duration=t,n.stagger=n.stagger||r,n.onComplete=a,n.onCompleteParams=o,n.parent=this,new Q(e,n,Fi(this,i)),this},n.staggerFrom=function(e,t,n,r,i,a,o){return n.runBackwards=1,ui(n).immediateRender=dr(n.immediateRender),this.staggerTo(e,t,n,r,i,a,o)},n.staggerFromTo=function(e,t,n,r,i,a,o,s){return r.startAt=n,ui(r).immediateRender=dr(r.immediateRender),this.staggerTo(e,t,r,i,a,o,s)},n.render=function(e,t,n){var r=this._time,i=this._dirty?this.totalDuration():this._tDur,a=this._dur,o=e<=0?0:Y(e),s=this._zTime<0!=e<0&&(this._initted||!a),c,l,u,d,f,p,m,h,g,_,v,y;if(this!==q&&o>i&&e>=0&&(o=i),o!==this._tTime||n||s){if(r!==this._time&&a&&(o+=this._time-r,e+=this._time-r),c=o,g=this._start,h=this._ts,p=!h,s&&(a||(r=this._zTime),(e||!t)&&(this._zTime=e)),this._repeat){if(v=this._yoyo,f=a+this._rDelay,this._repeat<-1&&e<0)return this.totalTime(f*100+e,t,n);if(c=Y(o%f),o===i?(d=this._repeat,c=a):(_=Y(o/f),d=~~_,d&&d===_&&(c=a,d--),c>a&&(c=a)),_=bi(this._tTime,f),!r&&this._tTime&&_!==d&&this._tTime-_*f-this._dur<=0&&(_=d),v&&d&1&&(c=a-c,y=1),d!==_&&!this._lock){var b=v&&_&1,x=b===(v&&d&1);if(d<_&&(b=!b),r=b?0:o%a?a:o,this._lock=1,this.render(r||(y?0:Y(d*f)),t,!a)._lock=0,this._tTime=o,!t&&this.parent&&sa(this,`onRepeat`),this.vars.repeatRefresh&&!y&&(this.invalidate()._lock=1,_=d),r&&r!==this._time||p!==!this._ts||this.vars.onRepeat&&!this.parent&&!this._act||(a=this._dur,i=this._tDur,x&&(this._lock=2,r=b?a:-1e-4,this.render(r,!0),this.vars.repeatRefresh&&!y&&this.invalidate()),this._lock=0,!this._ts&&!p))return this}}if(this._hasPause&&!this._forcing&&this._lock<2&&(m=ji(this,Y(r),Y(c)),m&&(o-=c-(c=m._start))),this._tTime=o,this._time=c,this._act=!!h,this._initted||(this._onUpdate=this.vars.onUpdate,this._initted=1,this._zTime=e,r=0),!r&&o&&a&&!t&&!_&&(sa(this,`onStart`),this._tTime!==o))return this;if(c>=r&&e>=0)for(l=this._first;l;){if(u=l._next,(l._act||c>=l._start)&&l._ts&&m!==l){if(l.parent!==this)return this.render(e,t,n);if(l.render(l._ts>0?(c-l._start)*l._ts:(l._dirty?l.totalDuration():l._tDur)+(c-l._start)*l._ts,t,n),c!==this._time||!this._ts&&!p){m=0,u&&(o+=this._zTime=-W);break}}l=u}else{l=this._last;for(var S=e<0?e:c;l;){if(u=l._prev,(l._act||S<=l._end)&&l._ts&&m!==l){if(l.parent!==this)return this.render(e,t,n);if(l.render(l._ts>0?(S-l._start)*l._ts:(l._dirty?l.totalDuration():l._tDur)+(S-l._start)*l._ts,t,n||er&&ti(l)),c!==this._time||!this._ts&&!p){m=0,u&&(o+=this._zTime=S?-W:W);break}}l=u}}if(m&&!t&&(this.pause(),m.render(c>=r?0:-W)._zTime=c>=r?1:-1,this._ts))return this._start=g,Si(this),this.render(e,t,n);this._onUpdate&&!t&&sa(this,`onUpdate`,!0),(o===i&&this._tTime>=this.totalDuration()||!o&&r)&&(g===this._start||Math.abs(h)!==Math.abs(this._ts))&&(this._lock||((e||!a)&&(o===i&&this._ts>0||!o&&this._ts<0)&&mi(this,1),!t&&!(e<0&&!r)&&(o||r||!i)&&(sa(this,o===i&&e>=0?`onComplete`:`onReverseComplete`,!0),this._prom&&!(o<i&&this.timeScale()>0)&&this._prom())))}return this},n.add=function(e,t){var n=this;if(cr(t)||(t=Fi(this,t,e)),!(e instanceof Fa)){if(hr(e))return e.forEach(function(e){return n.add(e,t)}),this;if(G(e))return this.addLabel(e,t);if(K(e))e=Q.delayedCall(0,e);else return this}return this===e?this:Ti(this,e,t)},n.getChildren=function(e,t,n,r){e===void 0&&(e=!0),t===void 0&&(t=!0),n===void 0&&(n=!0),r===void 0&&(r=-tr);for(var i=[],a=this._first;a;)a._start>=r&&(a instanceof Q?t&&i.push(a):(n&&i.push(a),e&&i.push.apply(i,a.getChildren(!0,t,n)))),a=a._next;return i},n.getById=function(e){for(var t=this.getChildren(1,1,1),n=t.length;n--;)if(t[n].vars.id===e)return t[n]},n.remove=function(e){return G(e)?this.removeLabel(e):K(e)?this.killTweensOf(e):(e.parent===this&&pi(this,e),e===this._recent&&(this._recent=this._last),hi(this))},n.totalTime=function(t,n){return arguments.length?(this._forcing=1,!this._dp&&this._ts&&(this._start=Y(xa.time-(this._ts>0?t/this._ts:(this.totalDuration()-t)/-this._ts))),e.prototype.totalTime.call(this,t,n),this._forcing=0,this):this._tTime},n.addLabel=function(e,t){return this.labels[e]=Fi(this,t),this},n.removeLabel=function(e){return delete this.labels[e],this},n.addPause=function(e,t,n){var r=Q.delayedCall(0,t||Fr,n);return r.data=`isPause`,this._hasPause=1,Ti(this,r,Fi(this,e))},n.removePause=function(e){var t=this._first;for(e=Fi(this,e);t;)t._start===e&&t.data===`isPause`&&mi(t),t=t._next},n.killTweensOf=function(e,t,n){for(var r=this.getTweensOf(e,n),i=r.length;i--;)Va!==r[i]&&r[i].kill(e,t);return this},n.getTweensOf=function(e,t){for(var n=[],r=Wi(e),i=this._first,a=cr(t),o;i;)i instanceof Q?$r(i._targets,r)&&(a?(!Va||i._initted&&i._ts)&&i.globalTime(0)<=t&&i.globalTime(i.totalDuration())>t:!t||i.isActive())&&n.push(i):(o=i.getTweensOf(r,t)).length&&n.push.apply(n,o),i=i._next;return n},n.tweenTo=function(e,t){t||={};var n=this,r=Fi(n,e),i=t,a=i.startAt,o=i.onStart,s=i.onStartParams,c=i.immediateRender,l,u=Q.to(n,ai({ease:t.ease||`none`,lazy:!1,immediateRender:!1,time:r,overwrite:`auto`,duration:t.duration||Math.abs((r-(a&&`time`in a?a.time:n._time))/n.timeScale())||W,onStart:function(){if(n.pause(),!l){var e=t.duration||Math.abs((r-(a&&`time`in a?a.time:n._time))/n.timeScale());u._dur!==e&&Mi(u,e,0,1).render(u._time,!0,!0),l=1}o&&o.apply(u,s||[])}},t));return c?u.render(0):u},n.tweenFromTo=function(e,t,n){return this.tweenTo(t,ai({startAt:{time:Fi(this,e)}},n))},n.recent=function(){return this._recent},n.nextLabel=function(e){return e===void 0&&(e=this._time),oa(this,Fi(this,e))},n.previousLabel=function(e){return e===void 0&&(e=this._time),oa(this,Fi(this,e),1)},n.currentLabel=function(e){return arguments.length?this.seek(e,!0):this.previousLabel(this._time+W)},n.shiftChildren=function(e,t,n){n===void 0&&(n=0);var r=this._first,i=this.labels,a;for(e=Y(e);r;)r._start>=n&&(r._start+=e,r._end+=e),r=r._next;if(t)for(a in i)i[a]>=n&&(i[a]+=e);return hi(this)},n.invalidate=function(t){var n=this._first;for(this._lock=0;n;)n.invalidate(t),n=n._next;return e.prototype.invalidate.call(this,t)},n.clear=function(e){e===void 0&&(e=!0);for(var t=this._first,n;t;)n=t._next,this.remove(t),t=n;return this._dp&&(this._time=this._tTime=this._pTime=0),e&&(this.labels={}),hi(this)},n.totalDuration=function(e){var t=0,n=this,r=n._last,i=tr,a,o,s;if(arguments.length)return n.timeScale((n._repeat<0?n.duration():n.totalDuration())/(n.reversed()?-e:e));if(n._dirty){for(s=n.parent;r;)a=r._prev,r._dirty&&r.totalDuration(),o=r._start,o>i&&n._sort&&r._ts&&!n._lock?(n._lock=1,Ti(n,r,o-r._delay,1)._lock=0):i=o,o<0&&r._ts&&(t-=o,(!s&&!n._dp||s&&s.smoothChildTiming)&&(n._start+=Y(o/n._ts),n._time-=o,n._tTime-=o),n.shiftChildren(-o,!1,-1/0),i=0),r._end>t&&r._ts&&(t=r._end),r=a;Mi(n,n===q&&n._time>t?n._time:t,1,1),n._dirty=0}return n._tDur},t.updateRoot=function(e){if(q._ts&&(ni(q,xi(e,q)),Hr=xa.frame),xa.frame>=Gr){Gr+=Zn.autoSleep||120;var t=q._first;if((!t||!t._ts)&&Zn.autoSleep&&xa._listeners.length<2){for(;t&&!t._ts;)t=t._next;t||xa.sleep()}}},t}(Fa);ai(Ia.prototype,{_lock:0,_hasPause:0,_forcing:0});var La=function(e,t,n,r,i,a,o){var s=new lo(this._pt,e,t,0,1,ro,null,i),c=0,l=0,u,d,f,p,m,h,g,_;for(s.b=n,s.e=r,n+=``,r+=``,(g=~r.indexOf(`random(`))&&(r=ra(r)),a&&(_=[n,r],a(_,e,t),n=_[0],r=_[1]),d=n.match(xr)||[];u=xr.exec(r);)p=u[0],m=r.substring(c,u.index),f?f=(f+1)%5:m.substr(-5)===`rgba(`&&(f=1),p!==d[l++]&&(h=parseFloat(d[l-1])||0,s._pt={_next:s._pt,p:m||l===1?m:`,`,s:h,c:p.charAt(1)===`=`?Qr(h,p)-h:parseFloat(p)-h,m:f&&f<4?Math.round:0},c=xr.lastIndex);return s.c=c<r.length?r.substring(c,r.length):``,s.fp=o,(Sr.test(r)||g)&&(s.e=0),this._pt=s,s},Ra=function(e,t,n,r,i,a,o,s,c,l){K(r)&&(r=r(i||0,e,a));var u=e[t],d=n===`get`?K(u)?c?e[t.indexOf(`set`)||!K(e[`get`+t.substr(3)])?t:`get`+t.substr(3)](c):e[t]():u:n,f=K(u)?c?Qa:Za:Xa,p;if(G(r)&&(~r.indexOf(`random(`)&&(r=ra(r)),r.charAt(1)===`=`&&(p=Qr(d,r)+(zi(d)||0),(p||p===0)&&(r=p))),!l||d!==r||Ha)return!isNaN(d*r)&&r!==``?(p=new lo(this._pt,e,t,+d||0,r-(d||0),typeof u==`boolean`?no:to,0,f),c&&(p.fp=c),o&&p.modifier(o,this,e),this._pt=p):(!u&&!(t in e)&&Mr(t,r),La.call(this,e,t,d,r,f,s||Zn.stringFilter,c))},za=function(e,t,n,r,i){if(K(e)&&(e=qa(e,i,t,n,r)),!ur(e)||e.style&&e.nodeType||hr(e)||mr(e))return G(e)?qa(e,i,t,n,r):e;var a={},o;for(o in e)a[o]=qa(e[o],i,t,n,r);return a},Ba=function(e,t,n,r,i,a){var o,s,c,l;if(Ur[e]&&(o=new Ur[e]).init(i,o.rawVars?t[e]:za(t[e],r,i,a,n),n,r,a)!==!1&&(n._pt=s=new lo(n._pt,i,e,0,1,o.render,o,0,o.priority),n!==la))for(c=n._ptLookup[n._targets.indexOf(i)],l=o._props.length;l--;)c[o._props[l]]=s;return o},Va,Ha,Ua=function e(t,n,r){var i=t.vars,a=i.ease,o=i.startAt,s=i.immediateRender,c=i.lazy,l=i.onUpdate,u=i.runBackwards,d=i.yoyoEase,f=i.keyframes,p=i.autoRevert,m=t._dur,h=t._startAt,g=t._targets,_=t.parent,v=_&&_.data===`nested`?_.vars.targets:g,y=t._overwrite===`auto`&&!$n,b=t.timeline,x=i.easeReverse||d,S,C,w,T,E,D,O,k,A,j,M,N,P;if(b&&(!f||!a)&&(a=`none`),t._ease=ka(a,Qn.ease),t._rEase=x&&(ka(x)||t._ease),t._from=!b&&!!i.runBackwards,t._from&&(t.ratio=1),!b||f&&!i.stagger){if(k=g[0]?Yr(g[0]).harness:0,N=k&&i[k.prop],S=li(i,zr),h&&(h._zTime<0&&h.progress(1),n<0&&u&&s&&!p?h.render(-1,!0):h.revert(u&&m?Lr:Ir),h._lazy=0),o){if(mi(t._startAt=Q.set(g,ai({data:`isStart`,overwrite:!1,parent:_,immediateRender:!0,lazy:!h&&dr(c),startAt:null,delay:0,onUpdate:l&&function(){return sa(t,`onUpdate`)},stagger:0},o))),t._startAt._dp=0,t._startAt._sat=t,n<0&&(er||!s&&!p)&&t._startAt.revert(Lr),s&&m&&n<=0&&r<=0){n&&(t._zTime=n);return}}else if(u&&m&&!h){if(n&&(s=!1),w=ai({overwrite:!1,data:`isFromStart`,lazy:s&&!h&&dr(c),immediateRender:s,stagger:0,parent:_},S),N&&(w[k.prop]=N),mi(t._startAt=Q.set(g,w)),t._startAt._dp=0,t._startAt._sat=t,n<0&&(er?t._startAt.revert(Lr):t._startAt.render(-1,!0)),t._zTime=n,!s)e(t._startAt,W,W);else if(!n)return}for(t._pt=t._ptCache=0,c=m&&dr(c)||c&&!m,C=0;C<g.length;C++){if(E=g[C],O=E._gsap||Jr(g)[C]._gsap,t._ptLookup[C]=j={},Vr[O.id]&&Br.length&&ei(),M=v===g?C:v.indexOf(E),k&&(A=new k).init(E,N||S,t,M,v)!==!1&&(t._pt=T=new lo(t._pt,E,A.name,0,1,A.render,A,0,A.priority),A._props.forEach(function(e){j[e]=T}),A.priority&&(D=1)),!k||N)for(w in S)Ur[w]&&(A=Ba(w,S,t,M,E,v))?A.priority&&(D=1):j[w]=T=Ra.call(t,E,w,`get`,S[w],M,v,0,i.stringFilter);t._op&&t._op[C]&&t.kill(E,t._op[C]),y&&t._pt&&(Va=t,q.killTweensOf(E,j,t.globalTime(n)),P=!t.parent,Va=0),t._pt&&c&&(Vr[O.id]=1)}D&&co(t),t._onInit&&t._onInit(t)}t._onUpdate=l,t._initted=(!t._op||t._pt)&&!P,f&&n<=0&&b.render(tr,!0,!0)},Wa=function(e,t,n,r,i,a,o,s){var c=(e._pt&&e._ptCache||(e._ptCache={}))[t],l,u,d,f;if(!c)for(c=e._ptCache[t]=[],d=e._ptLookup,f=e._targets.length;f--;){if(l=d[f][t],l&&l.d&&l.d._pt)for(l=l.d._pt;l&&l.p!==t&&l.fp!==t;)l=l._next;if(!l)return Ha=1,e.vars[t]=`+=0`,Ua(e,o),Ha=0,s?Nr(t+` not eligible for reset. Try splitting into individual properties`):1;c.push(l)}for(f=c.length;f--;)u=c[f],l=u._pt||u,l.s=(r||r===0)&&!i?r:l.s+(r||0)+a*l.c,l.c=n-l.s,u.e&&=J(n)+zi(u.e),u.b&&=l.s+zi(u.b)},Ga=function(e,t){var n=e[0]?Yr(e[0]).harness:0,r=n&&n.aliases,i,a,o,s;if(!r)return t;for(a in i=si({},t),r)if(a in i)for(s=r[a].split(`,`),o=s.length;o--;)i[s[o]]=i[a];return i},Ka=function(e,t,n,r){var i=t.ease||r||`power1.inOut`,a,o;if(hr(t))o=n[e]||(n[e]=[]),t.forEach(function(e,n){return o.push({t:n/(t.length-1)*100,v:e,e:i})});else for(a in t)o=n[a]||(n[a]=[]),a===`ease`||o.push({t:parseFloat(e),v:t[a],e:i})},qa=function(e,t,n,r,i){return K(e)?e.call(t,n,r,i):G(e)&&~e.indexOf(`random(`)?ra(e):e},Ja=qr+`repeat,repeatDelay,yoyo,repeatRefresh,yoyoEase,easeReverse,autoRevert`,Ya={};Zr(Ja+`,id,stagger,delay,duration,paused,scrollTrigger`,function(e){return Ya[e]=1});var Q=function(e){Xn(t,e);function t(t,n,r,i){var a;typeof n==`number`&&(r.duration=n,n=r,r=null),a=e.call(this,i?n:ui(n))||this;var o=a.vars,s=o.duration,c=o.delay,l=o.immediateRender,u=o.stagger,d=o.overwrite,f=o.keyframes,p=o.defaults,m=o.scrollTrigger,h=n.parent||q,g=(hr(t)||mr(t)?cr(t[0]):`length`in n)?[t]:Wi(t),_,v,y,b,x,S,C,w;if(a._targets=g.length?Jr(g):Nr(`GSAP target `+t+` not found. https://gsap.com`,!Zn.nullTargetWarn)||[],a._ptLookup=[],a._overwrite=d,f||u||pr(s)||pr(c)){n=a.vars;var T=n.easeReverse||n.yoyoEase;if(_=a.timeline=new Ia({data:`nested`,defaults:p||{},targets:h&&h.data===`nested`?h.vars.targets:g}),_.kill(),_.parent=_._dp=Yn(a),_._start=0,u||pr(s)||pr(c)){if(b=g.length,C=u&&qi(u),ur(u))for(x in u)~Ja.indexOf(x)&&(w||={},w[x]=u[x]);for(v=0;v<b;v++)y=li(n,Ya),y.stagger=0,T&&(y.easeReverse=T),w&&si(y,w),S=g[v],y.duration=+qa(s,Yn(a),v,S,g),y.delay=(+qa(c,Yn(a),v,S,g)||0)-a._delay,!u&&b===1&&y.delay&&(a._delay=c=y.delay,a._start+=c,y.delay=0),_.to(S,y,C?C(v,S,g):0),_._ease=Z.none;_.duration()?s=c=0:a.timeline=0}else if(f){ui(ai(_.vars.defaults,{ease:`none`})),_._ease=ka(f.ease||n.ease||`none`);var E=0,D,O,k;if(hr(f))f.forEach(function(e){return _.to(g,e,`>`)}),_.duration();else{for(x in y={},f)x===`ease`||x===`easeEach`||Ka(x,f[x],y,f.easeEach);for(x in y)for(D=y[x].sort(function(e,t){return e.t-t.t}),E=0,v=0;v<D.length;v++)O=D[v],k={ease:O.e,duration:(O.t-(v?D[v-1].t:0))/100*s},k[x]=O.v,_.to(g,k,E),E+=k.duration;_.duration()<s&&_.to({},{duration:s-_.duration()})}}s||a.duration(s=_.duration())}else a.timeline=0;return d===!0&&!$n&&(Va=Yn(a),q.killTweensOf(g),Va=0),Ti(h,Yn(a),r),n.reversed&&a.reverse(),n.paused&&a.paused(!0),(l||!s&&!f&&a._start===Y(h._time)&&dr(l)&&vi(Yn(a))&&h.data!==`nested`)&&(a._tTime=-W,a.render(Math.max(0,-c)||0)),m&&Ei(Yn(a),m),a}var n=t.prototype;return n.render=function(e,t,n){var r=this._time,i=this._tDur,a=this._dur,o=e<0,s=e>i-W&&!o?i:e<W?0:e,c,l,u,d,f,p,m,h;if(!a)Ai(this,e,t,n);else if(s!==this._tTime||!e||n||!this._initted&&this._tTime||this._startAt&&this._zTime<0!==o||this._lazy){if(c=s,h=this.timeline,this._repeat){if(d=a+this._rDelay,this._repeat<-1&&o)return this.totalTime(d*100+e,t,n);if(c=Y(s%d),s===i?(u=this._repeat,c=a):(f=Y(s/d),u=~~f,u&&u===f?(c=a,u--):c>a&&(c=a)),p=this._yoyo&&u&1,p&&(c=a-c),f=bi(this._tTime,d),c===r&&!n&&this._initted&&u===f)return this._tTime=s,this;u!==f&&this.vars.repeatRefresh&&!p&&!this._lock&&c!==d&&this._initted&&(this._lock=n=1,this.render(Y(d*u),!0).invalidate()._lock=0)}if(!this._initted){if(Di(this,o?e:c,n,t,s))return this._tTime=0,this;if(r!==this._time&&!(n&&this.vars.repeatRefresh&&u!==f))return this;if(a!==this._dur)return this.render(e,t,n)}if(this._rEase){var g=c<r;if(g!==this._inv){var _=g?r:a-r;this._inv=g,this._from&&(this.ratio=1-this.ratio),this._invRatio=this.ratio,this._invTime=r,this._invRecip=_?(g?-1:1)/_:0,this._invScale=g?-this.ratio:1-this.ratio,this._invEase=g?this._rEase:this._ease}this.ratio=m=this._invRatio+this._invScale*this._invEase((c-this._invTime)*this._invRecip)}else this.ratio=m=this._ease(c/a);if(this._from&&(this.ratio=m=1-m),this._tTime=s,this._time=c,!this._act&&this._ts&&(this._act=1,this._lazy=0),!r&&s&&!t&&!f&&(sa(this,`onStart`),this._tTime!==s))return this;for(l=this._pt;l;)l.r(m,l.d),l=l._next;h&&h.render(e<0?e:h._dur*h._ease(c/this._dur),t,n)||this._startAt&&(this._zTime=e),this._onUpdate&&!t&&(o&&_i(this,e,t,n),sa(this,`onUpdate`)),this._repeat&&u!==f&&this.vars.onRepeat&&!t&&this.parent&&sa(this,`onRepeat`),(s===this._tDur||!s)&&this._tTime===s&&(o&&!this._onUpdate&&_i(this,e,!0,!0),(e||!a)&&(s===this._tDur&&this._ts>0||!s&&this._ts<0)&&mi(this,1),!t&&!(o&&!r)&&(s||r||p)&&(sa(this,s===i?`onComplete`:`onReverseComplete`,!0),this._prom&&!(s<i&&this.timeScale()>0)&&this._prom()))}return this},n.targets=function(){return this._targets},n.invalidate=function(t){return(!t||!this.vars.runBackwards)&&(this._startAt=0),this._pt=this._op=this._onUpdate=this._lazy=this.ratio=0,this._ptLookup=[],this.timeline&&this.timeline.invalidate(t),e.prototype.invalidate.call(this,t)},n.resetTo=function(e,t,n,r,i){ba||xa.wake(),this._ts||this.play();var a=Math.min(this._dur,(this._dp._time-this._start)*this._ts),o;return this._initted||Ua(this,a),o=this._ease(a/this._dur),Wa(this,e,t,n,r,o,a,i)?this.resetTo(e,t,n,r,1):(Ci(this,0),this.parent||fi(this._dp,this,`_first`,`_last`,this._dp._sort?`_start`:0),this.render(0))},n.kill=function(e,t){if(t===void 0&&(t=`all`),!e&&(!t||t===`all`))return this._lazy=this._pt=0,this.parent?ca(this):this.scrollTrigger&&this.scrollTrigger.kill(!!er),this;if(this.timeline){var n=this.timeline.totalDuration();return this.timeline.killTweensOf(e,t,Va&&Va.vars.overwrite!==!0)._first||ca(this),this.parent&&n!==this.timeline.totalDuration()&&Mi(this,this._dur*this.timeline._tDur/n,0,1),this}var r=this._targets,i=e?Wi(e):r,a=this._ptLookup,o=this._pt,s,c,l,u,d,f,p;if((!t||t===`all`)&&di(r,i))return t===`all`&&(this._pt=0),ca(this);for(s=this._op=this._op||[],t!==`all`&&(G(t)&&(d={},Zr(t,function(e){return d[e]=1}),t=d),t=Ga(r,t)),p=r.length;p--;)if(~i.indexOf(r[p]))for(d in c=a[p],t===`all`?(s[p]=t,u=c,l={}):(l=s[p]=s[p]||{},u=t),u)f=c&&c[d],f&&((!(`kill`in f.d)||f.d.kill(d)===!0)&&pi(this,f,`_pt`),delete c[d]),l!==`all`&&(l[d]=1);return this._initted&&!this._pt&&o&&ca(this),this},t.to=function(e,n){return new t(e,n,arguments[2])},t.from=function(e,t){return Ii(1,arguments)},t.delayedCall=function(e,n,r,i){return new t(n,0,{immediateRender:!1,lazy:!1,overwrite:!1,delay:e,onComplete:n,onReverseComplete:n,onCompleteParams:r,onReverseCompleteParams:r,callbackScope:i})},t.fromTo=function(e,t,n){return Ii(2,arguments)},t.set=function(e,n){return n.duration=0,n.repeatDelay||(n.repeat=0),new t(e,n)},t.killTweensOf=function(e,t,n){return q.killTweensOf(e,t,n)},t}(Fa);ai(Q.prototype,{_targets:[],_lazy:0,_startAt:0,_op:0,_onInit:0}),Zr(`staggerTo,staggerFrom,staggerFromTo`,function(e){Q[e]=function(){var t=new Ia,n=Vi.call(arguments,0);return n.splice(e===`staggerFromTo`?5:4,0,0),t[e].apply(t,n)}});var Xa=function(e,t,n){return e[t]=n},Za=function(e,t,n){return e[t](n)},Qa=function(e,t,n,r){return e[t](r.fp,n)},$a=function(e,t,n){return e.setAttribute(t,n)},eo=function(e,t){return K(e[t])?Za:lr(e[t])&&e.setAttribute?$a:Xa},to=function(e,t){return t.set(t.t,t.p,Math.round((t.s+t.c*e)*1e6)/1e6,t)},no=function(e,t){return t.set(t.t,t.p,!!(t.s+t.c*e),t)},ro=function(e,t){var n=t._pt,r=``;if(!e&&t.b)r=t.b;else if(e===1&&t.e)r=t.e;else{for(;n;)r=n.p+(n.m?n.m(n.s+n.c*e):Math.round((n.s+n.c*e)*1e4)/1e4)+r,n=n._next;r+=t.c}t.set(t.t,t.p,r,t)},io=function(e,t){for(var n=t._pt;n;)n.r(e,n.d),n=n._next},ao=function(e,t,n,r){for(var i=this._pt,a;i;)a=i._next,i.p===r&&i.modifier(e,t,n),i=a},oo=function(e){for(var t=this._pt,n,r;t;)r=t._next,t.p===e&&!t.op||t.op===e?pi(this,t,`_pt`):t.dep||(n=1),t=r;return!n},so=function(e,t,n,r){r.mSet(e,t,r.m.call(r.tween,n,r.mt),r)},co=function(e){for(var t=e._pt,n,r,i,a;t;){for(n=t._next,r=i;r&&r.pr>t.pr;)r=r._next;(t._prev=r?r._prev:a)?t._prev._next=t:i=t,(t._next=r)?r._prev=t:a=t,t=n}e._pt=i},lo=function(){function e(e,t,n,r,i,a,o,s,c){this.t=t,this.s=r,this.c=i,this.p=n,this.r=a||to,this.d=o||this,this.set=s||Xa,this.pr=c||0,this._next=e,e&&(e._prev=this)}var t=e.prototype;return t.modifier=function(e,t,n){this.mSet=this.mSet||this.set,this.set=so,this.m=e,this.mt=n,this.tween=t},e}();Zr(qr+`parent,duration,ease,delay,overwrite,runBackwards,startAt,yoyo,immediateRender,repeat,repeatDelay,data,paused,reversed,lazy,callbackScope,stringFilter,id,yoyoEase,stagger,inherit,repeatRefresh,keyframes,autoRevert,scrollTrigger,easeReverse`,function(e){return zr[e]=1}),Or.TweenMax=Or.TweenLite=Q,Or.TimelineLite=Or.TimelineMax=Ia,q=new Ia({sortChildren:!1,defaults:Qn,autoRemoveChildren:!0,id:`root`,smoothChildTiming:!0}),Zn.stringFilter=ya;var uo=[],fo={},po=[],mo=0,ho=0,go=function(e){return(fo[e]||po).map(function(e){return e()})},_o=function(){var e=Date.now(),t=[];e-mo>2&&(go(`matchMediaInit`),uo.forEach(function(e){var n=e.queries,r=e.conditions,i,a,o,s;for(a in n)i=Tr.matchMedia(n[a]).matches,i&&(o=1),i!==r[a]&&(r[a]=i,s=1);s&&(e.revert(),o&&t.push(e))}),go(`matchMediaRevert`),t.forEach(function(e){return e.onMatch(e,function(t){return e.add(null,t)})}),mo=e,go(`matchMedia`))},vo=function(){function e(e,t){this.selector=t&&Gi(t),this.data=[],this._r=[],this.isReverted=!1,this.id=ho++,e&&this.add(e)}var t=e.prototype;return t.add=function(e,t,n){K(e)&&(n=t,t=e,e=K);var r=this,i=function(){var e=U,i=r.selector,a;return e&&e!==r&&e.data.push(r),n&&(r.selector=Gi(n)),U=r,a=t.apply(r,arguments),K(a)&&r._r.push(a),U=e,r.selector=i,r.isReverted=!1,a};return r.last=i,e===K?i(r,function(e){return r.add(null,e)}):e?r[e]=i:i},t.ignore=function(e){var t=U;U=null,e(this),U=t},t.getTweens=function(){var t=[];return this.data.forEach(function(n){return n instanceof e?t.push.apply(t,n.getTweens()):n instanceof Q&&!(n.parent&&n.parent.data===`nested`)&&t.push(n)}),t},t.clear=function(){this._r.length=this.data.length=0},t.kill=function(e,t){var n=this;if(e?(function(){for(var t=n.getTweens(),r=n.data.length,i;r--;)i=n.data[r],i.data===`isFlip`&&(i.revert(),i.getChildren(!0,!0,!1).forEach(function(e){return t.splice(t.indexOf(e),1)}));for(t.map(function(e){return{g:e._dur||e._delay||e._sat&&!e._sat.vars.immediateRender?e.globalTime(0):-1/0,t:e}}).sort(function(e,t){return t.g-e.g||-1/0}).forEach(function(t){return t.t.revert(e)}),r=n.data.length;r--;)i=n.data[r],i instanceof Ia?i.data!==`nested`&&(i.scrollTrigger&&i.scrollTrigger.revert(),i.kill()):!(i instanceof Q)&&i.revert&&i.revert(e);n._r.forEach(function(t){return t(e,n)}),n.isReverted=!0})():this.data.forEach(function(e){return e.kill&&e.kill()}),this.clear(),t)for(var r=uo.length;r--;)uo[r].id===this.id&&uo.splice(r,1)},t.revert=function(e){this.kill(e||{})},e}(),yo=function(){function e(e){this.contexts=[],this.scope=e,U&&U.data.push(this)}var t=e.prototype;return t.add=function(e,t,n){ur(e)||(e={matches:e});var r=new vo(0,n||this.scope),i=r.conditions={},a,o,s;for(o in U&&!r.selector&&(r.selector=U.selector),this.contexts.push(r),t=r.add(`onMatch`,t),r.queries=e,e)o===`all`?s=1:(a=Tr.matchMedia(e[o]),a&&(uo.indexOf(r)<0&&uo.push(r),(i[o]=a.matches)&&(s=1),a.addListener?a.addListener(_o):a.addEventListener(`change`,_o)));return s&&t(r,function(e){return r.add(null,e)}),this},t.revert=function(e){this.kill(e||{})},t.kill=function(e){this.contexts.forEach(function(t){return t.kill(e,!0)})},e}(),bo={registerPlugin:function(){[...arguments].forEach(function(e){return da(e)})},timeline:function(e){return new Ia(e)},getTweensOf:function(e,t){return q.getTweensOf(e,t)},getProperty:function(e,t,n,r){G(e)&&(e=Wi(e)[0]);var i=Yr(e||{}).get,a=n?ii:ri;return n===`native`&&(n=``),e&&(t?a((Ur[t]&&Ur[t].get||i)(e,t,n,r)):function(t,n,r){return a((Ur[t]&&Ur[t].get||i)(e,t,n,r))})},quickSetter:function(e,t,n){if(e=Wi(e),e.length>1){var r=e.map(function(e){return wo.quickSetter(e,t,n)}),i=r.length;return function(e){for(var t=i;t--;)r[t](e)}}e=e[0]||{};var a=Ur[t],o=Yr(e),s=o.harness&&(o.harness.aliases||{})[t]||t,c=a?function(t){var r=new a;la._pt=0,r.init(e,n?t+n:t,la,0,[e]),r.render(1,r),la._pt&&io(1,la)}:o.set(e,s);return a?c:function(t){return c(e,s,n?t+n:t,o,1)}},quickTo:function(e,t,n){var r,i=wo.to(e,ai((r={},r[t]=`+=0.1`,r.paused=!0,r.stagger=0,r),n||{})),a=function(e,n,r){return i.resetTo(t,e,n,r)};return a.tween=i,a},isTweening:function(e){return q.getTweensOf(e,!0).length>0},defaults:function(e){return e&&e.ease&&(e.ease=ka(e.ease,Qn.ease)),ci(Qn,e||{})},config:function(e){return ci(Zn,e||{})},registerEffect:function(e){var t=e.name,n=e.effect,r=e.plugins,i=e.defaults,a=e.extendTimeline;(r||``).split(`,`).forEach(function(e){return e&&!Ur[e]&&!Or[e]&&Nr(t+` effect requires `+e+` plugin.`)}),Wr[t]=function(e,t,r){return n(Wi(e),ai(t||{},i),r)},a&&(Ia.prototype[t]=function(e,n,r){return this.add(Wr[t](e,ur(n)?n:(r=n)&&{},this),r)})},registerEase:function(e,t){Z[e]=ka(t)},parseEase:function(e,t){return arguments.length?ka(e,t):Z},getById:function(e){return q.getById(e)},exportRoot:function(e,t){e===void 0&&(e={});var n=new Ia(e),r,i;for(n.smoothChildTiming=dr(e.smoothChildTiming),q.remove(n),n._dp=0,n._time=n._tTime=q._time,r=q._first;r;)i=r._next,(t||!(!r._dur&&r instanceof Q&&r.vars.onComplete===r._targets[0]))&&Ti(n,r,r._start-r._delay),r=i;return Ti(q,n,0),n},context:function(e,t){return e?new vo(e,t):U},matchMedia:function(e){return new yo(e)},matchMediaRefresh:function(){return uo.forEach(function(e){var t=e.conditions,n,r;for(r in t)t[r]&&(t[r]=!1,n=1);n&&e.revert()})||_o()},addEventListener:function(e,t){var n=fo[e]||(fo[e]=[]);~n.indexOf(t)||n.push(t)},removeEventListener:function(e,t){var n=fo[e],r=n&&n.indexOf(t);r>=0&&n.splice(r,1)},utils:{wrap:ta,wrapYoyo:na,distribute:qi,random:Xi,snap:Yi,normalize:$i,getUnit:zi,clamp:Bi,splitColor:ma,toArray:Wi,selector:Gi,mapRange:ia,pipe:Zi,unitize:Qi,interpolate:aa,shuffle:Ki},install:jr,effects:Wr,ticker:xa,updateRoot:Ia.updateRoot,plugins:Ur,globalTimeline:q,core:{PropTween:lo,globals:Pr,Tween:Q,Timeline:Ia,Animation:Fa,getCache:Yr,_removeLinkedListItem:pi,reverting:function(){return er},context:function(e){return e&&U&&(U.data.push(e),e._ctx=U),U},suppressOverwrites:function(e){return $n=e}}};Zr(`to,from,fromTo,delayedCall,set,killTweensOf`,function(e){return bo[e]=Q[e]}),xa.add(Ia.updateRoot),la=bo.to({},{duration:0});var xo=function(e,t){for(var n=e._pt;n&&n.p!==t&&n.op!==t&&n.fp!==t;)n=n._next;return n},So=function(e,t){var n=e._targets,r,i,a;for(r in t)for(i=n.length;i--;)a=e._ptLookup[i][r],(a&&=a.d)&&(a._pt&&(a=xo(a,r)),a&&a.modifier&&a.modifier(t[r],e,n[i],r))},Co=function(e,t){return{name:e,headless:1,rawVars:1,init:function(e,n,r){r._onInit=function(e){var r,i;if(G(n)&&(r={},Zr(n,function(e){return r[e]=1}),n=r),t){for(i in r={},n)r[i]=t(n[i]);n=r}So(e,n)}}}},wo=bo.registerPlugin({name:`attr`,init:function(e,t,n,r,i){var a,o,s;for(a in this.tween=n,t)s=e.getAttribute(a)||``,o=this.add(e,`setAttribute`,(s||0)+``,t[a],r,i,0,0,a),o.op=a,o.b=s,this._props.push(a)},render:function(e,t){for(var n=t._pt;n;)er?n.set(n.t,n.p,n.b,n):n.r(e,n.d),n=n._next}},{name:`endArray`,headless:1,init:function(e,t){for(var n=t.length;n--;)this.add(e,n,e[n]||0,t[n],0,0,0,0,0,1)}},Co(`roundProps`,Ji),Co(`modifiers`),Co(`snap`,Yi))||bo;Q.version=Ia.version=wo.version=`3.15.0`,Ar=1,fr()&&Sa(),Z.Power0,Z.Power1,Z.Power2,Z.Power3,Z.Power4,Z.Linear,Z.Quad,Z.Cubic,Z.Quart,Z.Quint,Z.Strong,Z.Elastic,Z.Back,Z.SteppedEase,Z.Bounce,Z.Sine,Z.Expo,Z.Circ;var To,Eo,Do,Oo,ko,Ao,jo,Mo=function(){return typeof window<`u`},No={},Po=180/Math.PI,Fo=Math.PI/180,Io=Math.atan2,Lo=1e8,Ro=/([A-Z])/g,zo=/(left|right|width|margin|padding|x)/i,Bo=/[\s,\(]\S/,Vo={autoAlpha:`opacity,visibility`,scale:`scaleX,scaleY`,alpha:`opacity`},Ho=function(e,t){return t.set(t.t,t.p,Math.round((t.s+t.c*e)*1e4)/1e4+t.u,t)},Uo=function(e,t){return t.set(t.t,t.p,e===1?t.e:Math.round((t.s+t.c*e)*1e4)/1e4+t.u,t)},Wo=function(e,t){return t.set(t.t,t.p,e?Math.round((t.s+t.c*e)*1e4)/1e4+t.u:t.b,t)},Go=function(e,t){return t.set(t.t,t.p,e===1?t.e:e?Math.round((t.s+t.c*e)*1e4)/1e4+t.u:t.b,t)},Ko=function(e,t){var n=t.s+t.c*e;t.set(t.t,t.p,~~(n+(n<0?-.5:.5))+t.u,t)},qo=function(e,t){return t.set(t.t,t.p,e?t.e:t.b,t)},Jo=function(e,t){return t.set(t.t,t.p,e===1?t.e:t.b,t)},Yo=function(e,t,n){return e.style[t]=n},Xo=function(e,t,n){return e.style.setProperty(t,n)},Zo=function(e,t,n){return e._gsap[t]=n},Qo=function(e,t,n){return e._gsap.scaleX=e._gsap.scaleY=n},$o=function(e,t,n,r,i){var a=e._gsap;a.scaleX=a.scaleY=n,a.renderTransform(i,a)},es=function(e,t,n,r,i){var a=e._gsap;a[t]=n,a.renderTransform(i,a)},$=`transform`,ts=$+`Origin`,ns=function e(t,n){var r=this,i=this.target,a=i.style,o=i._gsap;if(t in No&&a){if(this.tfm=this.tfm||{},t!==`transform`)t=Vo[t]||t,~t.indexOf(`,`)?t.split(`,`).forEach(function(e){return r.tfm[e]=xs(i,e)}):this.tfm[t]=o.x?o[t]:xs(i,t),t===ts&&(this.tfm.zOrigin=o.zOrigin);else return Vo.transform.split(`,`).forEach(function(t){return e.call(r,t,n)});if(this.props.indexOf($)>=0)return;o.svg&&(this.svgo=i.getAttribute(`data-svg-origin`),this.props.push(ts,n,``)),t=$}(a||n)&&this.props.push(t,n,a[t])},rs=function(e){e.translate&&(e.removeProperty(`translate`),e.removeProperty(`scale`),e.removeProperty(`rotate`))},is=function(){var e=this.props,t=this.target,n=t.style,r=t._gsap,i,a;for(i=0;i<e.length;i+=3)e[i+1]?e[i+1]===2?t[e[i]](e[i+2]):t[e[i]]=e[i+2]:e[i+2]?n[e[i]]=e[i+2]:n.removeProperty(e[i].substr(0,2)===`--`?e[i]:e[i].replace(Ro,`-$1`).toLowerCase());if(this.tfm){for(a in this.tfm)r[a]=this.tfm[a];r.svg&&(r.renderTransform(),t.setAttribute(`data-svg-origin`,this.svgo||``)),i=jo(),(!i||!i.isStart)&&!n[$]&&(rs(n),r.zOrigin&&n[ts]&&(n[ts]+=` `+r.zOrigin+`px`,r.zOrigin=0,r.renderTransform()),r.uncache=1)}},as=function(e,t){var n={target:e,props:[],revert:is,save:ns};return e._gsap||wo.core.getCache(e),t&&e.style&&e.nodeType&&t.split(`,`).forEach(function(e){return n.save(e)}),n},os,ss=function(e,t){var n=Eo.createElementNS?Eo.createElementNS((t||`http://www.w3.org/1999/xhtml`).replace(/^https/,`http`),e):Eo.createElement(e);return n&&n.style?n:Eo.createElement(e)},cs=function e(t,n,r){var i=getComputedStyle(t);return i[n]||i.getPropertyValue(n.replace(Ro,`-$1`).toLowerCase())||i.getPropertyValue(n)||!r&&e(t,us(n)||n,1)||``},ls=`O,Moz,ms,Ms,Webkit`.split(`,`),us=function(e,t,n){var r=(t||ko).style,i=5;if(e in r&&!n)return e;for(e=e.charAt(0).toUpperCase()+e.substr(1);i--&&!(ls[i]+e in r););return i<0?null:(i===3?`ms`:i>=0?ls[i]:``)+e},ds=function(){Mo()&&window.document&&(To=window,Eo=To.document,Do=Eo.documentElement,ko=ss(`div`)||{style:{}},ss(`div`),$=us($),ts=$+`Origin`,ko.style.cssText=`border-width:0;line-height:0;position:absolute;padding:0`,os=!!us(`perspective`),jo=wo.core.reverting,Oo=1)},fs=function(e){var t=e.ownerSVGElement,n=ss(`svg`,t&&t.getAttribute(`xmlns`)||`http://www.w3.org/2000/svg`),r=e.cloneNode(!0),i;r.style.display=`block`,n.appendChild(r),Do.appendChild(n);try{i=r.getBBox()}catch{}return n.removeChild(r),Do.removeChild(n),i},ps=function(e,t){for(var n=t.length;n--;)if(e.hasAttribute(t[n]))return e.getAttribute(t[n])},ms=function(e){var t,n;try{t=e.getBBox()}catch{t=fs(e),n=1}return t&&(t.width||t.height)||n||(t=fs(e)),t&&!t.width&&!t.x&&!t.y?{x:+ps(e,[`x`,`cx`,`x1`])||0,y:+ps(e,[`y`,`cy`,`y1`])||0,width:0,height:0}:t},hs=function(e){return!!(e.getCTM&&(!e.parentNode||e.ownerSVGElement)&&ms(e))},gs=function(e,t){if(t){var n=e.style,r;t in No&&t!==ts&&(t=$),n.removeProperty?(r=t.substr(0,2),(r===`ms`||t.substr(0,6)===`webkit`)&&(t=`-`+t),n.removeProperty(r===`--`?t:t.replace(Ro,`-$1`).toLowerCase())):n.removeAttribute(t)}},_s=function(e,t,n,r,i,a){var o=new lo(e._pt,t,n,0,1,a?Jo:qo);return e._pt=o,o.b=r,o.e=i,e._props.push(n),o},vs={deg:1,rad:1,turn:1},ys={grid:1,flex:1},bs=function e(t,n,r,i){var a=parseFloat(r)||0,o=(r+``).trim().substr((a+``).length)||`px`,s=ko.style,c=zo.test(n),l=t.tagName.toLowerCase()===`svg`,u=(l?`client`:`offset`)+(c?`Width`:`Height`),d=100,f=i===`px`,p=i===`%`,m,h,g,_;if(i===o||!a||vs[i]||vs[o])return a;if(o!==`px`&&!f&&(a=e(t,n,r,`px`)),_=t.getCTM&&hs(t),(p||o===`%`)&&(No[n]||~n.indexOf(`adius`)))return m=_?t.getBBox()[c?`width`:`height`]:t[u],J(p?a/m*d:a/100*m);if(s[c?`width`:`height`]=d+(f?o:i),h=i!==`rem`&&~n.indexOf(`adius`)||i===`em`&&t.appendChild&&!l?t:t.parentNode,_&&(h=(t.ownerSVGElement||{}).parentNode),(!h||h===Eo||!h.appendChild)&&(h=Eo.body),g=h._gsap,g&&p&&g.width&&c&&g.time===xa.time&&!g.uncache)return J(a/g.width*d);if(p&&(n===`height`||n===`width`)){var v=t.style[n];t.style[n]=d+i,m=t[u],v?t.style[n]=v:gs(t,n)}else(p||o===`%`)&&!ys[cs(h,`display`)]&&(s.position=cs(t,`position`)),h===t&&(s.position=`static`),h.appendChild(ko),m=ko[u],h.removeChild(ko),s.position=`absolute`;return c&&p&&(g=Yr(h),g.time=xa.time,g.width=h[u]),J(f?m*a/d:m&&a?d/m*a:0)},xs=function(e,t,n,r){var i;return Oo||ds(),t in Vo&&t!==`transform`&&(t=Vo[t],~t.indexOf(`,`)&&(t=t.split(`,`)[0])),No[t]&&t!==`transform`?(i=Ns(e,r),i=t===`transformOrigin`?i.svg?i.origin:Ps(cs(e,ts))+` `+i.zOrigin+`px`:i[t]):(i=e.style[t],(!i||i===`auto`||r||~(i+``).indexOf(`calc(`))&&(i=Es[t]&&Es[t](e,t,n)||cs(e,t)||Xr(e,t)||+(t===`opacity`))),n&&!~(i+``).trim().indexOf(` `)?bs(e,t,i,n)+n:i},Ss=function(e,t,n,r){if(!n||n===`none`){var i=us(t,e,1),a=i&&cs(e,i,1);a&&a!==n?(t=i,n=a):t===`borderColor`&&(n=cs(e,`borderTopColor`))}var o=new lo(this._pt,e.style,t,0,1,ro),s=0,c=0,l,u,d,f,p,m,h,g,_,v,y,b;if(o.b=n,o.e=r,n+=``,r+=``,r.substring(0,6)===`var(--`&&(r=cs(e,r.substring(4,r.indexOf(`)`)))),r===`auto`&&(m=e.style[t],e.style[t]=r,r=cs(e,t)||r,m?e.style[t]=m:gs(e,t)),l=[n,r],ya(l),n=l[0],r=l[1],d=n.match(br)||[],b=r.match(br)||[],b.length){for(;u=br.exec(r);)h=u[0],_=r.substring(s,u.index),p?p=(p+1)%5:(_.substr(-5)===`rgba(`||_.substr(-5)===`hsla(`)&&(p=1),h!==(m=d[c++]||``)&&(f=parseFloat(m)||0,y=m.substr((f+``).length),h.charAt(1)===`=`&&(h=Qr(f,h)+y),g=parseFloat(h),v=h.substr((g+``).length),s=br.lastIndex-v.length,v||(v=v||Zn.units[t]||y,s===r.length&&(r+=v,o.e+=v)),y!==v&&(f=bs(e,t,m,v)||0),o._pt={_next:o._pt,p:_||c===1?_:`,`,s:f,c:g-f,m:p&&p<4||t===`zIndex`?Math.round:0});o.c=s<r.length?r.substring(s,r.length):``}else o.r=t===`display`&&r===`none`?Jo:qo;return Sr.test(r)&&(o.e=0),this._pt=o,o},Cs={top:`0%`,bottom:`100%`,left:`0%`,right:`100%`,center:`50%`},ws=function(e){var t=e.split(` `),n=t[0],r=t[1]||`50%`;return(n===`top`||n===`bottom`||r===`left`||r===`right`)&&(e=n,n=r,r=e),t[0]=Cs[n]||n,t[1]=Cs[r]||r,t.join(` `)},Ts=function(e,t){if(t.tween&&t.tween._time===t.tween._dur){var n=t.t,r=n.style,i=t.u,a=n._gsap,o,s,c;if(i===`all`||i===!0)r.cssText=``,s=1;else for(i=i.split(`,`),c=i.length;--c>-1;)o=i[c],No[o]&&(s=1,o=o===`transformOrigin`?ts:$),gs(n,o);s&&(gs(n,$),a&&(a.svg&&n.removeAttribute(`transform`),r.scale=r.rotate=r.translate=`none`,Ns(n,1),a.uncache=1,rs(r)))}},Es={clearProps:function(e,t,n,r,i){if(i.data!==`isFromStart`){var a=e._pt=new lo(e._pt,t,n,0,0,Ts);return a.u=r,a.pr=-10,a.tween=i,e._props.push(n),1}}},Ds=[1,0,0,1,0,0],Os={},ks=function(e){return e===`matrix(1, 0, 0, 1, 0, 0)`||e===`none`||!e},As=function(e){var t=cs(e,$);return ks(t)?Ds:t.substr(7).match(yr).map(J)},js=function(e,t){var n=e._gsap||Yr(e),r=e.style,i=As(e),a,o,s,c;return n.svg&&e.getAttribute(`transform`)?(s=e.transform.baseVal.consolidate().matrix,i=[s.a,s.b,s.c,s.d,s.e,s.f],i.join(`,`)===`1,0,0,1,0,0`?Ds:i):(i===Ds&&!e.offsetParent&&e!==Do&&!n.svg&&(s=r.display,r.display=`block`,a=e.parentNode,(!a||!e.offsetParent&&!e.getBoundingClientRect().width)&&(c=1,o=e.nextElementSibling,Do.appendChild(e)),i=As(e),s?r.display=s:gs(e,`display`),c&&(o?a.insertBefore(e,o):a?a.appendChild(e):Do.removeChild(e))),t&&i.length>6?[i[0],i[1],i[4],i[5],i[12],i[13]]:i)},Ms=function(e,t,n,r,i,a){var o=e._gsap,s=i||js(e,!0),c=o.xOrigin||0,l=o.yOrigin||0,u=o.xOffset||0,d=o.yOffset||0,f=s[0],p=s[1],m=s[2],h=s[3],g=s[4],_=s[5],v=t.split(` `),y=parseFloat(v[0])||0,b=parseFloat(v[1])||0,x,S,C,w;n?s!==Ds&&(S=f*h-p*m)&&(C=h/S*y+b*(-m/S)+(m*_-h*g)/S,w=y*(-p/S)+f/S*b-(f*_-p*g)/S,y=C,b=w):(x=ms(e),y=x.x+(~v[0].indexOf(`%`)?y/100*x.width:y),b=x.y+(~(v[1]||v[0]).indexOf(`%`)?b/100*x.height:b)),r||r!==!1&&o.smooth?(g=y-c,_=b-l,o.xOffset=u+(g*f+_*m)-g,o.yOffset=d+(g*p+_*h)-_):o.xOffset=o.yOffset=0,o.xOrigin=y,o.yOrigin=b,o.smooth=!!r,o.origin=t,o.originIsAbsolute=!!n,e.style[ts]=`0px 0px`,a&&(_s(a,o,`xOrigin`,c,y),_s(a,o,`yOrigin`,l,b),_s(a,o,`xOffset`,u,o.xOffset),_s(a,o,`yOffset`,d,o.yOffset)),e.setAttribute(`data-svg-origin`,y+` `+b)},Ns=function(e,t){var n=e._gsap||new Pa(e);if(`x`in n&&!t&&!n.uncache)return n;var r=e.style,i=n.scaleX<0,a=`px`,o=`deg`,s=getComputedStyle(e),c=cs(e,ts)||`0`,l=u=d=m=h=g=_=v=y=0,u,d,f=p=1,p,m,h,g,_,v,y,b,x,S,C,w,T,E,D,O,k,A,j,M,N,P,F,I,L,R,ee,te;return n.svg=!!(e.getCTM&&hs(e)),s.translate&&((s.translate!==`none`||s.scale!==`none`||s.rotate!==`none`)&&(r[$]=(s.translate===`none`?``:`translate3d(`+(s.translate+` 0 0`).split(` `).slice(0,3).join(`, `)+`) `)+(s.rotate===`none`?``:`rotate(`+s.rotate+`) `)+(s.scale===`none`?``:`scale(`+s.scale.split(` `).join(`,`)+`) `)+(s[$]===`none`?``:s[$])),r.scale=r.rotate=r.translate=`none`),S=js(e,n.svg),n.svg&&(n.uncache?(N=e.getBBox(),c=n.xOrigin-N.x+`px `+(n.yOrigin-N.y)+`px`,M=``):M=!t&&e.getAttribute(`data-svg-origin`),Ms(e,M||c,!!M||n.originIsAbsolute,n.smooth!==!1,S)),b=n.xOrigin||0,x=n.yOrigin||0,S!==Ds&&(E=S[0],D=S[1],O=S[2],k=S[3],l=A=S[4],u=j=S[5],S.length===6?(f=Math.sqrt(E*E+D*D),p=Math.sqrt(k*k+O*O),m=E||D?Io(D,E)*Po:0,_=O||k?Io(O,k)*Po+m:0,_&&(p*=Math.abs(Math.cos(_*Fo))),n.svg&&(l-=b-(b*E+x*O),u-=x-(b*D+x*k))):(te=S[6],R=S[7],F=S[8],I=S[9],L=S[10],ee=S[11],l=S[12],u=S[13],d=S[14],C=Io(te,L),h=C*Po,C&&(w=Math.cos(-C),T=Math.sin(-C),M=A*w+F*T,N=j*w+I*T,P=te*w+L*T,F=A*-T+F*w,I=j*-T+I*w,L=te*-T+L*w,ee=R*-T+ee*w,A=M,j=N,te=P),C=Io(-O,L),g=C*Po,C&&(w=Math.cos(-C),T=Math.sin(-C),M=E*w-F*T,N=D*w-I*T,P=O*w-L*T,ee=k*T+ee*w,E=M,D=N,O=P),C=Io(D,E),m=C*Po,C&&(w=Math.cos(C),T=Math.sin(C),M=E*w+D*T,N=A*w+j*T,D=D*w-E*T,j=j*w-A*T,E=M,A=N),h&&Math.abs(h)+Math.abs(m)>359.9&&(h=m=0,g=180-g),f=J(Math.sqrt(E*E+D*D+O*O)),p=J(Math.sqrt(j*j+te*te)),C=Io(A,j),_=Math.abs(C)>2e-4?C*Po:0,y=ee?1/(ee<0?-ee:ee):0),n.svg&&(M=e.getAttribute(`transform`),n.forceCSS=e.setAttribute(`transform`,``)||!ks(cs(e,$)),M&&e.setAttribute(`transform`,M))),Math.abs(_)>90&&Math.abs(_)<270&&(i?(f*=-1,_+=m<=0?180:-180,m+=m<=0?180:-180):(p*=-1,_+=_<=0?180:-180)),t||=n.uncache,n.x=l-((n.xPercent=l&&(!t&&n.xPercent||(Math.round(e.offsetWidth/2)===Math.round(-l)?-50:0)))?e.offsetWidth*n.xPercent/100:0)+a,n.y=u-((n.yPercent=u&&(!t&&n.yPercent||(Math.round(e.offsetHeight/2)===Math.round(-u)?-50:0)))?e.offsetHeight*n.yPercent/100:0)+a,n.z=d+a,n.scaleX=J(f),n.scaleY=J(p),n.rotation=J(m)+o,n.rotationX=J(h)+o,n.rotationY=J(g)+o,n.skewX=_+o,n.skewY=v+o,n.transformPerspective=y+a,(n.zOrigin=parseFloat(c.split(` `)[2])||!t&&n.zOrigin||0)&&(r[ts]=Ps(c)),n.xOffset=n.yOffset=0,n.force3D=Zn.force3D,n.renderTransform=n.svg?Vs:os?Bs:Is,n.uncache=0,n},Ps=function(e){return(e=e.split(` `))[0]+` `+e[1]},Fs=function(e,t,n){var r=zi(t);return J(parseFloat(t)+parseFloat(bs(e,`x`,n+`px`,r)))+r},Is=function(e,t){t.z=`0px`,t.rotationY=t.rotationX=`0deg`,t.force3D=0,Bs(e,t)},Ls=`0deg`,Rs=`0px`,zs=`) `,Bs=function(e,t){var n=t||this,r=n.xPercent,i=n.yPercent,a=n.x,o=n.y,s=n.z,c=n.rotation,l=n.rotationY,u=n.rotationX,d=n.skewX,f=n.skewY,p=n.scaleX,m=n.scaleY,h=n.transformPerspective,g=n.force3D,_=n.target,v=n.zOrigin,y=``,b=g===`auto`&&e&&e!==1||g===!0;if(v&&(u!==Ls||l!==Ls)){var x=parseFloat(l)*Fo,S=Math.sin(x),C=Math.cos(x),w;x=parseFloat(u)*Fo,w=Math.cos(x),a=Fs(_,a,S*w*-v),o=Fs(_,o,-Math.sin(x)*-v),s=Fs(_,s,C*w*-v+v)}h!==Rs&&(y+=`perspective(`+h+zs),(r||i)&&(y+=`translate(`+r+`%, `+i+`%) `),(b||a!==Rs||o!==Rs||s!==Rs)&&(y+=s!==Rs||b?`translate3d(`+a+`, `+o+`, `+s+`) `:`translate(`+a+`, `+o+zs),c!==Ls&&(y+=`rotate(`+c+zs),l!==Ls&&(y+=`rotateY(`+l+zs),u!==Ls&&(y+=`rotateX(`+u+zs),(d!==Ls||f!==Ls)&&(y+=`skew(`+d+`, `+f+zs),(p!==1||m!==1)&&(y+=`scale(`+p+`, `+m+zs),_.style[$]=y||`translate(0, 0)`},Vs=function(e,t){var n=t||this,r=n.xPercent,i=n.yPercent,a=n.x,o=n.y,s=n.rotation,c=n.skewX,l=n.skewY,u=n.scaleX,d=n.scaleY,f=n.target,p=n.xOrigin,m=n.yOrigin,h=n.xOffset,g=n.yOffset,_=n.forceCSS,v=parseFloat(a),y=parseFloat(o),b,x,S,C,w;s=parseFloat(s),c=parseFloat(c),l=parseFloat(l),l&&(l=parseFloat(l),c+=l,s+=l),s||c?(s*=Fo,c*=Fo,b=Math.cos(s)*u,x=Math.sin(s)*u,S=Math.sin(s-c)*-d,C=Math.cos(s-c)*d,c&&(l*=Fo,w=Math.tan(c-l),w=Math.sqrt(1+w*w),S*=w,C*=w,l&&(w=Math.tan(l),w=Math.sqrt(1+w*w),b*=w,x*=w)),b=J(b),x=J(x),S=J(S),C=J(C)):(b=u,C=d,x=S=0),(v&&!~(a+``).indexOf(`px`)||y&&!~(o+``).indexOf(`px`))&&(v=bs(f,`x`,a,`px`),y=bs(f,`y`,o,`px`)),(p||m||h||g)&&(v=J(v+p-(p*b+m*S)+h),y=J(y+m-(p*x+m*C)+g)),(r||i)&&(w=f.getBBox(),v=J(v+r/100*w.width),y=J(y+i/100*w.height)),w=`matrix(`+b+`,`+x+`,`+S+`,`+C+`,`+v+`,`+y+`)`,f.setAttribute(`transform`,w),_&&(f.style[$]=w)},Hs=function(e,t,n,r,i){var a=360,o=G(i),s=parseFloat(i)*(o&&~i.indexOf(`rad`)?Po:1)-r,c=r+s+`deg`,l,u;return o&&(l=i.split(`_`)[1],l===`short`&&(s%=a,s!==s%(a/2)&&(s+=s<0?a:-a)),l===`cw`&&s<0?s=(s+a*Lo)%a-~~(s/a)*a:l===`ccw`&&s>0&&(s=(s-a*Lo)%a-~~(s/a)*a)),e._pt=u=new lo(e._pt,t,n,r,s,Uo),u.e=c,u.u=`deg`,e._props.push(n),u},Us=function(e,t){for(var n in t)e[n]=t[n];return e},Ws=function(e,t,n){var r=Us({},n._gsap),i=`perspective,force3D,transformOrigin,svgOrigin`,a=n.style,o,s,c,l,u,d,f,p;for(s in r.svg?(c=n.getAttribute(`transform`),n.setAttribute(`transform`,``),a[$]=t,o=Ns(n,1),gs(n,$),n.setAttribute(`transform`,c)):(c=getComputedStyle(n)[$],a[$]=t,o=Ns(n,1),a[$]=c),No)c=r[s],l=o[s],c!==l&&i.indexOf(s)<0&&(f=zi(c),p=zi(l),u=f===p?parseFloat(c):bs(n,s,c,p),d=parseFloat(l),e._pt=new lo(e._pt,o,s,u,d-u,Ho),e._pt.u=p||0,e._props.push(s));Us(o,r)};Zr(`padding,margin,Width,Radius`,function(e,t){var n=`Top`,r=`Right`,i=`Bottom`,a=`Left`,o=(t<3?[n,r,i,a]:[n+a,n+r,i+r,i+a]).map(function(n){return t<2?e+n:`border`+n+e});Es[t>1?`border`+e:e]=function(e,t,n,r,i){var a,s;if(arguments.length<4)return a=o.map(function(t){return xs(e,t,n)}),s=a.join(` `),s.split(a[0]).length===5?a[0]:s;a=(r+``).split(` `),s={},o.forEach(function(e,t){return s[e]=a[t]=a[t]||a[(t-1)/2|0]}),e.init(t,s,i)}});var Gs={name:`css`,register:ds,targetTest:function(e){return e.style&&e.nodeType},init:function(e,t,n,r,i){var a=this._props,o=e.style,s=n.vars.startAt,c,l,u,d,f,p,m,h,g,_,v,y,b,x,S,C,w;for(m in Oo||ds(),this.styles=this.styles||as(e),C=this.styles.props,this.tween=n,t)if(m!==`autoRound`&&(l=t[m],!(Ur[m]&&Ba(m,t,n,r,e,i)))){if(f=typeof l,p=Es[m],f===`function`&&(l=l.call(n,r,e,i),f=typeof l),f===`string`&&~l.indexOf(`random(`)&&(l=ra(l)),p)p(this,e,m,l,n)&&(S=1);else if(m.substr(0,2)===`--`)c=(getComputedStyle(e).getPropertyValue(m)+``).trim(),l+=``,_a.lastIndex=0,_a.test(c)||(h=zi(c),g=zi(l),g?h!==g&&(c=bs(e,m,c,g)+g):h&&(l+=h)),this.add(o,`setProperty`,c,l,r,i,0,0,m),a.push(m),C.push(m,0,o[m]);else if(f!==`undefined`){if(s&&m in s?(c=typeof s[m]==`function`?s[m].call(n,r,e,i):s[m],G(c)&&~c.indexOf(`random(`)&&(c=ra(c)),zi(c+``)||c===`auto`||(c+=Zn.units[m]||zi(xs(e,m))||``),(c+``).charAt(1)===`=`&&(c=xs(e,m))):c=xs(e,m),d=parseFloat(c),_=f===`string`&&l.charAt(1)===`=`&&l.substr(0,2),_&&(l=l.substr(2)),u=parseFloat(l),m in Vo&&(m===`autoAlpha`&&(d===1&&xs(e,`visibility`)===`hidden`&&u&&(d=0),C.push(`visibility`,0,o.visibility),_s(this,o,`visibility`,d?`inherit`:`hidden`,u?`inherit`:`hidden`,!u)),m!==`scale`&&m!==`transform`&&(m=Vo[m],~m.indexOf(`,`)&&(m=m.split(`,`)[0]))),v=m in No,v){if(this.styles.save(m),w=l,f===`string`&&l.substring(0,6)===`var(--`){if(l=cs(e,l.substring(4,l.indexOf(`)`))),l.substring(0,5)===`calc(`){var T=e.style.perspective;e.style.perspective=l,l=cs(e,`perspective`),T?e.style.perspective=T:gs(e,`perspective`)}u=parseFloat(l)}if(y||(b=e._gsap,b.renderTransform&&!t.parseTransform||Ns(e,t.parseTransform),x=t.smoothOrigin!==!1&&b.smooth,y=this._pt=new lo(this._pt,o,$,0,1,b.renderTransform,b,0,-1),y.dep=1),m===`scale`)this._pt=new lo(this._pt,b,`scaleY`,b.scaleY,(_?Qr(b.scaleY,_+u):u)-b.scaleY||0,Ho),this._pt.u=0,a.push(`scaleY`,m),m+=`X`;else if(m===`transformOrigin`){C.push(ts,0,o[ts]),l=ws(l),b.svg?Ms(e,l,0,x,0,this):(g=parseFloat(l.split(` `)[2])||0,g!==b.zOrigin&&_s(this,b,`zOrigin`,b.zOrigin,g),_s(this,o,m,Ps(c),Ps(l)));continue}else if(m===`svgOrigin`){Ms(e,l,1,x,0,this);continue}else if(m in Os){Hs(this,b,m,d,_?Qr(d,_+l):l);continue}else if(m===`smoothOrigin`){_s(this,b,`smooth`,b.smooth,l);continue}else if(m===`force3D`){b[m]=l;continue}else if(m===`transform`){Ws(this,l,e);continue}}else m in o||(m=us(m)||m);if(v||(u||u===0)&&(d||d===0)&&!Bo.test(l)&&m in o)h=(c+``).substr((d+``).length),u||=0,g=zi(l)||(m in Zn.units?Zn.units[m]:h),h!==g&&(d=bs(e,m,c,g)),this._pt=new lo(this._pt,v?b:o,m,d,(_?Qr(d,_+u):u)-d,!v&&(g===`px`||m===`zIndex`)&&t.autoRound!==!1?Ko:Ho),this._pt.u=g||0,v&&w!==l?(this._pt.b=c,this._pt.e=w,this._pt.r=Go):h!==g&&g!==`%`&&(this._pt.b=c,this._pt.r=Wo);else if(m in o)Ss.call(this,e,m,c,_?_+l:l);else if(m in e)this.add(e,m,c||e[m],_?_+l:l,r,i);else if(m!==`parseTransform`){Mr(m,l);continue}v||(m in o?C.push(m,0,o[m]):typeof e[m]==`function`?C.push(m,2,e[m]()):C.push(m,1,c||e[m])),a.push(m)}}S&&co(this)},render:function(e,t){if(t.tween._time||!jo())for(var n=t._pt;n;)n.r(e,n.d),n=n._next;else t.styles.revert()},get:xs,aliases:Vo,getSetter:function(e,t,n){var r=Vo[t];return r&&r.indexOf(`,`)<0&&(t=r),t in No&&t!==ts&&(e._gsap.x||xs(e,`x`))?n&&Ao===n?t===`scale`?Qo:Zo:(Ao=n||{})&&(t===`scale`?$o:es):e.style&&!lr(e.style[t])?Yo:~t.indexOf(`-`)?Xo:eo(e,t)},core:{_removeProperty:gs,_getMatrix:js}};wo.utils.checkPrefix=us,wo.core.getStyleSaver=as,(function(e,t,n,r){var i=Zr(e+`,`+t+`,`+n,function(e){No[e]=1});Zr(t,function(e){Zn.units[e]=`deg`,Os[e]=1}),Vo[i[13]]=e+`,`+t,Zr(r,function(e){var t=e.split(`:`);Vo[t[1]]=i[t[0]]})})(`x,y,z,scale,scaleX,scaleY,xPercent,yPercent`,`rotation,rotationX,rotationY,skewX,skewY`,`transform,transformOrigin,svgOrigin,force3D,smoothOrigin,transformPerspective`,`0:translateX,1:translateY,2:translateZ,8:rotate,8:rotationZ,8:rotateZ,9:rotateX,10:rotateY`),Zr(`x,y,z,top,right,bottom,left,width,height,fontSize,padding,margin,perspective`,function(e){Zn.units[e]=`px`}),wo.registerPlugin(Gs);var Ks=wo.registerPlugin(Gs)||wo;Ks.core.Tween;var qs=null,Js=null,Ys=null,Xs=!1,Zs=[],Qs=0;function $s(){if(document.getElementById(`command-palette-overlay`))return;qs=document.createElement(`div`),qs.id=`command-palette-overlay`,qs.className=`command-palette-overlay`,qs.innerHTML=`
3940
+ `,$.querySelectorAll(`.db-switcher-item`).forEach(t=>{t.addEventListener(`click`,async n=>{if(n.target.closest(`.db-remove-btn`))return;let r=t.getAttribute(`data-id`),i=e.find(e=>e.id===r);i&&($.classList.add(`hidden`),document.getElementById(`breadcrumb-db-crumb`)?.classList.remove(`is-open`),await Jr(i))})}),$.querySelectorAll(`.db-remove-btn`).forEach(e=>{e.addEventListener(`click`,t=>{t.stopPropagation();let n=e.getAttribute(`data-id`);n&&(qr(n),ni())})});let r=document.getElementById(`db-switcher-new-btn`);r&&r.addEventListener(`click`,e=>{e.stopPropagation(),$.classList.add(`hidden`),document.getElementById(`breadcrumb-db-crumb`)?.classList.remove(`is-open`),typeof window.handleSwitchTab==`function`&&window.handleSwitchTab(`connect-btn`)})}function ri(e){return e?String(e).replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`).replace(/"/g,`&quot;`):``}var ii=null,ai=null,oi=null,si=!1,ci=[],li=0;function ui(){if(document.getElementById(`command-palette-overlay`))return;ii=document.createElement(`div`),ii.id=`command-palette-overlay`,ii.className=`command-palette-overlay`,ii.innerHTML=`
3191
3941
  <div class="command-palette-modal" id="command-palette-modal">
3192
3942
  <div class="command-palette-header">
3193
3943
  <span class="material-symbols-outlined search-icon">search</span>
@@ -3195,7 +3945,7 @@ $1`)}),t=t.replace(/[ \t]+(AND\b|OR\b)/g,`
3195
3945
  type="text"
3196
3946
  class="command-palette-input"
3197
3947
  id="command-palette-input"
3198
- placeholder="Search tables, views, or commands..."
3948
+ placeholder="Search tables, commands, or type SQL to run directly..."
3199
3949
  autocomplete="off"
3200
3950
  spellcheck="false"
3201
3951
  />
@@ -3211,25 +3961,25 @@ $1`)}),t=t.replace(/[ \t]+(AND\b|OR\b)/g,`
3211
3961
  <span class="font-mono text-soft">Drixio Command</span>
3212
3962
  </div>
3213
3963
  </div>
3214
- `,document.body.appendChild(qs),Js=document.getElementById(`command-palette-input`),Ys=document.getElementById(`command-palette-results`),document.getElementById(`command-palette-modal`);let e=document.getElementById(`command-palette-esc-btn`);qs.addEventListener(`click`,e=>{e.target===qs&&tc()}),e?.addEventListener(`click`,tc),Js.addEventListener(`input`,()=>{rc(Js.value.trim())}),Js.addEventListener(`keydown`,e=>{e.key===`ArrowDown`?(e.preventDefault(),Zs.length>0&&(Qs=(Qs+1)%Zs.length,ic())):e.key===`ArrowUp`?(e.preventDefault(),Zs.length>0&&(Qs=(Qs-1+Zs.length)%Zs.length,ic())):e.key===`Enter`?(e.preventDefault(),Zs[Qs]&&oc(Zs[Qs])):e.key===`Escape`&&(e.preventDefault(),tc())}),window.openCommandPalette=ec,window.closeCommandPalette=tc}function ec(){qs||$s(),Xs=!0,Qs=0,Js.value=``,qs.classList.add(`is-open`);let e=document.getElementById(`command-palette-modal`);window.gsap&&e&&gsap.fromTo(e,{opacity:0,scale:.95,y:-15},{opacity:1,scale:1,y:0,duration:.2,ease:`power2.out`}),rc(``),setTimeout(()=>Js?.focus(),50)}function tc(){if(!Xs||!qs)return;Xs=!1;let e=document.getElementById(`command-palette-modal`);window.gsap&&e?gsap.to(e,{opacity:0,scale:.96,y:-10,duration:.15,ease:`power2.in`,onComplete:()=>{qs.classList.remove(`is-open`)}}):qs.classList.remove(`is-open`)}function nc(){let e=[];return document.querySelectorAll(`.table-btn`).forEach(t=>{let n=t.dataset.table;n&&e.push({group:`Tables`,id:`table-${n}`,icon:`table`,title:n,desc:`Open table in Data Editor`,badge:`Table`,action:()=>{window.AppState.currentTable=n,window.AppState.currentTableBtnElement=t,document.querySelectorAll(`.table-btn`).forEach(e=>e.classList.remove(`active`)),t.classList.add(`active`),window.handleSwitchTab(`data-btn`)}})}),e.push({group:`Views`,id:`view-sql`,icon:`terminal`,title:`SQL Console`,desc:`Execute raw SQL queries & analyze execution plans`,badge:`Console`,action:()=>window.handleSwitchTab(`sql-btn`)},{group:`Views`,id:`view-status`,icon:`monitoring`,title:`Database Status & Metrics`,desc:`View real-time database metrics, performance and storage`,badge:`Dashboard`,action:()=>window.handleSwitchTab(`status-btn`)},{group:`Views`,id:`view-erd`,icon:`account_tree`,title:`Visual ERD Diagram`,desc:`Interactive schema relation diagram and canvas`,badge:`Diagram`,action:()=>window.handleSwitchTab(`erd-btn`)},{group:`Views`,id:`view-connect`,icon:`cable`,title:`Connect Database`,desc:`Configure connection string or switch database instances`,badge:`Connection`,action:()=>window.handleSwitchTab(`connect-btn`)},{group:`Views`,id:`view-schema`,icon:`schema`,title:`Schema Viewer`,desc:`Inspect columns, indexes, and constraints`,badge:`Schema`,action:()=>window.handleSwitchTab(`schema-btn`)}),e.push({group:`Actions`,id:`action-theme`,icon:`dark_mode`,title:`Toggle Color Theme`,desc:`Switch between light and dark visual modes`,badge:`Theme`,action:()=>document.getElementById(`theme-toggle`)?.click()},{group:`Actions`,id:`action-create-table`,icon:`add_box`,title:`Create New Table`,desc:`Design and create a new database table schema`,badge:`Schema`,action:()=>window.openCreateTableModal?.()},{group:`Actions`,id:`action-export-db`,icon:`download`,title:`Export Full Database Backup`,desc:`Download complete SQL schema & data dump`,badge:`.sql`,action:()=>window.open(`/api/database/export`,`_blank`)},{group:`Actions`,id:`action-export-ddl`,icon:`description`,title:`Export Schema DDL Only`,desc:`Download CREATE TABLE statements without rows`,badge:`.sql`,action:()=>window.open(`/api/database/schema-only`,`_blank`)},{group:`Actions`,id:`action-export-dict`,icon:`menu_book`,title:`Export Data Dictionary`,desc:`Download schema markdown documentation`,badge:`.md`,action:()=>window.open(`/api/database/dictionary`,`_blank`)},{group:`Actions`,id:`action-import-data`,icon:`upload`,title:`Import & Restore Data`,desc:`Import SQL script or JSON dataset into database`,badge:`Import`,action:()=>Sn(`records`)},{group:`Actions`,id:`action-refresh`,icon:`refresh`,title:`Refresh Data & Tables`,desc:`Reload database schema and table rows`,badge:`Reload`,action:()=>{document.getElementById(`header-refresh-btn`)?.click()}}),e}function rc(e){let t=e.toLowerCase(),n=nc();if(Zs=t?n.filter(e=>e.title.toLowerCase().includes(t)||e.desc.toLowerCase().includes(t)||e.badge.toLowerCase().includes(t)||e.group.toLowerCase().includes(t)):n,Qs=Math.min(Qs,Math.max(0,Zs.length-1)),Zs.length===0){Ys.innerHTML=`
3964
+ `,document.body.appendChild(ii),ai=document.getElementById(`command-palette-input`),oi=document.getElementById(`command-palette-results`),document.getElementById(`command-palette-modal`);let e=document.getElementById(`command-palette-esc-btn`);ii.addEventListener(`click`,e=>{e.target===ii&&fi()}),e?.addEventListener(`click`,fi),ai.addEventListener(`input`,()=>{mi(ai.value.trim())}),ai.addEventListener(`keydown`,e=>{e.key===`ArrowDown`?(e.preventDefault(),ci.length>0&&(li=(li+1)%ci.length,hi())):e.key===`ArrowUp`?(e.preventDefault(),ci.length>0&&(li=(li-1+ci.length)%ci.length,hi())):e.key===`Enter`?(e.preventDefault(),ci[li]&&_i(ci[li])):e.key===`Escape`&&(e.preventDefault(),fi())}),window.openCommandPalette=di,window.closeCommandPalette=fi}function di(){ii||ui(),si=!0,li=0,ai.value=``,ii.classList.add(`is-open`);let e=document.getElementById(`command-palette-modal`);e&&e.animate([{opacity:0,transform:`translateY(-15px) scale(0.95)`},{opacity:1,transform:`translateY(0) scale(1)`}],{duration:200,easing:`cubic-bezier(0.16, 1, 0.3, 1)`,fill:`forwards`}),mi(``),setTimeout(()=>ai?.focus(),50)}function fi(){if(!si||!ii)return;si=!1;let e=document.getElementById(`command-palette-modal`);if(e){let t=e.animate([{opacity:1,transform:`translateY(0) scale(1)`},{opacity:0,transform:`translateY(-10px) scale(0.95)`}],{duration:150,easing:`cubic-bezier(0.4, 0, 1, 1)`,fill:`forwards`});t.onfinish=()=>{ii?.classList.remove(`is-open`)}}else ii.classList.remove(`is-open`)}function pi(){let e=[];return document.querySelectorAll(`.table-btn`).forEach(t=>{let n=t.dataset.table;n&&e.push({group:`Tables`,id:`table-${n}`,icon:`table`,title:n,desc:`Open table in Data Editor`,badge:`Table`,action:()=>{window.AppState.currentTable=n,window.AppState.currentTableBtnElement=t,document.querySelectorAll(`.table-btn`).forEach(e=>e.classList.remove(`active`)),t.classList.add(`active`),window.handleSwitchTab(`data-btn`)}})}),e.push({group:`Views`,id:`view-sql`,icon:`terminal`,title:`SQL Console`,desc:`Execute raw SQL queries & analyze execution plans`,badge:`Console`,action:()=>window.handleSwitchTab(`sql-btn`)},{group:`Views`,id:`view-status`,icon:`monitoring`,title:`Database Status & Metrics`,desc:`View real-time database metrics, performance and storage`,badge:`Dashboard`,action:()=>window.handleSwitchTab(`status-btn`)},{group:`Views`,id:`view-erd`,icon:`account_tree`,title:`Visual ERD Diagram`,desc:`Interactive schema relation diagram and canvas`,badge:`Diagram`,action:()=>window.handleSwitchTab(`erd-btn`)},{group:`Views`,id:`view-connect`,icon:`cable`,title:`Connect Database`,desc:`Configure connection string or switch database instances`,badge:`Connection`,action:()=>window.handleSwitchTab(`connect-btn`)},{group:`Views`,id:`view-schema`,icon:`schema`,title:`Schema Viewer`,desc:`Inspect columns, indexes, and constraints`,badge:`Schema`,action:()=>window.handleSwitchTab(`schema-btn`)}),e.push({group:`AI & Safety`,id:`action-ask-ai`,icon:`auto_awesome`,title:`Ask AI SQL Assistant`,desc:`Open AI Copilot right panel to write or optimize SQL queries`,badge:`Ctrl+I`,action:()=>{window.handleSwitchTab&&window.handleSwitchTab(`sql-btn`),setTimeout(()=>{window.toggleConsoleAiBar?window.toggleConsoleAiBar():document.getElementById(`console-ai-btn`)?.click()},80)}},{group:`AI & Safety`,id:`action-ai-config`,icon:`tune`,title:`AI Configuration & Models`,desc:`Configure DeepSeek, Ollama, OpenAI API keys and provider presets`,badge:`AI Config`,action:()=>{hn()}},{group:`AI & Safety`,id:`action-safe-mode`,icon:`security`,title:`Toggle Safe Mode (Production Guard)`,desc:`Protect against accidental UPDATE/DELETE/DROP queries without confirmation`,badge:`Safe Mode`,action:()=>{let e=Vt();Ht(!e),window.showToast?.(e?`Safe Mode disabled (Guard OFF)`:`Safe Mode enabled (Destructive query guard ON)`,e?`info`:`success`)}},{group:`AI & Safety`,id:`action-health-doctor`,icon:`health_and_safety`,title:`Run Schema Health Doctor`,desc:`Audit tables for missing PKs, unindexed foreign keys, and antipatterns`,badge:`Health Check`,action:()=>{De(()=>import(`./healthModal-Wc69raxJ.js`).then(e=>e.openHealthModal()),[],import.meta.url)}},{group:`AI & Safety`,id:`action-recycle-bin`,icon:`delete`,title:`Open Table Recycle Bin`,desc:`View, restore, or purge soft-deleted database tables`,badge:`Recycle Bin`,action:()=>{De(()=>import(`./recycleBinModal-CM1yVRKo.js`).then(e=>e.openRecycleBinModal()),[],import.meta.url)}}),e.push({group:`Actions`,id:`action-theme`,icon:`dark_mode`,title:`Toggle Color Theme`,desc:`Switch between light and dark visual modes`,badge:`Theme`,action:()=>document.getElementById(`theme-toggle`)?.click()},{group:`Actions`,id:`action-create-table`,icon:`add_box`,title:`Create New Table`,desc:`Design and create a new database table schema`,badge:`Schema`,action:()=>window.openCreateTableModal?.()},{group:`Actions`,id:`action-export-db`,icon:`download`,title:`Export Full Database Backup`,desc:`Download complete SQL schema & data dump`,badge:`.sql`,action:()=>window.open(`/api/database/export`,`_blank`)},{group:`Actions`,id:`action-create-app-launcher`,icon:`install_desktop`,title:`Install Desktop App Shortcut`,desc:`Create a 1-click desktop shortcut to launch Drixio directly without terminal commands`,badge:`Desktop App`,action:async()=>{let e=await ne();e.success?window.showToast?.(e.message,`success`):window.showToast?.(`Failed: ${e.error}`,`error`)}},{group:`Actions`,id:`action-export-ddl`,icon:`description`,title:`Export Schema DDL Only`,desc:`Download CREATE TABLE statements without rows`,badge:`.sql`,action:()=>window.open(`/api/database/schema-only`,`_blank`)},{group:`Actions`,id:`action-export-dict`,icon:`menu_book`,title:`Export Data Dictionary`,desc:`Download schema markdown documentation`,badge:`.md`,action:()=>window.open(`/api/database/dictionary`,`_blank`)},{group:`Actions`,id:`action-import-data`,icon:`upload`,title:`Import & Restore Data`,desc:`Import SQL script or JSON dataset into database`,badge:`Import`,action:()=>jr(`records`)},{group:`Actions`,id:`action-refresh`,icon:`refresh`,title:`Refresh Data & Tables`,desc:`Reload database schema and table rows`,badge:`Reload`,action:()=>{document.getElementById(`header-refresh-btn`)?.click()}}),e}function mi(e){let t=(e||``).trim(),n=t.toLowerCase(),r=pi(),i=n?r.filter(e=>e.title.toLowerCase().includes(n)||e.desc.toLowerCase().includes(n)||e.badge.toLowerCase().includes(n)||e.group.toLowerCase().includes(n)):r;if(/^\s*(SELECT|INSERT|UPDATE|DELETE|CREATE|ALTER|DROP|WITH|PRAGMA|EXPLAIN|SHOW)\b/i.test(t)||t.startsWith(`>`)){let e=t.replace(/^>\s*/,``);i=[{group:`Direct SQL Command`,id:`action-direct-sql-exec`,icon:`play_circle`,title:`Execute SQL: "${e.length>45?e.slice(0,45)+`...`:e}"`,desc:`Switch to SQL Editor and execute query immediately`,badge:`↵ Run Query`,action:()=>{typeof window.runQueryInConsole==`function`?window.runQueryInConsole(e,!0):(window.handleSwitchTab&&window.handleSwitchTab(`sql-btn`),setTimeout(()=>{typeof window.runQueryInConsole==`function`&&window.runQueryInConsole(e,!0)},150))}},...i]}if(ci=i,li=Math.min(li,Math.max(0,ci.length-1)),ci.length===0){oi.innerHTML=`
3215
3965
  <div class="command-palette-empty">
3216
3966
  <span class="material-symbols-outlined">search_off</span>
3217
3967
  <div class="command-palette-empty-text">No matching commands or tables found</div>
3218
3968
  </div>
3219
- `;return}let r={};Zs.forEach((e,t)=>{r[e.group]||(r[e.group]=[]),r[e.group].push({item:e,index:t})});let i=``;for(let[e,t]of Object.entries(r)){i+=`<div class="command-palette-group-title">${e}</div>`;for(let{item:e,index:n}of t)i+=`
3220
- <div class="command-palette-item ${n===Qs?`is-selected`:``}" data-idx="${n}">
3969
+ `;return}let a={};ci.forEach((e,t)=>{a[e.group]||(a[e.group]=[]),a[e.group].push({item:e,index:t})});let o=``;for(let[e,t]of Object.entries(a)){o+=`<div class="command-palette-group-title">${e}</div>`;for(let{item:e,index:n}of t)o+=`
3970
+ <div class="command-palette-item ${n===li?`is-selected`:``}" data-idx="${n}">
3221
3971
  <div class="command-palette-item-left">
3222
3972
  <div class="command-palette-item-icon">
3223
3973
  <span class="material-symbols-outlined">${e.icon}</span>
3224
3974
  </div>
3225
3975
  <div class="command-palette-item-info">
3226
- <div class="command-palette-item-title">${vt(e.title)}</div>
3227
- <div class="command-palette-item-desc">${vt(e.desc)}</div>
3976
+ <div class="command-palette-item-title">${en(e.title)}</div>
3977
+ <div class="command-palette-item-desc">${en(e.desc)}</div>
3228
3978
  </div>
3229
3979
  </div>
3230
3980
  <span class="command-palette-item-badge">${e.badge}</span>
3231
3981
  </div>
3232
- `}Ys.innerHTML=i,Ys.querySelectorAll(`.command-palette-item`).forEach(e=>{e.addEventListener(`click`,()=>{let t=parseInt(e.dataset.idx,10);Zs[t]&&oc(Zs[t])}),e.addEventListener(`mouseenter`,()=>{Qs=parseInt(e.dataset.idx,10),ic()})}),ac()}function ic(){Ys.querySelectorAll(`.command-palette-item`).forEach(e=>{let t=parseInt(e.dataset.idx,10);e.classList.toggle(`is-selected`,t===Qs)}),ac()}function ac(){let e=Ys.querySelector(`.command-palette-item.is-selected`);e&&e.scrollIntoView({block:`nearest`})}function oc(e){tc(),setTimeout(()=>{try{e.action()}catch(e){console.error(`Command execution failed:`,e)}},100)}window.gsap=Ks;var sc=document.getElementById(`header-container`),cc=document.getElementById(`sidebar-container`),lc=document.getElementById(`tab-container`);sc.innerHTML=e,cc.innerHTML=t,lc.innerHTML=n;var uc=document.getElementById(`export-btn`),dc=document.getElementById(`export-dropdown`),fc=document.getElementById(`import-btn`);fc&&fc.addEventListener(`click`,e=>{e.stopPropagation(),dc&&(dc.classList.add(`hidden`),uc?.classList.remove(`is-open`)),Sn(`records`)});var pc=document.getElementById(`header-connect-btn`);pc&&pc.addEventListener(`click`,()=>{window.handleSwitchTab(`connect-btn`)}),Kn(),$s();var mc=document.getElementById(`header-search-pill`);mc&&mc.addEventListener(`click`,()=>{ec()}),document.addEventListener(`keydown`,e=>{(e.ctrlKey||e.metaKey)&&e.key.toLowerCase()===`k`&&(e.preventDefault(),ec())});var hc=document.getElementById(`header-help-btn`);if(hc&&hc.addEventListener(`click`,()=>{Gn()}),uc&&dc){uc.addEventListener(`click`,e=>{e.stopPropagation();let t=dc.classList.contains(`hidden`);dc.classList.toggle(`hidden`),uc.classList.toggle(`is-open`,t);let n=window.AppState.currentTab===`data-btn`,r=window.AppState.currentTab===`console-btn`;document.querySelectorAll(`.data-tab-only`).forEach(e=>{e.style.display=n?`list-item`:`none`}),document.querySelectorAll(`.console-tab-only`).forEach(e=>{e.style.display=r?`list-item`:`none`})}),document.addEventListener(`click`,e=>{!uc.contains(e.target)&&!dc.contains(e.target)&&(dc.classList.add(`hidden`),uc.classList.remove(`is-open`))});let e=(e,t,n=!1)=>{if(dc.classList.add(`hidden`),uc.classList.remove(`is-open`),e===`/api/query/export`){let e=document.querySelector(`#sql-editor textarea`)||document.querySelector(`#sql-editor`),n=``;if(e&&e.value&&(n=e.value),!n&&window.ViewCache&&window.ViewCache.lastQuery&&(n=window.ViewCache.lastQuery),!n){alert(`No SQL query found to export.`);return}fetch(`/api/query/export?format=${t}`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({sql:n})}).then(e=>e.ok?e.blob():e.json().then(e=>{throw Error(e.error||`Export failed`)})).then(e=>{let n=URL.createObjectURL(e),r=document.createElement(`a`);r.href=n,r.download=`query_result_${new Date().getTime()}.${t}`,document.body.appendChild(r),r.click(),r.remove()}).catch(e=>alert(`Failed to export query: `+e.message));return}let r=`${e}?format=${t}`;if(n&&window.DataGrid){let e=Ee?Ee():``,t=window.DataGrid.sortState?.col||``,n=window.DataGrid.sortState?.asc??!0;r+=`&where=${encodeURIComponent(e)}&orderCol=${t}&orderAsc=${n}`}window.open(r,`_blank`)};document.getElementById(`export-data-csv-btn`)?.addEventListener(`click`,()=>{window.AppState.currentTable&&e(`/api/tables/${window.AppState.currentTable}/export`,`csv`)}),document.getElementById(`export-data-json-btn`)?.addEventListener(`click`,()=>{window.AppState.currentTable&&e(`/api/tables/${window.AppState.currentTable}/export`,`json`)}),document.getElementById(`export-data-filtered-csv-btn`)?.addEventListener(`click`,()=>{window.AppState.currentTable&&e(`/api/tables/${window.AppState.currentTable}/export`,`csv`,!0)}),document.getElementById(`export-data-filtered-json-btn`)?.addEventListener(`click`,()=>{window.AppState.currentTable&&e(`/api/tables/${window.AppState.currentTable}/export`,`json`,!0)}),document.getElementById(`export-schema-dict-btn`)?.addEventListener(`click`,()=>{window.open(`/api/database/dictionary`,`_blank`),dc.classList.add(`hidden`),uc.classList.remove(`is-open`)}),document.getElementById(`export-schema-sql-btn`)?.addEventListener(`click`,()=>{window.open(`/api/database/schema-only`,`_blank`),dc.classList.add(`hidden`),uc.classList.remove(`is-open`)}),document.getElementById(`export-schema-snapshot-btn`)?.addEventListener(`click`,()=>{window.open(`/api/schema/snapshot`,`_blank`),dc.classList.add(`hidden`),uc.classList.remove(`is-open`)}),document.getElementById(`export-console-csv-btn`)?.addEventListener(`click`,()=>{e(`/api/query/export`,`csv`)}),document.getElementById(`export-console-json-btn`)?.addEventListener(`click`,()=>{e(`/api/query/export`,`json`)}),document.getElementById(`export-erd-json-btn`)?.addEventListener(`click`,()=>{let e=localStorage.getItem(`drixio_erd_drafts`);if(!e){alert(`No ERD layout found to export.`);return}let t=new Blob([e],{type:`application/json`}),n=URL.createObjectURL(t),r=document.createElement(`a`);r.href=n,r.download=`erd_layout_${new Date().getTime()}.json`,r.click(),dc.classList.add(`hidden`),uc.classList.remove(`is-open`)}),document.getElementById(`export-db-sql-btn`)?.addEventListener(`click`,()=>{window.open(`/api/database/export`,`_blank`),dc.classList.add(`hidden`),uc.classList.remove(`is-open`)})}window.AppState={currentTable:null,currentTab:`data-btn`,currentTableBtnElement:null,dbType:null},window.setStudioConnectionMode=function(e){let t=document.getElementById(`data-btn`),n=document.getElementById(`schema-btn`),r=document.getElementById(`erd-btn`),i=document.getElementById(`status-btn`),a=document.getElementById(`connect-btn`),o=document.getElementById(`export-btn`)?.closest(`.header-dropdown-wrap`),s=document.getElementById(`import-btn`),c=document.getElementById(`slash`),l=document.getElementById(`current-table`),u=document.getElementById(`db-name`),d=document.getElementById(`env-badge`);e?(t?.classList.remove(`hidden`),n?.classList.remove(`hidden`),r?.classList.remove(`hidden`),i?.classList.remove(`hidden`),a?.classList.add(`hidden`),o&&o.classList.remove(`hidden`),s&&s.classList.remove(`hidden`),c&&c.classList.remove(`hidden`),l&&l.classList.remove(`hidden`),d&&d.classList.remove(`hidden`),window.AppState.currentTab===`connect-btn`&&window.handleSwitchTab(`data-btn`)):(t?.classList.add(`hidden`),n?.classList.add(`hidden`),r?.classList.add(`hidden`),i?.classList.add(`hidden`),a?.classList.remove(`hidden`),o&&o.classList.add(`hidden`),s&&s.classList.add(`hidden`),c&&c.classList.add(`hidden`),l&&l.classList.add(`hidden`),d&&d.classList.add(`hidden`),u&&(u.textContent=`No Database`),window.AppState.currentTab!==`connect-btn`&&window.AppState.currentTab!==`sql-btn`&&window.handleSwitchTab(`connect-btn`))},a().then(e=>{if(e&&e.success&&e.data){window.AppState.dbType=e.data.dbType,window.AppState.isRemote=!!e.data.isRemote,window.AppState.badgeLabel=e.data.badgeLabel;let t=document.getElementById(`env-badge`);if(t&&(t.textContent=e.data.badgeLabel||(e.data.isRemote?`REMOTE`:`LOCAL`),t.className=`env-badge ${e.data.isRemote?`remote`:`local`}`),e.data.dbName){let t=document.getElementById(`db-name`);t&&(t.textContent=e.data.dbName)}if(e.data.appVersion){let t=document.getElementById(`sidebar-version-tag`);t&&(t.textContent=`v${e.data.appVersion}`)}e.data.connected&&e.data.dbType&&e.data.dbType!==`none`?(window.setStudioConnectionMode(!0),e.data.targetUrl&&Ln({name:e.data.dbName,dialect:e.data.dbType,url:e.data.targetUrl,isRemote:!!e.data.isRemote,badgeLabel:e.data.badgeLabel})):window.setStudioConnectionMode(!1)}else window.setStudioConnectionMode(!1)}),window.TableStates={},window.ViewCache={},window.updateSidebarDirtyState=function(){document.querySelectorAll(`.table-btn`).forEach(e=>{let t=e.dataset.table,n=e.querySelector(`span`).textContent,r=t||n.replace(/\s*\*$/,``),i=window.TableStates[r],a=!1;if(i){if(i.dataGrid){let e=i.dataGrid;(Object.keys(e.pendingEdits||{}).length>0||e.pendingInserts&&e.pendingInserts.some(e=>Object.keys(e).length>0)||e.pendingDeletes&&e.pendingDeletes.size>0)&&(a=!0)}if(i.schemaGrid){let e=i.schemaGrid,t=e.pendingIndexEdits&&(e.pendingIndexEdits.added.length>0||e.pendingIndexEdits.dropped.length>0);(Object.keys(e.pendingEdits||{}).length>0||e.pendingInserts&&e.pendingInserts.some(e=>Object.keys(e).length>0)||e.pendingDeletes&&e.pendingDeletes.size>0||t)&&(a=!0)}}let o=e.querySelector(`span`),s=o.textContent.replace(/\s*\*$/,``),c=e.querySelector(`.dirty-indicator-dot`);o.textContent=s,a?(o.style.fontWeight=`600`,c&&c.classList.remove(`hidden`)):(o.style.fontWeight=`500`,c&&c.classList.add(`hidden`))})};var gc={data:`data-btn`,schema:`schema-btn`,sql:`sql-btn`,erd:`erd-btn`,status:`status-btn`,connect:`connect-btn`},_c={"data-btn":`data`,"schema-btn":`schema`,"sql-btn":`sql`,"erd-btn":`erd`,"status-btn":`status`,"connect-btn":`connect`};function vc(){let e=window.location.hash.replace(/^#\/?/,``).trim();if(!e)return{route:null,table:null};let t=e.split(`/`);return{route:t[0]?t[0].toLowerCase():null,table:t[1]?decodeURIComponent(t[1]):null}}window.parseHash=vc;function yc(e,t){let n=_c[e]||`data`,r=t===void 0?window.AppState?.currentTable:t,i=`#${n}`;r&&(e===`data-btn`||e===`schema-btn`)&&(i=`#${n}/${encodeURIComponent(r)}`),window.location.hash!==i&&history.replaceState(null,``,i)}window.updateUrlHash=yc,window.getInitialRouteTab=function(){let{route:e}=vc();return e&&gc[e]?gc[e]:null},window.handleSwitchTab=function(e,t=!0){document.querySelectorAll(`.tab-btn`).forEach(e=>e.classList.remove(`isCurrentTab`));let n=document.getElementById(e);n&&n.classList.add(`isCurrentTab`),window.AppState.currentTab=e;let r=document.getElementById(`sidebar-container`);if(e===`data-btn`||e===`schema-btn`?r?.classList.remove(`hidden`):r?.classList.add(`hidden`),e===`erd-btn`||e===`sql-btn`||e===`status-btn`||e===`connect-btn`)window.AppState.currentTable=null,window.AppState.currentTableBtnElement=null,document.querySelectorAll(`.table-btn`).forEach(e=>e.classList.remove(`active`));else if(e===`data-btn`||e===`schema-btn`)if(window.AppState.currentTable)window.updateSidebarActiveTable?.(window.AppState.currentTable);else{let e=document.querySelector(`.table-btn`);e&&(window.AppState.currentTable=e.dataset.table||e.querySelector(`span`).textContent.replace(/\s*\*$/,``),window.AppState.currentTableBtnElement=e,e.classList.add(`active`))}t&&yc(e),window.renderCurrentView()},window.addEventListener(`hashchange`,()=>{let{route:e,table:t}=vc();if(e&&gc[e]){let n=gc[e];if(t&&(n===`data-btn`||n===`schema-btn`)){window.AppState.currentTable=t;let e=document.querySelector(`.table-btn[data-table="${t}"]`);window.AppState.currentTableBtnElement=e||null}(window.AppState.currentTab!==n||t&&window.AppState.currentTable!==t)&&window.handleSwitchTab(n,!1)}}),window.renderEmptyState=function(e){e.innerHTML=`
3982
+ `}oi.innerHTML=o,oi.querySelectorAll(`.command-palette-item`).forEach(e=>{e.addEventListener(`click`,()=>{let t=parseInt(e.dataset.idx,10);ci[t]&&_i(ci[t])}),e.addEventListener(`mouseenter`,()=>{li=parseInt(e.dataset.idx,10),hi()})}),gi()}function hi(){oi.querySelectorAll(`.command-palette-item`).forEach(e=>{let t=parseInt(e.dataset.idx,10);e.classList.toggle(`is-selected`,t===li)}),gi()}function gi(){let e=oi.querySelector(`.command-palette-item.is-selected`);e&&e.scrollIntoView({block:`nearest`})}function _i(e){fi(),setTimeout(()=>{try{e.action()}catch(e){console.error(`Command execution failed:`,e)}},100)}var vi=document.getElementById(`header-container`),yi=document.getElementById(`sidebar-container`),bi=document.getElementById(`tab-container`);vi.innerHTML=t,yi.innerHTML=n,bi.innerHTML=r;var xi=document.getElementById(`export-btn`),Si=document.getElementById(`export-dropdown`),Ci=document.getElementById(`import-btn`);Ci&&Ci.addEventListener(`click`,e=>{e.stopPropagation(),Si&&(Si.classList.add(`hidden`),xi?.classList.remove(`is-open`)),jr(`records`)});var wi=document.getElementById(`header-connect-btn`);wi&&wi.addEventListener(`click`,()=>{window.handleSwitchTab(`connect-btn`)});var Ti=document.getElementById(`header-readonly-btn`);Ti&&Ti.addEventListener(`click`,async()=>{let e=!window.AppState.isReadOnly;try{let t=await s(e);t.success&&(window.updateReadOnlyUI(t.data.readOnly),window.showToast?.(t.data.readOnly?`🔒 Production Shield Enabled: Database is now in READ-ONLY mode.`:`🔓 Read-Only Mode Disabled: Database is now EDITABLE.`,t.data.readOnly?`warning`:`info`),window.renderCurrentView?.())}catch(e){window.showToast?.(e.message||`Failed to toggle read-only mode`,`error`)}}),ti(),ui();var Ei=document.getElementById(`header-search-pill`);Ei&&Ei.addEventListener(`click`,()=>{di()}),document.addEventListener(`keydown`,e=>{(e.ctrlKey||e.metaKey)&&e.key.toLowerCase()===`k`&&(e.preventDefault(),di())});var Di=document.getElementById(`header-help-btn`);if(Di&&Di.addEventListener(`click`,()=>{ei()}),xi&&Si){xi.addEventListener(`click`,e=>{e.stopPropagation();let t=Si.classList.contains(`hidden`);Si.classList.toggle(`hidden`),xi.classList.toggle(`is-open`,t);let n=window.AppState.currentTab===`data-btn`,r=window.AppState.currentTab===`console-btn`;document.querySelectorAll(`.data-tab-only`).forEach(e=>{e.style.display=n?`list-item`:`none`}),document.querySelectorAll(`.console-tab-only`).forEach(e=>{e.style.display=r?`list-item`:`none`})}),document.addEventListener(`click`,e=>{!xi.contains(e.target)&&!Si.contains(e.target)&&(Si.classList.add(`hidden`),xi.classList.remove(`is-open`))});let e=(e,t,n=!1,r=!1)=>{if(Si.classList.add(`hidden`),xi.classList.remove(`is-open`),e===`/api/query/export`){let e=document.querySelector(`#sql-editor textarea`)||document.querySelector(`#sql-editor`),n=``;if(e&&e.value&&(n=e.value),!n&&window.ViewCache&&window.ViewCache.lastQuery&&(n=window.ViewCache.lastQuery),!n){alert(`No SQL query found to export.`);return}fetch(`/api/query/export?format=${t}${r?`&mask=true`:``}`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({sql:n,mask:r})}).then(e=>e.ok?e.blob():e.json().then(e=>{throw Error(e.error||`Export failed`)})).then(e=>{let n=URL.createObjectURL(e),i=document.createElement(`a`);i.href=n,i.download=`query_result_${r?`masked_`:``}${new Date().getTime()}.${t}`,document.body.appendChild(i),i.click(),i.remove()}).catch(e=>alert(`Failed to export query: `+e.message));return}let i=`${e}?format=${t}`;if(r&&(i+=`&mask=true`),n&&window.DataGrid){let e=$e?$e():``,t=window.DataGrid.sortState?.col||``,n=window.DataGrid.sortState?.asc??!0;i+=`&where=${encodeURIComponent(e)}&orderCol=${t}&orderAsc=${n}`}window.open(i,`_blank`)};document.getElementById(`export-data-csv-btn`)?.addEventListener(`click`,()=>{window.AppState.currentTable&&e(`/api/tables/${encodeURIComponent(window.AppState.currentTable)}/export`,`csv`)}),document.getElementById(`export-data-json-btn`)?.addEventListener(`click`,()=>{window.AppState.currentTable&&e(`/api/tables/${encodeURIComponent(window.AppState.currentTable)}/export`,`json`)}),document.getElementById(`export-data-filtered-csv-btn`)?.addEventListener(`click`,()=>{window.AppState.currentTable&&e(`/api/tables/${encodeURIComponent(window.AppState.currentTable)}/export`,`csv`,!0)}),document.getElementById(`export-data-filtered-json-btn`)?.addEventListener(`click`,()=>{window.AppState.currentTable&&e(`/api/tables/${encodeURIComponent(window.AppState.currentTable)}/export`,`json`,!0)}),document.getElementById(`export-data-masked-csv-btn`)?.addEventListener(`click`,()=>{window.AppState.currentTable&&e(`/api/tables/${encodeURIComponent(window.AppState.currentTable)}/export`,`csv`,!1,!0)}),document.getElementById(`export-data-masked-json-btn`)?.addEventListener(`click`,()=>{window.AppState.currentTable&&e(`/api/tables/${encodeURIComponent(window.AppState.currentTable)}/export`,`json`,!1,!0)}),document.getElementById(`export-schema-dict-btn`)?.addEventListener(`click`,()=>{window.open(`/api/database/dictionary`,`_blank`),Si.classList.add(`hidden`),xi.classList.remove(`is-open`)}),document.getElementById(`export-schema-sql-btn`)?.addEventListener(`click`,()=>{window.open(`/api/database/schema-only`,`_blank`),Si.classList.add(`hidden`),xi.classList.remove(`is-open`)}),document.getElementById(`export-schema-snapshot-btn`)?.addEventListener(`click`,()=>{window.open(`/api/schema/snapshot`,`_blank`),Si.classList.add(`hidden`),xi.classList.remove(`is-open`)}),document.getElementById(`export-console-csv-btn`)?.addEventListener(`click`,()=>{e(`/api/query/export`,`csv`)}),document.getElementById(`export-console-json-btn`)?.addEventListener(`click`,()=>{e(`/api/query/export`,`json`)}),document.getElementById(`export-console-masked-csv-btn`)?.addEventListener(`click`,()=>{e(`/api/query/export`,`csv`,!1,!0)}),document.getElementById(`export-console-masked-json-btn`)?.addEventListener(`click`,()=>{e(`/api/query/export`,`json`,!1,!0)}),document.getElementById(`export-erd-json-btn`)?.addEventListener(`click`,()=>{let e=localStorage.getItem(`drixio_erd_drafts`);if(!e){alert(`No ERD layout found to export.`);return}let t=new Blob([e],{type:`application/json`}),n=URL.createObjectURL(t),r=document.createElement(`a`);r.href=n,r.download=`erd_layout_${new Date().getTime()}.json`,r.click(),Si.classList.add(`hidden`),xi.classList.remove(`is-open`)}),document.getElementById(`export-db-sql-btn`)?.addEventListener(`click`,()=>{window.open(`/api/database/export`,`_blank`),Si.classList.add(`hidden`),xi.classList.remove(`is-open`)})}window.AppState={currentTable:null,currentTab:`data-btn`,currentTableBtnElement:null,dbType:null,isReadOnly:!1},window.updateReadOnlyUI=function(e){window.AppState.isReadOnly=!!e;let t=document.getElementById(`header-readonly-btn`),n=document.getElementById(`readonly-icon`),r=document.getElementById(`readonly-label`);t&&(e?(t.classList.add(`readonly-active`),t.title=`Production Shield Active: Read-Only Mode (Click to toggle)`,n&&(n.textContent=`lock`),r&&(r.textContent=`READ-ONLY`)):(t.classList.remove(`readonly-active`),t.title=`Protection OFF: Editable Mode (Click to toggle)`,n&&(n.textContent=`lock_open`),r&&(r.textContent=`EDITABLE`)))},window.setStudioConnectionMode=function(e){let t=document.getElementById(`data-btn`),n=document.getElementById(`schema-btn`),r=document.getElementById(`erd-btn`),i=document.getElementById(`status-btn`),a=document.getElementById(`connect-btn`),o=document.getElementById(`export-btn`)?.closest(`.header-dropdown-wrap`),s=document.getElementById(`import-btn`),c=document.getElementById(`slash`),l=document.getElementById(`current-table`),u=document.getElementById(`db-name`),d=document.getElementById(`env-badge`);e?(t?.classList.remove(`hidden`),n?.classList.remove(`hidden`),r?.classList.remove(`hidden`),i?.classList.remove(`hidden`),a?.classList.add(`hidden`),o&&o.classList.remove(`hidden`),s&&s.classList.remove(`hidden`),c&&c.classList.remove(`hidden`),l&&l.classList.remove(`hidden`),d&&d.classList.remove(`hidden`),window.AppState.currentTab===`connect-btn`&&window.handleSwitchTab(`data-btn`)):(t?.classList.add(`hidden`),n?.classList.add(`hidden`),r?.classList.add(`hidden`),i?.classList.add(`hidden`),a?.classList.remove(`hidden`),o&&o.classList.add(`hidden`),s&&s.classList.add(`hidden`),c&&c.classList.add(`hidden`),l&&l.classList.add(`hidden`),d&&d.classList.add(`hidden`),u&&(u.textContent=`No Database`),window.AppState.currentTab!==`connect-btn`&&window.AppState.currentTab!==`sql-btn`&&window.handleSwitchTab(`connect-btn`))},o().then(e=>{if(e&&e.success&&e.data){window.AppState.dbType=e.data.dbType,window.AppState.isRemote=!!e.data.isRemote,window.AppState.badgeLabel=e.data.badgeLabel,window.updateReadOnlyUI(!!e.data.readOnly);let t=document.getElementById(`env-badge`);if(t&&(t.textContent=e.data.badgeLabel||(e.data.isRemote?`REMOTE`:`LOCAL`),t.className=`env-badge ${e.data.isRemote?`remote`:`local`}`),e.data.dbName){let t=document.getElementById(`db-name`);t&&(t.textContent=e.data.dbName)}if(e.data.appVersion){let t=document.getElementById(`sidebar-version-tag`);t&&(t.textContent=`v${e.data.appVersion}`)}e.data.connected&&e.data.dbType&&e.data.dbType!==`none`?(window.setStudioConnectionMode(!0),e.data.targetUrl&&Kr({name:e.data.dbName,dialect:e.data.dbType,url:e.data.targetUrl,isRemote:!!e.data.isRemote,badgeLabel:e.data.badgeLabel})):window.setStudioConnectionMode(!1)}else window.setStudioConnectionMode(!1)}),window.TableStates={},window.ViewCache={},window.updateSidebarDirtyState=function(){document.querySelectorAll(`.table-btn`).forEach(e=>{let t=e.dataset.table,n=e.querySelector(`span`).textContent,r=t||n.replace(/\s*\*$/,``),i=window.TableStates[r],a=!1;if(i){if(i.dataGrid){let e=i.dataGrid;(Object.keys(e.pendingEdits||{}).length>0||e.pendingInserts&&e.pendingInserts.some(e=>Object.keys(e).length>0)||e.pendingDeletes&&e.pendingDeletes.size>0)&&(a=!0)}if(i.schemaGrid){let e=i.schemaGrid,t=e.pendingIndexEdits&&(e.pendingIndexEdits.added.length>0||e.pendingIndexEdits.dropped.length>0);(Object.keys(e.pendingEdits||{}).length>0||e.pendingInserts&&e.pendingInserts.some(e=>Object.keys(e).length>0)||e.pendingDeletes&&e.pendingDeletes.size>0||t)&&(a=!0)}}let o=e.querySelector(`span`),s=o.textContent.replace(/\s*\*$/,``),c=e.querySelector(`.dirty-indicator-dot`);o.textContent=s,a?(o.style.fontWeight=`600`,c&&c.classList.remove(`hidden`)):(o.style.fontWeight=`500`,c&&c.classList.add(`hidden`))})};var Oi={data:`data-btn`,schema:`schema-btn`,sql:`sql-btn`,erd:`erd-btn`,status:`status-btn`,connect:`connect-btn`},ki={"data-btn":`data`,"schema-btn":`schema`,"sql-btn":`sql`,"erd-btn":`erd`,"status-btn":`status`,"connect-btn":`connect`};function Ai(){let e=window.location.hash.replace(/^#\/?/,``).trim();if(!e)return{route:null,table:null};let t=e.split(`/`);return{route:t[0]?t[0].toLowerCase():null,table:t[1]?decodeURIComponent(t[1]):null}}window.parseHash=Ai;function ji(e,t){let n=ki[e]||`data`,r=t===void 0?window.AppState?.currentTable:t,i=`#${n}`;r&&(e===`data-btn`||e===`schema-btn`)&&(i=`#${n}/${encodeURIComponent(r)}`),window.location.hash!==i&&history.replaceState(null,``,i)}window.updateUrlHash=ji,window.getInitialRouteTab=function(){let{route:e}=Ai();return e&&Oi[e]?Oi[e]:null},window.handleSwitchTab=function(e,t=!0){document.querySelectorAll(`.tab-btn`).forEach(e=>e.classList.remove(`isCurrentTab`));let n=document.getElementById(e);n&&n.classList.add(`isCurrentTab`),window.AppState.currentTab=e;let r=document.getElementById(`sidebar-container`);if(e===`data-btn`||e===`schema-btn`?r?.classList.remove(`hidden`):r?.classList.add(`hidden`),e===`erd-btn`||e===`sql-btn`||e===`status-btn`||e===`connect-btn`)window.AppState.currentTable=null,window.AppState.currentTableBtnElement=null,document.querySelectorAll(`.table-btn`).forEach(e=>e.classList.remove(`active`));else if(e===`data-btn`||e===`schema-btn`)if(window.AppState.currentTable)window.updateSidebarActiveTable?.(window.AppState.currentTable);else{let e=document.querySelector(`.table-btn`);e&&(window.AppState.currentTable=e.dataset.table||e.querySelector(`span`).textContent.replace(/\s*\*$/,``),window.AppState.currentTableBtnElement=e,e.classList.add(`active`))}t&&ji(e),window.renderCurrentView()},window.addEventListener(`hashchange`,()=>{let{route:e,table:t}=Ai();if(e&&Oi[e]){let n=Oi[e];if(t&&(n===`data-btn`||n===`schema-btn`)){window.AppState.currentTable=t;let e=document.querySelector(`.table-btn[data-table="${t}"]`);window.AppState.currentTableBtnElement=e||null}(window.AppState.currentTab!==n||t&&window.AppState.currentTable!==t)&&window.handleSwitchTab(n,!1)}}),window.renderEmptyState=function(e){e.innerHTML=`
3233
3983
  <div class="empty-state">
3234
3984
  <div class="icon-container">
3235
3985
  <span class="material-symbols-outlined">database</span>
@@ -3241,4 +3991,4 @@ $1`)}),t=t.replace(/[ \t]+(AND\b|OR\b)/g,`
3241
3991
  <span>Create Table</span>
3242
3992
  </button>
3243
3993
  </div>
3244
- `;let t=e.querySelector(`#btn-empty-create-table`);t&&(t.onclick=()=>{window.openCreateTableModal?.()})},window.renderCurrentView=function(e=``,t=!1){let n=[`erd-btn`,`sql-btn`,`status-btn`,`connect-btn`].includes(window.AppState.currentTab),r=document.getElementById(`main-content`);document.querySelectorAll(`.view-container`).forEach(e=>e.style.display=`none`);let i=n?`view-${window.AppState.currentTab}`:`view-${window.AppState.currentTab}-${window.AppState.currentTable}`,a=document.getElementById(i);if(a||(a=document.createElement(`div`),a.id=i,a.className=`view-container`,a.style.width=`100%`,a.style.flex=`1`,a.style.display=`flex`,a.style.flexDirection=`column`,a.style.overflow=`hidden`,r.appendChild(a)),a.style.display=`flex`,!window.AppState.currentTable&&!n){window.renderEmptyState(a);return}let o=window.AppState.currentTable;o&&!window.TableStates[o]&&(window.TableStates[o]={dataGrid:null,schemaGrid:null}),window.AppState.currentTab===`data-btn`?(window.TableStates[o].dataGrid&&(window.DataGrid=window.TableStates[o].dataGrid),!window.TableStates[o].dataGrid||!a.hasChildNodes()?Ge(o,window.AppState.currentTableBtnElement,e,t,a):window.updateSidebarActiveTable?.(o)):window.AppState.currentTab===`schema-btn`?(window.TableStates[o].schemaGrid&&(window.SchemaGrid=window.TableStates[o].schemaGrid),!window.TableStates[o].schemaGrid||!a.hasChildNodes()?rt(o,window.AppState.currentTableBtnElement,a):window.updateSidebarActiveTable?.(o)):window.AppState.currentTab===`sql-btn`?a.hasChildNodes()||kt(o,window.AppState.currentTableBtnElement,a):window.AppState.currentTab===`erd-btn`?a.hasChildNodes()||pn(a):window.AppState.currentTab===`status-btn`?a.hasChildNodes()?An():jn(a):window.AppState.currentTab===`connect-btn`&&(a.hasChildNodes()||Bn(a));let s=document.getElementById(`table-icon`),c=document.getElementById(`table-name`);s&&c&&(o?(s.textContent=`table_chart`,c.textContent=o):window.AppState.currentTab===`erd-btn`?(s.textContent=`account_tree`,c.textContent=`ER Diagram`):window.AppState.currentTab===`sql-btn`?(s.textContent=`terminal`,c.textContent=`SQL Console`):window.AppState.currentTab===`status-btn`?(s.textContent=`monitoring`,c.textContent=`Dashboard`):window.AppState.currentTab===`connect-btn`?(s.textContent=`cable`,c.textContent=`Connect Database`):(s.textContent=`table_chart`,c.textContent=`none`)),document.querySelectorAll(`.table-btn`).forEach(e=>e.classList.remove(`active`)),window.AppState.currentTableBtnElement&&window.AppState.currentTableBtnElement.classList.add(`active`)},window.saveDataGridEdits=ke,window.saveSchemaEdits=Ke,document.addEventListener(`DOMContentLoaded`,()=>{ie(),Vn(),Hn(),Un();let e=document.getElementById(`header-refresh-btn`);e&&e.addEventListener(`click`,()=>{let t=e.querySelector(`.material-symbols-outlined`);t?.classList.add(`animate-spin`);let n=window.AppState.currentTab,r=window.AppState.currentTable;if(r){let e=`view-${n}-${r}`,t=document.getElementById(e);t&&(t.innerHTML=``)}window.renderCurrentView(``,!0),setTimeout(()=>{t?.classList.remove(`animate-spin`),window.showToast&&window.showToast(`Data refreshed`,`success`)},350)})});
3994
+ `;let t=e.querySelector(`#btn-empty-create-table`);t&&(t.onclick=()=>{window.openCreateTableModal?.()})},window.renderCurrentView=function(e=``,t=!1){let n=[`erd-btn`,`sql-btn`,`status-btn`,`connect-btn`].includes(window.AppState.currentTab),r=document.getElementById(`main-content`);document.querySelectorAll(`.view-container`).forEach(e=>e.style.display=`none`);let i=n?`view-${window.AppState.currentTab}`:`view-${window.AppState.currentTab}-${window.AppState.currentTable}`,a=document.getElementById(i);if(a||(a=document.createElement(`div`),a.id=i,a.className=`view-container`,a.style.width=`100%`,a.style.flex=`1`,a.style.display=`flex`,a.style.flexDirection=`column`,a.style.overflow=`hidden`,r.appendChild(a)),a.style.display=`flex`,!window.AppState.currentTable&&!n){window.renderEmptyState(a);return}let o=window.AppState.currentTable;o&&!window.TableStates[o]&&(window.TableStates[o]={dataGrid:null,schemaGrid:null}),window.AppState.currentTab===`data-btn`?(window.TableStates[o].dataGrid&&(window.DataGrid=window.TableStates[o].dataGrid),!window.TableStates[o].dataGrid||!a.hasChildNodes()?G(o,window.AppState.currentTableBtnElement,e,t,a):window.updateSidebarActiveTable?.(o)):window.AppState.currentTab===`schema-btn`?(window.TableStates[o].schemaGrid&&(window.SchemaGrid=window.TableStates[o].schemaGrid),!window.TableStates[o].schemaGrid||!a.hasChildNodes()?Bt(o,window.AppState.currentTableBtnElement,a):window.updateSidebarActiveTable?.(o)):window.AppState.currentTab===`sql-btn`?a.hasChildNodes()||Rn(o,window.AppState.currentTableBtnElement,a):window.AppState.currentTab===`erd-btn`?a.hasChildNodes()||br(a):window.AppState.currentTab===`status-btn`?a.hasChildNodes()?zr():Br(a):window.AppState.currentTab===`connect-btn`&&(a.hasChildNodes()||Yr(a));let s=document.getElementById(`table-icon`),c=document.getElementById(`table-name`);s&&c&&(o?(s.textContent=`table_chart`,c.textContent=o):window.AppState.currentTab===`erd-btn`?(s.textContent=`account_tree`,c.textContent=`ER Diagram`):window.AppState.currentTab===`sql-btn`?(s.textContent=`terminal`,c.textContent=`SQL Console`):window.AppState.currentTab===`status-btn`?(s.textContent=`monitoring`,c.textContent=`Dashboard`):window.AppState.currentTab===`connect-btn`?(s.textContent=`cable`,c.textContent=`Connect Database`):(s.textContent=`table_chart`,c.textContent=`none`)),document.querySelectorAll(`.table-btn`).forEach(e=>e.classList.remove(`active`)),window.AppState.currentTableBtnElement&&window.AppState.currentTableBtnElement.classList.add(`active`)},window.saveDataGridEdits=nt,window.saveSchemaEdits=he,document.addEventListener(`DOMContentLoaded`,()=>{ke(),Xr(),Zr(),Qr();let e=document.getElementById(`header-refresh-btn`);e&&e.addEventListener(`click`,()=>{let t=e.querySelector(`.material-symbols-outlined`);t?.classList.add(`animate-spin`);let n=window.AppState.currentTab,r=window.AppState.currentTable;if(r){let e=`view-${n}-${r}`,t=document.getElementById(e);t&&(t.innerHTML=``)}window.renderCurrentView(``,!0),setTimeout(()=>{t?.classList.remove(`animate-spin`),window.showToast&&window.showToast(`Data refreshed`,`success`)},350)})});export{P as a,F as i,te as n,I as r,L as t};