planche 0.8.8 → 0.8.10

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.
Files changed (67) hide show
  1. package/app/assets/{DmnLfXty.js → -hNDclQL.js} +1 -1
  2. package/app/assets/{rcI4Fmt0.js → 1XwwL8xu.js} +1 -1
  3. package/app/assets/3z4eHGF-.js +1 -0
  4. package/app/assets/{Ca4g4XbM.js → B49XtolG.js} +1 -1
  5. package/app/assets/{CoElGuoC.js → B4Yy1mj_.js} +1 -1
  6. package/app/assets/{fDSXGLmI.js → BAZqI8g_.js} +2 -2
  7. package/app/assets/{C5SHWmPn.js → BHsXOlR9.js} +1 -1
  8. package/app/assets/{Dc-epzIX.js → B_zZh5dR.js} +1 -1
  9. package/app/assets/{CRr_nYUE.js → BbdU8Zop.js} +1 -1
  10. package/app/assets/{BwrB7xZ-.js → BeiubXnY.js} +1 -1
  11. package/app/assets/{B_UAjgBr.js → Bg6u9htc.js} +185 -185
  12. package/app/assets/{ZjgMfDAG.js → BjkAHEsD.js} +1 -1
  13. package/app/assets/{XzPc-eVf.js → BkIkgVK5.js} +1 -1
  14. package/app/assets/{9U3RO0MO.js → Bn-kznw7.js} +1 -1
  15. package/app/assets/{RCiVSH3E.js → BoonIczC.js} +1 -1
  16. package/app/assets/{B7ofUN9Z.js → Bp0UhSMs.js} +1 -1
  17. package/app/assets/{CCcRP83D.js → ByHW6Lyi.js} +1 -1
  18. package/app/assets/{DprcmWG4.js → BzhSva5M.js} +1 -1
  19. package/app/assets/{CKOS5Y-e.js → C0O3rJzW.js} +1 -1
  20. package/app/assets/{Baj0YiGk.js → C5VVaHNf.js} +1 -1
  21. package/app/assets/{CKDAL3sp.js → C9rqYcV-.js} +1 -1
  22. package/app/assets/{DouS7NHO.js → CC5k5YaI.js} +1 -1
  23. package/app/assets/{BxdVjvjj.js → CGvlSihl.js} +1 -1
  24. package/app/assets/{Cni8dWDa.js → CPX5LuC-.js} +1 -1
  25. package/app/assets/{Bz1cma8F.js → CUQISMvX.js} +1 -1
  26. package/app/assets/{BfSKVZnY.js → CYMzEa4j.js} +1 -1
  27. package/app/assets/{CZQ1r4zz.js → CaoceGhm.js} +1 -1
  28. package/app/assets/CdUXbAKF.js +1 -0
  29. package/app/assets/{CQLuUHsS.js → Cf8o-5U6.js} +1 -1
  30. package/app/assets/{DxuXBECK.js → Cg4DfVr4.js} +1 -1
  31. package/app/assets/{9YYClKHB.js → ClUjvL-2.js} +1 -1
  32. package/app/assets/{CFzRFS2A.js → CnInyuhK.js} +1 -1
  33. package/app/assets/{C8pwHENI.js → CoI4rONw.js} +1 -1
  34. package/app/assets/{CytzrZ6l.js → CpZOnYKF.js} +1 -1
  35. package/app/assets/{DUi2bIfW.js → CtU21VEz.js} +1 -1
  36. package/app/assets/{40YxirOy.js → D6tNbIL6.js} +1 -1
  37. package/app/assets/{D8QuNkWm.js → DBHRzz66.js} +1 -1
  38. package/app/assets/{B3nhMsGp.js → DC8XCjJ3.js} +1 -1
  39. package/app/assets/{D7TzN7zW.js → DERfOWZ5.js} +1 -1
  40. package/app/assets/{COuEjUso.js → DInfC28p.js} +1 -1
  41. package/app/assets/{8DjNs_2Q.js → DM33HLij.js} +1 -1
  42. package/app/assets/{BBSxV90W.js → DP94Ond0.js} +1 -1
  43. package/app/assets/{CcgrsKRV.js → DSx167Dy.js} +1 -1
  44. package/app/assets/{BjlaUaDI.js → DYuA_YQr.js} +1 -1
  45. package/app/assets/{CtXRSNHU.js → Dd9quIZg.js} +1 -1
  46. package/app/assets/{Cr6Fx4T5.js → Dht5Mpyb.js} +1 -1
  47. package/app/assets/DjDcAaBy.js +8 -0
  48. package/app/assets/{CCQZjXae.js → DnJeTfn9.js} +2 -2
  49. package/app/assets/{DnMHkY8_.js → DqoiWQxk.js} +1 -1
  50. package/app/assets/{BVrYyQUV.js → G6EbcZKg.js} +1 -1
  51. package/app/assets/{COkWw8gt.js → GwHHKhHq.js} +1 -1
  52. package/app/assets/{CYAMmigV.js → Ik6Uk6MY.js} +1 -1
  53. package/app/assets/KuSp3gJs.css +2 -0
  54. package/app/assets/{BteHmqJi.js → Svdye2Hc.js} +1 -1
  55. package/app/assets/{xc6SHidZ.js → aP_gLLGt.js} +1 -1
  56. package/app/assets/{BNkgLUl5.js → dMlgA_r1.js} +1 -1
  57. package/app/assets/{HtYgLQZp.js → lui9VgkF.js} +1 -1
  58. package/app/assets/{KZSCUzXE.js → mIcOy4nG.js} +1 -1
  59. package/app/assets/{AiAiN2FW.js → p4yYbMPY.js} +1 -1
  60. package/app/assets/{zrrdltej.js → ufiABG3J.js} +1 -1
  61. package/app/assets/{BFDfeOJg.js → zspOy9D_.js} +1 -1
  62. package/app/index.html +19 -19
  63. package/package.json +1 -1
  64. package/app/assets/4_c4BD6i.js +0 -1
  65. package/app/assets/CgWXabLX.js +0 -8
  66. package/app/assets/CmJ3siBN.js +0 -1
  67. package/app/assets/MJ9qDdN_.css +0 -2
@@ -1 +1 @@
1
- import{r as e}from"./hePW80VL.js";import{c as t,h as n,n as r,t as i}from"./XzPc-eVf.js";import{l as a,m as ee,t as o}from"./CKOS5Y-e.js";import{a as s,i as c,n as l,r as u,t as d}from"./Bz1cma8F.js";import{t as f}from"./B3nhMsGp.js";import{a as p}from"./CtXRSNHU.js";import{n as m}from"./Cr6Fx4T5.js";import{a as h,d as te}from"./CCQZjXae.js";import{c as g,kt as _,l as ne,lt as re,mt as ie,ot as v}from"./B_UAjgBr.js";import{a as ae,i as oe,n as se,o as ce,r as le,t as y}from"./DxuXBECK.js";var b=e(n(),1),ue=[`SUM`,`AVG`,`MIN`,`MAX`],x=`row_count`;function de(e,t){if(t.columns.length===0)return``;let n=t=>e.quoteIdentifier(t),r=t.columns.map(n),i=[...r,`COUNT(*) AS ${n(x)}`];if(t.aggregate){let{fn:e,column:r}=t.aggregate;i.push(`${e}(${n(r)}) AS ${n(`${e.toLowerCase()}_${r}`)}`)}let a=[];return t.where&&a.push(t.where),a.push(`GROUP BY ${r.join(`, `)}`),t.minCount&&t.minCount>1&&a.push(`HAVING COUNT(*) >= ${Math.floor(t.minCount)}`),a.push(`ORDER BY COUNT(*) DESC`),t.limit>0&&a.push(e.limitClause(t.limit)),e.getQuery(`SELECT_TABLE`,t.database,t.table,i.join(`, `),a.join(` `))}function S(e){let t=new Set;for(let n of e){let e=n.columns[0];e&&t.add(e.toLowerCase())}return t}function C(e,t){return t.has(e.toLowerCase())}function fe(e,t){let n=S(t);return e.some(e=>C(e,n))}var w=a(),T=`none`,pe=/\b(int|dec|numeric|number|float|double|real|money|serial)/i;function E(){let{t:e}=ee(),n=r(e=>e.activeDialog),a=r(e=>e.closeDialog),x=i(`group-by`),E=n===`group-by`,D=f(e=>e.activeConnections),me=f(e=>e.activeConnectionId),he=(0,b.useMemo)(()=>D.filter(e=>e.serverConnectionId),[D]),[O,ge]=(0,b.useState)(()=>x?.connectionId??me??``),[k,A]=(0,b.useState)(()=>x?.database??``),[j,M]=(0,b.useState)(()=>x?.table??``),[N,P]=(0,b.useState)([]),[F,I]=(0,b.useState)([]),L=x&&O===x.connectionId&&k===x.database&&j===x.table?x.where??``:``,[R,z]=(0,b.useState)([]),[B,_e]=(0,b.useState)([]),[V,H]=(0,b.useState)(()=>x?.column?[x.column]:[]),[U,ve]=(0,b.useState)(T),[W,ye]=(0,b.useState)(``),[G,be]=(0,b.useState)(`1`),[K,xe]=(0,b.useState)(!0),[q,J]=(0,b.useState)(``),[Se,Y]=(0,b.useState)(!1),X=e=>f.getState().activeConnections.find(t=>t.id===e)?.serverConnectionId;(0,b.useEffect)(()=>{if(!E||!O)return;let e=X(O);if(!e)return;let t=!1;return(async()=>{try{let n=await m(O).introspect.listDatabases(p(e));if(t)return;P(n),A(e=>e&&n.includes(e)?e:n[0]??``)}catch(e){t||J(e instanceof Error?e.message:String(e))}})(),()=>{t=!0}},[E,O]),(0,b.useEffect)(()=>{if(!E||!O||!k)return;let e=X(O);if(!e)return;let t=!1;return(async()=>{try{let n=await m(O).introspect.listTables(p(e),k);if(t)return;let r=n.map(e=>e.name);I(r),M(e=>e&&r.includes(e)?e:r[0]??``)}catch(e){t||J(e instanceof Error?e.message:String(e))}})(),()=>{t=!0}},[E,O,k]),(0,b.useEffect)(()=>{if(!E||!O||!j)return;let e=X(O);if(!e)return;let t=!1;return(async()=>{let n=p(e),r=m(O).introspect;try{let[e,i]=await Promise.all([r.listColumns(n,k,j),r.listIndexes(n,k,j).catch(()=>[])]);if(t)return;z(e),_e(i),H(t=>t.filter(t=>e.some(e=>e.name===t)))}catch(e){t||J(e instanceof Error?e.message:String(e))}})(),()=>{t=!0}},[E,O,k,j]);let Ce=(0,b.useMemo)(()=>S(B),[B]),we=(0,b.useMemo)(()=>R.filter(e=>pe.test(e.type)),[R]),Z=(0,b.useMemo)(()=>!O||V.length===0?``:de(m(O),{database:k,table:j,columns:V,aggregate:U!==T&&W?{fn:U,column:W}:null,where:K?L:``,minCount:Number(G)||1,limit:te()}),[O,k,j,V,U,W,G,K,L]),Q=V.length>0&&B.length>0&&!fe(V,B);function Te(e){H(t=>t.includes(e)?t.filter(t=>t!==e):[...t,e])}function $(e){t(`group_by`,{action:e,dbms:m(O).id,columns:V.length,aggregate:U,filtered:!!(K&&L),indexed:!Q})}function Ee(){Z&&($(`open`),v(O,Z,k,e(`database.groupBy.tabTitle`,{table:j})),a())}async function De(){if(!Z)return;$(`run`),Y(!0);let t=v(O,Z,k,e(`database.groupBy.tabTitle`,{table:j}));a();try{await h(O,t)}finally{Y(!1)}}return(0,w.jsx)(y,{open:E,onOpenChange:e=>{e||a()},children:(0,w.jsxs)(se,{className:`flex max-h-[85vh] flex-col sm:max-w-[720px]`,children:[(0,w.jsxs)(ae,{children:[(0,w.jsx)(ce,{children:e(`database.groupBy.title`)}),(0,w.jsx)(le,{children:e(`database.groupBy.description`,{table:j})})]}),q&&(0,w.jsx)(`p`,{className:`rounded-md border border-destructive/40 px-3 py-2 text-xs text-destructive`,children:q}),(0,w.jsxs)(`div`,{className:`grid grid-cols-3 gap-2`,children:[(0,w.jsxs)(`div`,{className:`space-y-1`,children:[(0,w.jsx)(g,{className:`text-xs`,children:e(`database.groupBy.connection`)}),(0,w.jsxs)(d,{value:O,onValueChange:ge,children:[(0,w.jsx)(c,{className:`h-8 text-xs`,children:(0,w.jsx)(s,{})}),(0,w.jsx)(l,{children:he.map(e=>(0,w.jsx)(u,{value:e.id,children:e.hostName||e.host||e.file||e.id},e.id))})]})]}),(0,w.jsxs)(`div`,{className:`space-y-1`,children:[(0,w.jsx)(g,{className:`text-xs`,children:e(`database.groupBy.database`)}),(0,w.jsxs)(d,{value:k,onValueChange:A,children:[(0,w.jsx)(c,{className:`h-8 text-xs`,children:(0,w.jsx)(s,{})}),(0,w.jsx)(l,{children:N.map(e=>(0,w.jsx)(u,{value:e,children:e},e))})]})]}),(0,w.jsxs)(`div`,{className:`space-y-1`,children:[(0,w.jsx)(g,{className:`text-xs`,children:e(`database.groupBy.table`)}),(0,w.jsxs)(d,{value:j,onValueChange:M,children:[(0,w.jsx)(c,{className:`h-8 text-xs`,children:(0,w.jsx)(s,{})}),(0,w.jsx)(l,{children:F.map(e=>(0,w.jsx)(u,{value:e,children:e},e))})]})]})]}),(0,w.jsxs)(`div`,{className:`grid min-h-0 grid-cols-[1fr_1fr] gap-4`,children:[(0,w.jsxs)(`div`,{className:`flex min-h-0 flex-col gap-1.5`,children:[(0,w.jsx)(g,{className:`text-xs`,children:e(`database.groupBy.columns`)}),(0,w.jsx)(re,{className:`h-[260px] rounded-md border`,children:(0,w.jsx)(`ul`,{className:`p-1`,children:R.map(t=>{let n=C(t.name,Ce);return(0,w.jsx)(`li`,{children:(0,w.jsxs)(`label`,{className:`flex cursor-pointer items-center gap-2 rounded px-2 py-1 text-xs hover:bg-accent`,children:[(0,w.jsx)(`input`,{type:`checkbox`,checked:V.includes(t.name),onChange:()=>Te(t.name)}),(0,w.jsx)(`span`,{className:`truncate font-medium`,children:t.name}),(0,w.jsx)(`span`,{className:`truncate text-muted-foreground`,children:t.type}),n&&(0,w.jsx)(_,{className:`ml-auto h-3 w-3 shrink-0 text-muted-foreground`,"aria-label":e(`database.groupBy.indexed`)})]})},t.name)})})})]}),(0,w.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,w.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,w.jsx)(g,{className:`text-xs`,children:e(`database.groupBy.aggregate`)}),(0,w.jsxs)(`div`,{className:`flex gap-2`,children:[(0,w.jsxs)(d,{value:U,onValueChange:ve,children:[(0,w.jsx)(c,{className:`h-8 w-[110px] text-xs`,children:(0,w.jsx)(s,{})}),(0,w.jsxs)(l,{children:[(0,w.jsx)(u,{value:T,children:e(`database.groupBy.countOnly`)}),ue.map(e=>(0,w.jsx)(u,{value:e,children:e},e))]})]}),(0,w.jsxs)(d,{value:W,onValueChange:ye,disabled:U===T,children:[(0,w.jsx)(c,{className:`h-8 flex-1 text-xs`,children:(0,w.jsx)(s,{placeholder:e(`database.groupBy.column`)})}),(0,w.jsx)(l,{children:we.map(e=>(0,w.jsx)(u,{value:e.name,children:e.name},e.name))})]})]})]}),(0,w.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,w.jsx)(g,{htmlFor:`gb-min`,className:`text-xs`,children:e(`database.groupBy.minCount`)}),(0,w.jsx)(ne,{id:`gb-min`,type:`number`,min:1,value:G,onChange:e=>be(e.target.value),className:`h-8 text-xs`})]}),L&&(0,w.jsxs)(`label`,{className:`flex items-center gap-2 text-xs`,children:[(0,w.jsx)(`input`,{type:`checkbox`,checked:K,onChange:e=>xe(e.target.checked)}),e(`database.groupBy.useFilter`)]}),Q&&(0,w.jsxs)(`p`,{className:`flex gap-1.5 rounded-md border border-dashed px-2 py-1.5 text-xs text-muted-foreground`,children:[(0,w.jsx)(ie,{className:`mt-0.5 h-3.5 w-3.5 shrink-0`}),(0,w.jsx)(`span`,{children:e(`database.groupBy.noIndexWarning`)})]})]})]}),(0,w.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,w.jsx)(g,{className:`text-xs`,children:e(`database.groupBy.preview`)}),(0,w.jsx)(`pre`,{className:`max-h-[120px] overflow-auto rounded-md border bg-muted p-2 font-mono text-xs whitespace-pre-wrap`,children:Z||e(`database.groupBy.pickColumn`)})]}),(0,w.jsxs)(oe,{children:[(0,w.jsx)(o,{variant:`outline`,onClick:a,children:e(`command.close`)}),(0,w.jsx)(o,{variant:`outline`,onClick:Ee,disabled:!Z,children:e(`database.groupBy.openInTab`)}),(0,w.jsx)(o,{onClick:De,disabled:!Z||Se,children:e(`database.groupBy.run`)})]})]})})}export{E as GroupByDialog};
1
+ import{r as e}from"./hePW80VL.js";import{c as t,h as n,n as r,t as i}from"./BkIkgVK5.js";import{l as a,m as ee,t as o}from"./C0O3rJzW.js";import{a as s,i as c,n as l,r as u,t as d}from"./CUQISMvX.js";import{t as f}from"./DC8XCjJ3.js";import{a as p}from"./Dd9quIZg.js";import{n as m}from"./Dht5Mpyb.js";import{a as h,d as te}from"./DnJeTfn9.js";import{c as g,kt as _,l as ne,lt as re,mt as ie,ot as v}from"./Bg6u9htc.js";import{a as ae,i as oe,n as se,o as ce,r as le,t as y}from"./Cg4DfVr4.js";var b=e(n(),1),ue=[`SUM`,`AVG`,`MIN`,`MAX`],x=`row_count`;function de(e,t){if(t.columns.length===0)return``;let n=t=>e.quoteIdentifier(t),r=t.columns.map(n),i=[...r,`COUNT(*) AS ${n(x)}`];if(t.aggregate){let{fn:e,column:r}=t.aggregate;i.push(`${e}(${n(r)}) AS ${n(`${e.toLowerCase()}_${r}`)}`)}let a=[];return t.where&&a.push(t.where),a.push(`GROUP BY ${r.join(`, `)}`),t.minCount&&t.minCount>1&&a.push(`HAVING COUNT(*) >= ${Math.floor(t.minCount)}`),a.push(`ORDER BY COUNT(*) DESC`),t.limit>0&&a.push(e.limitClause(t.limit)),e.getQuery(`SELECT_TABLE`,t.database,t.table,i.join(`, `),a.join(` `))}function S(e){let t=new Set;for(let n of e){let e=n.columns[0];e&&t.add(e.toLowerCase())}return t}function C(e,t){return t.has(e.toLowerCase())}function fe(e,t){let n=S(t);return e.some(e=>C(e,n))}var w=a(),T=`none`,pe=/\b(int|dec|numeric|number|float|double|real|money|serial)/i;function E(){let{t:e}=ee(),n=r(e=>e.activeDialog),a=r(e=>e.closeDialog),x=i(`group-by`),E=n===`group-by`,D=f(e=>e.activeConnections),me=f(e=>e.activeConnectionId),he=(0,b.useMemo)(()=>D.filter(e=>e.serverConnectionId),[D]),[O,ge]=(0,b.useState)(()=>x?.connectionId??me??``),[k,A]=(0,b.useState)(()=>x?.database??``),[j,M]=(0,b.useState)(()=>x?.table??``),[N,P]=(0,b.useState)([]),[F,I]=(0,b.useState)([]),L=x&&O===x.connectionId&&k===x.database&&j===x.table?x.where??``:``,[R,z]=(0,b.useState)([]),[B,_e]=(0,b.useState)([]),[V,H]=(0,b.useState)(()=>x?.column?[x.column]:[]),[U,ve]=(0,b.useState)(T),[W,ye]=(0,b.useState)(``),[G,be]=(0,b.useState)(`1`),[K,xe]=(0,b.useState)(!0),[q,J]=(0,b.useState)(``),[Se,Y]=(0,b.useState)(!1),X=e=>f.getState().activeConnections.find(t=>t.id===e)?.serverConnectionId;(0,b.useEffect)(()=>{if(!E||!O)return;let e=X(O);if(!e)return;let t=!1;return(async()=>{try{let n=await m(O).introspect.listDatabases(p(e));if(t)return;P(n),A(e=>e&&n.includes(e)?e:n[0]??``)}catch(e){t||J(e instanceof Error?e.message:String(e))}})(),()=>{t=!0}},[E,O]),(0,b.useEffect)(()=>{if(!E||!O||!k)return;let e=X(O);if(!e)return;let t=!1;return(async()=>{try{let n=await m(O).introspect.listTables(p(e),k);if(t)return;let r=n.map(e=>e.name);I(r),M(e=>e&&r.includes(e)?e:r[0]??``)}catch(e){t||J(e instanceof Error?e.message:String(e))}})(),()=>{t=!0}},[E,O,k]),(0,b.useEffect)(()=>{if(!E||!O||!j)return;let e=X(O);if(!e)return;let t=!1;return(async()=>{let n=p(e),r=m(O).introspect;try{let[e,i]=await Promise.all([r.listColumns(n,k,j),r.listIndexes(n,k,j).catch(()=>[])]);if(t)return;z(e),_e(i),H(t=>t.filter(t=>e.some(e=>e.name===t)))}catch(e){t||J(e instanceof Error?e.message:String(e))}})(),()=>{t=!0}},[E,O,k,j]);let Ce=(0,b.useMemo)(()=>S(B),[B]),we=(0,b.useMemo)(()=>R.filter(e=>pe.test(e.type)),[R]),Z=(0,b.useMemo)(()=>!O||V.length===0?``:de(m(O),{database:k,table:j,columns:V,aggregate:U!==T&&W?{fn:U,column:W}:null,where:K?L:``,minCount:Number(G)||1,limit:te()}),[O,k,j,V,U,W,G,K,L]),Q=V.length>0&&B.length>0&&!fe(V,B);function Te(e){H(t=>t.includes(e)?t.filter(t=>t!==e):[...t,e])}function $(e){t(`group_by`,{action:e,dbms:m(O).id,columns:V.length,aggregate:U,filtered:!!(K&&L),indexed:!Q})}function Ee(){Z&&($(`open`),v(O,Z,k,e(`database.groupBy.tabTitle`,{table:j})),a())}async function De(){if(!Z)return;$(`run`),Y(!0);let t=v(O,Z,k,e(`database.groupBy.tabTitle`,{table:j}));a();try{await h(O,t)}finally{Y(!1)}}return(0,w.jsx)(y,{open:E,onOpenChange:e=>{e||a()},children:(0,w.jsxs)(se,{className:`flex max-h-[85vh] flex-col sm:max-w-[720px]`,children:[(0,w.jsxs)(ae,{children:[(0,w.jsx)(ce,{children:e(`database.groupBy.title`)}),(0,w.jsx)(le,{children:e(`database.groupBy.description`,{table:j})})]}),q&&(0,w.jsx)(`p`,{className:`rounded-md border border-destructive/40 px-3 py-2 text-xs text-destructive`,children:q}),(0,w.jsxs)(`div`,{className:`grid grid-cols-3 gap-2`,children:[(0,w.jsxs)(`div`,{className:`space-y-1`,children:[(0,w.jsx)(g,{className:`text-xs`,children:e(`database.groupBy.connection`)}),(0,w.jsxs)(d,{value:O,onValueChange:ge,children:[(0,w.jsx)(c,{className:`h-8 text-xs`,children:(0,w.jsx)(s,{})}),(0,w.jsx)(l,{children:he.map(e=>(0,w.jsx)(u,{value:e.id,children:e.hostName||e.host||e.file||e.id},e.id))})]})]}),(0,w.jsxs)(`div`,{className:`space-y-1`,children:[(0,w.jsx)(g,{className:`text-xs`,children:e(`database.groupBy.database`)}),(0,w.jsxs)(d,{value:k,onValueChange:A,children:[(0,w.jsx)(c,{className:`h-8 text-xs`,children:(0,w.jsx)(s,{})}),(0,w.jsx)(l,{children:N.map(e=>(0,w.jsx)(u,{value:e,children:e},e))})]})]}),(0,w.jsxs)(`div`,{className:`space-y-1`,children:[(0,w.jsx)(g,{className:`text-xs`,children:e(`database.groupBy.table`)}),(0,w.jsxs)(d,{value:j,onValueChange:M,children:[(0,w.jsx)(c,{className:`h-8 text-xs`,children:(0,w.jsx)(s,{})}),(0,w.jsx)(l,{children:F.map(e=>(0,w.jsx)(u,{value:e,children:e},e))})]})]})]}),(0,w.jsxs)(`div`,{className:`grid min-h-0 grid-cols-[1fr_1fr] gap-4`,children:[(0,w.jsxs)(`div`,{className:`flex min-h-0 flex-col gap-1.5`,children:[(0,w.jsx)(g,{className:`text-xs`,children:e(`database.groupBy.columns`)}),(0,w.jsx)(re,{className:`h-[260px] rounded-md border`,children:(0,w.jsx)(`ul`,{className:`p-1`,children:R.map(t=>{let n=C(t.name,Ce);return(0,w.jsx)(`li`,{children:(0,w.jsxs)(`label`,{className:`flex cursor-pointer items-center gap-2 rounded px-2 py-1 text-xs hover:bg-accent`,children:[(0,w.jsx)(`input`,{type:`checkbox`,checked:V.includes(t.name),onChange:()=>Te(t.name)}),(0,w.jsx)(`span`,{className:`truncate font-medium`,children:t.name}),(0,w.jsx)(`span`,{className:`truncate text-muted-foreground`,children:t.type}),n&&(0,w.jsx)(_,{className:`ml-auto h-3 w-3 shrink-0 text-muted-foreground`,"aria-label":e(`database.groupBy.indexed`)})]})},t.name)})})})]}),(0,w.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,w.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,w.jsx)(g,{className:`text-xs`,children:e(`database.groupBy.aggregate`)}),(0,w.jsxs)(`div`,{className:`flex gap-2`,children:[(0,w.jsxs)(d,{value:U,onValueChange:ve,children:[(0,w.jsx)(c,{className:`h-8 w-[110px] text-xs`,children:(0,w.jsx)(s,{})}),(0,w.jsxs)(l,{children:[(0,w.jsx)(u,{value:T,children:e(`database.groupBy.countOnly`)}),ue.map(e=>(0,w.jsx)(u,{value:e,children:e},e))]})]}),(0,w.jsxs)(d,{value:W,onValueChange:ye,disabled:U===T,children:[(0,w.jsx)(c,{className:`h-8 flex-1 text-xs`,children:(0,w.jsx)(s,{placeholder:e(`database.groupBy.column`)})}),(0,w.jsx)(l,{children:we.map(e=>(0,w.jsx)(u,{value:e.name,children:e.name},e.name))})]})]})]}),(0,w.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,w.jsx)(g,{htmlFor:`gb-min`,className:`text-xs`,children:e(`database.groupBy.minCount`)}),(0,w.jsx)(ne,{id:`gb-min`,type:`number`,min:1,value:G,onChange:e=>be(e.target.value),className:`h-8 text-xs`})]}),L&&(0,w.jsxs)(`label`,{className:`flex items-center gap-2 text-xs`,children:[(0,w.jsx)(`input`,{type:`checkbox`,checked:K,onChange:e=>xe(e.target.checked)}),e(`database.groupBy.useFilter`)]}),Q&&(0,w.jsxs)(`p`,{className:`flex gap-1.5 rounded-md border border-dashed px-2 py-1.5 text-xs text-muted-foreground`,children:[(0,w.jsx)(ie,{className:`mt-0.5 h-3.5 w-3.5 shrink-0`}),(0,w.jsx)(`span`,{children:e(`database.groupBy.noIndexWarning`)})]})]})]}),(0,w.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,w.jsx)(g,{className:`text-xs`,children:e(`database.groupBy.preview`)}),(0,w.jsx)(`pre`,{className:`max-h-[120px] overflow-auto rounded-md border bg-muted p-2 font-mono text-xs whitespace-pre-wrap`,children:Z||e(`database.groupBy.pickColumn`)})]}),(0,w.jsxs)(oe,{children:[(0,w.jsx)(o,{variant:`outline`,onClick:a,children:e(`command.close`)}),(0,w.jsx)(o,{variant:`outline`,onClick:Ee,disabled:!Z,children:e(`database.groupBy.openInTab`)}),(0,w.jsx)(o,{onClick:De,disabled:!Z||Se,children:e(`database.groupBy.run`)})]})]})})}export{E as GroupByDialog};
@@ -1 +1 @@
1
- import{r as e}from"./XzPc-eVf.js";import{i as t,t as n}from"./eFSiW0Lh.js";import{a as r,i,k as a,n as o,r as s}from"./B3nhMsGp.js";import{n as c}from"./BBSxV90W.js";var l=200,u=Object.freeze([]);function d(e,t,n){return e.map(e=>e.id===t?{...e,...n}:e)}function f(e){let t=e;if(delete t.erdOpen,delete t.erdDatabase,t.tabs&&typeof t.tabs==`object`){let e=t.tabs;for(let t of Object.keys(e))e[t]=e[t].map(e=>{if(!Array.isArray(e.results)){let t={...e};return delete t.result,{...t,results:[]}}return e})}return t}var p=e()(t((e,t)=>({tabs:{},activeTabId:{},history:[],addQueryTab:(t,n)=>e(e=>{let r=e.tabs[t]??[];return{tabs:{...e.tabs,[t]:[...r,n]},activeTabId:{...e.activeTabId,[t]:n.id}}}),removeQueryTab:(e,n)=>t().removeQueryTabs(e,[n]),removeQueryTabs:(n,r)=>{for(let e of r)t().captureRevision(n,e,`close`);e(e=>{let t=new Set(r),i=(e.tabs[n]??[]).filter(e=>!t.has(e.id)),a=e.activeTabId[n],o=a&&t.has(a)?i.length>0?i[i.length-1].id:null:a;return{tabs:{...e.tabs,[n]:i},activeTabId:{...e.activeTabId,[n]:o}}})},reorderQueryTab:(t,n,i)=>e(e=>({tabs:{...e.tabs,[t]:r(e.tabs[t]??[],n,i)}})),setActiveQueryTab:(t,n)=>e(e=>({activeTabId:{...e.activeTabId,[t]:n}})),setEditorContent:(n,r,i)=>{e(e=>{let t=e.tabs[n]??[];return{tabs:{...e.tabs,[n]:d(t,r,{query:i})}}});let a=t().tabs[n]?.find(e=>e.id===r);a&&s(n,{docId:r,title:a.title,text:i,database:a.database,reason:`edit`})},setResults:(t,n,r)=>e(e=>{let i=e.tabs[t]??[];return{tabs:{...e.tabs,[t]:d(i,n,{results:r,isExecuting:!1,error:null})}}}),setExecuting:(t,n,r)=>e(e=>{let i=e.tabs[t]??[];return{tabs:{...e.tabs,[t]:d(i,n,{isExecuting:r})}}}),setPlan:(t,n,r)=>e(e=>{let i=e.tabs[t]??[];return{tabs:{...e.tabs,[t]:d(i,n,{plan:r})}}}),setGraphs:(t,n,r)=>e(e=>{let i=e.tabs[t];return i?{tabs:{...e.tabs,[t]:d(i,n,{graphs:r})}}:e}),setError:(t,n,r,i=null)=>e(e=>{let a=e.tabs[t]??[];return{tabs:{...e.tabs,[t]:d(a,n,{error:r,errorSql:r?i:null,...r?{isExecuting:!1}:{}})}}}),setDatabase:(t,n,r)=>e(e=>{let i=e.tabs[t]??[];return{tabs:{...e.tabs,[t]:d(i,n,{database:r})}}}),setExecutionTime:(t,n,r)=>e(e=>{let i=e.tabs[t]??[];return{tabs:{...e.tabs,[t]:d(i,n,{executionTime:r})}}}),addHistory:t=>e(e=>({history:[t,...e.history].slice(0,500)})),recordExecution:({connectionId:e,tabId:n,query:r,database:i,executionTime:o,error:s,kind:c,rowCount:l,affectedRows:u})=>t().addHistory({id:crypto.randomUUID(),query:a(r),database:i,timestamp:Date.now(),executionTime:o,success:!s,connectionId:e,tabId:n??void 0,...s?{error:s}:{},...c?{kind:c}:{},...l==null?{}:{rowCount:l},...u==null?{}:{affectedRows:u}}),clearHistory:()=>e({history:[]}),captureRevision:(e,n,r)=>{let a=t().tabs[e]?.find(e=>e.id===n);a&&(o(e,n),i.getState().capture(e,{docId:n,title:a.title,text:a.query,database:a.database,reason:r}))}}),{name:`planche-query`,storage:n(),version:2,migrate:f,partialize:e=>({tabs:Object.fromEntries(Object.entries(e.tabs).map(([e,t])=>[e,t.map(e=>({...e,isExecuting:!1,results:[],plan:null,graphs:null,error:null,errorSql:null,executionTime:null}))])),activeTabId:e.activeTabId,history:c.getState().persistQueryHistory?e.history.slice(0,l):[]})}));export{p as n,u as t};
1
+ import{r as e}from"./BkIkgVK5.js";import{i as t,t as n}from"./eFSiW0Lh.js";import{a as r,i,k as a,n as o,r as s}from"./DC8XCjJ3.js";import{n as c}from"./DP94Ond0.js";var l=200,u=Object.freeze([]);function d(e,t,n){return e.map(e=>e.id===t?{...e,...n}:e)}function f(e){let t=e;if(delete t.erdOpen,delete t.erdDatabase,t.tabs&&typeof t.tabs==`object`){let e=t.tabs;for(let t of Object.keys(e))e[t]=e[t].map(e=>{if(!Array.isArray(e.results)){let t={...e};return delete t.result,{...t,results:[]}}return e})}return t}var p=e()(t((e,t)=>({tabs:{},activeTabId:{},history:[],addQueryTab:(t,n)=>e(e=>{let r=e.tabs[t]??[];return{tabs:{...e.tabs,[t]:[...r,n]},activeTabId:{...e.activeTabId,[t]:n.id}}}),removeQueryTab:(e,n)=>t().removeQueryTabs(e,[n]),removeQueryTabs:(n,r)=>{for(let e of r)t().captureRevision(n,e,`close`);e(e=>{let t=new Set(r),i=(e.tabs[n]??[]).filter(e=>!t.has(e.id)),a=e.activeTabId[n],o=a&&t.has(a)?i.length>0?i[i.length-1].id:null:a;return{tabs:{...e.tabs,[n]:i},activeTabId:{...e.activeTabId,[n]:o}}})},reorderQueryTab:(t,n,i)=>e(e=>({tabs:{...e.tabs,[t]:r(e.tabs[t]??[],n,i)}})),setActiveQueryTab:(t,n)=>e(e=>({activeTabId:{...e.activeTabId,[t]:n}})),setEditorContent:(n,r,i)=>{e(e=>{let t=e.tabs[n]??[];return{tabs:{...e.tabs,[n]:d(t,r,{query:i})}}});let a=t().tabs[n]?.find(e=>e.id===r);a&&s(n,{docId:r,title:a.title,text:i,database:a.database,reason:`edit`})},setResults:(t,n,r)=>e(e=>{let i=e.tabs[t]??[];return{tabs:{...e.tabs,[t]:d(i,n,{results:r,isExecuting:!1,error:null})}}}),setExecuting:(t,n,r)=>e(e=>{let i=e.tabs[t]??[];return{tabs:{...e.tabs,[t]:d(i,n,{isExecuting:r})}}}),setPlan:(t,n,r)=>e(e=>{let i=e.tabs[t]??[];return{tabs:{...e.tabs,[t]:d(i,n,{plan:r})}}}),setGraphs:(t,n,r)=>e(e=>{let i=e.tabs[t];return i?{tabs:{...e.tabs,[t]:d(i,n,{graphs:r})}}:e}),setError:(t,n,r,i=null)=>e(e=>{let a=e.tabs[t]??[];return{tabs:{...e.tabs,[t]:d(a,n,{error:r,errorSql:r?i:null,...r?{isExecuting:!1}:{}})}}}),setDatabase:(t,n,r)=>e(e=>{let i=e.tabs[t]??[];return{tabs:{...e.tabs,[t]:d(i,n,{database:r})}}}),setExecutionTime:(t,n,r)=>e(e=>{let i=e.tabs[t]??[];return{tabs:{...e.tabs,[t]:d(i,n,{executionTime:r})}}}),addHistory:t=>e(e=>({history:[t,...e.history].slice(0,500)})),recordExecution:({connectionId:e,tabId:n,query:r,database:i,executionTime:o,error:s,kind:c,rowCount:l,affectedRows:u})=>t().addHistory({id:crypto.randomUUID(),query:a(r),database:i,timestamp:Date.now(),executionTime:o,success:!s,connectionId:e,tabId:n??void 0,...s?{error:s}:{},...c?{kind:c}:{},...l==null?{}:{rowCount:l},...u==null?{}:{affectedRows:u}}),clearHistory:()=>e({history:[]}),captureRevision:(e,n,r)=>{let a=t().tabs[e]?.find(e=>e.id===n);a&&(o(e,n),i.getState().capture(e,{docId:n,title:a.title,text:a.query,database:a.database,reason:r}))}}),{name:`planche-query`,storage:n(),version:2,migrate:f,partialize:e=>({tabs:Object.fromEntries(Object.entries(e.tabs).map(([e,t])=>[e,t.map(e=>({...e,isExecuting:!1,results:[],plan:null,graphs:null,error:null,errorSql:null,executionTime:null}))])),activeTabId:e.activeTabId,history:c.getState().persistQueryHistory?e.history.slice(0,l):[]})}));export{p as n,u as t};
@@ -1 +1 @@
1
- import{r as e}from"./hePW80VL.js";import{h as t,n}from"./XzPc-eVf.js";import{l as r,m as i,t as a}from"./CKOS5Y-e.js";import{a as o,i as s,n as c,r as l,t as u}from"./Bz1cma8F.js";import{i as d,n as f}from"./BBSxV90W.js";import{b as p,c as m,d as h}from"./Ca4g4XbM.js";import{c as g,l as _,w as v}from"./B_UAjgBr.js";import{a as y,i as b,n as x,o as S,r as C,t as w}from"./DxuXBECK.js";var T=e(t(),1),E=r(),D={autoComplete:`off`,"data-1p-ignore":!0,"data-lpignore":`true`,"data-bwignore":!0};function O(){let{t:e}=i(),[t,n]=(0,T.useState)(null),[r,y]=(0,T.useState)(!1),[b,x]=(0,T.useState)(`anthropic`),[S,C]=(0,T.useState)(``),[w,O]=(0,T.useState)(``),[k,A]=(0,T.useState)(``),[j,M]=(0,T.useState)(!1),[N,P]=(0,T.useState)([]),[F,I]=(0,T.useState)(!1),[L,R]=(0,T.useState)(!1),[z,B]=(0,T.useState)(null),V=f(e=>e.setAiPreferences),H=(0,T.useCallback)(()=>{h().then(e=>{n(e);let t=f.getState().aiPreferences,r=e.storage!==`none`;x(r?e.provider:t.provider),C(r?e.model:t.model),O((r?e.baseUrl:t.baseUrl)??``),M(r?e.storage===`file`:t.remember),P(e.clis??[]),I(e.anthropicProfile===!0)}).catch(()=>y(!0))},[]);(0,T.useEffect)(H,[H]);let U=(0,T.useCallback)(e=>{x(e),C(t=>d(t,e))},[]),W=(0,T.useCallback)(()=>{R(!0),B(null),p({provider:b,model:S.trim()||void 0,baseUrl:w.trim()||void 0,key:k,remember:j}).then(t=>{n(t),A(``),V({provider:b,model:S.trim()||t.model,baseUrl:w.trim(),remember:j}),B(e(`settings.ai.saved`)),v()}).catch(e=>B(e instanceof Error?e.message:String(e))).finally(()=>R(!1))},[b,S,w,k,j,V,e]),G=(0,T.useCallback)(()=>{R(!0),B(null),m().then(e=>{n(e),A(``),v()}).catch(e=>B(e instanceof Error?e.message:String(e))).finally(()=>R(!1))},[]);if(r)return(0,E.jsx)(`p`,{className:`rounded-md border p-3 text-xs text-muted-foreground`,children:e(`settings.ai.unreachable`)});if(!t)return null;let K=t.fromEnvironment,q=b===`cli`||b===`anthropic-profile`;return(0,E.jsxs)(`div`,{className:`grid gap-3 rounded-md border p-3`,children:[(0,E.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:e(`settings.ai.intro`)}),(0,E.jsx)(`p`,{className:`text-xs`,children:t.storage===`environment`?e(`settings.ai.configuredEnv`):t.storage===`file`?e(t.provider===`cli`||t.provider===`anthropic-profile`?`settings.ai.configuredChoice`:`settings.ai.configuredFile`,{path:t.path,provider:t.provider===`cli`?t.model:e(`settings.ai.profile`)}):t.storage===`session`?e(`settings.ai.configuredSession`):e(`settings.ai.none`)}),!K&&(0,E.jsxs)(E.Fragment,{children:[(0,E.jsxs)(`div`,{className:`grid grid-cols-[1fr_220px] items-center gap-3`,children:[(0,E.jsx)(g,{htmlFor:`ai-provider`,className:`text-sm font-medium`,children:e(`settings.ai.provider`)}),(0,E.jsxs)(u,{value:b,onValueChange:e=>U(e),children:[(0,E.jsx)(s,{id:`ai-provider`,children:(0,E.jsx)(o,{})}),(0,E.jsxs)(c,{children:[(0,E.jsx)(l,{value:`anthropic`,children:`Anthropic`}),(0,E.jsx)(l,{value:`anthropic-profile`,children:e(`settings.ai.profile`)}),(0,E.jsx)(l,{value:`openai`,children:e(`settings.ai.openaiCompatible`)}),(0,E.jsx)(l,{value:`gemini`,children:`Google Gemini`}),(0,E.jsx)(l,{value:`cli`,children:e(`settings.ai.cli`)})]})]})]}),b===`cli`?(0,E.jsxs)(E.Fragment,{children:[(0,E.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:e(`settings.ai.cliHint`)}),N.length===0?(0,E.jsx)(`p`,{className:`rounded-md border p-2 text-xs text-muted-foreground`,children:e(`settings.ai.cliNone`)}):(0,E.jsxs)(`div`,{className:`grid grid-cols-[1fr_220px] items-center gap-3`,children:[(0,E.jsx)(g,{htmlFor:`ai-cli`,className:`text-sm font-medium`,children:e(`settings.ai.cliCommand`)}),(0,E.jsxs)(u,{value:N.includes(S)?S:N[0],onValueChange:C,children:[(0,E.jsx)(s,{id:`ai-cli`,children:(0,E.jsx)(o,{})}),(0,E.jsx)(c,{children:N.map(e=>(0,E.jsx)(l,{value:e,children:e},e))})]})]})]}):(0,E.jsxs)(`div`,{className:`grid gap-3`,children:[b===`anthropic-profile`&&(0,E.jsxs)(E.Fragment,{children:[(0,E.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:e(`settings.ai.profileHint`)}),!F&&(0,E.jsx)(`p`,{className:`rounded-md border p-2 text-xs text-muted-foreground`,children:e(`settings.ai.profileNone`)})]}),(0,E.jsxs)(`div`,{className:`grid grid-cols-[1fr_220px] items-center gap-3`,children:[(0,E.jsx)(g,{htmlFor:`ai-model`,className:`text-sm font-medium`,children:e(`settings.ai.model`)}),(0,E.jsx)(_,{id:`ai-model`,value:S,onChange:e=>C(e.target.value),spellCheck:!1,...D})]})]}),b===`openai`&&(0,E.jsxs)(`div`,{className:`grid grid-cols-[1fr_220px] items-center gap-3`,children:[(0,E.jsxs)(`div`,{className:`grid gap-0.5`,children:[(0,E.jsx)(g,{htmlFor:`ai-base-url`,className:`text-sm font-medium`,children:e(`settings.ai.baseUrl`)}),(0,E.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:e(`settings.ai.baseUrlHint`)})]}),(0,E.jsx)(_,{id:`ai-base-url`,value:w,onChange:e=>O(e.target.value),placeholder:`https://api.openai.com/v1`,spellCheck:!1,...D})]}),q||(0,E.jsxs)(`div`,{className:`grid gap-1`,children:[(0,E.jsx)(g,{htmlFor:`ai-key`,className:`text-sm font-medium`,children:e(`settings.ai.key`)}),(0,E.jsx)(_,{id:`ai-key`,type:`password`,value:k,onChange:e=>A(e.target.value),spellCheck:!1,placeholder:t.configured?`••••••••`:``,...D,autoComplete:`new-password`}),(0,E.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:e(`settings.ai.keyHint`)})]}),q||(0,E.jsxs)(`label`,{htmlFor:`ai-remember`,className:`flex cursor-pointer items-start gap-3 rounded-md border p-3 hover:bg-accent/40`,children:[(0,E.jsx)(`input`,{id:`ai-remember`,type:`checkbox`,checked:j,onChange:e=>M(e.target.checked),className:`mt-0.5 size-4 accent-primary`}),(0,E.jsxs)(`span`,{className:`grid flex-1 gap-0.5`,children:[(0,E.jsx)(`span`,{className:`text-sm font-medium`,children:e(`settings.ai.remember`)}),(0,E.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:e(`settings.ai.rememberHint`,{path:t.path})})]})]}),(0,E.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,E.jsx)(a,{size:`sm`,onClick:W,disabled:L||(b===`cli`?N.length===0:!q&&!k.trim()),children:e(`settings.ai.save`)}),t.configured&&(0,E.jsx)(a,{size:`sm`,variant:`ghost`,onClick:G,disabled:L,children:e(`settings.ai.forget`)}),z&&(0,E.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:z})]})]})]})}function k(){let e=n(e=>e.activeDialog),t=n(e=>e.closeDialog),{t:r}=i();return(0,E.jsx)(w,{open:e===`ai-settings`,onOpenChange:e=>{e||t()},children:(0,E.jsxs)(x,{className:`sm:max-w-[560px]`,children:[(0,E.jsxs)(y,{children:[(0,E.jsx)(S,{children:r(`settings.ai.title`)}),(0,E.jsx)(C,{children:r(`settings.ai.description`)})]}),(0,E.jsx)(O,{}),(0,E.jsx)(b,{children:(0,E.jsx)(a,{onClick:t,children:r(`settings.done`)})})]})})}export{k as AiSettingsDialog};
1
+ import{r as e}from"./hePW80VL.js";import{h as t,n}from"./BkIkgVK5.js";import{l as r,m as i,t as a}from"./C0O3rJzW.js";import{a as o,i as s,n as c,r as l,t as u}from"./CUQISMvX.js";import{i as d,n as f}from"./DP94Ond0.js";import{b as p,c as m,d as h}from"./B49XtolG.js";import{c as g,l as _,w as v}from"./Bg6u9htc.js";import{a as y,i as b,n as x,o as S,r as C,t as w}from"./Cg4DfVr4.js";var T=e(t(),1),E=r(),D={autoComplete:`off`,"data-1p-ignore":!0,"data-lpignore":`true`,"data-bwignore":!0};function O(){let{t:e}=i(),[t,n]=(0,T.useState)(null),[r,y]=(0,T.useState)(!1),[b,x]=(0,T.useState)(`anthropic`),[S,C]=(0,T.useState)(``),[w,O]=(0,T.useState)(``),[k,A]=(0,T.useState)(``),[j,M]=(0,T.useState)(!1),[N,P]=(0,T.useState)([]),[F,I]=(0,T.useState)(!1),[L,R]=(0,T.useState)(!1),[z,B]=(0,T.useState)(null),V=f(e=>e.setAiPreferences),H=(0,T.useCallback)(()=>{h().then(e=>{n(e);let t=f.getState().aiPreferences,r=e.storage!==`none`;x(r?e.provider:t.provider),C(r?e.model:t.model),O((r?e.baseUrl:t.baseUrl)??``),M(r?e.storage===`file`:t.remember),P(e.clis??[]),I(e.anthropicProfile===!0)}).catch(()=>y(!0))},[]);(0,T.useEffect)(H,[H]);let U=(0,T.useCallback)(e=>{x(e),C(t=>d(t,e))},[]),W=(0,T.useCallback)(()=>{R(!0),B(null),p({provider:b,model:S.trim()||void 0,baseUrl:w.trim()||void 0,key:k,remember:j}).then(t=>{n(t),A(``),V({provider:b,model:S.trim()||t.model,baseUrl:w.trim(),remember:j}),B(e(`settings.ai.saved`)),v()}).catch(e=>B(e instanceof Error?e.message:String(e))).finally(()=>R(!1))},[b,S,w,k,j,V,e]),G=(0,T.useCallback)(()=>{R(!0),B(null),m().then(e=>{n(e),A(``),v()}).catch(e=>B(e instanceof Error?e.message:String(e))).finally(()=>R(!1))},[]);if(r)return(0,E.jsx)(`p`,{className:`rounded-md border p-3 text-xs text-muted-foreground`,children:e(`settings.ai.unreachable`)});if(!t)return null;let K=t.fromEnvironment,q=b===`cli`||b===`anthropic-profile`;return(0,E.jsxs)(`div`,{className:`grid gap-3 rounded-md border p-3`,children:[(0,E.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:e(`settings.ai.intro`)}),(0,E.jsx)(`p`,{className:`text-xs`,children:t.storage===`environment`?e(`settings.ai.configuredEnv`):t.storage===`file`?e(t.provider===`cli`||t.provider===`anthropic-profile`?`settings.ai.configuredChoice`:`settings.ai.configuredFile`,{path:t.path,provider:t.provider===`cli`?t.model:e(`settings.ai.profile`)}):t.storage===`session`?e(`settings.ai.configuredSession`):e(`settings.ai.none`)}),!K&&(0,E.jsxs)(E.Fragment,{children:[(0,E.jsxs)(`div`,{className:`grid grid-cols-[1fr_220px] items-center gap-3`,children:[(0,E.jsx)(g,{htmlFor:`ai-provider`,className:`text-sm font-medium`,children:e(`settings.ai.provider`)}),(0,E.jsxs)(u,{value:b,onValueChange:e=>U(e),children:[(0,E.jsx)(s,{id:`ai-provider`,children:(0,E.jsx)(o,{})}),(0,E.jsxs)(c,{children:[(0,E.jsx)(l,{value:`anthropic`,children:`Anthropic`}),(0,E.jsx)(l,{value:`anthropic-profile`,children:e(`settings.ai.profile`)}),(0,E.jsx)(l,{value:`openai`,children:e(`settings.ai.openaiCompatible`)}),(0,E.jsx)(l,{value:`gemini`,children:`Google Gemini`}),(0,E.jsx)(l,{value:`cli`,children:e(`settings.ai.cli`)})]})]})]}),b===`cli`?(0,E.jsxs)(E.Fragment,{children:[(0,E.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:e(`settings.ai.cliHint`)}),N.length===0?(0,E.jsx)(`p`,{className:`rounded-md border p-2 text-xs text-muted-foreground`,children:e(`settings.ai.cliNone`)}):(0,E.jsxs)(`div`,{className:`grid grid-cols-[1fr_220px] items-center gap-3`,children:[(0,E.jsx)(g,{htmlFor:`ai-cli`,className:`text-sm font-medium`,children:e(`settings.ai.cliCommand`)}),(0,E.jsxs)(u,{value:N.includes(S)?S:N[0],onValueChange:C,children:[(0,E.jsx)(s,{id:`ai-cli`,children:(0,E.jsx)(o,{})}),(0,E.jsx)(c,{children:N.map(e=>(0,E.jsx)(l,{value:e,children:e},e))})]})]})]}):(0,E.jsxs)(`div`,{className:`grid gap-3`,children:[b===`anthropic-profile`&&(0,E.jsxs)(E.Fragment,{children:[(0,E.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:e(`settings.ai.profileHint`)}),!F&&(0,E.jsx)(`p`,{className:`rounded-md border p-2 text-xs text-muted-foreground`,children:e(`settings.ai.profileNone`)})]}),(0,E.jsxs)(`div`,{className:`grid grid-cols-[1fr_220px] items-center gap-3`,children:[(0,E.jsx)(g,{htmlFor:`ai-model`,className:`text-sm font-medium`,children:e(`settings.ai.model`)}),(0,E.jsx)(_,{id:`ai-model`,value:S,onChange:e=>C(e.target.value),spellCheck:!1,...D})]})]}),b===`openai`&&(0,E.jsxs)(`div`,{className:`grid grid-cols-[1fr_220px] items-center gap-3`,children:[(0,E.jsxs)(`div`,{className:`grid gap-0.5`,children:[(0,E.jsx)(g,{htmlFor:`ai-base-url`,className:`text-sm font-medium`,children:e(`settings.ai.baseUrl`)}),(0,E.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:e(`settings.ai.baseUrlHint`)})]}),(0,E.jsx)(_,{id:`ai-base-url`,value:w,onChange:e=>O(e.target.value),placeholder:`https://api.openai.com/v1`,spellCheck:!1,...D})]}),q||(0,E.jsxs)(`div`,{className:`grid gap-1`,children:[(0,E.jsx)(g,{htmlFor:`ai-key`,className:`text-sm font-medium`,children:e(`settings.ai.key`)}),(0,E.jsx)(_,{id:`ai-key`,type:`password`,value:k,onChange:e=>A(e.target.value),spellCheck:!1,placeholder:t.configured?`••••••••`:``,...D,autoComplete:`new-password`}),(0,E.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:e(`settings.ai.keyHint`)})]}),q||(0,E.jsxs)(`label`,{htmlFor:`ai-remember`,className:`flex cursor-pointer items-start gap-3 rounded-md border p-3 hover:bg-accent/40`,children:[(0,E.jsx)(`input`,{id:`ai-remember`,type:`checkbox`,checked:j,onChange:e=>M(e.target.checked),className:`mt-0.5 size-4 accent-primary`}),(0,E.jsxs)(`span`,{className:`grid flex-1 gap-0.5`,children:[(0,E.jsx)(`span`,{className:`text-sm font-medium`,children:e(`settings.ai.remember`)}),(0,E.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:e(`settings.ai.rememberHint`,{path:t.path})})]})]}),(0,E.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,E.jsx)(a,{size:`sm`,onClick:W,disabled:L||(b===`cli`?N.length===0:!q&&!k.trim()),children:e(`settings.ai.save`)}),t.configured&&(0,E.jsx)(a,{size:`sm`,variant:`ghost`,onClick:G,disabled:L,children:e(`settings.ai.forget`)}),z&&(0,E.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:z})]})]})]})}function k(){let e=n(e=>e.activeDialog),t=n(e=>e.closeDialog),{t:r}=i();return(0,E.jsx)(w,{open:e===`ai-settings`,onOpenChange:e=>{e||t()},children:(0,E.jsxs)(x,{className:`sm:max-w-[560px]`,children:[(0,E.jsxs)(y,{children:[(0,E.jsx)(S,{children:r(`settings.ai.title`)}),(0,E.jsx)(C,{children:r(`settings.ai.description`)})]}),(0,E.jsx)(O,{}),(0,E.jsx)(b,{children:(0,E.jsx)(a,{onClick:t,children:r(`settings.done`)})})]})})}export{k as AiSettingsDialog};
@@ -1 +1 @@
1
- import{r as e}from"./hePW80VL.js";import{h as t,n}from"./XzPc-eVf.js";import{a as r,l as i,m as a,o,t as s}from"./CKOS5Y-e.js";import{t as c}from"./B3nhMsGp.js";import{a as l}from"./CtXRSNHU.js";import{i as u}from"./BfSKVZnY.js";import{n as d}from"./Cr6Fx4T5.js";import{l as f}from"./CCQZjXae.js";import{It as p,Mt as m,_t as h,c as g,ht as _,lt as v}from"./B_UAjgBr.js";import{a as y,i as b,n as x,o as S,t as C}from"./DxuXBECK.js";import{n as w,t as T}from"./rcI4Fmt0.js";var E=r(`globe`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`path`,{d:`M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20`,key:`13o1zl`}],[`path`,{d:`M2 12h20`,key:`9i4pu4`}]]),D=r(`user-plus`,[[`path`,{d:`M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2`,key:`1yyitq`}],[`circle`,{cx:`9`,cy:`7`,r:`4`,key:`nufk8`}],[`line`,{x1:`19`,x2:`19`,y1:`8`,y2:`14`,key:`1bvyxn`}],[`line`,{x1:`22`,x2:`16`,y1:`11`,y2:`11`,key:`1shjgl`}]]),O=e(t(),1),k=i();function A({databases:e,tables:t,onSelectScope:n}){let{t:r}=a(),[i,s]=(0,O.useState)(new Set),[c,l]=(0,O.useState)(`global`),u=(0,O.useCallback)(e=>{s(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})},[]),d=[{id:`global`,text:r(`user.grantTree.globalPrivileges`),type:`global`,children:e.map(e=>({id:`db:${e}`,text:e,type:`database`,database:e,children:(t[e]??[]).map(t=>({id:`tbl:${e}.${t}`,text:t,type:`table`,database:e,table:t}))}))}];function f(e){l(e.id),n({level:e.type,database:e.database,table:e.table})}function g(e,t){let n=e.children&&e.children.length>0,r=i.has(e.id),a=c===e.id,s=E;return e.type===`database`&&(s=m),e.type===`table`&&(s=h),(0,k.jsxs)(`div`,{children:[(0,k.jsxs)(`div`,{className:o(`flex items-center gap-1 px-2 py-0.5 cursor-pointer text-sm hover:bg-accent rounded-sm`,a&&`bg-accent text-accent-foreground`),style:{paddingLeft:`${t*16+4}px`},onClick:()=>{f(e),n&&u(e.id)},children:[n?(0,k.jsx)(p,{className:o(`h-3 w-3 transition-transform shrink-0`,r&&`rotate-90`)}):(0,k.jsx)(`span`,{className:`w-3 shrink-0`}),(0,k.jsx)(s,{className:`h-4 w-4 text-muted-foreground shrink-0`}),(0,k.jsx)(`span`,{className:`truncate`,children:e.text})]}),r&&e.children?.map(e=>g(e,t+1))]},e.id)}return(0,k.jsx)(v,{className:`h-full`,children:(0,k.jsx)(`div`,{className:`py-1`,children:d.map(e=>g(e,0))})})}var j={Data:[`SELECT`,`INSERT`,`UPDATE`,`DELETE`],Structure:[`CREATE`,`ALTER`,`DROP`,`INDEX`,`REFERENCES`],Administration:[`GRANT OPTION`,`SUPER`,`PROCESS`,`RELOAD`,`SHUTDOWN`,`SHOW DATABASES`,`LOCK TABLES`,`EXECUTE`,`REPLICATION SLAVE`,`REPLICATION CLIENT`,`CREATE VIEW`,`SHOW VIEW`,`CREATE ROUTINE`,`ALTER ROUTINE`,`CREATE USER`,`EVENT`,`TRIGGER`,`CREATE TABLESPACE`]},M={Data:[`SELECT`,`INSERT`,`UPDATE`,`DELETE`],Structure:[`CREATE`,`ALTER`,`DROP`,`INDEX`,`REFERENCES`],Administration:[`GRANT OPTION`,`LOCK TABLES`,`EXECUTE`,`CREATE VIEW`,`SHOW VIEW`,`CREATE ROUTINE`,`ALTER ROUTINE`,`EVENT`,`TRIGGER`]},N={Data:[`SELECT`,`INSERT`,`UPDATE`,`DELETE`],Structure:[`CREATE`,`ALTER`,`DROP`,`INDEX`,`REFERENCES`],Administration:[`GRANT OPTION`,`TRIGGER`]},P={global:`user.privileges.globalTitle`,database:`user.privileges.databaseTitle`,table:`user.privileges.tableTitle`},F={Data:`user.privileges.categoryData`,Structure:`user.privileges.categoryStructure`,Administration:`user.privileges.categoryAdministration`};function I({scope:e,privileges:t,onChange:n}){let{t:r}=a(),i=(0,O.useMemo)(()=>e===`global`?j:e===`database`?M:N,[e]),o=(0,O.useMemo)(()=>Object.values(i).flat(),[i]);function c(e){n({...t,[e]:!t[e]})}function l(){let e={...t};for(let t of o)e[t]=!0;n(e)}function u(){let e={...t};for(let t of o)e[t]=!1;n(e)}return(0,k.jsxs)(`div`,{className:`flex flex-col h-full`,children:[(0,k.jsxs)(`div`,{className:`flex items-center gap-2 p-2 border-b`,children:[(0,k.jsx)(`span`,{className:`text-sm font-medium`,children:r(P[e])}),(0,k.jsxs)(`div`,{className:`ml-auto flex gap-1`,children:[(0,k.jsx)(s,{variant:`outline`,size:`sm`,onClick:l,children:r(`user.privileges.checkAll`)}),(0,k.jsx)(s,{variant:`outline`,size:`sm`,onClick:u,children:r(`user.privileges.uncheckAll`)})]})]}),(0,k.jsx)(v,{className:`flex-1`,children:(0,k.jsx)(`div`,{className:`p-3 space-y-4`,children:Object.entries(i).map(([e,n])=>(0,k.jsxs)(`div`,{children:[(0,k.jsx)(`h4`,{className:`text-xs font-semibold text-muted-foreground uppercase tracking-wider mb-2`,children:F[e]?r(F[e]):e}),(0,k.jsx)(`div`,{className:`grid grid-cols-2 gap-1`,children:n.map(e=>(0,k.jsxs)(g,{className:`flex items-center gap-2 text-sm font-normal cursor-pointer py-1`,children:[(0,k.jsx)(`input`,{type:`checkbox`,checked:t[e]??!1,onChange:()=>c(e),className:`rounded border-input`}),e]},e))})]},e))})})]})}var L={SELECT:`Select_priv`,INSERT:`Insert_priv`,UPDATE:`Update_priv`,DELETE:`Delete_priv`,CREATE:`Create_priv`,ALTER:`Alter_priv`,DROP:`Drop_priv`,INDEX:`Index_priv`,REFERENCES:`References_priv`,"GRANT OPTION":`Grant_priv`,SUPER:`Super_priv`,PROCESS:`Process_priv`,RELOAD:`Reload_priv`,SHUTDOWN:`Shutdown_priv`,"SHOW DATABASES":`Show_db_priv`,"LOCK TABLES":`Lock_tables_priv`,EXECUTE:`Execute_priv`,"REPLICATION SLAVE":`Repl_slave_priv`,"REPLICATION CLIENT":`Repl_client_priv`,"CREATE VIEW":`Create_view_priv`,"SHOW VIEW":`Show_view_priv`,"CREATE ROUTINE":`Create_routine_priv`,"ALTER ROUTINE":`Alter_routine_priv`,"CREATE USER":`Create_user_priv`,EVENT:`Event_priv`,TRIGGER:`Trigger_priv`,"CREATE TABLESPACE":`Create_tablespace_priv`,"CREATE TEMPORARY TABLES":`Create_tmp_table_priv`,FILE:`File_priv`};function R(e){let t={};for(let n of e.split(`,`)){let e=n.trim().toUpperCase();e&&(t[e]=!0)}return t}function z(e){let t={};for(let[n,r]of Object.entries(L)){let i=e[r];i!==void 0&&(t[n]=String(i).toUpperCase()===`Y`)}return t}function B(e,t){let n=t=>e.quoteIdentifier(t);return t.level===`global`?`*.*`:t.level===`database`?`${n(t.database??``)}.*`:`${n(t.database??``)}.${n(t.table??``)}`}async function V(e,t,n,r,i){if(i.level===`global`){let i=await e(t.getQuery(`USER_PRIV`,n,r)),a=u(i)[0];return a?z(a):{}}if(i.level===`database`){let a=await e(t.getQuery(`USER_DATABASE_PRIV`,n,r)),o=u(a).find(e=>String(e.Db)===i.database);return o?z(o):{}}let a=await e(t.getQuery(`USER_TABLE_PRIV`,n,r)),o=u(a).find(e=>String(e.Db)===i.database&&String(e.Table_name)===i.table);return o?R(String(o.Table_priv??``)):{}}function H(e,t,n,r,i,a){let o=B(e,r),s=[],c=[],l=null;for(let e of new Set([...Object.keys(i),...Object.keys(a)])){let t=i[e]===!0,n=a[e]===!0;if(t!==n){if(e===`GRANT OPTION`){l=n;continue}(n?s:c).push(e)}}let u=[];if(s.length>0||l===!0){let r=s.length>0?s.join(`, `):`USAGE`;u.push(e.getQuery(`GRANT`,r,t,n,o,l===!0?`WITH GRANT OPTION`:``))}return c.length>0&&u.push(e.getQuery(`REVOKE`,c.join(`, `),t,n,o)),l===!1&&u.push(e.getQuery(`REVOKE`,`GRANT OPTION`,t,n,o)),u}function U(e){return c.getState().activeConnections.find(t=>t.id===e)?.serverConnectionId??null}function W(){let{t:e}=a(),{activeDialog:t,closeDialog:r,openDialog:i,setFooterMessage:u}=n(),p=c(e=>e.activeConnectionId)??``,m=w(e=>e.users[p]??T),h=w(e=>e.selectedUser[p]??null),g=w(e=>e.setSelectedUser),E=w(e=>e.removeUser),j=e=>g(p,e),M=(e,t)=>E(p,e,t),[N,P]=(0,O.useState)({level:`global`}),[F,L]=(0,O.useState)({}),[R,z]=(0,O.useState)([]),[B,W]=(0,O.useState)({}),[G,K]=(0,O.useState)({}),[q,J]=(0,O.useState)(!1),Y=t===`user-manager`;(0,O.useEffect)(()=>{if(!Y||!p)return;let e=U(p);if(!e)return;let t=!1;return d(p).introspect.listDatabases(l(e)).then(e=>{t||z(e)}).catch(()=>{t||z([])}),()=>{t=!0}},[Y,p]),(0,O.useEffect)(()=>{let e=N.database;if(!Y||!p||!e||B[e])return;let t=U(p);if(!t)return;let n=!1;return d(p).introspect.listTables(l(t),e).then(t=>{n||W(n=>({...n,[e]:t.map(e=>e.name)}))}).catch(()=>void 0),()=>{n=!0}},[Y,p,N.database,B]),(0,O.useEffect)(()=>{if(!Y||!p||!h){K({}),L({});return}let e=U(p);if(!e)return;let t=!1;return V(l(e),d(p),h.user,h.host,N).then(e=>{t||(K(e),L(e))}).catch(()=>{t||(K({}),L({}))}),()=>{t=!0}},[Y,p,h,N]);function X(e){e||(r(),j(null),P({level:`global`}),L({}))}let Z=(0,O.useCallback)(e=>{P(e),L({})},[]);function Q(){i(`user-add`)}async function $(){if(!h||!p)return;let{user:t,host:n}=h;J(!0);try{await f(p,d(p).getQuery(`DELETE_USER`,t,n)),M(n,t),j(null),u(e(`user.manager.removed`,{user:t,host:n}))}catch(e){u(e instanceof Error?e.message:String(e))}finally{J(!1)}}async function ee(){if(!h||!p){u(e(`user.manager.selectUserFirst`));return}let t=H(d(p),h.user,h.host,N,G,F);if(t.length===0){u(e(`user.manager.noChanges`));return}J(!0);try{for(let e of t)await f(p,e);K(F),u(e(`user.manager.applied`))}catch(e){u(e instanceof Error?e.message:String(e))}finally{J(!1)}}return(0,k.jsx)(C,{open:Y,onOpenChange:X,children:(0,k.jsxs)(x,{className:`sm:max-w-[80vw] max-h-[70vh] flex flex-col`,children:[(0,k.jsx)(y,{children:(0,k.jsx)(S,{children:e(`user.manager.title`)})}),(0,k.jsxs)(`div`,{className:`flex flex-1 gap-0 overflow-hidden min-h-0 border rounded-md`,children:[(0,k.jsxs)(`div`,{className:`w-[200px] shrink-0 border-r flex flex-col`,children:[(0,k.jsxs)(`div`,{className:`flex items-center gap-1 p-2 border-b`,children:[(0,k.jsx)(s,{variant:`ghost`,size:`sm`,onClick:Q,title:e(`user.manager.addUser`),children:(0,k.jsx)(D,{className:`h-4 w-4`})}),(0,k.jsx)(s,{variant:`ghost`,size:`sm`,onClick:()=>void $(),disabled:!h||q,title:e(`user.manager.removeUser`),children:(0,k.jsx)(_,{className:`h-4 w-4`})})]}),(0,k.jsx)(v,{className:`flex-1`,children:(0,k.jsx)(`div`,{className:`py-1`,children:m.length===0?(0,k.jsx)(`div`,{className:`px-3 py-4 text-sm text-muted-foreground text-center`,children:e(`user.manager.noUsers`)}):m.map(e=>{let t=h?.user===e.user&&h?.host===e.host;return(0,k.jsx)(`div`,{className:o(`flex items-center gap-2 px-3 py-1.5 cursor-pointer text-sm hover:bg-accent`,t&&`bg-accent text-accent-foreground`),onClick:()=>j(e),children:(0,k.jsxs)(`span`,{className:`truncate`,children:[e.user,`@`,e.host]})},`${e.user}@${e.host}`)})})})]}),(0,k.jsxs)(`div`,{className:`w-[250px] shrink-0 border-r`,children:[(0,k.jsx)(`div`,{className:`p-2 border-b text-sm font-medium`,children:e(`user.manager.grantScope`)}),(0,k.jsx)(A,{connectionId:``,databases:R,tables:B,onSelectScope:Z})]}),(0,k.jsx)(`div`,{className:`flex-1 min-w-0`,children:(0,k.jsx)(I,{scope:N.level,privileges:F,onChange:L})})]}),(0,k.jsxs)(b,{children:[(0,k.jsx)(s,{onClick:()=>void ee(),disabled:q,children:e(`user.manager.apply`)}),(0,k.jsx)(s,{variant:`outline`,onClick:()=>X(!1),children:e(`user.manager.close`)})]})]})})}export{W as UserManagerDialog};
1
+ import{r as e}from"./hePW80VL.js";import{h as t,n}from"./BkIkgVK5.js";import{a as r,l as i,m as a,o,t as s}from"./C0O3rJzW.js";import{t as c}from"./DC8XCjJ3.js";import{a as l}from"./Dd9quIZg.js";import{i as u}from"./CYMzEa4j.js";import{n as d}from"./Dht5Mpyb.js";import{l as f}from"./DnJeTfn9.js";import{It as p,Mt as m,_t as h,c as g,ht as _,lt as v}from"./Bg6u9htc.js";import{a as y,i as b,n as x,o as S,t as C}from"./Cg4DfVr4.js";import{n as w,t as T}from"./1XwwL8xu.js";var E=r(`globe`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`path`,{d:`M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20`,key:`13o1zl`}],[`path`,{d:`M2 12h20`,key:`9i4pu4`}]]),D=r(`user-plus`,[[`path`,{d:`M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2`,key:`1yyitq`}],[`circle`,{cx:`9`,cy:`7`,r:`4`,key:`nufk8`}],[`line`,{x1:`19`,x2:`19`,y1:`8`,y2:`14`,key:`1bvyxn`}],[`line`,{x1:`22`,x2:`16`,y1:`11`,y2:`11`,key:`1shjgl`}]]),O=e(t(),1),k=i();function A({databases:e,tables:t,onSelectScope:n}){let{t:r}=a(),[i,s]=(0,O.useState)(new Set),[c,l]=(0,O.useState)(`global`),u=(0,O.useCallback)(e=>{s(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})},[]),d=[{id:`global`,text:r(`user.grantTree.globalPrivileges`),type:`global`,children:e.map(e=>({id:`db:${e}`,text:e,type:`database`,database:e,children:(t[e]??[]).map(t=>({id:`tbl:${e}.${t}`,text:t,type:`table`,database:e,table:t}))}))}];function f(e){l(e.id),n({level:e.type,database:e.database,table:e.table})}function g(e,t){let n=e.children&&e.children.length>0,r=i.has(e.id),a=c===e.id,s=E;return e.type===`database`&&(s=m),e.type===`table`&&(s=h),(0,k.jsxs)(`div`,{children:[(0,k.jsxs)(`div`,{className:o(`flex items-center gap-1 px-2 py-0.5 cursor-pointer text-sm hover:bg-accent rounded-sm`,a&&`bg-accent text-accent-foreground`),style:{paddingLeft:`${t*16+4}px`},onClick:()=>{f(e),n&&u(e.id)},children:[n?(0,k.jsx)(p,{className:o(`h-3 w-3 transition-transform shrink-0`,r&&`rotate-90`)}):(0,k.jsx)(`span`,{className:`w-3 shrink-0`}),(0,k.jsx)(s,{className:`h-4 w-4 text-muted-foreground shrink-0`}),(0,k.jsx)(`span`,{className:`truncate`,children:e.text})]}),r&&e.children?.map(e=>g(e,t+1))]},e.id)}return(0,k.jsx)(v,{className:`h-full`,children:(0,k.jsx)(`div`,{className:`py-1`,children:d.map(e=>g(e,0))})})}var j={Data:[`SELECT`,`INSERT`,`UPDATE`,`DELETE`],Structure:[`CREATE`,`ALTER`,`DROP`,`INDEX`,`REFERENCES`],Administration:[`GRANT OPTION`,`SUPER`,`PROCESS`,`RELOAD`,`SHUTDOWN`,`SHOW DATABASES`,`LOCK TABLES`,`EXECUTE`,`REPLICATION SLAVE`,`REPLICATION CLIENT`,`CREATE VIEW`,`SHOW VIEW`,`CREATE ROUTINE`,`ALTER ROUTINE`,`CREATE USER`,`EVENT`,`TRIGGER`,`CREATE TABLESPACE`]},M={Data:[`SELECT`,`INSERT`,`UPDATE`,`DELETE`],Structure:[`CREATE`,`ALTER`,`DROP`,`INDEX`,`REFERENCES`],Administration:[`GRANT OPTION`,`LOCK TABLES`,`EXECUTE`,`CREATE VIEW`,`SHOW VIEW`,`CREATE ROUTINE`,`ALTER ROUTINE`,`EVENT`,`TRIGGER`]},N={Data:[`SELECT`,`INSERT`,`UPDATE`,`DELETE`],Structure:[`CREATE`,`ALTER`,`DROP`,`INDEX`,`REFERENCES`],Administration:[`GRANT OPTION`,`TRIGGER`]},P={global:`user.privileges.globalTitle`,database:`user.privileges.databaseTitle`,table:`user.privileges.tableTitle`},F={Data:`user.privileges.categoryData`,Structure:`user.privileges.categoryStructure`,Administration:`user.privileges.categoryAdministration`};function I({scope:e,privileges:t,onChange:n}){let{t:r}=a(),i=(0,O.useMemo)(()=>e===`global`?j:e===`database`?M:N,[e]),o=(0,O.useMemo)(()=>Object.values(i).flat(),[i]);function c(e){n({...t,[e]:!t[e]})}function l(){let e={...t};for(let t of o)e[t]=!0;n(e)}function u(){let e={...t};for(let t of o)e[t]=!1;n(e)}return(0,k.jsxs)(`div`,{className:`flex flex-col h-full`,children:[(0,k.jsxs)(`div`,{className:`flex items-center gap-2 p-2 border-b`,children:[(0,k.jsx)(`span`,{className:`text-sm font-medium`,children:r(P[e])}),(0,k.jsxs)(`div`,{className:`ml-auto flex gap-1`,children:[(0,k.jsx)(s,{variant:`outline`,size:`sm`,onClick:l,children:r(`user.privileges.checkAll`)}),(0,k.jsx)(s,{variant:`outline`,size:`sm`,onClick:u,children:r(`user.privileges.uncheckAll`)})]})]}),(0,k.jsx)(v,{className:`flex-1`,children:(0,k.jsx)(`div`,{className:`p-3 space-y-4`,children:Object.entries(i).map(([e,n])=>(0,k.jsxs)(`div`,{children:[(0,k.jsx)(`h4`,{className:`text-xs font-semibold text-muted-foreground uppercase tracking-wider mb-2`,children:F[e]?r(F[e]):e}),(0,k.jsx)(`div`,{className:`grid grid-cols-2 gap-1`,children:n.map(e=>(0,k.jsxs)(g,{className:`flex items-center gap-2 text-sm font-normal cursor-pointer py-1`,children:[(0,k.jsx)(`input`,{type:`checkbox`,checked:t[e]??!1,onChange:()=>c(e),className:`rounded border-input`}),e]},e))})]},e))})})]})}var L={SELECT:`Select_priv`,INSERT:`Insert_priv`,UPDATE:`Update_priv`,DELETE:`Delete_priv`,CREATE:`Create_priv`,ALTER:`Alter_priv`,DROP:`Drop_priv`,INDEX:`Index_priv`,REFERENCES:`References_priv`,"GRANT OPTION":`Grant_priv`,SUPER:`Super_priv`,PROCESS:`Process_priv`,RELOAD:`Reload_priv`,SHUTDOWN:`Shutdown_priv`,"SHOW DATABASES":`Show_db_priv`,"LOCK TABLES":`Lock_tables_priv`,EXECUTE:`Execute_priv`,"REPLICATION SLAVE":`Repl_slave_priv`,"REPLICATION CLIENT":`Repl_client_priv`,"CREATE VIEW":`Create_view_priv`,"SHOW VIEW":`Show_view_priv`,"CREATE ROUTINE":`Create_routine_priv`,"ALTER ROUTINE":`Alter_routine_priv`,"CREATE USER":`Create_user_priv`,EVENT:`Event_priv`,TRIGGER:`Trigger_priv`,"CREATE TABLESPACE":`Create_tablespace_priv`,"CREATE TEMPORARY TABLES":`Create_tmp_table_priv`,FILE:`File_priv`};function R(e){let t={};for(let n of e.split(`,`)){let e=n.trim().toUpperCase();e&&(t[e]=!0)}return t}function z(e){let t={};for(let[n,r]of Object.entries(L)){let i=e[r];i!==void 0&&(t[n]=String(i).toUpperCase()===`Y`)}return t}function B(e,t){let n=t=>e.quoteIdentifier(t);return t.level===`global`?`*.*`:t.level===`database`?`${n(t.database??``)}.*`:`${n(t.database??``)}.${n(t.table??``)}`}async function V(e,t,n,r,i){if(i.level===`global`){let i=await e(t.getQuery(`USER_PRIV`,n,r)),a=u(i)[0];return a?z(a):{}}if(i.level===`database`){let a=await e(t.getQuery(`USER_DATABASE_PRIV`,n,r)),o=u(a).find(e=>String(e.Db)===i.database);return o?z(o):{}}let a=await e(t.getQuery(`USER_TABLE_PRIV`,n,r)),o=u(a).find(e=>String(e.Db)===i.database&&String(e.Table_name)===i.table);return o?R(String(o.Table_priv??``)):{}}function H(e,t,n,r,i,a){let o=B(e,r),s=[],c=[],l=null;for(let e of new Set([...Object.keys(i),...Object.keys(a)])){let t=i[e]===!0,n=a[e]===!0;if(t!==n){if(e===`GRANT OPTION`){l=n;continue}(n?s:c).push(e)}}let u=[];if(s.length>0||l===!0){let r=s.length>0?s.join(`, `):`USAGE`;u.push(e.getQuery(`GRANT`,r,t,n,o,l===!0?`WITH GRANT OPTION`:``))}return c.length>0&&u.push(e.getQuery(`REVOKE`,c.join(`, `),t,n,o)),l===!1&&u.push(e.getQuery(`REVOKE`,`GRANT OPTION`,t,n,o)),u}function U(e){return c.getState().activeConnections.find(t=>t.id===e)?.serverConnectionId??null}function W(){let{t:e}=a(),{activeDialog:t,closeDialog:r,openDialog:i,setFooterMessage:u}=n(),p=c(e=>e.activeConnectionId)??``,m=w(e=>e.users[p]??T),h=w(e=>e.selectedUser[p]??null),g=w(e=>e.setSelectedUser),E=w(e=>e.removeUser),j=e=>g(p,e),M=(e,t)=>E(p,e,t),[N,P]=(0,O.useState)({level:`global`}),[F,L]=(0,O.useState)({}),[R,z]=(0,O.useState)([]),[B,W]=(0,O.useState)({}),[G,K]=(0,O.useState)({}),[q,J]=(0,O.useState)(!1),Y=t===`user-manager`;(0,O.useEffect)(()=>{if(!Y||!p)return;let e=U(p);if(!e)return;let t=!1;return d(p).introspect.listDatabases(l(e)).then(e=>{t||z(e)}).catch(()=>{t||z([])}),()=>{t=!0}},[Y,p]),(0,O.useEffect)(()=>{let e=N.database;if(!Y||!p||!e||B[e])return;let t=U(p);if(!t)return;let n=!1;return d(p).introspect.listTables(l(t),e).then(t=>{n||W(n=>({...n,[e]:t.map(e=>e.name)}))}).catch(()=>void 0),()=>{n=!0}},[Y,p,N.database,B]),(0,O.useEffect)(()=>{if(!Y||!p||!h){K({}),L({});return}let e=U(p);if(!e)return;let t=!1;return V(l(e),d(p),h.user,h.host,N).then(e=>{t||(K(e),L(e))}).catch(()=>{t||(K({}),L({}))}),()=>{t=!0}},[Y,p,h,N]);function X(e){e||(r(),j(null),P({level:`global`}),L({}))}let Z=(0,O.useCallback)(e=>{P(e),L({})},[]);function Q(){i(`user-add`)}async function $(){if(!h||!p)return;let{user:t,host:n}=h;J(!0);try{await f(p,d(p).getQuery(`DELETE_USER`,t,n)),M(n,t),j(null),u(e(`user.manager.removed`,{user:t,host:n}))}catch(e){u(e instanceof Error?e.message:String(e))}finally{J(!1)}}async function ee(){if(!h||!p){u(e(`user.manager.selectUserFirst`));return}let t=H(d(p),h.user,h.host,N,G,F);if(t.length===0){u(e(`user.manager.noChanges`));return}J(!0);try{for(let e of t)await f(p,e);K(F),u(e(`user.manager.applied`))}catch(e){u(e instanceof Error?e.message:String(e))}finally{J(!1)}}return(0,k.jsx)(C,{open:Y,onOpenChange:X,children:(0,k.jsxs)(x,{className:`sm:max-w-[80vw] max-h-[70vh] flex flex-col`,children:[(0,k.jsx)(y,{children:(0,k.jsx)(S,{children:e(`user.manager.title`)})}),(0,k.jsxs)(`div`,{className:`flex flex-1 gap-0 overflow-hidden min-h-0 border rounded-md`,children:[(0,k.jsxs)(`div`,{className:`w-[200px] shrink-0 border-r flex flex-col`,children:[(0,k.jsxs)(`div`,{className:`flex items-center gap-1 p-2 border-b`,children:[(0,k.jsx)(s,{variant:`ghost`,size:`sm`,onClick:Q,title:e(`user.manager.addUser`),children:(0,k.jsx)(D,{className:`h-4 w-4`})}),(0,k.jsx)(s,{variant:`ghost`,size:`sm`,onClick:()=>void $(),disabled:!h||q,title:e(`user.manager.removeUser`),children:(0,k.jsx)(_,{className:`h-4 w-4`})})]}),(0,k.jsx)(v,{className:`flex-1`,children:(0,k.jsx)(`div`,{className:`py-1`,children:m.length===0?(0,k.jsx)(`div`,{className:`px-3 py-4 text-sm text-muted-foreground text-center`,children:e(`user.manager.noUsers`)}):m.map(e=>{let t=h?.user===e.user&&h?.host===e.host;return(0,k.jsx)(`div`,{className:o(`flex items-center gap-2 px-3 py-1.5 cursor-pointer text-sm hover:bg-accent`,t&&`bg-accent text-accent-foreground`),onClick:()=>j(e),children:(0,k.jsxs)(`span`,{className:`truncate`,children:[e.user,`@`,e.host]})},`${e.user}@${e.host}`)})})})]}),(0,k.jsxs)(`div`,{className:`w-[250px] shrink-0 border-r`,children:[(0,k.jsx)(`div`,{className:`p-2 border-b text-sm font-medium`,children:e(`user.manager.grantScope`)}),(0,k.jsx)(A,{connectionId:``,databases:R,tables:B,onSelectScope:Z})]}),(0,k.jsx)(`div`,{className:`flex-1 min-w-0`,children:(0,k.jsx)(I,{scope:N.level,privileges:F,onChange:L})})]}),(0,k.jsxs)(b,{children:[(0,k.jsx)(s,{onClick:()=>void ee(),disabled:q,children:e(`user.manager.apply`)}),(0,k.jsx)(s,{variant:`outline`,onClick:()=>X(!1),children:e(`user.manager.close`)})]})]})})}export{W as UserManagerDialog};
@@ -1,2 +1,2 @@
1
1
  var e={reconnecting:`再接続中…`,dropSqlite:`ドロップして SQLite ファイルを開く`,dropSqliteHint:`WebAssembly でブラウザ内に開かれ、ファイルはお使いのコンピューターから出ません。-wal ファイルがあれば一緒にドロップしてください。`,dropFailedTitle:`ドロップしたファイルを開けませんでした`,dropNotSqlite:`{{name}} は SQLite データベースファイルではありません。`,crashTitle:`問題が発生しました`,crashBody:`予期しないエラーが発生しました。再読み込みすると接続とタブは復元されますが、保存していないグリッドの編集は失われます。`,crashReload:`再読み込み`},t={auto:`システムの言語({{name}})`,en:`English`,ko:`한국어`,zh:`中文(简体)`,ja:`日本語`,de:`Deutsch`,fr:`Français`},n={title:`安全設定`,description:`意図しないデータ損失を防ぐためのガードレールです。読み取り専用、環境カラー、トランザクションモードは接続ごとに設定します。`,language:`言語`,languageHint:`すぐに反映されます。「システム言語」はブラウザの設定に従います。`,resetDefaults:`デフォルトに戻す`,done:`完了`,analytics:`匿名の使用統計を送信する`,analyticsHint:`匿名の使用イベント(エンジン、機能、文の種類)を Google Analytics に送信します。SQL 本文、ホスト名、テーブル名やユーザー名は送信しません。`,analyticsUnavailableHint:`このビルドでは無効です(測定 ID 未設定)。`,persistHistory:`再読み込み後もクエリ履歴を保持`,persistHistoryHint:`文のテキストがこのブラウザに保存されます (パスワードのリテラルはマスク、開いているエディタタブ自体は常に保持)。オフにすると履歴とスナップショットはタブを閉じるまでのみ保持されます。`,ai:{intro:`失敗した文や遅いプランの理由をモデルに尋ねられます。質問はこのアプリで組み立てられ、ローカルエージェントが下記のプロバイダへ送ります — SQL やスキーマが planche.dev に届くことはありません。`,provider:`プロバイダ`,openaiCompatible:`OpenAI 互換`,model:`モデル`,baseUrl:`ベース URL`,baseUrlHint:`空欄ならプロバイダ既定のエンドポイントを使います。OpenAI 互換サーバーなら何でも動きます — Azure、OpenRouter、ローカルの Ollama。`,key:`API キー`,keyHint:`ローカルエージェントに渡され、そこで使われます。このブラウザには保存されず、planche.dev にも送られません。`,remember:`このマシンにキーを記憶する`,rememberHint:`{{path}} に本人だけが読める形で書き込みます。チェックしない場合、キーは実行中のエージェント内にのみ存在し、停止すると消えます。`,save:`保存`,forget:`キーを削除`,saved:`保存しました。`,none:`キーは未設定です。`,configuredSession:`今回のエージェントセッションのみ有効なキーが設定されています。`,configuredFile:`{{path}} にキーが保存されています。`,configuredEnv:`このエージェントの AI 設定は環境変数由来のため、ここでは変更できません。`,unreachable:`エージェントに接続できないため、AI 設定を変更できません。`,title:`AI による説明`,description:`失敗やプランをどのモデルが説明し、誰のキーで支払うか。`,cli:`ローカル CLI(キー不要)`,cliCommand:`コマンド`,cliHint:`このマシンに導入済みでサインイン済みのエージェント CLI を実行するため、入力するキーはありません。失敗やプランの説明に使えます。AI パネルにはツールを呼べる provider が必要です。`,cliNone:`このマシンにエージェント CLI が見つかりません。Claude Code か Codex を入れるか、別の provider を選んでください。`,profile:`Anthropic(このマシンのログイン)`,profileHint:"このマシンが既にサインイン済みの資格情報を使います。`ant auth login` の後は SDK が自動で見つけます。貼り付けるものはなく、ローカル CLI と違い本物の API なので AI パネルも動きます。",profileNone:"このマシンに Anthropic の資格情報が見つかりません。`ant auth login` を実行するか、キーを設定してください。",configuredChoice:`{{provider}} を使用中 — キーは保持せず、選択は {{path}} に保存されます。`},query:{title:`クエリ`,description:`文をどう実行するか: F9 が何を走らせ、何行返し、何を先に確認するか。`},general:{title:`一般`,description:`言語、再読み込みを越えて残るもの、そしてこのマシンを離れるもの。`}},r={settings:{safety:`安全設定…`,language:`言語`,title:`設定`,theme:`テーマ`,query:`クエリ…`,general:`一般…`,ai:`AI…`},help:{gettingStarted:`はじめに`,about:`Planche について`,title:`ヘルプ`,documentation:`ドキュメント`,learn:`SQL を学ぶ`,terms:`利用規約`,license:`ライセンス`,support:`お問い合わせ`,mcp:`AI エージェントを接続 (MCP)…`,privacy:`プライバシーポリシー`},connection:{title:`接続`,connect:`接続`,disconnect:`切断`,readOnly:`読み取り専用`,manualTransactions:`手動トランザクション`,saveDatabaseFile:`データベースファイルを保存`,saveDatabaseFileBlocked:`データベースファイルを保存(先に -wal を読み込んでください)`,exit:`終了`,sync:`接続の同期`},query:{title:`クエリ`,execute:`実行`,executeStatementAtCursor:`カーソル位置のステートメントを実行`,executeWholeScript:`スクリプト全体を実行`,newQueryTab:`新しいクエリタブ`,findReplace:`検索と置換`,localHistory:`ローカル履歴…`,explainPlan:`実行計画を表示`,explainAnalyze:`実行計画を実測 (文を実際に実行)`,structure:`クエリ構造`},edit:{title:`編集`,undo:`元に戻す`,redo:`やり直す`,cut:`切り取り`,copy:`コピー`,paste:`貼り付け`,selectAll:`すべて選択`},database:{title:`データベース`,create:`データベースを作成`,alter:`データベースを変更`,drop:`データベースを削除`,copy:`データベースをコピー`,compare:`スキーマを比較…`,truncate:`データベースを空にする`,compareData:`データを比較…`,groupBy:`グループ集計…`},table:{title:`テーブル`,create:`テーブルを作成`,alter:`テーブルを変更`,drop:`テーブルを削除`,rename:`テーブル名を変更`,truncate:`テーブルを空にする`,duplicateStructure:`テーブル構造を複製`},export:{title:`エクスポート`,csv:`CSV としてダウンロード`,tsv:`TSV でダウンロード`,schemaHtml:`スキーマを HTML に出力`,links:`列リンクをエクスポート…`,importLinks:`列リンクをインポート…`},tools:{title:`ツール`,userManager:`ユーザー管理`,processList:`プロセス一覧`,variables:`変数`,status:`ステータス`,flush:`フラッシュ`,quickCommand:`クイックコマンド`,viewErd:`ERD を表示`,scratchpad:`スクラッチパッド(ブラウザ内 SQLite)`,federated:`統合クエリ(接続をまたぐ結合)…`,federatedTab:`統合クエリ {{n}}`,ai:`AI アシスタント`},messages:{databaseFileSaved:`データベースファイルを保存しました`,databaseExported:`データベースをダウンロードとしてエクスポートしました`,databaseExportedWithReason:`データベースをダウンロードとしてエクスポートしました — {{reason}}`,errorSavingDatabase:`データベースの保存中にエラーが発生しました: {{message}}`,noDatabaseSelected:`データベースが選択されていません`,noTableSelected:`テーブルが選択されていません`,noActiveConnection:`アクティブな接続がありません`,databaseDropped:`データベース "{{database}}" を削除しました`,errorDroppingDatabase:`データベースの削除中にエラーが発生しました: {{message}}`,noTablesInDatabase:`データベース "{{database}}" にテーブルが見つかりません`,databaseTruncated_other:`"{{database}}" の {{count}} 個のテーブルをすべて空にしました`,errorTruncatingDatabase:`データベースを空にする際にエラーが発生しました: {{message}}`,tableDropped:`テーブル "{{table}}" を削除しました`,errorDroppingTable:`テーブルの削除中にエラーが発生しました: {{message}}`,tableTruncated:`テーブル "{{table}}" を空にしました`,errorTruncatingTable:`テーブルを空にする際にエラーが発生しました: {{message}}`,renameTablePrompt:`テーブル "{{table}}" の新しい名前:`,tableRenamed:`テーブル "{{table}}" の名前を "{{newName}}" に変更しました`,errorRenamingTable:`テーブル名の変更中にエラーが発生しました: {{message}}`,truncateDatabaseTitle:`"{{name}}" のすべてのテーブルを空にしますか?`,truncateDatabaseDescription:`"{{name}}" の {{count}} 個のテーブルのすべての行が削除されます。テーブル構造は保持されます。この操作は元に戻せません。`,truncateDatabaseConfirm:`すべてのテーブルを空にする`,renameTableTitle:`テーブル名の変更`,renameTableConfirm:`名前を変更`,noLinksToExport:`エクスポートする列リンクがありません。`,linksExported:`列リンク {{count}} 件をエクスポートしました。`,linksImported:`列リンク {{count}} 件をインポートしました。`,linksImportedPartial:`列リンク {{count}} 件をインポートしました。一致するプロファイルなし: {{profiles}}`,linksImportFailed:`列リンクをインポートできませんでした: {{reason}}`}},i={title:`Planche について`,tagline:`MySQL、MariaDB、PostgreSQL、SQLite 向けのデータベースクライアントです。`,version:`バージョン`,website:`ウェブサイト`,licenses:`ライセンス`,licensesLink:`サードパーティ通知`,disclaimer:`Planche は「現状のまま」提供され、いかなる保証もありません。作者は本ソフトウェアの使用によって生じた損害やデータ損失について一切の責任を負いません。破壊的なステートメントを実行する前にデータをバックアップしてください。`,rights:`All rights reserved.`,legal:`規約`,terms:`利用規約`,privacy:`プライバシー`,refund:`返金`},a=JSON.parse('{"dialog":{"title":"データベースに接続","firstQueryTab":"クエリ 1","colHostName":"接続名","colTarget":"接続先","colDbms":"DBMS","noSaved":"保存された接続はありません","unnamed":"(名前なし)","pickOnConnect":"(接続時に選択)","noFile":"(ファイルなし)","selectPrompt":"接続を選択するか、新しく追加してください","addNew":"新規追加","delete":"削除","testConnection":"接続テスト","connect":"接続","close":"閉じる","unknownError":"不明なエラー","browserTestHint":"ブラウザ内 SQLite 接続は、「接続」をクリックするとローカルファイルを開きます。","testSuccess":"接続に成功しました","restoredUnsaved":"{{file}}: キャッシュされたコピーから未保存の変更を復元しました","restoredUnsavedDiskChanged":"{{file}}: キャッシュされたコピーから未保存の変更を復元しました — ディスク上のファイルはその後変更されています","walPending":"{{file}} は WAL モードです: 最近の変更が -wal ファイルに残っている可能性があります。上の「-wal ファイルを読み込む」で取り込んでください。","walApplied":"{{file}} を -wal の変更を適用して開きました","connectFailedTitle":"接続に失敗しました","testSuccessDescription":"サーバーが認証情報を受け付けました。","testFailedTitle":"接続テストに失敗しました","privacy":"ここに入力した情報が planche.dev のサーバーに送信・保存されることはありません。接続プロファイルはこのブラウザのローカルストレージにのみ保存され、クエリはローカルエージェントからデータベースへ直接送られます。","hostKeyTitle":"不明な SSH ホスト鍵","hostKeyDescription":"{{host}}:{{port}} がフィンガープリント {{fingerprint}} の {{type}} 鍵を提示しました。サーバー管理者から受け取ったフィンガープリントと照合してください。誤った鍵を受け入れると攻撃者に通信を読まれます。","hostKeyAccept":"このホストを信頼する","gatewayTitle":"ゲートウェイのプロファイル","gatewayAdd":"追加","gatewayAdded":"ゲートウェイのプロファイル {{name}} を追加しました。","gatewayReadOnly":"読み取り専用","gatewayWritable":"書き込み可","gatewayProfileHint":"この接続はゲートウェイが保持するプロファイル「{{name}}」を使います。ここで設定するものはありません。","gatewayLoadFailed":"ゲートウェイのプロファイルを読み込めませんでした: {{error}}","export":"エクスポート…","exportWithoutSecrets":"パスワードを含めない","exportWithSecrets":"パスワードと鍵を含める","import":"インポート…","exported":"接続「{{name}}」をエクスポートしました。","imported":"接続「{{name}}」をインポートしました。","importFailedTitle":"接続をインポートできませんでした"},"form":{"hostName":"接続名","hostNamePlaceholder":"My Connection","dataSource":"データソース","openVia":"開く方法","viaBrowser":"ブラウザ(ローカルファイル)","viaAgent":"ローカルエージェント","viaBrowserHint":"インストール不要です。他のプログラムが使用していないファイルに最適です: ブラウザはメモリ上のコピーで作業し、ファイルをロックできないため、開いている間に他で行われた編集は反映されず、保存時に上書きされます。","viaAgentHint":"npx planche 経由で SQLite 自体がファイルを開きます — 適切なロックと WAL に対応し、同じデータベースを使う他のプログラムと安全に共存できます。","databaseFile":"データベースファイル","changeFile":"ファイルを変更","filePickerHint":"「接続」をクリックするとファイル選択ダイアログが開きます(ヒント: ⌘⇧. で隠しファイルを表示、⌘⇧G でパスを入力できます)。","fileRememberedHint":"選択したファイルは記憶される(Chromium)ため、再接続時は権限の確認のみ行われます。変更を書き戻すには「接続 > データベースファイルを保存」を使用してください。","authToken":"認証トークン","authTokenPlaceholder":"空欄でペアリング済みのエージェントトークンを使用","filePathPlaceholder":"/path/to/database.sqlite または :memory:","createIfMissing":"存在しない場合は作成","createIfMissingHint":"パスはトンネリングサーバーのホスト上で解決されます","host":"ホスト","port":"ポート","database":"データベース","serviceName":"サービス名","user":"ユーザー","password":"パスワード","savePassword":"パスワードを保存","savePasswordHint":"オフ: パスワードはこのブラウザセッションの間だけ保持され、ディスクには書き込まれません。","charset":"文字セット","autoConnection":"自動接続","safety":"安全設定","environment":"環境","environmentHint":"タブとワークスペースに色を付けます","readOnly":"読み取り専用","readOnlyHint":"データやスキーマを変更するステートメントを拒否します","transactions":"トランザクション","txAuto":"自動コミット","txManual":"手動 — ツールバーからコミット / ロールバック","ssh":"SSH","sshTunnel":"SSHトンネル","sshTunnelHint":"SSH踏み台ホスト経由でデータベースに接続します(ローカルエージェントがトンネルを開きます)","sshHost":"SSHホスト","sshPort":"SSHポート","sshUser":"SSHユーザー","sshAuth":"SSH認証","sshAuthKey":"秘密鍵","sshAuthPassword":"パスワード","sshAuthAgent":"ssh-agent","sshAuthAgentHint":"npx planche を実行しているマシンの ssh-agent に読み込まれた鍵を使用します(SSH_AUTH_SOCK)。","sshPassword":"SSHパスワード","sshKey":"秘密鍵","sshKeyPick":"鍵ファイルを選択…","sshKeyLoaded":"鍵を読み込み済み","sshKeyHint":"空ならエージェントのマシンの ~/.ssh/config の IdentityFile(または ~/.ssh/id_*)を使用します。選択した鍵はこのプロファイルと共に保存されます","sshPassphrase":"パスフレーズ","sshPassphrasePlaceholder":"鍵にパスフレーズがなければ空のまま","sshSecretsHint":"SSH のパスワード・秘密鍵・パスフレーズは上の「パスワードを保存」設定に従います。不明なホスト鍵は初回接続前に確認用に表示され、エージェントのマシンの ~/.planche/known_hosts に保存されます。","sshHostPlaceholder":"bastion.example.com または ~/.ssh/config の Host エイリアス","sshUserPlaceholder":"空なら ~/.ssh/config の User を使用","sshTargetHint":"DB のホスト/ポートは踏み台ホスト側で解決されます — localhost やローカルポートフォワードではなく、DB の実際のアドレス(例: RDS エンドポイント)を入力してください。","connectionString":"接続文字列","connectionStringApplied":"下のフィールドに反映しました。文字列自体は保存されず、フィールドのみ保存されます。","connectionStringInvalid":"PostgreSQL URI ではありません (postgresql://user:password@host/database の形式)。","neonHint":"Neon コンソール (Connect > Connection string) の URI を貼り付けると、下のフィールドが埋まります。","supabaseHint":"Supabase (Connect > Session pooler または Direct connection) の URI を貼り付けると、下のフィールドが埋まります。","supabasePoolerWarning":"ポート 6543 はトランザクションモードのプーラーです。文ごとに別のバックエンドで実行される可能性があるため、スキーマの切り替え、一時テーブル、プリペアドステートメント、手動トランザクションは動作しません。セッションプーラー (ポート 5432) か直接接続を使ってください。","managedTlsHint":"このサービスへは常に TLS で接続し、ローカルエージェントからサービスへ直接接続します (SSH トンネルなし)。","d1AccountId":"Account ID","d1DatabaseId":"Database ID","d1ApiToken":"API トークン","d1Hint":"Account ID: Cloudflare ダッシュボードのアカウントホーム右側。Database ID: Storage & Databases > D1 > データベース。トークン: My Profile > API Tokens > Create Token で \\"D1 Edit\\" 権限 (読み取り専用は \\"D1 Read\\")。ローカルエージェントがこのトークンで Cloudflare API を呼び出します。","d1LimitsHint":"D1 はリクエストごとに独立して実行され自動コミットされるため、手動トランザクションは使えません。データベースは \\"main\\" スキーマ 1 つとして表示されます。","doDevUrl":"wrangler dev URL","doHint":"Worker プロジェクトで `wrangler dev` を実行し、表示された URL を入力してください (既定のポートは 8787)。ローカルエージェントがそのセッションの Durable Object を読み取ります。同時に動作している他の `wrangler dev` セッションも表示されます。","doLimitsHint":"ローカル開発専用です。デプロイ済みの Durable Object は Worker からしかアクセスできず、Cloudflare は照会 API を提供していません。各オブジェクトは \\"<名前空間>/<オブジェクト>\\" というデータベースとして表示され、リクエストごとに自動コミットされるため手動トランザクションは使えません。","tls":"TLS","tlsEnable":"接続を暗号化","tlsVerify":"サーバー証明書を検証","tlsVerifyHint":"オフ: 自己署名証明書も受け入れます (暗号化はされますがサーバーは認証されません)。SSH トンネル経由では使えません。","d1DevUrl":"ローカル開発 URL","d1DevUrlHint":"空にすると Cloudflare アカウント経由で接続します。入力すると、このマシンで `wrangler dev` が動かしているデータベースを直接読みます — アカウントも API トークンも不要で、下のアカウント欄は無視されます。開発サーバーの D1 が 1 つだけなら Database ID は空のままで構いません。","d1PickDatabase":"データベースを選択"},"agent":{"copy":"コピー","looking":"Planche エージェントを探しています…","online":"エージェント <b>v{{version}}</b> が <mono>{{url}}</mono> で実行中です","outdated":"エージェント v{{version}} はプロトコル {{protocol}} を使用していますが、このアプリにはより新しいものが必要です。<cmd/> で再起動してください","unauthorized":"エージェント <b>v{{version}}</b> が <mono>{{url}}</mono> で実行中ですが、このアプリとペアリングされていません(トークンは起動のたびに変わります)。エージェントのターミナルに表示されたリンクを開くか、「設定」でトークンを貼り付けてください。","offline":"<mono>{{url}}</mono> にエージェントがありません。ターミナルで起動してください — ペアリング済みの状態でこのアプリが開きます。","close":"閉じる","configure":"設定","checkAgain":"再確認","urlLabel":"エージェント URL","urlPlaceholder":"http://127.0.0.1:8888(デフォルト)","tokenLabel":"トークン","tokenPlaceholder":"エージェントが表示したもの","reset":"リセット","save":"保存","remoteWarning":"このエージェントはお使いのコンピューター上にありません ({{host}}): すべての接続のパスワードと SSH 鍵がそこへ送られます。","remoteRefusedTitle":"リモートエージェントは使用できません","remoteRefused":"エージェントはこのコンピューター (127.0.0.1 または localhost) 上で実行する必要があります。別のマシンのエージェントを使うには `ssh -L 8888:127.0.0.1:8888 user@host` でポートを転送し、URL は http://127.0.0.1:8888 のままにしてください。","gateway":"ゲートウェイ「{{name}}」: サーバー側プロファイル {{count}} 件。認証情報はゲートウェイにのみあります。下からプロファイルを選んでください。"},"tab":{"noConnections":"開いている接続はありません。「接続」を押して始めてください。","theSqliteFile":"SQLite ファイル","reopened":"{{file}} を再度開きました","reopenFailed":"ファイルを再度開けませんでした: {{message}}","reopenPrompt":"<b>{{file}}</b> を読み取るには、ブラウザの許可が再度必要です。","reopenFile":"ファイルを再度開く","closeConnection":"接続を閉じる","reconnected":"{{file}} に再接続しました","accessNotGranted":"ファイルへのアクセスが許可されませんでした。保存時はダウンロードとしてエクスポートします。","detachedPrompt":"<b>{{file}}</b> のキャッシュされたコピーで作業しています。変更をその場で保存するにはファイルを再接続してください。","reconnectFile":"ファイルを再接続","detachedHide":"非表示(保存時に必要に応じてファイルを求めます)","walFramesApplied_other":"{{file}}-wal から {{count}} 個の WAL フレームを適用しました","walNoChanges":"-wal ファイルにコミット済みの変更はありませんでした","walLoadFailed":"-wal ファイルを読み込めませんでした: {{message}}","walPrompt":"<b>{{file}}</b> は WAL モードです: <mono>{{file}}-wal</mono> ファイルを読み込むまで最新のデータが表示されない場合があり、それまで保存は無効です。隣にそのようなファイルがない場合(データベースが正常に閉じられた場合)は、代わりにその旨を確認してください。他のプログラムがまだこのデータベースを使用している場合は、代わりにローカルエージェント(<mono>npx planche</mono>)経由で開いてください: ブラウザはファイルを安全に共有できません。","loadWal":"-wal ファイルを読み込む","noWalHint":"確認済み: データベースの隣に -wal ファイルはありません","noWal":"-wal ファイルなし","dismiss":"閉じる","walHide":"非表示(保存は無効のまま)","readOnlyBadge":"読み取り専用"}}'),o={connect:`接続 (Alt+N)`,disconnect:`切断`,newQueryTab:`新しいクエリタブ (Alt+T)`,execute:`実行 (F9)`,executeStatement:`カーソル位置 / 選択範囲のステートメントを実行 (Ctrl+Enter)`,commit:`コミット`,commitHint:`開いているトランザクションをコミットします`,noOpenTransaction:`開いているトランザクションはありません`,rollback:`ロールバック`,rollbackHint:`開いているトランザクションを破棄します`,readOnlyBadge:`読み取り専用`,readOnlyHint:`この接続はデータやスキーマを変更するステートメントを拒否します`,userManager:`ユーザー管理 (Alt+U)`,quickCommand:`クイックコマンド`,processList:`プロセス一覧`,variables:`変数`,status:`ステータス`,flush:`フラッシュ`,fullscreen:`全画面表示`},s={readOnly:`読み取り専用`,txOpen:`トランザクション中`,manualTx:`手動トランザクション`},c={title:`クイックコマンド`,description:`実行するコマンドを検索...`,inputPlaceholder:`コマンドを入力または検索...`,empty:`コマンドが見つかりません。`,groups:{connection:`接続`,query:`クエリ`,database:`データベース`,table:`テーブル`,tools:`ツール`},commands:{connect:`接続`,disconnect:`切断`,executeQuery:`クエリを実行`,newQueryTab:`新しいクエリタブ`,createDatabase:`データベースを作成`,dropDatabase:`データベースを削除`,createTable:`テーブルを作成`,alterTable:`テーブルを変更`,dropTable:`テーブルを削除`,processList:`プロセス一覧`,serverVariables:`サーバー変数`,serverStatus:`サーバーステータス`,flush:`フラッシュ`,userManager:`ユーザー管理`}},l={title:`Planche へようこそ`,intro:`ブラウザで動作する SQL クライアントです。データベースにはお使いのマシン上の小さなエージェントを通じてアクセスするため、認証情報やデータがコンピューターの外に出ることはありません。`,skip:`スキップ`,skipTitle:`この画面を非表示にします(「ヘルプ > はじめに」で再表示できます)`,copy:`コピー`,copied:`コピーしました`,sampleOpenFailed:`サンプルデータベースを開けませんでした: {{message}}`,steps:{agent:{title:`ローカルエージェントを実行する`,body:`ターミナルで次のいずれかを実行します。エージェントが起動し、このページとペアリングされます。`},connection:{title:`接続を追加する`,body:`データベースを選ぶと、適切なデフォルト値で接続フォームが開きます。`},sample:{title:`手元にデータベースがない場合はサンプルをお試しください`,body:`サンプルのウェブショップデータベース(24 テーブル、約 5 万行、ビューとトリガー)をブラウザに読み込み、エディター、グリッド、スキーマツリーを試せます。`,loading:`サンプルを読み込み中…`,button:`サンプルデータベースを試す`}},terms:{title:`はじめる前に`,local:`すべてローカルで動作します。認証情報、クエリ、結果はお使いのコンピュータにのみ保存され、当方へ送信されることはありません。`,asIs:`Planche は現状有姿で提供され、いかなる保証もありません。安全機能(破壊的操作の確認、読み取り専用モード)は補助的なものであり、保証ではありません。`,dataLoss:`Planche を通じて実行されるすべての文の責任はユーザーにあります。破壊的な操作を行う前に必ずデータをバックアップしてください。`,agree:`利用規約を読み、同意します。`,accepted:`利用規約に同意済みです。`,readFull:`規約の全文を読む`}},u={treeLabel:`スキーマ`,unreachableHint:`この接続に紐付いたデータベースではありません。閲覧するにはそのデータベース用のプロファイルを作成してください`,objectType:{table:`テーブル`,view:`ビュー`,procedure:`プロシージャ`,function:`関数`,trigger:`トリガー`,event:`イベント`},menu:{showCreate:`{{type}}の CREATE 文を表示`,alter:`{{type}}を変更`,drop:`{{type}}を削除`,create:`{{type}}を作成`,refresh:`更新`,unreachable:`このデータベースを閲覧するには、これに紐付いたプロファイルで接続してください`,openDatabase:`データベースを開く`,createSchema:`スキーマを作成…`,createTable:`テーブルを作成`,dropDatabase:`データベースを削除`,openSchema:`スキーマを開く`,dropSchema:`スキーマを削除`,newQueryTab:`新しいクエリタブ`,generateSql:`SQL を生成`,openTable:`テーブルを開く`,alterTable:`テーブルを変更`,showCreateTable:`CREATE TABLE 文を表示`,duplicateStructure:`構造を複製`,copyTable:`別の場所へテーブルをコピー…`,compare:`{{type}}を比較…`,truncateTable:`テーブルを空にする`,dropTable:`テーブルを削除`,exportCsv:`CSV にエクスポート`,exportTsv:`TSV でエクスポート…`,openView:`ビューを開く`,alterView:`ビューを変更`,showCreateView:`CREATE VIEW 文を表示`,dropView:`ビューを削除`,compareData:`データを比較…`,groupBy:`グループ集計…`},actions:{createStatementUnavailable:`-- {{type}} {{name}} の CREATE 文を取得できませんでした`,getCreateFailed:`CREATE {{type}} の取得に失敗しました: {{message}}`,createTabTitle:`{{type}}を作成`,createSchemaTabTitle:`スキーマを作成`,generateSqlFailed:`SQL を生成できませんでした: {{message}}`,dropTableTitle:`テーブル "{{name}}" を削除しますか?`,dropTableDescription:`{{from}}テーブルとそのすべての行が完全に削除されます。この操作は元に戻せません。`,dropTableConfirm:`テーブルを削除`,dropObjectTitle:`{{type}} "{{name}}" を削除しますか?`,dropObjectDescription:`{{from}}{{type}}の定義が削除されます。この操作は元に戻せません。`,dropObjectConfirm:`{{type}}を削除`,fromDatabase:`データベース "{{database}}" から`,dropped:`{{type}} {{name}} を削除しました`,dropFailed:`{{type}}の削除に失敗しました`,dropDatabaseTitle:`データベース "{{name}}" を削除しますか?`,dropDatabaseDescription:`データベースとそのすべてのテーブルおよびデータが完全に削除されます。この操作は元に戻せません。`,dropDatabaseConfirm:`データベースを削除`,droppedDatabase:`データベース {{name}} を削除しました`,dropDatabaseFailed:`データベースの削除に失敗しました`,dropSchemaTitle:`スキーマ "{{name}}" を削除しますか?`,dropSchemaDescription:`スキーマとそのすべてのテーブルおよびデータが完全に削除されます。この操作は元に戻せません。`,dropSchemaConfirm:`スキーマを削除`,droppedSchema:`スキーマ {{name}} を削除しました`,dropSchemaFailed:`スキーマの削除に失敗しました`,truncateTitle:`テーブル "{{name}}" を空にしますか?`,truncateDescription:`"{{name}}" のすべての行が削除されます。テーブル構造は保持されます。この操作は元に戻せません。`,truncateConfirm:`テーブルを空にする`,truncated:`{{name}} を空にしました`,truncateFailed:`テーブルを空にできませんでした`},tree:{loadDatabasesFailed:`データベースの読み込みに失敗しました: {{message}}`}},d={editor:{destructiveMarker:`破壊的操作: {{action}} {{names}}`,readOnlyMarker:`接続は読み取り専用です。このステートメントはデータまたはスキーマを変更します`,actionExecute:`実行(設定に従う)`,actionExecuteStatement:`カーソル位置 / 選択範囲のステートメントを実行`,actionExecuteScript:`スクリプト全体を実行`,actionExplainPlan:`実行計画を表示`,actionQueryStructure:`クエリ構造`},tabs:{newQuery:`新しいクエリ`,queryTitle:`クエリ {{n}}`,erdViewer:`ERD ビューアー`,close:`閉じる`,closeOthers:`他のタブを閉じる`,closeLeft:`左側のタブを閉じる`,closeRight:`右側のタブを閉じる`,closeAll:`すべて閉じる`},executor:{noActiveConnection:`アクティブな接続がありません`,uncommittedTitle:`未コミットのトランザクション`,uncommittedDescription:`この接続には開いているトランザクションがあります。切断するとその変更はロールバックされます。`,uncommittedConfirm:`ロールバックして切断`,unsavedTitle:`未保存の変更`,unsavedDescription:`{{file}} にはファイルに保存されていない変更があります。切断するとそれらは破棄されます(保持するには先に「接続 > データベースファイルを保存」を使用してください)。`,theSqliteDatabase:`SQLite データベース`,unsavedConfirm:`破棄して切断`}},f=JSON.parse('{"tabs":{"message":"メッセージ","info":"情報","history":"履歴","result":"結果","resultN":"結果 {{n}}","plan":"実行計画","structure":"構造","structureN":"構造 {{n}}"},"message":{"executing":"クエリを実行中...","error":"エラー: {{message}}","total":"(合計: {{ms}}ms)","ready":"準備完了。","log":"実行ログ","statementN":"文 {{n}}","limitedBadge":"上限到達","insertId":"insert id {{id}}","failed":"失敗","failedStatement":"失敗した文","summary":"成功 {{ok}} · 失敗 {{failed}} · 合計 {{ms}}","copy":"コピー","copied":"コピー済み","showSql":"SQL を表示","hideSql":"SQL を隠す"},"hints":{"title":"ヒント","unknownColumn":"{{name}} という列はありません。{{suggestions}} ではありませんか?","unknownTable":"{{name}} というテーブルはありません。{{suggestions}} ではありませんか?","syntaxSwap":"{{engine}} では {{found}} ではなく {{expected}} を使います。","doubleQuotedLiteral":"{{engine}} は \\"{{value}}\\" を文字列ではなく列名として読みます。文字列は \'{{value}}\' と書きます。"},"ai":{"title":"AI による説明","explain":"AI に説明してもらう","thinking":"失敗を読んでいます…","by":"{{model}}","applyFix":"修正文を新しいタブで開く","failed":"説明できませんでした: {{message}}","noFailure":"説明する失敗した文がありません。","noPack":"planche.dev からプロンプトを取得できませんでした。","badShape":"モデルが想定した形式で応答しませんでした。","noPlan":"説明するプランがまだありません。","explainPlan":"このプランを説明してもらう"},"info":{"empty":"クエリ情報はありません。","resultN":"結果 {{n}}","metadata":"クエリのメタデータ","executionTime":"実行時間","notAvailable":"N/A","affectedRows":"影響を受けた行数","fields":"フィールド","fieldDetails":"フィールドの詳細","colName":"名前","colType":"型","colTable":"テーブル","resultSets":"結果セット","rowsReturned":"返された行","insertId":"最後の Insert ID","lastQuery":"最後に実行した文","copy":"コピー","copied":"コピー済み","colOrigin":"元の名前","primaryKey":"主キー","rowsAndFields":"{{rows}}行 × {{fields}}列","noFields":"この文は列を返しませんでした。"},"rowForm":{"colColumn":"列","colValue":"値","insertTitle":"行を追加","editTitle":"行を編集","loading":"列情報を読み込み中...","preview":"実行される文","nothingToWrite":"書き込む内容がありません","insert":"挿入","update":"更新","stageInsert":"保留行として追加","stageEdit":"グリッドに反映","stageHint":"実行せずにグリッドへ値を置き、後で他の編集と一緒にコミットします。","inserted":"{{table}} に行を挿入しました","updated":"{{table}} の行を更新しました","confirmInsertTitle":"{{table}} に行を挿入しますか?","confirmUpdateTitle":"{{table}} の行を更新しますか?","inTransaction":"開いているトランザクション内で実行されます","pickDate":"日付を選択","now":"現在時刻","formatJson":"整形","binaryUnsupported":"バイナリ列はここでは編集できません。NULL/DEFAULT のままにするか SQL で設定してください。","generateUuid":"UUID を生成","defaultValue":"デフォルト値","clickToChange":"クリックして変更","empty":"(空)","autoHint":"サーバーが自動生成","mode":{"keep":"維持","auto":"自動","value":"値"},"invalid":{"integer":"整数を入力してください","unsigned":"この列は負の数を受け付けません","number":"数値を入力してください","json":"不正な JSON","date":"YYYY-MM-DD 形式で入力してください","datetime":"YYYY-MM-DD HH:MM:SS 形式で入力してください","time":"HH:MM:SS 形式で入力してください","length":"最大 {{max}} 文字"}},"history":{"copied":"クリップボードにコピーしました","searchPlaceholder":"履歴を検索...","all":"すべて","success":"成功","failed":"失敗","thisTab":"このタブのみ","noMatch":"一致する項目がありません。","count":"{{count}}件","clear":"消去","clearTitle":"クエリ履歴を消去しますか?","clearDescription":"この接続の {{count}} 件がすべて削除されます。元に戻せません。","clearConfirm":"履歴を消去","insert":"エディターに挿入","inserted":"エディターに挿入しました","copy":"コピー","rows":"{{count}}行","affected":"{{count}}行変更","today":"今日","yesterday":"昨日","empty":"クエリ履歴はありません。"},"json":{"arrayLength":"Array[{{count}}]","keys_other":"{{count}} 個のキー","invalid":"無効な JSON","clickToView":"クリックして JSON を表示","expandAll":"すべて展開","collapseAll":"すべて折りたたむ","edit":"編集","view":"表示","copied":"コピーしました","copy":"コピー","shortcutHint":"{{mod}}+Enter で保存 · Esc でキャンセル","cancel":"キャンセル","save":"保存"},"text":{"clickToView":"クリックしてテキストを表示","size":"{{chars}}文字 · {{lines}}行","wrap":"折り返し"},"grid":{"readOnlyConnection":"読み取り専用の接続","readOnlyWal":"読み取り専用: -wal ファイルが読み込まれていません","readOnlyNoPk":"読み取り専用: テーブルに主キーがありません","commitTitle":"{{count}} 件の変更を {{table}} にコミットしますか?","commitDescription":"次のステートメントが実行されます。","commitConfirm":"コミット","rowPrefix":"行 {{row}}:","cancelled":"キャンセルされました","commitFailed":"コミットに失敗しました: {{message}}","executedInTransaction":"開いているトランザクション内で {{count}} 件の変更を実行しました — 確定するにはツールバーの「コミット」を押してください(再読み込みするとロールバックされます)","committed":"{{count}} 件の変更を {{table}} にコミットしました","noData":"表示するデータがありません。","commit":"コミット","discard":"破棄","addRow":"行を追加","removeNewRow":"この新しい行を取り消す","addRowForm":"フォームで追加","addRowFormHint":"列ごとの入力欄を持つフォームを開きます (INSERT としてコミット)","editRowForm":"この行をフォームで編集","addRowHint":"新しい行を追加します(INSERT としてコミット)","delete":"削除","deleteCount":"削除 ({{count}})","deleteHint":"選択した行を削除します(DELETE としてコミット)。行番号の列で行を選択してください。","field":"フィールド","searchPlaceholder":"検索...","orderBy":"並び順","none":"なし","refresh":"更新","dismiss":"閉じる","clearSelection":"選択を解除","columns":"列","showAllColumns":"すべて表示","hideAllColumns":"すべて非表示","resetWidths":"幅をリセット","selectAll":"すべての行を選択","emptyTable":"このテーブルには行がありません。","noRows":"行は返されませんでした。","addARow":"行を追加","markedForDeletion":"削除予定 — クリックで元に戻す","newRow":"新しい行","clickToSelect":"クリックで選択、Shift/Ctrl で複数選択","rows":"行数: {{count}}","rowsWithNew":"行数: {{count}} (+{{added}})","sortedBy":"並び順: {{column}} {{direction}}","pageRange":"{{from}}–{{to}} 行","firstPage":"最初のページ","prevPage":"前のページ","nextPage":"次のページ","lastPage":"最後のページ","pagingBlocked":"ページを移動する前に変更をコミットまたは破棄してください","selected":"{{count}} 件選択中","cellsModified":"{{count}} 個のセルを変更","newCount":"{{count}} 件追加","toDelete":"{{count}} 件削除予定","searchMode":"一致方法","contains":"含む","equals":"一致","followLink":"{{table}} を {{column}} = 値 で開く","linkColumn":"「{{column}}」を別のテーブルにリンク…","editLink":"「{{column}}」のリンクを編集…","removeLink":"リンクを削除","copyValue":"値をコピー","filterByValue":"フィルタ: {{column}} = この値","clearFilter":"フィルタを解除","copyColumnName":"列名をコピー","editCell":"セルを編集","setNull":"NULL に設定","setEmpty":"空文字列に設定","restoreRow":"行を復元","hideColumn":"列「{{column}}」を隠す","copyRowsTsv_other":"{{count}} 行を TSV としてコピー(ヘッダー付き)","copyRowsCsv_other":"{{count}} 行を CSV としてコピー","copyRowsJson_other":"{{count}} 行を JSON としてコピー","copyRowsInsert_other":"{{count}} 行を INSERT 文としてコピー","deleteRowsPending_other":"{{count}} 行を削除(コミットまで保留)","sendRowsToScratchpad_other":"{{count}} 行をスクラッチパッドへ送る","sendAllToScratchpad":"読み込み済みの {{count}} 行すべてをスクラッチパッドへ送る","sentToScratchpad":"{{count}} 行をスクラッチパッドのテーブル {{table}} にコピーしました。","changesSince":"前回の読み込み以降: 変更 {{changed}} · 新規 {{added}} · 消失 {{gone}}","changesToggle":"前回の読み込みからの変更のハイライトを切り替え","changesDismiss":"変更表示を消す","previousValue":"以前の値: {{value}}","groupByValue":"{{column}} でグループ集計"},"link":{"title":"列を別のテーブルにリンク","source":"列","hint":"この列の値がリンクになります。クリックすると対象テーブルが一致する行で絞り込まれて開きます。実際の外部キーは自動でリンクされます。","targetDatabase":"対象データベース","targetTable":"対象テーブル","targetColumn":"対象列","pickTable":"テーブルを選択","pickColumn":"列を選択","remove":"リンクを削除","cancel":"キャンセル","save":"リンクを保存","targetConnection":"対象の接続","targetNotConnected":"リンク先の接続が開いていません。先に接続してください。"},"running":{"label":"クエリ実行中…","elapsed":"{{seconds}}秒","stop":"中断","stopping":"中断中…","cannotCancel":"このエンジンは実行中の文を中断できません。","agentOutdated":"ローカルエージェントが古いためクエリを中断できません。`npx planche@latest`(または `planche upgrade`)で更新して再接続してください。","cancelFailed":"エージェントに接続できず、クエリを中断できませんでした。","abandoned":"リクエストの待機を中止しました。このエンジンには取り消し機能がないため、クエリはサーバー側で最後まで実行される場合があります。"},"plan":{"empty":"実行計画を表示 (Ctrl+Shift+E) を実行すると、カーソル位置の文をエンジンがどう処理するかを確認できます。","unreadable":"計画をツリーとして読み取れなかったため、エンジンの出力をそのまま表示します。","estimated":"推定値","analyzed":"実測値","estimatedHint":"オプティマイザの推定値です。文は実行されていません。","analyzedHint":"文を実際に実行しました。行数と時間は実測値です。","totalCost":"最大ノードコスト","totalTime":"最も遅いノード","rows":"推定行数","actualRows":"実際の行数","cost":"コスト","time":"時間","showRaw":"生の出力","showTree":"計画ツリー","selectNode":"ノードを選択すると、エンジンが報告した内容を確認できます。","noDetails":"このノードについて、エンジンからの追加情報はありません。","warnings":{"fullScan":"フルスキャン","noIndex":"インデックスなし","estimateOff":"推定のずれ","temporary":"一時テーブル","filesort":"ソート"},"hints":{"fullScan":"テーブルの全行を読みます。絞り込み列にインデックスがあれば回避できます。","noIndex":"このアクセスに使えるインデックスが見つかりませんでした。","estimateOff":"推定行数が大きく外れています。テーブル統計を更新すると改善することが多いです。","temporary":"次の処理に進む前に、行を一時テーブルに書き出します。","filesort":"インデックスを使わずに並べ替えています。ORDER BY に合うインデックスがあれば不要になります。"}},"structure":{"empty":"クエリ構造を表示 (Ctrl+Shift+G) すると、カーソル位置の文の行がどこから来るか分かります。","notQuery":"SELECT 文のみ構造グラフを描画できます。","unsupported":"{{engine}} の文は構造グラフとして読み取れません。","parseError":"文を解析できませんでした: {{message}}","columns_other":"{{count}} 列","columnsUnknown":"列数不明","fit":"全体に合わせる","reveal":"エディタでこの部分を選択","notDrawn":"未描画: {{what}}","kindTable":"テーブル","kindCte":"CTE","kindCteRef":"参照","kindDerived":"サブクエリ","kindScalar":"スカラー","kindSetop":"集合","kindResult":"結果","fullscreen":"全画面","exitFullscreen":"全画面を終了"}}'),p={defaultDescription:`この操作は元に戻せません。`,typeToConfirm:`確認のため <name/> を入力してください`,cancel:`キャンセル`,confirm:`確認`,ok:`OK`},m={dialog:{createTitle:`テーブルを作成`,alterTitle:`テーブルを変更`,duplicateTitle:`テーブル構造を複製`,create:`作成`,alter:`変更`,cancel:`キャンセル`,tableName:`テーブル名`,tableNamePlaceholder:`テーブル名を入力...`,loading:`テーブルスキーマを読み込み中...`,tabSchema:`スキーマ`,tabIndexes:`インデックス`,tabProperties:`プロパティ`,applying:`適用中…`,cannotAlterColumns:`{{engine}} は既存の列の定義を変更できません({{columns}})。列の追加・削除・名前変更とインデックスの変更は可能です。列の定義を変えるにはテーブルを作り直してください。`},schema:{colField:`フィールド名`,colType:`データ型`,colLength:`長さ`,colDefault:`デフォルト`,colPk:`PK`,colNotNull:`Not Null`,colUnsigned:`Unsigned`,colAutoIncrement:`Auto Incr`,colZerofill:`Zerofill`,colComment:`コメント`,empty:`カラムが定義されていません。「カラムを追加」をクリックして追加してください。`,add:`カラムを追加`,remove:`カラムを削除`},indexes:{colName:`インデックス名`,colType:`インデックスの種類`,colColumns:`カラム`,empty:`インデックスが定義されていません。「インデックスを追加」をクリックして追加してください。`,add:`インデックスを追加`,remove:`インデックスを削除`},index:{addTitle:`インデックスを追加`,editTitle:`インデックスを編集`,name:`インデックス名`,namePlaceholder:`インデックス名を入力`,type:`インデックスの種類`,columns:`カラム`,noColumns:`使用できるカラムがありません。先に「スキーマ」タブでカラムを定義してください。`,unnamed:`(名前なし)`,cancel:`キャンセル`,ok:`OK`},properties:{engine:`エンジン`,charset:`文字セット`,collation:`照合順序`,autoIncrement:`Auto Increment`,autoIncrementPlaceholder:`デフォルト`,comment:`コメント`},info:{engine:`エンジン`,version:`バージョン`,rowFormat:`行フォーマット`,rows:`行数`,avgRowLength:`平均行長`,dataLength:`データサイズ`,createTime:`作成日時`,updateTime:`更新日時`,collation:`照合順序`,comment:`コメント`},copy:{title:`テーブルをコピー`,source:`コピー元`,targetConnection:`コピー先の接続`,targetDatabase:`コピー先データベース`,targetTable:`コピー先テーブル名`,what:`コピー内容`,structureAndData:`構造とデータ`,structureOnly:`構造のみ`,ifExists:`コピー先にテーブルがある場合`,abort:`中止(既定)`,dropAndRecreate:`削除して再作成(名前の再入力で確認)`,preview:`コピー先で実行する CREATE TABLE(編集可)`,crossEngineHint:`コピー先は {{engine}} です。下の型を確認してください。MySQL 固有の属性は除外されました。`,readOnly:`読み取り専用`,loading:`読み込み中…`,progressCreate:`テーブルを作成中…`,progressCount:`行数を確認中…`,progressRows:`{{total}} 行中 {{copied}} 行をコピー済み`,progressDone:`完了`,doneTitle:`テーブルをコピーしました`,doneRows:`{{table}} に {{count}} 行をコピーしました。`,doneStructure:`{{table}} の構造を作成しました。`,noColumns:`コピー元テーブルに列がありません。`,exists:`コピー先に {{table}} が既に存在します。別の名前にするか「削除して再作成」を選んでください。`,dropTitle:`既存のテーブル {{table}} を削除しますか?`,dropDescription:`コピーの前にコピー先テーブルとすべての行が削除されます。元に戻せません。`,dropConfirm:`削除してコピー`,cancelled:`コピーを中止しました。`,stop:`停止`,cancel:`キャンセル`,copy:`コピー`}},h={copy:{title:`データベースをコピー`,source:`コピー元データベース`,target:`コピー先データベース名`,targetPlaceholder:`コピー先のデータベース名を入力`,options:`オプション`,structureAndData:`構造とデータ`,structureOnly:`構造のみ`,cancel:`キャンセル`,copy:`コピー`,creating:`{{database}} を作成中…`,copying:`{{table}} をコピー中 ({{index}}/{{total}})…`},diff:{title:`スキーマを比較`,source:`比較元`,target:`比較先`,pickConnection:`接続`,pickDatabase:`データベース`,crossEngineHint:`エンジンが異なります。型名は方言ごとに違うため、多くの列が型の変更として表示されます。`,sameSide:`比較元と比較先が同じデータベースです。`,summary:`変更 {{changed}}、比較先にない {{missingTarget}}、比較先のみ {{missingSource}}、同一 {{identical}}`,showIdentical:`同一のテーブルを表示`,identicalAll:`テーブルは同一です。`,column:`列`,index:`インデックス`,object:`オブジェクト`,selectTable:`差分を見るテーブルを選択してください。`,missingInTarget:`{{table}} は比較先にありません。スクリプトが作成します。`,missingInSource:`{{table}} は比較先にのみあります。スクリプトが削除します(DROP を含めない限りコメントアウト)。`,includeDrops:`DROP 文を実行可能な SQL として含める(既定: コメントアウト)`,tabTitle:`同期 {{database}}`,close:`閉じる`,compare:`比較`,comparing:`比較中…`,openScript:`スクリプトをエディタで開く`,noDefinition:`CREATE 文を取得できません`},create:{title:`データベースを作成`,name:`データベース名`,namePlaceholder:`データベース名を入力`,charset:`文字セット`,collation:`照合順序`,cancel:`キャンセル`,create:`作成`},csv:{title:`{{format}} でダウンロード`,target:`対象`,targetQueryResult:`現在のクエリ結果`,targetTableData:`テーブルデータ`,tableName:`テーブル名`,tableNamePlaceholder:`テーブル名を入力`,delimiter:`区切り文字`,delimiterComma:`カンマ (,)`,delimiterTab:`タブ (\\t)`,delimiterSemicolon:`セミコロン (;)`,delimiterPipe:`パイプ (|)`,includeHeaders:`ヘッダーを含める`,cancel:`キャンセル`,download:`ダウンロード`,downloading:`ダウンロード中...`,progress:`{{total}} 行中 {{loaded}} 行を書き込み`,progressUnknown:`{{loaded}} 行を書き込み`,stop:`停止`,done:`{{table}} の {{count}} 行を {{format}} にエクスポートしました。`,database:`データベース`,databasePlaceholder:`データベースを選択`},html:{title:`スキーマを HTML に出力`,database:`データベース`,selectDatabase:`データベースを選択`,tables:`含めるテーブル`,selectAll:`すべて選択`,deselectAll:`すべて解除`,noTables:`使用できるテーブルがありません。`,include:`含める項目`,includeColumns:`カラム`,includeIndexes:`インデックス`,includeProperties:`プロパティ`,cancel:`キャンセル`,generate:`生成`,generating:`生成中...`,sectionColumns:`カラム`,sectionIndexes:`インデックス`,sectionProperties:`プロパティ`,docTitle:`スキーマ: {{database}}`,heading:`データベース: {{database}}`,summary:`テーブル数: {{count}} | 生成日時: {{date}}`,footer:`Planche 2026 により生成`},dataDiff:{title:`データを比較`,pickTable:`テーブル`,hint:`比較元テーブルの主キーで行を対応付け、値をテキストとして比較します。片側あたり最大 {{cap}} 行を読み込むので、大きなテーブルは先にフィルタで絞ってください。`,sameSide:`比較元と比較先が同じテーブルです。`,noPrimaryKey:`{{table}} に主キーがないため、行を対応付けできません。`,keyMissingInTarget:`比較先テーブルにキー列がありません: {{columns}}`,summary:`キー: {{key}} — 比較先にない {{added}}、相違 {{changed}}、比較先のみ {{removed}}、同一 {{identical}}`,capped:`両側とも先頭 {{cap}} 行のみ比較しました。`,ignoredColumns:`比較から除外した列(片側のみ): {{columns}}`,added_other:`比較先にない {{count}}`,changed_other:`相違 {{count}}`,removed_other:`比較先のみ {{count}}`,none:`このグループには何もありません。`,more:`… 他 {{count}} 件`,includeDeletes:`DELETE 文を実行可能な SQL として含める(既定: コメントアウト)`,tabTitle:`データ同期 {{table}}`,loading:`行を読み込み中 — 比較元: {{source}}、比較先: {{target}}`},schema:{createTitle:`スキーマを作成`,name:`スキーマ名`,namePlaceholder:`スキーマ名を入力`,create:`作成`,cancel:`キャンセル`},groupBy:{title:`グループ集計`,description:`{{table}} の行を選択した列でまとめて数えます。`,columns:`グループ化する列`,aggregate:`追加の集計`,countOnly:`件数のみ`,column:`列`,minCount:`グループごとの最小行数`,useFilter:`グリッドの現在のフィルタを適用`,noIndexWarning:`選択した列にインデックスの先頭列がないため、テーブル全体を読み込んで並べ替えます。大きなテーブルでは時間がかかることがあります。`,preview:`クエリ`,pickColumn:`グループ化する列を 1 つ以上選択してください。`,openInTab:`新しいタブで開く`,run:`実行`,tabTitle:`{{table}} のグループ集計`,indexed:`インデックスの先頭列`,connection:`接続`,database:`データベース`,table:`テーブル`}},g={manager:{title:`ユーザー管理`,addUser:`ユーザーを追加`,removeUser:`ユーザーを削除`,noUsers:`ユーザーが読み込まれていません`,grantScope:`権限の範囲`,apply:`適用`,close:`閉じる`,removed:`ユーザー '{{user}}'@'{{host}}' を削除しました`,selectUserFirst:`先にユーザーを選択してください`,applied:`変更を適用しました`,noChanges:`適用する権限の変更はありません。`},add:{title:`ユーザーを追加`,username:`ユーザー名`,usernamePlaceholder:`ユーザー名を入力`,host:`ホスト`,password:`パスワード`,passwordPlaceholder:`パスワードを入力`,confirmPassword:`パスワードの確認`,confirmPasswordPlaceholder:`パスワードを再入力`,plugin:`プラグイン`,cancel:`キャンセル`,add:`追加`,usernameRequired:`ユーザー名は必須です`,passwordMismatch:`パスワードが一致しません`,added:`ユーザー '{{user}}'@'{{host}}' を追加しました`},privileges:{globalTitle:`グローバル権限`,databaseTitle:`データベース権限`,tableTitle:`テーブル権限`,checkAll:`すべてチェック`,uncheckAll:`すべて解除`,categoryData:`データ`,categoryStructure:`構造`,categoryAdministration:`管理`},grantTree:{globalPrivileges:`グローバル権限`}},_={close:`閉じる`,noActiveConnection:`アクティブな接続がありません`,variableName:`変数名`,value:`値`,scope:{session:`セッション`,global:`グローバル`},findReplace:{findPlaceholder:`検索`,replacePlaceholder:`置換`,found:`{{count}} 件見つかりました`,noResults:`結果なし`,previous:`前へ`,next:`次へ`,close:`閉じる`,replace:`置換`,all:`すべて`,caseSensitive:`大文字と小文字を区別`,regex:`正規表現`,wholeWord:`単語単位`},flush:{title:`フラッシュ`,executed:`実行しました: {{command}}`,executeError:`{{command}} の実行中にエラーが発生しました: {{message}}`},localHistory:{title:`ローカル履歴`,description:`この接続のエディタ内容のバージョンです。実行時、入力が止まったとき、タブを閉じたときに保存されます。`,empty:`保存されたバージョンはまだありません。`,noMatch:`検索に一致するバージョンがありません。`,notPersisted:`設定 > 安全 の「再読み込み後もクエリ履歴を保持」がオフのため、バージョンはこのセッション中のみ保持されます。`,searchPlaceholder:`バージョンを検索`,scopeTab:`このタブ`,scopeAll:`すべてのタブ`,compareCurrent:`現在と比較`,comparePrevious:`直前と比較`,diffAgainstCurrent:`現在のエディタ内容と比較`,diffAgainstPrevious:`{{time}} のバージョンと比較`,noPrevious:`比較できる以前のバージョンがありません`,restored:`ローカル履歴からエディタの内容を復元しました`,restore:`このバージョンを復元`,openInNewTab:`新しいタブで開く`,openedInTab:`新しいタブでバージョンを開きました`,delete:`このバージョンを削除`,clearAll:`履歴を消去`,chars:`{{count}}文字`,reason:{execute:`実行前`,edit:`編集中`,replaced:`上書き前`,restore:`復元前`,close:`閉じる前`}},processList:{title:`プロセス一覧`,refresh:`更新`,autoRefresh:`自動更新`,empty:`表示するプロセスがありません`,kill:`強制終了`,killProcess:`プロセスを強制終了`,selectToKill:`強制終了するプロセスを選択してください`,killed:`プロセス {{id}} を強制終了しました`,killError:`プロセスの強制終了中にエラーが発生しました: {{message}}`,loadError:`プロセス一覧の読み込み中にエラーが発生しました: {{message}}`,updatedAt:`{{time}} 更新`,filterPlaceholder:`ユーザー、ホスト、DB、SQL で絞り込み...`,hideIdle:`アイドルを隠す`,noMatch:`条件に一致するプロセスがありません`,self:`自分`,selfHint:`Planche 自身のセッションです`,statementOf:`#{{id}} の実行文`,noStatement:`実行中の文なし`,copy:`コピー`,copied:`コピー済み`,killConfirmTitle:`プロセス {{id}} を終了しますか?`,killConfirmDescription:`{{user}}@{{host}} のセッションが切断され、実行中の文は中断されます。開いているトランザクションはロールバックされます。`,stats:{total:`合計`,active:`アクティブ`,idle:`アイドル`,longest:`最長実行`},columns:{id:`Id`,user:`ユーザー`,host:`ホスト`,db:`db`,command:`コマンド`,time:`時間`,state:`状態`,info:`情報`,action:`操作`}},status:{title:`サーバーステータス`,filterPlaceholder:`ステータス変数を絞り込み...`,empty:`表示するステータス変数がありません`,loadError:`ステータスの読み込み中にエラーが発生しました: {{message}}`},variables:{title:`サーバー変数`,filterPlaceholder:`変数を絞り込み...`,empty:`表示する変数がありません`,loadError:`変数の読み込み中にエラーが発生しました: {{message}}`}},v={empty:{title:`Prisma スキーマファイル (.prisma) を開いて ERD を表示`,description:`モデル、enum、リレーションが自動的に解析されます`,openFile:`.prisma ファイルを開く`,dropHint:`またはこの領域にファイルをドラッグ&ドロップ`},entity:{enumBadge:`ENUM`,modelBadge:`MODEL`,columns:{value:`値`,comment:`コメント`,type:`型`,column:`カラム`},linkBadge:`リンク`,externalTitle:`{{location}} 上のリンク先テーブル(実際の外部キーではなく列リンク)`,nullable:`NULL を許可する列`},toolbar:{refresh:`更新`,zoomIn:`拡大`,zoomOut:`縮小`,resetView:`表示をリセット`,center:`中央に配置`,fitAll:`全体を表示`,spreadAll:`重なりを解消`,resetLayout:`レイアウトをリセット`,legendOneToMany:`1:N (FK)`,tables:`テーブル:`,relations:`リレーション:`,columns:`カラム:`,fullscreen:`全画面`,exitFullscreen:`全画面を終了`},viewer:{noServerConnection:`アクティブなサーバー接続がありません`,loading:`{{database}} からスキーマを読み込み中...`,loadFailed:`ERD の読み込みに失敗しました`,noDatabase:`データベースが選択されていません。`,selectDatabaseHint:`スキーマツリーでデータベースを選択してから、「ERD を表示」を開いてください。`}},y={runAnyway:`それでも実行`,query:{rowsReturned:`{{count}} 行を返しました`,rowsAffected:`{{count}} 行が影響を受けました`,rowsReturnedLimited:`{{count}} 行を返しました({{limit}} 行に制限。さらに取得するには LIMIT を追加してください)`,notConnected:`接続されていません`,fileNotOpen:`SQLite ファイルがまだ開かれていません — 上の「ファイルを再度開く」をクリックしてアクセスを再度許可してください。`,failed:`クエリが失敗しました`,nothingToExecute:`実行するものがありません`,dryRunMismatch:`ドライランは {{predicted}} 行を見込みましたが、実際に変更されたのは {{actual}} 行です。プレビュー後にデータが変わった可能性があり、そうでなければプレビューがこの文と一致していません。`},destructive:{title_other:`{{count}} 件の破壊的なステートメントを実行しますか?`,description:`次の操作はデータを完全に変更または削除します。この操作は元に戻せません。`,unknownTarget:`(不明)`,deleteAll:`{{target}} のすべての行を DELETE`,updateAll:`{{target}} のすべての行を UPDATE`,alterDrop:`{{target}} に対する DROP COLUMN/PARTITION`},readOnly:{refused:`接続 "{{label}}" は読み取り専用です。{{count}} 件のステートメントがデータまたはスキーマを変更しようとしました。`,title:`"{{label}}" は読み取り専用です`,description:`これらのステートメントはデータまたはスキーマを変更します。それでもこの接続で実行しますか?`},transaction:{startFailed:`トランザクションを開始できませんでした`,started:`トランザクションを開始しました — 終了時にコミットまたはロールバックしてください`,implicitCommit:`{{kind}} により、開いていたトランザクションが暗黙的に COMMIT されました`,committed:`トランザクションをコミットしました`,rolledBack:`トランザクションをロールバックしました`,commandFailed:`{{name}} に失敗しました`,commandFailedWith:`{{name}} に失敗しました: {{message}}`},save:{notBrowserSqlite:`ブラウザ SQLite 接続ではありません。`,inMemory:`インメモリデータベース: ダウンロードとしてのみエクスポートできます。`,noFileSystemAccess:`このブラウザには File System Access API がありません(Chrome/Edge のみ対応): データベースはその場に書き込む代わりにダウンロードとしてエクスポートされます。`,noWritableHandle:`ファイルは書き込み可能なハンドルなしで開かれました: ダウンロードとしてエクスポートされます。`},agent:{devProxyUrl:`{{url}}(開発用プロキシ経由)`,notPlanche:`応答はありましたが、Planche エージェントではありません`,unreachable:"{{url}} の Planche エージェントに到達できません — `npx planche` を実行してください({{message}})",httpError:`HTTP エラー: {{status}} {{statusText}}`,emptyResponse:`トンネリングサーバーが空の応答を返しました`,reconnected:`{{name}} に再接続しました — エージェントが接続を破棄していました (再起動またはアイドルタイムアウト)。`},sample:{profileName:`サンプルショップ(ブラウザ内)`,downloadFailed:`サンプルデータベースをダウンロードできませんでした({{status}})`,tabTitle:`クエリ 1`},sqliteFile:{tooSmall:`ファイルが小さすぎるため SQLite データベースではありません。`,notSqlite:`SQLite データベースではありません(または SQLCipher などで暗号化されています)。16 バイトのヘッダーが "SQLite format 3" ではありません。`,badPageSize:`SQLite ヘッダーが破損しています: 無効なページサイズ {{size}}。`,unreadable:`SQLite がファイルを読み取れませんでした: {{message}}`,pickerDescription:`SQLite データベース`,walNotLoaded:`このデータベースは WAL モードですが、-wal ファイルが読み込まれていません。保存する前に読み込むか、バナーで -wal ファイルが存在しないことを確認してください。`,changedOnDisk:`{{name}} は読み込み後にディスク上で変更されました(他のプログラムが書き込みました)。保存するとその変更が上書きされます — ファイルを再度開いて編集をやり直すか、トンネリングサーバーを使用してください。`,walHasChanges:`{{name}}-wal に新しい変更があります。保存する前に読み込んでください。`,walChangedOnDisk:`{{name}}-wal は読み込み後に他のプログラムによって書き込まれました。保存する前にファイルを再度開いてください。`,writeDenied:`{{name}} への書き込みアクセスが許可されませんでした。ブラウザのプロンプトで許可するか、代わりにダウンロードとしてエクスポートしてください。`},environment:{none:`なし`,green:`緑(開発)`,blue:`青`,yellow:`黄(ステージング)`,orange:`オレンジ`,red:`赤(本番)`,purple:`紫`},scratchpad:{profileName:`スクラッチパッド`,namePromptTitle:`スクラッチパッドのテーブル名`,namePromptDescription:`スクラッチパッドに {{table}} という名前のテーブルが既にあります。別の名前を入力してください。`,nameTaken:`テーブル {{table}} は既に存在します。`},federated:{pulling:`{{connection}} から {{table}} を取得中…`,capped:`{{table}}: 先頭 {{limit}} 行のみ取得しました。`,templateLine1:`開いている接続のテーブルを "接続名".database.table として参照します。文の実行前にこのスクラッチパッドへコピーされます。`,templateLine2:`テーブルごとに最大 {{limit}} 行。クエリ自体はブラウザ内の SQLite で実行されます。`,templateConnections:`開いている接続: {{names}}`,templateNone:`まだ他の接続が開いていません。接続してからここで参照してください。`,done:`リモートテーブル {{tables}} 個から {{rows}} 行をスクラッチパッドへ取得しました。`,pullingProgress:`{{connection}} から {{table}} を取得中: {{loaded}} / {{total}} 行…`},paged:{noColumns:`{{table}} に列がありません。`,cancelled:`キャンセルしました。`}},b={title:`利用規約`,version:`バージョン {{version}}`,englishOnly:`規約の全文は英語で提供されます。ようこそ画面の要約はお使いの言語で表示されます。`,privacyLink:`プライバシーポリシー`,refundLink:`返金ポリシー`,online:`planche.dev で読む`,updated:`最終更新 {{date}}`},x={title:`{{kind}} は {{count}} 行に影響します`,titleUnknown:`{{kind}} — 影響行数は不明`,description:`この文が今触れる行を SELECT で先に読んだものです。まだ何も書き込んでいません。`,previewFailed:`プレビュークエリが失敗しました: {{error}}
2
- それでも文を実行できます。`,noRows:`一致する行がありません — この文は何も変更しません。`,truncated:`{{count}} 行のうち先頭 {{shown}} 行を表示しています。`,previewQuery:`プレビュークエリ`,run:`{{kind}} を実行({{count}} 行)`,runAnyway:`それでも実行`},S={badge:`PRO`,tooltip:`Pro ライセンスが必要です。`,noticeTitle:`Pro 機能`,notice:`PRO と表示された機能には Pro ライセンスが必要です。`,licenseTitle:`Planche Pro`,licenseDescription:`購入メールに記載されたライセンスキーを貼り付けてください。このコンピュータ上で確認し、どこにも送信しません。`,blocked:`{{feature}}には Pro ライセンスが必要です。`,keyLabel:`ライセンスキー`,activate:`有効化`,remove:`ライセンスを削除`,active:`Pro が有効です。`,licensedTo:`{{email}} 様のライセンス`,validUntil:`{{date}} まで有効`,expiredOn:`{{date}} に期限が切れました。Pro 機能を使い続けるには更新してください。`,invalidKey:`Planche のライセンスキーではありません。`,notConfigured:`このビルドはライセンスキーを確認できません。ご連絡ください。`,noWebcrypto:`このブラウザではライセンスキーを確認できません。`,pricing:`料金を見る`,features:{ssh_tunnel:`SSH トンネル`,compare_schemas:`スキーマ比較`,compare_data:`データ比較`,copy_table:`テーブルコピー`,dry_run:`ドライラン`,federated:`フェデレーテッドクエリ`,scratchpad:`スクラッチパッド`,column_link:`カラムリンク`,sync:`接続の同期`,ai_explain:`AI による説明`},included:`Pro に含まれる機能`,haveKey:`すでにライセンスキーをお持ちですか?`,perMonth:`/ 月`,priceNote:`年に 1 回 {{annual}} を請求。月払いは {{monthly}} です。`,featureDetails:{sync:`ブラウザで暗号化したプロファイルを、どのコンピュータでも`,ssh_tunnel:`踏み台の先のデータベースにパスワード・鍵・ssh-agent で接続`,compare_schemas:`開いている 2 つの接続を比較して ALTER スクリプトを取得`,compare_data:`2 つのテーブルの行を比較して INSERT・UPDATE スクリプトを取得`,copy_table:`別の接続へ、別のエンジンへテーブルを作り直す`,dry_run:`UPDATE・DELETE が何行をどう変えるのか実行前に確認`,federated:`異なる接続にあるテーブルを結合`,scratchpad:`作業データ用のローカル SQLite データベース`,column_link:`グリッドでたどれる仮想外部キー`,ai_explain:`失敗した文や遅いプランの理由をモデルに尋ねる — スキーマを添えて`}},C={npxNote:`Node.js 22 以上が必要です。恒久的にインストールされるものはなく、npx が npm レジストリから直接実行します。`,installNote:`Node.js は不要です。管理者権限なしでホームディレクトリの中だけにインストールされ、以後は planche コマンドでいつでも起動できます。`},w={unsupported:`{{engine}} は実行計画を提供しません。`,oneStatement:`実行計画は一度に 1 文だけ解析します。対象の文にカーソルを置くか選択してください。`},T={title:`AI アシスタント`,intro:`クエリを頼んだり、やることを指示してください — スキーマを読み、タブに SQL を書いて実行します。動くのは開いている接続だけで、会話は接続ごとに分かれています。`,privacy:`ツールが読んだ内容は、サンプル行を含めて利用中の provider に送信されます。planche.dev には何も送られません。`,placeholder:`例: デモ DB で月次売上のクエリを作って`,send:`送信`,stop:`停止`,clear:`新しい会話`,working:`実行中…`,tabTitle:`AI クエリ`,approvalTitle:`書き込みを伴います。実行しますか?`,approve:`実行`,reject:`スキップ`,rejected:`ユーザーが実行を拒否しました。`,notConfigured:`エージェントに AI キーがありません。設定 ▸ AI で追加してください。`,needsAgent:`このローカルエージェントはまだツールを実行できません。更新して再度ペアリングしてください。`,failed:`失敗`,empty:`まだ何も尋ねていません。`,steps:`{{count}} ステップ`,tooManySteps:`{{count}} ステップ進みましたが答えに至りませんでした。`,collapse:`折りたたむ`,planWarningTitle:`このクエリはフルスキャンです。実行しますか?`,interrupted:`リロードで中断されました。`,external:`Planche の外から要求された操作です`},E={title:`AI エージェントを接続 (MCP)`,description:`MCP に対応した AI エージェントから Planche のツールを使えるようにします。`,readsLabel:`読み取り`,reads:`開いているデータベースを読み、その結果は相手のプログラムに渡ります。`,writesLabel:`書き込み`,writes:`データを変更する文には承認が要ります。DROP と TRUNCATE は実行できません。`,needsLabel:`条件`,needs:`AI パネルが開いている必要があります。`,tokenLabel:`トークン`,token:`一つを複数のプログラムで共有します。失効させると全部切れます。`,command:`Claude Code に追加`,json:`手動で設定`,stored:`{{path}} に保存されます。`,revoke:`トークンを失効`,revoked:`失効しました。新しく発行するにはこの画面を開き直してください。`},D={title:`接続の同期`,description:`接続プロファイルをこのブラウザで暗号化し、planche.dev に保管します。ほかのコンピュータからもそのまま使えます。`,stored:`サーバーに置かれるのは暗号化された塊ひとつだけです。ホスト・ユーザー・パスワード・SSH 鍵を読むことはできません。`,unavailable:`同期は planche.dev でのみ動きます。この Planche はローカルエージェントが配信しており、エージェントは外部へ接続できないようにしてあります。`,signIn:`GitHub でログイン`,signedInAs:`{{email}} でログイン中`,signOut:`ログアウト`,createTitle:`パスフレーズを決める`,createHint:`このパスフレーズがプロファイルを暗号化します。サーバーには送られないため、失うと保管された控えは復元できません — プロファイルが残っているコンピュータから作り直すしかありません。`,passphrase:`パスフレーズ`,confirm:`パスフレーズの確認`,mismatch:`2 つのパスフレーズが一致しません。`,tooShort:`{{count}} 文字以上で入力してください。`,enable:`同期を有効にする`,unlockTitle:`プロファイルのロック解除`,unlockHint:`同期を有効にしたときに決めたパスフレーズを入力してください。`,unlock:`ロック解除`,wrongPassphrase:`パスフレーズが違うか、保管された控えが壊れています。`,syncNow:`今すぐ同期`,lastSynced:`最終同期 {{when}}`,neverSynced:`まだ同期していません`,profiles_one:`プロファイル {{count}} 件`,profiles_other:`プロファイル {{count}} 件`,changePassphrase:`パスフレーズを変更`,deleteVault:`サーバーから削除`,deleteVaultConfirm:`planche.dev にある暗号化された控えを削除しますか?このコンピュータのプロファイルはそのまま残ります。`,offline:`planche.dev に接続できません。`,working:`処理中…`,serverError:`planche.dev が処理を完了できませんでした。しばらくしてからお試しください。`,signInShort:`ログイン`,needsPro:`ログインしました。プロファイルの同期には Pro ライセンスが必要で、取得すればすぐに動きます。`,deleteAccount:`アカウントを削除`,deleteAccountConfirm:`アカウントを削除しますか?保管された控えとログイン情報も一緒に消えます。このコンピュータのプロファイルはそのまま残ります。`,notDeployed:`このサイトではまだ接続の同期が有効になっていません。`},O={app:e,language:t,settings:n,menu:r,about:i,connection:a,toolbar:o,footer:s,palette:c,welcome:l,schema:u,query:d,result:f,confirm:p,table:m,database:h,user:g,command:_,erd:v,services:y,terms:b,dryRun:x,pro:S,install:C,explain:w,ai:T,mcp:E,sync:D};export{i as about,T as ai,e as app,_ as command,p as confirm,a as connection,h as database,O as default,x as dryRun,v as erd,w as explain,s as footer,C as install,t as language,E as mcp,r as menu,c as palette,S as pro,d as query,f as result,u as schema,y as services,n as settings,D as sync,m as table,b as terms,o as toolbar,g as user,l as welcome};
2
+ それでも文を実行できます。`,noRows:`一致する行がありません — この文は何も変更しません。`,truncated:`{{count}} 行のうち先頭 {{shown}} 行を表示しています。`,previewQuery:`プレビュークエリ`,run:`{{kind}} を実行({{count}} 行)`,runAnyway:`それでも実行`},S={badge:`PRO`,tooltip:`Pro ライセンスが必要です。`,noticeTitle:`Pro 機能`,notice:`PRO と表示された機能には Pro ライセンスが必要です。`,licenseTitle:`Planche Pro`,licenseDescription:`購入メールに記載されたライセンスキーを貼り付けてください。このコンピュータ上で確認し、どこにも送信しません。`,blocked:`{{feature}}には Pro ライセンスが必要です。`,keyLabel:`ライセンスキー`,activate:`有効化`,remove:`ライセンスを削除`,active:`Pro が有効です。`,licensedTo:`{{email}} 様のライセンス`,validUntil:`{{date}} まで有効`,expiredOn:`{{date}} に期限が切れました。Pro 機能を使い続けるには更新してください。`,invalidKey:`Planche のライセンスキーではありません。`,notConfigured:`このビルドはライセンスキーを確認できません。ご連絡ください。`,noWebcrypto:`このブラウザではライセンスキーを確認できません。`,pricing:`料金を見る`,features:{ssh_tunnel:`SSH トンネル`,compare_schemas:`スキーマ比較`,compare_data:`データ比較`,copy_table:`テーブルコピー`,dry_run:`ドライラン`,federated:`フェデレーテッドクエリ`,scratchpad:`スクラッチパッド`,column_link:`カラムリンク`,sync:`接続の同期`,ai_explain:`AI による説明`},included:`Pro に含まれる機能`,haveKey:`すでにライセンスキーをお持ちですか?`,perMonth:`/ 月`,priceNote:`年に 1 回 {{annual}} を請求。月払いは {{monthly}} です。`,featureDetails:{sync:`ブラウザで暗号化したプロファイルを、どのコンピュータでも`,ssh_tunnel:`踏み台の先のデータベースにパスワード・鍵・ssh-agent で接続`,compare_schemas:`開いている 2 つの接続を比較して ALTER スクリプトを取得`,compare_data:`2 つのテーブルの行を比較して INSERT・UPDATE スクリプトを取得`,copy_table:`別の接続へ、別のエンジンへテーブルを作り直す`,dry_run:`UPDATE・DELETE が何行をどう変えるのか実行前に確認`,federated:`異なる接続にあるテーブルを結合`,scratchpad:`作業データ用のローカル SQLite データベース`,column_link:`グリッドでたどれる仮想外部キー`,ai_explain:`失敗した文や遅いプランの理由をモデルに尋ねる — スキーマを添えて`}},C={npxNote:`Node.js 22 以上が必要です。恒久的にインストールされるものはなく、npx が npm レジストリから直接実行します。`,installNote:`Node.js は不要です。管理者権限なしでホームディレクトリの中だけにインストールされ、以後は planche コマンドでいつでも起動できます。`},w={unsupported:`{{engine}} は実行計画を提供しません。`,oneStatement:`実行計画は一度に 1 文だけ解析します。対象の文にカーソルを置くか選択してください。`},T={title:`AI アシスタント`,intro:`クエリを頼んだり、やることを指示してください — スキーマを読み、タブに SQL を書いて実行します。動くのは開いている接続だけで、会話は接続ごとに分かれています。`,privacy:`ツールが読んだ内容は、サンプル行を含めて利用中の provider に送信されます。planche.dev には何も送られません。`,placeholder:`例: デモ DB で月次売上のクエリを作って`,send:`送信`,stop:`停止`,clear:`新しい会話`,working:`実行中…`,tabTitle:`AI クエリ`,approvalTitle:`書き込みを伴います。実行しますか?`,approve:`実行`,reject:`スキップ`,rejected:`ユーザーが実行を拒否しました。`,notConfigured:`エージェントに AI キーがありません。設定 ▸ AI で追加してください。`,needsAgent:`このローカルエージェントはまだツールを実行できません。更新して再度ペアリングしてください。`,failed:`失敗`,empty:`まだ何も尋ねていません。`,steps:`{{count}} ステップ`,tooManySteps:`{{count}} ステップ進みましたが答えに至りませんでした。`,collapse:`折りたたむ`,planWarningTitle:`このクエリはフルスキャンです。実行しますか?`,interrupted:`リロードで中断されました。`,external:`Planche の外から要求された操作です`},E={title:`AI エージェントを接続 (MCP)`,description:`MCP に対応した AI エージェントから Planche のツールを使えるようにします。`,readsLabel:`読み取り`,reads:`開いているデータベースを読み、その結果は相手のプログラムに渡ります。`,writesLabel:`書き込み`,writes:`データを変更する文には承認が要ります。DROP と TRUNCATE は実行できません。`,needsLabel:`条件`,needs:`AI パネルが開いている必要があります。`,tokenLabel:`トークン`,token:`一つを複数のプログラムで共有します。失効させると全部切れます。`,command:`Claude Code に追加`,json:`手動で設定`,stored:`{{path}} に保存されます。`,revoke:`トークンを失効`,revoked:`失効しました。新しく発行するにはこの画面を開き直してください。`},D={title:`接続の同期`,description:`接続プロファイルをこのブラウザで暗号化し、planche.dev に保管します。ほかのコンピュータからもそのまま使えます。`,stored:`サーバーに置かれるのは暗号化された塊ひとつだけです。ホスト・ユーザー・パスワード・SSH 鍵を読むことはできません。`,unavailable:`同期は planche.dev でのみ動きます。この Planche はローカルエージェントが配信しており、エージェントは外部へ接続できないようにしてあります。`,signIn:`GitHub でログイン`,signedInAs:`{{email}} でログイン中`,signOut:`ログアウト`,createTitle:`パスフレーズを決める`,createHint:`このパスフレーズがプロファイルを暗号化します。サーバーには送られないため、失うと保管された控えは復元できません — プロファイルが残っているコンピュータから作り直すしかありません。`,passphrase:`パスフレーズ`,confirm:`パスフレーズの確認`,mismatch:`2 つのパスフレーズが一致しません。`,tooShort:`{{count}} 文字以上で入力してください。`,enable:`同期を有効にする`,unlockTitle:`プロファイルのロック解除`,unlockHint:`同期を有効にしたときに決めたパスフレーズを入力してください。`,unlock:`ロック解除`,wrongPassphrase:`パスフレーズが違うか、保管された控えが壊れています。`,syncNow:`今すぐ同期`,lastSynced:`最終同期 {{when}}`,neverSynced:`まだ同期していません`,profiles_one:`プロファイル {{count}} 件`,profiles_other:`プロファイル {{count}} 件`,changePassphrase:`パスフレーズを変更`,deleteVault:`サーバーから削除`,deleteVaultConfirm:`planche.dev にある暗号化された控えを削除しますか?このコンピュータのプロファイルはそのまま残ります。`,offline:`planche.dev に接続できません。`,working:`処理中…`,serverError:`planche.dev が処理を完了できませんでした。しばらくしてからお試しください。`,signInShort:`ログイン`,needsPro:`ログインしました。プロファイルの同期には Pro ライセンスが必要で、取得すればすぐに動きます。`,deleteAccount:`アカウントを削除`,deleteAccountConfirm:`アカウントを削除しますか?保管された控えとログイン情報も一緒に消えます。このコンピュータのプロファイルはそのまま残ります。`,notDeployed:`このサイトではまだ接続の同期が有効になっていません。`},O={closeTitle:`Planche を閉じますか?`,closeDescription:`未保存の作業があります: 開いているトランザクション、コミットしていない編集、または実行中のクエリ。閉じると破棄され、ロールバックされます。`,closeAnyway:`閉じる`},k={app:e,language:t,settings:n,menu:r,about:i,connection:a,toolbar:o,footer:s,palette:c,welcome:l,schema:u,query:d,result:f,confirm:p,table:m,database:h,user:g,command:_,erd:v,services:y,terms:b,dryRun:x,pro:S,install:C,explain:w,ai:T,mcp:E,sync:D,desktop:O};export{i as about,T as ai,e as app,_ as command,p as confirm,a as connection,h as database,k as default,O as desktop,x as dryRun,v as erd,w as explain,s as footer,C as install,t as language,E as mcp,r as menu,c as palette,S as pro,d as query,f as result,u as schema,y as services,n as settings,D as sync,m as table,b as terms,o as toolbar,g as user,l as welcome};
@@ -1 +1 @@
1
- import{r as e}from"./hePW80VL.js";import{c as t,h as n,n as r,t as i}from"./XzPc-eVf.js";import{l as a,m as o,t as s}from"./CKOS5Y-e.js";import{a as c,i as l,n as u,r as d,t as f}from"./Bz1cma8F.js";import{t as p}from"./B3nhMsGp.js";import{a as m}from"./CtXRSNHU.js";import{n as h}from"./Cr6Fx4T5.js";import{t as ee}from"./4_c4BD6i.js";import{X as g,Y as _,c as v,l as y}from"./B_UAjgBr.js";import{a as b,i as x,n as S,o as C,t as w}from"./DxuXBECK.js";var T=e(n(),1),E=a(),D=e=>e instanceof Error?e.message:String(e);function O(){let{t:e}=o(),n=r(e=>e.activeDialog),a=r(e=>e.closeDialog),O=i(`link-column`),k=n===`link-column`&&!!O,A=O?.connectionId??``,j=p(e=>e.activeConnections),M=j.filter(e=>e.serverConnectionId),N=g(e=>e.links),P=g(e=>e.setLink),F=g(e=>e.removeLink),I=O?_(N,A,O.database,O.table).find(e=>e.column===O.column)??null:null,[L,R]=(0,T.useState)(I?.targetConnectionId??A),z=j.find(e=>e.id===L)?.serverConnectionId,[B,V]=(0,T.useState)([]),[H,U]=(0,T.useState)([]),[W,G]=(0,T.useState)([]),[K,q]=(0,T.useState)(I?.targetDatabase??O?.database??``),[J,Y]=(0,T.useState)(I?.targetTable??``),[X,Z]=(0,T.useState)(I?.targetColumn??``),[Q,$]=(0,T.useState)(null);if((0,T.useEffect)(()=>{if(!k||!z)return;let e=!1;return(async()=>{try{let t=await h(L).introspect.listDatabases(m(z));if(e)return;V(t),q(e=>t.includes(e)?e:t[0]??``)}catch(t){e||$(D(t))}})(),()=>{e=!0}},[k,z,L]),(0,T.useEffect)(()=>{if(!k||!z||!K)return;let e=!1;return(async()=>{try{let t=await h(L).introspect.listTables(m(z),K);if(e)return;U(t.map(e=>e.name))}catch(t){e||$(D(t))}})(),()=>{e=!0}},[k,z,L,K]),(0,T.useEffect)(()=>{if(!k||!z||!K||!J)return;let e=!1;return(async()=>{try{let t=await h(L).introspect.listColumns(m(z),K,J);if(e)return;G(t.map(e=>e.name)),Z(e=>t.some(t=>t.name===e)?e:t.find(e=>e.key===`PRI`)?.name??t[0]?.name??``)}catch(t){e||$(D(t))}})(),()=>{e=!0}},[k,z,L,K,J]),!O)return null;function te(){if(!O||!K||!J||!X)return;let e=L!==A;P(A,{database:O.database,table:O.table,column:O.column,...e?{targetConnectionId:L}:{},targetDatabase:K,targetTable:J,targetColumn:X}),ee(`column_link`),t(`column_link_set`,{dbms:h(A).id,target_dbms:h(L).id,cross_database:K!==O.database,cross_connection:e}),a()}function ne(){O&&(F(A,O),a())}return(0,E.jsx)(w,{open:k,onOpenChange:e=>{e||a()},children:(0,E.jsxs)(S,{className:`sm:max-w-[460px]`,children:[(0,E.jsx)(b,{children:(0,E.jsx)(C,{children:e(`result.link.title`)})}),(0,E.jsxs)(`div`,{className:`space-y-4`,children:[(0,E.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,E.jsx)(v,{children:e(`result.link.source`)}),(0,E.jsx)(y,{value:`${O.database}.${O.table}.${O.column}`,disabled:!0})]}),(0,E.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:e(`result.link.hint`)}),(0,E.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,E.jsx)(v,{htmlFor:`link-conn`,children:e(`result.link.targetConnection`)}),(0,E.jsxs)(f,{value:L,onValueChange:e=>{R(e),Y(``),U([]),G([])},children:[(0,E.jsx)(l,{id:`link-conn`,className:`w-full`,children:(0,E.jsx)(c,{})}),(0,E.jsx)(u,{children:M.map(e=>(0,E.jsx)(d,{value:e.id,children:e.hostName||e.host||e.file||e.id},e.id))})]})]}),(0,E.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,E.jsx)(v,{htmlFor:`link-db`,children:e(`result.link.targetDatabase`)}),(0,E.jsxs)(f,{value:K,onValueChange:e=>{q(e),Y(``),G([])},children:[(0,E.jsx)(l,{id:`link-db`,className:`w-full`,children:(0,E.jsx)(c,{})}),(0,E.jsx)(u,{children:B.map(e=>(0,E.jsx)(d,{value:e,children:e},e))})]})]}),(0,E.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,E.jsx)(v,{htmlFor:`link-table`,children:e(`result.link.targetTable`)}),(0,E.jsxs)(f,{value:J,onValueChange:Y,disabled:H.length===0,children:[(0,E.jsx)(l,{id:`link-table`,className:`w-full`,children:(0,E.jsx)(c,{placeholder:e(`result.link.pickTable`)})}),(0,E.jsx)(u,{children:H.map(e=>(0,E.jsx)(d,{value:e,children:e},e))})]})]}),(0,E.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,E.jsx)(v,{htmlFor:`link-column`,children:e(`result.link.targetColumn`)}),(0,E.jsxs)(f,{value:X,onValueChange:Z,disabled:W.length===0,children:[(0,E.jsx)(l,{id:`link-column`,className:`w-full`,children:(0,E.jsx)(c,{placeholder:e(`result.link.pickColumn`)})}),(0,E.jsx)(u,{children:W.map(e=>(0,E.jsx)(d,{value:e,children:e},e))})]})]}),Q&&(0,E.jsx)(`p`,{className:`text-xs text-destructive`,children:Q})]}),(0,E.jsxs)(x,{children:[I&&(0,E.jsx)(s,{variant:`destructive`,onClick:ne,className:`mr-auto`,children:e(`result.link.remove`)}),(0,E.jsx)(s,{variant:`outline`,onClick:a,children:e(`result.link.cancel`)}),(0,E.jsx)(s,{onClick:te,disabled:!K||!J||!X,children:e(`result.link.save`)})]})]})})}export{O as LinkColumnDialog};
1
+ import{r as e}from"./hePW80VL.js";import{c as t,h as n,n as r,t as i}from"./BkIkgVK5.js";import{l as a,m as o,t as s}from"./C0O3rJzW.js";import{a as c,i as l,n as u,r as d,t as f}from"./CUQISMvX.js";import{t as p}from"./DC8XCjJ3.js";import{a as m}from"./Dd9quIZg.js";import{n as h}from"./Dht5Mpyb.js";import{t as ee}from"./3z4eHGF-.js";import{X as g,Y as _,c as v,l as y}from"./Bg6u9htc.js";import{a as b,i as x,n as S,o as C,t as w}from"./Cg4DfVr4.js";var T=e(n(),1),E=a(),D=e=>e instanceof Error?e.message:String(e);function O(){let{t:e}=o(),n=r(e=>e.activeDialog),a=r(e=>e.closeDialog),O=i(`link-column`),k=n===`link-column`&&!!O,A=O?.connectionId??``,j=p(e=>e.activeConnections),M=j.filter(e=>e.serverConnectionId),N=g(e=>e.links),P=g(e=>e.setLink),F=g(e=>e.removeLink),I=O?_(N,A,O.database,O.table).find(e=>e.column===O.column)??null:null,[L,R]=(0,T.useState)(I?.targetConnectionId??A),z=j.find(e=>e.id===L)?.serverConnectionId,[B,V]=(0,T.useState)([]),[H,U]=(0,T.useState)([]),[W,G]=(0,T.useState)([]),[K,q]=(0,T.useState)(I?.targetDatabase??O?.database??``),[J,Y]=(0,T.useState)(I?.targetTable??``),[X,Z]=(0,T.useState)(I?.targetColumn??``),[Q,$]=(0,T.useState)(null);if((0,T.useEffect)(()=>{if(!k||!z)return;let e=!1;return(async()=>{try{let t=await h(L).introspect.listDatabases(m(z));if(e)return;V(t),q(e=>t.includes(e)?e:t[0]??``)}catch(t){e||$(D(t))}})(),()=>{e=!0}},[k,z,L]),(0,T.useEffect)(()=>{if(!k||!z||!K)return;let e=!1;return(async()=>{try{let t=await h(L).introspect.listTables(m(z),K);if(e)return;U(t.map(e=>e.name))}catch(t){e||$(D(t))}})(),()=>{e=!0}},[k,z,L,K]),(0,T.useEffect)(()=>{if(!k||!z||!K||!J)return;let e=!1;return(async()=>{try{let t=await h(L).introspect.listColumns(m(z),K,J);if(e)return;G(t.map(e=>e.name)),Z(e=>t.some(t=>t.name===e)?e:t.find(e=>e.key===`PRI`)?.name??t[0]?.name??``)}catch(t){e||$(D(t))}})(),()=>{e=!0}},[k,z,L,K,J]),!O)return null;function te(){if(!O||!K||!J||!X)return;let e=L!==A;P(A,{database:O.database,table:O.table,column:O.column,...e?{targetConnectionId:L}:{},targetDatabase:K,targetTable:J,targetColumn:X}),ee(`column_link`),t(`column_link_set`,{dbms:h(A).id,target_dbms:h(L).id,cross_database:K!==O.database,cross_connection:e}),a()}function ne(){O&&(F(A,O),a())}return(0,E.jsx)(w,{open:k,onOpenChange:e=>{e||a()},children:(0,E.jsxs)(S,{className:`sm:max-w-[460px]`,children:[(0,E.jsx)(b,{children:(0,E.jsx)(C,{children:e(`result.link.title`)})}),(0,E.jsxs)(`div`,{className:`space-y-4`,children:[(0,E.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,E.jsx)(v,{children:e(`result.link.source`)}),(0,E.jsx)(y,{value:`${O.database}.${O.table}.${O.column}`,disabled:!0})]}),(0,E.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:e(`result.link.hint`)}),(0,E.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,E.jsx)(v,{htmlFor:`link-conn`,children:e(`result.link.targetConnection`)}),(0,E.jsxs)(f,{value:L,onValueChange:e=>{R(e),Y(``),U([]),G([])},children:[(0,E.jsx)(l,{id:`link-conn`,className:`w-full`,children:(0,E.jsx)(c,{})}),(0,E.jsx)(u,{children:M.map(e=>(0,E.jsx)(d,{value:e.id,children:e.hostName||e.host||e.file||e.id},e.id))})]})]}),(0,E.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,E.jsx)(v,{htmlFor:`link-db`,children:e(`result.link.targetDatabase`)}),(0,E.jsxs)(f,{value:K,onValueChange:e=>{q(e),Y(``),G([])},children:[(0,E.jsx)(l,{id:`link-db`,className:`w-full`,children:(0,E.jsx)(c,{})}),(0,E.jsx)(u,{children:B.map(e=>(0,E.jsx)(d,{value:e,children:e},e))})]})]}),(0,E.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,E.jsx)(v,{htmlFor:`link-table`,children:e(`result.link.targetTable`)}),(0,E.jsxs)(f,{value:J,onValueChange:Y,disabled:H.length===0,children:[(0,E.jsx)(l,{id:`link-table`,className:`w-full`,children:(0,E.jsx)(c,{placeholder:e(`result.link.pickTable`)})}),(0,E.jsx)(u,{children:H.map(e=>(0,E.jsx)(d,{value:e,children:e},e))})]})]}),(0,E.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,E.jsx)(v,{htmlFor:`link-column`,children:e(`result.link.targetColumn`)}),(0,E.jsxs)(f,{value:X,onValueChange:Z,disabled:W.length===0,children:[(0,E.jsx)(l,{id:`link-column`,className:`w-full`,children:(0,E.jsx)(c,{placeholder:e(`result.link.pickColumn`)})}),(0,E.jsx)(u,{children:W.map(e=>(0,E.jsx)(d,{value:e,children:e},e))})]})]}),Q&&(0,E.jsx)(`p`,{className:`text-xs text-destructive`,children:Q})]}),(0,E.jsxs)(x,{children:[I&&(0,E.jsx)(s,{variant:`destructive`,onClick:ne,className:`mr-auto`,children:e(`result.link.remove`)}),(0,E.jsx)(s,{variant:`outline`,onClick:a,children:e(`result.link.cancel`)}),(0,E.jsx)(s,{onClick:te,disabled:!K||!J||!X,children:e(`result.link.save`)})]})]})})}export{O as LinkColumnDialog};
@@ -1,2 +1,2 @@
1
1
  var e={reconnecting:`正在重新连接…`,dropSqlite:`松开以打开 SQLite 文件`,dropSqliteHint:`通过 WebAssembly 在浏览器中打开,文件不会离开您的电脑。如有 -wal 文件,请一并拖入。`,dropFailedTitle:`无法打开拖入的文件`,dropNotSqlite:`{{name}} 不是 SQLite 数据库文件。`,crashTitle:`出了点问题`,crashBody:`应用遇到了意外错误。重新加载会恢复连接和标签页;未保存的表格编辑将丢失。`,crashReload:`重新加载`},t={auto:`系统语言({{name}})`,en:`English`,ko:`한국어`,zh:`中文(简体)`,ja:`日本語`,de:`Deutsch`,fr:`Français`},n={title:`安全`,description:`防止意外数据丢失的保护措施。只读、环境颜色和事务模式按连接单独设置。`,language:`语言`,languageHint:`立即生效。“系统语言”跟随浏览器设置。`,resetDefaults:`恢复默认值`,done:`完成`,analytics:`分享匿名使用统计`,analyticsHint:`向 Google Analytics 发送匿名使用事件(引擎、功能、语句类型)。绝不发送 SQL 文本、主机名、表名或用户名。`,analyticsUnavailableHint:`此版本未启用(未配置衡量 ID)。`,persistHistory:`重新加载后保留查询历史`,persistHistoryHint:`语句文本保存在此浏览器中(密码字面量会被遮盖;打开的编辑器标签本身始终保留)。关闭后,历史和快照仅保留到标签页关闭。`,ai:{intro:`可以让模型解释语句为何失败、计划为何缓慢。问题在本应用中组装,由本地代理发送给下面的提供方 — 你的 SQL 和表结构不会到达 planche.dev。`,provider:`提供方`,openaiCompatible:`OpenAI 兼容`,model:`模型`,baseUrl:`Base URL`,baseUrlHint:`留空则使用提供方默认端点。任何 OpenAI 兼容服务器都可以 — Azure、OpenRouter、本地 Ollama。`,key:`API 密钥`,keyHint:`交给本地代理并在那里使用。不会保存在此浏览器中,也不会发送到 planche.dev。`,remember:`在这台机器上记住密钥`,rememberHint:`写入 {{path}},仅你本人可读。不勾选时密钥只存在于运行中的代理里,代理停止即消失。`,save:`保存`,forget:`删除密钥`,saved:`已保存。`,none:`尚未设置密钥。`,configuredSession:`已设置仅在本次代理会话有效的密钥。`,configuredFile:`密钥已保存在 {{path}}。`,configuredEnv:`此代理的 AI 设置来自环境变量,无法在此更改。`,unreachable:`无法连接代理,因此无法更改 AI 设置。`,title:`AI 解释`,description:`由哪个模型解释失败或执行计划,用谁的密钥付费。`,cli:`本地 CLI(无需密钥)`,cliCommand:`命令`,cliHint:`运行本机上已安装并已登录的 agent CLI,因此不需要填写密钥。可用于解释失败和执行计划;AI 面板需要能调用工具的 provider。`,cliNone:`本机未找到 agent CLI。请安装 Claude Code 或 Codex,或改选其他 provider。`,profile:`Anthropic(本机登录)`,profileHint:"使用本机已登录的凭据 —— 执行 `ant auth login` 后 SDK 会自行找到。无需粘贴任何内容;与本地 CLI 不同,这是真正的 API,所以 AI 面板也能用。",profileNone:"本机未找到 Anthropic 凭据。请执行 `ant auth login`,或改为填写密钥。",configuredChoice:`正在使用 {{provider}} — 不保存密钥;该选择保存在 {{path}}。`},query:{title:`查询`,description:`语句如何执行: F9 运行什么、返回多少行、先预览什么。`},general:{title:`通用`,description:`语言、重新加载后仍保留的内容,以及离开这台机器的内容。`}},r={settings:{safety:`安全…`,language:`语言`,title:`设置`,theme:`主题`,query:`查询…`,general:`通用…`,ai:`AI…`},help:{gettingStarted:`快速入门`,about:`关于 Planche`,title:`帮助`,documentation:`文档`,learn:`学习 SQL`,terms:`使用条款`,license:`许可证`,support:`联系支持`,mcp:`连接 AI 代理 (MCP)…`,privacy:`隐私政策`},connection:{title:`连接`,connect:`连接`,disconnect:`断开连接`,readOnly:`只读`,manualTransactions:`手动事务`,saveDatabaseFile:`保存数据库文件`,saveDatabaseFileBlocked:`保存数据库文件(请先加载 -wal)`,exit:`退出`,sync:`连接同步`},query:{title:`查询`,execute:`执行`,executeStatementAtCursor:`执行光标处语句`,executeWholeScript:`执行整个脚本`,newQueryTab:`新建查询标签页`,findReplace:`查找和替换`,localHistory:`本地历史记录…`,explainPlan:`查看执行计划`,explainAnalyze:`实测执行计划 (会真正执行该语句)`,structure:`查询结构`},edit:{title:`编辑`,undo:`撤销`,redo:`重做`,cut:`剪切`,copy:`复制`,paste:`粘贴`,selectAll:`全选`},database:{title:`数据库`,create:`创建数据库`,alter:`修改数据库`,drop:`删除数据库`,copy:`复制数据库`,compare:`比较架构…`,truncate:`清空数据库`,compareData:`比较数据…`,groupBy:`分组统计…`},table:{title:`表`,create:`创建表`,alter:`修改表`,drop:`删除表`,rename:`重命名表`,truncate:`清空表`,duplicateStructure:`复制表结构`},export:{title:`导出`,csv:`下载为 CSV`,tsv:`下载为 TSV`,schemaHtml:`架构导出为 HTML`,links:`导出列链接…`,importLinks:`导入列链接…`},tools:{title:`工具`,userManager:`用户管理`,processList:`进程列表`,variables:`变量`,status:`状态`,flush:`Flush`,quickCommand:`快速命令`,viewErd:`查看 ERD`,scratchpad:`草稿板(浏览器内 SQLite)`,federated:`联合查询(跨连接联接)…`,federatedTab:`联合查询 {{n}}`,ai:`AI 助手`},messages:{databaseFileSaved:`数据库文件已保存`,databaseExported:`数据库已导出为下载文件`,databaseExportedWithReason:`数据库已导出为下载文件 — {{reason}}`,errorSavingDatabase:`保存数据库时出错:{{message}}`,noDatabaseSelected:`未选择数据库`,noTableSelected:`未选择表`,noActiveConnection:`没有活动连接`,databaseDropped:`数据库“{{database}}”已成功删除`,errorDroppingDatabase:`删除数据库时出错:{{message}}`,noTablesInDatabase:`数据库“{{database}}”中没有表`,databaseTruncated_other:`已成功清空“{{database}}”中的全部 {{count}} 张表`,errorTruncatingDatabase:`清空数据库时出错:{{message}}`,tableDropped:`表“{{table}}”已成功删除`,errorDroppingTable:`删除表时出错:{{message}}`,tableTruncated:`表“{{table}}”已成功清空`,errorTruncatingTable:`清空表时出错:{{message}}`,renameTablePrompt:`将表“{{table}}”重命名为:`,tableRenamed:`表“{{table}}”已成功重命名为“{{newName}}”`,errorRenamingTable:`重命名表时出错:{{message}}`,truncateDatabaseTitle:`清空 "{{name}}" 中的所有表?`,truncateDatabaseDescription:`"{{name}}" 中 {{count}} 个表的所有行将被删除。表结构将保留。此操作无法撤销。`,truncateDatabaseConfirm:`清空所有表`,renameTableTitle:`重命名表`,renameTableConfirm:`重命名`,noLinksToExport:`没有可导出的列链接。`,linksExported:`已导出 {{count}} 个列链接。`,linksImported:`已导入 {{count}} 个列链接。`,linksImportedPartial:`已导入 {{count}} 个列链接;没有匹配的连接配置:{{profiles}}`,linksImportFailed:`无法导入列链接:{{reason}}`}},i={title:`关于 Planche`,tagline:`适用于 MySQL、MariaDB、PostgreSQL 和 SQLite 的数据库客户端。`,version:`版本`,website:`网站`,licenses:`许可证`,licensesLink:`第三方声明`,disclaimer:`Planche 按“原样”提供,不附带任何形式的保证。作者不对因使用本软件造成的任何损害或数据丢失承担责任。执行破坏性语句前请备份数据。`,rights:`保留所有权利。`,legal:`法律条款`,terms:`服务条款`,privacy:`隐私`,refund:`退款`},a=JSON.parse('{"dialog":{"title":"连接到数据库","firstQueryTab":"查询 1","colHostName":"主机名称","colTarget":"目标","colDbms":"DBMS","noSaved":"没有已保存的连接","unnamed":"(未命名)","pickOnConnect":"(连接时选择)","noFile":"(无文件)","selectPrompt":"选择一个连接或新建一个","addNew":"新建","delete":"删除","testConnection":"测试连接","connect":"连接","close":"关闭","unknownError":"未知错误","browserTestHint":"浏览器内 SQLite 连接会在点击“连接”时打开本地文件。","testSuccess":"连接成功","restoredUnsaved":"{{file}}:已从缓存副本恢复未保存的更改","restoredUnsavedDiskChanged":"{{file}}:已从缓存副本恢复未保存的更改 — 注意,磁盘上的文件此后已发生变化","walPending":"{{file}} 处于 WAL 模式:最近的更改可能仍在其 -wal 文件中。请使用上方的“加载 -wal 文件”将其包含进来。","walApplied":"{{file}} 已打开并应用了其 -wal 中的更改","connectFailedTitle":"连接失败","testSuccessDescription":"服务器已接受该凭据。","testFailedTitle":"连接测试失败","privacy":"您在此输入的任何信息都不会发送到或存储在 planche.dev 的服务器上。连接配置仅保存在此浏览器的本地存储中;查询由本地代理直接发送到您的数据库。","hostKeyTitle":"未知的 SSH 主机密钥","hostKeyDescription":"{{host}}:{{port}} 出示了指纹为 {{fingerprint}} 的 {{type}} 密钥。请与服务器管理员提供的指纹核对;接受错误的密钥会让攻击者读取您的流量。","hostKeyAccept":"信任此主机","gatewayTitle":"网关配置","gatewayAdd":"添加","gatewayAdded":"已添加网关配置 {{name}}。","gatewayReadOnly":"只读","gatewayWritable":"可写","gatewayProfileHint":"此连接使用网关保存的配置“{{name}}”,这里无需设置。","gatewayLoadFailed":"无法加载网关配置:{{error}}","export":"导出…","exportWithoutSecrets":"不含密码","exportWithSecrets":"包含密码和密钥","import":"导入…","exported":"已导出连接“{{name}}”。","imported":"已导入连接“{{name}}”。","importFailedTitle":"无法导入连接"},"form":{"hostName":"主机名称","hostNamePlaceholder":"我的连接","dataSource":"数据源","openVia":"打开方式","viaBrowser":"浏览器(本地文件)","viaAgent":"本地代理","viaBrowserHint":"无需安装。最适合没有其他程序在使用的文件:浏览器在内存副本上工作,无法锁定文件,因此在打开期间其他程序所做的修改不会被看到,保存时会将其覆盖。","viaAgentHint":"通过 npx planche 用 SQLite 本身打开文件 — 具备正确的锁定和 WAL 支持,可与使用同一数据库的其他程序安全共存。","databaseFile":"数据库文件","changeFile":"更改文件","filePickerHint":"点击“连接”时会打开文件选择器(提示:⌘⇧. 显示隐藏文件,⌘⇧G 可输入路径)。","fileRememberedHint":"所选文件会被记住(Chromium),重新连接时只需再次授权。使用“连接 > 保存数据库文件”将更改写回。","authToken":"认证令牌","authTokenPlaceholder":"留空则使用已配对的代理令牌","filePathPlaceholder":"/path/to/database.sqlite 或 :memory:","createIfMissing":"不存在时创建","createIfMissingHint":"路径在隧道服务器主机上解析","host":"主机","port":"端口","database":"数据库","serviceName":"服务名","user":"用户","password":"密码","savePassword":"保存密码","savePasswordHint":"关闭:密码仅在本次浏览器会话中保留,绝不写入磁盘。","charset":"字符集","autoConnection":"自动连接","safety":"安全","environment":"环境","environmentHint":"为标签页和工作区着色","readOnly":"只读","readOnlyHint":"拒绝修改数据或架构的语句","transactions":"事务","txAuto":"自动提交","txManual":"手动 — 在工具栏中提交 / 回滚","ssh":"SSH","sshTunnel":"SSH 隧道","sshTunnelHint":"通过 SSH 跳板机连接数据库(由本地代理建立隧道)","sshHost":"SSH 主机","sshPort":"SSH 端口","sshUser":"SSH 用户","sshAuth":"SSH 认证","sshAuthKey":"私钥","sshAuthPassword":"密码","sshAuthAgent":"ssh-agent","sshAuthAgentHint":"使用运行 npx planche 的机器上 ssh-agent 中加载的密钥(SSH_AUTH_SOCK)。","sshPassword":"SSH 密码","sshKey":"私钥","sshKeyPick":"选择密钥文件…","sshKeyLoaded":"已加载密钥","sshKeyHint":"留空则使用代理机器上 ~/.ssh/config 的 IdentityFile(或 ~/.ssh/id_*);选择的密钥随此配置一起保存","sshPassphrase":"密码短语","sshPassphrasePlaceholder":"密钥没有密码短语时留空","sshSecretsHint":"SSH 密码、私钥和口令遵循上方的“保存密码”设置。未知的主机密钥会在首次连接前显示供您核对,并保存到代理所在机器的 ~/.planche/known_hosts。","sshHostPlaceholder":"bastion.example.com 或 ~/.ssh/config 中的 Host 别名","sshUserPlaceholder":"留空则使用 ~/.ssh/config 中的 User","sshTargetHint":"数据库主机/端口在跳板机上解析——请填写数据库的真实地址(如 RDS 端点),而不是 localhost 或本地端口转发。","connectionString":"连接字符串","connectionStringApplied":"已填入下方字段。字符串本身不会保存,只保存字段。","connectionStringInvalid":"不是 PostgreSQL URI(应为 postgresql://user:password@host/database)。","neonHint":"粘贴 Neon 控制台(Connect > Connection string)中的 URI,下方字段将自动填写。","supabaseHint":"粘贴 Supabase(Connect > Session pooler 或 Direct connection)中的 URI,下方字段将自动填写。","supabasePoolerWarning":"端口 6543 是事务模式连接池:每条语句可能在不同的后端执行,因此切换模式、临时表、预处理语句和手动事务都无法使用。请改用会话连接池(端口 5432)或直接连接。","managedTlsHint":"此服务始终使用 TLS 连接,由本地代理直接连接到服务(不经过 SSH 隧道)。","d1AccountId":"Account ID","d1DatabaseId":"Database ID","d1ApiToken":"API 令牌","d1Hint":"Account ID:Cloudflare 控制台账户首页右侧。Database ID:Storage & Databases > D1 > 你的数据库。令牌:My Profile > API Tokens > Create Token,授予 \\"D1 Edit\\" 权限(只读用 \\"D1 Read\\")。本地代理用它调用 Cloudflare API。","d1LimitsHint":"D1 每个请求独立执行并自动提交,因此无法使用手动事务;数据库显示为单一模式 \\"main\\"。","doDevUrl":"wrangler dev URL","doHint":"在 Worker 项目中运行 `wrangler dev`,并填入它输出的 URL(默认端口 8787)。本地代理会读取该会话的 Durable Object,同时运行的其他 `wrangler dev` 会话也会一并显示。","doLimitsHint":"仅限本地开发:已部署的 Durable Object 只能从 Worker 内访问,Cloudflare 未提供查询 API。每个对象显示为名为 \\"<命名空间>/<对象>\\" 的数据库;每个请求自动提交,因此无法使用手动事务。","tls":"TLS","tlsEnable":"加密连接","tlsVerify":"验证服务器证书","tlsVerifyHint":"关闭时接受自签名证书(已加密但不验证服务器身份)。通过 SSH 隧道时不可用。","d1DevUrl":"本地开发 URL","d1DevUrlHint":"留空则通过 Cloudflare 账号连接。填写后,Planche 直接读取本机 `wrangler dev` 正在运行的数据库——不需要账号和 API 令牌,下面的账号字段会被忽略。开发服务器只绑定一个 D1 时,Database ID 可以留空。","d1PickDatabase":"选择数据库"},"agent":{"copy":"复制","looking":"正在查找 Planche 代理…","online":"代理 <b>v{{version}}</b> 正在 <mono>{{url}}</mono> 运行","outdated":"代理 v{{version}} 使用协议 {{protocol}},但此应用需要更新的版本。请使用 <cmd/> 重新启动","unauthorized":"代理 <b>v{{version}}</b> 正在 <mono>{{url}}</mono> 运行,但此应用尚未与其配对(令牌每次启动都会变化)。请打开代理终端中打印的链接,或在“配置”中粘贴令牌。","offline":"<mono>{{url}}</mono> 上没有代理。请在终端启动它 — 它会以已配对的状态打开本应用。","close":"关闭","configure":"配置","checkAgain":"重新检查","urlLabel":"代理 URL","urlPlaceholder":"http://127.0.0.1:8888(默认)","tokenLabel":"令牌","tokenPlaceholder":"由代理打印","reset":"重置","save":"保存","remoteWarning":"此代理不在您的电脑上({{host}}):每个连接的密码和 SSH 密钥都会发送到那里。","remoteRefusedTitle":"不允许使用远程代理","remoteRefused":"代理必须在本机(127.0.0.1 或 localhost)运行。要使用另一台机器上的代理,请用 `ssh -L 8888:127.0.0.1:8888 user@host` 转发端口,并保持 URL 为 http://127.0.0.1:8888。","gateway":"网关“{{name}}”:{{count}} 个服务端配置。凭据只保存在网关上;请在下方选择配置。"},"tab":{"noConnections":"没有打开的连接。点击“连接”开始。","theSqliteFile":"该 SQLite 文件","reopened":"已重新打开 {{file}}","reopenFailed":"无法重新打开文件:{{message}}","reopenPrompt":"浏览器需要再次获得您的授权才能读取 <b>{{file}}</b>。","reopenFile":"重新打开文件","closeConnection":"关闭连接","reconnected":"已重新连接 {{file}}","accessNotGranted":"未授予文件访问权限;保存时将改为导出下载文件。","detachedPrompt":"正在处理 <b>{{file}}</b> 的缓存副本。请重新连接文件以就地保存更改。","reconnectFile":"重新连接文件","detachedHide":"隐藏(保存时会在需要时请求文件)","walFramesApplied_other":"已从 {{file}}-wal 应用 {{count}} 个 WAL 帧","walNoChanges":"-wal 文件中没有已提交的更改","walLoadFailed":"无法加载 -wal 文件:{{message}}","walPrompt":"<b>{{file}}</b> 处于 WAL 模式:在加载其 <mono>{{file}}-wal</mono> 文件之前可能无法显示最新数据,并且在此之前无法保存。如果旁边没有该文件(数据库已正常关闭),请改为确认这一点。如果其他程序仍在使用此数据库,请改为通过本地代理(<mono>npx planche</mono>)打开:浏览器无法安全地共享该文件。","loadWal":"加载 -wal 文件","noWalHint":"我已确认:数据库旁边没有 -wal 文件","noWal":"没有 -wal 文件","dismiss":"关闭","walHide":"隐藏(仍然无法保存)","readOnlyBadge":"只读"}}'),o={connect:`连接 (Alt+N)`,disconnect:`断开连接`,newQueryTab:`新建查询标签页 (Alt+T)`,execute:`执行 (F9)`,executeStatement:`执行光标处 / 选中的语句 (Ctrl+Enter)`,commit:`提交`,commitHint:`提交当前打开的事务`,noOpenTransaction:`没有打开的事务`,rollback:`回滚`,rollbackHint:`放弃当前打开的事务`,readOnlyBadge:`只读`,readOnlyHint:`此连接拒绝修改数据或架构的语句`,userManager:`用户管理 (Alt+U)`,quickCommand:`快速命令`,processList:`进程列表`,variables:`变量`,status:`状态`,flush:`Flush`,fullscreen:`全屏`},s={readOnly:`只读`,txOpen:`事务进行中`,manualTx:`手动事务`},c={title:`快速命令`,description:`搜索要运行的命令...`,inputPlaceholder:`输入命令或搜索...`,empty:`未找到命令。`,groups:{connection:`连接`,query:`查询`,database:`数据库`,table:`表`,tools:`工具`},commands:{connect:`连接`,disconnect:`断开连接`,executeQuery:`执行查询`,newQueryTab:`新建查询标签页`,createDatabase:`创建数据库`,dropDatabase:`删除数据库`,createTable:`创建表`,alterTable:`修改表`,dropTable:`删除表`,processList:`进程列表`,serverVariables:`服务器变量`,serverStatus:`服务器状态`,flush:`Flush`,userManager:`用户管理`}},l={title:`欢迎使用 Planche`,intro:`一个在浏览器中运行的 SQL 客户端。通过您机器上的一个小型代理访问数据库,因此凭据和数据绝不会离开您的电脑。`,skip:`跳过`,skipTitle:`隐藏此页面(可通过“帮助 > 快速入门”重新打开)`,copy:`复制`,copied:`已复制`,sampleOpenFailed:`无法打开示例数据库:{{message}}`,steps:{agent:{title:`运行本地代理`,body:`在终端运行下面任意一条命令。代理会启动,并与本页面配对。`},connection:{title:`添加连接`,body:`选择您的数据库,以合适的默认值打开连接表单。`},sample:{title:`手边没有数据库?试试示例`,body:`将一个示例网店数据库(24 张表、约 5 万行、视图和触发器)加载到浏览器中,体验编辑器、数据网格和架构树。`,loading:`正在加载示例…`,button:`试用示例数据库`}},terms:{title:`开始之前`,local:`一切都在本地运行:凭据、查询和结果只保留在您的计算机上,绝不会发送给我们。`,asIs:`Planche 按“原样”提供,不作任何保证。安全措施(危险操作确认、只读模式)只是便利功能,并非保证。`,dataLoss:`通过 Planche 执行的每条语句均由您自行负责。执行任何破坏性操作前请先备份数据。`,agree:`我已阅读并同意使用条款。`,accepted:`您已接受使用条款。`,readFull:`阅读完整条款`}},u={treeLabel:`架构`,unreachableHint:`不是此连接绑定的数据库;请为其创建一个配置文件以进行浏览`,objectType:{table:`表`,view:`视图`,procedure:`存储过程`,function:`函数`,trigger:`触发器`,event:`事件`},menu:{showCreate:`显示{{type}}的 CREATE 语句`,alter:`修改{{type}}`,drop:`删除{{type}}`,create:`创建{{type}}`,refresh:`刷新`,unreachable:`请使用绑定到此数据库的配置文件连接以进行浏览`,openDatabase:`打开数据库`,createSchema:`创建模式…`,createTable:`创建表`,dropDatabase:`删除数据库`,openSchema:`打开架构`,dropSchema:`删除架构`,newQueryTab:`新建查询标签`,generateSql:`生成 SQL`,openTable:`打开表`,alterTable:`修改表`,showCreateTable:`显示表的 CREATE 语句`,duplicateStructure:`复制结构`,copyTable:`复制表到其他位置…`,compare:`比较{{type}}…`,truncateTable:`清空表`,dropTable:`删除表`,exportCsv:`导出为 CSV`,exportTsv:`导出为 TSV…`,openView:`打开视图`,alterView:`修改视图`,showCreateView:`显示视图的 CREATE 语句`,dropView:`删除视图`,compareData:`比较数据…`,groupBy:`分组统计…`},actions:{createStatementUnavailable:`-- 无法获取{{type}} {{name}} 的 CREATE 语句`,getCreateFailed:`获取 CREATE {{type}} 失败:{{message}}`,createTabTitle:`创建{{type}}`,createSchemaTabTitle:`创建架构`,generateSqlFailed:`无法生成 SQL:{{message}}`,dropTableTitle:`删除表“{{name}}”?`,dropTableDescription:`这将永久删除{{from}}该表及其所有行。此操作无法撤销。`,dropTableConfirm:`删除表`,dropObjectTitle:`删除{{type}}“{{name}}”?`,dropObjectDescription:`该{{type}}的定义将被{{from}}移除。此操作无法撤销。`,dropObjectConfirm:`删除{{type}}`,fromDatabase:`从数据库“{{database}}”`,dropped:`已删除{{type}} {{name}}`,dropFailed:`删除{{type}}失败`,dropDatabaseTitle:`删除数据库“{{name}}”?`,dropDatabaseDescription:`这将永久删除该数据库及其所有表和数据。此操作无法撤销。`,dropDatabaseConfirm:`删除数据库`,droppedDatabase:`已删除数据库 {{name}}`,dropDatabaseFailed:`删除数据库失败`,dropSchemaTitle:`删除架构“{{name}}”?`,dropSchemaDescription:`这将永久删除该架构及其所有表和数据。此操作无法撤销。`,dropSchemaConfirm:`删除架构`,droppedSchema:`已删除架构 {{name}}`,dropSchemaFailed:`删除架构失败`,truncateTitle:`清空表“{{name}}”?`,truncateDescription:`“{{name}}”中的所有行都将被删除。表结构将保留。此操作无法撤销。`,truncateConfirm:`清空表`,truncated:`已清空 {{name}}`,truncateFailed:`清空失败`},tree:{loadDatabasesFailed:`加载数据库失败:{{message}}`}},d={editor:{destructiveMarker:`破坏性操作:{{action}} {{names}}`,readOnlyMarker:`连接为只读;此语句会修改数据或架构`,actionExecute:`执行(按设置)`,actionExecuteStatement:`执行光标处 / 选中的语句`,actionExecuteScript:`执行整个脚本`,actionExplainPlan:`查看执行计划`,actionQueryStructure:`查询结构`},tabs:{newQuery:`新建查询`,queryTitle:`查询 {{n}}`,erdViewer:`ERD 查看器`,close:`关闭`,closeOthers:`关闭其他`,closeLeft:`关闭左侧标签页`,closeRight:`关闭右侧标签页`,closeAll:`全部关闭`},executor:{noActiveConnection:`没有活动连接`,uncommittedTitle:`未提交的事务`,uncommittedDescription:`此连接有一个打开的事务。断开连接将回滚其更改。`,uncommittedConfirm:`回滚并断开连接`,unsavedTitle:`未保存的更改`,unsavedDescription:`{{file}} 有尚未保存到文件的更改。断开连接将丢弃这些更改(请先使用“连接 > 保存数据库文件”保留它们)。`,theSqliteDatabase:`该 SQLite 数据库`,unsavedConfirm:`丢弃并断开连接`}},f=JSON.parse('{"tabs":{"message":"消息","info":"信息","history":"历史记录","result":"结果","resultN":"结果 {{n}}","plan":"执行计划","structure":"结构","structureN":"结构 {{n}}"},"message":{"executing":"正在执行查询...","error":"错误:{{message}}","total":"(总计:{{ms}}ms)","ready":"就绪。","log":"执行日志","statementN":"语句 {{n}}","limitedBadge":"已达上限","insertId":"insert id {{id}}","failed":"失败","failedStatement":"失败的语句","summary":"成功 {{ok}} · 失败 {{failed}} · 共 {{ms}}","copy":"复制","copied":"已复制","showSql":"显示 SQL","hideSql":"隐藏 SQL"},"hints":{"title":"提示","unknownColumn":"没有名为 {{name}} 的列。是否想用 {{suggestions}}?","unknownTable":"没有名为 {{name}} 的表。是否想用 {{suggestions}}?","syntaxSwap":"{{engine}} 使用 {{expected}},而不是 {{found}}。","doubleQuotedLiteral":"{{engine}} 把 \\"{{value}}\\" 当作列名而不是文本。字符串请写成 \'{{value}}\'。"},"ai":{"title":"AI 解释","explain":"用 AI 解释","thinking":"正在读取失败信息…","by":"{{model}}","applyFix":"在新标签页中打开修正语句","failed":"无法解释: {{message}}","noFailure":"没有可解释的失败语句。","noPack":"无法从 planche.dev 获取提示词。","badShape":"模型没有按预期格式作答。","noPlan":"还没有可解释的执行计划。","explainPlan":"解释这个执行计划"},"info":{"empty":"没有可用的查询信息。","resultN":"结果 {{n}}","metadata":"查询元数据","executionTime":"执行时间","notAvailable":"不适用","affectedRows":"受影响的行数","fields":"字段","fieldDetails":"字段详情","colName":"名称","colType":"类型","colTable":"表","resultSets":"结果集","rowsReturned":"返回行数","insertId":"最后插入 ID","lastQuery":"最后执行的语句","copy":"复制","copied":"已复制","colOrigin":"原始名称","primaryKey":"主键","rowsAndFields":"{{rows}} 行 × {{fields}} 列","noFields":"此语句未返回任何列。"},"rowForm":{"colColumn":"列","colValue":"值","insertTitle":"插入行","editTitle":"编辑行","loading":"正在加载列信息...","preview":"将执行的语句","nothingToWrite":"没有要写入的内容","insert":"插入","update":"更新","stageInsert":"添加为待提交行","stageEdit":"应用到网格","stageHint":"不执行,仅把值放入网格,稍后与其他修改一起提交。","inserted":"已向 {{table}} 插入一行","updated":"已更新 {{table}} 中的一行","confirmInsertTitle":"向 {{table}} 插入一行?","confirmUpdateTitle":"更新 {{table}} 中的一行?","inTransaction":"在已打开的事务中执行","pickDate":"选择日期","now":"当前时间","formatJson":"格式化","binaryUnsupported":"二进制列无法在此编辑;请保留 NULL/DEFAULT 或用 SQL 设置。","generateUuid":"生成 UUID","defaultValue":"默认值","clickToChange":"点击修改","empty":"(空)","autoHint":"由服务器自动生成","mode":{"keep":"保留","auto":"自动","value":"值"},"invalid":{"integer":"请输入整数","unsigned":"此列不接受负数","number":"请输入数字","json":"无效的 JSON","date":"请使用 YYYY-MM-DD","datetime":"请使用 YYYY-MM-DD HH:MM:SS","time":"请使用 HH:MM:SS","length":"最多 {{max}} 个字符"}},"history":{"copied":"已复制到剪贴板","searchPlaceholder":"搜索历史...","all":"全部","success":"成功","failed":"失败","thisTab":"仅当前标签","noMatch":"没有匹配的记录。","count":"{{count}} 条","clear":"清除","clearTitle":"清除查询历史?","clearDescription":"将删除此连接的全部 {{count}} 条记录。此操作无法撤销。","clearConfirm":"清除历史","insert":"插入编辑器","inserted":"已插入编辑器","copy":"复制","rows":"{{count}} 行","affected":"影响 {{count}} 行","today":"今天","yesterday":"昨天","empty":"没有查询历史记录。"},"json":{"arrayLength":"Array[{{count}}]","keys_other":"{{count}} 个键","invalid":"无效的 JSON","clickToView":"点击查看 JSON","expandAll":"全部展开","collapseAll":"全部折叠","edit":"编辑","view":"查看","copied":"已复制","copy":"复制","shortcutHint":"{{mod}}+Enter 保存 · Esc 取消","cancel":"取消","save":"保存"},"text":{"clickToView":"点击查看文本","size":"{{chars}} 字符 · {{lines}} 行","wrap":"自动换行"},"grid":{"readOnlyConnection":"只读连接","readOnlyWal":"只读:未加载 -wal 文件","readOnlyNoPk":"只读:表没有主键","commitTitle":"将 {{count}} 处更改提交到 {{table}}?","commitDescription":"将执行以下语句。","commitConfirm":"提交","rowPrefix":"第 {{row}} 行:","cancelled":"已取消","commitFailed":"提交失败:{{message}}","executedInTransaction":"已在打开的事务中执行 {{count}} 处更改 — 请在工具栏中点击“提交”使其永久生效(重新加载会回滚这些更改)","committed":"已将 {{count}} 处更改提交到 {{table}}","noData":"没有可显示的数据。","commit":"提交","discard":"放弃","addRow":"添加行","removeNewRow":"取消此新行","addRowForm":"用表单添加","addRowFormHint":"打开每列一个输入框的表单(以 INSERT 提交)","editRowForm":"用表单编辑此行","addRowHint":"添加新行(以 INSERT 提交)","delete":"删除","deleteCount":"删除({{count}})","deleteHint":"删除选中的行(以 DELETE 提交)。请通过行号列选择行。","field":"字段","searchPlaceholder":"搜索...","orderBy":"排序依据","none":"无","refresh":"刷新","dismiss":"关闭","clearSelection":"清除选择","columns":"列","showAllColumns":"全部显示","hideAllColumns":"全部隐藏","resetWidths":"重置列宽","selectAll":"选择所有行","emptyTable":"此表没有行。","noRows":"未返回任何行。","addARow":"添加一行","markedForDeletion":"已标记为删除 — 点击恢复","newRow":"新行","clickToSelect":"点击选择;按住 Shift/Ctrl 可多选","rows":"行数:{{count}}","rowsWithNew":"行数:{{count}}(+{{added}})","sortedBy":"排序:{{column}} {{direction}}","pageRange":"第 {{from}}–{{to}} 行","firstPage":"第一页","prevPage":"上一页","nextPage":"下一页","lastPage":"最后一页","pagingBlocked":"翻页前请提交或放弃更改","selected":"已选择 {{count}} 项","cellsModified":"已修改 {{count}} 个单元格","newCount":"新增 {{count}}","toDelete":"待删除 {{count}}","searchMode":"匹配方式","contains":"包含","equals":"等于","followLink":"打开 {{table}},其中 {{column}} = 值","linkColumn":"将“{{column}}”链接到其他表…","editLink":"编辑“{{column}}”的链接…","removeLink":"移除链接","copyValue":"复制值","filterByValue":"筛选:{{column}} = 此值","clearFilter":"清除筛选","copyColumnName":"复制列名","editCell":"编辑单元格","setNull":"设为 NULL","setEmpty":"设为空字符串","restoreRow":"恢复行","hideColumn":"隐藏列“{{column}}”","copyRowsTsv_other":"复制 {{count}} 行为 TSV(含表头)","copyRowsCsv_other":"复制 {{count}} 行为 CSV","copyRowsJson_other":"复制 {{count}} 行为 JSON","copyRowsInsert_other":"复制 {{count}} 行为 INSERT 语句","deleteRowsPending_other":"删除 {{count}} 行(提交前挂起)","sendRowsToScratchpad_other":"将 {{count}} 行发送到草稿板","sendAllToScratchpad":"将已加载的全部 {{count}} 行发送到草稿板","sentToScratchpad":"已将 {{count}} 行复制到草稿板表 {{table}}。","changesSince":"自上次加载:更改 {{changed}} · 新增 {{added}} · 消失 {{gone}}","changesToggle":"切换高亮显示自上次加载以来的变化","changesDismiss":"清除这些变化","previousValue":"之前的值:{{value}}","groupByValue":"按 {{column}} 分组统计"},"link":{"title":"将列链接到其他表","source":"列","hint":"该列的值将变成链接:点击后会打开目标表并筛选出匹配的行。真实的外键会自动链接。","targetDatabase":"目标数据库","targetTable":"目标表","targetColumn":"目标列","pickTable":"选择表","pickColumn":"选择列","remove":"移除链接","cancel":"取消","save":"保存链接","targetConnection":"目标连接","targetNotConnected":"链接的连接未打开。请先连接。"},"running":{"label":"正在查询…","elapsed":"{{seconds}} 秒","stop":"停止","stopping":"正在停止…","cannotCancel":"该引擎无法中断正在执行的语句。","agentOutdated":"本地代理版本过旧,无法停止查询。请用 `npx planche@latest`(或 `planche upgrade`)更新后重新连接。","cancelFailed":"无法连接到代理,查询未能停止。","abandoned":"已停止等待该请求。此引擎没有自带的取消功能,查询可能仍会在服务端执行完毕。"},"plan":{"empty":"运行\\"查看执行计划\\"(Ctrl+Shift+E)即可看到引擎将如何执行光标处的语句。","unreadable":"无法将计划解析为树形结构,直接显示引擎原始输出。","estimated":"估算值","analyzed":"实测值","estimatedHint":"优化器的估算值,语句并未执行。","analyzedHint":"语句已实际执行,行数与耗时为实测值。","totalCost":"最高节点成本","totalTime":"最慢节点","rows":"估算行数","actualRows":"实际行数","cost":"成本","time":"耗时","showRaw":"原始输出","showTree":"计划树","selectNode":"选择一个节点即可查看引擎对它的报告。","noDetails":"引擎没有报告该节点的其他信息。","warnings":{"fullScan":"全表扫描","noIndex":"无索引","estimateOff":"估算偏差","temporary":"临时表","filesort":"排序"},"hints":{"fullScan":"会读取表中的每一行。为过滤列建立索引即可避免。","noIndex":"引擎未找到可用于此次访问的索引。","estimateOff":"优化器估算的行数偏差很大,刷新表统计信息通常可以改善计划。","temporary":"进入下一步之前,行会被写入临时表。","filesort":"在索引之外进行排序。与 ORDER BY 匹配的索引可以省去这次排序。"}},"structure":{"empty":"运行\\"查询结构\\"(Ctrl+Shift+G) 可查看光标处语句的行来自何处。","notQuery":"只有 SELECT 语句才有结构图。","unsupported":"{{engine}} 语句无法解析为结构图。","parseError":"无法解析该语句:{{message}}","columns_other":"{{count}} 列","columnsUnknown":"列数未知","fit":"适应窗口","reveal":"在编辑器中选中","notDrawn":"未绘制:{{what}}","kindTable":"表","kindCte":"CTE","kindCteRef":"引用","kindDerived":"子查询","kindScalar":"标量","kindSetop":"集合","kindResult":"结果","fullscreen":"全屏","exitFullscreen":"退出全屏"}}'),p={defaultDescription:`此操作无法撤销。`,typeToConfirm:`输入 <name/> 以确认`,cancel:`取消`,confirm:`确认`,ok:`确定`},m={dialog:{createTitle:`创建表`,alterTitle:`修改表`,duplicateTitle:`复制表结构`,create:`创建`,alter:`修改`,cancel:`取消`,tableName:`表名`,tableNamePlaceholder:`输入表名...`,loading:`正在加载表架构...`,tabSchema:`架构`,tabIndexes:`索引`,tabProperties:`属性`,applying:`正在应用…`,cannotAlterColumns:`{{engine}} 无法修改已存在的列的定义({{columns}})。添加、删除、重命名列以及修改索引均可用;如需更改列定义,请重建表。`},schema:{colField:`字段名`,colType:`数据类型`,colLength:`长度`,colDefault:`默认值`,colPk:`主键`,colNotNull:`非空`,colUnsigned:`无符号`,colAutoIncrement:`自增`,colZerofill:`零填充`,colComment:`注释`,empty:`未定义任何列。点击“添加列”添加一列。`,add:`添加列`,remove:`移除列`},indexes:{colName:`索引名`,colType:`索引类型`,colColumns:`列`,empty:`未定义任何索引。点击“添加索引”添加一个。`,add:`添加索引`,remove:`移除索引`},index:{addTitle:`添加索引`,editTitle:`编辑索引`,name:`索引名`,namePlaceholder:`输入索引名`,type:`索引类型`,columns:`列`,noColumns:`没有可用的列。请先在“架构”标签页中定义列。`,unnamed:`(未命名)`,cancel:`取消`,ok:`确定`},properties:{engine:`引擎`,charset:`字符集`,collation:`排序规则`,autoIncrement:`自增值`,autoIncrementPlaceholder:`默认`,comment:`注释`},info:{engine:`引擎`,version:`版本`,rowFormat:`行格式`,rows:`行数`,avgRowLength:`平均行长度`,dataLength:`数据长度`,createTime:`创建时间`,updateTime:`更新时间`,collation:`排序规则`,comment:`注释`},copy:{title:`复制表`,source:`源`,targetConnection:`目标连接`,targetDatabase:`目标数据库`,targetTable:`目标表名`,what:`复制内容`,structureAndData:`结构和数据`,structureOnly:`仅结构`,ifExists:`目标表已存在时`,abort:`中止(默认)`,dropAndRecreate:`删除并重建(需重新输入名称确认)`,preview:`在目标上执行的 CREATE TABLE(可编辑)`,crossEngineHint:`目标是 {{engine}}:请检查下方的类型,MySQL 专有属性已被移除。`,readOnly:`只读`,loading:`加载中…`,progressCreate:`正在创建表…`,progressCount:`正在统计行数…`,progressRows:`已复制 {{copied}} / {{total}} 行`,progressDone:`完成`,doneTitle:`表已复制`,doneRows:`已将 {{count}} 行复制到 {{table}}。`,doneStructure:`已创建 {{table}} 的结构。`,noColumns:`源表没有列。`,exists:`目标中已存在表 {{table}}。请换一个名称或选择“删除并重建”。`,dropTitle:`删除现有表 {{table}}?`,dropDescription:`复制前将删除目标表及其全部行。此操作无法撤销。`,dropConfirm:`删除并复制`,cancelled:`复制已取消。`,stop:`停止`,cancel:`取消`,copy:`复制`}},h={copy:{title:`复制数据库`,source:`源数据库`,target:`目标数据库名`,targetPlaceholder:`输入目标数据库名`,options:`选项`,structureAndData:`结构和数据`,structureOnly:`仅结构`,cancel:`取消`,copy:`复制`,creating:`正在创建 {{database}}…`,copying:`正在复制 {{table}}({{index}}/{{total}})…`},diff:{title:`比较架构`,source:`源`,target:`目标`,pickConnection:`连接`,pickDatabase:`数据库`,crossEngineHint:`引擎不同:类型名称因方言而异,大多数列会显示为类型变更。`,sameSide:`源和目标是同一个数据库。`,summary:`已更改 {{changed}},目标缺少 {{missingTarget}},仅目标有 {{missingSource}},相同 {{identical}}`,showIdentical:`显示相同的表`,identicalAll:`表完全相同。`,column:`列`,index:`索引`,object:`对象`,selectTable:`选择一个表以查看差异。`,missingInTarget:`目标中不存在 {{table}};脚本将创建它。`,missingInSource:`{{table}} 仅存在于目标中;脚本将删除它(除非包含 DROP,否则为注释)。`,includeDrops:`将 DROP 语句作为可执行 SQL 包含(默认:注释掉)`,tabTitle:`同步 {{database}}`,close:`关闭`,compare:`比较`,comparing:`比较中…`,openScript:`在编辑器中打开脚本`,noDefinition:`无法获取 CREATE 语句`},create:{title:`创建数据库`,name:`数据库名`,namePlaceholder:`输入数据库名`,charset:`字符集`,collation:`排序规则`,cancel:`取消`,create:`创建`},csv:{title:`下载为 {{format}}`,target:`目标`,targetQueryResult:`当前查询结果`,targetTableData:`表数据`,tableName:`表名`,tableNamePlaceholder:`输入表名`,delimiter:`分隔符`,delimiterComma:`逗号 (,)`,delimiterTab:`制表符 (\\t)`,delimiterSemicolon:`分号 (;)`,delimiterPipe:`竖线 (|)`,includeHeaders:`包含表头`,cancel:`取消`,download:`下载`,downloading:`正在下载...`,progress:`已写入 {{loaded}} / {{total}} 行`,progressUnknown:`已写入 {{loaded}} 行`,stop:`停止`,done:`已将 {{table}} 的 {{count}} 行导出为 {{format}}。`,database:`数据库`,databasePlaceholder:`选择数据库`},html:{title:`架构导出为 HTML`,database:`数据库`,selectDatabase:`选择数据库`,tables:`要包含的表`,selectAll:`全选`,deselectAll:`全不选`,noTables:`没有可用的表。`,include:`包含`,includeColumns:`列`,includeIndexes:`索引`,includeProperties:`属性`,cancel:`取消`,generate:`生成`,generating:`正在生成...`,sectionColumns:`列`,sectionIndexes:`索引`,sectionProperties:`属性`,docTitle:`架构:{{database}}`,heading:`数据库:{{database}}`,summary:`表数:{{count}} | 生成时间:{{date}}`,footer:`由 Planche 2026 生成`},dataDiff:{title:`比较数据`,pickTable:`表`,hint:`按源表主键匹配行,并以文本形式比较值。每侧最多加载 {{cap}} 行;大表请先用筛选缩小范围。`,sameSide:`源和目标是同一张表。`,noPrimaryKey:`{{table}} 没有主键,无法匹配行。`,keyMissingInTarget:`目标表缺少键列:{{columns}}`,summary:`键:{{key}} — 目标缺少 {{added}},不同 {{changed}},仅目标有 {{removed}},相同 {{identical}}`,capped:`两侧都只比较了前 {{cap}} 行。`,ignoredColumns:`忽略的列(仅一侧存在):{{columns}}`,added_other:`目标缺少 {{count}}`,changed_other:`不同 {{count}}`,removed_other:`仅目标有 {{count}}`,none:`此分组中没有内容。`,more:`… 还有 {{count}} 条未列出`,includeDeletes:`将 DELETE 语句作为可执行 SQL 包含(默认:注释掉)`,tabTitle:`同步数据 {{table}}`,loading:`正在加载行——源:{{source}},目标:{{target}}`},schema:{createTitle:`创建模式`,name:`模式名称`,namePlaceholder:`输入模式名称`,create:`创建`,cancel:`取消`},groupBy:{title:`分组统计`,description:`按所选列对 {{table}} 的行进行分组计数。`,columns:`分组列`,aggregate:`附加聚合`,countOnly:`仅计数`,column:`列`,minCount:`每组最少行数`,useFilter:`应用网格当前的筛选`,noIndexWarning:`所选列都不是索引的首列,数据库需要读取并排序整张表。在大表上可能会很慢。`,preview:`查询`,pickColumn:`请至少选择一个分组列。`,openInTab:`在新标签页中打开`,run:`运行`,tabTitle:`{{table}} 分组统计`,indexed:`索引首列`,connection:`连接`,database:`数据库`,table:`表`}},g={manager:{title:`用户管理`,addUser:`添加用户`,removeUser:`移除用户`,noUsers:`未加载用户`,grantScope:`授权范围`,apply:`应用`,close:`关闭`,removed:`用户 '{{user}}'@'{{host}}' 已移除`,selectUserFirst:`请先选择一个用户`,applied:`更改已成功应用`,noChanges:`没有需要应用的权限更改。`},add:{title:`添加用户`,username:`用户名`,usernamePlaceholder:`输入用户名`,host:`主机`,password:`密码`,passwordPlaceholder:`输入密码`,confirmPassword:`确认密码`,confirmPasswordPlaceholder:`再次输入密码`,plugin:`插件`,cancel:`取消`,add:`添加`,usernameRequired:`用户名为必填项`,passwordMismatch:`两次输入的密码不一致`,added:`用户 '{{user}}'@'{{host}}' 已添加`},privileges:{globalTitle:`全局权限`,databaseTitle:`数据库权限`,tableTitle:`表权限`,checkAll:`全选`,uncheckAll:`全不选`,categoryData:`数据`,categoryStructure:`结构`,categoryAdministration:`管理`},grantTree:{globalPrivileges:`全局权限`}},_={close:`关闭`,noActiveConnection:`没有活动连接`,variableName:`变量名`,value:`值`,scope:{session:`会话`,global:`全局`},findReplace:{findPlaceholder:`查找`,replacePlaceholder:`替换`,found:`找到 {{count}} 处`,noResults:`无结果`,previous:`上一个`,next:`下一个`,close:`关闭`,replace:`替换`,all:`全部`,caseSensitive:`区分大小写`,regex:`正则表达式`,wholeWord:`全字匹配`},flush:{title:`Flush`,executed:`已执行:{{command}}`,executeError:`执行 {{command}} 时出错:{{message}}`},localHistory:{title:`本地历史`,description:`此连接的编辑器文本版本:运行时、停止输入后以及关闭标签页时保存。`,empty:`尚未记录任何版本。`,noMatch:`没有与搜索匹配的版本。`,notPersisted:`设置 > 安全 中的“重新加载后保留查询历史”已关闭,版本仅在本次会话中保留。`,searchPlaceholder:`搜索版本`,scopeTab:`当前标签页`,scopeAll:`所有标签页`,compareCurrent:`与当前比较`,comparePrevious:`与上一版本比较`,diffAgainstCurrent:`与当前编辑器内容比较`,diffAgainstPrevious:`与 {{time}} 的版本比较`,noPrevious:`没有可比较的更早版本`,restored:`已从本地历史恢复编辑器内容`,restore:`恢复此版本`,openInNewTab:`在新标签页中打开`,openedInTab:`已在新标签页中打开该版本`,delete:`删除此版本`,clearAll:`清除历史`,chars:`{{count}} 个字符`,reason:{execute:`运行前`,edit:`编辑期间`,replaced:`覆盖前`,restore:`恢复前`,close:`关闭前`}},processList:{title:`进程列表`,refresh:`刷新`,autoRefresh:`自动刷新`,empty:`没有可显示的进程`,kill:`终止`,killProcess:`终止进程`,selectToKill:`请选择要终止的进程`,killed:`进程 {{id}} 已成功终止`,killError:`终止进程时出错:{{message}}`,loadError:`加载进程列表时出错:{{message}}`,updatedAt:`{{time}} 更新`,filterPlaceholder:`按用户、主机、数据库、SQL 筛选...`,hideIdle:`隐藏空闲`,noMatch:`没有符合筛选条件的进程`,self:`本会话`,selfHint:`这是 Planche 自身的会话`,statementOf:`#{{id}} 的语句`,noStatement:`无正在执行的语句`,copy:`复制`,copied:`已复制`,killConfirmTitle:`终止进程 {{id}}?`,killConfirmDescription:`{{user}}@{{host}} 的会话将被终止,正在执行的语句将被中止。未提交的事务将回滚。`,stats:{total:`总计`,active:`活动`,idle:`空闲`,longest:`最长运行`},columns:{id:`Id`,user:`用户`,host:`主机`,db:`db`,command:`命令`,time:`时间`,state:`状态`,info:`信息`,action:`操作`}},status:{title:`服务器状态`,filterPlaceholder:`筛选状态变量...`,empty:`没有可显示的状态变量`,loadError:`加载状态时出错:{{message}}`},variables:{title:`服务器变量`,filterPlaceholder:`筛选变量...`,empty:`没有可显示的变量`,loadError:`加载变量时出错:{{message}}`}},v={empty:{title:`打开 Prisma 架构文件(.prisma)以查看 ERD`,description:`将自动分析模型、枚举和关系`,openFile:`打开 .prisma 文件`,dropHint:`或将文件拖放到此区域`},entity:{enumBadge:`ENUM`,modelBadge:`MODEL`,columns:{value:`值`,comment:`注释`,type:`类型`,column:`列`},linkBadge:`链接`,externalTitle:`{{location}} 上的链接表(列链接,非真实外键)`,nullable:`允许 NULL 的列`},toolbar:{refresh:`刷新`,zoomIn:`放大`,zoomOut:`缩小`,resetView:`重置视图`,center:`居中`,fitAll:`适应全部`,spreadAll:`解决重叠`,resetLayout:`重置布局`,legendOneToMany:`1:N (FK)`,tables:`表:`,relations:`关系:`,columns:`列:`,fullscreen:`全屏`,exitFullscreen:`退出全屏`},viewer:{noServerConnection:`没有活动的服务器连接`,loading:`正在从 {{database}} 加载架构...`,loadFailed:`加载 ERD 失败`,noDatabase:`未选择数据库。`,selectDatabaseHint:`请在架构树中选择一个数据库,然后打开“查看 ERD”。`}},y={runAnyway:`仍然运行`,query:{rowsReturned:`返回 {{count}} 行`,rowsAffected:`影响 {{count}} 行`,rowsReturnedLimited:`返回 {{count}} 行(已限制为 {{limit}} 行;添加 LIMIT 以获取更多)`,notConnected:`未连接`,fileNotOpen:`SQLite 文件尚未打开 — 请点击上方的“重新打开文件”再次授权访问。`,failed:`查询失败`,nothingToExecute:`没有可执行的内容`,dryRunMismatch:`试运行预计 {{predicted}} 行,实际更改了 {{actual}} 行。预览之后数据可能已发生变化;如果没有,则说明预览与该语句不匹配。`},destructive:{title_other:`运行 {{count}} 条破坏性语句?`,description:`以下操作将永久修改或删除数据。此操作无法撤销。`,unknownTarget:`(未知)`,deleteAll:`DELETE {{target}} 中的所有行`,updateAll:`UPDATE {{target}} 中的所有行`,alterDrop:`对 {{target}} 执行 DROP COLUMN/PARTITION`},readOnly:{refused:`连接“{{label}}”为只读。有 {{count}} 条语句会修改数据或架构。`,title:`“{{label}}”为只读`,description:`这些语句会修改数据或架构。仍要在此连接上运行吗?`},transaction:{startFailed:`无法启动事务`,started:`事务已启动 — 完成后请提交或回滚`,implicitCommit:`{{kind}} 导致当前打开的事务被隐式 COMMIT`,committed:`事务已提交`,rolledBack:`事务已回滚`,commandFailed:`{{name}} 失败`,commandFailedWith:`{{name}} 失败:{{message}}`},save:{notBrowserSqlite:`不是浏览器 SQLite 连接。`,inMemory:`内存数据库:只能导出为下载文件。`,noFileSystemAccess:`此浏览器不支持 File System Access API(仅 Chrome/Edge 支持):数据库将导出为下载文件,而不是就地写入。`,noWritableHandle:`文件打开时没有可写句柄:将导出为下载文件。`},agent:{devProxyUrl:`{{url}}(通过开发代理)`,notPlanche:`收到了响应,但它不是 Planche 代理`,unreachable:"无法在 {{url}} 访问 Planche 代理 — 请运行 `npx planche`({{message}})",httpError:`HTTP 错误:{{status}} {{statusText}}`,emptyResponse:`隧道服务器返回了空响应`,reconnected:`已重新连接到 {{name}} — 代理曾断开该连接(重启或空闲超时)。`},sample:{profileName:`示例商店(浏览器内)`,downloadFailed:`无法下载示例数据库({{status}})`,tabTitle:`查询 1`},sqliteFile:{tooSmall:`文件太小,不是 SQLite 数据库。`,notSqlite:`不是 SQLite 数据库(或已加密,例如 SQLCipher)。其 16 字节文件头不是“SQLite format 3”。`,badPageSize:`SQLite 文件头损坏:无效的页大小 {{size}}。`,unreadable:`SQLite 无法读取该文件:{{message}}`,pickerDescription:`SQLite 数据库`,walNotLoaded:`此数据库处于 WAL 模式,且其 -wal 文件尚未加载。请先加载它,或在横幅中确认不存在 -wal 文件,然后再保存。`,changedOnDisk:`{{name}} 在加载后于磁盘上被修改(另一个程序写入了它)。保存会覆盖这些更改 — 请重新打开文件并重做您的编辑,或改用隧道服务器。`,walHasChanges:`{{name}}-wal 包含新的更改;请在保存前加载它。`,walChangedOnDisk:`{{name}}-wal 在加载后被另一个程序写入;请在保存前重新打开文件。`,writeDenied:`未授予对 {{name}} 的写入权限。请在浏览器提示中允许,或改为导出为下载文件。`},environment:{none:`无`,green:`绿色(开发)`,blue:`蓝色`,yellow:`黄色(预发布)`,orange:`橙色`,red:`红色(生产)`,purple:`紫色`},scratchpad:{profileName:`草稿板`,namePromptTitle:`草稿板表名`,namePromptDescription:`草稿板中已存在名为 {{table}} 的表。请输入其他名称。`,nameTaken:`表 {{table}} 已存在。`},federated:{pulling:`正在从 {{connection}} 拉取 {{table}}…`,capped:`{{table}}:只拉取了前 {{limit}} 行。`,templateLine1:`用 "连接名".database.table 引用任意已打开连接的表;语句运行前会把它复制到此草稿板。`,templateLine2:`每个表最多 {{limit}} 行。查询本身在浏览器内的 SQLite 中运行。`,templateConnections:`已打开的连接:{{names}}`,templateNone:`尚未打开其他连接。请先连接,然后在这里引用。`,done:`已从 {{tables}} 个远程表拉取 {{rows}} 行到草稿板。`,pullingProgress:`正在从 {{connection}} 拉取 {{table}}:{{loaded}} / {{total}} 行…`},paged:{noColumns:`{{table}} 没有列。`,cancelled:`已取消。`}},b={title:`使用条款`,version:`版本 {{version}}`,englishOnly:`条款全文以英文提供。欢迎页面上的摘要以您的语言显示。`,privacyLink:`隐私政策`,refundLink:`退款政策`,online:`在 planche.dev 上阅读`,updated:`最后更新 {{date}}`},x={title:`{{kind}} 将影响 {{count}} 行`,titleUnknown:`{{kind}} — 受影响行数未知`,description:`这是该语句此刻会触及的行,用 SELECT 预先读取。尚未写入任何内容。`,previewFailed:`预览查询失败:{{error}}
2
- 你仍然可以运行该语句。`,noRows:`没有匹配的行——该语句不会改变任何内容。`,truncated:`显示 {{count}} 行中的前 {{shown}} 行。`,previewQuery:`预览查询`,run:`运行 {{kind}}({{count}} 行)`,runAnyway:`仍然运行`},S={badge:`PRO`,tooltip:`需要 Pro 许可证。`,noticeTitle:`Pro 功能`,notice:`标有 PRO 的功能需要 Pro 许可证。`,licenseTitle:`Planche Pro`,licenseDescription:`粘贴购买邮件中的许可证密钥。校验在本机完成,不会发送到任何地方。`,blocked:`{{feature}}需要 Pro 许可证。`,keyLabel:`许可证密钥`,activate:`激活`,remove:`移除许可证`,active:`Pro 已激活。`,licensedTo:`授权给 {{email}}`,validUntil:`有效期至 {{date}}`,expiredOn:`此许可证已于 {{date}} 到期。续订后可继续使用 Pro 功能。`,invalidKey:`这不是 Planche 的许可证密钥。`,notConfigured:`此版本无法校验许可证密钥,请反馈给我们。`,noWebcrypto:`此浏览器无法校验许可证密钥。`,pricing:`查看价格`,features:{ssh_tunnel:`SSH 隧道`,compare_schemas:`架构比较`,compare_data:`数据比较`,copy_table:`复制表`,dry_run:`试运行`,federated:`联邦查询`,scratchpad:`草稿库`,column_link:`列链接`,sync:`连接同步`,ai_explain:`AI 解释`},included:`Pro 包含的功能`,haveKey:`已经有许可证密钥了?`,perMonth:`/ 月`,priceNote:`每年一次性收取 {{annual}}。按月付费为 {{monthly}}。`,featureDetails:{sync:`在浏览器中加密后,在你的所有电脑上使用同一套配置`,ssh_tunnel:`通过密码、密钥或 ssh-agent 连接跳板机后的数据库`,compare_schemas:`比较两个已打开的连接并生成 ALTER 脚本`,compare_data:`比较两张表的行并生成 INSERT、UPDATE 脚本`,copy_table:`在另一个连接、甚至另一种数据库上重建表`,dry_run:`执行前查看 UPDATE、DELETE 会改动多少行以及哪些行`,federated:`连接不同数据库连接中的表`,scratchpad:`存放工作数据的本地 SQLite 数据库`,column_link:`可在网格中跳转的虚拟外键`,ai_explain:`让模型解释语句为何失败、计划为何缓慢 — 并附上你的表结构`}},C={npxNote:`需要 Node.js 22 或更高版本。不会永久安装任何东西 —— npx 直接从 npm 仓库运行代理。`,installNote:`不需要 Node.js。它只安装在你的主目录中,无需管理员权限;之后用 planche 命令随时启动。`},w={unsupported:`{{engine}} 不提供执行计划。`,oneStatement:`执行计划一次只分析一条语句。请把光标放在目标语句上,或选中它。`},T={title:`AI 助手`,intro:`让它写查询,或直接下指令 —— 它会读取结构、在标签页里写 SQL 并执行。它只作用于你当前打开的连接,每个连接各有各的对话。`,privacy:`工具读取到的内容(包括示例行)会发送给你配置的 provider。不会有任何内容发往 planche.dev。`,placeholder:`例如:在演示数据库上做一个按月营收的查询`,send:`发送`,stop:`停止`,clear:`新会话`,working:`执行中…`,tabTitle:`AI 查询`,approvalTitle:`这一步会写入。要执行吗?`,approve:`执行`,reject:`跳过`,rejected:`用户拒绝执行。`,notConfigured:`代理上没有配置 AI 密钥。请在 设置 ▸ AI 中添加。`,needsAgent:`该本地代理还不支持工具调用。请更新后重新配对。`,failed:`失败`,empty:`还没有提问。`,steps:`{{count}} 步`,tooManySteps:`已进行 {{count}} 步仍未得出答案。`,collapse:`收起`,planWarningTitle:`这个查询会全表扫描。仍要执行吗?`,interrupted:`因刷新而中断。`,external:`来自 Planche 之外的请求`},E={title:`连接 AI 代理 (MCP)`,description:`让支持 MCP 的 AI 代理使用 Planche 的工具。`,readsLabel:`读取`,reads:`它会读取打开的数据库,结果发给那个程序。`,writesLabel:`写入`,writes:`写入数据的语句需要你确认。DROP 和 TRUNCATE 无法执行。`,needsLabel:`前提`,needs:`AI 面板必须打开。`,tokenLabel:`令牌`,token:`一个令牌,给出去的程序共用。吊销后全部断开。`,command:`添加到 Claude Code`,json:`手动配置`,stored:`保存在 {{path}}。`,revoke:`吊销令牌`,revoked:`已吊销。要签发新的,请重新打开此窗口。`},D={title:`连接同步`,description:`连接配置在本浏览器中加密后保存到 planche.dev,你的其他电脑可以直接使用。`,stored:`服务端只存放一个加密数据块,无法读取你的主机、用户名、密码或 SSH 密钥。`,unavailable:`同步仅在 planche.dev 上可用。当前这份 Planche 由本地代理提供,而代理被限制不能访问外部网络。`,signIn:`使用 GitHub 登录`,signedInAs:`已登录:{{email}}`,signOut:`退出登录`,createTitle:`设置密码短语`,createHint:`这个密码短语用于加密你的配置。它不会发送到服务器,因此一旦丢失,已保存的副本将无法恢复——只能在仍有配置的电脑上重新创建。`,passphrase:`密码短语`,confirm:`确认密码短语`,mismatch:`两次输入的密码短语不一致。`,tooShort:`请至少输入 {{count}} 个字符。`,enable:`开启同步`,unlockTitle:`解锁你的配置`,unlockHint:`请输入开启同步时设置的密码短语。`,unlock:`解锁`,wrongPassphrase:`密码短语错误,或已保存的副本已损坏。`,syncNow:`立即同步`,lastSynced:`上次同步 {{when}}`,neverSynced:`尚未同步`,profiles_one:`{{count}} 个配置`,profiles_other:`{{count}} 个配置`,changePassphrase:`修改密码短语`,deleteVault:`从服务器删除`,deleteVaultConfirm:`要删除 planche.dev 上的加密副本吗?本机的配置不受影响。`,offline:`无法连接 planche.dev。`,working:`处理中…`,serverError:`planche.dev 未能完成该操作,请稍后重试。`,signInShort:`登录`,needsPro:`已登录。同步配置需要 Pro 许可证,获得后即可使用。`,deleteAccount:`删除账号`,deleteAccountConfirm:`要删除账号吗?已保存的副本和登录信息会一并删除。本机的配置不受影响。`,notDeployed:`本站点尚未启用连接同步。`},O={app:e,language:t,settings:n,menu:r,about:i,connection:a,toolbar:o,footer:s,palette:c,welcome:l,schema:u,query:d,result:f,confirm:p,table:m,database:h,user:g,command:_,erd:v,services:y,terms:b,dryRun:x,pro:S,install:C,explain:w,ai:T,mcp:E,sync:D};export{i as about,T as ai,e as app,_ as command,p as confirm,a as connection,h as database,O as default,x as dryRun,v as erd,w as explain,s as footer,C as install,t as language,E as mcp,r as menu,c as palette,S as pro,d as query,f as result,u as schema,y as services,n as settings,D as sync,m as table,b as terms,o as toolbar,g as user,l as welcome};
2
+ 你仍然可以运行该语句。`,noRows:`没有匹配的行——该语句不会改变任何内容。`,truncated:`显示 {{count}} 行中的前 {{shown}} 行。`,previewQuery:`预览查询`,run:`运行 {{kind}}({{count}} 行)`,runAnyway:`仍然运行`},S={badge:`PRO`,tooltip:`需要 Pro 许可证。`,noticeTitle:`Pro 功能`,notice:`标有 PRO 的功能需要 Pro 许可证。`,licenseTitle:`Planche Pro`,licenseDescription:`粘贴购买邮件中的许可证密钥。校验在本机完成,不会发送到任何地方。`,blocked:`{{feature}}需要 Pro 许可证。`,keyLabel:`许可证密钥`,activate:`激活`,remove:`移除许可证`,active:`Pro 已激活。`,licensedTo:`授权给 {{email}}`,validUntil:`有效期至 {{date}}`,expiredOn:`此许可证已于 {{date}} 到期。续订后可继续使用 Pro 功能。`,invalidKey:`这不是 Planche 的许可证密钥。`,notConfigured:`此版本无法校验许可证密钥,请反馈给我们。`,noWebcrypto:`此浏览器无法校验许可证密钥。`,pricing:`查看价格`,features:{ssh_tunnel:`SSH 隧道`,compare_schemas:`架构比较`,compare_data:`数据比较`,copy_table:`复制表`,dry_run:`试运行`,federated:`联邦查询`,scratchpad:`草稿库`,column_link:`列链接`,sync:`连接同步`,ai_explain:`AI 解释`},included:`Pro 包含的功能`,haveKey:`已经有许可证密钥了?`,perMonth:`/ 月`,priceNote:`每年一次性收取 {{annual}}。按月付费为 {{monthly}}。`,featureDetails:{sync:`在浏览器中加密后,在你的所有电脑上使用同一套配置`,ssh_tunnel:`通过密码、密钥或 ssh-agent 连接跳板机后的数据库`,compare_schemas:`比较两个已打开的连接并生成 ALTER 脚本`,compare_data:`比较两张表的行并生成 INSERT、UPDATE 脚本`,copy_table:`在另一个连接、甚至另一种数据库上重建表`,dry_run:`执行前查看 UPDATE、DELETE 会改动多少行以及哪些行`,federated:`连接不同数据库连接中的表`,scratchpad:`存放工作数据的本地 SQLite 数据库`,column_link:`可在网格中跳转的虚拟外键`,ai_explain:`让模型解释语句为何失败、计划为何缓慢 — 并附上你的表结构`}},C={npxNote:`需要 Node.js 22 或更高版本。不会永久安装任何东西 —— npx 直接从 npm 仓库运行代理。`,installNote:`不需要 Node.js。它只安装在你的主目录中,无需管理员权限;之后用 planche 命令随时启动。`},w={unsupported:`{{engine}} 不提供执行计划。`,oneStatement:`执行计划一次只分析一条语句。请把光标放在目标语句上,或选中它。`},T={title:`AI 助手`,intro:`让它写查询,或直接下指令 —— 它会读取结构、在标签页里写 SQL 并执行。它只作用于你当前打开的连接,每个连接各有各的对话。`,privacy:`工具读取到的内容(包括示例行)会发送给你配置的 provider。不会有任何内容发往 planche.dev。`,placeholder:`例如:在演示数据库上做一个按月营收的查询`,send:`发送`,stop:`停止`,clear:`新会话`,working:`执行中…`,tabTitle:`AI 查询`,approvalTitle:`这一步会写入。要执行吗?`,approve:`执行`,reject:`跳过`,rejected:`用户拒绝执行。`,notConfigured:`代理上没有配置 AI 密钥。请在 设置 ▸ AI 中添加。`,needsAgent:`该本地代理还不支持工具调用。请更新后重新配对。`,failed:`失败`,empty:`还没有提问。`,steps:`{{count}} 步`,tooManySteps:`已进行 {{count}} 步仍未得出答案。`,collapse:`收起`,planWarningTitle:`这个查询会全表扫描。仍要执行吗?`,interrupted:`因刷新而中断。`,external:`来自 Planche 之外的请求`},E={title:`连接 AI 代理 (MCP)`,description:`让支持 MCP 的 AI 代理使用 Planche 的工具。`,readsLabel:`读取`,reads:`它会读取打开的数据库,结果发给那个程序。`,writesLabel:`写入`,writes:`写入数据的语句需要你确认。DROP 和 TRUNCATE 无法执行。`,needsLabel:`前提`,needs:`AI 面板必须打开。`,tokenLabel:`令牌`,token:`一个令牌,给出去的程序共用。吊销后全部断开。`,command:`添加到 Claude Code`,json:`手动配置`,stored:`保存在 {{path}}。`,revoke:`吊销令牌`,revoked:`已吊销。要签发新的,请重新打开此窗口。`},D={title:`连接同步`,description:`连接配置在本浏览器中加密后保存到 planche.dev,你的其他电脑可以直接使用。`,stored:`服务端只存放一个加密数据块,无法读取你的主机、用户名、密码或 SSH 密钥。`,unavailable:`同步仅在 planche.dev 上可用。当前这份 Planche 由本地代理提供,而代理被限制不能访问外部网络。`,signIn:`使用 GitHub 登录`,signedInAs:`已登录:{{email}}`,signOut:`退出登录`,createTitle:`设置密码短语`,createHint:`这个密码短语用于加密你的配置。它不会发送到服务器,因此一旦丢失,已保存的副本将无法恢复——只能在仍有配置的电脑上重新创建。`,passphrase:`密码短语`,confirm:`确认密码短语`,mismatch:`两次输入的密码短语不一致。`,tooShort:`请至少输入 {{count}} 个字符。`,enable:`开启同步`,unlockTitle:`解锁你的配置`,unlockHint:`请输入开启同步时设置的密码短语。`,unlock:`解锁`,wrongPassphrase:`密码短语错误,或已保存的副本已损坏。`,syncNow:`立即同步`,lastSynced:`上次同步 {{when}}`,neverSynced:`尚未同步`,profiles_one:`{{count}} 个配置`,profiles_other:`{{count}} 个配置`,changePassphrase:`修改密码短语`,deleteVault:`从服务器删除`,deleteVaultConfirm:`要删除 planche.dev 上的加密副本吗?本机的配置不受影响。`,offline:`无法连接 planche.dev。`,working:`处理中…`,serverError:`planche.dev 未能完成该操作,请稍后重试。`,signInShort:`登录`,needsPro:`已登录。同步配置需要 Pro 许可证,获得后即可使用。`,deleteAccount:`删除账号`,deleteAccountConfirm:`要删除账号吗?已保存的副本和登录信息会一并删除。本机的配置不受影响。`,notDeployed:`本站点尚未启用连接同步。`},O={closeTitle:`关闭 Planche?`,closeDescription:`有未保存的工作:打开的事务、未提交的编辑或正在运行的查询。关闭会丢弃它们并回滚。`,closeAnyway:`仍然关闭`},k={app:e,language:t,settings:n,menu:r,about:i,connection:a,toolbar:o,footer:s,palette:c,welcome:l,schema:u,query:d,result:f,confirm:p,table:m,database:h,user:g,command:_,erd:v,services:y,terms:b,dryRun:x,pro:S,install:C,explain:w,ai:T,mcp:E,sync:D,desktop:O};export{i as about,T as ai,e as app,_ as command,p as confirm,a as connection,h as database,k as default,O as desktop,x as dryRun,v as erd,w as explain,s as footer,C as install,t as language,E as mcp,r as menu,c as palette,S as pro,d as query,f as result,u as schema,y as services,n as settings,D as sync,m as table,b as terms,o as toolbar,g as user,l as welcome};