drixio 1.1.4 → 1.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -9,7 +9,7 @@ var Jt=Object.defineProperty;var E=(s,a)=>()=>(s&&(a=s(s=0)),a);var L=(s,a)=>{fo
9
9
  `)+aa(` \u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2554\u255D \u2588\u2588\u2557 \u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D
10
10
  `)+oa(" \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D")))}function se(s,a){let r="\u2550".repeat(72);console.log(N.cyan(`
11
11
  \u2554${r}\u2557`));let o=72-s.length,e=Math.max(0,Math.floor(o/2)),n=Math.max(0,o-e),c=" ".repeat(e)+N.bold(N.white(s))+" ".repeat(n);console.log(N.cyan("\u2551")+c+N.cyan("\u2551")),console.log(N.cyan(`\u2560${"\u2550".repeat(72)}\u2563`));let i=(l,m)=>{let p=l.padEnd(12),u=` ${N.bold(p)}: ${m}`,d=` ${p}: `+m.replace(/\x1b\[[0-9;]*m/g,""),f=" ".repeat(Math.max(0,72-d.length));console.log(N.cyan("\u2551")+u+f+N.cyan("\u2551"))};for(let l of a)i(l.label,l.value);console.log(N.cyan(`\u255A${"\u2550".repeat(72)}\u255D`)),console.log(N.dim(` Use arrow keys to navigate \u2022 Enter to select \u2022 Ctrl+C to exit
12
- `))}function Ue(s){let a=" Lightweight Interactive TUI Database Client \u2022 v1.1.4 ",t="None",r="-",o="None";s.type==="unknown"?o=N.dim("No configuration found. Please run check to configure."):(t=s.type.toUpperCase(),r=s.targetUrl,o=s.source===".env"?"Loaded from project .env file":s.source==="auto-detected"?"Auto-detected local SQLite file":"Manual connection config"),se(a,[{label:"Database",value:t},{label:"Target",value:r.length>45?"..."+r.slice(-42):r},{label:"Source",value:o},{label:"Working Dir",value:process.cwd().length>45?"..."+process.cwd().slice(-42):process.cwd()}])}var J,Xt,Zt,ea,ta,aa,oa,Se=E(()=>{"use strict";J=(s,a,t)=>r=>`\x1B[38;2;${s};${a};${t}m${r}\x1B[39m`,Xt=J(0,255,255),Zt=J(0,230,245),ea=J(0,210,235),ta=J(0,188,220),aa=J(0,168,205),oa=J(0,148,188)});var $e,We=E(()=>{"use strict";$e=class{dbPath;db=null;constructor(a){this.dbPath=a}async getDb(){if(!this.db){if(!(await import("fs")).existsSync(this.dbPath))throw new Error(`Failed to found database file at: ${this.dbPath}`);let t=await import("sqlite");this.db=new t.DatabaseSync(this.dbPath)}return this.db}quoteIdentifier(a){return`"${a.replace(/"/g,'""')}"`}async getTables(){return(await this.getDb()).prepare("SELECT name FROM sqlite_master WHERE type = 'table' AND name NOT LIKE 'sqlite_%' ORDER BY name;").all().map(r=>r.name)}async getSchema(a){let t=await this.getDb(),r=this.quoteIdentifier(a),e=t.prepare(`PRAGMA table_info(${r})`).all(),c=t.prepare(`PRAGMA foreign_key_list(${r})`).all();return e.map(i=>{let l=c.find(m=>m.from===i.name);return{name:i.name,type:i.type,isPk:i.pk>0,nullable:i.notnull===0,defaultValue:i.dflt_value!=null?String(i.dflt_value):void 0,fkTarget:l?{table:l.table,column:l.to}:void 0}})}async getIndexes(a){let t=await this.getDb(),r=this.quoteIdentifier(a),e=t.prepare(`PRAGMA index_list(${r})`).all(),n=[];for(let c of e){if(c.origin==="pk")continue;let l=t.prepare(`PRAGMA index_info(${this.quoteIdentifier(c.name)})`).all();n.push({name:c.name,columns:l.map(m=>m.name),isUnique:c.unique>0})}return n}async getData(a,t=50,r=0,o,e){let n=await this.getDb(),i=(await this.getSchema(a)).map(u=>u.name),l=`SELECT * FROM ${this.quoteIdentifier(a)}`;o&&(l+=` WHERE ${o}`),e&&(l+=` ORDER BY ${this.quoteIdentifier(e.col)} ${e.asc?"ASC":"DESC"}`),l+=` LIMIT ${t} OFFSET ${r}`;let p=n.prepare(l).all();return{columns:i,rows:p}}async query(a){let t=await this.getDb(),r=a.trim().toUpperCase();if(r.startsWith("SELECT")||r.startsWith("PRAGMA")||r.startsWith("EXPLAIN")||r.startsWith("WITH")){let n=t.prepare(a).all(),c=[];return n.length>0&&(c=Object.keys(n[0])),{columns:c,rows:n}}else return t.prepare(a).run(),{columns:["Result"],rows:[{Result:"Success"}]}}async executeSql(a){(await this.getDb()).exec(a)}async close(){this.db&&(this.db.close(),this.db=null)}async insert(a,t){if(t.length===0)return;let r=await this.getDb(),o=Object.keys(t[0]),e=o.map(l=>this.quoteIdentifier(l)).join(", "),n=o.map(()=>"?").join(", "),c=`INSERT INTO ${this.quoteIdentifier(a)} (${e}) VALUES (${n})`,i=r.prepare(c);for(let l of t){let m=o.map(p=>l[p]);i.run(...m)}}}});import na from"pg";var xe,je=E(()=>{"use strict";xe=class{client;connected=!1;constructor(a){this.client=new na.Client({connectionString:a})}async connectIfNecessary(){this.connected||(await this.client.connect(),this.connected=!0)}quoteIdentifier(a){return`"${a.replace(/"/g,'""')}"`}async getTables(){return await this.connectIfNecessary(),(await this.client.query(`
12
+ `))}function Ue(s){let a=" Lightweight Interactive TUI Database Client \u2022 v1.1.5 ",t="None",r="-",o="None";s.type==="unknown"?o=N.dim("No configuration found. Please run check to configure."):(t=s.type.toUpperCase(),r=s.targetUrl,o=s.source===".env"?"Loaded from project .env file":s.source==="auto-detected"?"Auto-detected local SQLite file":"Manual connection config"),se(a,[{label:"Database",value:t},{label:"Target",value:r.length>45?"..."+r.slice(-42):r},{label:"Source",value:o},{label:"Working Dir",value:process.cwd().length>45?"..."+process.cwd().slice(-42):process.cwd()}])}var J,Xt,Zt,ea,ta,aa,oa,Se=E(()=>{"use strict";J=(s,a,t)=>r=>`\x1B[38;2;${s};${a};${t}m${r}\x1B[39m`,Xt=J(0,255,255),Zt=J(0,230,245),ea=J(0,210,235),ta=J(0,188,220),aa=J(0,168,205),oa=J(0,148,188)});var $e,We=E(()=>{"use strict";$e=class{dbPath;db=null;constructor(a){this.dbPath=a}async getDb(){if(!this.db){if(!(await import("fs")).existsSync(this.dbPath))throw new Error(`Failed to found database file at: ${this.dbPath}`);let t=await import("sqlite");this.db=new t.DatabaseSync(this.dbPath)}return this.db}quoteIdentifier(a){return`"${a.replace(/"/g,'""')}"`}async getTables(){return(await this.getDb()).prepare("SELECT name FROM sqlite_master WHERE type = 'table' AND name NOT LIKE 'sqlite_%' ORDER BY name;").all().map(r=>r.name)}async getSchema(a){let t=await this.getDb(),r=this.quoteIdentifier(a),e=t.prepare(`PRAGMA table_info(${r})`).all(),c=t.prepare(`PRAGMA foreign_key_list(${r})`).all();return e.map(i=>{let l=c.find(m=>m.from===i.name);return{name:i.name,type:i.type,isPk:i.pk>0,nullable:i.notnull===0,defaultValue:i.dflt_value!=null?String(i.dflt_value):void 0,fkTarget:l?{table:l.table,column:l.to}:void 0}})}async getIndexes(a){let t=await this.getDb(),r=this.quoteIdentifier(a),e=t.prepare(`PRAGMA index_list(${r})`).all(),n=[];for(let c of e){if(c.origin==="pk")continue;let l=t.prepare(`PRAGMA index_info(${this.quoteIdentifier(c.name)})`).all();n.push({name:c.name,columns:l.map(m=>m.name),isUnique:c.unique>0})}return n}async getData(a,t=50,r=0,o,e){let n=await this.getDb(),i=(await this.getSchema(a)).map(u=>u.name),l=`SELECT * FROM ${this.quoteIdentifier(a)}`;o&&(l+=` WHERE ${o}`),e&&(l+=` ORDER BY ${this.quoteIdentifier(e.col)} ${e.asc?"ASC":"DESC"}`),l+=` LIMIT ${t} OFFSET ${r}`;let p=n.prepare(l).all();return{columns:i,rows:p}}async query(a){let t=await this.getDb(),r=a.trim().toUpperCase();if(r.startsWith("SELECT")||r.startsWith("PRAGMA")||r.startsWith("EXPLAIN")||r.startsWith("WITH")){let n=t.prepare(a).all(),c=[];return n.length>0&&(c=Object.keys(n[0])),{columns:c,rows:n}}else return t.prepare(a).run(),{columns:["Result"],rows:[{Result:"Success"}]}}async executeSql(a){(await this.getDb()).exec(a)}async close(){this.db&&(this.db.close(),this.db=null)}async insert(a,t){if(t.length===0)return;let r=await this.getDb(),o=Object.keys(t[0]),e=o.map(l=>this.quoteIdentifier(l)).join(", "),n=o.map(()=>"?").join(", "),c=`INSERT INTO ${this.quoteIdentifier(a)} (${e}) VALUES (${n})`,i=r.prepare(c);for(let l of t){let m=o.map(p=>l[p]);i.run(...m)}}}});import na from"pg";var xe,je=E(()=>{"use strict";xe=class{client;connected=!1;constructor(a){this.client=new na.Client({connectionString:a})}async connectIfNecessary(){this.connected||(await this.client.connect(),this.connected=!0)}quoteIdentifier(a){return`"${a.replace(/"/g,'""')}"`}async getTables(){return await this.connectIfNecessary(),(await this.client.query(`
13
13
  SELECT tablename
14
14
  FROM pg_catalog.pg_tables
15
15
  WHERE schemaname != 'pg_catalog' AND schemaname != 'information_schema'
@@ -0,0 +1 @@
1
+ @import "https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap";:root{--color-bg-primary:#fff;--color-bg-secondary:#f8fafc;--color-bg-secondary-dark:#f1f5f9;--color-primary:#2c68ec;--color-primary-active:#eff6ff;--color-primary-dark:#285bb8;--color-text:#0f172a;--color-text-soft:#94a3b8;--color-text-secondary:#64748b;--color-border:#e2e8f0;--color-border-soft:#f1f5f9;--ring-primary-2:0 0 0 2px #2c68ec33;--font-inter:"Inter", sans-serif;--color-btn-active-text:var(--color-primary);--color-cell-range-bg:#dbeafe;--color-cell-edited-bg:#fffbeb;--color-cell-edited-text:#b45309;--color-cell-error-bg:#fef2f2;--color-row-deleted-bg:#fee2e2;--color-row-deleted-text:#ef4444;--color-ghost-row-bg:#f8fafc}[data-theme=dark]{--color-bg-primary:#0f172a;--color-bg-secondary:#1e293b;--color-bg-secondary-dark:#334155;--color-primary:#3b82f6;--color-primary-active:#1e3a8a;--color-primary-dark:#60a5fa;--color-text:#f8fafc;--color-text-soft:#64748b;--color-text-secondary:#cbd5e1;--color-border:#334155;--color-border-soft:#1e293b;--ring-primary-2:0 0 0 2px #3b82f633;--color-btn-active-text:#fff;--color-cell-range-bg:#3b82f626;--color-cell-edited-bg:#f59e0b26;--color-cell-edited-text:#fbbf24;--color-cell-error-bg:#ef444426;--color-row-deleted-bg:#ef444426;--color-row-deleted-text:#f87171;--color-ghost-row-bg:var(--color-bg-secondary)}body,html{background-color:var(--color-bg-primary);width:100vw;height:100vh;color:var(--color-text);font-family:var(--font-inter);margin:0;padding:0;display:flex;overflow:hidden}main{flex-direction:column;flex:1;min-width:0;display:flex}aside{border-right:1px var(--color-border) solid;box-sizing:border-box;flex-direction:column;width:256px;height:100vh;display:flex}#sidebar-header{border-bottom:1px var(--color-border-soft) solid;box-sizing:border-box;align-items:center;gap:8px;height:64px;padding:0 16px;display:flex}.table-btn{color:var(--color-text-secondary);cursor:pointer;letter-spacing:.5px;background-color:#0000;border:1px solid #0000;border-radius:8px;outline:none;justify-content:space-between;align-items:center;padding:10px 16px;font-size:12px;font-weight:500;transition:all .2s;display:flex}#sidebar-footer{flex:1;align-items:center;min-width:0;display:flex}aside{border-right:1px var(--color-border) solid;flex-direction:column;width:256px;height:100vh;display:flex}#sidebar-header{border-bottom:1px var(--color-border-soft) solid;align-items:center;gap:8px;height:64px;padding:0 16px;display:flex}#database-icon{color:var(--color-primary);font-size:26px}#brand-title{letter-spacing:.5px;align-items:center;gap:4px;margin:0;padding:0;font-size:16px;font-weight:bolder;line-height:1;display:flex}#brand-subtitle{background-color:var(--color-primary);color:#fff;border-radius:5px;align-items:center;height:100%;padding:4px 6px;font-size:12px;font-weight:600;line-height:1;display:flex}#sidebar-content{flex-direction:column;flex:1;gap:24px;padding:16px;display:flex}#search-bar{background-color:var(--color-bg-secondary);border:1px var(--color-border) solid;border-radius:8px;outline:none;align-items:center;padding:0 4px;transition:all .1s linear;display:flex;overflow:hidden}#search-bar:focus-within{border:1px var(--color-primary) solid;box-shadow:var(--ring-primary-2);background-color:var(--color-bg-primary);transform:scale(1.02)}#search-icon{color:var(--color-text-soft);margin:0 3px 0 6px;font-size:20px;transition:all .1s linear}#search-bar:focus-within #search-icon{color:var(--color-primary);transform:scale(1.15)}#search-input{width:100%;height:34px;color:var(--color-text);background-color:#0000;border:none;outline:none;font-size:12px}#search-input::placeholder{color:var(--color-text-soft)}#table-nav{flex-direction:column;flex:1;gap:6px;display:flex;overflow-y:auto}#table-nav::-webkit-scrollbar{width:4px}#table-nav::-webkit-scrollbar-track{background:0 0}#table-nav::-webkit-scrollbar-thumb{background:var(--color-border);border-radius:4px}#table-nav::-webkit-scrollbar-thumb:hover{background:var(--color-text-soft)}.table-btn{color:var(--color-text-secondary);cursor:pointer;background-color:#0000;border:1px solid #0000;border-radius:8px;outline:none;justify-content:space-between;align-items:center;padding:10px 16px;font-size:12px;font-weight:500;transition:all .2s;display:flex}.table-btn:hover{background-color:var(--color-bg-secondary);color:var(--color-text)}.table-btn:active{transform:scale(.97)}.table-btn.active{background-color:var(--color-primary-active);border:1px var(--color-primary) solid;color:var(--color-btn-active-text);font-weight:600}.table-btn-badge{background-color:var(--color-bg-secondary-dark);color:var(--color-text-secondary);border-radius:10px;justify-content:center;align-items:center;min-width:16px;min-height:16px;padding:1px;font-size:8px;font-weight:600;line-height:1;display:flex}.table-btn.active .table-btn-badge{background-color:var(--color-primary);color:#fff}#not-found-msg{color:var(--color-text-soft);flex:1;justify-content:center;align-items:center;font-size:12px;font-weight:400;display:flex}#sidebar-footer{border-top:1px var(--color-border-soft) solid;justify-content:center;align-items:center;max-height:fit-content;margin-top:auto;padding:16px;display:flex}#theme-toggle{background-color:var(--color-bg-secondary);color:var(--color-text-secondary);border:1px var(--color-border) solid;cursor:pointer;border-radius:8px;outline:none;justify-content:center;align-items:center;gap:8px;width:100%;padding:12px 24px;font-weight:600;transition:all .1s linear;display:flex}#theme-toggle:hover{color:var(--color-primary);border-color:var(--color-primary);background-color:var(--color-bg-primary)}header{border-bottom:1px var(--color-border) solid;box-sizing:border-box;justify-content:space-between;align-items:center;width:100%;height:64px;padding:0 32px;font-size:14px;font-weight:300;display:flex;position:sticky;top:0}#current-path{text-transform:lowercase;align-items:center;gap:10px;display:flex}#db-name{color:var(--color-text-secondary)}#slash{color:var(--color-text-soft);font-size:18px;font-weight:lighter}#current-table{align-items:center;gap:4px;display:flex}#table-icon{color:var(--color-primary);font-size:20px}#table-name{color:var(--color-text);font-weight:600}#tab-nav{border-bottom:1px var(--color-border) solid;gap:24px;height:48px;padding:0 32px;display:flex}.tab-btn{height:100%;color:var(--color-text-secondary);cursor:pointer;background-color:#0000;border:none;border-bottom:2px solid #0000;outline:none;align-items:center;gap:8px;padding:0 6px;font-size:12px;font-weight:300;line-height:1;transition:all .1s linear;display:flex}.tab-btn:hover{border-bottom:2px var(--color-border) solid;color:var(--color-text)}.tab-btn.isCurrentTab{border-bottom:2px var(--color-primary) solid;color:var(--color-primary)}.tab-btn .material-symbols-outlined{font-size:16px}#main-content{background-color:var(--color-bg-primary);flex-direction:column;flex:1;min-width:0;display:flex;overflow:hidden}.toolbar{border-bottom:1px var(--color-border) solid;background-color:var(--color-bg-secondary);flex-shrink:0;align-items:center;height:48px;display:flex}.filter-group{flex:1;align-items:center;height:100%;transition:all .15s;display:flex;overflow:hidden}.filter-icon-container{background-color:var(--color-bg-secondary);border-right:1px var(--color-border) solid;align-items:center;gap:6px;height:100%;padding:0 16px;font-size:16px;display:flex}.filter-icon-container .material-symbols-outlined{color:var(--color-text-secondary);font-size:18px}.filter-icon-container span:not(.material-symbols-outlined){text-transform:uppercase;color:var(--color-text-secondary);font-size:13px;font-weight:500}.filter-select{height:100%;color:var(--color-text-secondary);border:none;border-right:1px var(--color-border) solid;cursor:pointer;background-color:#0000;outline:none;padding:0 16px;font-size:13px;font-weight:500}.filter-select:hover{background-color:var(--color-bg-secondary)}.filter-input{height:100%;color:var(--color-text);background:0 0;border:none;outline:none;flex:1;padding:0 20px;font-size:13px;font-weight:200}.filter-input::placeholder{color:var(--color-text-soft)}#btn-run-query{background-color:var(--color-primary);color:#fff;border:none;border-right:1px var(--color-border) solid;cursor:pointer;border-radius:8px;outline:none;justify-content:center;align-items:center;gap:8px;padding:8px 12px;font-size:10px;font-weight:700;transition:all .1s linear;display:flex}#btn-run-query:hover{background-color:var(--color-primary-dark)}#btn-run-query .material-symbols-outlined{margin-bottom:.5px;font-size:16px}#btn-clear-query{background-color:var(--color-bg-primary);color:var(--color-text-secondary);border:none;border:1px var(--color-border) solid;cursor:pointer;border-radius:8px;outline:none;justify-content:center;align-items:center;gap:8px;margin-left:16px;padding:8px 12px;font-size:10px;font-weight:700;transition:all .1s linear;display:flex}#btn-clear-query:hover{background-color:var(--color-bg-secondary-dark);color:var(--color-text)}#btn-run-query:active,#btn-clear-query:active,.btn-primary:active,.btn-secondary:active,.table-btn:active{transform:scale(.96)}#btn-clear-query .material-symbols-outlined{margin-bottom:.5px;font-size:16px}.refresh-btn{background-color:var(--color-bg-secondary);border:1px var(--color-border) solid;color:var(--color-text-secondary);cursor:pointer;border-radius:8px;outline:none;justify-content:center;align-items:center;gap:8px;margin:16px;padding:6px;font-size:10px;font-weight:700;transition:all .1s linear;display:flex}.refresh-btn:hover{background-color:var(--color-bg-secondary-dark);color:var(--color-text)}.refresh-btn .material-symbols-outlined{margin-bottom:.5px;font-size:18px}.sql-console-wrapper{background-color:var(--color-bg-secondary);text-wrap:nowrap;flex-direction:column-reverse;height:100%;display:flex}#console-welcome-msg{color:var(--color-text-soft);text-align:center;letter-spacing:.5px;flex-direction:column;justify-content:center;align-items:center;gap:10px;margin:auto 0;font-family:monospace;display:flex}#console-welcome-title{color:var(--color-text);flex-direction:column;align-items:center;gap:36px;font-size:24px;font-weight:bolder;display:flex}#console-welcome-title #icon-container{background-color:var(--color-primary);color:#fff;border-radius:12px;justify-content:center;align-items:center;width:fit-content;padding:14px;display:flex}#console-welcome-description{text-wrap:wrap;max-width:50%;font-size:14px;line-height:2}#console-welcome-description b{color:var(--color-primary);background-color:var(--color-bg-secondary);border-radius:4px;padding:2px 6px;font-size:16px}#console-welcome-hint{opacity:.65;margin-top:24px;font-size:12px}.sql-console-wrapper{background-color:var(--color-bg-primary);flex-direction:column;height:100%;display:flex;overflow:hidden}.sql-console-wrapper ::-webkit-scrollbar{display:none}.sql-console-wrapper{-ms-overflow-style:none;scrollbar-width:none}#console-history-pane{flex-direction:column;flex:1;gap:24px;padding:24px;display:flex;overflow-y:auto}#console-input-pane{border-top:1px solid var(--color-border);background-color:var(--color-bg-secondary);flex-direction:column;flex-shrink:0;padding:16px 24px;display:flex;position:relative;box-shadow:0 -4px 12px #00000005}.sql-editor-wrapper{align-items:flex-start;gap:8px;display:flex}.sql-prompt{color:var(--color-primary);-webkit-user-select:none;user-select:none;margin-top:1.5px;font-family:monospace;font-size:14px;font-weight:700}.sql-editor-layer-container{flex:1;height:fit-content;min-height:128px;position:relative}#sql-highlight-layer{pointer-events:none;white-space:pre-wrap;word-break:break-all;z-index:1;margin:0;padding:0;position:absolute;inset:1.5px 0 0;overflow:hidden}.sql-editor{resize:none;width:100%;height:fit-content;min-height:128px;color:var(--color-text);letter-spacing:.8px;background-color:#0000;border:none;outline:none;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:14px;line-height:normal}textarea#sql-editor{z-index:2;width:100%;height:100%;caret-color:var(--color-text);margin:0;padding:0;position:absolute;top:0;left:0;color:#0000!important}.console-history-block{background-color:var(--color-bg-secondary);border:1px solid var(--color-border);border-radius:8px;flex-shrink:0;overflow:hidden;box-shadow:0 2px 8px #0000000d}.console-history-header{background-color:var(--color-bg-primary);border-bottom:1px solid var(--color-border);justify-content:space-between;align-items:flex-start;gap:16px;padding:12px 16px;display:flex}.console-history-sql{color:var(--color-text);white-space:pre-wrap;word-break:break-all;flex:1;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:13px;line-height:1.5}.console-history-actions{flex-shrink:0;gap:4px;display:flex}.console-history-actions .icon-btn{cursor:pointer;color:var(--color-text-soft);background:0 0;border:none;border-radius:4px;justify-content:center;align-items:center;padding:4px;display:flex}.console-history-results{max-height:400px;padding:16px;overflow:auto}.console-msg-executing,.console-msg-error,.console-msg-success{align-items:center;gap:8px;font-family:monospace;font-size:13px;display:flex}.console-msg-executing{color:var(--color-text-soft)}.console-msg-error{color:var(--color-error);white-space:pre-wrap;align-items:flex-start}.console-msg-success{color:#10b981}.console-stats-header{justify-content:space-between;align-items:center;margin-bottom:12px;display:flex}.console-stats-info{color:var(--color-text-soft);align-items:center;gap:6px;font-family:monospace;font-size:12px;display:flex}.console-export-btn{border:1px solid var(--color-border);cursor:pointer;color:var(--color-text);background:0 0;border-radius:4px;align-items:center;gap:4px;padding:4px 8px;font-size:12px;font-weight:500;display:flex}.hl-string{color:#98c379}.hl-number{color:#d19a66}.hl-keyword{color:#c678dd;font-weight:700}.hl-placeholder{color:var(--color-text-soft);opacity:.5}.data-cell-truncate{white-space:nowrap;text-overflow:ellipsis;max-width:300px;overflow:hidden}.table-container{background-color:var(--color-bg-primary);scrollbar-width:none;-ms-overflow-style:none;flex:1;width:100%;min-width:0;overflow:auto}.table-container::-webkit-scrollbar{display:none}.data-table{border-collapse:separate;border-spacing:0;-webkit-user-select:none;user-select:none;width:max-content;min-width:100%}.data-table input,.data-table select{-webkit-user-select:text;user-select:text;box-sizing:border-box}.data-table th,.data-table td{text-align:left;border-bottom:1px var(--color-border-soft) solid;border-right:1px var(--color-border-soft) solid;white-space:nowrap;cursor:cell;height:24px;padding:8px 16px;font-size:13px;position:relative}.data-table th{background-color:var(--color-primary);color:#fff;text-transform:uppercase;letter-spacing:.5px;z-index:10;border-bottom:1px var(--color-border) solid;box-shadow:0 1px 0 var(--color-border);cursor:default;border-right:1px solid #fff3;font-size:11px;font-weight:600;position:sticky;top:0}.data-table td.cell-in-range{background-color:var(--color-cell-range-bg)}.data-table td.cell-in-range:after{content:"";box-sizing:border-box;pointer-events:none;border-top:var(--border-t,0);border-bottom:var(--border-b,0);border-left:var(--border-l,0);border-right:var(--border-r,0);position:absolute;inset:0}.data-table td.range-top{--border-t:2px solid var(--color-primary)}.data-table td.range-bottom{--border-b:2px solid var(--color-primary)}.data-table td.range-left{--border-l:2px solid var(--color-primary)}.data-table td.range-right{--border-r:2px solid var(--color-primary)}.data-table td.cell-selected{background-color:var(--color-bg-primary);z-index:5;box-shadow:inset 0 0 0 2px var(--color-primary)}.data-table td.row-header,.data-table th.row-header{z-index:9;background-color:var(--color-bg-secondary);color:var(--color-text-soft);text-align:center;border-right:1px var(--color-border) solid;width:32px;min-width:32px;padding:8px 4px;font-weight:500;position:sticky;left:0}.data-table th.row-header{z-index:11;background-color:var(--color-primary);color:#fff}.data-table td.cell-edited{background-color:var(--color-cell-edited-bg);color:var(--color-cell-edited-text);font-weight:700}.data-table td.cell-error{background-color:var(--color-cell-error-bg)}.data-table td.cell-error:not(.cell-in-range):not(.cell-selected){box-shadow:inset 0 0 0 2px #ef4444}.data-table tr.row-deleted td{text-decoration:line-through;background-color:var(--color-row-deleted-bg)!important;color:var(--color-row-deleted-text)!important}.data-table td.ghost-row{color:var(--color-text-soft);background-color:var(--color-ghost-row-bg);font-style:italic}.data-table td input,.data-table td select{box-sizing:border-box;width:100%;height:100%;color:var(--color-text);background-color:var(--color-bg-primary);box-shadow:var(--ring-primary-2);border:none;outline:none;padding:0 16px;font-family:inherit;font-size:13px;position:absolute;top:0;left:0}.data-table tbody tr:hover:not(:has(.manage-indexes-cell:hover)){background-color:var(--color-bg-secondary)}.manage-indexes-cell{background-color:var(--color-bg-primary)!important}.manage-indexes-cell:hover{background-color:var(--color-bg-secondary)!important}.resizer{cursor:col-resize;-webkit-user-select:none;user-select:none;z-index:10;width:8px;height:100%;position:absolute;top:0;right:-4px}.resizer:hover,.resizer:active{background-color:var(--color-primary);opacity:.5}.cell-expand-btn{cursor:pointer;color:var(--color-text-soft);background-color:var(--color-bg-primary);border:1px var(--color-border) solid;z-index:10;border-radius:4px;justify-content:center;align-items:center;padding:3px;font-size:14px;transition:all .1s;display:flex;position:absolute;top:50%;right:6px;transform:translateY(-50%);box-shadow:0 2px 4px #0000000d}.cell-expand-btn:hover{color:var(--color-primary);border-color:var(--color-primary)}#modal-editor-overlay{-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);z-index:9999;background-color:#0f172a66;justify-content:center;align-items:center;width:100vw;height:100vh;display:flex;position:fixed;top:0;left:0}.modal-editor-container{background-color:var(--color-bg-primary);background-color:rgba(var(--color-bg-primary), .85);background:var(--color-bg-primary);border-radius:12px;flex-direction:column;width:600px;max-width:90vw;height:500px;max-height:90vh;display:flex;overflow:hidden;box-shadow:0 10px 25px -5px #0000001a,0 8px 10px -6px #0000001a}.modal-header{border-bottom:1px var(--color-border) solid;color:var(--color-text);align-items:center;gap:8px;padding:16px 20px;display:flex}.modal-header h3{margin:0;font-size:16px;font-weight:600}.modal-header .material-symbols-outlined{color:var(--color-primary)}#modal-textarea{resize:none;color:var(--color-text);background-color:var(--color-bg-secondary-dark);border:none;outline:none;flex:1;padding:20px;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:13px}#modal-textarea:focus{background-color:var(--color-bg-primary)}.modal-footer{border-top:1px var(--color-border) solid;background-color:var(--color-bg-secondary);justify-content:flex-end;gap:12px;padding:16px 20px;display:flex}.modal-footer button{cursor:pointer;border:1px var(--color-border) solid;background-color:var(--color-bg-primary);color:var(--color-text);border-radius:6px;padding:8px 16px;font-size:13px;font-weight:500;transition:all .2s}.modal-footer button:active{transform:scale(.97)}.modal-footer button:hover{background-color:var(--color-bg-secondary-dark)}.modal-footer button.primary{background-color:var(--color-primary);color:#fff;border-color:var(--color-primary)}.modal-footer button.primary:hover{background-color:var(--color-primary-dark)}.empty-state{flex-direction:column;flex:1;justify-content:center;align-items:center;display:flex}.empty-state .icon-container{background-color:var(--color-primary);color:#fff;border-radius:10px;justify-content:center;align-items:center;width:64px;height:64px;display:flex;box-shadow:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a}.empty-state .material-symbols-outlined{font-size:36px}.empty-state h2{color:var(--color-text);margin-top:32px;margin-bottom:10px;font-size:24px;font-weight:700}.empty-state p{color:var(--color-text-secondary);text-align:center;max-width:500px;margin:0;font-size:16px;line-height:1.5}#toast-container{z-index:10000;flex-direction:column;gap:10px;display:flex;position:fixed;bottom:20px;right:20px}.toast{background-color:var(--color-bg-primary);color:var(--color-text);border-left:4px solid var(--color-primary);opacity:0;border-radius:8px;align-items:center;gap:8px;padding:12px 20px;font-size:14px;font-weight:500;animation:.3s ease-out forwards slideIn,.3s ease-in 2.7s forwards fadeOut;display:flex;transform:translate(100%);box-shadow:0 4px 12px #00000026}.toast.error{border-left-color:#ef4444}@keyframes slideIn{0%{opacity:0;transform:translate(100%)}to{opacity:1;transform:translate(0)}}@keyframes fadeOut{0%{opacity:1}to{opacity:0}}#theme-toggle{color:var(--color-text-secondary);cursor:pointer;background:0 0;border:none;border-radius:6px;justify-content:center;align-items:center;padding:6px;transition:all .2s;display:flex}#theme-toggle:hover{background-color:var(--color-bg-secondary);color:var(--color-text)}#theme-toggle:active{transform:scale(.9)}.erd-node{border:1px solid var(--color-border);background:var(--color-bg-primary);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);border-radius:12px;flex-direction:column;width:300px;transition:box-shadow .2s,transform .1s;display:flex;position:absolute;overflow:hidden;box-shadow:0 4px 12px #0000001a}.erd-node:hover{box-shadow:0 8px 24px #00000026}.erd-node.is-selected{border:1px solid var(--color-primary);box-shadow:0 0 0 3px var(--color-cell-range-bg)}.erd-node-header{background-color:var(--color-primary);color:#fff;cursor:grab;-webkit-user-select:none;user-select:none;align-items:center;gap:8px;padding:12px 14px;font-size:16px;display:flex}.erd-node-header:active{cursor:grabbing}.erd-node-body{flex-direction:column;display:flex}.erd-column{border-bottom:1px solid var(--color-border);background-color:#0000;justify-content:space-between;align-items:center;padding:12px 14px;font-size:12px;transition:background-color .15s;display:flex}.erd-column:last-child{border-bottom:none}.erd-column:hover{background-color:var(--color-bg-secondary)}.erd-col-left{align-items:center;gap:8px;display:flex}.erd-col-name{color:var(--color-text);font-family:JetBrains Mono,Fira Code,monospace;font-size:12px}.erd-col-right{align-items:center;display:flex}.erd-col-type{color:var(--color-text-soft);background-color:var(--color-bg-secondary);border-radius:4px;padding:4px 6px;font-family:JetBrains Mono,Fira Code,monospace;font-size:10px}#erd-wrapper{scrollbar-width:none;-ms-overflow-style:none;background-color:var(--color-bg-secondary)}#erd-wrapper::-webkit-scrollbar{display:none}.erd-node.is-draft{border:2px dashed var(--color-primary);box-shadow:0 0 15px rgba(var(--color-primary-rgb), .2)}.erd-column.is-draft{background-color:rgba(var(--color-primary-rgb), .05)}.erd-add-col-btn{text-align:center;color:var(--color-primary);cursor:pointer;border-top:1px dashed var(--color-border);background-color:#0000;justify-content:center;align-items:center;gap:6px;padding:14px;font-size:12px;font-weight:500;transition:background-color .15s;display:flex}.erd-add-col-btn:hover{background-color:var(--color-bg-secondary)}.drixio-context-menu{background-color:var(--color-bg-primary);border:1px solid var(--color-border);z-index:9999;border-radius:8px;min-width:180px;padding:6px 0;font-family:inherit;display:none;position:fixed;box-shadow:0 8px 24px #00000026}.drixio-context-menu.visible{display:block}.drixio-context-menu-item{cursor:pointer;color:var(--color-text);align-items:center;gap:12px;padding:8px 16px;font-size:13px;transition:background-color .1s;display:flex}.drixio-context-menu-item:hover{background-color:var(--color-cell-range-bg)}.drixio-context-menu-item.danger,.drixio-context-menu-item.danger .material-symbols-outlined{color:#ef4444}.drixio-context-menu-item.danger:hover{background-color:#ef44441a}.drixio-context-menu-item .material-symbols-outlined{color:var(--color-text-soft);font-size:18px}.drixio-menu-label{flex:1}.drixio-menu-shortcut{color:var(--color-text-soft);opacity:.7;font-size:11px}.drixio-context-menu-divider{background-color:var(--color-border);height:1px;margin:4px 0}.erd-inline-input{background:var(--color-bg-primary);border:1px solid var(--color-primary);color:var(--color-text);font:inherit;border-radius:4px;outline:none;width:100%;padding:2px 6px}.erd-drag-handle{border:2px solid var(--color-primary);background:var(--color-bg-primary);cursor:crosshair;opacity:.4;border-radius:50%;width:14px;height:14px;margin-left:8px;transition:opacity .2s,transform .2s}.erd-drag-handle:hover{transform:scale(1.2)}.erd-column:hover .erd-reorder-handle{opacity:1}.erd-drag-line{pointer-events:none;z-index:50;width:100%;height:100%;position:absolute;top:0;left:0}.erd-grid-bg{background-image:linear-gradient(90deg,#0000000d 1px,#0000 1px),linear-gradient(#0000000d 1px,#0000 1px);background-position:50%;background-size:20px 20px}.erd-ui-overlay{pointer-events:none;z-index:100;justify-content:space-between;padding:16px;display:flex;position:fixed;top:60px;left:320px;right:0}.erd-toolbar{pointer-events:auto;gap:8px;display:flex}.erd-search-container{pointer-events:auto;align-items:center;display:flex;position:relative}.erd-search-container .search-icon{color:var(--color-text-soft);font-size:18px;position:absolute;left:8px}.erd-search-container input{background-color:var(--color-bg-primary);border:1px solid var(--color-border);color:var(--color-text);border-radius:6px;width:250px;padding:8px 12px 8px 32px;font-family:inherit;font-size:13px;box-shadow:0 4px 6px #0000000d}.erd-search-container input:focus{border-color:var(--color-primary);outline:none}.erd-search-results{background-color:var(--color-bg-primary);border:1px solid var(--color-border);z-index:110;border-radius:6px;max-height:300px;margin-top:4px;position:absolute;top:100%;left:0;right:0;overflow-y:auto;box-shadow:0 8px 16px #0000001a}.erd-search-item{cursor:pointer;color:var(--color-text);padding:8px 12px;font-size:13px}.erd-search-item:hover{background-color:var(--color-bg-secondary)}.erd-minimap{background-color:var(--color-bg-primary);border:1px solid var(--color-border);z-index:100;pointer-events:auto;border-radius:8px;width:180px;height:130px;position:relative;overflow:hidden;box-shadow:0 8px 24px #0000001a}.erd-minimap-content{width:100%;height:100%;position:relative}.erd-minimap-viewport{border:2px solid var(--color-primary);box-sizing:border-box;pointer-events:none;background-color:#3b82f61a;position:absolute}
@@ -0,0 +1,365 @@
1
+ var e=Object.defineProperty,t=(t,n)=>{let r={};for(var i in t)e(r,i,{get:t[i],enumerable:!0});return n||e(r,Symbol.toStringTag,{value:`Module`}),r};(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 n=`
2
+ <header>
3
+ <div id="current-path">
4
+ <span id="db-name">database</span>
5
+ <span id="slash">/</span>
6
+ <div id="current-table">
7
+ <span class="material-symbols-outlined" id="table-icon"> table </span>
8
+ <span id="table-name">users</span>
9
+ </div>
10
+ </div>
11
+
12
+
13
+ <div class="header-actions">
14
+ <button id="export-btn" class="secondary" title="Export Data / DDL" style="display: flex; align-items: center; gap: 6px; padding: 6px 12px; background: transparent; border: 1px solid var(--color-border); border-radius: 6px; cursor: pointer; color: var(--color-text-secondary); font-size: 13px; font-weight: 500;">
15
+ <span class="material-symbols-outlined" style="font-size: 18px;">download</span>
16
+ Export
17
+ </button>
18
+ </div>
19
+ </header>
20
+ `,r=`
21
+ <aside>
22
+ <div id="sidebar-header">
23
+ <span class="material-symbols-outlined" id="database-icon"> database </span>
24
+ <h1 id="brand-title">
25
+ DRIXIO
26
+ <p id="brand-subtitle">STUDIO</p>
27
+ </h1>
28
+ </div>
29
+
30
+ <div id="sidebar-content">
31
+ <div id="search-bar">
32
+ <span class="material-symbols-outlined" id="search-icon"> search </span>
33
+ <input type="text" placeholder="Search" id="search-input" />
34
+ </div>
35
+
36
+ <nav id="table-nav">
37
+ <!-- Display All Table -->
38
+ </nav>
39
+ </div>
40
+
41
+ <div id="sidebar-footer">
42
+ <button id="theme-toggle" title="Toggle Dark Mode">
43
+ <span class="material-symbols-outlined" id="theme-icon">dark_mode</span>
44
+ Theme
45
+ </button>
46
+ </div>
47
+ </aside>
48
+ `,i=`
49
+ <nav id="tab-nav">
50
+ <button
51
+ type="button"
52
+ class="tab-btn"
53
+ onclick="handleSwitchTab('data-btn')"
54
+ id="data-btn"
55
+ >
56
+ <span class="material-symbols-outlined" id="data-icon"> table_rows </span>
57
+ Data
58
+ </button>
59
+ <button
60
+ class="tab-btn"
61
+ onclick="handleSwitchTab('schema-btn')"
62
+ id="schema-btn"
63
+ >
64
+ <span class="material-symbols-outlined" id="schema-icon">
65
+ grid_layout_side
66
+ </span>
67
+ Schema (Table)
68
+ </button>
69
+
70
+ <div style="flex: 1;"></div>
71
+
72
+ <button class="tab-btn" onclick="handleSwitchTab('status-btn')" id="status-btn">
73
+ <span class="material-symbols-outlined" id="status-icon"> database </span>
74
+ Database Status
75
+ </button>
76
+ <button class="tab-btn" onclick="handleSwitchTab('erd-btn')" id="erd-btn">
77
+ <span class="material-symbols-outlined" id="erd-icon"> schema </span>
78
+ ERD Visualization
79
+ </button>
80
+ <button class="tab-btn" onclick="handleSwitchTab('sql-btn')" id="sql-btn">
81
+ <span class="material-symbols-outlined" id="sql-icon"> code </span>
82
+ SQL Console
83
+ </button>
84
+ </nav>
85
+ `,a=t({executeRawQuery:()=>f,fetchConfig:()=>s,fetchTableIndexes:()=>d,fetchTableSchema:()=>u,fetchTableStats:()=>c,fetchTableWithName:()=>l,fetchTables:()=>o});async function o(){return await(await fetch(`/api/tables`)).json()}async function s(){return await(await fetch(`/api/config`)).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/${e}/data?${s.toString()}`;return await(await fetch(c)).json()}async function u(e){return await(await fetch(`/api/tables/${e}/schema`)).json()}async function d(e){return await(await fetch(`/api/tables/${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(){try{let e=await o(),t=document.getElementById(`table-nav`),n=document.getElementById(`not-found-msg`);n&&n.remove(),e.success&&e.data&&e.data.length>0?(e.data.forEach(e=>{let n=document.createElement(`button`);n.type=`button`,n.className=`table-btn`,n.dataset.table=e,n.innerHTML=`<span>${e}</span><span class="table-btn-badge" id="badge-${e}" style="display:none;"></span>`,n.onclick=()=>{window.AppState.currentTable=e,window.AppState.currentTableBtnElement=n,window.AppState.currentTab===`erd-btn`||window.AppState.currentTab===`sql-btn`||window.AppState.currentTab===`status-btn`?window.handleSwitchTab(`data-btn`):window.renderCurrentView()},t.appendChild(n)}),window.handleSwitchTab(`data-btn`),c().then(e=>{e.success&&e.data&&Object.entries(e.data).forEach(([e,t])=>{let n=document.getElementById(`badge-${e}`);n&&(n.textContent=Number(t).toLocaleString(),n.style.display=`inline-flex`)})}).catch(e=>console.error(`Failed to load table stats:`,e))):(t.innerHTML=`<div id="not-found-msg">No Tables Found.</div>`,window.handleSwitchTab(`data-btn`))}catch(e){console.error(`Failed to fetch tables:`,e)}}function m(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.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.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 h(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 e=parseInt(i.dataset.rowIdx);n.selection={isDragging:!1,isDraggingRow:!0,startRow:e,endRow:e,startCol:0,endCol:r-1},m(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);n.selection={isDragging:!0,startRow:o,startCol:s,endRow:o,endCol:s},m(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),m(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),m(t,n))}),e.addEventListener(`mouseup`,()=>{n.selection&&(n.selection.isDragging=!1,n.selection.isDraggingRow=!1)})}function g(e,t){let n=document.createElement(`div`);n.className=`resizer`,e.appendChild(n),n.addEventListener(`click`,e=>e.stopPropagation()),n.addEventListener(`mousedown`,n=>{n.preventDefault(),n.stopPropagation();let r=n.pageX,i=e.offsetWidth,a=!1,o=n=>{a=!0,t&&(t.isResizing=!0);let o=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=``,a&&setTimeout(()=>{t&&(t.isResizing=!1)},100)};document.body.style.cursor=`col-resize`,document.addEventListener(`mousemove`,o),document.addEventListener(`mouseup`,s)})}async function _(){if(!window.DataGrid)return;let{pendingEdits:e,pendingInserts:t,pkColumn:n}=window.DataGrid,r=window.AppState.currentTable;if(!r||!n){alert(`Cannot save: No Primary Key detected for this table.`);return}let i=[];for(let[t,a]of Object.entries(e)){if(Object.keys(a).length===0)continue;let e=Object.entries(a).map(([e,t])=>t===``?`"${e}" = NULL`:`"${e}" = '${t.replace(/'/g,`''`)}'`).join(`, `);i.push(`UPDATE "${r}" SET ${e} WHERE "${n}" = '${t.replace(/'/g,`''`)}';`)}for(let e=0;e<t.length;e++){let n=t[e];if(Object.keys(n).length===0||!Object.values(n).some(e=>e!==``))continue;let a=Object.keys(n),o=a.map(e=>{let t=n[e];return t===``?`NULL`:`'${t.replace(/'/g,`''`)}'`});i.push(`INSERT INTO "${r}" ("${a.join(`", "`)}") VALUES (${o.join(`, `)});`)}if(window.DataGrid.pendingDeletes)for(let e of window.DataGrid.pendingDeletes)i.push(`DELETE FROM "${r}" WHERE "${n}" = '${e.replace(/'/g,`''`)}';`);if(i.length===0)return;let a=!0,o=``;for(let e of i)try{let t=await f(e);if(!t.success){a=!1,o=t.error;break}}catch(e){a=!1,o=e.message;break}a?(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.showToast&&window.showToast(`Data saved successfully!`)):(window.showToast?window.showToast(`Save failed: `+o,`error`):alert(`Save failed:
86
+ `+o),document.querySelectorAll(`.cell-edited`).forEach(e=>{e.classList.remove(`cell-edited`),e.classList.add(`cell-error`)})),window.updateSidebarDirtyState?.()}function v(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;if(e.innerHTML=t||(e.dataset.insertIndex===void 0?`<em>null</em>`:`+ New`),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)=>{i.innerHTML+=`<td class="data-cell ghost-row" data-row-idx="${a}" data-col-idx="${t}" data-insert-index="${r+1}" data-col="${e}">+ New</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 y(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`)?.dataset.pk;r!==void 0&&(t&&window.DataGrid.currentTransaction&&window.DataGrid.currentTransaction.push({type:`delete`,rowIdx:e,pk:r}),window.DataGrid.pendingDeletes.add(r),n.classList.add(`row-deleted`)),window.updateSidebarDirtyState?.()}function b(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 x(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`&&v(o,n,t,!0)}})})}function ee(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()||``,s=o.includes(`ENUM`),c=o===`DATE`,l=o.includes(`DATETIME`)||o.includes(`TIMESTAMP`),u=o.includes(`BOOL`)||o===`TINYINT(1)`,d=r.textContent===`null`||r.textContent===`+ New`?``:r.textContent,p;if(a&&a.fkTarget){p=document.createElement(`select`);let e=document.createElement(`option`);e.value=d,e.textContent=`Loading...`,p.appendChild(e);let{table:t,column:n}=a.fkTarget;f(`SELECT * FROM "${t}" LIMIT 100`).then(e=>{if(e.success&&e.data&&e.data.rows){if(p.innerHTML=``,a.nullable){let e=document.createElement(`option`);e.value=``,e.textContent=`-- None --`,p.appendChild(e)}let t=n;if(e.data.columns){let n=[`name`,`title`,`label`,`description`],r=e.data.columns.find(e=>n.includes(e.toLowerCase()));r&&(t=r)}if(e.data.rows.forEach(e=>{let r=String(e[n]),i=t===n?r:`${r} - ${e[t]}`,a=document.createElement(`option`);a.value=r,a.textContent=i,r===d&&(a.selected=!0),p.appendChild(a)}),d&&!e.data.rows.find(e=>String(e[n])===d)){let e=document.createElement(`option`);e.value=d,e.textContent=`${d} (Not in limit)`,e.selected=!0,p.appendChild(e)}}}).catch(t=>{e.textContent=`Error loading options`})}else if(s){let e=a.type.match(/enum\((.*?)\)/i),t=[];e&&(t=e[1].split(`,`).map(e=>e.trim().replace(/^'|'$/g,``))),p=document.createElement(`select`),t.forEach(e=>{let t=document.createElement(`option`);t.value=e,t.textContent=e,e===d&&(t.selected=!0),p.appendChild(t)})}else if(c)p=document.createElement(`input`),p.type=`date`,p.value=d;else if(l){p=document.createElement(`input`),p.type=`datetime-local`;let e=d.replace(` `,`T`).slice(0,16);p.value=e}else u?(p=document.createElement(`input`),p.type=`checkbox`,p.checked=d===`1`||d.toLowerCase()===`true`):(p=document.createElement(`input`),p.type=`text`,p.value=d);let m=!1,h=()=>{m=!0;let e=document.getElementById(`modal-editor-overlay`),t=document.getElementById(`modal-textarea`),n=document.getElementById(`modal-cancel-btn`),r=document.getElementById(`modal-save-btn`),a=document.getElementById(`modal-title`);a.textContent=`Edit ${i}`,t.value=p.value,e.style.display=`flex`,t.focus();let o=()=>{e.style.display=`none`,r.onclick=null,n.onclick=null,m=!1,p.focus()};n.onclick=o,r.onclick=()=>{p.value=t.value,o(),g()}};if(r.innerHTML=``,r.appendChild(p),o===``||!s&&!c&&!l&&!u&&!(a&&a.fkTarget)){let e=document.createElement(`span`);e.className=`material-symbols-outlined cell-expand-btn`,e.textContent=`open_in_full`,e.onmousedown=e=>e.preventDefault(),e.onclick=()=>h(),r.appendChild(e),p.style.width=`100%`,p.style.paddingRight=`32px`,p.addEventListener(`keydown`,e=>{e.key===`Enter`&&e.shiftKey?(e.preventDefault(),h()):e.key===`Enter`&&p.blur(),e.key===`Tab`&&(e.preventDefault(),p.blur(),document.body.dispatchEvent(new KeyboardEvent(`keydown`,{key:`Tab`,shiftKey:e.shiftKey,bubbles:!0})))})}else p.addEventListener(`keydown`,e=>{e.key===`Enter`&&p.blur(),e.key===`Tab`&&(e.preventDefault(),p.blur(),document.body.dispatchEvent(new KeyboardEvent(`keydown`,{key:`Tab`,shiftKey:e.shiftKey,bubbles:!0})))});p.focus();let g=()=>{if(m)return;let e=u?p.checked?`1`:`0`:p.value;l&&e&&(e=e.replace(`T`,` `)+`:00`),window.DataGrid.currentTransaction=[],v(r,e,n),window.DataGrid.currentTransaction.length>0&&window.DataGrid.history.push(window.DataGrid.currentTransaction),window.DataGrid.currentTransaction=null};p.addEventListener(`blur`,()=>{setTimeout(()=>{m||g()},100)})})}function S(){let e=window.AppState?.currentTable;if(!e)return``;let t=document.getElementById(`filter-val-${e}`)?.value.trim(),n=document.getElementById(`filter-op-${e}`)?.value,r=document.getElementById(`filter-col-${e}`)?.value,i=``;if(t||n===`IS NULL`){let e=t;e&&!e.startsWith(`'`)&&!e.endsWith(`'`)&&isNaN(Number(e))&&(e.toUpperCase().includes(` AND `)||e.toUpperCase().includes(` OR `)||(e=`'${e.replace(/'/g,`''`)}'`)),i=`"${r}" ${n} ${e}`}return i}function C(e,t,n,r){let i=`<td class="row-header" data-row-idx="${t}">${t+1}</td>`,a=n?e[n]:t;return r.forEach((n,r)=>{let o=e[n]===null?`null`:String(e[n]),s=o.replace(/"/g,`&quot;`),c=o===`null`?`<em>null</em>`:o.replace(/</g,`&lt;`);i+=`<td class="data-cell" data-row-idx="${t}" data-col-idx="${r}" data-pk="${a}" data-col="${n}" data-original="${s}">${c}</td>`}),i}async function w(e,t,n=``,r=!1,i=null){document.querySelectorAll(`.table-btn`).forEach(e=>e.classList.remove(`active`)),t&&t.classList.add(`active`);let a=document.getElementById(`table-name`);a&&(a.textContent=e);let o=i||document.getElementById(`main-content`);r||(o.innerHTML=`<div style='padding:24px;'>Loading...</div>`);try{let i=await u(e);if(!i.success)throw Error(i.error);let a=i.data,s=a.find(e=>e.isPk)?.name;(!r||!window.DataGrid)&&(window.DataGrid={schema:a,pkColumn:s,pendingEdits:{},pendingInserts:[{}],pendingDeletes:new Set,selectedCell:null,history:[],currentTransaction:null,sortState:{col:s||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 c=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(c.success&&c.data){let n=c.data.rows,i=c.data.columns;window.DataGrid.pagination.hasMore=n.length===window.DataGrid.pagination.limit;let u=i.map(e=>`<option value="${e}">${e}</option>`).join(``);r||(o.innerHTML=`
87
+ <div class="toolbar">
88
+ <div class="filter-group">
89
+ <div class="filter-icon-container">
90
+ <span class="material-symbols-outlined" id="filter-icon">filter_list</span>
91
+ <span>Filter</span>
92
+ </div>
93
+ <select id="filter-col-${e}" class="filter-select">${u}</select>
94
+ <select id="filter-op-${e}" class="filter-select">
95
+ <option value="=">=</option>
96
+ <option value=">">></option>
97
+ <option value="<"><</option>
98
+ <option value=">=">>=</option>
99
+ <option value="<="><=</option>
100
+ <option value="LIKE">LIKE</option>
101
+ <option value="!=">!=</option>
102
+ </select>
103
+ <input type="text" id="filter-val-${e}" class="filter-input" placeholder="Enter value..." />
104
+ </div>
105
+ <div style="flex:1;"></div>
106
+ <button id="btn-refresh-data-${e}" class="refresh-btn" title="Refresh Data (F5)"><span class="material-symbols-outlined">refresh</span></button>
107
+ </div>
108
+ <div class="table-container" id="data-grid-container-${e}"></div>
109
+ `);let d=`<table class="data-table" id="data-grid-table-${e}"><thead><tr>`;d+=`<th class="row-header">#</th>`,i.forEach(e=>{let t=a.find(t=>t.name===e),n=``,r=``;t&&(t.isPk&&(n=` <span style="opacity:0.5; font-size:10px;">(PK)</span>`),t.name.toLowerCase().includes(`id`)&&!t.isPk&&(n=` <span style="opacity:0.5; font-size:10px;">(FK)</span>`),r=`<br><span style="font-weight:normal; opacity:0.7; font-size:10px; font-family:monospace;">${t.type}</span>`);let i=``;window.DataGrid.sortState.col===e&&(i=window.DataGrid.sortState.asc?`▲`:`▼`),d+=`<th class="sortable" data-col="${e}" style="cursor:pointer; user-select:none;">
110
+ <div style="display: flex; justify-content: space-between; align-items: center;">
111
+ <div>${e}${n}${r}</div>
112
+ <div class="sort-arrow" style="font-size:10px; opacity:0.8; margin-left: 8px; width: 12px; text-align: right;">${i}</div>
113
+ </div>
114
+ </th>`}),d+=`</tr></thead><tbody>`,n&&n.length>0&&n.forEach((e,t)=>{d+=`<tr>${C(e,t,s,i)}</tr>`}),d+=`<tr class="ghost-row-tr">`;let f=n?n.length:0;d+=`<td class="row-header" data-row-idx="${f}">*</td>`,i.forEach((e,t)=>{d+=`<td class="data-cell ghost-row" data-row-idx="${f}" data-col-idx="${t}" data-insert-index="0" data-col="${e}">+ New</td>`}),d+=`</tr></tbody></table>`;let p=document.getElementById(`data-grid-container-${e}`);if(!p)return;if(p.innerHTML=d,document.querySelectorAll(`th.sortable`).forEach(n=>{n.onclick=r=>{if(window.DataGrid&&window.DataGrid.isResizing)return;if(Object.keys(window.DataGrid.pendingEdits).length>0||window.DataGrid.pendingInserts.length>1||window.DataGrid.pendingDeletes.size>0){alert(`You have unsaved changes. Please save changes before sorting.`);return}let i=n.dataset.col;window.DataGrid.sortState.col===i?window.DataGrid.sortState.asc=!window.DataGrid.sortState.asc:(window.DataGrid.sortState.col=i,window.DataGrid.sortState.asc=!0),window.DataGrid.pagination.offset=0,w(e,t,S(),!0)},g(n,window.DataGrid)}),h(p,`data-grid-table-${e}`,window.DataGrid,i.length),ee(p,a,i),!r){let n=document.getElementById(`filter-val-${e}`),r=(n=!0)=>{n&&window.DataGrid&&(window.DataGrid.pagination.offset=0),w(e,t,S(),!0)},a;n&&n.addEventListener(`input`,()=>{clearTimeout(a),a=setTimeout(()=>r(!0),400)});let o=document.getElementById(`filter-col-${e}`),c=document.getElementById(`filter-op-${e}`);o&&o.addEventListener(`change`,()=>r(!0)),c&&c.addEventListener(`change`,()=>r(!0));let u=()=>{(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?.(),r(!1))},d=document.getElementById(`btn-refresh-data-${e}`);d&&(d.onclick=u),window.DataGrid.refreshData=u;let f=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:S(),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 a=r.querySelector(`td[data-insert-index]`)?.closest(`tr`),o=window.DataGrid.pagination.offset;t.forEach((e,t)=>{let n=document.createElement(`tr`);n.innerHTML=C(e,o+t,s,i),a?r.insertBefore(n,a):r.appendChild(n)});let c=o+t.length,l=r.querySelectorAll(`td[data-insert-index]`),u=new Set;l.forEach(e=>{let t=e.closest(`tr`);if(u.has(t))return;u.add(t);let n=t.querySelector(`.row-header`);n&&(n.dataset.rowIdx=c),t.querySelectorAll(`td.data-cell`).forEach(e=>e.dataset.rowIdx=c),c++})}}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&&f()})},50)}}else o.innerHTML=`<div style="padding:24px; color:red;">Error: ${c.error}</div>`}catch(e){o.innerHTML=`<div style="padding:24px; color:red;">Failed to load data: ${e.message}</div>`}}async function te(){if(!window.SchemaGrid)return;let{pendingEdits:e,pendingInserts:t,pendingDeletes:n}=window.SchemaGrid,r=window.AppState.currentTable;if(!r)return;let i=[];if(n)for(let e of n)i.push(`ALTER TABLE "${r}" DROP COLUMN "${e}";`);for(let[t,n]of Object.entries(e)){let e=t;if(n.name&&n.name!==t&&(i.push(`ALTER TABLE "${r}" RENAME COLUMN "${t}" TO "${n.name}";`),e=n.name),Object.keys(n).filter(e=>e!==`name`).length>0){let a=window.SchemaGrid.schema?.find(e=>e.name===t)||{},o=n.type===void 0?a.type:n.type,s=[],c=n.isPk===void 0?a.isPk:n.isPk,l=String(c).toUpperCase();if((l===`1`||l===`TRUE`||l===`YES`||l.includes(`PK`)||l===`KEY`)&&s.push(`PRIMARY KEY`),l.includes(`FK:`)){let e=l.match(/FK:\s*([^\s,]+)/i);if(e&&e[1]){let t=e[1].split(`.`);t.length===2&&s.push(`REFERENCES "${t[0]}"("${t[1]}")`)}}let u=n.nullable===void 0?a.nullable:n.nullable;(u===`0`||u===`No`||u===!1)&&s.push(`NOT NULL`);let d=n.defaultValue===void 0?a.defaultValue:n.defaultValue;if(d&&s.push(`DEFAULT '${String(d).replace(/'/g,`''`)}'`),window.AppState.dbType===`sqlite`){alert(`SQLite does not support altering column types directly. Please recreate the table or use Raw SQL.`);return}else window.AppState.dbType===`postgres`?(i.push(`ALTER TABLE "${r}" ALTER COLUMN "${e}" TYPE ${o};`),s.includes(`NOT NULL`)&&i.push(`ALTER TABLE "${r}" ALTER COLUMN "${e}" SET NOT NULL;`),d&&i.push(`ALTER TABLE "${r}" ALTER COLUMN "${e}" SET DEFAULT '${String(d).replace(/'/g,`''`)}';`)):i.push(`ALTER TABLE "${r}" MODIFY COLUMN "${e}" ${o} ${s.join(` `)};`)}}for(let e=0;e<t.length;e++){let n=t[e];if(Object.keys(n).length===0||!n.name||n.name.trim()===``)continue;let a=n.name.trim(),o=n.type||`TEXT`,s=[],c=String(n.isPk||``).toUpperCase();if((c===`1`||c===`TRUE`||c===`YES`||c.includes(`PK`)||c===`KEY`)&&s.push(`PRIMARY KEY`),c.includes(`FK:`)){let e=c.match(/FK:\s*([^\s,]+)/i);if(e&&e[1]){let t=e[1].split(`.`);t.length===2&&s.push(`REFERENCES "${t[0]}"("${t[1]}")`)}}(n.nullable===`0`||n.nullable===`false`||n.nullable===`No`)&&s.push(`NOT NULL`),n.defaultValue&&s.push(`DEFAULT '${n.defaultValue.replace(/'/g,`''`)}'`),i.push(`ALTER TABLE "${r}" ADD COLUMN "${a}" ${o} ${s.join(` `)};`)}if(window.SchemaGrid.pendingIndexEdits){for(let e of window.SchemaGrid.pendingIndexEdits.dropped)e&&e.trim()!==``&&i.push(`DROP INDEX "${e}";`);for(let e of window.SchemaGrid.pendingIndexEdits.added){let t=``;t=e.name&&e.name.trim()!==``?`"${e.name}"`:`"idx_${r}_${e.columns.join(`_`)}_${Date.now()}"`;let n=e.isUnique?`UNIQUE`:``,a=e.columns.map(e=>`"${e}"`).join(`, `);i.push(`CREATE ${n} INDEX IF NOT EXISTS ${t} ON "${r}" (${a});`)}}if(i.length===0)return;let a=!0,o=``;for(let e of i)try{let t=await f(e);if(!t.success){a=!1,o=t.error;break}}catch(e){a=!1,o=e.message;break}if(a){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);let e=document.getElementById(`btn-refresh-schema-${r}`);e?e.click():window.renderCurrentView(),window.showToast&&window.showToast(`Schema saved successfully!`)}else o.includes(`near "MODIFY": syntax error`)?o=`SQLite: Currently does not support modifying existing column types or constraints directly. You can only Rename columns or Add new columns.`:o.includes(`syntax error`)&&(o=`SQLite: `+o),window.showToast?window.showToast(`Save failed: `+o,`error`):alert(`Save failed:
115
+ `+o),document.querySelectorAll(`.cell-edited`).forEach(e=>{e.classList.remove(`cell-edited`),e.classList.add(`cell-error`)});window.updateSidebarDirtyState?.()}function T(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;if(e.innerHTML=t||(e.dataset.insertIndex===void 0?`<span style="color:var(--color-text-soft)">-</span>`:`+ New`),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)=>{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}">+ New</td>`}),t.appendChild(i)}}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 E(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 ne(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 re(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`),T(o,n,t,!0))}})})}function ie(){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=o.map(e=>`<option value="${e}">${e}</option>`).join(``);t=document.createElement(`div`),t.id=`index-modal`,t.style.cssText=`
116
+ position: fixed; top:0; left:0; width:100vw; height:100vh; background:rgba(0,0,0,0.5);
117
+ display:flex; justify-content:center; align-items:center; z-index:9999;
118
+ `,t.innerHTML=`
119
+ <div style="background:var(--color-bg-primary); width:500px; border-radius:8px; box-shadow:0 4px 12px rgba(0,0,0,0.2); overflow:hidden; display:flex; flex-direction:column;">
120
+ <div style="padding:16px; border-bottom:1px solid var(--color-border); display:flex; justify-content:space-between; align-items:center;">
121
+ <h3 style="margin:0;">Manage Indexes</h3>
122
+ <button id="close-idx-modal" style="background:none; border:none; color:var(--color-text-primary); cursor:pointer;"><span class="material-symbols-outlined">close</span></button>
123
+ </div>
124
+ <div style="padding:16px; max-height:300px; overflow-y:auto;" id="idx-list-container">
125
+ </div>
126
+ <div style="padding:16px; border-top:1px solid var(--color-border); background:var(--color-bg-secondary);">
127
+ <div style="font-weight:500; margin-bottom:8px;">Add New Index</div>
128
+ <div style="display:flex; flex-direction:column; gap:8px;">
129
+ <input type="text" id="new-idx-name" placeholder="Index Name (Optional)" style="padding:6px; border-radius:4px; border:1px solid var(--color-border); background:var(--color-bg-primary); color:var(--color-text-primary);" />
130
+ <select id="new-idx-cols" multiple style="padding:6px; border-radius:4px; border:1px solid var(--color-border); background:var(--color-bg-primary); color:var(--color-text-primary); height:80px;">
131
+ ${s}
132
+ </select>
133
+ <div style="font-size:12px; color:var(--color-text-soft);">Hold Ctrl/Cmd to select multiple columns</div>
134
+ <label style="display:flex; align-items:center; gap:6px; cursor:pointer;">
135
+ <input type="checkbox" id="new-idx-unique" /> Unique Index
136
+ </label>
137
+ <button id="add-idx-btn" class="primary" style="align-self:flex-end; padding:6px 16px; border-radius:4px; border:none; cursor:pointer;">Add</button>
138
+ </div>
139
+ </div>
140
+ <div style="padding:16px; border-top:1px solid var(--color-border); display:flex; justify-content:flex-end; gap:8px;">
141
+ <button id="cancel-idx-btn" class="secondary" style="padding:6px 16px; border-radius:4px; border:1px solid var(--color-border); cursor:pointer;">Cancel</button>
142
+ <button id="save-idx-btn" class="primary" style="padding:6px 16px; border-radius:4px; border:none; cursor:pointer;">Save Changes</button>
143
+ </div>
144
+ </div>
145
+ `,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=a.map((e,t)=>`
146
+ <div class="index-row" style="display:flex; gap:8px; align-items:center; margin-bottom:8px; padding:8px; background:var(--color-bg-primary); border:1px solid var(--color-border); border-radius:4px;">
147
+ <div style="flex:1;"><strong>${e.name||`-`}</strong></div>
148
+ <div style="flex:2; font-size:12px; color:var(--color-text-secondary);">${e.columns.join(`, `)}</div>
149
+ <div style="width:60px; font-size:12px; text-align:center;">${e.isUnique?`UNIQUE`:``}</div>
150
+ <button class="icon-btn delete-idx-btn" data-idx="${t}" style="color:var(--color-error); border:none; background:none; cursor:pointer;"><span class="material-symbols-outlined" style="font-size:18px;">delete</span></button>
151
+ </div>
152
+ `).join(``);a.length===0&&(e=`<div style="padding:16px; text-align:center; color:var(--color-text-secondary);">No indexes yet.</div>`),document.getElementById(`idx-list-container`).innerHTML=e,document.querySelectorAll(`.delete-idx-btn`).forEach(e=>{e.onclick=e=>{let t=parseInt(e.currentTarget.dataset.idx,10);a.splice(t,1),l()}})};l(),document.getElementById(`add-idx-btn`).onclick=()=>{let e=document.getElementById(`new-idx-name`).value.trim(),t=document.getElementById(`new-idx-cols`),n=Array.from(t.selectedOptions).map(e=>e.value),r=document.getElementById(`new-idx-unique`).checked;if(n.length===0){alert(`Please select at least one column for the index.`);return}a.push({name:e,columns:n,isUnique:r}),document.getElementById(`new-idx-name`).value=``,document.getElementById(`new-idx-unique`).checked=!1,t.selectedIndex=-1,l()},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 D(e,t){if(!window.SchemaGrid)return;let n=document.getElementById(`pkfk-modal`);n&&n.remove();let r=e.dataset.insertIndex!==void 0,i=t.includes(`PK`),a=t.includes(`FK`),o=``,s=``;if(a){let e=t.match(/FK \((.*?)\)/);if(e&&e[1]){let t=e[1].split(`.`);t.length===2&&(o=t[0],s=t[1])}else{let e=t.match(/FK:\s*([^\s,]+)/i);if(e&&e[1]){let t=e[1].split(`.`);t.length===2&&(o=t[0],s=t[1])}}}n=document.createElement(`div`),n.id=`pkfk-modal`,n.style.cssText=`
153
+ position: fixed; top:0; left:0; width:100vw; height:100vh; background:rgba(0,0,0,0.5);
154
+ display:flex; justify-content:center; align-items:center; z-index:9999;
155
+ `,n.innerHTML=`
156
+ <div style="background:var(--color-bg-primary); width:400px; border-radius:8px; box-shadow:0 4px 12px rgba(0,0,0,0.2); overflow:hidden; display:flex; flex-direction:column;">
157
+ <div style="padding:16px; border-bottom:1px solid var(--color-border); display:flex; justify-content:space-between; align-items:center;">
158
+ <h3 style="margin:0;">Manage Keys</h3>
159
+ <button id="close-pkfk-modal" style="background:none; border:none; color:var(--color-text-primary); cursor:pointer;"><span class="material-symbols-outlined">close</span></button>
160
+ </div>
161
+ <div style="padding:16px; display:flex; flex-direction:column; gap:16px;">
162
+ <label style="display:flex; align-items:center; gap:8px; cursor:pointer;">
163
+ <input type="checkbox" id="modal-is-pk" ${i?`checked`:``} />
164
+ <strong>Primary Key (PK)</strong>
165
+ </label>
166
+
167
+ <div style="border-top: 1px solid var(--color-border); margin: 8px 0;"></div>
168
+
169
+ <label style="display:flex; align-items:center; gap:8px; cursor:${r?`pointer`:`not-allowed`}; opacity:${r?`1`:`0.6`};">
170
+ <input type="checkbox" id="modal-is-fk" ${a?`checked`:``} ${r?``:`disabled`} />
171
+ <strong>Foreign Key (FK)</strong>
172
+ </label>
173
+
174
+ ${r?``:`<div style="font-size:11px; color:var(--color-text-soft); margin-top:-12px; margin-left:24px;">Note: FKs can only be added when creating new columns.</div>`}
175
+
176
+ <div id="fk-settings-container" style="display:${a?`flex`:`none`}; flex-direction:column; gap:8px; padding-left: 24px;">
177
+ <div>
178
+ <div style="font-size:12px; color:var(--color-text-secondary); margin-bottom:4px;">Target Table</div>
179
+ <select id="modal-fk-table" style="width:100%; padding:6px; border-radius:4px; border:1px solid var(--color-border); background:var(--color-bg-primary); color:var(--color-text-primary);">
180
+ <option value="">Loading tables...</option>
181
+ </select>
182
+ </div>
183
+ <div>
184
+ <div style="font-size:12px; color:var(--color-text-secondary); margin-bottom:4px;">Target Column</div>
185
+ <select id="modal-fk-col" style="width:100%; padding:6px; border-radius:4px; border:1px solid var(--color-border); background:var(--color-bg-primary); color:var(--color-text-primary);" ${o?``:`disabled`}>
186
+ <option value="">Select a table first</option>
187
+ </select>
188
+ </div>
189
+ </div>
190
+ </div>
191
+ <div style="padding:16px; border-top:1px solid var(--color-border); background:var(--color-bg-secondary); display:flex; justify-content:flex-end; gap:8px;">
192
+ <button id="cancel-pkfk-btn" class="secondary" style="padding:6px 16px; border-radius:4px; border:1px solid var(--color-border); cursor:pointer;">Cancel</button>
193
+ <button id="save-pkfk-btn" class="primary" style="padding:6px 16px; border-radius:4px; border:none; cursor:pointer;">Save</button>
194
+ </div>
195
+ </div>
196
+ `,document.body.appendChild(n);let c=()=>n.remove();document.getElementById(`close-pkfk-modal`).onclick=c,document.getElementById(`cancel-pkfk-btn`).onclick=c;let l=document.getElementById(`modal-is-fk`),u=document.getElementById(`fk-settings-container`),d=document.getElementById(`modal-fk-table`),f=document.getElementById(`modal-fk-col`);l.addEventListener(`change`,e=>{u.style.display=e.target.checked?`flex`:`none`});try{let e=await(await fetch(`/api/tables`)).json();e.success&&e.data&&(d.innerHTML=`<option value="">-- Select Table --</option>`+e.data.map(e=>`<option value="${e}" ${e===o?`selected`:``}>${e}</option>`).join(``),o&&p(o,s))}catch{d.innerHTML=`<option value="">Error loading tables</option>`}async function p(e,t=``){f.disabled=!0,f.innerHTML=`<option value="">Loading columns...</option>`;try{let n=await(await fetch(`/api/tables/${e}/schema`)).json();n.success&&n.data&&(f.innerHTML=`<option value="">-- Select Column --</option>`+n.data.map(e=>`<option value="${e.name}" ${e.name===t?`selected`:``}>${e.name}</option>`).join(``),f.disabled=!1)}catch{f.innerHTML=`<option value="">Error loading columns</option>`}}d.addEventListener(`change`,e=>{let t=e.target.value;t?p(t):(f.innerHTML=`<option value="">Select a table first</option>`,f.disabled=!0)}),document.getElementById(`save-pkfk-btn`).onclick=()=>{let t=document.getElementById(`modal-is-pk`).checked,n=document.getElementById(`modal-is-fk`).checked,r=d.value,l=f.value;if(t===i&&n===a&&r===o&&l===s){c();return}let u=``;if(t&&n){if(!r||!l){alert(`Please select both Target Table and Target Column for the Foreign Key.`);return}u=`PK, FK: ${r}.${l}`}else if(t)u=`PK`;else if(n){if(!r||!l){alert(`Please select both Target Table and Target Column for the Foreign Key.`);return}u=`FK: ${r}.${l}`}window.SchemaGrid.currentTransaction=[],T(e,u,[`name`,`type`,`isPk`,`nullable`,`defaultValue`,`indexing`]),window.SchemaGrid.currentTransaction.length>0&&window.SchemaGrid.history.push(window.SchemaGrid.currentTransaction),window.SchemaGrid.currentTransaction=null,c()}}function ae(e,t){e.addEventListener(`click`,e=>{e.target.closest(`.manage-indexes-cell`)&&ie()}),e.addEventListener(`dblclick`,e=>{let n=e.target.closest(`td.data-cell`);if(!n||n.querySelector(`input, select`))return;let r=n.dataset.colKey;n.dataset.insertIndex;let i=n.textContent===`-`||n.textContent===`+ New`||n.textContent===`No`||n.textContent===`null`?``:n.textContent===`Yes`?`1`:n.textContent,a;if(r===`isPk`){D(n,n.textContent);return}else if(r===`nullable`)a=document.createElement(`select`),[`No`,`Yes`].forEach(e=>{let t=document.createElement(`option`);t.value=e,t.textContent=e,(e===`Yes`&&i===`1`||e===`No`&&i===``)&&(t.selected=!0),a.appendChild(t)});else if(r===`type`){a=document.createElement(`select`);let e=[`INTEGER`,`TEXT`,`REAL`,`BLOB`,`NUMERIC`,`BOOLEAN`,`DATE`,`DATETIME`,`JSON`,`VARCHAR(255)`,`DECIMAL(10,2)`,`UUID`];i&&!e.some(e=>e.toUpperCase()===i.toUpperCase())&&e.unshift(i),e.forEach(e=>{let t=document.createElement(`option`);t.value=e,t.textContent=e,e.toUpperCase()===i.toUpperCase()&&(t.selected=!0),a.appendChild(t)})}else a=document.createElement(`input`),a.type=`text`,a.value=i;n.innerHTML=``,n.appendChild(a),a.style.width=`100%`,a.addEventListener(`keydown`,e=>{e.key===`Enter`&&a.blur(),e.key===`Tab`&&(e.preventDefault(),a.blur(),document.body.dispatchEvent(new KeyboardEvent(`keydown`,{key:`Tab`,shiftKey:e.shiftKey,bubbles:!0})))}),a.focus();let o=()=>{let e=a.value;window.SchemaGrid.currentTransaction=[],T(n,e,t),window.SchemaGrid.currentTransaction.length>0&&window.SchemaGrid.history.push(window.SchemaGrid.currentTransaction),window.SchemaGrid.currentTransaction=null};a.addEventListener(`blur`,()=>{o()})})}async function O(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 style='padding:24px;'>Loading Schema...</div>`;try{let[n,r]=await Promise.all([u(e),d(e)]);if(n.success&&n.data){let a=n.data,o=r.success&&r.data?r.data:[];window.SchemaGrid={schema:a,indexes:o,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=`
197
+ <div class="toolbar">
198
+ <div class="filter-group">
199
+ <div class="filter-icon-container">
200
+ <span class="material-symbols-outlined">search</span>
201
+ <span>Search</span>
202
+ </div>
203
+ <input type="text" id="schema-search-val-${e}" class="filter-input" placeholder="Search name or type..." style="width: 250px;" value="${window.SchemaGrid.filterText}" />
204
+ </div>
205
+ <div style="flex:1;"></div>
206
+ <button id="btn-refresh-schema-${e}" class="refresh-btn" title="Refresh Schema (F5)"><span class="material-symbols-outlined">refresh</span></button>
207
+ </div>
208
+ <div id="schema-grid-container-${e}" class="table-container"></div>
209
+ `,window.renderSchemaGrid=()=>{let t=document.getElementById(`schema-grid-container-${e}`);if(!t)return;let n=[...window.SchemaGrid.schema];if(window.SchemaGrid.filterText){let e=window.SchemaGrid.filterText.toLowerCase();n=n.filter(t=>t.name&&t.name.toLowerCase().includes(e)||t.type&&t.type.toLowerCase().includes(e))}window.SchemaGrid.sortState.colKey&&n.sort((e,t)=>{let n=window.SchemaGrid.sortState.colKey,r=e[n],i=t[n];return r??=``,i??=``,r<i?window.SchemaGrid.sortState.asc?-1:1:r>i?window.SchemaGrid.sortState.asc?1:-1:0});let r=[`name`,`type`,`isPk`,`nullable`,`defaultValue`,`indexing`],i=[`Name`,`Type`,`PK/FK`,`Nullable`,`Default Value`,`Indexing`],a=`<table class="data-table" id="schema-grid-table-${e}"><thead><tr><th class="row-header">#</th>`;r.forEach((e,t)=>{let n=``;window.SchemaGrid.sortState.colKey===e&&(n=window.SchemaGrid.sortState.asc?`▲`:`▼`),a+=`<th class="sortable" data-col-key="${e}">
210
+ <div style="display: flex; justify-content: space-between; align-items: center;">
211
+ <div>${i[t]}</div>
212
+ <div class="sort-arrow" style="font-size:10px; opacity:0.8; margin-left: 8px; width: 12px; text-align: right;">${n}</div>
213
+ </div>
214
+ </th>`}),a+=`</tr></thead><tbody>`,n&&n.length>0&&n.forEach((e,t)=>{a+=`<tr><td class="row-header" data-row-idx="${t}">${t+1}</td>`,r.forEach((r,i)=>{if(r===`indexing`){if(t===0){let e=(n?n.length:0)+1,t=window.SchemaGrid.indexes.length,r=window.SchemaGrid.pendingIndexEdits.added.length,i=window.SchemaGrid.pendingIndexEdits.dropped.length,o=t+r-i;a+=`<td class="data-cell manage-indexes-cell" rowspan="${e}" style="text-align:center; vertical-align:middle; cursor:pointer; color:var(--color-brand-500); font-weight:500; border-left: 1px solid var(--color-border);">
215
+ Manage Indexes (${o})
216
+ </td>`}return}let o=e[r];if(r===`isPk`){let t=o,n=!!e.fkTarget;o=t&&n?`PK, FK (${e.fkTarget.table}.${e.fkTarget.column})`:t?`PK`:n?`FK (${e.fkTarget.table}.${e.fkTarget.column})`:`-`}else r===`nullable`?o=o?`Yes`:`No`:o??=``;let s=String(o).replace(/"/g,`&quot;`),c=o===``?`<span style="color:var(--color-text-soft)">-</span>`:String(o).replace(/</g,`&lt;`);a+=`<td class="data-cell" data-row-idx="${t}" data-col-idx="${i}" data-pk="${e.name}" data-col-key="${r}" data-original="${s}">${c}</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>`,r.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}">+ New</td>`)}),a+=`</tr></tbody></table>`,t.innerHTML=a,document.querySelectorAll(`#schema-grid-table-${e} th.sortable`).forEach(e=>{e.onclick=t=>{if(window.SchemaGrid.isResizing)return;if(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){alert(`You have unsaved changes! Please press Ctrl+S to save them before sorting.`);return}let n=e.dataset.colKey;window.SchemaGrid.sortState.colKey===n?window.SchemaGrid.sortState.asc=!window.SchemaGrid.sortState.asc:(window.SchemaGrid.sortState.colKey=n,window.SchemaGrid.sortState.asc=!0),window.SchemaGrid.selection={startRow:-1,startCol:-1,endRow:-1,endCol:-1,isDragging:!1},window.renderSchemaGrid()},g(e,window.SchemaGrid)}),h(t,`schema-grid-table-${e}`,window.SchemaGrid,r.length),ae(t,r)},window.renderSchemaGrid();let s=document.getElementById(`schema-search-val-${e}`);s&&s.addEventListener(`input`,e=>{window.SchemaGrid.filterText=e.target.value,window.SchemaGrid.selection={startRow:-1,startCol:-1,endRow:-1,endCol:-1,isDragging:!1},window.renderSchemaGrid()});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?.(),O(e,t,document.getElementById(`view-schema-btn-${e}`)))})}else i.innerHTML=`<div style="padding:24px; color:red;">Error: ${n.error}</div>`}catch(e){i.innerHTML=`<div style="padding:24px; color:red;">Failed to load schema: ${e.message}</div>`}}var k=0,A=(e,t,n)=>{let r=[e.map(e=>`"${String(e).replace(/"/g,`""`)}"`).join(`,`),...t.map(t=>e.map(e=>`"${(t[e]===null?``:String(t[e])).replace(/"/g,`""`)}"`).join(`,`))].join(`\\n`),i=new Blob([r],{type:`text/csv;charset=utf-8;`}),a=URL.createObjectURL(i),o=document.createElement(`a`);o.setAttribute(`href`,a),o.setAttribute(`download`,n),o.style.visibility=`hidden`,document.body.appendChild(o),o.click(),document.body.removeChild(o)},j=async(e,t,n)=>{let r=e||t.value.substring(t.selectionStart,t.selectionEnd).trim();if(r||=t.value.trim(),!r)return;if(r.toLowerCase()===`clear`||r.toLowerCase()===`clear;`){n.innerHTML=``,e||(t.selectionStart=t.selectionEnd,t.value=``);return}window.AppState.lastQuery=t.value,window.AppState.queryHistory||(window.AppState.queryHistory=[]);let i=window.AppState.queryHistory;i.includes(r)||(i.unshift(r),i.length>10&&i.pop(),window.dispatchEvent(new Event(`query-history-updated`))),k++;let a=`history-block-${k}`,o=document.getElementById(`console-welcome-msg`);o&&(o.style.display=`none`);let s=document.createElement(`div`);s.className=`console-history-block`,s.innerHTML=`
217
+ <div class="console-history-header">
218
+ <div class="console-history-sql">${r.replace(/</g,`&lt;`).replace(/>/g,`&gt;`)}</div>
219
+ <div class="console-history-actions">
220
+ <button class="icon-btn copy-btn" title="Copy SQL"><span class="material-symbols-outlined" style="font-size: 16px;">content_copy</span></button>
221
+ <button class="icon-btn rerun-btn" title="Re-run"><span class="material-symbols-outlined" style="font-size: 16px;">refresh</span></button>
222
+ </div>
223
+ </div>
224
+ <div id="${a}-results" class="console-history-results">
225
+ <div class="console-msg-executing">
226
+ <span class="material-symbols-outlined" style="animation: spin 1s linear infinite;">sync</span> Executing...
227
+ </div>
228
+ </div>
229
+ `,n.appendChild(s),s.querySelector(`.copy-btn`).onclick=()=>{navigator.clipboard.writeText(r),window.showToast?window.showToast(`SQL copied to clipboard`):alert(`Copied`)},s.querySelector(`.rerun-btn`).onclick=()=>j(r,t,n),n.scrollTop=n.scrollHeight,e||(t.selectionStart=t.selectionEnd,t.value=``);try{let e=performance.now(),t=await f(r),i=(performance.now()-e).toFixed(1),o=document.getElementById(`${a}-results`);if(!t.success){o.innerHTML=`<div class="console-msg-error"><span class="material-symbols-outlined" style="font-size: 16px; margin-top: 2px;">error</span><span>Error: ${t.error}</span></div>`,n.scrollTop=n.scrollHeight;return}let s=t.data.rows||[],c=s.length;if(c===0){o.innerHTML=`<div class="console-msg-success"><span class="material-symbols-outlined" style="font-size: 16px;">check_circle</span> Query executed successfully in ${i}ms. 0 rows returned.</div>`,n.scrollTop=n.scrollHeight;return}let l=Object.keys(s[0]),u=document.createElement(`div`);u.className=`console-stats-header`;let d=s.slice(0,1e3);u.innerHTML=`
230
+ <div class="console-stats-info">
231
+ <span class="material-symbols-outlined" style="color: #10b981; font-size: 14px;">check_circle</span>
232
+ <span>${c} rows${c>1e3?` (Showing first 1000)`:``} &middot; ${i}ms</span>
233
+ </div>
234
+ <button class="console-export-btn export-btn">
235
+ <span class="material-symbols-outlined" style="font-size: 14px;">download</span> CSV
236
+ </button>
237
+ `,o.innerHTML=``,o.appendChild(u),u.querySelector(`.export-btn`).onclick=()=>{A(l,s,`drixio_export_${new Date().getTime()}.csv`)};let p=document.createElement(`div`);p.className=`table-container`,p.style.border=`1px solid var(--color-border)`,p.style.borderRadius=`6px`,p.style.overflow=`auto`,p.style.maxHeight=`320px`;let m=document.createElement(`table`);m.className=`data-table`;let h=document.createElement(`thead`);h.style.position=`sticky`,h.style.top=`0`,h.style.zIndex=`10`;let g=document.createElement(`tr`),_=document.createElement(`th`);_.className=`row-header`,_.textContent=`#`,g.appendChild(_),l.forEach(e=>{let t=document.createElement(`th`);t.textContent=e,g.appendChild(t)}),h.appendChild(g),m.appendChild(h);let v=document.createElement(`tbody`);d.forEach((e,t)=>{let n=document.createElement(`tr`),r=document.createElement(`td`);r.className=`row-header`,r.textContent=t+1,n.appendChild(r),l.forEach(t=>{let r=document.createElement(`td`);r.className=`data-cell data-cell-truncate`;let i=e[t];if(i===null){let e=document.createElement(`span`);e.textContent=`NULL`,e.style.color=`var(--color-text-soft)`,e.style.fontStyle=`italic`,r.appendChild(e)}else{let e=String(i);r.textContent=e,e.length>40&&(r.title=e)}n.appendChild(r)}),v.appendChild(n)}),m.appendChild(v),p.appendChild(m),o.appendChild(p),setTimeout(()=>n.scrollTop=n.scrollHeight,10)}catch(e){let t=document.getElementById(`${a}-results`);t&&(t.innerHTML=`<div class="console-msg-error"><span class="material-symbols-outlined" style="font-size: 16px; margin-top: 2px;">error</span><span>Error: ${e.message}</span></div>`,n.scrollTop=n.scrollHeight)}},oe=(e,t)=>{let n=-1,r=``,i=()=>{j(null,e,t),n=-1,r=``,s()},a=document.getElementById(`run-sql-btn`);a&&(a.onclick=()=>i());let o=document.getElementById(`sql-highlight-layer`),s=()=>{let t=e.value;if(t===``){o&&(o.innerHTML=`<span class="hl-placeholder">SELECT * FROM sqlite_master;</span>`);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(`\\n`)&&(t+=` `),o&&(o.innerHTML=t)};e.addEventListener(`input`,s),e.addEventListener(`scroll`,()=>{o&&(o.scrollTop=e.scrollTop,o.scrollLeft=e.scrollLeft)}),s(),e.addEventListener(`keydown`,t=>{let a=window.AppState.queryHistory||[];t.key===`ArrowUp`?e.selectionStart===0&&e.selectionEnd===0&&n<a.length-1&&(t.preventDefault(),n===-1&&(r=e.value),n++,e.value=a[n],s(),setTimeout(()=>{e.selectionStart=e.value.length,e.selectionEnd=e.value.length},0)):t.key===`ArrowDown`?e.selectionStart===e.value.length&&e.selectionEnd===e.value.length&&n>-1&&(t.preventDefault(),n--,n===-1?e.value=r:e.value=a[n],s(),setTimeout(()=>{e.selectionStart=e.value.length,e.selectionEnd=e.value.length},0)):((t.ctrlKey||t.metaKey)&&t.key===`Enter`||t.key===`Enter`&&!t.shiftKey&&e.value.trim().endsWith(`;`))&&(t.preventDefault(),i())})};function se(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 Console`),n.innerHTML=`
238
+ <div class="sql-console-wrapper">
239
+ <div id="console-history-pane">
240
+ <div id="console-welcome-msg">
241
+ <div id="console-welcome-title">
242
+ <div id="icon-container">
243
+ <span class="material-symbols-outlined" style="font-size: 36px;">database_search</span>
244
+ </div>
245
+ <span>Welcome to Drixio SQL Terminal.</span>
246
+ </div>
247
+ <span id="console-welcome-description">Type your query below and press <b>Ctrl+Enter</b> or end with <b>;</b> and press <b>Enter</b> to execute.</span>
248
+ <span id="console-welcome-hint"><b>Hint:</b> Highlight specific lines to only run the selection.</span>
249
+ </div>
250
+ </div>
251
+ <div id="console-input-pane">
252
+ <div class="sql-editor-wrapper">
253
+ <span class="sql-prompt">sql &gt;</span>
254
+ <div class="sql-editor-layer-container">
255
+ <!-- Syntax Highlight Layer (Background) -->
256
+ <div id="sql-highlight-layer" class="sql-editor"></div>
257
+ <!-- Real Textarea (Foreground) -->
258
+ <textarea id="sql-editor" class="sql-editor"></textarea>
259
+ </div>
260
+ </div>
261
+ <div style="display: none; justify-content: flex-end; margin-top: 8px;">
262
+ <button id="run-sql-btn" class="primary" style="padding: 6px 16px; border-radius: 6px; border: none; background-color: var(--color-primary); color: #fff; font-weight: 600; cursor: pointer; display: flex; align-items: center; gap: 6px; font-size: 13px; transition: opacity 0.2s;">
263
+ <span class="material-symbols-outlined" style="font-size: 16px;">play_arrow</span> Run (Ctrl+Enter)
264
+ </button>
265
+ </div>
266
+ </div>
267
+ </div>
268
+ `;let i=document.getElementById(`sql-editor`),a=document.getElementById(`console-history-pane`);window.AppState.lastQuery&&(i.value=window.AppState.lastQuery),i.focus(),oe(i,a)}var M={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)}},N=`modulepreload`,ce=function(e,t){return new URL(e,t).href},P={},le=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=ce(t,n),t=s(t),t in P)return;P[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`:N,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)})};async function ue(){let e=await o();if(!e||!e.success||!e.data)return[];let t=e.data,n=[],r=t.map(async e=>{let t=await u(e);t&&t.success&&n.push({table:e,columns:t.data})});return await Promise.all(r),n}function F(){try{let e=localStorage.getItem(`drixio-erd-positions`);return e?JSON.parse(e):{}}catch{return{}}}function I(e){localStorage.setItem(`drixio-erd-positions`,JSON.stringify(e))}async function de(e){let{runQuery:t}=await le(async()=>{let{runQuery:e}=await Promise.resolve().then(()=>a);return{runQuery:e}},void 0,import.meta.url),n=[];if(e.forEach(e=>{if(e.isDraft){let t=e.columns.map(e=>{let t=`${e.name} ${e.type}`;return e.isPk&&(e.type.toUpperCase()===`INTEGER`?t+=` PRIMARY KEY AUTOINCREMENT`:t+=` PRIMARY KEY`),!e.nullable&&!e.isPk&&(t+=` NOT NULL DEFAULT ''`),e.fkTarget&&(t+=` REFERENCES ${e.fkTarget.table}(${e.fkTarget.column})`),t}).join(`, `);n.push(`CREATE TABLE ${e.table} (${t});`)}else e.columns.forEach(t=>{if(t.isDraft){let r=`ALTER TABLE ${e.table} ADD COLUMN ${t.name} ${t.type}`;t.fkTarget&&(r+=` REFERENCES ${t.fkTarget.table}(${t.fkTarget.column})`),n.push(r+`;`)}})}),n.length===0)return!0;try{for(let e of n){let n=await t(e);if(!n.success)throw Error(n.error||`Query failed`)}return!0}catch(e){return window.showToast(`Failed to save: `+e.message,`error`),!1}}function fe(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=F()||{};return Object.keys(a).forEach(e=>{let t=parseInt(e);a[e].forEach((e,n)=>{o[e]={x:50+t*350,y:50+n*250}})}),I(o),o}var L=null;function R(){L||(L=document.createElement(`div`),L.className=`drixio-context-menu`,document.body.appendChild(L),document.addEventListener(`click`,e=>{L.classList.contains(`visible`)&&!L.contains(e.target)&&B()}),window.addEventListener(`scroll`,e=>{L.classList.contains(`visible`)&&(L.contains(e.target)||B())},!0))}function z(e,t){e.preventDefault&&e.preventDefault(),e.stopPropagation&&e.stopPropagation(),R(),L.innerHTML=``,t.forEach(e=>{if(e.type===`divider`||e===`divider`){let e=document.createElement(`div`);e.className=`drixio-context-menu-divider`,L.appendChild(e);return}let t=document.createElement(`div`);t.className=`drixio-context-menu-item`,e.danger&&t.classList.add(`danger`),t.innerHTML=`
269
+ ${e.icon?`<span class="material-symbols-outlined">${e.icon}</span>`:``}
270
+ <span class="drixio-menu-label">${e.label}</span>
271
+ ${e.shortcut?`<span class="drixio-menu-shortcut">${e.shortcut}</span>`:``}
272
+ `,t.addEventListener(`click`,t=>{t.stopPropagation(),B(),e.action&&e.action()}),L.appendChild(t)}),L.style.visibility=`hidden`,L.classList.add(`visible`),requestAnimationFrame(()=>{let t=L.getBoundingClientRect(),n=e.clientX,r=e.clientY;n+t.width>window.innerWidth&&(n=window.innerWidth-t.width-8),r+t.height>window.innerHeight&&(r=window.innerHeight-t.height-8),L.style.left=`${n}px`,L.style.top=`${r}px`,L.style.visibility=`visible`})}function B(){L&&L.classList.remove(`visible`)}function V(){if(M.selectedTables.size===0)return;let e=[];M.selectedTables.forEach(t=>{let n=M.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)}}),M.clipboard=e,window.showToast(`Copied ${e.length} table(s)`,`success`)}function H(){M.selectedTables.size!==0&&(M.pushUndoState(),M.erdData.forEach(e=>{e.columns.forEach(e=>{e.fkTarget&&M.selectedTables.has(e.fkTarget.table)&&delete e.fkTarget})}),M.erdData=M.erdData.filter(e=>!M.selectedTables.has(e.table)),M.clearSelection(),Y(),window.showToast(`Deleted selected table(s)`,`success`))}function U(){if(!M.clipboard||M.clipboard.length===0)return;M.pushUndoState(),M.clearSelection();let e=F();M.clipboard.forEach((t,n)=>{let r=JSON.parse(JSON.stringify(t)),i=`_copy`,a=r.table+i,o=1;for(;M.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},M.erdData.push(r),M.selectedTables.add(a)}),I(e),Y(),window.showToast(`Pasted ${M.clipboard.length} table(s)`,`success`)}function pe(){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 de(M.erdData)&&(window.showToast(`ERD Schema saved successfully!`,`success`),Q(document.getElementById(`main-content`)))),(e.ctrlKey||e.metaKey)&&e.key===`z`&&(e.preventDefault(),M.undo()?(Y(),window.showToast(`Undid last action`,`success`)):window.showToast(`Nothing to undo`,`info`)),e.ctrlKey&&e.key===`c`&&(e.preventDefault(),V()),e.ctrlKey&&e.key===`v`&&(e.preventDefault(),U()),e.key===`Delete`&&(e.preventDefault(),H()))})}function me(){let e=document.getElementById(`erd-workspace`);document.querySelectorAll(`.erd-node`).forEach(t=>{let n=M.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(!M.selectedTables.has(n.table))!r.ctrlKey&&!r.metaKey&&M.clearSelection(),M.selectedTables.add(n.table),document.querySelectorAll(`.erd-node`).forEach(e=>{M.selectedTables.has(e.dataset.table)?e.classList.add(`is-selected`):e.classList.remove(`is-selected`)});else if(r.ctrlKey||r.metaKey){M.selectedTables.delete(n.table),t.classList.remove(`is-selected`);return}M.draggingNode=t;let i=e.getBoundingClientRect();M.dragStartMouse={x:r.clientX,y:r.clientY},M.draggedNodesStart=[],M.selectedTables.forEach(e=>{let t=document.querySelector(`.erd-node[data-table="${e}"]`);if(t){let e=t.getBoundingClientRect();M.draggedNodesStart.push({node:t,startX:(e.left-i.left)/M.zoom,startY:(e.top-i.top)/M.zoom}),t.style.zIndex=`10`}}),document.body.style.cursor=`grabbing`}),t.addEventListener(`contextmenu`,e=>{e.preventDefault(),e.stopPropagation(),M.selectedTables.has(n.table)||(M.setSelection(n.table),document.querySelectorAll(`.erd-node`).forEach(e=>{M.selectedTables.has(e.dataset.table)?e.classList.add(`is-selected`):e.classList.remove(`is-selected`)})),z(e,[{label:`Copy`,icon:`content_copy`,action:V},{label:`Cut`,icon:`content_cut`,action:()=>{V(),H()}},`divider`,{label:`Delete`,icon:`delete`,danger:!0,action:H}])}),t.querySelector(`.erd-add-col-btn`).addEventListener(`click`,()=>{M.pushUndoState(),n.columns.push({name:`new_col_${n.columns.length}`,type:`TEXT`,isDraft:!0,nullable:!0}),Y()}),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){M.pushUndoState(),n.table=t;let r=F();r[e]&&(r[t]=r[e],delete r[e],I(r)),M.erdData.forEach(n=>{n.columns.forEach(n=>{n.fkTarget&&n.fkTarget.table===e&&(n.fkTarget.table=t)})}),M.selectedTables.has(e)&&(M.selectedTables.delete(e),M.selectedTables.add(t))}Y()}),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(),z(e,[{label:`Delete Column`,icon:`delete`,danger:!0,action:()=>{M.pushUndoState(),M.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),Y()}}]))}),!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,a;if(r===`type`){a=document.createElement(`select`),a.className=`erd-inline-input`;let e=[`INTEGER`,`TEXT`,`REAL`,`BLOB`,`BOOLEAN`,`DATE`,`DATETIME`];if(e.forEach(e=>{let t=document.createElement(`option`);t.value=e,t.textContent=e,i.type.toUpperCase()===e&&(t.selected=!0),a.appendChild(t)}),!e.includes(i.type.toUpperCase())){let e=document.createElement(`option`);e.value=i.type,e.textContent=i.type,e.selected=!0,a.appendChild(e)}a.addEventListener(`change`,()=>{a.blur()})}else 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(`!`)){Y();return}M.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&&M.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,Y()}),a.addEventListener(`keydown`,e=>{e.key===`Enter`&&a.blur()})})});let a=t.querySelector(`.erd-drag-handle`);a&&a.addEventListener(`mousedown`,t=>{t.stopPropagation(),M.drawingFkStartCol={table:n.table,col:i.name,colIndex:r};let o=a.getBoundingClientRect(),s=e.getBoundingClientRect();M.drawingFkStartCoords={x:(o.right-s.left)/M.zoom,y:(o.top+o.height/2-s.top)/M.zoom}})}),t.querySelectorAll(`.erd-reorder-handle`).forEach(e=>{e.addEventListener(`dragstart`,t=>{let r=e.closest(`.erd-column`);M.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=>{!M.draggingColInfo||M.draggingColInfo.table!==n.table||(e.preventDefault(),e.dataTransfer.dropEffect=`move`)}),e.addEventListener(`drop`,t=>{if(t.preventDefault(),!M.draggingColInfo||M.draggingColInfo.table!==n.table)return;let r=M.draggingColInfo.colIndex,i=parseInt(e.dataset.index);if(r!==i){M.pushUndoState();let[e]=n.columns.splice(r,1);n.columns.splice(i,0,e),Y()}M.draggingColInfo=null})})})}var W=!1;function he(){W||(W=!0,document.addEventListener(`mousemove`,e=>{if(M.drawingFkStartCol){let t=document.getElementById(`erd-workspace`);if(!t)return;let n=t.getBoundingClientRect(),r=(e.clientX-n.left)/M.zoom,i=(e.clientY-n.top)/M.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 ${M.drawingFkStartCoords.x} ${M.drawingFkStartCoords.y} L ${r} ${i}`);return}if(!M.draggingNode)return;let t=(e.clientX-M.dragStartMouse.x)/M.zoom,n=(e.clientY-M.dragStartMouse.y)/M.zoom;M.draggedNodesStart.forEach(e=>{let r=e.startX+t,i=e.startY+n;r<0&&(r=0),i<0&&(i=0),M.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`}),X()}),document.addEventListener(`mouseup`,e=>{if(M.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!==M.drawingFkStartCol.table){let t=M.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)`);M.pushUndoState();let r=M.erdData.find(e=>e.table===M.drawingFkStartCol.table),i=r.columns[M.drawingFkStartCol.colIndex];i.fkTarget={table:e,column:t.name},i.nullable=n,r.columns.splice(M.drawingFkStartCol.colIndex,1),r.columns.push(i),Y()}else window.showToast(`Target table has no Primary Key!`,`error`)}}else{let e=M.erdData.find(e=>e.table===M.drawingFkStartCol.table).columns[M.drawingFkStartCol.colIndex];e.fkTarget&&(M.pushUndoState(),delete e.fkTarget,Y())}let r=document.getElementById(`erd-temp-path`);r&&r.remove(),M.drawingFkStartCol=null}if(M.draggingNode){document.body.style.cursor=``;let e=F();M.draggedNodesStart.forEach(t=>{t.node.style.zIndex=``,e[t.node.dataset.table]={x:parseFloat(t.node.style.left),y:parseFloat(t.node.style.top)}}),I(e),Z(),M.draggingNode=null,M.draggedNodesStart=[]}}))}var G=!1,K={x:0,y:0},q=null;function ge(e){e.addEventListener(`scroll`,()=>{Z()}),e.addEventListener(`mousedown`,t=>{t.button===1||t.button===0&&t.altKey?(t.preventDefault(),M.isPanning=!0,M.panStart.x=t.clientX,M.panStart.y=t.clientY,M.scrollStart.left=e.scrollLeft,M.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`)&&(G=!0,K={x:t.clientX,y:t.clientY},!t.ctrlKey&&!t.metaKey&&(M.clearSelection(),Y()),q=document.createElement(`div`),q.style.position=`fixed`,q.style.border=`1px solid #3b82f6`,q.style.backgroundColor=`rgba(59, 130, 246, 0.1)`,q.style.zIndex=`1000`,q.style.pointerEvents=`none`,document.body.appendChild(q))});let t=()=>{let e=document.getElementById(`btn-erd-zoom-reset`);e&&(e.textContent=Math.round(M.zoom*100)+`%`)},n=e=>{M.zoom=Math.max(.2,Math.min(e,3));let n=document.getElementById(`erd-workspace`);n&&(n.style.transform=`scale(${M.zoom})`,X(),Z(),t())},r=document.getElementById(`btn-erd-zoom-in`);r&&r.addEventListener(`click`,()=>n(M.zoom+.1));let i=document.getElementById(`btn-erd-zoom-out`);i&&i.addEventListener(`click`,()=>n(M.zoom-.1));let a=document.getElementById(`btn-erd-zoom-reset`);a&&a.addEventListener(`click`,()=>n(1)),e.addEventListener(`wheel`,e=>{(e.ctrlKey||e.metaKey)&&(e.preventDefault(),n(M.zoom-e.deltaY*.001))},{passive:!1}),document.addEventListener(`mousemove`,t=>{if(G&&q){let e=Math.min(t.clientX,K.x),n=Math.min(t.clientY,K.y),r=Math.abs(t.clientX-K.x),i=Math.abs(t.clientY-K.y);q.style.left=e+`px`,q.style.top=n+`px`,q.style.width=r+`px`,q.style.height=i+`px`;return}if(M.isPanning){if(e){let n=t.clientX-M.panStart.x,r=t.clientY-M.panStart.y;e.scrollLeft=M.scrollStart.left-n,e.scrollTop=M.scrollStart.top-r}return}}),document.addEventListener(`mouseup`,e=>{if(G&&(G=!1,q)){let e=q.getBoundingClientRect();q.remove(),q=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||(M.selectedTables.add(t.dataset.table),n=!0)}),n&&Y()}M.isPanning&&(M.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(),z(e,[{label:`Add Table`,icon:`add_box`,action:()=>{let e=document.getElementById(`btn-add-table`);e&&e.click()}},`divider`,{label:`Auto Layout`,icon:`account_tree`,action:()=>{M.pushUndoState(),fe(M.erdData),Y(),window.showToast(`Auto Layout Applied`,`success`)}}]))});let o=document.getElementById(`erd-search-input`),s=document.getElementById(`erd-search-results`);o&&s&&(o.addEventListener(`input`,t=>{let n=t.target.value.toLowerCase();if(s.innerHTML=``,!n){s.style.display=`none`;return}let r=M.erdData.filter(e=>e.table.toLowerCase().includes(n));if(r.length===0){s.innerHTML=`<div class="erd-search-item" style="color: var(--color-text-soft);">No results</div>`,s.style.display=`block`;return}r.forEach(t=>{let n=document.createElement(`div`);n.className=`erd-search-item`,n.textContent=t.table,n.onclick=()=>{M.setSelection(t.table);let n=document.querySelector(`.erd-node[data-table="${t.table}"]`);if(n){let t=n.getBoundingClientRect(),r=e.getBoundingClientRect(),i=parseFloat(n.style.left),a=parseFloat(n.style.top);e.scrollLeft=i*M.zoom-r.width/2+t.width/2,e.scrollTop=a*M.zoom-r.height/2+t.height/2}Y(),s.style.display=`none`,o.value=``},s.appendChild(n)}),s.style.display=`block`}),document.addEventListener(`click`,e=>{!o.contains(e.target)&&!s.contains(e.target)&&(s.style.display=`none`)}))}function _e(e){let t=document.getElementById(`erd-minimap`);if(!t)return;let n=!1;t.addEventListener(`mousedown`,r=>{if(r.stopPropagation(),r.button!==0)return;n=!0;let i=t.getBoundingClientRect(),a=.0325,o=t=>{let n=t.clientX-i.left,r=t.clientY-i.top,o=(n-25)/a,s=(r-0)/a,c=e.clientWidth/M.zoom,l=e.clientHeight/M.zoom;e.scrollLeft=(o-c/2)*M.zoom,e.scrollTop=(s-l/2)*M.zoom};o(r);let s=e=>{n&&o(e)},c=()=>{n=!1,document.removeEventListener(`mousemove`,s),document.removeEventListener(`mouseup`,c)};document.addEventListener(`mousemove`,s),document.addEventListener(`mouseup`,c)})}var J=!1;function ve(){if(J)return;let e=document.getElementById(`erd-wrapper`);e&&(ge(e),_e(e),pe(),he(),J=!0)}function Y(){let e=document.getElementById(`erd-nodes-layer`);if(!e)return;if(e.innerHTML=``,!M.erdData||M.erdData.length===0){e.innerHTML=`
273
+ <div style="padding: 24px; color: var(--color-text-soft);">No tables found. Right click to add one.</div>
274
+ `;return}let t=F(),n=50,r=50,i=0;M.erdData.forEach(a=>{let o,s;t[a.table]?(o=t[a.table].x,s=t[a.table].y):(o=n,s=r,n+=320,n>1200&&(n=50,r+=i+50,i=0));let c=ye(a,o,s);M.selectedTables.has(a.table)&&c.classList.add(`is-selected`),e.appendChild(c);let l=40+a.columns.length*40+40;l>i&&(i=l)}),me(),setTimeout(()=>{X(),Z()},10)}function ye(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.map((t,n)=>{let r=`web_asset`,i=`var(--color-text-soft)`;t.isPk?(r=`key`,i=`#f59e0b`):t.fkTarget&&(r=`link`,i=`#3b82f6`);let a=t.fkTarget?`is-fk`:``,o=t.isDraft?`is-draft`:``,s=t.type.toUpperCase();return`
275
+ <div class="erd-column ${a} ${o}" data-col="${t.name}" data-index="${n}">
276
+ <div class="erd-col-left" style="flex: 1; display: flex; align-items: center; gap: 8px;">
277
+ <span class="material-symbols-outlined erd-reorder-handle" draggable="true" style="font-size: 16px; color: ${i}; cursor: grab;">${r}</span>
278
+ <span class="erd-col-name editable-field" data-field="name">${t.name}${t.nullable?` ?`:``}</span>
279
+ </div>
280
+ <div class="erd-col-right" style="display: flex; align-items: center; gap: 6px;">
281
+ <span class="erd-col-type editable-field" data-field="type">${s}</span>
282
+ ${(t.isDraft||e.isDraft)&&!t.isPk?`<div class="erd-drag-handle" title="Drag to create Foreign Key"></div>`:``}
283
+ </div>
284
+ </div>
285
+ `}).join(``);return r.innerHTML=`
286
+ <div class="erd-node-header" title="${e.isDraft?`Double click to rename`:``}">
287
+ <span class="material-symbols-outlined" style="font-size: 16px;">table_chart</span>
288
+ <span style="font-weight: 600;" class="erd-node-name">${e.table}</span>
289
+ </div>
290
+ <div class="erd-node-body">
291
+ ${i}
292
+ </div>
293
+ <div class="erd-add-col-btn">
294
+ <span class="material-symbols-outlined" style="font-size: 16px;">add</span> Add Column
295
+ </div>
296
+ `,r}function X(){let e=document.getElementById(`erd-svg-layer`);if(!e)return;let t=``;M.erdData.forEach(e=>{let n=e.table,r=document.querySelector(`.erd-node[data-table="${n}"]`);r&&e.columns.forEach(e=>{if(e.fkTarget){let n=e.fkTarget.table,i=e.fkTarget.column,a=document.querySelector(`.erd-node[data-table="${n}"]`);if(!a)return;let o=r.querySelector(`.erd-column[data-col="${e.name}"]`),s=a.querySelector(`.erd-column[data-col="${i}"]`);if(!o||!s)return;let c=o.getBoundingClientRect(),l=s.getBoundingClientRect(),u=document.getElementById(`erd-workspace`).getBoundingClientRect(),d,f,p,m;c.right<l.left+20?(d=(c.right-u.left)/M.zoom,p=(l.left-u.left)/M.zoom):(d=(c.left-u.left)/M.zoom,p=(l.right-u.left)/M.zoom),f=(c.top+c.height/2-u.top)/M.zoom,m=(l.top+l.height/2-u.top)/M.zoom;let h=Math.abs(p-d),g=Math.max(h*.5,50),_=d<p?d+g:d-g,v=f,y=d<p?p-g:p+g,b=m,x=e.nullable?`url(#zero-or-one)`:`url(#one-and-only-one)`;t+=`
297
+ <path
298
+ d="M ${d} ${f} C ${_} ${v}, ${y} ${b}, ${p} ${m}"
299
+ fill="none"
300
+ stroke="var(--color-text)"
301
+ stroke-width="1.5"
302
+ opacity="0.8"
303
+ marker-start="url(#crows-foot-zero-many)"
304
+ marker-end="${x}"
305
+ />
306
+ `}})}),e.innerHTML=`
307
+ <defs>
308
+ <!-- FK side: Zero or Many (0<) -->
309
+ <marker id="crows-foot-zero-many" viewBox="0 0 16 10" refX="16" refY="5" markerWidth="10" markerHeight="10" orient="auto-start-reverse">
310
+ <path d="M 16 0 L 8 5 M 16 10 L 8 5 M 16 5 L 8 5 M 4 5 L 0 5" fill="none" stroke="var(--color-text)" stroke-width="1.5" opacity="0.9" />
311
+ <circle cx="5" cy="5" r="3" fill="var(--color-bg-primary)" stroke="var(--color-text)" stroke-width="1.5" opacity="0.9" />
312
+ </marker>
313
+
314
+ <!-- PK side: One and Only One (||) -->
315
+ <marker id="one-and-only-one" viewBox="0 0 16 10" refX="13" refY="5" markerWidth="10" markerHeight="10" orient="auto">
316
+ <path d="M 10 0 L 10 10 M 6 0 L 6 10" fill="none" stroke="var(--color-text)" stroke-width="1.5" opacity="0.9" />
317
+ </marker>
318
+
319
+ <!-- PK side: Zero or One (0|) -->
320
+ <marker id="zero-or-one" viewBox="0 0 16 10" refX="13" refY="5" markerWidth="10" markerHeight="10" orient="auto">
321
+ <path d="M 10 0 L 10 10" fill="none" stroke="var(--color-text)" stroke-width="1.5" opacity="0.9" />
322
+ <circle cx="5" cy="5" r="3" fill="var(--color-bg-primary)" stroke="var(--color-text)" stroke-width="1.5" opacity="0.9" />
323
+ </marker>
324
+ </defs>
325
+ ${t}
326
+ `}function Z(){let e=document.getElementById(`erd-minimap-content`);if(!e)return;e.innerHTML=``;let t=F(),n=document.getElementById(`erd-nodes-layer`);if(!n)return;let r=Array.from(n.querySelectorAll(`.erd-node`)),i=.0325;r.forEach(n=>{let r=n.dataset.table,a=t[r]||{x:0,y:0},o=n.getBoundingClientRect(),s=o.width/M.zoom,c=o.height/M.zoom,l=document.createElement(`div`);l.style.position=`absolute`,l.style.left=`${25+a.x*i}px`,l.style.top=`${0+a.y*i}px`,l.style.width=`${s*i}px`,l.style.height=`${c*i}px`,l.style.backgroundColor=`var(--color-primary)`,l.style.opacity=M.selectedTables.has(r)?`1`:`0.5`,l.style.borderRadius=`2px`,e.appendChild(l)});let a=document.getElementById(`erd-minimap-viewport`);if(a){let e=document.getElementById(`erd-wrapper`),t=e.clientWidth/M.zoom,n=e.clientHeight/M.zoom,r=e.scrollLeft/M.zoom,o=e.scrollTop/M.zoom;a.style.left=`${25+r*i}px`,a.style.top=`${0+o*i}px`,a.style.width=`${t*i}px`,a.style.height=`${n*i}px`}}async function Q(e){if(!document.getElementById(`erd-wrapper`)){e.innerHTML=`
327
+ <div id="erd-wrapper" class="erd-grid-bg" style="width: 100%; height: 100%; overflow: auto; background-color: var(--color-bg-secondary); position: relative; user-select: none;">
328
+ <div id="erd-workspace" style="position: relative; width: 4000px; height: 4000px; transform-origin: 0 0;">
329
+ <svg id="erd-svg-layer" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; z-index: 1;"></svg>
330
+ <div id="erd-nodes-layer" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 2;"></div>
331
+ </div>
332
+
333
+ <!-- Minimap & Search Container -->
334
+ <div style="position: fixed; bottom: 24px; right: 24px; display: flex; flex-direction: column; gap: 12px; z-index: 100; pointer-events: none;">
335
+ <!-- Search -->
336
+ <div class="erd-search-container" style="pointer-events: auto;">
337
+ <span class="material-symbols-outlined search-icon">search</span>
338
+ <input type="text" id="erd-search-input" placeholder="Search tables..." autocomplete="off">
339
+ <div id="erd-search-results" class="erd-search-results" style="display: none;"></div>
340
+ </div>
341
+
342
+ <!-- Zoom Controls -->
343
+ <div style="display: flex; gap: 8px; justify-content: flex-end; pointer-events: auto;">
344
+ <button id="btn-erd-zoom-out" class="drixio-btn drixio-btn-secondary" title="Zoom Out" style="padding: 4px; border-radius: 4px; min-width: 32px; height: 32px;"><span class="material-symbols-outlined" style="font-size: 20px;">remove</span></button>
345
+ <button id="btn-erd-zoom-reset" class="drixio-btn drixio-btn-secondary" title="Reset Zoom" style="padding: 4px; border-radius: 4px; min-width: 32px; height: 32px; font-weight: bold; font-size: 13px;">100%</button>
346
+ <button id="btn-erd-zoom-in" class="drixio-btn drixio-btn-secondary" title="Zoom In" style="padding: 4px; border-radius: 4px; min-width: 32px; height: 32px;"><span class="material-symbols-outlined" style="font-size: 20px;">add</span></button>
347
+ </div>
348
+
349
+ <!-- Minimap -->
350
+ <div id="erd-minimap" class="erd-minimap">
351
+ <div id="erd-minimap-content" class="erd-minimap-content"></div>
352
+ <div id="erd-minimap-viewport" class="erd-minimap-viewport"></div>
353
+ </div>
354
+ </div>
355
+ </div>
356
+ `;let t={x:0,y:0};document.getElementById(`erd-wrapper`).addEventListener(`contextmenu`,e=>{if(e.preventDefault(),e.target.closest(`.erd-node`))return;let n=document.getElementById(`erd-workspace`).getBoundingClientRect();t.x=(e.clientX-n.left)/M.zoom,t.y=(e.clientY-n.top)/M.zoom,z(e,[{label:`Add Table`,icon:`table_chart`,action:()=>{let e=`new_table_${Math.floor(Math.random()*1e3)}`,n={table:e,isDraft:!0,columns:[{name:`id`,type:`INTEGER`,isPk:!0,isDraft:!0,nullable:!1}]},r=F();r[e]={x:t.x,y:t.y},I(r),M.pushUndoState(),M.erdData.push(n),Y()}},{label:`Paste`,icon:`content_paste`,action:U}])}),ve()}let t=document.getElementById(`erd-nodes-layer`);t&&(t.innerHTML=`<div style="padding: 24px; color: var(--color-text-soft);">Loading ERD Data...</div>`),M.erdData=await ue()||[],M.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)})}),M.undoStack=[],M.clearSelection(),Y()}var $=()=>{let e=localStorage.getItem(`drixio-theme`),t=window.matchMedia&&window.matchMedia(`(prefers-color-scheme: dark)`).matches;if(e===`dark`||!e&&t){document.documentElement.setAttribute(`data-theme`,`dark`);let e=document.getElementById(`theme-icon`);e&&(e.textContent=`light_mode`)}let n=document.getElementById(`theme-toggle`);n&&n.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),document.getElementById(`theme-icon`).textContent=e?`dark_mode`:`light_mode`})},be=()=>{window.showToast=function(e,t=`success`){let n=document.getElementById(`toast-container`);if(!n)return;let r=document.createElement(`div`);r.className=`toast ${t}`,r.innerHTML=`<span class="material-symbols-outlined">${t===`success`?`check_circle`:`error`}</span> <span>${e}</span>`,n.appendChild(r),setTimeout(()=>{r.parentNode&&r.parentNode.removeChild(r)},3e3)}},xe=()=>{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`);if(!r)return;e.preventDefault();let i=parseInt(r.dataset.rowIdx),a=e=>{let r=[i],a=t?window.DataGrid:window.SchemaGrid;if(a&&a.selection&&a.selection.startRow!==-1){let e=a.selection,t=Math.min(e.startRow,e.endRow),n=Math.max(e.startRow,e.endRow);if(i>=t&&i<=n){r=[];for(let e=t;e<=n;e++)r.push(e)}}t?(window.DataGrid.currentTransaction=[],e===`delete`?r.forEach(e=>y(e)):e===`duplicate`&&(x(r,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`?r.forEach(e=>E(e)):e===`duplicate`&&(re(r,[`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)};z(e,[{label:`Duplicate Row(s)`,icon:`content_copy`,action:()=>a(`duplicate`)},`divider`,{label:`Delete Row(s)`,icon:`delete`,danger:!0,action:()=>a(`delete`)}])}),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)&&!(e.target.tagName===`INPUT`||e.target.tagName===`SELECT`||e.target.tagName===`TEXTAREA`)){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),m(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===`Enter`||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);if(e.key===`Enter`){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 t=new MouseEvent(`dblclick`,{bubbles:!0,cancelable:!0,view:window});e.dispatchEvent(t)}return}if(e.key===`Tab`){let 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,m(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`){if(t)window.DataGrid.currentTransaction=[],document.querySelectorAll(`#data-grid-table-${window.AppState.currentTable} .cell-in-range`).forEach(e=>v(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){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`)&&T(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(` `)+`
357
+ `}navigator.clipboard.writeText(o.trimEnd()),document.querySelectorAll(`.cell-in-range`).forEach(e=>{e.style.backgroundColor=`#bfdbfe`,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++)y(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++)E(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`?b(r.rowIdx,r.pk):v(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`?ne(r.rowIdx,r.pk):T(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&&v(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`)&&T(i,t,e)}),s++}),r.currentTransaction.length>0&&r.history.push(r.currentTransaction),r.currentTransaction=null}})},Se=document.getElementById(`header-container`),Ce=document.getElementById(`sidebar-container`),we=document.getElementById(`tab-container`);Se.innerHTML=n,Ce.innerHTML=r,we.innerHTML=i,window.AppState={currentTable:null,currentTab:`data-btn`,currentTableBtnElement:null,dbType:null},s().then(e=>{e&&e.success&&e.data&&(window.AppState.dbType=e.data.dbType)}),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*\*$/,``);a?(o.textContent=s+` *`,o.style.fontWeight=`bold`):(o.textContent=s,o.style.fontWeight=`normal`)})},window.handleSwitchTab=function(e){document.querySelectorAll(`.tab-btn`).forEach(e=>e.classList.remove(`isCurrentTab`));let t=document.getElementById(e);if(t&&t.classList.add(`isCurrentTab`),window.AppState.currentTab=e,e===`erd-btn`||e===`sql-btn`||e===`status-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`)&&!window.AppState.currentTable){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`))}window.renderCurrentView()},window.renderEmptyState=function(e){e.innerHTML=`
358
+ <div class="empty-state">
359
+ <div class="icon-container">
360
+ <span class="material-symbols-outlined">database</span>
361
+ </div>
362
+ <h2>No Table Selected</h2>
363
+ <p>Select a table from the sidebar to view its data, schema, or run SQL queries.</p>
364
+ </div>
365
+ `},window.renderCurrentView=function(e=``,t=!1){let n=[`erd-btn`,`sql-btn`,`status-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())&&w(o,window.AppState.currentTableBtnElement,e,t,a)):window.AppState.currentTab===`schema-btn`?(window.TableStates[o].schemaGrid&&(window.SchemaGrid=window.TableStates[o].schemaGrid),(!window.TableStates[o].schemaGrid||!a.hasChildNodes())&&O(o,window.AppState.currentTableBtnElement,a)):window.AppState.currentTab===`sql-btn`?a.hasChildNodes()||se(o,window.AppState.currentTableBtnElement,a):window.AppState.currentTab===`erd-btn`?a.hasChildNodes()||Q(a):window.AppState.currentTab===`status-btn`&&(a.hasChildNodes()||(a.innerHTML=`<div style='padding:24px; color: var(--color-text-soft);'>Database Status Dashboard coming soon!</div>`)),document.querySelectorAll(`.table-btn`).forEach(e=>e.classList.remove(`active`)),window.AppState.currentTableBtnElement&&window.AppState.currentTableBtnElement.classList.add(`active`)},window.saveDataGridEdits=_,window.saveSchemaEdits=te,document.addEventListener(`DOMContentLoaded`,()=>{p(),$(),be(),xe()});
@@ -9,15 +9,9 @@
9
9
  />
10
10
 
11
11
  <title>DRIXIO STUDIO</title>
12
- <!-- Ace Editor for SQL Console -->
13
- <script
14
- src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.32.7/ace.js"
15
- integrity="sha512-V127u0iE/681x9Z+S3Xz/2aQeY6k/Q+TtwO046sA4K8E0KqNqP/n139xJqG1oE31g3m8L7u5T1WwH0tOWePjxw=="
16
- crossorigin="anonymous"
17
- referrerpolicy="no-referrer"
18
- ></script>
19
- <script type="module" crossorigin src="./assets/index-DrR5jotT.js"></script>
20
- <link rel="stylesheet" crossorigin href="./assets/index-CCy0fVAv.css">
12
+ <!-- Native Textarea for SQL Console -->
13
+ <script type="module" crossorigin src="./assets/index-DfJyH7Vs.js"></script>
14
+ <link rel="stylesheet" crossorigin href="./assets/index-CpEbodwz.css">
21
15
  </head>
22
16
 
23
17
  <body>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "drixio",
3
- "version": "1.1.4",
3
+ "version": "1.1.5",
4
4
  "description": "A lightweight interactive TUI database client",
5
5
  "bin": {
6
6
  "drixio": "dist/cli.js"
@@ -1 +0,0 @@
1
- @import "https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap";:root{--color-bg-primary:#fff;--color-bg-secondary:#f8fafc;--color-bg-secondary-dark:#f1f5f9;--color-primary:#2c68ec;--color-primary-active:#eff6ff;--color-primary-dark:#285bb8;--color-text:#0f172a;--color-text-soft:#94a3b8;--color-text-secondary:#64748b;--color-border:#e2e8f0;--color-border-soft:#f1f5f9;--ring-primary-2:0 0 0 2px #2c68ec33;--font-inter:"Inter", sans-serif;--color-btn-active-text:var(--color-primary);--color-cell-range-bg:#dbeafe;--color-cell-edited-bg:#fffbeb;--color-cell-edited-text:#b45309;--color-cell-error-bg:#fef2f2;--color-row-deleted-bg:#fee2e2;--color-row-deleted-text:#ef4444;--color-ghost-row-bg:#f8fafc}[data-theme=dark]{--color-bg-primary:#0f172a;--color-bg-secondary:#1e293b;--color-bg-secondary-dark:#334155;--color-primary:#3b82f6;--color-primary-active:#1e3a8a;--color-primary-dark:#60a5fa;--color-text:#f8fafc;--color-text-soft:#64748b;--color-text-secondary:#cbd5e1;--color-border:#334155;--color-border-soft:#1e293b;--ring-primary-2:0 0 0 2px #3b82f633;--color-btn-active-text:#fff;--color-cell-range-bg:#3b82f626;--color-cell-edited-bg:#f59e0b26;--color-cell-edited-text:#fbbf24;--color-cell-error-bg:#ef444426;--color-row-deleted-bg:#ef444426;--color-row-deleted-text:#f87171;--color-ghost-row-bg:var(--color-bg-secondary)}body,html{background-color:var(--color-bg-primary);width:100vw;height:100vh;color:var(--color-text);font-family:var(--font-inter);margin:0;padding:0;display:flex;overflow:hidden}main{flex-direction:column;flex:1;min-width:0;display:flex}aside{border-right:1px var(--color-border) solid;box-sizing:border-box;flex-direction:column;width:256px;height:100vh;display:flex}#sidebar-header{border-bottom:1px var(--color-border-soft) solid;box-sizing:border-box;align-items:center;gap:8px;height:64px;padding:0 16px;display:flex}.table-btn{color:var(--color-text-secondary);cursor:pointer;letter-spacing:.5px;background-color:#0000;border:1px solid #0000;border-radius:8px;outline:none;justify-content:space-between;align-items:center;padding:10px 16px;font-size:12px;font-weight:500;transition:all .2s;display:flex}#sidebar-footer{flex:1;align-items:center;min-width:0;display:flex}aside{border-right:1px var(--color-border) solid;flex-direction:column;width:256px;height:100vh;display:flex}#sidebar-header{border-bottom:1px var(--color-border-soft) solid;align-items:center;gap:8px;height:64px;padding:0 16px;display:flex}#database-icon{color:var(--color-primary);font-size:26px}#brand-title{letter-spacing:.5px;align-items:center;gap:4px;margin:0;padding:0;font-size:16px;font-weight:bolder;line-height:1;display:flex}#brand-subtitle{background-color:var(--color-primary);color:#fff;border-radius:5px;align-items:center;height:100%;padding:4px 6px;font-size:12px;font-weight:600;line-height:1;display:flex}#sidebar-content{flex-direction:column;flex:1;gap:24px;padding:16px;display:flex}#search-bar{background-color:var(--color-bg-secondary);border:1px var(--color-border) solid;border-radius:8px;outline:none;align-items:center;padding:0 4px;transition:all .1s linear;display:flex;overflow:hidden}#search-bar:focus-within{border:1px var(--color-primary) solid;box-shadow:var(--ring-primary-2);background-color:var(--color-bg-primary);transform:scale(1.02)}#search-icon{color:var(--color-text-soft);margin:0 3px 0 6px;font-size:20px;transition:all .1s linear}#search-bar:focus-within #search-icon{color:var(--color-primary);transform:scale(1.15)}#search-input{width:100%;height:34px;color:var(--color-text);background-color:#0000;border:none;outline:none;font-size:12px}#search-input::placeholder{color:var(--color-text-soft)}#table-nav{flex-direction:column;flex:1;gap:6px;display:flex;overflow-y:auto}#table-nav::-webkit-scrollbar{width:4px}#table-nav::-webkit-scrollbar-track{background:0 0}#table-nav::-webkit-scrollbar-thumb{background:var(--color-border);border-radius:4px}#table-nav::-webkit-scrollbar-thumb:hover{background:var(--color-text-soft)}.table-btn{color:var(--color-text-secondary);cursor:pointer;background-color:#0000;border:1px solid #0000;border-radius:8px;outline:none;justify-content:space-between;align-items:center;padding:10px 16px;font-size:12px;font-weight:500;transition:all .2s;display:flex}.table-btn:hover{background-color:var(--color-bg-secondary);color:var(--color-text)}.table-btn:active{transform:scale(.97)}.table-btn.active{background-color:var(--color-primary-active);border:1px var(--color-primary) solid;color:var(--color-btn-active-text);font-weight:600}.table-btn-badge{background-color:var(--color-bg-secondary-dark);color:var(--color-text-secondary);border-radius:10px;justify-content:center;align-items:center;min-width:16px;min-height:16px;padding:1px;font-size:8px;font-weight:600;line-height:1;display:flex}.table-btn.active .table-btn-badge{background-color:var(--color-primary);color:#fff}#not-found-msg{color:var(--color-text-soft);flex:1;justify-content:center;align-items:center;font-size:12px;font-weight:400;display:flex}#sidebar-footer{border-top:1px var(--color-border-soft) solid;justify-content:center;align-items:center;max-height:fit-content;margin-top:auto;padding:16px;display:flex}#theme-toggle{background-color:var(--color-bg-secondary);color:var(--color-text-secondary);border:1px var(--color-border) solid;cursor:pointer;border-radius:8px;outline:none;justify-content:center;align-items:center;gap:8px;width:100%;padding:12px 24px;font-weight:600;transition:all .1s linear;display:flex}#theme-toggle:hover{color:var(--color-primary);border-color:var(--color-primary);background-color:var(--color-bg-primary)}header{border-bottom:1px var(--color-border) solid;box-sizing:border-box;justify-content:space-between;align-items:center;width:100%;height:64px;padding:0 32px;font-size:14px;font-weight:300;display:flex;position:sticky;top:0}#current-path{text-transform:lowercase;align-items:center;gap:10px;display:flex}#db-name{color:var(--color-text-secondary)}#slash{color:var(--color-text-soft);font-size:18px;font-weight:lighter}#current-table{align-items:center;gap:4px;display:flex}#table-icon{color:var(--color-primary);font-size:20px}#table-name{color:var(--color-text);font-weight:600}#tab-nav{border-bottom:1px var(--color-border) solid;gap:24px;height:48px;padding:0 32px;display:flex}.tab-btn{height:100%;color:var(--color-text-secondary);cursor:pointer;background-color:#0000;border:none;border-bottom:2px solid #0000;outline:none;align-items:center;gap:8px;padding:0 6px;font-size:12px;font-weight:300;line-height:1;transition:all .1s linear;display:flex}.tab-btn:hover{border-bottom:2px var(--color-border) solid;color:var(--color-text)}.tab-btn.isCurrentTab{border-bottom:2px var(--color-primary) solid;color:var(--color-primary)}.tab-btn .material-symbols-outlined{font-size:16px}#main-content{background-color:var(--color-bg-primary);flex-direction:column;flex:1;min-width:0;display:flex;overflow:hidden}.toolbar{border-bottom:1px var(--color-border) solid;background-color:var(--color-bg-secondary);flex-shrink:0;align-items:center;height:48px;display:flex}.filter-group{flex:1;align-items:center;height:100%;transition:all .15s;display:flex;overflow:hidden}.filter-icon-container{background-color:var(--color-bg-secondary);border-right:1px var(--color-border) solid;align-items:center;gap:6px;height:100%;padding:0 16px;font-size:16px;display:flex}.filter-icon-container .material-symbols-outlined{color:var(--color-text-secondary);font-size:18px}.filter-icon-container span:not(.material-symbols-outlined){text-transform:uppercase;color:var(--color-text-secondary);font-size:13px;font-weight:500}.filter-select{height:100%;color:var(--color-text-secondary);border:none;border-right:1px var(--color-border) solid;cursor:pointer;background-color:#0000;outline:none;padding:0 16px;font-size:13px;font-weight:500}.filter-select:hover{background-color:var(--color-bg-secondary)}.filter-input{height:100%;color:var(--color-text);background:0 0;border:none;outline:none;flex:1;padding:0 20px;font-size:13px;font-weight:200}.filter-input::placeholder{color:var(--color-text-soft)}#btn-run-query{background-color:var(--color-primary);color:#fff;border:none;border-right:1px var(--color-border) solid;cursor:pointer;border-radius:8px;outline:none;justify-content:center;align-items:center;gap:8px;padding:8px 12px;font-size:10px;font-weight:700;transition:all .1s linear;display:flex}#btn-run-query:hover{background-color:var(--color-primary-dark)}#btn-run-query .material-symbols-outlined{margin-bottom:.5px;font-size:16px}#btn-clear-query{background-color:var(--color-bg-primary);color:var(--color-text-secondary);border:none;border:1px var(--color-border) solid;cursor:pointer;border-radius:8px;outline:none;justify-content:center;align-items:center;gap:8px;margin-left:16px;padding:8px 12px;font-size:10px;font-weight:700;transition:all .1s linear;display:flex}#btn-clear-query:hover{background-color:var(--color-bg-secondary-dark);color:var(--color-text)}#btn-run-query:active,#btn-clear-query:active,.btn-primary:active,.btn-secondary:active,.table-btn:active{transform:scale(.96)}#btn-clear-query .material-symbols-outlined{margin-bottom:.5px;font-size:16px}.refresh-btn{background-color:var(--color-bg-secondary);border:1px var(--color-border) solid;color:var(--color-text-secondary);cursor:pointer;border-radius:8px;outline:none;justify-content:center;align-items:center;gap:8px;margin:16px;padding:6px;font-size:10px;font-weight:700;transition:all .1s linear;display:flex}.refresh-btn:hover{background-color:var(--color-bg-secondary-dark);color:var(--color-text)}.refresh-btn .material-symbols-outlined{margin-bottom:.5px;font-size:18px}.sql-console-wrapper{flex-direction:column;height:100%;display:flex}.sql-editor{resize:vertical;border:none;border-bottom:1px var(--color-border) solid;background-color:var(--color-bg-primary);width:100%;height:200px;min-height:100px;color:var(--color-text);outline:none;padding:16px;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:13px}.sql-editor:focus{background-color:#fcfcfc}.table-container{background-color:var(--color-bg-primary);scrollbar-width:none;-ms-overflow-style:none;flex:1;width:100%;min-width:0;overflow:auto}.table-container::-webkit-scrollbar{display:none}.data-table{border-collapse:separate;border-spacing:0;-webkit-user-select:none;user-select:none;width:max-content;min-width:100%}.data-table input,.data-table select{-webkit-user-select:text;user-select:text;box-sizing:border-box}.data-table th,.data-table td{text-align:left;border-bottom:1px var(--color-border-soft) solid;border-right:1px var(--color-border-soft) solid;white-space:nowrap;cursor:cell;height:24px;padding:8px 16px;font-size:13px;position:relative}.data-table th{background-color:var(--color-primary);color:#fff;text-transform:uppercase;letter-spacing:.5px;z-index:10;border-bottom:1px var(--color-border) solid;box-shadow:0 1px 0 var(--color-border);cursor:default;border-right:1px solid #fff3;font-size:11px;font-weight:600;position:sticky;top:0}.data-table td.cell-in-range{background-color:var(--color-cell-range-bg)}.data-table td.cell-in-range:after{content:"";box-sizing:border-box;pointer-events:none;border-top:var(--border-t,0);border-bottom:var(--border-b,0);border-left:var(--border-l,0);border-right:var(--border-r,0);position:absolute;inset:0}.data-table td.range-top{--border-t:2px solid var(--color-primary)}.data-table td.range-bottom{--border-b:2px solid var(--color-primary)}.data-table td.range-left{--border-l:2px solid var(--color-primary)}.data-table td.range-right{--border-r:2px solid var(--color-primary)}.data-table td.cell-selected{background-color:var(--color-bg-primary);z-index:5;box-shadow:inset 0 0 0 2px var(--color-primary)}.data-table td.row-header,.data-table th.row-header{z-index:9;background-color:var(--color-bg-secondary);color:var(--color-text-soft);text-align:center;border-right:1px var(--color-border) solid;width:32px;min-width:32px;padding:8px 4px;font-weight:500;position:sticky;left:0}.data-table th.row-header{z-index:11;background-color:var(--color-primary);color:#fff}.data-table td.cell-edited{background-color:var(--color-cell-edited-bg);color:var(--color-cell-edited-text);font-weight:700}.data-table td.cell-error{background-color:var(--color-cell-error-bg)}.data-table td.cell-error:not(.cell-in-range):not(.cell-selected){box-shadow:inset 0 0 0 2px #ef4444}.data-table tr.row-deleted td{text-decoration:line-through;background-color:var(--color-row-deleted-bg)!important;color:var(--color-row-deleted-text)!important}.data-table td.ghost-row{color:var(--color-text-soft);background-color:var(--color-ghost-row-bg);font-style:italic}.data-table td input,.data-table td select{box-sizing:border-box;width:100%;height:100%;color:var(--color-text);background-color:var(--color-bg-primary);box-shadow:var(--ring-primary-2);border:none;outline:none;padding:0 16px;font-family:inherit;font-size:13px;position:absolute;top:0;left:0}.data-table tbody tr:hover:not(:has(.manage-indexes-cell:hover)){background-color:var(--color-bg-secondary)}.manage-indexes-cell{background-color:var(--color-bg-primary)!important}.manage-indexes-cell:hover{background-color:var(--color-bg-secondary)!important}.context-menu{background-color:var(--color-bg-primary);border:1px var(--color-border) solid;z-index:9999;border-radius:6px;flex-direction:column;min-width:150px;padding:4px;display:flex;position:absolute;box-shadow:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a}.context-menu-item{color:var(--color-text);cursor:pointer;border-radius:4px;align-items:center;gap:8px;padding:8px 12px;font-size:13px;display:flex}.context-menu-item:hover{background-color:var(--color-bg-secondary)}.context-menu-item.danger{color:#ef4444}.context-menu-item.danger:hover{background-color:#fef2f2}.resizer{cursor:col-resize;-webkit-user-select:none;user-select:none;z-index:10;width:8px;height:100%;position:absolute;top:0;right:-4px}.resizer:hover,.resizer:active{background-color:var(--color-primary);opacity:.5}.cell-expand-btn{cursor:pointer;color:var(--color-text-soft);background-color:var(--color-bg-primary);border:1px var(--color-border) solid;z-index:10;border-radius:4px;justify-content:center;align-items:center;padding:3px;font-size:14px;transition:all .1s;display:flex;position:absolute;top:50%;right:6px;transform:translateY(-50%);box-shadow:0 2px 4px #0000000d}.cell-expand-btn:hover{color:var(--color-primary);border-color:var(--color-primary)}#modal-editor-overlay{-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);z-index:9999;background-color:#0f172a66;justify-content:center;align-items:center;width:100vw;height:100vh;display:flex;position:fixed;top:0;left:0}.modal-editor-container{background-color:var(--color-bg-primary);background-color:rgba(var(--color-bg-primary), .85);background:var(--color-bg-primary);border-radius:12px;flex-direction:column;width:600px;max-width:90vw;height:500px;max-height:90vh;display:flex;overflow:hidden;box-shadow:0 10px 25px -5px #0000001a,0 8px 10px -6px #0000001a}.modal-header{border-bottom:1px var(--color-border) solid;color:var(--color-text);align-items:center;gap:8px;padding:16px 20px;display:flex}.modal-header h3{margin:0;font-size:16px;font-weight:600}.modal-header .material-symbols-outlined{color:var(--color-primary)}#modal-textarea{resize:none;color:var(--color-text);background-color:var(--color-bg-secondary-dark);border:none;outline:none;flex:1;padding:20px;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:13px}#modal-textarea:focus{background-color:var(--color-bg-primary)}.modal-footer{border-top:1px var(--color-border) solid;background-color:var(--color-bg-secondary);justify-content:flex-end;gap:12px;padding:16px 20px;display:flex}.modal-footer button{cursor:pointer;border:1px var(--color-border) solid;background-color:var(--color-bg-primary);color:var(--color-text);border-radius:6px;padding:8px 16px;font-size:13px;font-weight:500;transition:all .2s}.modal-footer button:active{transform:scale(.97)}.modal-footer button:hover{background-color:var(--color-bg-secondary-dark)}.modal-footer button.primary{background-color:var(--color-primary);color:#fff;border-color:var(--color-primary)}.modal-footer button.primary:hover{background-color:var(--color-primary-dark)}.empty-state{flex-direction:column;flex:1;justify-content:center;align-items:center;display:flex}.empty-state .icon-container{background-color:var(--color-primary);color:#fff;border-radius:10px;justify-content:center;align-items:center;width:64px;height:64px;display:flex;box-shadow:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a}.empty-state .material-symbols-outlined{font-size:36px}.empty-state h2{color:var(--color-text);margin-top:32px;margin-bottom:10px;font-size:24px;font-weight:700}.empty-state p{color:var(--color-text-secondary);text-align:center;max-width:500px;margin:0;font-size:16px;line-height:1.5}#toast-container{z-index:10000;flex-direction:column;gap:10px;display:flex;position:fixed;bottom:20px;right:20px}.toast{background-color:var(--color-bg-primary);color:var(--color-text);border-left:4px solid var(--color-primary);opacity:0;border-radius:8px;align-items:center;gap:8px;padding:12px 20px;font-size:14px;font-weight:500;animation:.3s ease-out forwards slideIn,.3s ease-in 2.7s forwards fadeOut;display:flex;transform:translate(100%);box-shadow:0 4px 12px #00000026}.toast.error{border-left-color:#ef4444}@keyframes slideIn{0%{opacity:0;transform:translate(100%)}to{opacity:1;transform:translate(0)}}@keyframes fadeOut{0%{opacity:1}to{opacity:0}}#theme-toggle{color:var(--color-text-secondary);cursor:pointer;background:0 0;border:none;border-radius:6px;justify-content:center;align-items:center;padding:6px;transition:all .2s;display:flex}#theme-toggle:hover{background-color:var(--color-bg-secondary);color:var(--color-text)}#theme-toggle:active{transform:scale(.9)}
@@ -1,254 +0,0 @@
1
- var e=Object.defineProperty,t=(t,n)=>{let r={};for(var i in t)e(r,i,{get:t[i],enumerable:!0});return n||e(r,Symbol.toStringTag,{value:`Module`}),r};(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 n=`
2
- <header>
3
- <div id="current-path">
4
- <span id="db-name">database</span>
5
- <span id="slash">/</span>
6
- <div id="current-table">
7
- <span class="material-symbols-outlined" id="table-icon"> table </span>
8
- <span id="table-name">users</span>
9
- </div>
10
- </div>
11
-
12
-
13
- <div class="header-actions">
14
- <button id="export-btn" class="secondary" title="Export Data / DDL" style="display: flex; align-items: center; gap: 6px; padding: 6px 12px; background: transparent; border: 1px solid var(--color-border); border-radius: 6px; cursor: pointer; color: var(--color-text-secondary); font-size: 13px; font-weight: 500;">
15
- <span class="material-symbols-outlined" style="font-size: 18px;">download</span>
16
- Export
17
- </button>
18
- </div>
19
- </header>
20
- `,r=`
21
- <aside>
22
- <div id="sidebar-header">
23
- <span class="material-symbols-outlined" id="database-icon"> database </span>
24
- <h1 id="brand-title">
25
- DRIXIO
26
- <p id="brand-subtitle">STUDIO</p>
27
- </h1>
28
- </div>
29
-
30
- <div id="sidebar-content">
31
- <div id="search-bar">
32
- <span class="material-symbols-outlined" id="search-icon"> search </span>
33
- <input type="text" placeholder="Search" id="search-input" />
34
- </div>
35
-
36
- <nav id="table-nav">
37
- <!-- Display All Table -->
38
- </nav>
39
- </div>
40
-
41
- <div id="sidebar-footer">
42
- <button id="theme-toggle" title="Toggle Dark Mode">
43
- <span class="material-symbols-outlined" id="theme-icon">dark_mode</span>
44
- Theme
45
- </button>
46
- </div>
47
- </aside>
48
- `,i=`
49
- <nav id="tab-nav">
50
- <button
51
- type="button"
52
- class="tab-btn"
53
- onclick="handleSwitchTab('data-btn')"
54
- id="data-btn"
55
- >
56
- <span class="material-symbols-outlined" id="data-icon"> table_rows </span>
57
- Data
58
- </button>
59
- <button
60
- class="tab-btn"
61
- onclick="handleSwitchTab('schema-btn')"
62
- id="schema-btn"
63
- >
64
- <span class="material-symbols-outlined" id="schema-icon">
65
- grid_layout_side
66
- </span>
67
- Schema (Table)
68
- </button>
69
-
70
- <div style="flex: 1;"></div>
71
-
72
- <button class="tab-btn" onclick="handleSwitchTab('status-btn')" id="status-btn">
73
- <span class="material-symbols-outlined" id="status-icon"> database </span>
74
- Database Status
75
- </button>
76
- <button class="tab-btn" onclick="handleSwitchTab('erd-btn')" id="erd-btn">
77
- <span class="material-symbols-outlined" id="erd-icon"> schema </span>
78
- ERD Visualization
79
- </button>
80
- <button class="tab-btn" onclick="handleSwitchTab('sql-btn')" id="sql-btn">
81
- <span class="material-symbols-outlined" id="sql-icon"> code </span>
82
- SQL Console
83
- </button>
84
- </nav>
85
- `,a=t({executeRawQuery:()=>f,fetchConfig:()=>s,fetchTableIndexes:()=>d,fetchTableSchema:()=>u,fetchTableStats:()=>c,fetchTableWithName:()=>l,fetchTables:()=>o});async function o(){return await(await fetch(`/api/tables`)).json()}async function s(){return await(await fetch(`/api/config`)).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/${e}/data?${s.toString()}`;return await(await fetch(c)).json()}async function u(e){return await(await fetch(`/api/tables/${e}/schema`)).json()}async function d(e){return await(await fetch(`/api/tables/${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(){try{let e=await o(),t=document.getElementById(`table-nav`),n=document.getElementById(`not-found-msg`);n&&n.remove(),e.success&&e.data&&e.data.length>0?(e.data.forEach(e=>{let n=document.createElement(`button`);n.type=`button`,n.className=`table-btn`,n.innerHTML=`<span>${e}</span><span class="table-btn-badge" id="badge-${e}" style="display:none;"></span>`,n.onclick=()=>{window.AppState.currentTable=e,window.AppState.currentTableBtnElement=n,window.AppState.currentTab===`erd-btn`||window.AppState.currentTab===`sql-btn`||window.AppState.currentTab===`status-btn`?window.handleSwitchTab(`data-btn`):window.renderCurrentView()},t.appendChild(n)}),window.handleSwitchTab(`data-btn`),c().then(e=>{e.success&&e.data&&Object.entries(e.data).forEach(([e,t])=>{let n=document.getElementById(`badge-${e}`);n&&(n.textContent=Number(t).toLocaleString(),n.style.display=`inline-flex`)})}).catch(e=>console.error(`Failed to load table stats:`,e))):(t.innerHTML=`<div id="not-found-msg">No Tables Found.</div>`,window.handleSwitchTab(`data-btn`))}catch(e){console.error(`Failed to fetch tables:`,e)}}var m=t({bindCellSelection:()=>g,bindColumnResizer:()=>v,renderSelection:()=>h});function h(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.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.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 g(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 e=parseInt(i.dataset.rowIdx);n.selection={isDragging:!1,isDraggingRow:!0,startRow:e,endRow:e,startCol:0,endCol:r-1},h(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);n.selection={isDragging:!0,startRow:o,startCol:s,endRow:o,endCol:s},h(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),h(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),h(t,n))}),e.addEventListener(`mouseup`,()=>{n.selection&&(n.selection.isDragging=!1,n.selection.isDraggingRow=!1)}),e.addEventListener(`contextmenu`,e=>{let r=e.target.closest(`td.row-header`);if(!r)return;let i=parseInt(r.dataset.rowIdx),a=n.selection,o=Math.min(a.startRow,a.endRow),s=Math.max(a.startRow,a.endRow);a.startRow!==-1&&i>=o&&i<=s&&(e.preventDefault(),_(e.pageX,e.pageY,n,t))})}function _(e,t,n,r){let i=document.getElementById(`grid-context-menu`);i||(i=document.createElement(`div`),i.id=`grid-context-menu`,i.className=`context-menu`,document.body.appendChild(i),document.addEventListener(`click`,()=>{i.style.display=`none`}));let a=n.selection,o=Math.min(a.startRow,a.endRow),s=Math.max(a.startRow,a.endRow),c=s-o+1;i.innerHTML=`
86
- <div class="menu-item delete-action">
87
- <span class="material-symbols-outlined">delete</span>
88
- Delete ${c} Row${c>1?`s`:``}
89
- </div>
90
- `,i.style.left=`${e}px`,i.style.top=`${t}px`,i.style.display=`block`,i.querySelector(`.delete-action`).onclick=e=>{e.stopPropagation(),i.style.display=`none`;let t=document.querySelectorAll(`#${r} tbody tr:not(.ghost-row-tr)`);for(let e=o;e<=s;e++){let r=t[e];if(!r)continue;let i=r.querySelector(`td.data-cell`);if(i){let e=i.dataset.pk;e!==`undefined`&&e!=null&&(n.pendingDeletes||=new Set,n.pendingDeletes.add(e),r.classList.add(`row-deleted`))}}let a=document.getElementById(`btn-save-changes`);a&&a.classList.add(`has-changes`)}}function v(e,t){let n=document.createElement(`div`);n.className=`resizer`,e.appendChild(n),n.addEventListener(`click`,e=>e.stopPropagation()),n.addEventListener(`mousedown`,n=>{n.preventDefault(),n.stopPropagation();let r=n.pageX,i=e.offsetWidth,a=!1,o=n=>{a=!0,t&&(t.isResizing=!0);let o=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=``,a&&setTimeout(()=>{t&&(t.isResizing=!1)},100)};document.body.style.cursor=`col-resize`,document.addEventListener(`mousemove`,o),document.addEventListener(`mouseup`,s)})}var y=t({duplicateDataRows:()=>w,markRowDeleted:()=>S,saveDataGridEdits:()=>b,unmarkRowDeleted:()=>C,updateCell:()=>x});async function b(){if(!window.DataGrid)return;let{pendingEdits:e,pendingInserts:t,pkColumn:n}=window.DataGrid,r=window.AppState.currentTable;if(!r||!n){alert(`Cannot save: No Primary Key detected for this table.`);return}let i=[];for(let[t,a]of Object.entries(e)){if(Object.keys(a).length===0)continue;let e=Object.entries(a).map(([e,t])=>t===``?`"${e}" = NULL`:`"${e}" = '${t.replace(/'/g,`''`)}'`).join(`, `);i.push(`UPDATE "${r}" SET ${e} WHERE "${n}" = '${t.replace(/'/g,`''`)}';`)}for(let e=0;e<t.length;e++){let n=t[e];if(Object.keys(n).length===0||!Object.values(n).some(e=>e!==``))continue;let a=Object.keys(n),o=a.map(e=>{let t=n[e];return t===``?`NULL`:`'${t.replace(/'/g,`''`)}'`});i.push(`INSERT INTO "${r}" ("${a.join(`", "`)}") VALUES (${o.join(`, `)});`)}if(window.DataGrid.pendingDeletes)for(let e of window.DataGrid.pendingDeletes)i.push(`DELETE FROM "${r}" WHERE "${n}" = '${e.replace(/'/g,`''`)}';`);if(i.length===0)return;let a=!0,o=``;for(let e of i)try{let t=await f(e);if(!t.success){a=!1,o=t.error;break}}catch(e){a=!1,o=e.message;break}a?(window.renderCurrentView(),window.showToast&&window.showToast(`Data saved successfully!`)):(window.showToast?window.showToast(`Save failed: `+o,`error`):alert(`Save failed:
91
- `+o),document.querySelectorAll(`.cell-edited`).forEach(e=>{e.classList.remove(`cell-edited`),e.classList.add(`cell-error`)})),window.updateSidebarDirtyState?.()}function x(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;if(e.innerHTML=t||(e.dataset.insertIndex===void 0?`<em>null</em>`:`+ New`),e.dataset.insertIndex!==void 0){let r=parseInt(e.dataset.insertIndex);if(window.DataGrid.pendingInserts[r]||(window.DataGrid.pendingInserts[r]={}),t&&(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)=>{i.innerHTML+=`<td class="data-cell ghost-row" data-row-idx="${a}" data-col-idx="${t}" data-insert-index="${r+1}" data-col="${e}">+ New</td>`}),t.appendChild(i)}}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]):(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 S(e,t=!0){let n=document.querySelector(`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.DataGrid.currentTransaction&&window.DataGrid.currentTransaction.push({type:`delete`,rowIdx:e,pk:r}),window.DataGrid.pendingDeletes.add(r),n.classList.add(`row-deleted`)),window.updateSidebarDirtyState?.()}function C(e,t){let n=document.querySelector(`td.data-cell[data-row-idx="${e}"]`)?.closest(`tr`);n&&n.classList.remove(`row-deleted`),window.DataGrid.pendingDeletes.delete(t),window.updateSidebarDirtyState?.()}function w(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`&&x(o,n,t,!0)}})})}var T=`modulepreload`,E=function(e,t){return new URL(e,t).href},D={},O=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=E(t,n),t=s(t),t in D)return;D[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`:T,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)})};function k(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,o=t.find(e=>e.name===i),s=o?.type?.toUpperCase()||``,c=s.includes(`ENUM`),l=s===`DATE`,u=s.includes(`DATETIME`)||s.includes(`TIMESTAMP`),d=s.includes(`BOOL`)||s===`TINYINT(1)`,f=r.textContent===`null`||r.textContent===`+ New`?``:r.textContent,p;if(o&&o.fkTarget){p=document.createElement(`select`);let e=document.createElement(`option`);e.value=f,e.textContent=`Loading...`,p.appendChild(e),O(async()=>{let{executeRawQuery:e}=await Promise.resolve().then(()=>a);return{executeRawQuery:e}},void 0,import.meta.url).then(({executeRawQuery:t})=>{let{table:n,column:r}=o.fkTarget;t(`SELECT * FROM "${n}" LIMIT 100`).then(e=>{if(e.success&&e.data&&e.data.rows){if(p.innerHTML=``,o.nullable){let e=document.createElement(`option`);e.value=``,e.textContent=`-- None --`,p.appendChild(e)}let t=r;if(e.data.columns){let n=[`name`,`title`,`label`,`description`],r=e.data.columns.find(e=>n.includes(e.toLowerCase()));r&&(t=r)}if(e.data.rows.forEach(e=>{let n=String(e[r]),i=t===r?n:`${n} - ${e[t]}`,a=document.createElement(`option`);a.value=n,a.textContent=i,n===f&&(a.selected=!0),p.appendChild(a)}),f&&!e.data.rows.find(e=>String(e[r])===f)){let e=document.createElement(`option`);e.value=f,e.textContent=`${f} (Not in limit)`,e.selected=!0,p.appendChild(e)}}}).catch(t=>{e.textContent=`Error loading options`})})}else if(c){let e=o.type.match(/enum\((.*?)\)/i),t=[];e&&(t=e[1].split(`,`).map(e=>e.trim().replace(/^'|'$/g,``))),p=document.createElement(`select`),t.forEach(e=>{let t=document.createElement(`option`);t.value=e,t.textContent=e,e===f&&(t.selected=!0),p.appendChild(t)})}else if(l)p=document.createElement(`input`),p.type=`date`,p.value=f;else if(u){p=document.createElement(`input`),p.type=`datetime-local`;let e=f.replace(` `,`T`).slice(0,16);p.value=e}else d?(p=document.createElement(`input`),p.type=`checkbox`,p.checked=f===`1`||f.toLowerCase()===`true`):(p=document.createElement(`input`),p.type=`text`,p.value=f);let m=!1,h=()=>{m=!0;let e=document.getElementById(`modal-editor-overlay`),t=document.getElementById(`modal-textarea`),n=document.getElementById(`modal-cancel-btn`),r=document.getElementById(`modal-save-btn`),a=document.getElementById(`modal-title`);a.textContent=`Edit ${i}`,t.value=p.value,e.style.display=`flex`,t.focus();let o=()=>{e.style.display=`none`,r.onclick=null,n.onclick=null,m=!1,p.focus()};n.onclick=o,r.onclick=()=>{p.value=t.value,o(),g()}};if(r.innerHTML=``,r.appendChild(p),s===``||!c&&!l&&!u&&!d&&!(o&&o.fkTarget)){let e=document.createElement(`span`);e.className=`material-symbols-outlined cell-expand-btn`,e.textContent=`open_in_full`,e.onmousedown=e=>e.preventDefault(),e.onclick=()=>h(),r.appendChild(e),p.style.width=`100%`,p.style.paddingRight=`32px`,p.addEventListener(`keydown`,e=>{e.key===`Enter`&&e.shiftKey?(e.preventDefault(),h()):e.key===`Enter`&&p.blur()})}else p.addEventListener(`keydown`,e=>{e.key===`Enter`&&p.blur()});p.focus();let g=()=>{if(m)return;let e=d?p.checked?`1`:`0`:p.value;u&&e&&(e=e.replace(`T`,` `)+`:00`),window.DataGrid.currentTransaction=[],x(r,e,n),window.DataGrid.currentTransaction.length>0&&window.DataGrid.history.push(window.DataGrid.currentTransaction),window.DataGrid.currentTransaction=null};p.addEventListener(`blur`,()=>{setTimeout(()=>{m||g()},100)})})}function A(){let e=window.AppState?.currentTable;if(!e)return``;let t=document.getElementById(`filter-val-${e}`)?.value.trim(),n=document.getElementById(`filter-op-${e}`)?.value,r=document.getElementById(`filter-col-${e}`)?.value,i=``;if(t||n===`IS NULL`){let e=t;e&&!e.startsWith(`'`)&&!e.endsWith(`'`)&&isNaN(Number(e))&&(e.toUpperCase().includes(` AND `)||e.toUpperCase().includes(` OR `)||(e=`'${e.replace(/'/g,`''`)}'`)),i=`"${r}" ${n} ${e}`}return i}function j(e,t,n,r){let i=`<td class="row-header" data-row-idx="${t}">${t+1}</td>`,a=n?e[n]:t;return r.forEach((n,r)=>{let o=e[n]===null?`null`:String(e[n]),s=o.replace(/"/g,`&quot;`),c=o===`null`?`<em>null</em>`:o.replace(/</g,`&lt;`);i+=`<td class="data-cell" data-row-idx="${t}" data-col-idx="${r}" data-pk="${a}" data-col="${n}" data-original="${s}">${c}</td>`}),i}async function M(e,t,n=``,r=!1,i=null){document.querySelectorAll(`.table-btn`).forEach(e=>e.classList.remove(`active`)),t&&t.classList.add(`active`);let a=document.getElementById(`table-name`);a&&(a.textContent=e);let o=i||document.getElementById(`main-content`);r||(o.innerHTML=`<div style='padding:24px;'>Loading...</div>`);try{let i=await u(e);if(!i.success)throw Error(i.error);let a=i.data,s=a.find(e=>e.isPk)?.name;(!r||!window.DataGrid)&&(window.DataGrid={schema:a,pkColumn:s,pendingEdits:{},pendingInserts:[{}],pendingDeletes:new Set,selectedCell:null,history:[],currentTransaction:null,sortState:{col:s||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 c=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(c.success&&c.data){let n=c.data.rows,i=c.data.columns;window.DataGrid.pagination.hasMore=n.length===window.DataGrid.pagination.limit;let u=i.map(e=>`<option value="${e}">${e}</option>`).join(``);r||(o.innerHTML=`
92
- <div class="toolbar">
93
- <div class="filter-group">
94
- <div class="filter-icon-container">
95
- <span class="material-symbols-outlined" id="filter-icon">filter_list</span>
96
- <span>Filter</span>
97
- </div>
98
- <select id="filter-col-${e}" class="filter-select">${u}</select>
99
- <select id="filter-op-${e}" class="filter-select">
100
- <option value="=">=</option>
101
- <option value=">">></option>
102
- <option value="<"><</option>
103
- <option value=">=">>=</option>
104
- <option value="<="><=</option>
105
- <option value="LIKE">LIKE</option>
106
- <option value="!=">!=</option>
107
- </select>
108
- <input type="text" id="filter-val-${e}" class="filter-input" placeholder="Enter value..." />
109
- </div>
110
- <div style="flex:1;"></div>
111
- <button id="btn-refresh-data-${e}" class="refresh-btn" title="Refresh Data (F5)"><span class="material-symbols-outlined">refresh</span></button>
112
- </div>
113
- <div class="table-container" id="data-grid-container-${e}"></div>
114
- `);let d=`<table class="data-table" id="data-grid-table-${e}"><thead><tr>`;d+=`<th class="row-header">#</th>`,i.forEach(e=>{let t=a.find(t=>t.name===e),n=``,r=``;t&&(t.isPk&&(n=` <span style="opacity:0.5; font-size:10px;">(PK)</span>`),t.name.toLowerCase().includes(`id`)&&!t.isPk&&(n=` <span style="opacity:0.5; font-size:10px;">(FK)</span>`),r=`<br><span style="font-weight:normal; opacity:0.7; font-size:10px; font-family:monospace;">${t.type}</span>`);let i=``;window.DataGrid.sortState.col===e&&(i=window.DataGrid.sortState.asc?`▲`:`▼`),d+=`<th class="sortable" data-col="${e}" style="cursor:pointer; user-select:none;">
115
- <div style="display: flex; justify-content: space-between; align-items: center;">
116
- <div>${e}${n}${r}</div>
117
- <div class="sort-arrow" style="font-size:10px; opacity:0.8; margin-left: 8px; width: 12px; text-align: right;">${i}</div>
118
- </div>
119
- </th>`}),d+=`</tr></thead><tbody>`,n&&n.length>0&&n.forEach((e,t)=>{d+=`<tr>${j(e,t,s,i)}</tr>`}),d+=`<tr class="ghost-row-tr">`;let f=n?n.length:0;d+=`<td class="row-header" data-row-idx="${f}">*</td>`,i.forEach((e,t)=>{d+=`<td class="data-cell ghost-row" data-row-idx="${f}" data-col-idx="${t}" data-insert-index="0" data-col="${e}">+ New</td>`}),d+=`</tr></tbody></table>`;let p=document.getElementById(`data-grid-container-${e}`);if(!p)return;if(p.innerHTML=d,document.querySelectorAll(`th.sortable`).forEach(n=>{n.onclick=r=>{if(window.DataGrid&&window.DataGrid.isResizing)return;if(Object.keys(window.DataGrid.pendingEdits).length>0||window.DataGrid.pendingInserts.length>1||window.DataGrid.pendingDeletes.size>0){alert(`You have unsaved changes. Please save changes before sorting.`);return}let i=n.dataset.col;window.DataGrid.sortState.col===i?window.DataGrid.sortState.asc=!window.DataGrid.sortState.asc:(window.DataGrid.sortState.col=i,window.DataGrid.sortState.asc=!0),window.DataGrid.pagination.offset=0,M(e,t,A(),!0)},v(n,window.DataGrid)}),g(p,`data-grid-table-${e}`,window.DataGrid,i.length),k(p,a,i),!r){let n=document.getElementById(`filter-val-${e}`),r=(n=!0)=>{n&&window.DataGrid&&(window.DataGrid.pagination.offset=0),M(e,t,A(),!0)},a;n&&n.addEventListener(`input`,()=>{clearTimeout(a),a=setTimeout(()=>r(!0),400)});let o=document.getElementById(`filter-col-${e}`),c=document.getElementById(`filter-op-${e}`);o&&o.addEventListener(`change`,()=>r(!0)),c&&c.addEventListener(`change`,()=>r(!0));let u=()=>{(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?.(),r(!1))},d=document.getElementById(`btn-refresh-data-${e}`);d&&(d.onclick=u),window.DataGrid.refreshData=u;let f=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:A(),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 a=r.querySelector(`.ghost-row-tr`);a&&r.removeChild(a);let o=window.DataGrid.pagination.offset;if(t.forEach((e,t)=>{let n=document.createElement(`tr`);n.innerHTML=j(e,o+t,s,i),r.appendChild(n)}),a){let e=o+t.length,n=a.querySelector(`.row-header`);n&&(n.dataset.rowIdx=e),a.querySelectorAll(`.ghost-row`).forEach(t=>{t.dataset.rowIdx=e}),r.appendChild(a)}}}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&&f()})},50)}}else o.innerHTML=`<div style="padding:24px; color:red;">Error: ${c.error}</div>`}catch(e){o.innerHTML=`<div style="padding:24px; color:red;">Failed to load data: ${e.message}</div>`}}var N=t({duplicateSchemaRows:()=>R,markSchemaRowDeleted:()=>I,saveSchemaEdits:()=>P,unmarkSchemaRowDeleted:()=>L,updateSchemaCell:()=>F});async function P(){if(!window.SchemaGrid)return;let{pendingEdits:e,pendingInserts:t,pendingDeletes:n}=window.SchemaGrid,r=window.AppState.currentTable;if(!r)return;let i=[];if(n)for(let e of n)i.push(`ALTER TABLE "${r}" DROP COLUMN "${e}";`);for(let[t,n]of Object.entries(e)){let e=t;if(n.name&&n.name!==t&&(i.push(`ALTER TABLE "${r}" RENAME COLUMN "${t}" TO "${n.name}";`),e=n.name),Object.keys(n).filter(e=>e!==`name`).length>0){let a=window.SchemaGrid.schema?.find(e=>e.name===t)||{},o=n.type===void 0?a.type:n.type,s=[],c=n.isPk===void 0?a.isPk:n.isPk,l=String(c).toUpperCase();if((l===`1`||l===`TRUE`||l===`YES`||l.includes(`PK`)||l===`KEY`)&&s.push(`PRIMARY KEY`),l.includes(`FK:`)){let e=l.match(/FK:\s*([^\s,]+)/i);if(e&&e[1]){let t=e[1].split(`.`);t.length===2&&s.push(`REFERENCES "${t[0]}"("${t[1]}")`)}}let u=n.nullable===void 0?a.nullable:n.nullable;(u===`0`||u===`No`||u===!1)&&s.push(`NOT NULL`);let d=n.defaultValue===void 0?a.defaultValue:n.defaultValue;if(d&&s.push(`DEFAULT '${String(d).replace(/'/g,`''`)}'`),window.AppState.dbType===`sqlite`){alert(`SQLite does not support altering column types directly. Please recreate the table or use Raw SQL.`);return}else window.AppState.dbType===`postgres`?(i.push(`ALTER TABLE "${r}" ALTER COLUMN "${e}" TYPE ${o};`),s.includes(`NOT NULL`)&&i.push(`ALTER TABLE "${r}" ALTER COLUMN "${e}" SET NOT NULL;`),d&&i.push(`ALTER TABLE "${r}" ALTER COLUMN "${e}" SET DEFAULT '${String(d).replace(/'/g,`''`)}';`)):i.push(`ALTER TABLE "${r}" MODIFY COLUMN "${e}" ${o} ${s.join(` `)};`)}}for(let e=0;e<t.length;e++){let n=t[e];if(Object.keys(n).length===0||!n.name||n.name.trim()===``)continue;let a=n.name.trim(),o=n.type||`TEXT`,s=[],c=String(n.isPk||``).toUpperCase();if((c===`1`||c===`TRUE`||c===`YES`||c.includes(`PK`)||c===`KEY`)&&s.push(`PRIMARY KEY`),c.includes(`FK:`)){let e=c.match(/FK:\s*([^\s,]+)/i);if(e&&e[1]){let t=e[1].split(`.`);t.length===2&&s.push(`REFERENCES "${t[0]}"("${t[1]}")`)}}(n.nullable===`0`||n.nullable===`false`||n.nullable===`No`)&&s.push(`NOT NULL`),n.defaultValue&&s.push(`DEFAULT '${n.defaultValue.replace(/'/g,`''`)}'`),i.push(`ALTER TABLE "${r}" ADD COLUMN "${a}" ${o} ${s.join(` `)};`)}if(window.SchemaGrid.pendingIndexEdits){for(let e of window.SchemaGrid.pendingIndexEdits.dropped)e&&e.trim()!==``&&i.push(`DROP INDEX "${e}";`);for(let e of window.SchemaGrid.pendingIndexEdits.added){let t=``;t=e.name&&e.name.trim()!==``?`"${e.name}"`:`"idx_${r}_${e.columns.join(`_`)}_${Date.now()}"`;let n=e.isUnique?`UNIQUE`:``,a=e.columns.map(e=>`"${e}"`).join(`, `);i.push(`CREATE ${n} INDEX IF NOT EXISTS ${t} ON "${r}" (${a});`)}}if(i.length===0)return;let a=!0,o=``;for(let e of i)try{let t=await f(e);if(!t.success){a=!1,o=t.error;break}}catch(e){a=!1,o=e.message;break}a?(window.renderCurrentView(),window.showToast&&window.showToast(`Schema saved successfully!`)):(o.includes(`near "MODIFY": syntax error`)?o=`SQLite: Currently does not support modifying existing column types or constraints directly. You can only Rename columns or Add new columns.`:o.includes(`syntax error`)&&(o=`SQLite: `+o),window.showToast?window.showToast(`Save failed: `+o,`error`):alert(`Save failed:
120
- `+o),document.querySelectorAll(`.cell-edited`).forEach(e=>{e.classList.remove(`cell-edited`),e.classList.add(`cell-error`)})),window.updateSidebarDirtyState?.()}function F(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;if(e.innerHTML=t||(e.dataset.insertIndex===void 0?`<span style="color:var(--color-text-soft)">-</span>`:`+ New`),e.dataset.insertIndex!==void 0){let r=parseInt(e.dataset.insertIndex);if(window.SchemaGrid.pendingInserts[r]||(window.SchemaGrid.pendingInserts[r]={}),t&&(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)=>{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}">+ New</td>`}),t.appendChild(i)}}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]):(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 I(e,t=!0){let n=document.querySelector(`#schema-grid-table 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 L(e,t){let n=document.querySelector(`#schema-grid-table td.data-cell[data-row-idx="${e}"]`)?.closest(`tr`);n&&n.classList.remove(`row-deleted`),window.SchemaGrid.pendingDeletes.delete(t),window.updateSidebarDirtyState?.()}function R(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`),F(o,n,t,!0))}})})}function z(){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=o.map(e=>`<option value="${e}">${e}</option>`).join(``);t=document.createElement(`div`),t.id=`index-modal`,t.style.cssText=`
121
- position: fixed; top:0; left:0; width:100vw; height:100vh; background:rgba(0,0,0,0.5);
122
- display:flex; justify-content:center; align-items:center; z-index:9999;
123
- `,t.innerHTML=`
124
- <div style="background:var(--color-bg-primary); width:500px; border-radius:8px; box-shadow:0 4px 12px rgba(0,0,0,0.2); overflow:hidden; display:flex; flex-direction:column;">
125
- <div style="padding:16px; border-bottom:1px solid var(--color-border); display:flex; justify-content:space-between; align-items:center;">
126
- <h3 style="margin:0;">Manage Indexes</h3>
127
- <button id="close-idx-modal" style="background:none; border:none; color:var(--color-text-primary); cursor:pointer;"><span class="material-symbols-outlined">close</span></button>
128
- </div>
129
- <div style="padding:16px; max-height:300px; overflow-y:auto;" id="idx-list-container">
130
- </div>
131
- <div style="padding:16px; border-top:1px solid var(--color-border); background:var(--color-bg-secondary);">
132
- <div style="font-weight:500; margin-bottom:8px;">Add New Index</div>
133
- <div style="display:flex; flex-direction:column; gap:8px;">
134
- <input type="text" id="new-idx-name" placeholder="Index Name (Optional)" style="padding:6px; border-radius:4px; border:1px solid var(--color-border); background:var(--color-bg-primary); color:var(--color-text-primary);" />
135
- <select id="new-idx-cols" multiple style="padding:6px; border-radius:4px; border:1px solid var(--color-border); background:var(--color-bg-primary); color:var(--color-text-primary); height:80px;">
136
- ${s}
137
- </select>
138
- <div style="font-size:12px; color:var(--color-text-soft);">Hold Ctrl/Cmd to select multiple columns</div>
139
- <label style="display:flex; align-items:center; gap:6px; cursor:pointer;">
140
- <input type="checkbox" id="new-idx-unique" /> Unique Index
141
- </label>
142
- <button id="add-idx-btn" class="primary" style="align-self:flex-end; padding:6px 16px; border-radius:4px; border:none; cursor:pointer;">Add</button>
143
- </div>
144
- </div>
145
- <div style="padding:16px; border-top:1px solid var(--color-border); display:flex; justify-content:flex-end; gap:8px;">
146
- <button id="cancel-idx-btn" class="secondary" style="padding:6px 16px; border-radius:4px; border:1px solid var(--color-border); cursor:pointer;">Cancel</button>
147
- <button id="save-idx-btn" class="primary" style="padding:6px 16px; border-radius:4px; border:none; cursor:pointer;">Save Changes</button>
148
- </div>
149
- </div>
150
- `,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=a.map((e,t)=>`
151
- <div class="index-row" style="display:flex; gap:8px; align-items:center; margin-bottom:8px; padding:8px; background:var(--color-bg-primary); border:1px solid var(--color-border); border-radius:4px;">
152
- <div style="flex:1;"><strong>${e.name||`-`}</strong></div>
153
- <div style="flex:2; font-size:12px; color:var(--color-text-secondary);">${e.columns.join(`, `)}</div>
154
- <div style="width:60px; font-size:12px; text-align:center;">${e.isUnique?`UNIQUE`:``}</div>
155
- <button class="icon-btn delete-idx-btn" data-idx="${t}" style="color:var(--color-error); border:none; background:none; cursor:pointer;"><span class="material-symbols-outlined" style="font-size:18px;">delete</span></button>
156
- </div>
157
- `).join(``);a.length===0&&(e=`<div style="padding:16px; text-align:center; color:var(--color-text-secondary);">No indexes yet.</div>`),document.getElementById(`idx-list-container`).innerHTML=e,document.querySelectorAll(`.delete-idx-btn`).forEach(e=>{e.onclick=e=>{let t=parseInt(e.currentTarget.dataset.idx,10);a.splice(t,1),l()}})};l(),document.getElementById(`add-idx-btn`).onclick=()=>{let e=document.getElementById(`new-idx-name`).value.trim(),t=document.getElementById(`new-idx-cols`),n=Array.from(t.selectedOptions).map(e=>e.value),r=document.getElementById(`new-idx-unique`).checked;if(n.length===0){alert(`Please select at least one column for the index.`);return}a.push({name:e,columns:n,isUnique:r}),document.getElementById(`new-idx-name`).value=``,document.getElementById(`new-idx-unique`).checked=!1,t.selectedIndex=-1,l()},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 B(e,t){if(!window.SchemaGrid)return;let n=document.getElementById(`pkfk-modal`);n&&n.remove();let r=e.dataset.insertIndex!==void 0,i=t.includes(`PK`),a=t.includes(`FK`),o=``,s=``;if(a){let e=t.match(/FK \((.*?)\)/);if(e&&e[1]){let t=e[1].split(`.`);t.length===2&&(o=t[0],s=t[1])}else{let e=t.match(/FK:\s*([^\s,]+)/i);if(e&&e[1]){let t=e[1].split(`.`);t.length===2&&(o=t[0],s=t[1])}}}n=document.createElement(`div`),n.id=`pkfk-modal`,n.style.cssText=`
158
- position: fixed; top:0; left:0; width:100vw; height:100vh; background:rgba(0,0,0,0.5);
159
- display:flex; justify-content:center; align-items:center; z-index:9999;
160
- `,n.innerHTML=`
161
- <div style="background:var(--color-bg-primary); width:400px; border-radius:8px; box-shadow:0 4px 12px rgba(0,0,0,0.2); overflow:hidden; display:flex; flex-direction:column;">
162
- <div style="padding:16px; border-bottom:1px solid var(--color-border); display:flex; justify-content:space-between; align-items:center;">
163
- <h3 style="margin:0;">Manage Keys</h3>
164
- <button id="close-pkfk-modal" style="background:none; border:none; color:var(--color-text-primary); cursor:pointer;"><span class="material-symbols-outlined">close</span></button>
165
- </div>
166
- <div style="padding:16px; display:flex; flex-direction:column; gap:16px;">
167
- <label style="display:flex; align-items:center; gap:8px; cursor:pointer;">
168
- <input type="checkbox" id="modal-is-pk" ${i?`checked`:``} />
169
- <strong>Primary Key (PK)</strong>
170
- </label>
171
-
172
- <div style="border-top: 1px solid var(--color-border); margin: 8px 0;"></div>
173
-
174
- <label style="display:flex; align-items:center; gap:8px; cursor:${r?`pointer`:`not-allowed`}; opacity:${r?`1`:`0.6`};">
175
- <input type="checkbox" id="modal-is-fk" ${a?`checked`:``} ${r?``:`disabled`} />
176
- <strong>Foreign Key (FK)</strong>
177
- </label>
178
-
179
- ${r?``:`<div style="font-size:11px; color:var(--color-text-soft); margin-top:-12px; margin-left:24px;">Note: FKs can only be added when creating new columns.</div>`}
180
-
181
- <div id="fk-settings-container" style="display:${a?`flex`:`none`}; flex-direction:column; gap:8px; padding-left: 24px;">
182
- <div>
183
- <div style="font-size:12px; color:var(--color-text-secondary); margin-bottom:4px;">Target Table</div>
184
- <select id="modal-fk-table" style="width:100%; padding:6px; border-radius:4px; border:1px solid var(--color-border); background:var(--color-bg-primary); color:var(--color-text-primary);">
185
- <option value="">Loading tables...</option>
186
- </select>
187
- </div>
188
- <div>
189
- <div style="font-size:12px; color:var(--color-text-secondary); margin-bottom:4px;">Target Column</div>
190
- <select id="modal-fk-col" style="width:100%; padding:6px; border-radius:4px; border:1px solid var(--color-border); background:var(--color-bg-primary); color:var(--color-text-primary);" ${o?``:`disabled`}>
191
- <option value="">Select a table first</option>
192
- </select>
193
- </div>
194
- </div>
195
- </div>
196
- <div style="padding:16px; border-top:1px solid var(--color-border); background:var(--color-bg-secondary); display:flex; justify-content:flex-end; gap:8px;">
197
- <button id="cancel-pkfk-btn" class="secondary" style="padding:6px 16px; border-radius:4px; border:1px solid var(--color-border); cursor:pointer;">Cancel</button>
198
- <button id="save-pkfk-btn" class="primary" style="padding:6px 16px; border-radius:4px; border:none; cursor:pointer;">Save</button>
199
- </div>
200
- </div>
201
- `,document.body.appendChild(n);let c=()=>n.remove();document.getElementById(`close-pkfk-modal`).onclick=c,document.getElementById(`cancel-pkfk-btn`).onclick=c;let l=document.getElementById(`modal-is-fk`),u=document.getElementById(`fk-settings-container`),d=document.getElementById(`modal-fk-table`),f=document.getElementById(`modal-fk-col`);l.addEventListener(`change`,e=>{u.style.display=e.target.checked?`flex`:`none`});try{let e=await(await fetch(`/api/tables`)).json();e.success&&e.data&&(d.innerHTML=`<option value="">-- Select Table --</option>`+e.data.map(e=>`<option value="${e}" ${e===o?`selected`:``}>${e}</option>`).join(``),o&&p(o,s))}catch{d.innerHTML=`<option value="">Error loading tables</option>`}async function p(e,t=``){f.disabled=!0,f.innerHTML=`<option value="">Loading columns...</option>`;try{let n=await(await fetch(`/api/tables/${e}/schema`)).json();n.success&&n.data&&(f.innerHTML=`<option value="">-- Select Column --</option>`+n.data.map(e=>`<option value="${e.name}" ${e.name===t?`selected`:``}>${e.name}</option>`).join(``),f.disabled=!1)}catch{f.innerHTML=`<option value="">Error loading columns</option>`}}d.addEventListener(`change`,e=>{let t=e.target.value;t?p(t):(f.innerHTML=`<option value="">Select a table first</option>`,f.disabled=!0)}),document.getElementById(`save-pkfk-btn`).onclick=()=>{let t=document.getElementById(`modal-is-pk`).checked,n=document.getElementById(`modal-is-fk`).checked,r=d.value,l=f.value;if(t===i&&n===a&&r===o&&l===s){c();return}let u=``;if(t&&n){if(!r||!l){alert(`Please select both Target Table and Target Column for the Foreign Key.`);return}u=`PK, FK: ${r}.${l}`}else if(t)u=`PK`;else if(n){if(!r||!l){alert(`Please select both Target Table and Target Column for the Foreign Key.`);return}u=`FK: ${r}.${l}`}window.SchemaGrid.currentTransaction=[];let p=[`name`,`type`,`isPk`,`nullable`,`defaultValue`,`indexing`];O(async()=>{let{updateSchemaCell:e}=await Promise.resolve().then(()=>N);return{updateSchemaCell:e}},void 0,import.meta.url).then(({updateSchemaCell:t})=>{t(e,u,p),window.SchemaGrid.currentTransaction.length>0&&window.SchemaGrid.history.push(window.SchemaGrid.currentTransaction),window.SchemaGrid.currentTransaction=null}),c()}}function V(e,t){e.addEventListener(`click`,e=>{e.target.closest(`.manage-indexes-cell`)&&z()}),e.addEventListener(`dblclick`,e=>{let n=e.target.closest(`td.data-cell`);if(!n||n.querySelector(`input, select`))return;let r=n.dataset.colKey;n.dataset.insertIndex;let i=n.textContent===`-`||n.textContent===`+ New`||n.textContent===`No`||n.textContent===`null`?``:n.textContent===`Yes`?`1`:n.textContent,a;if(r===`isPk`){B(n,n.textContent);return}else if(r===`nullable`)a=document.createElement(`select`),[`No`,`Yes`].forEach(e=>{let t=document.createElement(`option`);t.value=e,t.textContent=e,(e===`Yes`&&i===`1`||e===`No`&&i===``)&&(t.selected=!0),a.appendChild(t)});else if(r===`type`){a=document.createElement(`select`);let e=[`INTEGER`,`TEXT`,`REAL`,`BLOB`,`NUMERIC`,`BOOLEAN`,`DATE`,`DATETIME`,`JSON`,`VARCHAR(255)`,`DECIMAL(10,2)`,`UUID`];i&&!e.some(e=>e.toUpperCase()===i.toUpperCase())&&e.unshift(i),e.forEach(e=>{let t=document.createElement(`option`);t.value=e,t.textContent=e,e.toUpperCase()===i.toUpperCase()&&(t.selected=!0),a.appendChild(t)})}else a=document.createElement(`input`),a.type=`text`,a.value=i;n.innerHTML=``,n.appendChild(a),a.style.width=`100%`,a.addEventListener(`keydown`,e=>{e.key===`Enter`&&a.blur()}),a.focus();let o=()=>{let e=a.value;window.SchemaGrid.currentTransaction=[],F(n,e,t),window.SchemaGrid.currentTransaction.length>0&&window.SchemaGrid.history.push(window.SchemaGrid.currentTransaction),window.SchemaGrid.currentTransaction=null};a.addEventListener(`blur`,()=>{o()})})}async function H(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 style='padding:24px;'>Loading Schema...</div>`;try{let[n,r]=await Promise.all([u(e),d(e)]);if(n.success&&n.data){let a=n.data,o=r.success&&r.data?r.data:[];window.SchemaGrid={schema:a,indexes:o,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=`
202
- <div class="toolbar">
203
- <div class="filter-group">
204
- <div class="filter-icon-container">
205
- <span class="material-symbols-outlined">search</span>
206
- <span>Search</span>
207
- </div>
208
- <input type="text" id="schema-search-val-${e}" class="filter-input" placeholder="Search name or type..." style="width: 250px;" value="${window.SchemaGrid.filterText}" />
209
- </div>
210
- <div style="flex:1;"></div>
211
- <button id="btn-refresh-schema-${e}" class="refresh-btn" title="Refresh Schema (F5)"><span class="material-symbols-outlined">refresh</span></button>
212
- </div>
213
- <div id="schema-grid-container-${e}" class="table-container"></div>
214
- `,window.renderSchemaGrid=()=>{let t=document.getElementById(`schema-grid-container-${e}`);if(!t)return;let n=[...window.SchemaGrid.schema];if(window.SchemaGrid.filterText){let e=window.SchemaGrid.filterText.toLowerCase();n=n.filter(t=>t.name&&t.name.toLowerCase().includes(e)||t.type&&t.type.toLowerCase().includes(e))}window.SchemaGrid.sortState.colKey&&n.sort((e,t)=>{let n=window.SchemaGrid.sortState.colKey,r=e[n],i=t[n];return r??=``,i??=``,r<i?window.SchemaGrid.sortState.asc?-1:1:r>i?window.SchemaGrid.sortState.asc?1:-1:0});let r=[`name`,`type`,`isPk`,`nullable`,`defaultValue`,`indexing`],i=[`Name`,`Type`,`PK/FK`,`Nullable`,`Default Value`,`Indexing`],a=`<table class="data-table" id="schema-grid-table-${e}"><thead><tr><th class="row-header">#</th>`;r.forEach((e,t)=>{let n=``;window.SchemaGrid.sortState.colKey===e&&(n=window.SchemaGrid.sortState.asc?`▲`:`▼`),a+=`<th class="sortable" data-col-key="${e}">
215
- <div style="display: flex; justify-content: space-between; align-items: center;">
216
- <div>${i[t]}</div>
217
- <div class="sort-arrow" style="font-size:10px; opacity:0.8; margin-left: 8px; width: 12px; text-align: right;">${n}</div>
218
- </div>
219
- </th>`}),a+=`</tr></thead><tbody>`,n&&n.length>0&&n.forEach((e,t)=>{a+=`<tr><td class="row-header" data-row-idx="${t}">${t+1}</td>`,r.forEach((r,i)=>{if(r===`indexing`){if(t===0){let e=(n?n.length:0)+1,t=window.SchemaGrid.indexes.length,r=window.SchemaGrid.pendingIndexEdits.added.length,i=window.SchemaGrid.pendingIndexEdits.dropped.length,o=t+r-i;a+=`<td class="data-cell manage-indexes-cell" rowspan="${e}" style="text-align:center; vertical-align:middle; cursor:pointer; color:var(--color-brand-500); font-weight:500; border-left: 1px solid var(--color-border);">
220
- Manage Indexes (${o})
221
- </td>`}return}let o=e[r];if(r===`isPk`){let t=o,n=!!e.fkTarget;o=t&&n?`PK, FK (${e.fkTarget.table}.${e.fkTarget.column})`:t?`PK`:n?`FK (${e.fkTarget.table}.${e.fkTarget.column})`:`-`}else r===`nullable`?o=o?`Yes`:`No`:o??=``;let s=String(o).replace(/"/g,`&quot;`),c=o===``?`<span style="color:var(--color-text-soft)">-</span>`:String(o).replace(/</g,`&lt;`);a+=`<td class="data-cell" data-row-idx="${t}" data-col-idx="${i}" data-pk="${e.name}" data-col-key="${r}" data-original="${s}">${c}</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>`,r.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}">+ New</td>`)}),a+=`</tr></tbody></table>`,t.innerHTML=a,document.querySelectorAll(`#schema-grid-table-${e} th.sortable`).forEach(e=>{e.onclick=t=>{if(window.SchemaGrid.isResizing)return;if(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){alert(`You have unsaved changes! Please press Ctrl+S to save them before sorting.`);return}let n=e.dataset.colKey;window.SchemaGrid.sortState.colKey===n?window.SchemaGrid.sortState.asc=!window.SchemaGrid.sortState.asc:(window.SchemaGrid.sortState.colKey=n,window.SchemaGrid.sortState.asc=!0),window.SchemaGrid.selection={startRow:-1,startCol:-1,endRow:-1,endCol:-1,isDragging:!1},window.renderSchemaGrid()},v(e,window.SchemaGrid)}),g(t,`schema-grid-table-${e}`,window.SchemaGrid,r.length),V(t,r)},window.renderSchemaGrid();let s=document.getElementById(`schema-search-val-${e}`);s&&s.addEventListener(`input`,e=>{window.SchemaGrid.filterText=e.target.value,window.SchemaGrid.selection={startRow:-1,startCol:-1,endRow:-1,endCol:-1,isDragging:!1},window.renderSchemaGrid()});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?.(),H(e,t,document.getElementById(`view-schema-btn-${e}`)))})}else i.innerHTML=`<div style="padding:24px; color:red;">Error: ${n.error}</div>`}catch(e){i.innerHTML=`<div style="padding:24px; color:red;">Failed to load schema: ${e.message}</div>`}}function U(e,t){document.querySelectorAll(`.table-btn`).forEach(e=>e.classList.remove(`active`)),t&&t.classList.add(`active`);let n=document.getElementById(`table-name`);n&&(n.textContent=`SQL Console`);let r=document.getElementById(`main-content`);r.innerHTML=`
222
- <div id="console-container" style="display: flex; flex-direction: column; flex: 1; height: 100%; min-width: 0;">
223
- <div id="console-editor-pane" style="flex: 1; display: flex; flex-direction: column; border-bottom: 1px solid var(--color-border); position: relative; min-height: 200px;">
224
- <div id="sql-editor" style="flex: 1; font-size: 14px;"></div>
225
- <button id="run-sql-btn" class="primary" style="position: absolute; bottom: 16px; right: 24px; padding: 8px 16px; border-radius: 6px; border: none; background-color: var(--color-primary); color: #fff; font-weight: 600; cursor: pointer; box-shadow: 0 4px 6px rgba(0,0,0,0.1); z-index: 50; display: flex; align-items: center; gap: 6px; transition: all 0.2s;">
226
- <span class="material-symbols-outlined" style="font-size: 18px;">play_arrow</span> Run (Ctrl+Enter)
227
- </button>
228
- </div>
229
- <div id="console-results-pane" style="flex: 1; display: flex; flex-direction: column; overflow: hidden; background: #fff; min-height: 200px;">
230
- <div id="console-results-header" style="padding: 8px 16px; background-color: var(--color-bg-secondary); border-bottom: 1px solid var(--color-border); font-size: 12px; color: var(--color-text-soft); font-weight: 600;">RESULTS</div>
231
- <div class="table-container" id="console-table-container" style="flex: 1;">
232
- <div style="padding: 24px; color: var(--color-text-soft); text-align: center; font-size: 14px;">Run a query to see results.</div>
233
- </div>
234
- </div>
235
- </div>
236
- `;let i=window.ace.edit(`sql-editor`);i.setTheme(`ace/theme/chrome`),i.session.setMode(`ace/mode/sql`),i.setOptions({showPrintMargin:!1,fontSize:`14px`,fontFamily:`ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace`,highlightActiveLine:!0}),window.AppState.lastQuery?i.setValue(window.AppState.lastQuery,1):i.setValue(`-- Enter your SQL query here
237
- SELECT * FROM sqlite_master;
238
- `,1),i.focus();let a=async()=>{let e=i.getValue().trim();if(!e)return;window.AppState.lastQuery=e;let t=document.getElementById(`console-table-container`),n=document.getElementById(`console-results-header`);n.textContent=`EXECUTING...`,n.style.color=`var(--color-primary)`,t.innerHTML=`<div style="padding: 24px; text-align: center; color: var(--color-text-soft);">Executing query...</div>`;try{let r=await f(e);if(!r.success){n.textContent=`ERROR`,n.style.color=`red`,t.innerHTML=`<div style="padding: 24px; color: red; font-family: monospace; white-space: pre-wrap;">${r.error}</div>`;return}let i=r.data.rows||[];if(n.textContent=`SUCCESS - ${i.length} rows returned`,n.style.color=`green`,i.length===0){t.innerHTML=`<div style="padding: 24px; text-align: center; color: var(--color-text-soft);">0 rows returned.</div>`;return}let a=Object.keys(i[0]),o=document.createElement(`table`);o.className=`data-table`;let s=document.createElement(`thead`),c=document.createElement(`tr`),l=document.createElement(`th`);l.className=`row-header`,l.textContent=`#`,c.appendChild(l),a.forEach(e=>{let t=document.createElement(`th`);t.textContent=e;let n=document.createElement(`div`);n.className=`resizer`,t.appendChild(n),n.addEventListener(`click`,e=>e.stopPropagation()),n.addEventListener(`mousedown`,e=>{e.preventDefault(),e.stopPropagation();let n=e.pageX,r=t.offsetWidth,i=e=>{let i=r+(e.pageX-n);t.style.width=i+`px`,t.style.minWidth=i+`px`,t.style.maxWidth=i+`px`},a=()=>{document.removeEventListener(`mousemove`,i),document.removeEventListener(`mouseup`,a),document.body.style.cursor=``};document.body.style.cursor=`col-resize`,document.addEventListener(`mousemove`,i),document.addEventListener(`mouseup`,a)}),c.appendChild(t)}),s.appendChild(c),o.appendChild(s);let u=document.createElement(`tbody`);i.forEach((e,t)=>{let n=document.createElement(`tr`),r=document.createElement(`td`);r.className=`row-header`,r.textContent=t+1,n.appendChild(r),a.forEach(t=>{let r=document.createElement(`td`),i=e[t];if(i===null){let e=document.createElement(`span`);e.textContent=`NULL`,e.style.color=`var(--color-text-soft)`,e.style.fontStyle=`italic`,r.appendChild(e)}else r.textContent=String(i);n.appendChild(r)}),u.appendChild(n)}),o.appendChild(u),t.innerHTML=``,t.appendChild(o)}catch(e){n.textContent=`ERROR`,n.style.color=`red`,t.innerHTML=`<div style="padding: 24px; color: red; font-family: monospace; white-space: pre-wrap;">${e.message}</div>`}};document.getElementById(`run-sql-btn`).onclick=a,i.commands.addCommand({name:`run`,bindKey:{win:`Ctrl-Enter`,mac:`Command-Enter`},exec:function(){a()}})}var W=document.getElementById(`header-container`),G=document.getElementById(`sidebar-container`),K=document.getElementById(`tab-container`);W.innerHTML=n,G.innerHTML=r,K.innerHTML=i,window.AppState={currentTable:null,currentTab:`data-btn`,currentTableBtnElement:null,dbType:null},s().then(e=>{e&&e.success&&e.data&&(window.AppState.dbType=e.data.dbType)}),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.length>1||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.length>1||e.pendingDeletes&&e.pendingDeletes.size>0||t)&&(a=!0)}}let o=e.querySelector(`span`),s=o.textContent.replace(/\s*\*$/,``);a?(o.textContent=s+` *`,o.style.fontWeight=`bold`):(o.textContent=s,o.style.fontWeight=`normal`)})},window.handleSwitchTab=function(e){document.querySelectorAll(`.tab-btn`).forEach(e=>e.classList.remove(`isCurrentTab`));let t=document.getElementById(e);if(t&&t.classList.add(`isCurrentTab`),window.AppState.currentTab=e,e===`erd-btn`||e===`sql-btn`||e===`status-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`)&&!window.AppState.currentTable){let e=document.querySelector(`.table-btn`);e&&(window.AppState.currentTable=e.querySelector(`span`).textContent,window.AppState.currentTableBtnElement=e,e.classList.add(`active`))}window.renderCurrentView()},window.renderEmptyState=function(e){e.innerHTML=`
239
- <div class="empty-state">
240
- <div class="icon-container">
241
- <span class="material-symbols-outlined">database</span>
242
- </div>
243
- <h2>No Table Selected</h2>
244
- <p>Select a table from the sidebar to view its data, schema, or run SQL queries.</p>
245
- </div>
246
- `},window.renderCurrentView=function(e=``,t=!1){let n=[`erd-btn`,`sql-btn`,`status-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())&&M(o,window.AppState.currentTableBtnElement,e,t,a)):window.AppState.currentTab===`schema-btn`?(window.TableStates[o].schemaGrid&&(window.SchemaGrid=window.TableStates[o].schemaGrid),(!window.TableStates[o].schemaGrid||!a.hasChildNodes())&&H(o,window.AppState.currentTableBtnElement,a)):window.AppState.currentTab===`console-btn`?a.hasChildNodes()||U(o,window.AppState.currentTableBtnElement,a):window.AppState.currentTab===`erd-btn`?a.hasChildNodes()||(a.innerHTML=`<div style='padding:24px; color: var(--color-text-soft);'>ERD Visualization coming soon!</div>`):window.AppState.currentTab===`status-btn`&&(a.hasChildNodes()||(a.innerHTML=`<div style='padding:24px; color: var(--color-text-soft);'>Database Status Dashboard coming soon!</div>`)),document.querySelectorAll(`.table-btn`).forEach(e=>e.classList.remove(`active`)),window.AppState.currentTableBtnElement&&window.AppState.currentTableBtnElement.classList.add(`active`)},window.saveDataGridEdits=b,window.saveSchemaEdits=P,document.addEventListener(`DOMContentLoaded`,()=>{p();let e=localStorage.getItem(`drixio-theme`),t=window.matchMedia&&window.matchMedia(`(prefers-color-scheme: dark)`).matches;if(e===`dark`||!e&&t){document.documentElement.setAttribute(`data-theme`,`dark`);let e=document.getElementById(`theme-icon`);e&&(e.textContent=`light_mode`)}let n=document.getElementById(`theme-toggle`);n&&n.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),document.getElementById(`theme-icon`).textContent=e?`dark_mode`:`light_mode`}),window.showToast=function(e,t=`success`){let n=document.getElementById(`toast-container`);if(!n)return;let r=document.createElement(`div`);r.className=`toast ${t}`,r.innerHTML=`<span class="material-symbols-outlined">${t===`success`?`check_circle`:`error`}</span> <span>${e}</span>`,n.appendChild(r),setTimeout(()=>{r.parentNode&&r.parentNode.removeChild(r)},3e3)},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`);if(!r)return;e.preventDefault();let i=parseInt(r.dataset.rowIdx);document.getElementById(`custom-context-menu`)?.remove();let a=document.createElement(`div`);a.id=`custom-context-menu`,a.className=`context-menu`,a.style.top=`${e.clientY}px`,a.style.left=`${e.clientX}px`,a.innerHTML=`
247
- <div class="context-menu-item" id="cmenu-duplicate">
248
- <span class="material-symbols-outlined" style="font-size:16px;">content_copy</span> Duplicate Row(s)
249
- </div>
250
- <div class="context-menu-item danger" id="cmenu-delete">
251
- <span class="material-symbols-outlined" style="font-size:16px;">delete</span> Delete Row(s)
252
- </div>
253
- `,document.body.appendChild(a);let o=e=>{let r=[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){r=[];for(let e=t;e<=n;e++)r.push(e)}}t?O(()=>Promise.resolve().then(()=>y).then(t=>{window.DataGrid.currentTransaction=[],e===`delete`?r.forEach(e=>t.markRowDeleted(e)):e===`duplicate`&&(t.duplicateDataRows(r,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}),void 0,import.meta.url):n&&O(()=>Promise.resolve().then(()=>N).then(t=>{window.SchemaGrid.currentTransaction=[],e===`delete`?r.forEach(e=>t.markSchemaRowDeleted(e)):e===`duplicate`&&(t.duplicateSchemaRows(r,[`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}),void 0,import.meta.url),a.remove()};document.getElementById(`cmenu-duplicate`).onclick=()=>o(`duplicate`),document.getElementById(`cmenu-delete`).onclick=()=>o(`delete`);let s=e=>{a.contains(e.target)||(a.remove(),document.removeEventListener(`click`,s))};setTimeout(()=>document.addEventListener(`click`,s),0)}),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)&&!(e.target.tagName===`INPUT`||e.target.tagName===`SELECT`||e.target.tagName===`TEXTAREA`)){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);let u=t?`data-grid-table-${a}`:`schema-grid-table-${a}`;O(()=>Promise.resolve().then(()=>m).then(e=>e.renderSelection(u,n)),void 0,import.meta.url),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`:`schema-grid-container`);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`)&&(t?O(()=>Promise.resolve().then(()=>y).then(e=>{window.DataGrid.currentTransaction=[],document.querySelectorAll(`#data-grid-table-${window.AppState.currentTable} .cell-in-range`).forEach(t=>e.updateCell(t,``,window.DataGrid.schema.map(e=>e.name))),window.DataGrid.currentTransaction.length>0&&window.DataGrid.history.push(window.DataGrid.currentTransaction),window.DataGrid.currentTransaction=null}),void 0,import.meta.url):n&&O(()=>Promise.resolve().then(()=>N).then(e=>{window.SchemaGrid.currentTransaction=[];let t=[`name`,`type`,`isPk`,`nullable`,`defaultValue`];document.querySelectorAll(`#schema-grid-table-${window.AppState.currentTable} .cell-in-range`).forEach(n=>{(n.dataset.insertIndex!==void 0||n.dataset.colKey===`name`)&&e.updateSchemaCell(n,``,t)}),window.SchemaGrid.currentTransaction.length>0&&window.SchemaGrid.history.push(window.SchemaGrid.currentTransaction),window.SchemaGrid.currentTransaction=null}),void 0,import.meta.url)),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(` `)+`
254
- `}navigator.clipboard.writeText(o.trimEnd()),document.querySelectorAll(`.cell-in-range`).forEach(e=>{e.style.backgroundColor=`#bfdbfe`,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);t?O(()=>Promise.resolve().then(()=>y).then(e=>{r.currentTransaction=[];for(let t=a;t<=o;t++)e.markRowDeleted(t);r.currentTransaction.length>0&&r.history.push(r.currentTransaction),r.currentTransaction=null}),void 0,import.meta.url):n&&O(()=>Promise.resolve().then(()=>N).then(e=>{r.currentTransaction=[];for(let t=a;t<=o;t++)e.markSchemaRowDeleted(t);r.currentTransaction.length>0&&r.history.push(r.currentTransaction),r.currentTransaction=null}),void 0,import.meta.url)}if(e.key.toLowerCase()===`z`&&(e.ctrlKey||e.metaKey)){if(e.preventDefault(),t){let e=window.DataGrid.history?.pop();e&&O(()=>Promise.resolve().then(()=>y).then(t=>{let n=window.DataGrid.schema.map(e=>e.name);for(let r=e.length-1;r>=0;r--){let i=e[r];i.type===`delete`?t.unmarkRowDeleted(i.rowIdx,i.pk):t.updateCell(i.td,i.oldVal,n,!1)}}),void 0,import.meta.url)}else if(n){let e=window.SchemaGrid.history?.pop();e&&O(()=>Promise.resolve().then(()=>N).then(t=>{let n=[`name`,`type`,`isPk`,`nullable`,`defaultValue`];for(let r=e.length-1;r>=0;r--){let i=e[r];i.type===`delete`?t.unmarkSchemaRowDeleted(i.rowIdx,i.pk):t.updateSchemaCell(i.td,i.oldVal,n,!1)}}),void 0,import.meta.url)}}}}),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);r.currentTransaction=[],t?O(()=>Promise.resolve().then(()=>y).then(e=>{let t=r.schema.map(e=>e.name);o.forEach(n=>{n.forEach((n,r)=>{let i=c+r,a=document.querySelector(`#data-grid-table-${window.AppState.currentTable} td.data-cell[data-row-idx="${s}"][data-col-idx="${i}"]`);a&&e.updateCell(a,n,t)}),s++}),r.currentTransaction.length>0&&r.history.push(r.currentTransaction),r.currentTransaction=null}),void 0,import.meta.url):n&&O(()=>Promise.resolve().then(()=>N).then(e=>{let t=[`name`,`type`,`isPk`,`nullable`,`defaultValue`];o.forEach(n=>{n.forEach((n,r)=>{let i=c+r,a=document.querySelector(`#schema-grid-table-${window.AppState.currentTable} td.data-cell[data-row-idx="${s}"][data-col-idx="${i}"]`);a&&(a.dataset.insertIndex!==void 0||a.dataset.colKey===`name`)&&e.updateSchemaCell(a,n,t)}),s++}),r.currentTransaction.length>0&&r.history.push(r.currentTransaction),r.currentTransaction=null}),void 0,import.meta.url)})});