diff --git a/webapp/dist/assets/index-BQfwpP6V.js b/webapp/dist/assets/index-yJGRNYQc.js
similarity index 99%
rename from webapp/dist/assets/index-BQfwpP6V.js
rename to webapp/dist/assets/index-yJGRNYQc.js
index e573cfb..f45880c 100644
--- a/webapp/dist/assets/index-BQfwpP6V.js
+++ b/webapp/dist/assets/index-yJGRNYQc.js
@@ -32,7 +32,7 @@ b`.split(/\n/).length!=3?function(e){for(var t=0,i=[],r=e.length;t<=r;){var n=e.
* SPDX-License-Identifier: BSD-3-Clause
*/const Si=globalThis,dn=Si.trustedTypes,Pa=dn?dn.createPolicy("lit-html",{createHTML:O=>O}):void 0,Za="$lit$",qt=`lit$${(Math.random()+"").slice(9)}$`,Qa="?"+qt,Cf=`<${Qa}>`,gr=document,Ti=()=>gr.createComment(""),ki=O=>O===null||typeof O!="object"&&typeof O!="function",Ja=Array.isArray,Sf=O=>Ja(O)||typeof(O==null?void 0:O[Symbol.iterator])=="function",Ll=`[
\f\r]`,wi=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,Ba=/-->/g,Ra=/>/g,hr=RegExp(`>|${Ll}(?:([^\\s"'>=/]+)(${Ll}*=${Ll}*(?:[^
-\f\r"'\`<>=]|("|')|))|$)`,"g"),za=/'/g,Ua=/"/g,ja=/^(?:script|style|textarea|title)$/i,Lf=O=>(m,...S)=>({_$litType$:O,strings:m,values:S}),dr=Lf(1),xi=Symbol.for("lit-noChange"),Ye=Symbol.for("lit-nothing"),Ga=new WeakMap,cr=gr.createTreeWalker(gr,129);function Va(O,m){if(!Array.isArray(O)||!O.hasOwnProperty("raw"))throw Error("invalid template strings array");return Pa!==void 0?Pa.createHTML(m):m}const Tf=(O,m)=>{const S=O.length-1,N=[];let k,z=m===2?"":"")),N]};class Ai{constructor({strings:m,_$litType$:S},N){let k;this.parts=[];let z=0,h=0;const c=m.length-1,d=this.parts,[v,b]=Tf(m,S);if(this.el=Ai.createElement(v,N),cr.currentNode=this.el.content,S===2){const w=this.el.content.firstChild;w.replaceWith(...w.childNodes)}for(;(k=cr.nextNode())!==null&&d.length0){k.textContent=dn?dn.emptyScript:"";for(let _=0;_2||N[0]!==""||N[1]!==""?(this._$AH=Array(N.length-1).fill(new String),this.strings=N):this._$AH=Ye}_$AI(m,S=this,N,k){const z=this.strings;let h=!1;if(z===void 0)m=Rr(this,m,S,0),h=!ki(m)||m!==this._$AH&&m!==xi,h&&(this._$AH=m);else{const c=m;let d,v;for(m=z[0],d=0;d{const N=(S==null?void 0:S.renderBefore)??m;let k=N._$litPart$;if(k===void 0){const z=(S==null?void 0:S.renderBefore)??null;N._$litPart$=k=new _i(m.insertBefore(Ti(),z),z,void 0,S??{})}return k._$AI(O),k};function Df(){return window.crypto.getRandomValues(new Uint32Array(1))[0]}function Al(O,m=!1){const S=Df(),N=`_${S}`;return Object.defineProperty(window,N,{value:k=>(m&&Reflect.deleteProperty(window,N),O==null?void 0:O(k)),writable:!1,configurable:!0}),S}async function es(O,m={}){return new Promise((S,N)=>{const k=Al(h=>{S(h),Reflect.deleteProperty(window,`_${z}`)},!0),z=Al(h=>{N(h),Reflect.deleteProperty(window,`_${k}`)},!0);window.__TAURI_IPC__({cmd:O,callback:k,error:z,...m})})}async function Ml(O){return es("tauri",O)}async function Nf(O=0){return Ml({__tauriModule:"Process",message:{cmd:"exit",exitCode:O}})}function kl(O){return O.type=="Text"?O.value:null}const _l="__TAURI__"in globalThis;async function ts(O,m,S){if(_l){let N={};return S!=null&&(N={result:S}),await es(O,N)}else return await rs(O,m,S)}async function rs(O,m,S){let N=null,k={};S!=null&&(N=JSON.stringify(S),k["Content-Type"]="application/json");const z=await fetch(`/api/${O}`,{method:m,body:N,headers:k});if(z.ok)return await z.json();{let h="";throw z.status<500&&(h=`Likely bug in the webapp: got response "${z.status} ${z.statusText}" for "${O}" request. Additional details, if any, follow. `),h+await z.text()}}async function Dl(O){_l?await Nf(O):await rs("exit","POST",O)}async function Of(){await Dl(0)}async function Ka(){await Dl(1)}async function Ef(){await Dl(2)}async function $a(O){return await ts("save","PUT",O)}async function Wf(){const O=await ts("get_merge_data","GET");for(const m in O)O[m]={left:O[m][0],right:O[m][1],edit:O[m][2]};return O}class If{constructor(){fn(this,"merge_views");fn(this,"dom_ids");fn(this,"initial_values");this.merge_views={},this.dom_ids={},this.initial_values={}}values(){const m={};for(const S in this.merge_views)m[S]=this.merge_views[S].editor().getValue();return m}getSingleMergeState(m){const S=this.merge_views[m],N=S.editor();return{input:{left:this.initial_values[m].left,right:this.initial_values[m].right,edit:{type:"Text",value:this.merge_views[m].editor().getValue()}},wrapLines:N.getOption("lineWrapping")??!1,collapseIdentical:!!N.getOption("collapseIdentical"),showRightSide:!!S.rightOriginal()}}createCodeMirrorMergeWidget(m,S,N){const k=N.input,z=document.getElementById(`collapse_${m}`),h=document.getElementById(`linewrap_${m}`),c=document.getElementById(`rightside_${m}`),d=document.getElementById(`prevChange_${m}`),v=document.getElementById(`nextChange_${m}`),b=document.getElementById(`details_${m}`),w=document.getElementById(`cm_${m}`);let A;N.showRightSide&&(A=kl(k.right)??"");const _={value:kl(k.edit)??"",origLeft:kl(k.left)??"",orig:A,lineWrapping:N.wrapLines,collapseIdentical:N.collapseIdentical,lineNumbers:!0,mode:"text/plain",connect:"align"},F=mf.MergeView(w,_);F.editor().setOption("extraKeys",{"Alt-Down":Ci,"Option-Down":Ci,"Cmd-Down":Ci,"Alt-Up":hn,"Option-Up":hn,"Cmd-Up":hn,Tab:Ci}),N.cursorPosition!=null&&(F.editor().setSelection(N.cursorPosition),F.editor().scrollIntoView(null,50)),z.onclick=()=>this.recreateCodeMirrorFlippingOption(S,"collapseIdentical"),h.onclick=()=>this.recreateCodeMirrorFlippingOption(S,"wrapLines"),c.onclick=()=>this.recreateCodeMirrorFlippingOption(S,"showRightSide"),d.onclick=()=>hn(F.editor()),v.onclick=()=>Ci(F.editor()),b.open=!1,b.ontoggle=()=>F.editor().refresh(),console.log(b),this.merge_views[S]=F,this.dom_ids[S]=m,this.initial_values[S]=k}recreateCodeMirrorFlippingOption(m,S){var v;if(this.merge_views[m]==null){console.warn("Trying to toggle line wrapping on a non-existent editor",m,this);return}let k=this.dom_ids[m];const z=`cm_${k}`,h=this.getSingleMergeState(m),c=document.createElement("div");(v=document.getElementById(z))==null||v.replaceWith(c),c.id=z,this.createCodeMirrorMergeWidget(k,m,Pf(h,S));const d=document.getElementById(`details_${k}`);d.open=!0}}function Ff(O,m){let S=[],N=h=>`${h}_${O}`;for(const h in m){const c=Xa(m[h]);c!=null?S.push(dr`
+\f\r"'\`<>=]|("|')|))|$)`,"g"),za=/'/g,Ua=/"/g,ja=/^(?:script|style|textarea|title)$/i,Lf=O=>(m,...S)=>({_$litType$:O,strings:m,values:S}),dr=Lf(1),xi=Symbol.for("lit-noChange"),Ye=Symbol.for("lit-nothing"),Ga=new WeakMap,cr=gr.createTreeWalker(gr,129);function Va(O,m){if(!Array.isArray(O)||!O.hasOwnProperty("raw"))throw Error("invalid template strings array");return Pa!==void 0?Pa.createHTML(m):m}const Tf=(O,m)=>{const S=O.length-1,N=[];let k,z=m===2?"":"")),N]};class Ai{constructor({strings:m,_$litType$:S},N){let k;this.parts=[];let z=0,h=0;const c=m.length-1,d=this.parts,[v,b]=Tf(m,S);if(this.el=Ai.createElement(v,N),cr.currentNode=this.el.content,S===2){const w=this.el.content.firstChild;w.replaceWith(...w.childNodes)}for(;(k=cr.nextNode())!==null&&d.length0){k.textContent=dn?dn.emptyScript:"";for(let _=0;_2||N[0]!==""||N[1]!==""?(this._$AH=Array(N.length-1).fill(new String),this.strings=N):this._$AH=Ye}_$AI(m,S=this,N,k){const z=this.strings;let h=!1;if(z===void 0)m=Rr(this,m,S,0),h=!ki(m)||m!==this._$AH&&m!==xi,h&&(this._$AH=m);else{const c=m;let d,v;for(m=z[0],d=0;d{const N=(S==null?void 0:S.renderBefore)??m;let k=N._$litPart$;if(k===void 0){const z=(S==null?void 0:S.renderBefore)??null;N._$litPart$=k=new _i(m.insertBefore(Ti(),z),z,void 0,S??{})}return k._$AI(O),k};function Df(){return window.crypto.getRandomValues(new Uint32Array(1))[0]}function Al(O,m=!1){const S=Df(),N=`_${S}`;return Object.defineProperty(window,N,{value:k=>(m&&Reflect.deleteProperty(window,N),O==null?void 0:O(k)),writable:!1,configurable:!0}),S}async function es(O,m={}){return new Promise((S,N)=>{const k=Al(h=>{S(h),Reflect.deleteProperty(window,`_${z}`)},!0),z=Al(h=>{N(h),Reflect.deleteProperty(window,`_${k}`)},!0);window.__TAURI_IPC__({cmd:O,callback:k,error:z,...m})})}async function Ml(O){return es("tauri",O)}async function Nf(O=0){return Ml({__tauriModule:"Process",message:{cmd:"exit",exitCode:O}})}function kl(O){return O.type=="Text"?O.value:null}const _l="__TAURI__"in globalThis;async function ts(O,m,S){if(_l){let N={};return S!=null&&(N={result:S}),await es(O,N)}else return await rs(O,m,S)}async function rs(O,m,S){let N=null,k={};S!=null&&(N=JSON.stringify(S),k["Content-Type"]="application/json");const z=await fetch(`/api/${O}`,{method:m,body:N,headers:k});if(z.ok)return await z.json();{let h="";throw z.status<500&&(h=`Likely bug in the webapp: got response "${z.status} ${z.statusText}" for "${O}" request. Additional details, if any, follow. `),h+await z.text()}}async function Dl(O){_l?await Nf(O):await rs("exit","POST",O)}async function Of(){await Dl(0)}async function Ka(){await Dl(1)}async function Ef(){await Dl(2)}async function $a(O){return await ts("save","PUT",O)}async function Wf(){const O=await ts("get_merge_data","GET");for(const m in O)O[m]={left:O[m][0],right:O[m][1],edit:O[m][2]};return O}class If{constructor(){fn(this,"merge_views");fn(this,"dom_ids");fn(this,"initial_values");this.merge_views={},this.dom_ids={},this.initial_values={}}values(){const m={};for(const S in this.merge_views)m[S]=this.merge_views[S].editor().getValue();return m}getSingleMergeState(m){const S=this.merge_views[m],N=S.editor();return{input:{left:this.initial_values[m].left,right:this.initial_values[m].right,edit:{type:"Text",value:this.merge_views[m].editor().getValue()}},wrapLines:N.getOption("lineWrapping")??!1,collapseIdentical:!!N.getOption("collapseIdentical"),showRightSide:!!S.rightOriginal(),cursorPosition:N.getCursor()}}createCodeMirrorMergeWidget(m,S,N){const k=N.input,z=document.getElementById(`collapse_${m}`),h=document.getElementById(`linewrap_${m}`),c=document.getElementById(`rightside_${m}`),d=document.getElementById(`prevChange_${m}`),v=document.getElementById(`nextChange_${m}`),b=document.getElementById(`details_${m}`),w=document.getElementById(`cm_${m}`);let A;N.showRightSide&&(A=kl(k.right)??"");const _={value:kl(k.edit)??"",origLeft:kl(k.left)??"",orig:A,lineWrapping:N.wrapLines,collapseIdentical:N.collapseIdentical,lineNumbers:!0,mode:"text/plain",connect:"align"},F=mf.MergeView(w,_);F.editor().setOption("extraKeys",{"Alt-Down":Ci,"Option-Down":Ci,"Cmd-Down":Ci,"Alt-Up":hn,"Option-Up":hn,"Cmd-Up":hn,Tab:Ci}),N.cursorPosition!=null&&(F.editor().setSelection(N.cursorPosition),F.editor().scrollIntoView(null,50)),z.onclick=()=>this.recreateCodeMirrorFlippingOption(S,"collapseIdentical"),h.onclick=()=>this.recreateCodeMirrorFlippingOption(S,"wrapLines"),c.onclick=()=>this.recreateCodeMirrorFlippingOption(S,"showRightSide"),d.onclick=()=>hn(F.editor()),v.onclick=()=>Ci(F.editor()),b.open=!1,b.ontoggle=()=>F.editor().refresh(),console.log(b),this.merge_views[S]=F,this.dom_ids[S]=m,this.initial_values[S]=k}recreateCodeMirrorFlippingOption(m,S){var v;if(this.merge_views[m]==null){console.warn("Trying to toggle line wrapping on a non-existent editor",m,this);return}let k=this.dom_ids[m];const z=`cm_${k}`,h=this.getSingleMergeState(m),c=document.createElement("div");(v=document.getElementById(z))==null||v.replaceWith(c),c.id=z,this.createCodeMirrorMergeWidget(k,m,Pf(h,S));const d=document.getElementById(`details_${k}`);d.open=!0}}function Ff(O,m){let S=[],N=h=>`${h}_${O}`;for(const h in m){const c=Xa(m[h]);c!=null?S.push(dr`
${h}
: ${c}
Diffedit3
-
+
diff --git a/webapp/src/merge_state.ts b/webapp/src/merge_state.ts
index 415951f..1f01225 100644
--- a/webapp/src/merge_state.ts
+++ b/webapp/src/merge_state.ts
@@ -48,6 +48,7 @@ class MergeState {
"collapseIdentical"
) /* TODO: Allow integer values? */,
showRightSide: !!merge_view.rightOriginal(),
+ cursorPosition: editor.getCursor(),
};
}
@@ -196,14 +197,16 @@ export function render_input(unique_id: string, merge_input: MergeInput) {
alt="Previous Change"
title="Previous Change"
>
- ⇧ Previous Change
+ ⇧
+