@infekted11/stillnote 1.3.4 → 1.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/icon.ico +0 -0
- package/assets/icon.png +0 -0
- package/dist/assets/{index-SyIZ-CG1.js → index-CPkVYpr4.js} +10 -10
- package/dist/assets/{index-KzrG6n7D.css → index-Du8gzgQc.css} +1 -1
- package/dist/index.html +2 -2
- package/electron/main.cjs +5 -5
- package/electron/preload.cjs +1 -0
- package/package.json +4 -4
- /package/{main-logo.icns → assets/icon.icns} +0 -0
|
@@ -4353,9 +4353,9 @@ void main() {
|
|
|
4353
4353
|
`)!==-1&&(e=e.replace(/\r\n/g,`
|
|
4354
4354
|
`)),e.indexOf(`\\
|
|
4355
4355
|
`)!==-1&&(e=e.replace(/\\\n/g,""));const i=e.split(`
|
|
4356
|
-
`);let s=[];for(let o=0,l=i.length;o<l;o++){const c=i[o].trimStart();if(c.length===0)continue;const h=c.charAt(0);if(h!=="#")if(h==="v"){const d=c.split(jv);switch(d[0]){case"v":t.vertices.push(parseFloat(d[1]),parseFloat(d[2]),parseFloat(d[3])),d.length>=7?(fh.setRGB(parseFloat(d[4]),parseFloat(d[5]),parseFloat(d[6]),Ln),t.colors.push(fh.r,fh.g,fh.b)):t.colors.push(void 0,void 0,void 0);break;case"vn":t.normals.push(parseFloat(d[1]),parseFloat(d[2]),parseFloat(d[3]));break;case"vt":t.uvs.push(parseFloat(d[1]),parseFloat(d[2]));break}}else if(h==="f"){const u=c.slice(1).trim().split(jv),f=[];for(let O=0,g=u.length;O<g;O++){const m=u[O];if(m.length>0){const y=m.split("/");f.push(y)}}const p=f[0];for(let O=1,g=f.length-1;O<g;O++){const m=f[O],y=f[O+1];t.addFace(p[0],m[0],y[0],p[1],m[1],y[1],p[2],m[2],y[2])}}else if(h==="l"){const d=c.substring(1).trim().split(" ");let u=[];const f=[];if(c.indexOf("/")===-1)u=d;else for(let p=0,O=d.length;p<O;p++){const g=d[p].split("/");g[0]!==""&&u.push(g[0]),g[1]!==""&&f.push(g[1])}t.addLineGeometry(u,f)}else if(h==="p"){const u=c.slice(1).trim().split(" ");t.addPointGeometry(u)}else if((s=rX.exec(c))!==null){const d=(" "+s[0].slice(1).trim()).slice(1);t.startObject(d)}else if(oX.test(c))t.object.startMaterial(c.substring(7).trim(),t.materialLibraries);else if(aX.test(c))t.materialLibraries.push(c.substring(7).trim());else if(lX.test(c))console.warn('THREE.OBJLoader: Rendering identifier "usemap" not supported. Textures must be defined in MTL files.');else if(h==="s"){if(s=c.split(" "),s.length>1){const u=s[1].trim().toLowerCase();t.object.smooth=u!=="0"&&u!=="off"}else t.object.smooth=!0;const d=t.object.currentMaterial();d&&(d.smooth=t.object.smooth)}else{if(c==="\0")continue;console.warn('THREE.OBJLoader: Unexpected line: "'+c+'"')}}t.finalize();const r=new Ia;if(r.materialLibraries=[].concat(t.materialLibraries),!(t.objects.length===1&&t.objects[0].geometry.vertices.length===0)===!0)for(let o=0,l=t.objects.length;o<l;o++){const c=t.objects[o],h=c.geometry,d=c.materials,u=h.type==="Line",f=h.type==="Points";let p=!1;if(h.vertices.length===0)continue;const O=new Un;O.setAttribute("position",new tn(h.vertices,3)),h.normals.length>0&&O.setAttribute("normal",new tn(h.normals,3)),h.colors.length>0&&(p=!0,O.setAttribute("color",new tn(h.colors,3))),h.hasUVIndices===!0&&O.setAttribute("uv",new tn(h.uvs,2));const g=[];for(let y=0,T=d.length;y<T;y++){const w=d[y],_=w.name+"_"+w.smooth+"_"+p;let b=t.materials[_];if(this.materials!==null){if(b=this.materials.create(w.name),u&&b&&!(b instanceof Vh)){const k=new Vh;Ss.prototype.copy.call(k,b),k.color.copy(b.color),b=k}else if(f&&b&&!(b instanceof rl)){const k=new rl({size:10,sizeAttenuation:!1});Ss.prototype.copy.call(k,b),k.color.copy(b.color),k.map=b.map,b=k}}b===void 0&&(u?b=new Vh:f?b=new rl({size:1,sizeAttenuation:!1}):b=new j3,b.name=w.name,b.flatShading=!w.smooth,b.vertexColors=p,t.materials[_]=b),g.push(b)}let m;if(g.length>1){for(let y=0,T=d.length;y<T;y++){const w=d[y];O.addGroup(w.groupStart,w.groupCount,y)}u?m=new gv(O,g):f?m=new Zf(O,g):m=new pi(O,g)}else u?m=new gv(O,g[0]):f?m=new Zf(O,g[0]):m=new pi(O,g[0]);m.name=c.name,r.add(m)}else if(t.vertices.length>0){const o=new rl({size:1,sizeAttenuation:!1}),l=new Un;l.setAttribute("position",new tn(t.vertices,3)),t.colors.length>0&&t.colors[0]!==void 0&&(l.setAttribute("color",new tn(t.colors,3)),o.vertexColors=!0);const c=new Zf(l,o);r.add(c)}return r}}class dX extends du{constructor(e){super(e)}load(e,t,i,s){const r=this,a=new PT(this.manager);a.setPath(this.path),a.setResponseType("arraybuffer"),a.setRequestHeader(this.requestHeader),a.setWithCredentials(this.withCredentials),a.load(e,function(o){try{t(r.parse(o))}catch(l){s?s(l):console.error(l),r.manager.itemError(e)}},i,s)}parse(e){function t(c){const h=new DataView(c),d=32/8*3+32/8*3*3+16/8,u=h.getUint32(80,!0);if(80+32/8+u*d===h.byteLength)return!0;const p=[115,111,108,105,100];for(let O=0;O<5;O++)if(i(p,h,O))return!1;return!0}function i(c,h,d){for(let u=0,f=c.length;u<f;u++)if(c[u]!==h.getUint8(d+u))return!1;return!0}function s(c){const h=new DataView(c),d=h.getUint32(80,!0);let u,f,p,O=!1,g,m,y,T,w;for(let M=0;M<70;M++)h.getUint32(M,!1)==1129270351&&h.getUint8(M+4)==82&&h.getUint8(M+5)==61&&(O=!0,g=new Float32Array(d*3*3),m=h.getUint8(M+6)/255,y=h.getUint8(M+7)/255,T=h.getUint8(M+8)/255,w=h.getUint8(M+9)/255);const _=84,b=50,k=new Un,v=new Float32Array(d*3*3),C=new Float32Array(d*3*3),E=new rt;for(let M=0;M<d;M++){const R=_+M*b,N=h.getFloat32(R,!0),Q=h.getFloat32(R+4,!0),A=h.getFloat32(R+8,!0);if(O){const F=h.getUint16(R+48,!0);(F&32768)===0?(u=(F&31)/31,f=(F>>5&31)/31,p=(F>>10&31)/31):(u=m,f=y,p=T)}for(let F=1;F<=3;F++){const U=R+F*12,q=M*3*3+(F-1)*3;v[q]=h.getFloat32(U,!0),v[q+1]=h.getFloat32(U+4,!0),v[q+2]=h.getFloat32(U+8,!0),C[q]=N,C[q+1]=Q,C[q+2]=A,O&&(E.setRGB(u,f,p,Ln),g[q]=E.r,g[q+1]=E.g,g[q+2]=E.b)}}return k.setAttribute("position",new ki(v,3)),k.setAttribute("normal",new ki(C,3)),O&&(k.setAttribute("color",new ki(g,3)),k.hasColors=!0,k.alpha=w),k}function r(c){const h=new Un,d=/solid([\s\S]*?)endsolid/g,u=/facet([\s\S]*?)endfacet/g,f=/solid\s(.+)/;let p=0;const O=/[\s]+([+-]?(?:\d*)(?:\.\d*)?(?:[eE][+-]?\d+)?)/.source,g=new RegExp("vertex"+O+O+O,"g"),m=new RegExp("normal"+O+O+O,"g"),y=[],T=[],w=[],_=new G;let b,k=0,v=0,C=0;for(;(b=d.exec(c))!==null;){v=C;const E=b[0],M=(b=f.exec(E))!==null?b[1]:"";for(w.push(M);(b=u.exec(E))!==null;){let Q=0,A=0;const F=b[0];for(;(b=m.exec(F))!==null;)_.x=parseFloat(b[1]),_.y=parseFloat(b[2]),_.z=parseFloat(b[3]),A++;for(;(b=g.exec(F))!==null;)y.push(parseFloat(b[1]),parseFloat(b[2]),parseFloat(b[3])),T.push(_.x,_.y,_.z),Q++,C++;A!==1&&console.error("THREE.STLLoader: Something isn't right with the normal of face number "+p),Q!==3&&console.error("THREE.STLLoader: Something isn't right with the vertices of face number "+p),p++}const R=v,N=C-v;h.userData.groupNames=w,h.addGroup(R,N,k),k++}return h.setAttribute("position",new tn(y,3)),h.setAttribute("normal",new tn(T,3)),h}function a(c){return typeof c!="string"?new TextDecoder().decode(c):c}function o(c){if(typeof c=="string"){const h=new Uint8Array(c.length);for(let d=0;d<c.length;d++)h[d]=c.charCodeAt(d)&255;return h.buffer||h}else return c}const l=o(e);return t(l)?s(l):r(a(e))}}const ty={type:"change"},PO={type:"start"},FT={type:"end"},ph=new cu,ny=new Qs,uX=Math.cos(70*y3.DEG2RAD),on=new G,Yn=2*Math.PI,Qt={NONE:-1,ROTATE:0,DOLLY:1,PAN:2,TOUCH_ROTATE:3,TOUCH_PAN:4,TOUCH_DOLLY_PAN:5,TOUCH_DOLLY_ROTATE:6},ip=1e-6;class XT extends oI{constructor(e,t=null){super(e,t),this.state=Qt.NONE,this.target=new G,this.cursor=new G,this.minDistance=0,this.maxDistance=1/0,this.minZoom=0,this.maxZoom=1/0,this.minTargetRadius=0,this.maxTargetRadius=1/0,this.minPolarAngle=0,this.maxPolarAngle=Math.PI,this.minAzimuthAngle=-1/0,this.maxAzimuthAngle=1/0,this.enableDamping=!1,this.dampingFactor=.05,this.enableZoom=!0,this.zoomSpeed=1,this.enableRotate=!0,this.rotateSpeed=1,this.keyRotateSpeed=1,this.enablePan=!0,this.panSpeed=1,this.screenSpacePanning=!0,this.keyPanSpeed=7,this.zoomToCursor=!1,this.autoRotate=!1,this.autoRotateSpeed=2,this.keys={LEFT:"ArrowLeft",UP:"ArrowUp",RIGHT:"ArrowRight",BOTTOM:"ArrowDown"},this.mouseButtons={LEFT:Ya.ROTATE,MIDDLE:Ya.DOLLY,RIGHT:Ya.PAN},this.touches={ONE:Da.ROTATE,TWO:Da.DOLLY_PAN},this.target0=this.target.clone(),this.position0=this.object.position.clone(),this.zoom0=this.object.zoom,this._cursorStyle="auto",this._domElementKeyEvents=null,this._lastPosition=new G,this._lastQuaternion=new Mr,this._lastTargetPosition=new G,this._quat=new Mr().setFromUnitVectors(e.up,new G(0,1,0)),this._quatInverse=this._quat.clone().invert(),this._spherical=new Mv,this._sphericalDelta=new Mv,this._scale=1,this._panOffset=new G,this._rotateStart=new tt,this._rotateEnd=new tt,this._rotateDelta=new tt,this._panStart=new tt,this._panEnd=new tt,this._panDelta=new tt,this._dollyStart=new tt,this._dollyEnd=new tt,this._dollyDelta=new tt,this._dollyDirection=new G,this._mouse=new tt,this._performCursorZoom=!1,this._pointers=[],this._pointerPositions={},this._controlActive=!1,this._onPointerMove=pX.bind(this),this._onPointerDown=fX.bind(this),this._onPointerUp=mX.bind(this),this._onContextMenu=bX.bind(this),this._onMouseWheel=SX.bind(this),this._onKeyDown=xX.bind(this),this._onTouchStart=vX.bind(this),this._onTouchMove=yX.bind(this),this._onMouseDown=gX.bind(this),this._onMouseMove=OX.bind(this),this._interceptControlDown=_X.bind(this),this._interceptControlUp=wX.bind(this),this.domElement!==null&&this.connect(this.domElement),this.update()}set cursorStyle(e){this._cursorStyle=e,e==="grab"?this.domElement.style.cursor="grab":this.domElement.style.cursor="auto"}get cursorStyle(){return this._cursorStyle}connect(e){super.connect(e),this.domElement.addEventListener("pointerdown",this._onPointerDown),this.domElement.addEventListener("pointercancel",this._onPointerUp),this.domElement.addEventListener("contextmenu",this._onContextMenu),this.domElement.addEventListener("wheel",this._onMouseWheel,{passive:!1}),this.domElement.getRootNode().addEventListener("keydown",this._interceptControlDown,{passive:!0,capture:!0}),this.domElement.style.touchAction="none"}disconnect(){this.state=Qt.NONE,this.domElement.removeEventListener("pointerdown",this._onPointerDown),this.domElement.ownerDocument.removeEventListener("pointermove",this._onPointerMove),this.domElement.ownerDocument.removeEventListener("pointerup",this._onPointerUp),this.domElement.removeEventListener("pointercancel",this._onPointerUp),this.domElement.removeEventListener("wheel",this._onMouseWheel),this.domElement.removeEventListener("contextmenu",this._onContextMenu),this.stopListenToKeyEvents();const e=this.domElement.getRootNode();e.removeEventListener("keydown",this._interceptControlDown,{capture:!0}),e.removeEventListener("keyup",this._interceptControlUp,{capture:!0}),this._controlActive=!1,this._pointers.length=0,this._pointerPositions={},this.domElement.style.touchAction="",this.domElement.style.cursor="auto"}dispose(){this.disconnect()}getPolarAngle(){return this._spherical.phi}getAzimuthalAngle(){return this._spherical.theta}getDistance(){return this.object.position.distanceTo(this.target)}listenToKeyEvents(e){e.addEventListener("keydown",this._onKeyDown),this._domElementKeyEvents=e}stopListenToKeyEvents(){this._domElementKeyEvents!==null&&(this._domElementKeyEvents.removeEventListener("keydown",this._onKeyDown),this._domElementKeyEvents=null)}saveState(){this.target0.copy(this.target),this.position0.copy(this.object.position),this.zoom0=this.object.zoom}reset(){this.target.copy(this.target0),this.object.position.copy(this.position0),this.object.zoom=this.zoom0,this.object.updateProjectionMatrix(),this.dispatchEvent(ty),this.update(),this.state=Qt.NONE}pan(e,t){this._pan(e,t),this.update()}dollyIn(e){this._dollyIn(e),this.update()}dollyOut(e){this._dollyOut(e),this.update()}rotateLeft(e){this._rotateLeft(e),this.update()}rotateUp(e){this._rotateUp(e),this.update()}update(e=null){const t=this.object.position;on.copy(t).sub(this.target),on.applyQuaternion(this._quat),this._spherical.setFromVector3(on),this.autoRotate&&this.state===Qt.NONE&&this._rotateLeft(this._getAutoRotationAngle(e)),this.enableDamping?(this._spherical.theta+=this._sphericalDelta.theta*this.dampingFactor,this._spherical.phi+=this._sphericalDelta.phi*this.dampingFactor):(this._spherical.theta+=this._sphericalDelta.theta,this._spherical.phi+=this._sphericalDelta.phi);let i=this.minAzimuthAngle,s=this.maxAzimuthAngle;isFinite(i)&&isFinite(s)&&(i<-Math.PI?i+=Yn:i>Math.PI&&(i-=Yn),s<-Math.PI?s+=Yn:s>Math.PI&&(s-=Yn),i<=s?this._spherical.theta=Math.max(i,Math.min(s,this._spherical.theta)):this._spherical.theta=this._spherical.theta>(i+s)/2?Math.max(i,this._spherical.theta):Math.min(s,this._spherical.theta)),this._spherical.phi=Math.max(this.minPolarAngle,Math.min(this.maxPolarAngle,this._spherical.phi)),this._spherical.makeSafe(),this.enableDamping===!0?this.target.addScaledVector(this._panOffset,this.dampingFactor):this.target.add(this._panOffset),this.target.sub(this.cursor),this.target.clampLength(this.minTargetRadius,this.maxTargetRadius),this.target.add(this.cursor);let r=!1;if(this.zoomToCursor&&this._performCursorZoom||this.object.isOrthographicCamera)this._spherical.radius=this._clampDistance(this._spherical.radius);else{const a=this._spherical.radius;this._spherical.radius=this._clampDistance(this._spherical.radius*this._scale),r=a!=this._spherical.radius}if(on.setFromSpherical(this._spherical),on.applyQuaternion(this._quatInverse),t.copy(this.target).add(on),this.object.lookAt(this.target),this.enableDamping===!0?(this._sphericalDelta.theta*=1-this.dampingFactor,this._sphericalDelta.phi*=1-this.dampingFactor,this._panOffset.multiplyScalar(1-this.dampingFactor)):(this._sphericalDelta.set(0,0,0),this._panOffset.set(0,0,0)),this.zoomToCursor&&this._performCursorZoom){let a=null;if(this.object.isPerspectiveCamera){const o=on.length();a=this._clampDistance(o*this._scale);const l=o-a;this.object.position.addScaledVector(this._dollyDirection,l),this.object.updateMatrixWorld(),r=!!l}else if(this.object.isOrthographicCamera){const o=new G(this._mouse.x,this._mouse.y,0);o.unproject(this.object);const l=this.object.zoom;this.object.zoom=Math.max(this.minZoom,Math.min(this.maxZoom,this.object.zoom/this._scale)),this.object.updateProjectionMatrix(),r=l!==this.object.zoom;const c=new G(this._mouse.x,this._mouse.y,0);c.unproject(this.object),this.object.position.sub(c).add(o),this.object.updateMatrixWorld(),a=on.length()}else console.warn("WARNING: OrbitControls.js encountered an unknown camera type - zoom to cursor disabled."),this.zoomToCursor=!1;a!==null&&(this.screenSpacePanning?this.target.set(0,0,-1).transformDirection(this.object.matrix).multiplyScalar(a).add(this.object.position):(ph.origin.copy(this.object.position),ph.direction.set(0,0,-1).transformDirection(this.object.matrix),Math.abs(this.object.up.dot(ph.direction))<uX?this.object.lookAt(this.target):(ny.setFromNormalAndCoplanarPoint(this.object.up,this.target),ph.intersectPlane(ny,this.target))))}else if(this.object.isOrthographicCamera){const a=this.object.zoom;this.object.zoom=Math.max(this.minZoom,Math.min(this.maxZoom,this.object.zoom/this._scale)),a!==this.object.zoom&&(this.object.updateProjectionMatrix(),r=!0)}return this._scale=1,this._performCursorZoom=!1,r||this._lastPosition.distanceToSquared(this.object.position)>ip||8*(1-this._lastQuaternion.dot(this.object.quaternion))>ip||this._lastTargetPosition.distanceToSquared(this.target)>ip?(this.dispatchEvent(ty),this._lastPosition.copy(this.object.position),this._lastQuaternion.copy(this.object.quaternion),this._lastTargetPosition.copy(this.target),!0):!1}_getAutoRotationAngle(e){return e!==null?Yn/60*this.autoRotateSpeed*e:Yn/60/60*this.autoRotateSpeed}_getZoomScale(e){const t=Math.abs(e*.01);return Math.pow(.95,this.zoomSpeed*t)}_rotateLeft(e){this._sphericalDelta.theta-=e}_rotateUp(e){this._sphericalDelta.phi-=e}_panLeft(e,t){on.setFromMatrixColumn(t,0),on.multiplyScalar(-e),this._panOffset.add(on)}_panUp(e,t){this.screenSpacePanning===!0?on.setFromMatrixColumn(t,1):(on.setFromMatrixColumn(t,0),on.crossVectors(this.object.up,on)),on.multiplyScalar(e),this._panOffset.add(on)}_pan(e,t){const i=this.domElement;if(this.object.isPerspectiveCamera){const s=this.object.position;on.copy(s).sub(this.target);let r=on.length();r*=Math.tan(this.object.fov/2*Math.PI/180),this._panLeft(2*e*r/i.clientHeight,this.object.matrix),this._panUp(2*t*r/i.clientHeight,this.object.matrix)}else this.object.isOrthographicCamera?(this._panLeft(e*(this.object.right-this.object.left)/this.object.zoom/i.clientWidth,this.object.matrix),this._panUp(t*(this.object.top-this.object.bottom)/this.object.zoom/i.clientHeight,this.object.matrix)):(console.warn("WARNING: OrbitControls.js encountered an unknown camera type - pan disabled."),this.enablePan=!1)}_dollyOut(e){this.object.isPerspectiveCamera||this.object.isOrthographicCamera?this._scale/=e:(console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."),this.enableZoom=!1)}_dollyIn(e){this.object.isPerspectiveCamera||this.object.isOrthographicCamera?this._scale*=e:(console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."),this.enableZoom=!1)}_updateZoomParameters(e,t){if(!this.zoomToCursor)return;this._performCursorZoom=!0;const i=this.domElement.getBoundingClientRect(),s=e-i.left,r=t-i.top,a=i.width,o=i.height;this._mouse.x=s/a*2-1,this._mouse.y=-(r/o)*2+1,this._dollyDirection.set(this._mouse.x,this._mouse.y,1).unproject(this.object).sub(this.object.position).normalize()}_clampDistance(e){return Math.max(this.minDistance,Math.min(this.maxDistance,e))}_handleMouseDownRotate(e){this._rotateStart.set(e.clientX,e.clientY)}_handleMouseDownDolly(e){this._updateZoomParameters(e.clientX,e.clientX),this._dollyStart.set(e.clientX,e.clientY)}_handleMouseDownPan(e){this._panStart.set(e.clientX,e.clientY)}_handleMouseMoveRotate(e){this._rotateEnd.set(e.clientX,e.clientY),this._rotateDelta.subVectors(this._rotateEnd,this._rotateStart).multiplyScalar(this.rotateSpeed);const t=this.domElement;this._rotateLeft(Yn*this._rotateDelta.x/t.clientHeight),this._rotateUp(Yn*this._rotateDelta.y/t.clientHeight),this._rotateStart.copy(this._rotateEnd),this.update()}_handleMouseMoveDolly(e){this._dollyEnd.set(e.clientX,e.clientY),this._dollyDelta.subVectors(this._dollyEnd,this._dollyStart),this._dollyDelta.y>0?this._dollyOut(this._getZoomScale(this._dollyDelta.y)):this._dollyDelta.y<0&&this._dollyIn(this._getZoomScale(this._dollyDelta.y)),this._dollyStart.copy(this._dollyEnd),this.update()}_handleMouseMovePan(e){this._panEnd.set(e.clientX,e.clientY),this._panDelta.subVectors(this._panEnd,this._panStart).multiplyScalar(this.panSpeed),this._pan(this._panDelta.x,this._panDelta.y),this._panStart.copy(this._panEnd),this.update()}_handleMouseWheel(e){this._updateZoomParameters(e.clientX,e.clientY),e.deltaY<0?this._dollyIn(this._getZoomScale(e.deltaY)):e.deltaY>0&&this._dollyOut(this._getZoomScale(e.deltaY)),this.update()}_handleKeyDown(e){let t=!1;switch(e.code){case this.keys.UP:e.ctrlKey||e.metaKey||e.shiftKey?this.enableRotate&&this._rotateUp(Yn*this.keyRotateSpeed/this.domElement.clientHeight):this.enablePan&&this._pan(0,this.keyPanSpeed),t=!0;break;case this.keys.BOTTOM:e.ctrlKey||e.metaKey||e.shiftKey?this.enableRotate&&this._rotateUp(-Yn*this.keyRotateSpeed/this.domElement.clientHeight):this.enablePan&&this._pan(0,-this.keyPanSpeed),t=!0;break;case this.keys.LEFT:e.ctrlKey||e.metaKey||e.shiftKey?this.enableRotate&&this._rotateLeft(Yn*this.keyRotateSpeed/this.domElement.clientHeight):this.enablePan&&this._pan(this.keyPanSpeed,0),t=!0;break;case this.keys.RIGHT:e.ctrlKey||e.metaKey||e.shiftKey?this.enableRotate&&this._rotateLeft(-Yn*this.keyRotateSpeed/this.domElement.clientHeight):this.enablePan&&this._pan(-this.keyPanSpeed,0),t=!0;break}t&&(e.preventDefault(),this.update())}_handleTouchStartRotate(e){if(this._pointers.length===1)this._rotateStart.set(e.pageX,e.pageY);else{const t=this._getSecondPointerPosition(e),i=.5*(e.pageX+t.x),s=.5*(e.pageY+t.y);this._rotateStart.set(i,s)}}_handleTouchStartPan(e){if(this._pointers.length===1)this._panStart.set(e.pageX,e.pageY);else{const t=this._getSecondPointerPosition(e),i=.5*(e.pageX+t.x),s=.5*(e.pageY+t.y);this._panStart.set(i,s)}}_handleTouchStartDolly(e){const t=this._getSecondPointerPosition(e),i=e.pageX-t.x,s=e.pageY-t.y,r=Math.sqrt(i*i+s*s);this._dollyStart.set(0,r)}_handleTouchStartDollyPan(e){this.enableZoom&&this._handleTouchStartDolly(e),this.enablePan&&this._handleTouchStartPan(e)}_handleTouchStartDollyRotate(e){this.enableZoom&&this._handleTouchStartDolly(e),this.enableRotate&&this._handleTouchStartRotate(e)}_handleTouchMoveRotate(e){if(this._pointers.length==1)this._rotateEnd.set(e.pageX,e.pageY);else{const i=this._getSecondPointerPosition(e),s=.5*(e.pageX+i.x),r=.5*(e.pageY+i.y);this._rotateEnd.set(s,r)}this._rotateDelta.subVectors(this._rotateEnd,this._rotateStart).multiplyScalar(this.rotateSpeed);const t=this.domElement;this._rotateLeft(Yn*this._rotateDelta.x/t.clientHeight),this._rotateUp(Yn*this._rotateDelta.y/t.clientHeight),this._rotateStart.copy(this._rotateEnd)}_handleTouchMovePan(e){if(this._pointers.length===1)this._panEnd.set(e.pageX,e.pageY);else{const t=this._getSecondPointerPosition(e),i=.5*(e.pageX+t.x),s=.5*(e.pageY+t.y);this._panEnd.set(i,s)}this._panDelta.subVectors(this._panEnd,this._panStart).multiplyScalar(this.panSpeed),this._pan(this._panDelta.x,this._panDelta.y),this._panStart.copy(this._panEnd)}_handleTouchMoveDolly(e){const t=this._getSecondPointerPosition(e),i=e.pageX-t.x,s=e.pageY-t.y,r=Math.sqrt(i*i+s*s);this._dollyEnd.set(0,r),this._dollyDelta.set(0,Math.pow(this._dollyEnd.y/this._dollyStart.y,this.zoomSpeed)),this._dollyOut(this._dollyDelta.y),this._dollyStart.copy(this._dollyEnd);const a=(e.pageX+t.x)*.5,o=(e.pageY+t.y)*.5;this._updateZoomParameters(a,o)}_handleTouchMoveDollyPan(e){this.enableZoom&&this._handleTouchMoveDolly(e),this.enablePan&&this._handleTouchMovePan(e)}_handleTouchMoveDollyRotate(e){this.enableZoom&&this._handleTouchMoveDolly(e),this.enableRotate&&this._handleTouchMoveRotate(e)}_addPointer(e){this._pointers.push(e.pointerId)}_removePointer(e){delete this._pointerPositions[e.pointerId];for(let t=0;t<this._pointers.length;t++)if(this._pointers[t]==e.pointerId){this._pointers.splice(t,1);return}}_isTrackingPointer(e){for(let t=0;t<this._pointers.length;t++)if(this._pointers[t]==e.pointerId)return!0;return!1}_trackPointer(e){let t=this._pointerPositions[e.pointerId];t===void 0&&(t=new tt,this._pointerPositions[e.pointerId]=t),t.set(e.pageX,e.pageY)}_getSecondPointerPosition(e){const t=e.pointerId===this._pointers[0]?this._pointers[1]:this._pointers[0];return this._pointerPositions[t]}_customWheelEvent(e){const t=e.deltaMode,i={clientX:e.clientX,clientY:e.clientY,deltaY:e.deltaY};switch(t){case 1:i.deltaY*=16;break;case 2:i.deltaY*=100;break}return e.ctrlKey&&!this._controlActive&&(i.deltaY*=10),i}}function fX(n){this.enabled!==!1&&(this._pointers.length===0&&(this.domElement.setPointerCapture(n.pointerId),this.domElement.ownerDocument.addEventListener("pointermove",this._onPointerMove),this.domElement.ownerDocument.addEventListener("pointerup",this._onPointerUp)),!this._isTrackingPointer(n)&&(this._addPointer(n),n.pointerType==="touch"?this._onTouchStart(n):this._onMouseDown(n),this._cursorStyle==="grab"&&(this.domElement.style.cursor="grabbing")))}function pX(n){this.enabled!==!1&&(n.pointerType==="touch"?this._onTouchMove(n):this._onMouseMove(n))}function mX(n){switch(this._removePointer(n),this._pointers.length){case 0:this.domElement.releasePointerCapture(n.pointerId),this.domElement.ownerDocument.removeEventListener("pointermove",this._onPointerMove),this.domElement.ownerDocument.removeEventListener("pointerup",this._onPointerUp),this.dispatchEvent(FT),this.state=Qt.NONE,this._cursorStyle==="grab"&&(this.domElement.style.cursor="grab");break;case 1:const e=this._pointers[0],t=this._pointerPositions[e];this._onTouchStart({pointerId:e,pageX:t.x,pageY:t.y});break}}function gX(n){let e;switch(n.button){case 0:e=this.mouseButtons.LEFT;break;case 1:e=this.mouseButtons.MIDDLE;break;case 2:e=this.mouseButtons.RIGHT;break;default:e=-1}switch(e){case Ya.DOLLY:if(this.enableZoom===!1)return;this._handleMouseDownDolly(n),this.state=Qt.DOLLY;break;case Ya.ROTATE:if(n.ctrlKey||n.metaKey||n.shiftKey){if(this.enablePan===!1)return;this._handleMouseDownPan(n),this.state=Qt.PAN}else{if(this.enableRotate===!1)return;this._handleMouseDownRotate(n),this.state=Qt.ROTATE}break;case Ya.PAN:if(n.ctrlKey||n.metaKey||n.shiftKey){if(this.enableRotate===!1)return;this._handleMouseDownRotate(n),this.state=Qt.ROTATE}else{if(this.enablePan===!1)return;this._handleMouseDownPan(n),this.state=Qt.PAN}break;default:this.state=Qt.NONE}this.state!==Qt.NONE&&this.dispatchEvent(PO)}function OX(n){switch(this.state){case Qt.ROTATE:if(this.enableRotate===!1)return;this._handleMouseMoveRotate(n);break;case Qt.DOLLY:if(this.enableZoom===!1)return;this._handleMouseMoveDolly(n);break;case Qt.PAN:if(this.enablePan===!1)return;this._handleMouseMovePan(n);break}}function SX(n){this.enabled===!1||this.enableZoom===!1||this.state!==Qt.NONE||(n.preventDefault(),this.dispatchEvent(PO),this._handleMouseWheel(this._customWheelEvent(n)),this.dispatchEvent(FT))}function xX(n){this.enabled!==!1&&this._handleKeyDown(n)}function vX(n){switch(this._trackPointer(n),this._pointers.length){case 1:switch(this.touches.ONE){case Da.ROTATE:if(this.enableRotate===!1)return;this._handleTouchStartRotate(n),this.state=Qt.TOUCH_ROTATE;break;case Da.PAN:if(this.enablePan===!1)return;this._handleTouchStartPan(n),this.state=Qt.TOUCH_PAN;break;default:this.state=Qt.NONE}break;case 2:switch(this.touches.TWO){case Da.DOLLY_PAN:if(this.enableZoom===!1&&this.enablePan===!1)return;this._handleTouchStartDollyPan(n),this.state=Qt.TOUCH_DOLLY_PAN;break;case Da.DOLLY_ROTATE:if(this.enableZoom===!1&&this.enableRotate===!1)return;this._handleTouchStartDollyRotate(n),this.state=Qt.TOUCH_DOLLY_ROTATE;break;default:this.state=Qt.NONE}break;default:this.state=Qt.NONE}this.state!==Qt.NONE&&this.dispatchEvent(PO)}function yX(n){switch(this._trackPointer(n),this.state){case Qt.TOUCH_ROTATE:if(this.enableRotate===!1)return;this._handleTouchMoveRotate(n),this.update();break;case Qt.TOUCH_PAN:if(this.enablePan===!1)return;this._handleTouchMovePan(n),this.update();break;case Qt.TOUCH_DOLLY_PAN:if(this.enableZoom===!1&&this.enablePan===!1)return;this._handleTouchMoveDollyPan(n),this.update();break;case Qt.TOUCH_DOLLY_ROTATE:if(this.enableZoom===!1&&this.enableRotate===!1)return;this._handleTouchMoveDollyRotate(n),this.update();break;default:this.state=Qt.NONE}}function bX(n){this.enabled!==!1&&n.preventDefault()}function _X(n){n.key==="Control"&&(this._controlActive=!0,this.domElement.getRootNode().addEventListener("keyup",this._interceptControlUp,{passive:!0,capture:!0}))}function wX(n){n.key==="Control"&&(this._controlActive=!1,this.domElement.getRootNode().removeEventListener("keyup",this._interceptControlUp,{passive:!0,capture:!0}))}const bo=n=>{var e;return(e=window.matchMedia)!=null&&e.call(window,"(prefers-reduced-motion: reduce)").matches?1:n},zT=bt.define(),TX=ei.define({create:()=>Ie.none,update(n,e){n=n.map(e.changes);for(const t of e.effects)t.is(zT)&&(n=t.value);return n},provide:n=>Ae.decorations.from(n)});let sp=null,gr=null,na=new Set,rp=Promise.resolve(),iy=null,ap=0;async function BT(){return sp||(sp=window.stillnote.loadSpellcheckDictionary().then(n=>{gr=new Set(n.split(/\r?\n/).map(e=>e.trim().toLocaleLowerCase()).filter(Boolean));for(const e of gr)Gh.has(e[0])||Gh.set(e[0],[]),Zh.has(e.at(-1))||Zh.set(e.at(-1),[]),Gh.get(e[0]).push(e),Zh.get(e.at(-1)).push(e);return gr})),sp}function ql(n){const e=++ap;clearTimeout(iy),iy=setTimeout(async()=>{try{const t=await BT();if(e!==ap||n!==S.view)return;const i=n.state.doc.toString(),s=[];Tt(n.state).iterate({enter(l){["FencedCode","InlineCode","LinkDestination"].includes(l.type.name)&&s.push([l.from,l.to])}});const r=[],a=/[\p{L}]+(?:['’][\p{L}]+)?/gu;let o;for(;o=a.exec(i);){const l=o[0].toLocaleLowerCase();l.length<3||s.some(([c,h])=>o.index>=c&&o.index<h)||mu(l)||r.push(Ie.mark({class:"spellcheck-misspelled",attributes:{title:"Possible spelling mistake"}}).range(o.index,o.index+o[0].length))}e===ap&&n===S.view&&n.dispatch({effects:zT.of(Ie.set(r,!0))})}catch(t){console.error("Spellcheck dictionary could not be loaded:",t)}},180)}function MX(n){if(!gr||n.length<3)return[];const e=n.toLocaleLowerCase(),t=new Set([...Gh.get(e[0])||[],...Zh.get(e.at(-1))||[]]),i=[];for(const s of t){if(Math.abs(s.length-e.length)>2)continue;const r=EX(e,s);r<=2&&i.push({candidate:s,distance:r})}return i.sort((s,r)=>s.distance-r.distance||s.candidate.localeCompare(r.candidate)).slice(0,5).map(({candidate:s})=>s)}function sy(n){return new Set((Array.isArray(n)?n:[]).filter(e=>typeof e=="string").map(e=>e.trim().toLocaleLowerCase()).filter(e=>/^[\p{L}][\p{L}'’\-]{0,63}$/u.test(e)))}async function PX(){const n=await window.stillnote.loadCustomDictionary();let e=n.words;if(n.exists)localStorage.removeItem("stillnote-custom-dictionary");else try{const t=sy(JSON.parse(localStorage.getItem("stillnote-custom-dictionary")||"[]"));t.size&&(e=[...t],await window.stillnote.saveCustomDictionary(e)),localStorage.removeItem("stillnote-custom-dictionary")}catch(t){console.warn("Could not migrate the personal dictionary into this vault:",t.message)}na=sy(e),cc(),S.view&&ql(S.view)}function VT(){if(!S.vault)return Promise.reject(new Error("Open a vault before saving personal words."));const n=[...na].sort((e,t)=>e.localeCompare(t));return rp=rp.catch(()=>{}).then(()=>window.stillnote.saveCustomDictionary(n)),rp.catch(e=>{throw Re(e.message||"Could not save the personal dictionary."),e})}function WT(n){if(!S.vault)return Re("Open a vault before adding personal words."),!1;const e=String(n||"").trim().toLocaleLowerCase();return/^[\p{L}][\p{L}'’\-]{0,63}$/u.test(e)?mu(e)?(Re(`“${e}” is already in the dictionary.`),!1):(na.add(e),VT().catch(()=>{}),cc(),S.view&&ql(S.view),!0):(Re("Enter a single word using letters, apostrophes, or hyphens."),!1)}function cc(){const n=L("#custom-dictionary-list");if(!n)return;n.replaceChildren();const e=[...na].sort((t,i)=>t.localeCompare(i));if(!e.length){const t=document.createElement("p");t.className="dictionary-empty",t.textContent="No personal words yet.",n.append(t);return}for(const t of e){const i=document.createElement("div");i.className="dictionary-word-row";const s=document.createElement("span");s.textContent=t;const r=document.createElement("button");r.type="button",r.className="icon-button dictionary-remove",r.setAttribute("aria-label",`Remove ${t} from dictionary`),r.title="Remove word",r.innerHTML=fe.close,r.addEventListener("click",()=>{na.delete(t),VT().catch(()=>{}),cc(),S.view&&ql(S.view)}),i.append(s,r),n.append(i)}}function EX(n,e){if(Math.abs(n.length-e.length)>2)return 3;let t=Array.from({length:e.length+1},(s,r)=>r),i=null;for(let s=1;s<=n.length;s++){const r=[s];let a=s;for(let o=1;o<=e.length;o++){let l=Math.min(r[o-1]+1,t[o]+1,t[o-1]+(n[s-1]===e[o-1]?0:1));i&&s>1&&o>1&&n[s-1]===e[o-2]&&n[s-2]===e[o-1]&&(l=Math.min(l,i[o-2]+1)),r[o]=l,a=Math.min(a,l)}if(a>2)return 3;i=t,t=r}return t[e.length]}const Gh=new Map,Zh=new Map,We=(n,e="")=>`<svg class="app-icon ${e}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">${n}</svg>`,fe={panel:We('<rect x="3.5" y="4.5" width="17" height="15" rx="2"/><path d="M9 4.5v15"/>'),home:We('<path d="m3.5 10 8.5-7 8.5 7v9a2 2 0 0 1-2 2h-13a2 2 0 0 1-2-2z"/><path d="M9 21v-8h6v8"/>'),search:We('<circle cx="10.8" cy="10.8" r="6.3"/><path d="m15.5 15.5 4.2 4.2"/>'),file:We('<path d="M6 3.8h8l4 4v12.4H6z"/><path d="M14 3.8v4h4M9 12h6M9 15.5h6"/>'),filePlus:We('<path d="M6 3.8h8l4 4v12.4H6z"/><path d="M14 3.8v4h4M12 11v6M9 14h6"/>'),formatBold:We('<path d="M7 5h6a4 4 0 0 1 0 8H7zM7 13h7a3 3 0 0 1 0 6H7z"/>'),formatItalic:We('<path d="M10 5h9M5 19h9M14 5 10 19"/>'),formatCode:We('<path d="m8 8-4 4 4 4M16 8l4 4-4 4M14 5l-4 14"/>'),formatStrike:We('<path d="M5 8a4 4 0 0 1 4-3h6a4 4 0 0 1 3 1.4M4 12h16M19 16a4 4 0 0 1-4 3H9a4 4 0 0 1-3-1.4"/>'),formatH1:We('<path d="M4 5v14M4 12h8M12 5v14M17 8l2-2v12M16 18h6"/>'),formatH2:We('<path d="M3 5v14M3 12h8M11 5v14M15 9a3 3 0 0 1 6 0c0 3-6 4-6 9h7"/>'),formatBullet:We('<circle cx="5" cy="6" r="1"/><circle cx="5" cy="12" r="1"/><circle cx="5" cy="18" r="1"/><path d="M10 6h10M10 12h10M10 18h10"/>'),formatOrdered:We('<path d="M9 6h11M9 12h11M9 18h11M4 5h1v3M4 11h2l-2 2h2M4 17h2l-2 2h2"/>'),formatCheck:We('<rect x="3.5" y="4" width="6" height="6" rx="1"/><path d="m5 7 1.4 1.4L8.5 6M13 7h7M3.5 14h6v6h-6zM13 17h7"/>'),tasks:We('<path d="m4 7 1.5 1.5L8 5.8M11 7h9M4 16l1.5 1.5L8 14.8M11 16h9"/>'),formatHighlight:We('<path d="m8 14 7-7 4 4-7 7H8zM6 20h13M13 9l4 4M5 5h3M6.5 3.5v3M18 17l2 2M19 18l2-2"/>'),canvas:We('<rect x="4" y="4" width="16" height="16" rx="2"/><path d="m7 16 3-4 2 2 3-5 2 7"/>'),cursor:We('<path d="m5 3 14 10-7 1-3 7z"/>'),draw:We('<path d="m4 16 9-9 4 4-9 9H4zM12 8l4 4M14 6l2-2 4 4-2 2"/>'),rectangle:We('<rect x="4" y="5" width="16" height="14" rx="1"/>'),shape:We('<rect x="3.5" y="4" width="7" height="7" rx="1"/><circle cx="17" cy="7.5" r="3.5"/><path d="m5 20 4-6 4 6z"/>'),triangle:We('<path d="m12 3 9 17H3z"/>'),speech:We('<path d="M4 4h16v12H10l-5 4z"/>'),markerArrow:We('<path d="M3 8h11V4l7 8-7 8v-4H3z"/>'),markerCircle:We('<circle cx="12" cy="12" r="7"/>'),markerSquare:We('<rect x="5" y="5" width="14" height="14" rx="1"/>'),markerDiamond:We('<path d="m12 3 9 9-9 9-9-9z"/>'),markerNone:We('<path d="M5 5l14 14M19 5 5 19"/>'),ellipse:We('<ellipse cx="12" cy="12" rx="8" ry="6"/>'),rotate:We('<rect x="8" y="8" width="9" height="9" rx="1"/><path d="M5 8a8 8 0 0 1 12-4M17 1v4h-4"/>'),text:We('<path d="M4 6V4h16v2M12 4v16M9 20h6"/>'),line:We('<path d="M4 18 20 6"/>'),eraser:We('<path d="m7 16-3-3a2 2 0 0 1 0-3l6-6a2 2 0 0 1 3 0l6 6-8 8H7zM13 18h7"/>'),trash:We('<path d="M4 7h16M10 11v6M14 11v6M6 7l1 13h10l1-13M9 7V4h6v3"/>'),star:We('<path d="m12 3 2.75 5.57 6.15.89-4.45 4.33 1.05 6.12L12 17.02l-5.5 2.89 1.05-6.12L3.1 9.46l6.15-.89L12 3z"/>'),undo:We('<path d="M9 14 4 9l5-5"/><path d="M4 9h9a6 6 0 0 1 0 12h-2"/>'),redo:We('<path d="m15 14 5-5-5-5"/><path d="M20 9h-9a6 6 0 0 0 0 12h2"/>'),spreadsheet:We('<rect x="4" y="4" width="16" height="16" rx="2"/><path d="M4 9h16M4 14h16M10 9v11M15 9v11"/>'),graph:We('<path d="M4 20V4M4 20h16"/><path d="M7 16c2-1 2-7 5-7s3 5 6 1"/>'),folder:We('<path d="M3.5 7.5a2 2 0 0 1 2-2H10l2 2h6.5a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2h-13a2 2 0 0 1-2-2z"/>'),folderOpen:We('<path d="M3.5 7.5a2 2 0 0 1 2-2H10l2 2h6.5a2 2 0 0 1 2 2v1"/><path d="m3.5 12 1.2-1.5h15.8l-2.2 7a2 2 0 0 1-1.9 1.5H5.2a2 2 0 0 1-1.9-2.5z"/>'),folderPlus:We('<path d="M3 8a2 2 0 0 1 2-2h4.5l2 2H18a2 2 0 0 1 2 2v2"/><path d="M3 12h11M8.5 9.5v5M3 12l1.7 6.3A2 2 0 0 0 6.6 20h7"/>'),expandAll:We('<path d="M8 4H5a1 1 0 0 0-1 1v3M16 4h3a1 1 0 0 1 1 1v3M8 20H5a1 1 0 0 1-1-1v-3M16 20h3a1 1 0 0 0 1-1v-3"/><path d="M12 7v10M7 12h10"/>'),collapseAll:We('<path d="M8 4H5a1 1 0 0 0-1 1v3M16 4h3a1 1 0 0 1 1 1v3M8 20H5a1 1 0 0 1-1-1v-3M16 20h3a1 1 0 0 0 1-1v-3"/><path d="M7 12h10"/>'),menu:We('<path d="M4 6h16M4 12h16M4 18h16"/>'),chevron:We('<path d="m9 18 6-6-6-6"/>'),down:We('<path d="m6 9 6 6 6-6"/>'),refresh:We('<path d="M17.7 5.3A8 8 0 1 0 20 11"/><path d="M20 3v5h-5"/>'),external:We('<path d="M14 5h5v5M19 5l-8 8"/><path d="M17 13v5a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1V8a1 1 0 0 1 1-1h5"/>'),gear:We('<path d="M4 6h7m4 0h5M4 12h3m4 0h9M4 18h9m4 0h3"/><circle cx="13" cy="6" r="2"/><circle cx="9" cy="12" r="2"/><circle cx="15" cy="18" r="2"/>'),assistant:We('<path d="m12 3 1.6 5.4L19 10l-5.4 1.6L12 17l-1.6-5.4L5 10l5.4-1.6zM19 16l.8 2.2L22 19l-2.2.8L19 22l-.8-2.2L16 19l2.2-.8z"/>'),send:We('<path d="m21 3-7.2 18-3.2-7.6L3 10.2z"/><path d="M10.6 13.4 21 3"/>'),mic:We('<rect x="9" y="2" width="6" height="12" rx="3"/><path d="M5 10a7 7 0 0 0 14 0M12 17v5m-4 0h8"/>'),shift:We('<path d="m5 12 7-7 7 7h-4v7H9v-7z"/>',"shortcut-shift-icon"),close:We('<path d="m6 6 12 12M18 6 6 18"/>'),statusCheck:We('<path d="m5 12.5 4.5 4.5L19 7"/>'),statusX:We('<path d="m6 6 12 12M18 6 6 18"/>'),book:We('<path d="M5 4.5h11a3 3 0 0 1 3 3v12H8a3 3 0 0 1-3-3z"/><path d="M5 16.5a3 3 0 0 1 3-3h11M9 8h6"/>',"brand-mark-icon"),command:We('<path d="M9 9h6v6H9z"/><path d="M9 9V6a2 2 0 1 0-2 2h10a2 2 0 1 0-2-2v12a2 2 0 1 0-2-2H7a2 2 0 1 0 2 2z"/>')},AX=document.querySelector("#app");AX.innerHTML=`
|
|
4356
|
+
`);let s=[];for(let o=0,l=i.length;o<l;o++){const c=i[o].trimStart();if(c.length===0)continue;const h=c.charAt(0);if(h!=="#")if(h==="v"){const d=c.split(jv);switch(d[0]){case"v":t.vertices.push(parseFloat(d[1]),parseFloat(d[2]),parseFloat(d[3])),d.length>=7?(fh.setRGB(parseFloat(d[4]),parseFloat(d[5]),parseFloat(d[6]),Ln),t.colors.push(fh.r,fh.g,fh.b)):t.colors.push(void 0,void 0,void 0);break;case"vn":t.normals.push(parseFloat(d[1]),parseFloat(d[2]),parseFloat(d[3]));break;case"vt":t.uvs.push(parseFloat(d[1]),parseFloat(d[2]));break}}else if(h==="f"){const u=c.slice(1).trim().split(jv),f=[];for(let O=0,g=u.length;O<g;O++){const m=u[O];if(m.length>0){const y=m.split("/");f.push(y)}}const p=f[0];for(let O=1,g=f.length-1;O<g;O++){const m=f[O],y=f[O+1];t.addFace(p[0],m[0],y[0],p[1],m[1],y[1],p[2],m[2],y[2])}}else if(h==="l"){const d=c.substring(1).trim().split(" ");let u=[];const f=[];if(c.indexOf("/")===-1)u=d;else for(let p=0,O=d.length;p<O;p++){const g=d[p].split("/");g[0]!==""&&u.push(g[0]),g[1]!==""&&f.push(g[1])}t.addLineGeometry(u,f)}else if(h==="p"){const u=c.slice(1).trim().split(" ");t.addPointGeometry(u)}else if((s=rX.exec(c))!==null){const d=(" "+s[0].slice(1).trim()).slice(1);t.startObject(d)}else if(oX.test(c))t.object.startMaterial(c.substring(7).trim(),t.materialLibraries);else if(aX.test(c))t.materialLibraries.push(c.substring(7).trim());else if(lX.test(c))console.warn('THREE.OBJLoader: Rendering identifier "usemap" not supported. Textures must be defined in MTL files.');else if(h==="s"){if(s=c.split(" "),s.length>1){const u=s[1].trim().toLowerCase();t.object.smooth=u!=="0"&&u!=="off"}else t.object.smooth=!0;const d=t.object.currentMaterial();d&&(d.smooth=t.object.smooth)}else{if(c==="\0")continue;console.warn('THREE.OBJLoader: Unexpected line: "'+c+'"')}}t.finalize();const r=new Ia;if(r.materialLibraries=[].concat(t.materialLibraries),!(t.objects.length===1&&t.objects[0].geometry.vertices.length===0)===!0)for(let o=0,l=t.objects.length;o<l;o++){const c=t.objects[o],h=c.geometry,d=c.materials,u=h.type==="Line",f=h.type==="Points";let p=!1;if(h.vertices.length===0)continue;const O=new Un;O.setAttribute("position",new tn(h.vertices,3)),h.normals.length>0&&O.setAttribute("normal",new tn(h.normals,3)),h.colors.length>0&&(p=!0,O.setAttribute("color",new tn(h.colors,3))),h.hasUVIndices===!0&&O.setAttribute("uv",new tn(h.uvs,2));const g=[];for(let y=0,T=d.length;y<T;y++){const w=d[y],_=w.name+"_"+w.smooth+"_"+p;let b=t.materials[_];if(this.materials!==null){if(b=this.materials.create(w.name),u&&b&&!(b instanceof Vh)){const k=new Vh;Ss.prototype.copy.call(k,b),k.color.copy(b.color),b=k}else if(f&&b&&!(b instanceof rl)){const k=new rl({size:10,sizeAttenuation:!1});Ss.prototype.copy.call(k,b),k.color.copy(b.color),k.map=b.map,b=k}}b===void 0&&(u?b=new Vh:f?b=new rl({size:1,sizeAttenuation:!1}):b=new j3,b.name=w.name,b.flatShading=!w.smooth,b.vertexColors=p,t.materials[_]=b),g.push(b)}let m;if(g.length>1){for(let y=0,T=d.length;y<T;y++){const w=d[y];O.addGroup(w.groupStart,w.groupCount,y)}u?m=new gv(O,g):f?m=new Zf(O,g):m=new pi(O,g)}else u?m=new gv(O,g[0]):f?m=new Zf(O,g[0]):m=new pi(O,g[0]);m.name=c.name,r.add(m)}else if(t.vertices.length>0){const o=new rl({size:1,sizeAttenuation:!1}),l=new Un;l.setAttribute("position",new tn(t.vertices,3)),t.colors.length>0&&t.colors[0]!==void 0&&(l.setAttribute("color",new tn(t.colors,3)),o.vertexColors=!0);const c=new Zf(l,o);r.add(c)}return r}}class dX extends du{constructor(e){super(e)}load(e,t,i,s){const r=this,a=new PT(this.manager);a.setPath(this.path),a.setResponseType("arraybuffer"),a.setRequestHeader(this.requestHeader),a.setWithCredentials(this.withCredentials),a.load(e,function(o){try{t(r.parse(o))}catch(l){s?s(l):console.error(l),r.manager.itemError(e)}},i,s)}parse(e){function t(c){const h=new DataView(c),d=32/8*3+32/8*3*3+16/8,u=h.getUint32(80,!0);if(80+32/8+u*d===h.byteLength)return!0;const p=[115,111,108,105,100];for(let O=0;O<5;O++)if(i(p,h,O))return!1;return!0}function i(c,h,d){for(let u=0,f=c.length;u<f;u++)if(c[u]!==h.getUint8(d+u))return!1;return!0}function s(c){const h=new DataView(c),d=h.getUint32(80,!0);let u,f,p,O=!1,g,m,y,T,w;for(let M=0;M<70;M++)h.getUint32(M,!1)==1129270351&&h.getUint8(M+4)==82&&h.getUint8(M+5)==61&&(O=!0,g=new Float32Array(d*3*3),m=h.getUint8(M+6)/255,y=h.getUint8(M+7)/255,T=h.getUint8(M+8)/255,w=h.getUint8(M+9)/255);const _=84,b=50,k=new Un,v=new Float32Array(d*3*3),C=new Float32Array(d*3*3),E=new rt;for(let M=0;M<d;M++){const R=_+M*b,N=h.getFloat32(R,!0),Q=h.getFloat32(R+4,!0),A=h.getFloat32(R+8,!0);if(O){const F=h.getUint16(R+48,!0);(F&32768)===0?(u=(F&31)/31,f=(F>>5&31)/31,p=(F>>10&31)/31):(u=m,f=y,p=T)}for(let F=1;F<=3;F++){const U=R+F*12,q=M*3*3+(F-1)*3;v[q]=h.getFloat32(U,!0),v[q+1]=h.getFloat32(U+4,!0),v[q+2]=h.getFloat32(U+8,!0),C[q]=N,C[q+1]=Q,C[q+2]=A,O&&(E.setRGB(u,f,p,Ln),g[q]=E.r,g[q+1]=E.g,g[q+2]=E.b)}}return k.setAttribute("position",new ki(v,3)),k.setAttribute("normal",new ki(C,3)),O&&(k.setAttribute("color",new ki(g,3)),k.hasColors=!0,k.alpha=w),k}function r(c){const h=new Un,d=/solid([\s\S]*?)endsolid/g,u=/facet([\s\S]*?)endfacet/g,f=/solid\s(.+)/;let p=0;const O=/[\s]+([+-]?(?:\d*)(?:\.\d*)?(?:[eE][+-]?\d+)?)/.source,g=new RegExp("vertex"+O+O+O,"g"),m=new RegExp("normal"+O+O+O,"g"),y=[],T=[],w=[],_=new G;let b,k=0,v=0,C=0;for(;(b=d.exec(c))!==null;){v=C;const E=b[0],M=(b=f.exec(E))!==null?b[1]:"";for(w.push(M);(b=u.exec(E))!==null;){let Q=0,A=0;const F=b[0];for(;(b=m.exec(F))!==null;)_.x=parseFloat(b[1]),_.y=parseFloat(b[2]),_.z=parseFloat(b[3]),A++;for(;(b=g.exec(F))!==null;)y.push(parseFloat(b[1]),parseFloat(b[2]),parseFloat(b[3])),T.push(_.x,_.y,_.z),Q++,C++;A!==1&&console.error("THREE.STLLoader: Something isn't right with the normal of face number "+p),Q!==3&&console.error("THREE.STLLoader: Something isn't right with the vertices of face number "+p),p++}const R=v,N=C-v;h.userData.groupNames=w,h.addGroup(R,N,k),k++}return h.setAttribute("position",new tn(y,3)),h.setAttribute("normal",new tn(T,3)),h}function a(c){return typeof c!="string"?new TextDecoder().decode(c):c}function o(c){if(typeof c=="string"){const h=new Uint8Array(c.length);for(let d=0;d<c.length;d++)h[d]=c.charCodeAt(d)&255;return h.buffer||h}else return c}const l=o(e);return t(l)?s(l):r(a(e))}}const ty={type:"change"},PO={type:"start"},FT={type:"end"},ph=new cu,ny=new Qs,uX=Math.cos(70*y3.DEG2RAD),on=new G,Yn=2*Math.PI,Qt={NONE:-1,ROTATE:0,DOLLY:1,PAN:2,TOUCH_ROTATE:3,TOUCH_PAN:4,TOUCH_DOLLY_PAN:5,TOUCH_DOLLY_ROTATE:6},ip=1e-6;class XT extends oI{constructor(e,t=null){super(e,t),this.state=Qt.NONE,this.target=new G,this.cursor=new G,this.minDistance=0,this.maxDistance=1/0,this.minZoom=0,this.maxZoom=1/0,this.minTargetRadius=0,this.maxTargetRadius=1/0,this.minPolarAngle=0,this.maxPolarAngle=Math.PI,this.minAzimuthAngle=-1/0,this.maxAzimuthAngle=1/0,this.enableDamping=!1,this.dampingFactor=.05,this.enableZoom=!0,this.zoomSpeed=1,this.enableRotate=!0,this.rotateSpeed=1,this.keyRotateSpeed=1,this.enablePan=!0,this.panSpeed=1,this.screenSpacePanning=!0,this.keyPanSpeed=7,this.zoomToCursor=!1,this.autoRotate=!1,this.autoRotateSpeed=2,this.keys={LEFT:"ArrowLeft",UP:"ArrowUp",RIGHT:"ArrowRight",BOTTOM:"ArrowDown"},this.mouseButtons={LEFT:Ya.ROTATE,MIDDLE:Ya.DOLLY,RIGHT:Ya.PAN},this.touches={ONE:Da.ROTATE,TWO:Da.DOLLY_PAN},this.target0=this.target.clone(),this.position0=this.object.position.clone(),this.zoom0=this.object.zoom,this._cursorStyle="auto",this._domElementKeyEvents=null,this._lastPosition=new G,this._lastQuaternion=new Mr,this._lastTargetPosition=new G,this._quat=new Mr().setFromUnitVectors(e.up,new G(0,1,0)),this._quatInverse=this._quat.clone().invert(),this._spherical=new Mv,this._sphericalDelta=new Mv,this._scale=1,this._panOffset=new G,this._rotateStart=new tt,this._rotateEnd=new tt,this._rotateDelta=new tt,this._panStart=new tt,this._panEnd=new tt,this._panDelta=new tt,this._dollyStart=new tt,this._dollyEnd=new tt,this._dollyDelta=new tt,this._dollyDirection=new G,this._mouse=new tt,this._performCursorZoom=!1,this._pointers=[],this._pointerPositions={},this._controlActive=!1,this._onPointerMove=pX.bind(this),this._onPointerDown=fX.bind(this),this._onPointerUp=mX.bind(this),this._onContextMenu=bX.bind(this),this._onMouseWheel=SX.bind(this),this._onKeyDown=xX.bind(this),this._onTouchStart=vX.bind(this),this._onTouchMove=yX.bind(this),this._onMouseDown=gX.bind(this),this._onMouseMove=OX.bind(this),this._interceptControlDown=_X.bind(this),this._interceptControlUp=wX.bind(this),this.domElement!==null&&this.connect(this.domElement),this.update()}set cursorStyle(e){this._cursorStyle=e,e==="grab"?this.domElement.style.cursor="grab":this.domElement.style.cursor="auto"}get cursorStyle(){return this._cursorStyle}connect(e){super.connect(e),this.domElement.addEventListener("pointerdown",this._onPointerDown),this.domElement.addEventListener("pointercancel",this._onPointerUp),this.domElement.addEventListener("contextmenu",this._onContextMenu),this.domElement.addEventListener("wheel",this._onMouseWheel,{passive:!1}),this.domElement.getRootNode().addEventListener("keydown",this._interceptControlDown,{passive:!0,capture:!0}),this.domElement.style.touchAction="none"}disconnect(){this.state=Qt.NONE,this.domElement.removeEventListener("pointerdown",this._onPointerDown),this.domElement.ownerDocument.removeEventListener("pointermove",this._onPointerMove),this.domElement.ownerDocument.removeEventListener("pointerup",this._onPointerUp),this.domElement.removeEventListener("pointercancel",this._onPointerUp),this.domElement.removeEventListener("wheel",this._onMouseWheel),this.domElement.removeEventListener("contextmenu",this._onContextMenu),this.stopListenToKeyEvents();const e=this.domElement.getRootNode();e.removeEventListener("keydown",this._interceptControlDown,{capture:!0}),e.removeEventListener("keyup",this._interceptControlUp,{capture:!0}),this._controlActive=!1,this._pointers.length=0,this._pointerPositions={},this.domElement.style.touchAction="",this.domElement.style.cursor="auto"}dispose(){this.disconnect()}getPolarAngle(){return this._spherical.phi}getAzimuthalAngle(){return this._spherical.theta}getDistance(){return this.object.position.distanceTo(this.target)}listenToKeyEvents(e){e.addEventListener("keydown",this._onKeyDown),this._domElementKeyEvents=e}stopListenToKeyEvents(){this._domElementKeyEvents!==null&&(this._domElementKeyEvents.removeEventListener("keydown",this._onKeyDown),this._domElementKeyEvents=null)}saveState(){this.target0.copy(this.target),this.position0.copy(this.object.position),this.zoom0=this.object.zoom}reset(){this.target.copy(this.target0),this.object.position.copy(this.position0),this.object.zoom=this.zoom0,this.object.updateProjectionMatrix(),this.dispatchEvent(ty),this.update(),this.state=Qt.NONE}pan(e,t){this._pan(e,t),this.update()}dollyIn(e){this._dollyIn(e),this.update()}dollyOut(e){this._dollyOut(e),this.update()}rotateLeft(e){this._rotateLeft(e),this.update()}rotateUp(e){this._rotateUp(e),this.update()}update(e=null){const t=this.object.position;on.copy(t).sub(this.target),on.applyQuaternion(this._quat),this._spherical.setFromVector3(on),this.autoRotate&&this.state===Qt.NONE&&this._rotateLeft(this._getAutoRotationAngle(e)),this.enableDamping?(this._spherical.theta+=this._sphericalDelta.theta*this.dampingFactor,this._spherical.phi+=this._sphericalDelta.phi*this.dampingFactor):(this._spherical.theta+=this._sphericalDelta.theta,this._spherical.phi+=this._sphericalDelta.phi);let i=this.minAzimuthAngle,s=this.maxAzimuthAngle;isFinite(i)&&isFinite(s)&&(i<-Math.PI?i+=Yn:i>Math.PI&&(i-=Yn),s<-Math.PI?s+=Yn:s>Math.PI&&(s-=Yn),i<=s?this._spherical.theta=Math.max(i,Math.min(s,this._spherical.theta)):this._spherical.theta=this._spherical.theta>(i+s)/2?Math.max(i,this._spherical.theta):Math.min(s,this._spherical.theta)),this._spherical.phi=Math.max(this.minPolarAngle,Math.min(this.maxPolarAngle,this._spherical.phi)),this._spherical.makeSafe(),this.enableDamping===!0?this.target.addScaledVector(this._panOffset,this.dampingFactor):this.target.add(this._panOffset),this.target.sub(this.cursor),this.target.clampLength(this.minTargetRadius,this.maxTargetRadius),this.target.add(this.cursor);let r=!1;if(this.zoomToCursor&&this._performCursorZoom||this.object.isOrthographicCamera)this._spherical.radius=this._clampDistance(this._spherical.radius);else{const a=this._spherical.radius;this._spherical.radius=this._clampDistance(this._spherical.radius*this._scale),r=a!=this._spherical.radius}if(on.setFromSpherical(this._spherical),on.applyQuaternion(this._quatInverse),t.copy(this.target).add(on),this.object.lookAt(this.target),this.enableDamping===!0?(this._sphericalDelta.theta*=1-this.dampingFactor,this._sphericalDelta.phi*=1-this.dampingFactor,this._panOffset.multiplyScalar(1-this.dampingFactor)):(this._sphericalDelta.set(0,0,0),this._panOffset.set(0,0,0)),this.zoomToCursor&&this._performCursorZoom){let a=null;if(this.object.isPerspectiveCamera){const o=on.length();a=this._clampDistance(o*this._scale);const l=o-a;this.object.position.addScaledVector(this._dollyDirection,l),this.object.updateMatrixWorld(),r=!!l}else if(this.object.isOrthographicCamera){const o=new G(this._mouse.x,this._mouse.y,0);o.unproject(this.object);const l=this.object.zoom;this.object.zoom=Math.max(this.minZoom,Math.min(this.maxZoom,this.object.zoom/this._scale)),this.object.updateProjectionMatrix(),r=l!==this.object.zoom;const c=new G(this._mouse.x,this._mouse.y,0);c.unproject(this.object),this.object.position.sub(c).add(o),this.object.updateMatrixWorld(),a=on.length()}else console.warn("WARNING: OrbitControls.js encountered an unknown camera type - zoom to cursor disabled."),this.zoomToCursor=!1;a!==null&&(this.screenSpacePanning?this.target.set(0,0,-1).transformDirection(this.object.matrix).multiplyScalar(a).add(this.object.position):(ph.origin.copy(this.object.position),ph.direction.set(0,0,-1).transformDirection(this.object.matrix),Math.abs(this.object.up.dot(ph.direction))<uX?this.object.lookAt(this.target):(ny.setFromNormalAndCoplanarPoint(this.object.up,this.target),ph.intersectPlane(ny,this.target))))}else if(this.object.isOrthographicCamera){const a=this.object.zoom;this.object.zoom=Math.max(this.minZoom,Math.min(this.maxZoom,this.object.zoom/this._scale)),a!==this.object.zoom&&(this.object.updateProjectionMatrix(),r=!0)}return this._scale=1,this._performCursorZoom=!1,r||this._lastPosition.distanceToSquared(this.object.position)>ip||8*(1-this._lastQuaternion.dot(this.object.quaternion))>ip||this._lastTargetPosition.distanceToSquared(this.target)>ip?(this.dispatchEvent(ty),this._lastPosition.copy(this.object.position),this._lastQuaternion.copy(this.object.quaternion),this._lastTargetPosition.copy(this.target),!0):!1}_getAutoRotationAngle(e){return e!==null?Yn/60*this.autoRotateSpeed*e:Yn/60/60*this.autoRotateSpeed}_getZoomScale(e){const t=Math.abs(e*.01);return Math.pow(.95,this.zoomSpeed*t)}_rotateLeft(e){this._sphericalDelta.theta-=e}_rotateUp(e){this._sphericalDelta.phi-=e}_panLeft(e,t){on.setFromMatrixColumn(t,0),on.multiplyScalar(-e),this._panOffset.add(on)}_panUp(e,t){this.screenSpacePanning===!0?on.setFromMatrixColumn(t,1):(on.setFromMatrixColumn(t,0),on.crossVectors(this.object.up,on)),on.multiplyScalar(e),this._panOffset.add(on)}_pan(e,t){const i=this.domElement;if(this.object.isPerspectiveCamera){const s=this.object.position;on.copy(s).sub(this.target);let r=on.length();r*=Math.tan(this.object.fov/2*Math.PI/180),this._panLeft(2*e*r/i.clientHeight,this.object.matrix),this._panUp(2*t*r/i.clientHeight,this.object.matrix)}else this.object.isOrthographicCamera?(this._panLeft(e*(this.object.right-this.object.left)/this.object.zoom/i.clientWidth,this.object.matrix),this._panUp(t*(this.object.top-this.object.bottom)/this.object.zoom/i.clientHeight,this.object.matrix)):(console.warn("WARNING: OrbitControls.js encountered an unknown camera type - pan disabled."),this.enablePan=!1)}_dollyOut(e){this.object.isPerspectiveCamera||this.object.isOrthographicCamera?this._scale/=e:(console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."),this.enableZoom=!1)}_dollyIn(e){this.object.isPerspectiveCamera||this.object.isOrthographicCamera?this._scale*=e:(console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."),this.enableZoom=!1)}_updateZoomParameters(e,t){if(!this.zoomToCursor)return;this._performCursorZoom=!0;const i=this.domElement.getBoundingClientRect(),s=e-i.left,r=t-i.top,a=i.width,o=i.height;this._mouse.x=s/a*2-1,this._mouse.y=-(r/o)*2+1,this._dollyDirection.set(this._mouse.x,this._mouse.y,1).unproject(this.object).sub(this.object.position).normalize()}_clampDistance(e){return Math.max(this.minDistance,Math.min(this.maxDistance,e))}_handleMouseDownRotate(e){this._rotateStart.set(e.clientX,e.clientY)}_handleMouseDownDolly(e){this._updateZoomParameters(e.clientX,e.clientX),this._dollyStart.set(e.clientX,e.clientY)}_handleMouseDownPan(e){this._panStart.set(e.clientX,e.clientY)}_handleMouseMoveRotate(e){this._rotateEnd.set(e.clientX,e.clientY),this._rotateDelta.subVectors(this._rotateEnd,this._rotateStart).multiplyScalar(this.rotateSpeed);const t=this.domElement;this._rotateLeft(Yn*this._rotateDelta.x/t.clientHeight),this._rotateUp(Yn*this._rotateDelta.y/t.clientHeight),this._rotateStart.copy(this._rotateEnd),this.update()}_handleMouseMoveDolly(e){this._dollyEnd.set(e.clientX,e.clientY),this._dollyDelta.subVectors(this._dollyEnd,this._dollyStart),this._dollyDelta.y>0?this._dollyOut(this._getZoomScale(this._dollyDelta.y)):this._dollyDelta.y<0&&this._dollyIn(this._getZoomScale(this._dollyDelta.y)),this._dollyStart.copy(this._dollyEnd),this.update()}_handleMouseMovePan(e){this._panEnd.set(e.clientX,e.clientY),this._panDelta.subVectors(this._panEnd,this._panStart).multiplyScalar(this.panSpeed),this._pan(this._panDelta.x,this._panDelta.y),this._panStart.copy(this._panEnd),this.update()}_handleMouseWheel(e){this._updateZoomParameters(e.clientX,e.clientY),e.deltaY<0?this._dollyIn(this._getZoomScale(e.deltaY)):e.deltaY>0&&this._dollyOut(this._getZoomScale(e.deltaY)),this.update()}_handleKeyDown(e){let t=!1;switch(e.code){case this.keys.UP:e.ctrlKey||e.metaKey||e.shiftKey?this.enableRotate&&this._rotateUp(Yn*this.keyRotateSpeed/this.domElement.clientHeight):this.enablePan&&this._pan(0,this.keyPanSpeed),t=!0;break;case this.keys.BOTTOM:e.ctrlKey||e.metaKey||e.shiftKey?this.enableRotate&&this._rotateUp(-Yn*this.keyRotateSpeed/this.domElement.clientHeight):this.enablePan&&this._pan(0,-this.keyPanSpeed),t=!0;break;case this.keys.LEFT:e.ctrlKey||e.metaKey||e.shiftKey?this.enableRotate&&this._rotateLeft(Yn*this.keyRotateSpeed/this.domElement.clientHeight):this.enablePan&&this._pan(this.keyPanSpeed,0),t=!0;break;case this.keys.RIGHT:e.ctrlKey||e.metaKey||e.shiftKey?this.enableRotate&&this._rotateLeft(-Yn*this.keyRotateSpeed/this.domElement.clientHeight):this.enablePan&&this._pan(-this.keyPanSpeed,0),t=!0;break}t&&(e.preventDefault(),this.update())}_handleTouchStartRotate(e){if(this._pointers.length===1)this._rotateStart.set(e.pageX,e.pageY);else{const t=this._getSecondPointerPosition(e),i=.5*(e.pageX+t.x),s=.5*(e.pageY+t.y);this._rotateStart.set(i,s)}}_handleTouchStartPan(e){if(this._pointers.length===1)this._panStart.set(e.pageX,e.pageY);else{const t=this._getSecondPointerPosition(e),i=.5*(e.pageX+t.x),s=.5*(e.pageY+t.y);this._panStart.set(i,s)}}_handleTouchStartDolly(e){const t=this._getSecondPointerPosition(e),i=e.pageX-t.x,s=e.pageY-t.y,r=Math.sqrt(i*i+s*s);this._dollyStart.set(0,r)}_handleTouchStartDollyPan(e){this.enableZoom&&this._handleTouchStartDolly(e),this.enablePan&&this._handleTouchStartPan(e)}_handleTouchStartDollyRotate(e){this.enableZoom&&this._handleTouchStartDolly(e),this.enableRotate&&this._handleTouchStartRotate(e)}_handleTouchMoveRotate(e){if(this._pointers.length==1)this._rotateEnd.set(e.pageX,e.pageY);else{const i=this._getSecondPointerPosition(e),s=.5*(e.pageX+i.x),r=.5*(e.pageY+i.y);this._rotateEnd.set(s,r)}this._rotateDelta.subVectors(this._rotateEnd,this._rotateStart).multiplyScalar(this.rotateSpeed);const t=this.domElement;this._rotateLeft(Yn*this._rotateDelta.x/t.clientHeight),this._rotateUp(Yn*this._rotateDelta.y/t.clientHeight),this._rotateStart.copy(this._rotateEnd)}_handleTouchMovePan(e){if(this._pointers.length===1)this._panEnd.set(e.pageX,e.pageY);else{const t=this._getSecondPointerPosition(e),i=.5*(e.pageX+t.x),s=.5*(e.pageY+t.y);this._panEnd.set(i,s)}this._panDelta.subVectors(this._panEnd,this._panStart).multiplyScalar(this.panSpeed),this._pan(this._panDelta.x,this._panDelta.y),this._panStart.copy(this._panEnd)}_handleTouchMoveDolly(e){const t=this._getSecondPointerPosition(e),i=e.pageX-t.x,s=e.pageY-t.y,r=Math.sqrt(i*i+s*s);this._dollyEnd.set(0,r),this._dollyDelta.set(0,Math.pow(this._dollyEnd.y/this._dollyStart.y,this.zoomSpeed)),this._dollyOut(this._dollyDelta.y),this._dollyStart.copy(this._dollyEnd);const a=(e.pageX+t.x)*.5,o=(e.pageY+t.y)*.5;this._updateZoomParameters(a,o)}_handleTouchMoveDollyPan(e){this.enableZoom&&this._handleTouchMoveDolly(e),this.enablePan&&this._handleTouchMovePan(e)}_handleTouchMoveDollyRotate(e){this.enableZoom&&this._handleTouchMoveDolly(e),this.enableRotate&&this._handleTouchMoveRotate(e)}_addPointer(e){this._pointers.push(e.pointerId)}_removePointer(e){delete this._pointerPositions[e.pointerId];for(let t=0;t<this._pointers.length;t++)if(this._pointers[t]==e.pointerId){this._pointers.splice(t,1);return}}_isTrackingPointer(e){for(let t=0;t<this._pointers.length;t++)if(this._pointers[t]==e.pointerId)return!0;return!1}_trackPointer(e){let t=this._pointerPositions[e.pointerId];t===void 0&&(t=new tt,this._pointerPositions[e.pointerId]=t),t.set(e.pageX,e.pageY)}_getSecondPointerPosition(e){const t=e.pointerId===this._pointers[0]?this._pointers[1]:this._pointers[0];return this._pointerPositions[t]}_customWheelEvent(e){const t=e.deltaMode,i={clientX:e.clientX,clientY:e.clientY,deltaY:e.deltaY};switch(t){case 1:i.deltaY*=16;break;case 2:i.deltaY*=100;break}return e.ctrlKey&&!this._controlActive&&(i.deltaY*=10),i}}function fX(n){this.enabled!==!1&&(this._pointers.length===0&&(this.domElement.setPointerCapture(n.pointerId),this.domElement.ownerDocument.addEventListener("pointermove",this._onPointerMove),this.domElement.ownerDocument.addEventListener("pointerup",this._onPointerUp)),!this._isTrackingPointer(n)&&(this._addPointer(n),n.pointerType==="touch"?this._onTouchStart(n):this._onMouseDown(n),this._cursorStyle==="grab"&&(this.domElement.style.cursor="grabbing")))}function pX(n){this.enabled!==!1&&(n.pointerType==="touch"?this._onTouchMove(n):this._onMouseMove(n))}function mX(n){switch(this._removePointer(n),this._pointers.length){case 0:this.domElement.releasePointerCapture(n.pointerId),this.domElement.ownerDocument.removeEventListener("pointermove",this._onPointerMove),this.domElement.ownerDocument.removeEventListener("pointerup",this._onPointerUp),this.dispatchEvent(FT),this.state=Qt.NONE,this._cursorStyle==="grab"&&(this.domElement.style.cursor="grab");break;case 1:const e=this._pointers[0],t=this._pointerPositions[e];this._onTouchStart({pointerId:e,pageX:t.x,pageY:t.y});break}}function gX(n){let e;switch(n.button){case 0:e=this.mouseButtons.LEFT;break;case 1:e=this.mouseButtons.MIDDLE;break;case 2:e=this.mouseButtons.RIGHT;break;default:e=-1}switch(e){case Ya.DOLLY:if(this.enableZoom===!1)return;this._handleMouseDownDolly(n),this.state=Qt.DOLLY;break;case Ya.ROTATE:if(n.ctrlKey||n.metaKey||n.shiftKey){if(this.enablePan===!1)return;this._handleMouseDownPan(n),this.state=Qt.PAN}else{if(this.enableRotate===!1)return;this._handleMouseDownRotate(n),this.state=Qt.ROTATE}break;case Ya.PAN:if(n.ctrlKey||n.metaKey||n.shiftKey){if(this.enableRotate===!1)return;this._handleMouseDownRotate(n),this.state=Qt.ROTATE}else{if(this.enablePan===!1)return;this._handleMouseDownPan(n),this.state=Qt.PAN}break;default:this.state=Qt.NONE}this.state!==Qt.NONE&&this.dispatchEvent(PO)}function OX(n){switch(this.state){case Qt.ROTATE:if(this.enableRotate===!1)return;this._handleMouseMoveRotate(n);break;case Qt.DOLLY:if(this.enableZoom===!1)return;this._handleMouseMoveDolly(n);break;case Qt.PAN:if(this.enablePan===!1)return;this._handleMouseMovePan(n);break}}function SX(n){this.enabled===!1||this.enableZoom===!1||this.state!==Qt.NONE||(n.preventDefault(),this.dispatchEvent(PO),this._handleMouseWheel(this._customWheelEvent(n)),this.dispatchEvent(FT))}function xX(n){this.enabled!==!1&&this._handleKeyDown(n)}function vX(n){switch(this._trackPointer(n),this._pointers.length){case 1:switch(this.touches.ONE){case Da.ROTATE:if(this.enableRotate===!1)return;this._handleTouchStartRotate(n),this.state=Qt.TOUCH_ROTATE;break;case Da.PAN:if(this.enablePan===!1)return;this._handleTouchStartPan(n),this.state=Qt.TOUCH_PAN;break;default:this.state=Qt.NONE}break;case 2:switch(this.touches.TWO){case Da.DOLLY_PAN:if(this.enableZoom===!1&&this.enablePan===!1)return;this._handleTouchStartDollyPan(n),this.state=Qt.TOUCH_DOLLY_PAN;break;case Da.DOLLY_ROTATE:if(this.enableZoom===!1&&this.enableRotate===!1)return;this._handleTouchStartDollyRotate(n),this.state=Qt.TOUCH_DOLLY_ROTATE;break;default:this.state=Qt.NONE}break;default:this.state=Qt.NONE}this.state!==Qt.NONE&&this.dispatchEvent(PO)}function yX(n){switch(this._trackPointer(n),this.state){case Qt.TOUCH_ROTATE:if(this.enableRotate===!1)return;this._handleTouchMoveRotate(n),this.update();break;case Qt.TOUCH_PAN:if(this.enablePan===!1)return;this._handleTouchMovePan(n),this.update();break;case Qt.TOUCH_DOLLY_PAN:if(this.enableZoom===!1&&this.enablePan===!1)return;this._handleTouchMoveDollyPan(n),this.update();break;case Qt.TOUCH_DOLLY_ROTATE:if(this.enableZoom===!1&&this.enableRotate===!1)return;this._handleTouchMoveDollyRotate(n),this.update();break;default:this.state=Qt.NONE}}function bX(n){this.enabled!==!1&&n.preventDefault()}function _X(n){n.key==="Control"&&(this._controlActive=!0,this.domElement.getRootNode().addEventListener("keyup",this._interceptControlUp,{passive:!0,capture:!0}))}function wX(n){n.key==="Control"&&(this._controlActive=!1,this.domElement.getRootNode().removeEventListener("keyup",this._interceptControlUp,{passive:!0,capture:!0}))}const bo=n=>{var e;return(e=window.matchMedia)!=null&&e.call(window,"(prefers-reduced-motion: reduce)").matches?1:n},zT=bt.define(),TX=ei.define({create:()=>Ie.none,update(n,e){n=n.map(e.changes);for(const t of e.effects)t.is(zT)&&(n=t.value);return n},provide:n=>Ae.decorations.from(n)});let sp=null,gr=null,na=new Set,rp=Promise.resolve(),iy=null,ap=0;async function BT(){return sp||(sp=window.stillnote.loadSpellcheckDictionary().then(n=>{gr=new Set(n.split(/\r?\n/).map(e=>e.trim().toLocaleLowerCase()).filter(Boolean));for(const e of gr)Gh.has(e[0])||Gh.set(e[0],[]),Zh.has(e.at(-1))||Zh.set(e.at(-1),[]),Gh.get(e[0]).push(e),Zh.get(e.at(-1)).push(e);return gr})),sp}function ql(n){const e=++ap;clearTimeout(iy),iy=setTimeout(async()=>{try{const t=await BT();if(e!==ap||n!==S.view)return;const i=n.state.doc.toString(),s=[];Tt(n.state).iterate({enter(l){["FencedCode","InlineCode","LinkDestination"].includes(l.type.name)&&s.push([l.from,l.to])}});const r=[],a=/[\p{L}]+(?:['’][\p{L}]+)?/gu;let o;for(;o=a.exec(i);){const l=o[0].toLocaleLowerCase();l.length<3||s.some(([c,h])=>o.index>=c&&o.index<h)||mu(l)||r.push(Ie.mark({class:"spellcheck-misspelled",attributes:{title:"Possible spelling mistake"}}).range(o.index,o.index+o[0].length))}e===ap&&n===S.view&&n.dispatch({effects:zT.of(Ie.set(r,!0))})}catch(t){console.error("Spellcheck dictionary could not be loaded:",t)}},180)}function MX(n){if(!gr||n.length<3)return[];const e=n.toLocaleLowerCase(),t=new Set([...Gh.get(e[0])||[],...Zh.get(e.at(-1))||[]]),i=[];for(const s of t){if(Math.abs(s.length-e.length)>2)continue;const r=EX(e,s);r<=2&&i.push({candidate:s,distance:r})}return i.sort((s,r)=>s.distance-r.distance||s.candidate.localeCompare(r.candidate)).slice(0,5).map(({candidate:s})=>s)}function sy(n){return new Set((Array.isArray(n)?n:[]).filter(e=>typeof e=="string").map(e=>e.trim().toLocaleLowerCase()).filter(e=>/^[\p{L}][\p{L}'’\-]{0,63}$/u.test(e)))}async function PX(){const n=await window.stillnote.loadCustomDictionary();let e=n.words;if(n.exists)localStorage.removeItem("stillnote-custom-dictionary");else try{const t=sy(JSON.parse(localStorage.getItem("stillnote-custom-dictionary")||"[]"));t.size&&(e=[...t],await window.stillnote.saveCustomDictionary(e)),localStorage.removeItem("stillnote-custom-dictionary")}catch(t){console.warn("Could not migrate the personal dictionary into this vault:",t.message)}na=sy(e),cc(),S.view&&ql(S.view)}function VT(){if(!S.vault)return Promise.reject(new Error("Open a vault before saving personal words."));const n=[...na].sort((e,t)=>e.localeCompare(t));return rp=rp.catch(()=>{}).then(()=>window.stillnote.saveCustomDictionary(n)),rp.catch(e=>{throw Re(e.message||"Could not save the personal dictionary."),e})}function WT(n){if(!S.vault)return Re("Open a vault before adding personal words."),!1;const e=String(n||"").trim().toLocaleLowerCase();return/^[\p{L}][\p{L}'’\-]{0,63}$/u.test(e)?mu(e)?(Re(`“${e}” is already in the dictionary.`),!1):(na.add(e),VT().catch(()=>{}),cc(),S.view&&ql(S.view),!0):(Re("Enter a single word using letters, apostrophes, or hyphens."),!1)}function cc(){const n=L("#custom-dictionary-list");if(!n)return;n.replaceChildren();const e=[...na].sort((t,i)=>t.localeCompare(i));if(!e.length){const t=document.createElement("p");t.className="dictionary-empty",t.textContent="No personal words yet.",n.append(t);return}for(const t of e){const i=document.createElement("div");i.className="dictionary-word-row";const s=document.createElement("span");s.textContent=t;const r=document.createElement("button");r.type="button",r.className="icon-button dictionary-remove",r.setAttribute("aria-label",`Remove ${t} from dictionary`),r.title="Remove word",r.innerHTML=fe.close,r.addEventListener("click",()=>{na.delete(t),VT().catch(()=>{}),cc(),S.view&&ql(S.view)}),i.append(s,r),n.append(i)}}function EX(n,e){if(Math.abs(n.length-e.length)>2)return 3;let t=Array.from({length:e.length+1},(s,r)=>r),i=null;for(let s=1;s<=n.length;s++){const r=[s];let a=s;for(let o=1;o<=e.length;o++){let l=Math.min(r[o-1]+1,t[o]+1,t[o-1]+(n[s-1]===e[o-1]?0:1));i&&s>1&&o>1&&n[s-1]===e[o-2]&&n[s-2]===e[o-1]&&(l=Math.min(l,i[o-2]+1)),r[o]=l,a=Math.min(a,l)}if(a>2)return 3;i=t,t=r}return t[e.length]}const Gh=new Map,Zh=new Map,We=(n,e="")=>`<svg class="app-icon ${e}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">${n}</svg>`,fe={panel:We('<rect x="3.5" y="4.5" width="17" height="15" rx="2"/><path d="M9 4.5v15"/>'),home:We('<path d="m3.5 10 8.5-7 8.5 7v9a2 2 0 0 1-2 2h-13a2 2 0 0 1-2-2z"/><path d="M9 21v-8h6v8"/>'),search:We('<circle cx="10.8" cy="10.8" r="6.3"/><path d="m15.5 15.5 4.2 4.2"/>'),file:We('<path d="M6 3.8h8l4 4v12.4H6z"/><path d="M14 3.8v4h4M9 12h6M9 15.5h6"/>'),filePlus:We('<path d="M6 3.8h8l4 4v12.4H6z"/><path d="M14 3.8v4h4M12 11v6M9 14h6"/>'),formatBold:We('<path d="M7 5h6a4 4 0 0 1 0 8H7zM7 13h7a3 3 0 0 1 0 6H7z"/>'),formatItalic:We('<path d="M10 5h9M5 19h9M14 5 10 19"/>'),formatCode:We('<path d="m8 8-4 4 4 4M16 8l4 4-4 4M14 5l-4 14"/>'),formatStrike:We('<path d="M5 8a4 4 0 0 1 4-3h6a4 4 0 0 1 3 1.4M4 12h16M19 16a4 4 0 0 1-4 3H9a4 4 0 0 1-3-1.4"/>'),formatH1:We('<path d="M4 5v14M4 12h8M12 5v14M17 8l2-2v12M16 18h6"/>'),formatH2:We('<path d="M3 5v14M3 12h8M11 5v14M15 9a3 3 0 0 1 6 0c0 3-6 4-6 9h7"/>'),formatBullet:We('<circle cx="5" cy="6" r="1"/><circle cx="5" cy="12" r="1"/><circle cx="5" cy="18" r="1"/><path d="M10 6h10M10 12h10M10 18h10"/>'),formatOrdered:We('<path d="M9 6h11M9 12h11M9 18h11M4 5h1v3M4 11h2l-2 2h2M4 17h2l-2 2h2"/>'),formatCheck:We('<rect x="3.5" y="4" width="6" height="6" rx="1"/><path d="m5 7 1.4 1.4L8.5 6M13 7h7M3.5 14h6v6h-6zM13 17h7"/>'),tasks:We('<path d="m4 7 1.5 1.5L8 5.8M11 7h9M4 16l1.5 1.5L8 14.8M11 16h9"/>'),formatHighlight:We('<path d="m8 14 7-7 4 4-7 7H8zM6 20h13M13 9l4 4M5 5h3M6.5 3.5v3M18 17l2 2M19 18l2-2"/>'),canvas:We('<rect x="4" y="4" width="16" height="16" rx="2"/><path d="m7 16 3-4 2 2 3-5 2 7"/>'),cursor:We('<path d="m5 3 14 10-7 1-3 7z"/>'),draw:We('<path d="m4 16 9-9 4 4-9 9H4zM12 8l4 4M14 6l2-2 4 4-2 2"/>'),rectangle:We('<rect x="4" y="5" width="16" height="14" rx="1"/>'),shape:We('<rect x="3.5" y="4" width="7" height="7" rx="1"/><circle cx="17" cy="7.5" r="3.5"/><path d="m5 20 4-6 4 6z"/>'),triangle:We('<path d="m12 3 9 17H3z"/>'),speech:We('<path d="M4 4h16v12H10l-5 4z"/>'),markerArrow:We('<path d="M3 8h11V4l7 8-7 8v-4H3z"/>'),markerCircle:We('<circle cx="12" cy="12" r="7"/>'),markerSquare:We('<rect x="5" y="5" width="14" height="14" rx="1"/>'),markerDiamond:We('<path d="m12 3 9 9-9 9-9-9z"/>'),markerNone:We('<path d="M5 5l14 14M19 5 5 19"/>'),ellipse:We('<ellipse cx="12" cy="12" rx="8" ry="6"/>'),rotate:We('<rect x="8" y="8" width="9" height="9" rx="1"/><path d="M5 8a8 8 0 0 1 12-4M17 1v4h-4"/>'),text:We('<path d="M4 6V4h16v2M12 4v16M9 20h6"/>'),line:We('<path d="M4 18 20 6"/>'),eraser:We('<path d="m7 16-3-3a2 2 0 0 1 0-3l6-6a2 2 0 0 1 3 0l6 6-8 8H7zM13 18h7"/>'),trash:We('<path d="M4 7h16M10 11v6M14 11v6M6 7l1 13h10l1-13M9 7V4h6v3"/>'),star:We('<path d="m12 3 2.75 5.57 6.15.89-4.45 4.33 1.05 6.12L12 17.02l-5.5 2.89 1.05-6.12L3.1 9.46l6.15-.89L12 3z"/>'),undo:We('<path d="M9 14 4 9l5-5"/><path d="M4 9h9a6 6 0 0 1 0 12h-2"/>'),redo:We('<path d="m15 14 5-5-5-5"/><path d="M20 9h-9a6 6 0 0 0 0 12h2"/>'),spreadsheet:We('<rect x="4" y="4" width="16" height="16" rx="2"/><path d="M4 9h16M4 14h16M10 9v11M15 9v11"/>'),graph:We('<path d="M4 20V4M4 20h16"/><path d="M7 16c2-1 2-7 5-7s3 5 6 1"/>'),folder:We('<path d="M3.5 7.5a2 2 0 0 1 2-2H10l2 2h6.5a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2h-13a2 2 0 0 1-2-2z"/>'),folderOpen:We('<path d="M3.5 7.5a2 2 0 0 1 2-2H10l2 2h6.5a2 2 0 0 1 2 2v1"/><path d="m3.5 12 1.2-1.5h15.8l-2.2 7a2 2 0 0 1-1.9 1.5H5.2a2 2 0 0 1-1.9-2.5z"/>'),folderPlus:We('<path d="M3 8a2 2 0 0 1 2-2h4.5l2 2H18a2 2 0 0 1 2 2v2"/><path d="M3 12h11M8.5 9.5v5M3 12l1.7 6.3A2 2 0 0 0 6.6 20h7"/>'),expandAll:We('<path d="M8 4H5a1 1 0 0 0-1 1v3M16 4h3a1 1 0 0 1 1 1v3M8 20H5a1 1 0 0 1-1-1v-3M16 20h3a1 1 0 0 0 1-1v-3"/><path d="M12 7v10M7 12h10"/>'),collapseAll:We('<path d="M8 4H5a1 1 0 0 0-1 1v3M16 4h3a1 1 0 0 1 1 1v3M8 20H5a1 1 0 0 1-1-1v-3M16 20h3a1 1 0 0 0 1-1v-3"/><path d="M7 12h10"/>'),menu:We('<path d="M4 6h16M4 12h16M4 18h16"/>'),chevron:We('<path d="m9 18 6-6-6-6"/>'),down:We('<path d="m6 9 6 6 6-6"/>'),refresh:We('<path d="M17.7 5.3A8 8 0 1 0 20 11"/><path d="M20 3v5h-5"/>'),external:We('<path d="M14 5h5v5M19 5l-8 8"/><path d="M17 13v5a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1V8a1 1 0 0 1 1-1h5"/>'),gear:We('<path d="M4 6h7m4 0h5M4 12h3m4 0h9M4 18h9m4 0h3"/><circle cx="13" cy="6" r="2"/><circle cx="9" cy="12" r="2"/><circle cx="15" cy="18" r="2"/>'),assistant:We('<path d="m12 3 1.6 5.4L19 10l-5.4 1.6L12 17l-1.6-5.4L5 10l5.4-1.6zM19 16l.8 2.2L22 19l-2.2.8L19 22l-.8-2.2L16 19l2.2-.8z"/>'),send:We('<path d="m21 3-7.2 18-3.2-7.6L3 10.2z"/><path d="M10.6 13.4 21 3"/>'),mic:We('<rect x="9" y="2" width="6" height="12" rx="3"/><path d="M5 10a7 7 0 0 0 14 0M12 17v5m-4 0h8"/>'),shift:We('<path d="m5 12 7-7 7 7h-4v7H9v-7z"/>',"shortcut-shift-icon"),close:We('<path d="m6 6 12 12M18 6 6 18"/>'),statusCheck:We('<path d="m5 12.5 4.5 4.5L19 7"/>'),statusX:We('<path d="m6 6 12 12M18 6 6 18"/>'),book:We('<path d="M5 4.5h11a3 3 0 0 1 3 3v12H8a3 3 0 0 1-3-3z"/><path d="M5 16.5a3 3 0 0 1 3-3h11M9 8h6"/>',"brand-mark-icon"),command:We('<path d="M9 9h6v6H9z"/><path d="M9 9V6a2 2 0 1 0-2 2h10a2 2 0 1 0-2-2v12a2 2 0 1 0-2-2H7a2 2 0 1 0 2 2z"/>')},AX=document.querySelector("#app"),kX=window.stillnote.platform==="win32";AX.innerHTML=`
|
|
4357
4357
|
<div class="app-shell">
|
|
4358
|
-
<header class="topbar">
|
|
4358
|
+
<header class="topbar${kX?" topbar-windows":""}">
|
|
4359
4359
|
<div class="traffic-space"></div>
|
|
4360
4360
|
<button class="icon-button sidebar-toggle" aria-label="Toggle sidebar">${fe.panel}</button>
|
|
4361
4361
|
<div class="topbar-location"><span class="location-vault">No vault</span><span class="location-divider">/</span><span class="location-note">Welcome</span></div>
|
|
@@ -4444,34 +4444,34 @@ void main() {
|
|
|
4444
4444
|
</div>
|
|
4445
4445
|
<div class="rename-overlay delete-overlay" id="delete-overlay" hidden><section class="rename-dialog" role="alertdialog" aria-modal="true" aria-labelledby="delete-title"><h2 id="delete-title">Delete item?</h2><p id="delete-description"></p><div class="rename-actions"><button type="button" class="secondary-button" id="delete-cancel">Cancel</button><button type="button" class="primary-button delete-confirm" id="delete-confirm">Delete</button></div></section></div>
|
|
4446
4446
|
<div class="toast" id="toast" hidden></div>
|
|
4447
|
-
</div>`;const S={vault:null,files:[],tree:[],collapsed:new Set,active:null,home:!1,homeChats:CX(),homeSession:null,view:null,structured:null,assetViewer:null,assetPath:null,assetBytes:null,pdfText:null,pdfTextPromise:null,toolbarPositions:kX(),saveTimer:null,savePromise:null,dirty:!1,lastTitleValidationMessage:null,sidebarOpen:!0,sidebarWidth:Number(localStorage.getItem("stillnote-sidebar-width"))||258,assistantWidth:Number(localStorage.getItem("stillnote-assistant-width"))||360,theme:"light",assistantOpen:!1,assistantMode:"ask",chatHistory:[],draggedItem:null};function kX(){const n=localStorage.getItem("stillnote-notes-toolbar-position"),e=localStorage.getItem("stillnote-canvas-toolbar-position");return{notes:["left","right","bottom","hidden"].includes(n)?n:"right",canvas:["left","right","bottom"].includes(e)?e:"right"}}function CX(){try{const n=JSON.parse(localStorage.getItem("stillnote-home-chats")||"[]");return Array.isArray(n)?n.slice(0,3):[]}catch{return[]}}function RX(){S.homeSession&&(S.homeSession.updatedAt=Date.now(),S.homeChats=[S.homeSession,...S.homeChats.filter(n=>n.id!==S.homeSession.id)].slice(0,3),localStorage.setItem("stillnote-home-chats",JSON.stringify(S.homeChats)))}let qh=null,Hh=null;const L=n=>document.querySelector(n),op=L("#note-list");xz();const QX=new Set(["HeaderMark","EmphasisMark","CodeMark","LinkMark","LinkDestination","LinkTitle","StrikethroughMark","ListMark","QuoteMark","TaskMarker"]);class ry extends Ci{constructor(e,t){super(),this.text=e,this.className=t}toDOM(){const e=document.createElement("span");return e.className=this.className,e.textContent=this.text,e}eq(e){return e.text===this.text&&e.className===this.className}}class LX extends Ci{toDOM(){const e=document.createElement("hr");return e.className="cm-md-horizontal-rule-widget",e}}class $X extends Ci{constructor(e,t,i){super(),this.checked=e,this.from=t,this.to=i}toDOM(e){const t=document.createElement("input");return t.type="checkbox",t.className="cm-md-task-checkbox",t.checked=this.checked,t.setAttribute("aria-label",this.checked?"Mark task incomplete":"Mark task complete"),t.addEventListener("mousedown",i=>i.preventDefault()),t.addEventListener("change",()=>e.dispatch({changes:{from:this.from,to:this.to,insert:t.checked?"[x]":"[ ]"}})),t}eq(e){return this.checked===e.checked&&this.from===e.from&&this.to===e.to}}const DX="http://www.w3.org/1998/Math/MathML",mh={alpha:"α",beta:"β",gamma:"γ",delta:"δ",epsilon:"ε",theta:"θ",lambda:"λ",mu:"μ",pi:"π",rho:"ρ",sigma:"σ",tau:"τ",phi:"φ",chi:"χ",psi:"ψ",omega:"ω",Gamma:"Γ",Delta:"Δ",Theta:"Θ",Lambda:"Λ",Pi:"Π",Sigma:"Σ",Phi:"Φ",Psi:"Ψ",Omega:"Ω"};function vn(n,e){const t=document.createElementNS(DX,n);return e!=null&&(t.textContent=e),t}function IX(n){let e=0;function t(r=""){const a=vn("mrow");for(;e<n.length&&n[e]!==r;){let o;const l=n[e++];if(!/\s/.test(l)){if(l==="{")o=t("}"),e++;else if(l==="\\"||l==="/"){const c=(n.slice(e).match(/^[A-Za-z]+/)||[""])[0];if(e+=c.length,l==="/"&&!mh[c]&&!["int","infty","sum","prod","frac","sqrt","cdot","times","le","ge","neq","pm"].includes(c)){e-=c.length,o=vn("mo","/"),a.append(o);continue}if(c==="frac"||c==="dfrac"||c==="tfrac"){const h=i(),d=i();o=vn("mfrac"),o.append(h,d)}else if(c==="sqrt")o=vn("msqrt"),o.append(i());else if(c==="int"||c==="infty"||c==="sum"||c==="prod")o=vn("mo",{int:"∫",infty:"∞",sum:"∑",prod:"∏"}[c]);else if(mh[c])o=vn("mi",mh[c]);else if(c==="cdot"||c==="times"||c==="le"||c==="ge"||c==="neq"||c==="pm")o=vn("mo",{cdot:"·",times:"×",le:"≤",ge:"≥",neq:"≠",pm:"±"}[c]);else if(c==="left"||c==="right"){const h=n[e++];o=vn("mo",h||"")}else o=vn("mi",c||n[e-1])}else if(l==="^"||l==="_"){const c=i();a.lastChild||a.append(vn("mi"," "));const h=a.lastChild;a.removeChild(h);const d=vn(l==="^"?"msup":"msub");d.append(h,c),a.append(d);continue}else"+-=<>(),[]|".includes(l)?o=vn("mo",l):/\d/.test(l)?o=vn("mn",l):o=vn("mi",l);o&&a.append(o)}}return a}function i(){for(;n[e]===" ";)e++;if(n[e]==="{"){e++;const r=t("}");return e++,r}return s()}function s(){for(;n[e]===" ";)e++;if(e>=n.length)return vn("mrow");let r=n[e++];if(r==="\\"||r==="/"){const o=(n.slice(e).match(/^[A-Za-z]+/)||[""])[0];e+=o.length,r=mh[o]||{int:"∫",infty:"∞",sum:"∑",prod:"∏",cdot:"·",times:"×",le:"≤",ge:"≥",neq:"≠",pm:"±"}[o]||o||r}return vn(/^\d/.test(r)?"mn":"mi",r)}return t()}class UX extends Ci{constructor(e,t,i){super(),this.source=e,this.from=t,this.to=i}toDOM(e){const t=vn("math");return t.setAttribute("display","inline"),t.classList.add("cm-md-equation"),t.append(IX(this.source)),t.dataset.equation=this.source,t.title="Click to edit · right-click for Desmos preview",t.addEventListener("mousedown",i=>{if(i.button!==0)return;i.preventDefault();const s=t.getBoundingClientRect(),r=s.width?Math.max(0,Math.min(1,(i.clientX-s.left)/s.width)):0,a=Math.round(r*this.source.length);e.dispatch({selection:{anchor:this.from+1+a},scrollIntoView:!0}),e.focus()}),t}eq(e){return e.source===this.source&&e.from===this.from&&e.to===this.to}}class NX extends Ci{constructor(e,t,i){super(),this.file=e,this.from=t,this.to=i}toDOM(e){const t=`.${oa(this.file)}`,i=[".obj",".stl",".step",".stp"].includes(t),s=document.createElement("span");s.className=`cm-wiki-media-preview${i?" is-3d":" is-image"}`,s.title=`${this.file} · place the caret in the link to edit it`;const r=document.createElement("button");r.type="button",r.className="cm-wiki-media-edit",r.textContent="Edit link",r.title="Show and edit the link",r.addEventListener("mousedown",o=>{o.preventDefault(),o.stopPropagation()}),r.addEventListener("click",o=>{o.preventDefault(),o.stopPropagation(),e.dispatch({selection:{anchor:this.from+2},scrollIntoView:!0}),e.focus()}),s.append(r);const a=document.createElement("span");return a.className="cm-wiki-media-loading",a.textContent="Loading preview…",s.append(a),window.stillnote.readAsset(this.file).then(o=>{if(s.isConnected){if(s.replaceChildren(r),o.mime.startsWith("image/")){const l=document.createElement("img");l.className="cm-wiki-image-preview",l.src=o.data,l.alt=this.file,l.loading="lazy",s.append(l)}else if([".obj",".stl",".step",".stp"].includes(t)){const l=document.createElement("span");l.className="cm-wiki-3d-preview",s.append(l),ez(l,this.file,o,s)}}}).catch(()=>{if(!s.isConnected)return;s.classList.add("is-error");const o=document.createElement("span");o.textContent=`Preview unavailable · ${this.file}`,s.replaceChildren(r,o)}),s.addEventListener("pointerdown",o=>o.stopPropagation()),s.addEventListener("mousedown",o=>o.stopPropagation()),s}destroy(e){var t;(t=e.__disposePreview)==null||t.call(e)}eq(e){return e.file===this.file&&e.from===this.from&&e.to===this.to}}function ay(n,e,t){var a,o;(o=(a=document.querySelector(".equation-preview"))==null?void 0:a._dismiss)==null||o.call(a);const i=document.createElement("section");i.className="equation-preview",i.setAttribute("role","dialog"),i.setAttribute("aria-label","Desmos equation preview"),i.style.left=`${Math.min(e,innerWidth-440)}px`,i.style.top=`${Math.min(t,innerHeight-330)}px`,i.innerHTML='<div class="equation-preview-graph"></div>';const s=l=>{var c,h;l&&i.contains(l.target)||(document.removeEventListener("pointerdown",s),(h=(c=i._calculator)==null?void 0:c.destroy)==null||h.call(c),i.remove())};i._dismiss=()=>s(),document.body.append(i),document.addEventListener("pointerdown",s);const r=()=>{if(!i.isConnected)return;if(!window.Desmos){i.querySelector(".equation-preview-graph").textContent="Desmos could not be loaded. Check your internet connection.";return}const l=window.Desmos.GraphingCalculator(i.querySelector(".equation-preview-graph"),{expressions:!1,settingsMenu:!1,zoomButtons:!0}),c=n.replace(/\/(alpha|beta|gamma|delta|epsilon|theta|lambda|mu|pi|rho|sigma|tau|phi|chi|psi|omega|Gamma|Delta|Theta|Lambda|Pi|Sigma|Phi|Psi|Omega|int|infty|sum|prod|frac|sqrt|cdot|times|le|ge|neq|pm)\b/g,(h,d)=>`\\${d}`);l.setExpression({id:"equation",latex:c}),i._calculator=l};if(window.Desmos)r();else{let l=document.querySelector("#desmos-api");l?l.addEventListener("load",r,{once:!0}):(l=document.createElement("script"),l.id="desmos-api",l.src="https://www.desmos.com/api/v1.11/calculator.js?apiKey=dcb31709b452b1cf9dc26972add0fda6",l.onload=r,l.onerror=()=>{i.isConnected&&(i.querySelector(".equation-preview-graph").textContent="Desmos could not be loaded. Check your internet connection.")},document.head.append(l))}}function oy(n){const e=[],t=new Set(n.state.selection.ranges.map(o=>n.state.doc.lineAt(o.head).number)),i=new Set,s=[];Tt(n.state).iterate({enter(o){o.type.name==="FencedCode"&&s.push([o.from,o.to])}});const r=[];for(let o=1;o<=n.state.doc.lines;o++){const l=n.state.doc.line(o);if(s.some(([d,u])=>l.from>=d&&l.to<=u))continue;const c=new RegExp("(?<!\\$)\\$([^\\s$](?:[^$\\n]*?[^\\s$])?)\\$(?!\\$)","g");let h;for(;h=c.exec(l.text);){const d=l.from+h.index,u=d+h[0].length;Tt(n.state).resolveInner(d+1).type.is("InlineCode")||r.push({from:d,to:u,source:h[1],line:o})}}const a=[];Tt(n.state).iterate({enter(o){const l=o.type.name,c=n.state.doc.lineAt(o.from);if(l!=="FencedCode"&&r.some(({from:u,to:f})=>o.from<f&&o.to>u))return;if((l==="Emphasis"||l==="StrongEmphasis")&&o.to>o.from&&a.push([o.from,o.to]),l==="TaskMarker"&&o.to>o.from){const u=n.state.doc.sliceString(o.from,o.to);e.push(Ie.replace({widget:new $X(/\[[xX]\]/.test(u),o.from,o.to)}).range(o.from,o.to));return}if(l==="ListMark"&&o.to>o.from){const u=n.state.doc.sliceString(o.from,o.to);if(/^[*+-]$/.test(u.trim())){const f=/^\s*[-*+]\s+\[[ xX]\](?:\s|$)/.test(c.text);e.push(f?Ie.replace({}).range(o.from,o.to):Ie.replace({widget:new ry("•","cm-md-bullet")}).range(o.from,o.to)),i.has(c.from)||(e.push(Ie.line({class:"cm-md-list-line"}).range(c.from)),i.add(c.from))}else e.push(Ie.replace({widget:new ry(u.trim(),"cm-md-ordered-marker")}).range(o.from,o.to));return}const h=l.match(/^(?:ATX|Setext)Heading([1-6])$/);h&&o.to>o.from&&e.push(Ie.mark({class:`cm-md-heading cm-md-h${h[1]}`}).range(o.from,o.to));const d={Emphasis:"cm-md-emphasis",StrongEmphasis:"cm-md-strong",Strikethrough:"cm-md-strikethrough",InlineCode:"cm-md-inline-code",Link:"cm-md-link",Image:"cm-md-image",FencedCode:"cm-md-code-block"};if(d[l]&&o.to>o.from&&e.push(Ie.mark({class:d[l]}).range(o.from,o.to)),QX.has(l)&&o.to>o.from){const u=l==="EmphasisMark"&&a.some(([f,p])=>o.from>=f&&o.to<=p&&n.state.selection.ranges.some(O=>O.head>=f&&O.head<=p));(l==="EmphasisMark"?!u:!t.has(c.number))&&e.push(Ie.replace({}).range(o.from,o.to))}}});for(let o=1;o<=n.state.doc.lines;o++){const l=n.state.doc.line(o),c=s.some(([h,d])=>l.from>=h&&l.to<=d);if(!c){const h=/(?:<\[([^\]]+)\]>|\[\[([^\]]+)\]\])/g;let d;for(;d=h.exec(l.text);){const p=l.from+d.index,O=p+d[0].length;if(Tt(n.state).resolveInner(p+2).type.is("InlineCode"))continue;const g=(d[1]||d[2]).split("|")[0].split("#")[0].trim(),m=RO(g),y=m?`.${oa(m)}`:"",T=[".png",".jpg",".jpeg",".webp",".heic",".icns",".svg",".obj",".stl",".step",".stp"].includes(y),w=n.state.selection.ranges.some(({head:_})=>_>=p&&_<=O);T&&!w?e.push(Ie.replace({widget:new NX(m,p,O)}).range(p,O)):e.push(Ie.mark({class:"cm-md-wiki-link"}).range(p,O))}for(const p of r.filter(O=>O.line===o))t.has(o)||e.push(Ie.replace({widget:new UX(p.source,p.from,p.to)}).range(p.from,p.to));const u=/(^|[\s([{])=([^=\n]+)=(?=$|[\s.,!?;:)\]}])/g;let f;for(;f=u.exec(l.text);){const p=l.from+f.index+f[1].length,O=p+1,g=p+f[0].length-f[1].length-1;g<=O||(e.push(Ie.mark({class:"cm-md-highlight"}).range(O,g)),t.has(o)||(e.push(Ie.replace({}).range(p,p+1)),e.push(Ie.replace({}).range(g,g+1))))}}l.text.trim()==="---"&&!c&&(e.push(Ie.line({class:"cm-md-horizontal-rule-line"}).range(l.from)),e.push(Ie.replace({widget:new LX}).range(l.from,l.to)))}return Ie.set(e,!0)}function GT(n){const e=[],t=[],i=n.state.doc,s=new Set;let r=null;const a=d=>d.replace(/^\s{0,3}(?:>\s?)+/,"");for(let d=1;d<=i.lines;d++){const u=i.line(d),f=a(u.text),p=f.match(/^ {0,3}(`{3,}|~{3,})/);if(r){s.add(d),p&&p[1][0]===r.char&&p[1].length>=r.length&&!f.slice(p[0].length).trim()&&(r=null);continue}if(p){r={char:p[1][0],length:p[1].length},s.add(d);continue}const O=f.match(/^ {0,3}(#{1,2})(?:[ \t]+|$)(.*?)\s*#*\s*$/);if(O){e.push({from:u.from,label:O[2].trim()||"Heading"});continue}d<i.lines&&f.trim()&&a(i.line(d+1).text).match(/^ {0,3}(=+|-+)\s*$/)&&!s.has(d+1)&&e.push({from:u.from,label:f.trim()||"Heading"})}const o=n.state.doc.toString(),l=[];Tt(n.state).iterate({enter(d){d.type.name==="FencedCode"&&l.push([d.from,d.to])}});const c=/(^|[\s([{])=([^=\n]+)=(?=$|[\s.,!?;:)\]}])/g;let h;for(;h=c.exec(o);){const d=h.index+h[1].length;l.some(([u,f])=>d>=u&&d<f)||t.push({from:d,label:h[2].trim()||"Highlight"})}return{headings:e,highlights:t}}function ly(n){const e=L("#note-indexes");if(!e||n!==S.view)return;const t=GT(n),i=[...t.headings.map(s=>({...s,kind:"heading"})),...t.highlights.map(s=>({...s,kind:"highlight"}))].sort((s,r)=>s.from-r.from);e.replaceChildren(),i.forEach(s=>{const r=document.createElement("button");r.type="button",r.className=`note-index-entry note-index-${s.kind}`;const a=Array.from(s.label);r.textContent=a.length>10?`${a.slice(0,10).join("")}...`:s.label,r.title=s.label,r.setAttribute("aria-label",`${s.kind==="heading"?"Heading":"Highlight"}: ${s.label}`),r.addEventListener("click",()=>qT(n,s.from)),e.append(r)}),e.hidden=!e.childElementCount,EO(),ZT(n)}function EO(){const n=L("#note-indexes"),e=L("#note-editor");if(!n||!e||n.hidden)return;const t=e.getBoundingClientRect();n.style.setProperty("--note-index-top",`${t.top+t.height/2}px`),n.style.setProperty("--note-index-left",`${t.left+(L("#note-editor").dataset.toolbarPosition==="left"?58:12)}px`)}window.addEventListener("resize",EO);new ResizeObserver(EO).observe(L("#note-editor"));window.addEventListener("mousemove",n=>{const e=L("#note-indexes"),t=L("#note-editor");if(!e||e.hidden||t.hidden)return;const i=Number.parseFloat(e.style.getPropertyValue("--note-index-left"))||0,s=Number.parseFloat(e.style.getPropertyValue("--note-index-top"))||window.innerHeight/2,r=e.offsetHeight/2,a=e.classList.contains("is-visible"),o=n.clientX>=i-(a?96:80)&&n.clientX<=i+(a?Math.max(e.offsetWidth+36,170):145)&&n.clientY>=s-r-36&&n.clientY<=s+r+36;e.classList.toggle("is-visible",o)});window.addEventListener("blur",()=>{var n;return(n=L("#note-indexes"))==null?void 0:n.classList.remove("is-visible")});function ZT(n){const e=L("#note-indexes");if(!e||n!==S.view)return;const t=GT(n),i=n.scrollDOM,s=[...t.headings.map(l=>({...l,kind:"heading"})),...t.highlights.map(l=>({...l,kind:"highlight"}))].sort((l,c)=>l.from-c.from),r=i.getBoundingClientRect().top+64;let a=-1,o=1/0;s.forEach((l,c)=>{const h=n.coordsAtPos(l.from);if(!h)return;const d=Math.abs(h.top-r);d<o&&(a=c,o=d)}),e.querySelectorAll(".note-index-entry").forEach((l,c)=>{const h=c===a;l.classList.toggle("is-current",h),l.setAttribute("aria-current",h?"location":"false")})}function qT(n,e){n.dispatch({selection:{anchor:e}}),n.focus();const t=n.scrollDOM,i=n.lineBlockAt(e),s=n.documentTop+i.top+i.height/2,a=t.getBoundingClientRect().top+t.clientTop+t.clientHeight/2,o=t.style.scrollBehavior;t.style.scrollBehavior="auto",t.scrollTop+=s-a,t.style.scrollBehavior=o}const FX=xn.fromClass(class{constructor(n){this.decorations=oy(n)}update(n){(n.docChanged||n.selectionSet||n.viewportChanged)&&(this.decorations=oy(n.view))}},{decorations:n=>n.decorations});function $s(n,e){const t=n.state.selection.main,i=n.state.sliceDoc(t.from,t.to),s=`${e}${i}${e}`,r=(t.empty,t.from+e.length),a=t.empty?r:r+i.length;return n.dispatch({changes:{from:t.from,to:t.to,insert:s},selection:{anchor:r,head:a},scrollIntoView:!0}),!0}function Yo(n,e,t){const i=n.state.selection.main,s=n.state.doc.lineAt(i.from),r=n.state.doc.lineAt(i.to),a=[];for(let c=s.number;c<=r.number;c++)a.push(n.state.doc.line(c));const l=a.map(c=>c.text).map(c=>t==="heading"?/^#{1,6}\s/.test(c)?c.replace(/^#{1,6}\s+/,e?`${e} `:""):`${e} ${c}`:t==="task"?/^(\s*)[-*+]\s+\[[ xX]\]\s+/.test(c)?c.replace(/^(\s*)[-*+]\s+\[[ xX]\]\s+/,"$1"):/^(\s*)[-*+]\s+/.test(c)?c.replace(/^(\s*)[-*+]\s+/,`$1${e}`):`${e}${c}`:t==="ordered"&&/^\s*\d+\.\s+/.test(c)?c.replace(/^\s*\d+\.\s+/,""):t==="bullet"&&/^\s*[-*+]\s+/.test(c)?c.replace(/^\s*[-*+]\s+/,""):`${e}${c}`);n.dispatch({changes:{from:s.from,to:r.to,insert:l.join(`
|
|
4448
|
-
`)},scrollIntoView:!0}),n.focus()}function HT(n,e){const t=n.posAtCoords({x:e.clientX,y:e.clientY});if(t==null)return!1;const i=n.state.doc.lineAt(t),s=t-i.from,r=/(?:<\[([^\]]+)\]>|\[\[([^\]]+)\]\])/g;let a;for(;a=r.exec(i.text);){if(s<a.index||s>a.index+a[0].length)continue;if(Tt(n.state).resolveInner(i.from+a.index+2).type.is("InlineCode"))return!1;const o=(a[1]||a[2]).split("|")[0].trim();return e.preventDefault(),CO(o),!0}return!1}function
|
|
4447
|
+
</div>`;const S={vault:null,files:[],tree:[],collapsed:new Set,active:null,home:!1,homeChats:RX(),homeSession:null,view:null,structured:null,assetViewer:null,assetPath:null,assetBytes:null,pdfText:null,pdfTextPromise:null,toolbarPositions:CX(),saveTimer:null,savePromise:null,dirty:!1,lastTitleValidationMessage:null,sidebarOpen:!0,sidebarWidth:Number(localStorage.getItem("stillnote-sidebar-width"))||258,assistantWidth:Number(localStorage.getItem("stillnote-assistant-width"))||360,theme:"light",assistantOpen:!1,assistantMode:"ask",chatHistory:[],draggedItem:null};function CX(){const n=localStorage.getItem("stillnote-notes-toolbar-position"),e=localStorage.getItem("stillnote-canvas-toolbar-position");return{notes:["left","right","bottom","hidden"].includes(n)?n:"right",canvas:["left","right","bottom"].includes(e)?e:"right"}}function RX(){try{const n=JSON.parse(localStorage.getItem("stillnote-home-chats")||"[]");return Array.isArray(n)?n.slice(0,3):[]}catch{return[]}}function QX(){S.homeSession&&(S.homeSession.updatedAt=Date.now(),S.homeChats=[S.homeSession,...S.homeChats.filter(n=>n.id!==S.homeSession.id)].slice(0,3),localStorage.setItem("stillnote-home-chats",JSON.stringify(S.homeChats)))}let qh=null,Hh=null;const L=n=>document.querySelector(n),op=L("#note-list");vz();const LX=new Set(["HeaderMark","EmphasisMark","CodeMark","LinkMark","LinkDestination","LinkTitle","StrikethroughMark","ListMark","QuoteMark","TaskMarker"]);class ry extends Ci{constructor(e,t){super(),this.text=e,this.className=t}toDOM(){const e=document.createElement("span");return e.className=this.className,e.textContent=this.text,e}eq(e){return e.text===this.text&&e.className===this.className}}class $X extends Ci{toDOM(){const e=document.createElement("hr");return e.className="cm-md-horizontal-rule-widget",e}}class DX extends Ci{constructor(e,t,i){super(),this.checked=e,this.from=t,this.to=i}toDOM(e){const t=document.createElement("input");return t.type="checkbox",t.className="cm-md-task-checkbox",t.checked=this.checked,t.setAttribute("aria-label",this.checked?"Mark task incomplete":"Mark task complete"),t.addEventListener("mousedown",i=>i.preventDefault()),t.addEventListener("change",()=>e.dispatch({changes:{from:this.from,to:this.to,insert:t.checked?"[x]":"[ ]"}})),t}eq(e){return this.checked===e.checked&&this.from===e.from&&this.to===e.to}}const IX="http://www.w3.org/1998/Math/MathML",mh={alpha:"α",beta:"β",gamma:"γ",delta:"δ",epsilon:"ε",theta:"θ",lambda:"λ",mu:"μ",pi:"π",rho:"ρ",sigma:"σ",tau:"τ",phi:"φ",chi:"χ",psi:"ψ",omega:"ω",Gamma:"Γ",Delta:"Δ",Theta:"Θ",Lambda:"Λ",Pi:"Π",Sigma:"Σ",Phi:"Φ",Psi:"Ψ",Omega:"Ω"};function vn(n,e){const t=document.createElementNS(IX,n);return e!=null&&(t.textContent=e),t}function UX(n){let e=0;function t(r=""){const a=vn("mrow");for(;e<n.length&&n[e]!==r;){let o;const l=n[e++];if(!/\s/.test(l)){if(l==="{")o=t("}"),e++;else if(l==="\\"||l==="/"){const c=(n.slice(e).match(/^[A-Za-z]+/)||[""])[0];if(e+=c.length,l==="/"&&!mh[c]&&!["int","infty","sum","prod","frac","sqrt","cdot","times","le","ge","neq","pm"].includes(c)){e-=c.length,o=vn("mo","/"),a.append(o);continue}if(c==="frac"||c==="dfrac"||c==="tfrac"){const h=i(),d=i();o=vn("mfrac"),o.append(h,d)}else if(c==="sqrt")o=vn("msqrt"),o.append(i());else if(c==="int"||c==="infty"||c==="sum"||c==="prod")o=vn("mo",{int:"∫",infty:"∞",sum:"∑",prod:"∏"}[c]);else if(mh[c])o=vn("mi",mh[c]);else if(c==="cdot"||c==="times"||c==="le"||c==="ge"||c==="neq"||c==="pm")o=vn("mo",{cdot:"·",times:"×",le:"≤",ge:"≥",neq:"≠",pm:"±"}[c]);else if(c==="left"||c==="right"){const h=n[e++];o=vn("mo",h||"")}else o=vn("mi",c||n[e-1])}else if(l==="^"||l==="_"){const c=i();a.lastChild||a.append(vn("mi"," "));const h=a.lastChild;a.removeChild(h);const d=vn(l==="^"?"msup":"msub");d.append(h,c),a.append(d);continue}else"+-=<>(),[]|".includes(l)?o=vn("mo",l):/\d/.test(l)?o=vn("mn",l):o=vn("mi",l);o&&a.append(o)}}return a}function i(){for(;n[e]===" ";)e++;if(n[e]==="{"){e++;const r=t("}");return e++,r}return s()}function s(){for(;n[e]===" ";)e++;if(e>=n.length)return vn("mrow");let r=n[e++];if(r==="\\"||r==="/"){const o=(n.slice(e).match(/^[A-Za-z]+/)||[""])[0];e+=o.length,r=mh[o]||{int:"∫",infty:"∞",sum:"∑",prod:"∏",cdot:"·",times:"×",le:"≤",ge:"≥",neq:"≠",pm:"±"}[o]||o||r}return vn(/^\d/.test(r)?"mn":"mi",r)}return t()}class NX extends Ci{constructor(e,t,i){super(),this.source=e,this.from=t,this.to=i}toDOM(e){const t=vn("math");return t.setAttribute("display","inline"),t.classList.add("cm-md-equation"),t.append(UX(this.source)),t.dataset.equation=this.source,t.title="Click to edit · right-click for Desmos preview",t.addEventListener("mousedown",i=>{if(i.button!==0)return;i.preventDefault();const s=t.getBoundingClientRect(),r=s.width?Math.max(0,Math.min(1,(i.clientX-s.left)/s.width)):0,a=Math.round(r*this.source.length);e.dispatch({selection:{anchor:this.from+1+a},scrollIntoView:!0}),e.focus()}),t}eq(e){return e.source===this.source&&e.from===this.from&&e.to===this.to}}class FX extends Ci{constructor(e,t,i){super(),this.file=e,this.from=t,this.to=i}toDOM(e){const t=`.${oa(this.file)}`,i=[".obj",".stl",".step",".stp"].includes(t),s=document.createElement("span");s.className=`cm-wiki-media-preview${i?" is-3d":" is-image"}`,s.title=`${this.file} · place the caret in the link to edit it`;const r=document.createElement("button");r.type="button",r.className="cm-wiki-media-edit",r.textContent="Edit link",r.title="Show and edit the link",r.addEventListener("mousedown",o=>{o.preventDefault(),o.stopPropagation()}),r.addEventListener("click",o=>{o.preventDefault(),o.stopPropagation(),e.dispatch({selection:{anchor:this.from+2},scrollIntoView:!0}),e.focus()}),s.append(r);const a=document.createElement("span");return a.className="cm-wiki-media-loading",a.textContent="Loading preview…",s.append(a),window.stillnote.readAsset(this.file).then(o=>{if(s.isConnected){if(s.replaceChildren(r),o.mime.startsWith("image/")){const l=document.createElement("img");l.className="cm-wiki-image-preview",l.src=o.data,l.alt=this.file,l.loading="lazy",s.append(l)}else if([".obj",".stl",".step",".stp"].includes(t)){const l=document.createElement("span");l.className="cm-wiki-3d-preview",s.append(l),tz(l,this.file,o,s)}}}).catch(()=>{if(!s.isConnected)return;s.classList.add("is-error");const o=document.createElement("span");o.textContent=`Preview unavailable · ${this.file}`,s.replaceChildren(r,o)}),s.addEventListener("pointerdown",o=>o.stopPropagation()),s.addEventListener("mousedown",o=>o.stopPropagation()),s}destroy(e){var t;(t=e.__disposePreview)==null||t.call(e)}eq(e){return e.file===this.file&&e.from===this.from&&e.to===this.to}}function ay(n,e,t){var a,o;(o=(a=document.querySelector(".equation-preview"))==null?void 0:a._dismiss)==null||o.call(a);const i=document.createElement("section");i.className="equation-preview",i.setAttribute("role","dialog"),i.setAttribute("aria-label","Desmos equation preview"),i.style.left=`${Math.min(e,innerWidth-440)}px`,i.style.top=`${Math.min(t,innerHeight-330)}px`,i.innerHTML='<div class="equation-preview-graph"></div>';const s=l=>{var c,h;l&&i.contains(l.target)||(document.removeEventListener("pointerdown",s),(h=(c=i._calculator)==null?void 0:c.destroy)==null||h.call(c),i.remove())};i._dismiss=()=>s(),document.body.append(i),document.addEventListener("pointerdown",s);const r=()=>{if(!i.isConnected)return;if(!window.Desmos){i.querySelector(".equation-preview-graph").textContent="Desmos could not be loaded. Check your internet connection.";return}const l=window.Desmos.GraphingCalculator(i.querySelector(".equation-preview-graph"),{expressions:!1,settingsMenu:!1,zoomButtons:!0}),c=n.replace(/\/(alpha|beta|gamma|delta|epsilon|theta|lambda|mu|pi|rho|sigma|tau|phi|chi|psi|omega|Gamma|Delta|Theta|Lambda|Pi|Sigma|Phi|Psi|Omega|int|infty|sum|prod|frac|sqrt|cdot|times|le|ge|neq|pm)\b/g,(h,d)=>`\\${d}`);l.setExpression({id:"equation",latex:c}),i._calculator=l};if(window.Desmos)r();else{let l=document.querySelector("#desmos-api");l?l.addEventListener("load",r,{once:!0}):(l=document.createElement("script"),l.id="desmos-api",l.src="https://www.desmos.com/api/v1.11/calculator.js?apiKey=dcb31709b452b1cf9dc26972add0fda6",l.onload=r,l.onerror=()=>{i.isConnected&&(i.querySelector(".equation-preview-graph").textContent="Desmos could not be loaded. Check your internet connection.")},document.head.append(l))}}function oy(n){const e=[],t=new Set(n.state.selection.ranges.map(o=>n.state.doc.lineAt(o.head).number)),i=new Set,s=[];Tt(n.state).iterate({enter(o){o.type.name==="FencedCode"&&s.push([o.from,o.to])}});const r=[];for(let o=1;o<=n.state.doc.lines;o++){const l=n.state.doc.line(o);if(s.some(([d,u])=>l.from>=d&&l.to<=u))continue;const c=new RegExp("(?<!\\$)\\$([^\\s$](?:[^$\\n]*?[^\\s$])?)\\$(?!\\$)","g");let h;for(;h=c.exec(l.text);){const d=l.from+h.index,u=d+h[0].length;Tt(n.state).resolveInner(d+1).type.is("InlineCode")||r.push({from:d,to:u,source:h[1],line:o})}}const a=[];Tt(n.state).iterate({enter(o){const l=o.type.name,c=n.state.doc.lineAt(o.from);if(l!=="FencedCode"&&r.some(({from:u,to:f})=>o.from<f&&o.to>u))return;if((l==="Emphasis"||l==="StrongEmphasis")&&o.to>o.from&&a.push([o.from,o.to]),l==="TaskMarker"&&o.to>o.from){const u=n.state.doc.sliceString(o.from,o.to);e.push(Ie.replace({widget:new DX(/\[[xX]\]/.test(u),o.from,o.to)}).range(o.from,o.to));return}if(l==="ListMark"&&o.to>o.from){const u=n.state.doc.sliceString(o.from,o.to);if(/^[*+-]$/.test(u.trim())){const f=/^\s*[-*+]\s+\[[ xX]\](?:\s|$)/.test(c.text);e.push(f?Ie.replace({}).range(o.from,o.to):Ie.replace({widget:new ry("•","cm-md-bullet")}).range(o.from,o.to)),i.has(c.from)||(e.push(Ie.line({class:"cm-md-list-line"}).range(c.from)),i.add(c.from))}else e.push(Ie.replace({widget:new ry(u.trim(),"cm-md-ordered-marker")}).range(o.from,o.to));return}const h=l.match(/^(?:ATX|Setext)Heading([1-6])$/);h&&o.to>o.from&&e.push(Ie.mark({class:`cm-md-heading cm-md-h${h[1]}`}).range(o.from,o.to));const d={Emphasis:"cm-md-emphasis",StrongEmphasis:"cm-md-strong",Strikethrough:"cm-md-strikethrough",InlineCode:"cm-md-inline-code",Link:"cm-md-link",Image:"cm-md-image",FencedCode:"cm-md-code-block"};if(d[l]&&o.to>o.from&&e.push(Ie.mark({class:d[l]}).range(o.from,o.to)),LX.has(l)&&o.to>o.from){const u=l==="EmphasisMark"&&a.some(([f,p])=>o.from>=f&&o.to<=p&&n.state.selection.ranges.some(O=>O.head>=f&&O.head<=p));(l==="EmphasisMark"?!u:!t.has(c.number))&&e.push(Ie.replace({}).range(o.from,o.to))}}});for(let o=1;o<=n.state.doc.lines;o++){const l=n.state.doc.line(o),c=s.some(([h,d])=>l.from>=h&&l.to<=d);if(!c){const h=/(?:<\[([^\]]+)\]>|\[\[([^\]]+)\]\])/g;let d;for(;d=h.exec(l.text);){const p=l.from+d.index,O=p+d[0].length;if(Tt(n.state).resolveInner(p+2).type.is("InlineCode"))continue;const g=(d[1]||d[2]).split("|")[0].split("#")[0].trim(),m=RO(g),y=m?`.${oa(m)}`:"",T=[".png",".jpg",".jpeg",".webp",".heic",".icns",".svg",".obj",".stl",".step",".stp"].includes(y),w=n.state.selection.ranges.some(({head:_})=>_>=p&&_<=O);T&&!w?e.push(Ie.replace({widget:new FX(m,p,O)}).range(p,O)):e.push(Ie.mark({class:"cm-md-wiki-link"}).range(p,O))}for(const p of r.filter(O=>O.line===o))t.has(o)||e.push(Ie.replace({widget:new NX(p.source,p.from,p.to)}).range(p.from,p.to));const u=/(^|[\s([{])=([^=\n]+)=(?=$|[\s.,!?;:)\]}])/g;let f;for(;f=u.exec(l.text);){const p=l.from+f.index+f[1].length,O=p+1,g=p+f[0].length-f[1].length-1;g<=O||(e.push(Ie.mark({class:"cm-md-highlight"}).range(O,g)),t.has(o)||(e.push(Ie.replace({}).range(p,p+1)),e.push(Ie.replace({}).range(g,g+1))))}}l.text.trim()==="---"&&!c&&(e.push(Ie.line({class:"cm-md-horizontal-rule-line"}).range(l.from)),e.push(Ie.replace({widget:new $X}).range(l.from,l.to)))}return Ie.set(e,!0)}function GT(n){const e=[],t=[],i=n.state.doc,s=new Set;let r=null;const a=d=>d.replace(/^\s{0,3}(?:>\s?)+/,"");for(let d=1;d<=i.lines;d++){const u=i.line(d),f=a(u.text),p=f.match(/^ {0,3}(`{3,}|~{3,})/);if(r){s.add(d),p&&p[1][0]===r.char&&p[1].length>=r.length&&!f.slice(p[0].length).trim()&&(r=null);continue}if(p){r={char:p[1][0],length:p[1].length},s.add(d);continue}const O=f.match(/^ {0,3}(#{1,2})(?:[ \t]+|$)(.*?)\s*#*\s*$/);if(O){e.push({from:u.from,label:O[2].trim()||"Heading"});continue}d<i.lines&&f.trim()&&a(i.line(d+1).text).match(/^ {0,3}(=+|-+)\s*$/)&&!s.has(d+1)&&e.push({from:u.from,label:f.trim()||"Heading"})}const o=n.state.doc.toString(),l=[];Tt(n.state).iterate({enter(d){d.type.name==="FencedCode"&&l.push([d.from,d.to])}});const c=/(^|[\s([{])=([^=\n]+)=(?=$|[\s.,!?;:)\]}])/g;let h;for(;h=c.exec(o);){const d=h.index+h[1].length;l.some(([u,f])=>d>=u&&d<f)||t.push({from:d,label:h[2].trim()||"Highlight"})}return{headings:e,highlights:t}}function ly(n){const e=L("#note-indexes");if(!e||n!==S.view)return;const t=GT(n),i=[...t.headings.map(s=>({...s,kind:"heading"})),...t.highlights.map(s=>({...s,kind:"highlight"}))].sort((s,r)=>s.from-r.from);e.replaceChildren(),i.forEach(s=>{const r=document.createElement("button");r.type="button",r.className=`note-index-entry note-index-${s.kind}`;const a=Array.from(s.label);r.textContent=a.length>10?`${a.slice(0,10).join("")}...`:s.label,r.title=s.label,r.setAttribute("aria-label",`${s.kind==="heading"?"Heading":"Highlight"}: ${s.label}`),r.addEventListener("click",()=>qT(n,s.from)),e.append(r)}),e.hidden=!e.childElementCount,EO(),ZT(n)}function EO(){const n=L("#note-indexes"),e=L("#note-editor");if(!n||!e||n.hidden)return;const t=e.getBoundingClientRect();n.style.setProperty("--note-index-top",`${t.top+t.height/2}px`),n.style.setProperty("--note-index-left",`${t.left+(L("#note-editor").dataset.toolbarPosition==="left"?58:12)}px`)}window.addEventListener("resize",EO);new ResizeObserver(EO).observe(L("#note-editor"));window.addEventListener("mousemove",n=>{const e=L("#note-indexes"),t=L("#note-editor");if(!e||e.hidden||t.hidden)return;const i=Number.parseFloat(e.style.getPropertyValue("--note-index-left"))||0,s=Number.parseFloat(e.style.getPropertyValue("--note-index-top"))||window.innerHeight/2,r=e.offsetHeight/2,a=e.classList.contains("is-visible"),o=n.clientX>=i-(a?96:80)&&n.clientX<=i+(a?Math.max(e.offsetWidth+36,170):145)&&n.clientY>=s-r-36&&n.clientY<=s+r+36;e.classList.toggle("is-visible",o)});window.addEventListener("blur",()=>{var n;return(n=L("#note-indexes"))==null?void 0:n.classList.remove("is-visible")});function ZT(n){const e=L("#note-indexes");if(!e||n!==S.view)return;const t=GT(n),i=n.scrollDOM,s=[...t.headings.map(l=>({...l,kind:"heading"})),...t.highlights.map(l=>({...l,kind:"highlight"}))].sort((l,c)=>l.from-c.from),r=i.getBoundingClientRect().top+64;let a=-1,o=1/0;s.forEach((l,c)=>{const h=n.coordsAtPos(l.from);if(!h)return;const d=Math.abs(h.top-r);d<o&&(a=c,o=d)}),e.querySelectorAll(".note-index-entry").forEach((l,c)=>{const h=c===a;l.classList.toggle("is-current",h),l.setAttribute("aria-current",h?"location":"false")})}function qT(n,e){n.dispatch({selection:{anchor:e}}),n.focus();const t=n.scrollDOM,i=n.lineBlockAt(e),s=n.documentTop+i.top+i.height/2,a=t.getBoundingClientRect().top+t.clientTop+t.clientHeight/2,o=t.style.scrollBehavior;t.style.scrollBehavior="auto",t.scrollTop+=s-a,t.style.scrollBehavior=o}const XX=xn.fromClass(class{constructor(n){this.decorations=oy(n)}update(n){(n.docChanged||n.selectionSet||n.viewportChanged)&&(this.decorations=oy(n.view))}},{decorations:n=>n.decorations});function $s(n,e){const t=n.state.selection.main,i=n.state.sliceDoc(t.from,t.to),s=`${e}${i}${e}`,r=(t.empty,t.from+e.length),a=t.empty?r:r+i.length;return n.dispatch({changes:{from:t.from,to:t.to,insert:s},selection:{anchor:r,head:a},scrollIntoView:!0}),!0}function Yo(n,e,t){const i=n.state.selection.main,s=n.state.doc.lineAt(i.from),r=n.state.doc.lineAt(i.to),a=[];for(let c=s.number;c<=r.number;c++)a.push(n.state.doc.line(c));const l=a.map(c=>c.text).map(c=>t==="heading"?/^#{1,6}\s/.test(c)?c.replace(/^#{1,6}\s+/,e?`${e} `:""):`${e} ${c}`:t==="task"?/^(\s*)[-*+]\s+\[[ xX]\]\s+/.test(c)?c.replace(/^(\s*)[-*+]\s+\[[ xX]\]\s+/,"$1"):/^(\s*)[-*+]\s+/.test(c)?c.replace(/^(\s*)[-*+]\s+/,`$1${e}`):`${e}${c}`:t==="ordered"&&/^\s*\d+\.\s+/.test(c)?c.replace(/^\s*\d+\.\s+/,""):t==="bullet"&&/^\s*[-*+]\s+/.test(c)?c.replace(/^\s*[-*+]\s+/,""):`${e}${c}`);n.dispatch({changes:{from:s.from,to:r.to,insert:l.join(`
|
|
4448
|
+
`)},scrollIntoView:!0}),n.focus()}function HT(n,e){const t=n.posAtCoords({x:e.clientX,y:e.clientY});if(t==null)return!1;const i=n.state.doc.lineAt(t),s=t-i.from,r=/(?:<\[([^\]]+)\]>|\[\[([^\]]+)\]\])/g;let a;for(;a=r.exec(i.text);){if(s<a.index||s>a.index+a[0].length)continue;if(Tt(n.state).resolveInner(i.from+a.index+2).type.is("InlineCode"))return!1;const o=(a[1]||a[2]).split("|")[0].trim();return e.preventDefault(),CO(o),!0}return!1}function zX(n,e){const t=n.state.doc.lineAt(e),i=/[\p{L}]+(?:['’][\p{L}]+)?/gu;let s;for(;s=i.exec(t.text);){const r=t.from+s.index,a=r+s[0].length;if(e>=r&&e<=a)return{from:r,to:a,word:s[0]}}return null}function pu(){L("#editor-context-menu").hidden=!0}function BX(n,e,t,i){const s=L("#editor-context-menu");s.replaceChildren();const r=(a,o,l=!1)=>{const c=document.createElement("button");c.type="button",c.className="context-action",c.textContent=a,c.disabled=l,c.addEventListener("click",()=>{pu(),o(),n.focus()}),s.append(c)};if(i&&gr&&!mu(i.word)){const a=MX(i.word);if(a.length)for(const l of a){const c=i.word===i.word.toLocaleUpperCase()?l.toLocaleUpperCase():/^[A-Z]/.test(i.word)?l[0].toLocaleUpperCase()+l.slice(1):l;r(`Correct to “${c}”`,()=>n.dispatch({changes:{from:i.from,to:i.to,insert:c},selection:{anchor:i.from+c.length},scrollIntoView:!0}))}else r(`No suggestions for “${i.word}”`,()=>{},!0);const o=i.word.toLocaleLowerCase();r(`Add “${i.word}” to dictionary`,()=>{WT(o)})}s.hidden=!1,s.style.left=`${Math.max(8,Math.min(e.clientX,window.innerWidth-230))}px`,s.style.top=`${Math.max(8,Math.min(e.clientY,window.innerHeight-s.offsetHeight-8))}px`}async function VX(n,e){var s;if((s=S.active)!=null&&s.toLocaleLowerCase().endsWith(".md")&&HT(n,e))return;const t=n.posAtCoords({x:e.clientX,y:e.clientY});if(t==null)return;const i=zX(n,t);if(i){e.preventDefault();try{await BT()}catch{}n===S.view&&(mu(i.word)||(n.dispatch({selection:{anchor:i.from,head:i.to}}),pu(),BX(n,e,t,i)))}}function mu(n){const e=n.toLocaleLowerCase().replace(/’/g,"'");return na.has(e)||!!(gr!=null&&gr.has(e))}function Re(n){const e=L("#toast");e.textContent=n,e.hidden=!1,clearTimeout(Re.timer),Re.timer=setTimeout(()=>{e.hidden=!0},2400)}function at(n){return n.split("/").at(-1).replace(/\.md$/i,"")}const rg=[["JavaScript",".js"],["CommonJS JavaScript",".cjs"],["ES module JavaScript",".mjs"],["TypeScript",".ts"],["React JSX",".jsx"],["React TypeScript",".tsx"],["Python",".py"],["HTML",".html"],["CSS",".css"],["JSON",".json"],["Java",".java"],["C",".c"],["C header",".h"],["C++",".cpp"],["C++ header",".hpp"],["Rust",".rs"],["Go",".go"],["SQL",".sql"],["Shell script",".sh"],["XML",".xml"],["YAML",".yaml"],["YAML",".yml"],["TOML",".toml"],["Swift",".swift"],["Kotlin",".kt"],["Ruby",".rb"],["PHP",".php"]],WX=new Set(rg.map(([,n])=>n).concat(".jar"));function oa(n){return n.split("/").at(-1).split(".").at(-1).toLowerCase()}function Fd(n){return WX.has(`.${oa(n)}`)}function GX(n){const e=`.${oa(n)}`;return[".js",".cjs",".mjs",".jsx",".ts",".tsx"].includes(e)?J1({typescript:[".ts",".tsx"].includes(e),jsx:[".jsx",".tsx"].includes(e)}):e===".py"?u$():[".html",".xml"].includes(e)?lw():e===".css"?X1():e===".json"?g$():[]}function Ut(n){return String(n).replace(/[&<>"']/g,e=>({"&":"&","<":"<",">":">",'"':""","'":"'"})[e])}function jo(n){let e=Ut(n);const t=[];return e=e.replace(/`([^`]+)`/g,(i,s)=>{const r=`@@CODE${t.length}@@`;return t.push(`<code>${s}</code>`),r}),e=e.replace(/\[([^\]]+)\]\((https?:[^\s)]+)\)/g,'<a href="$2">$1</a>').replace(/(?:<\[([^\]|]+)(?:\|([^\]]+))?\]>|\[\[([^\]|]+)(?:\|([^\]]+))?\]\])/g,(i,s,r,a,o)=>`<span class="wiki-link">${r||s||o||a}</span>`).replace(/\*\*(.+?)\*\*/g,"<strong>$1</strong>").replace(/__(.+?)__/g,"<strong>$1</strong>").replace(/\*(.+?)\*/g,"<em>$1</em>").replace(/_(.+?)_/g,"<em>$1</em>").replace(/~~(.+?)~~/g,"<del>$1</del>"),e.replace(/@@CODE(\d+)@@/g,(i,s)=>t[Number(s)])}function ZX(n,e){const t=String(n).split(/\r?\n/);t.length&&t[0].trim().replace(/^#{1,6}\s+/,"").toLocaleLowerCase()===e.toLocaleLowerCase()&&t.shift();const i=[];let s=null,r=!1,a=[];const o=()=>{s&&(i.push(`</${s}>`),s=null)},l=c=>/^\s*(```|#{1,6}\s|>|-{3,}\s*$|(?:[-*+]\s+|\d+\.\s+))/.test(c);for(let c=0;c<t.length;c++){const h=t[c];if(/^\s*```/.test(h)){o(),r?(i.push(`<pre><code>${Ut(a.join(`
|
|
4449
4449
|
`))}</code></pre>`),a=[],r=!1):r=!0;continue}if(r){a.push(h);continue}if(!h.trim()){o();continue}const d=h.match(/^\s*(#{1,6})\s+(.*)$/);if(d){o();const O=d[1].length;i.push(`<h${O}>${jo(d[2])}</h${O}>`);continue}if(/^\s*(?:-{3,}|\*{3,}|_{3,})\s*$/.test(h)){o(),i.push("<hr>");continue}const u=h.match(/^\s*>\s?(.*)$/);if(u){o(),i.push(`<blockquote>${jo(u[1])}</blockquote>`);continue}const f=h.match(/^\s*(?:([-*+])|(\d+)\.)\s+(.*)$/);if(f){const O=f[1]&&f[3].match(/^\[([ xX])\]\s+(.*)$/),g=f[2]?"ol":"ul";s!==g&&(o(),i.push(`<${g}>`),s=g),O?i.push(`<li class="task ${O[1].trim()?"checked":""}">${O[1].trim()?"☑":"☐"} ${jo(O[2])}</li>`):i.push(`<li>${jo(f[3])}</li>`);continue}o();const p=[h];for(;c+1<t.length&&t[c+1].trim()&&!l(t[c+1]);)p.push(t[++c]);i.push(`<p>${p.map(jo).join("<br>")}</p>`)}return r&&i.push(`<pre><code>${Ut(a.join(`
|
|
4450
4450
|
`))}</code></pre>`),o(),`<!doctype html><html lang="en"><head><meta charset="utf-8"><title>${Ut(e)}</title><style>
|
|
4451
4451
|
*{box-sizing:border-box}body{margin:0;color:#292a27;font:12pt/1.65 Georgia,'Times New Roman',serif}h1{margin:0 0 28pt;font:26pt/1.15 Georgia,'Times New Roman',serif;letter-spacing:-.03em}h2{margin:24pt 0 9pt;font-size:18pt}h3{margin:20pt 0 8pt;font-size:14pt}h4,h5,h6{margin:16pt 0 6pt}p{margin:0 0 12pt}ul,ol{margin:0 0 14pt;padding-left:24pt}li{padding-left:3pt;margin:3pt 0}li.task{list-style:none;margin-left:-17pt}blockquote{margin:12pt 0;padding:2pt 0 2pt 12pt;border-left:2px solid #b8a18b;color:#5d5b54}hr{margin:20pt 0;border:0;border-top:1px solid #c9c5bb}pre{margin:12pt 0;padding:10pt;background:#f2f1ed;border-radius:4pt;white-space:pre-wrap;overflow-wrap:anywhere;font:9pt/1.5 Menlo,monospace}code{padding:1pt 3pt;background:#f0eee9;border-radius:2pt;font:9pt Menlo,monospace}a,.wiki-link{color:#725b49;text-decoration:underline}strong{font-weight:bold}em{font-style:italic}
|
|
4452
4452
|
</style></head><body><main><h1>${Ut(e)}</h1>${i.join(`
|
|
4453
|
-
`)}</main></body></html>`}async function
|
|
4453
|
+
`)}</main></body></html>`}async function qX(n=S.active){if(!S.vault||!n){Re("Open a note before exporting a PDF.");return}try{let e;n===S.active&&S.view?(await qn(),e=S.view.state.doc.toString()):e=await window.stillnote.readNote(n);const t=at(n);await window.stillnote.exportPdf(n,ZX(e,t))&&Re("PDF exported")}catch(e){Re(e.message||"Could not export PDF.")}}function Ht(){op.innerHTML="",S.files.length||S.tree.length||(op.innerHTML=`<div class="empty-files"><span class="empty-file-icon">${fe.folder}</span><span>Folder is empty</span></div>`);const n=(e,t,i=0)=>{for(const s of e)if(s.type==="folder"){const r=S.collapsed.has(s.path),a=document.createElement("button");a.className="folder-row",a.style.setProperty("--depth",i),a.setAttribute("aria-expanded",String(!r)),a.innerHTML=`<span class="folder-chevron${r?" is-collapsed":""}">${fe.down}</span>${r?fe.folder:fe.folderOpen}<span>${Ut(s.name)}</span>`,a.title=s.path,a.addEventListener("click",()=>{r?S.collapsed.delete(s.path):S.collapsed.add(s.path),Ht()}),a.addEventListener("contextmenu",o=>uy(o,s)),dy(a,s),t.append(a),r||n(s.children,t,i+1)}else{const r=document.createElement("button");r.className=`note-row${s.path===S.active?" selected":""}`,r.style.setProperty("--depth",i),r.innerHTML=`${fe[s.format]||fe.file}<span>${Ut(at(s.name))}</span>`,r.title=s.path,r.addEventListener("click",()=>mi(s.path)),r.addEventListener("contextmenu",a=>uy(a,s)),dy(r,s),t.append(r)}};n(S.tree,op)}function zs(n=S.tree,e=[]){for(const t of n)t.type==="folder"?zs(t.children||[],e):e.push(t.path);return e}function YT(n){const e=t=>{for(const i of t)i.type==="folder"&&(n?S.collapsed.delete(i.path):S.collapsed.add(i.path),e(i.children||[]))};e(S.tree),Ht()}async function jT(n){var t,i;(t=S.vault)!=null&&t.path&&S.vault.path!==n.path&&((i=S.view)==null||i.destroy(),S.view=null,S.active=null,L("#editor-content").replaceChildren()),S.vault=n,S.files=n.files,S.tree=n.tree,S.collapsed.clear(),L(".vault-name").textContent=n.name,L(".vault-mark").textContent=n.name.charAt(0).toUpperCase(),L(".location-vault").textContent=n.name,L("#status-vault").textContent=n.name,In("directory",!0,"Folder open"),Ht(),await PX().catch(s=>{na=new Set,cc(),console.warn("Could not load the personal dictionary for this vault:",s.message)});const e=localStorage.getItem("stillnote-desmos-api-key");if(e)try{(await window.stillnote.desmosKeyStatus()).configured||await window.stillnote.saveDesmosKey(e),localStorage.removeItem("stillnote-desmos-api-key")}catch(s){console.warn("Could not migrate the saved Desmos key into the vault:",s.message)}await mM()}function AO(){L("#welcome").hidden=!1,L("#welcome .eyebrow").textContent="VAULT READY",L("#welcome h1").innerHTML="A fresh page<br><em>is waiting.</em>",L("#welcome p").innerHTML="Create a note and start collecting your thoughts.",L("#open-vault").innerHTML=`Create your first note ${fe.external}`,L("#note-editor").hidden=!0}async function qs(){try{await qn();const n=await window.stillnote.chooseVault();if(!n)return;await jT(n),zs().length?await mi(zs()[0]):AO()}catch(n){Re(n.message||"Could not open that folder.")}}function ag(){const n=L("#home-transcript");if(!(!n||!S.homeSession)){if(n.replaceChildren(),!S.homeSession.messages.length){const e=document.createElement("section");e.className="home-empty-state",e.innerHTML=`<div class="home-empty-mark">${fe.assistant}</div><div class="eyebrow">A THOUGHTFUL START</div><h2>What can I help you untangle?</h2><p>Ask a question, explore an idea, or find something across your notes.</p><div class="home-prompt-suggestions"><button type="button" data-home-prompt="Summarize the ideas I’ve been collecting lately">Summarize my recent ideas</button><button type="button" data-home-prompt="Help me find a note about ">Find a note about…</button><button type="button" data-home-prompt="Explain this concept in a simple way: ">Explain a concept</button></div>`,n.append(e)}for(const e of S.homeSession.messages){const t=document.createElement("div");t.className=`home-bubble ${e.role}`;const s=String(e.content||"").split(/((?:<\[[^\]]+\]>|\[\[[^\]]+\]\]))/g);for(const r of s){const a=r.match(/^(?:<\[([^\]]+)\]>|\[\[([^\]]+)\]\])$/);if(!a){t.append(document.createTextNode(r));continue}const o=(a[1]||a[2]).trim(),l=RO(o.split("#")[0]);if(!l){t.append(document.createTextNode(o));continue}const c=document.createElement("button");c.type="button",c.className="home-file-link",c.textContent=at(l),c.title=`Open ${l}`,c.addEventListener("click",async()=>{const h=S.homeSession.messages.slice(-8).map(({role:d,content:u})=>({role:d,content:u}));await CO(o),Bd(!0),L("#assistant-messages").replaceChildren(),S.chatHistory=h,h.forEach(({role:d,content:u})=>Ds(d,u))}),t.append(c)}n.append(t)}n.scrollTop=n.scrollHeight}}function og(n=null){S.homeSession=n?JSON.parse(JSON.stringify(n)):{id:crypto.randomUUID(),title:"New conversation",updatedAt:Date.now(),messages:[]},ag(),KT()}function KT(){var e,t,i,s;const n=L("#home-history");if(n){if(n.replaceChildren(),!S.homeChats.length){const r=document.createElement("p");r.className="home-history-empty",r.textContent="Your conversations will appear here.",n.append(r);return}for(const r of S.homeChats){const a=document.createElement("button");a.type="button",a.className=`home-history-item${((e=S.homeSession)==null?void 0:e.id)===r.id?" active":""}`,a.textContent=r.title||((s=(i=(t=r.messages)==null?void 0:t.find(o=>o.role==="user"))==null?void 0:i.content)==null?void 0:s.slice(0,48))||"Conversation",a.addEventListener("click",()=>og(r)),n.append(a)}}}async function HX(){var n,e,t,i;FO(),L("#meeting-notes-trigger").hidden=!0,L("#note-format-toolbar").hidden=!0,L("#note-editor").classList.remove("has-markdown-editor");try{await qn()}catch(s){Re(s.message||"Could not save the open file.");return}S.view&&(S.view.destroy(),S.view=null),(t=(e=(n=S.structured)==null?void 0:n.desmos)==null?void 0:e.destroy)==null||t.call(e),S.structured=null,hr(),S.active=null,S.home=!0,S.dirty=!1,S.assistantOpen=!1,L(".workspace").classList.remove("assistant-open"),L("#editor-content").innerHTML=`<section class="home-view"><div class="home-topline"><button type="button" class="home-history-toggle" id="home-history-toggle" aria-label="Show recent chats" aria-expanded="false" title="Recent chats">${fe.menu}</button></div><div class="home-chat-layout"><aside class="home-history"><div class="home-history-top"><div class="home-history-label">RECENT CHATS</div><button type="button" id="home-new-chat" aria-label="New conversation" title="New conversation">${fe.filePlus}</button></div><div id="home-history"></div></aside><div class="home-chat-main"><div class="home-transcript" id="home-transcript"></div><form class="home-composer" id="home-form"><textarea id="home-input" rows="3" placeholder="Ask anything about your notes…"></textarea><button type="submit" class="send-button" id="home-send" aria-label="Send question">${fe.send}</button></form><div class="home-footnote">Relevant notes are selected on this device before they’re sent with your request.</div></div></div></section>`,L("#note-editor").hidden=!1,L("#welcome").hidden=!0,L("#breadcrumbs").innerHTML=`<span>${Ut(((i=S.vault)==null?void 0:i.name)||"Workspace")}</span><span class="crumb-slash">/</span><strong>Home</strong>`,L(".location-note").textContent="Home",L("#save-state").textContent="",L("#word-count").textContent="",L("#assistant-toggle").disabled=!0,L("#assistant-toggle").setAttribute("aria-disabled","true"),L("#assistant-toggle").setAttribute("aria-pressed","false"),await window.stillnote.rememberNote(null).catch(()=>{}),Ht(),og(),L("#home-form").addEventListener("submit",YX),L("#home-new-chat").addEventListener("click",()=>{og(),L("#home-input").focus()}),L("#home-history-toggle").addEventListener("click",s=>{const r=s.currentTarget,a=L(".home-view"),o=L(".home-history"),l=r.getAttribute("aria-expanded")!=="true";r.setAttribute("aria-expanded",String(l)),r.setAttribute("aria-label",l?"Hide recent chats":"Show recent chats"),l?(a.classList.add("has-home-history"),xo(o,{opacity:[0,1],translateX:[-7,0],duration:bo(130),ease:"outQuad"})):xo(o,{opacity:[1,0],translateX:[0,-5],duration:bo(100),ease:"inQuad",onComplete:()=>{r.getAttribute("aria-expanded")!=="true"&&a.classList.remove("has-home-history"),o.style.opacity="",o.style.transform=""}})}),L("#home-transcript").addEventListener("click",s=>{const r=s.target.closest("[data-home-prompt]");if(!r)return;const a=L("#home-input");a.value=r.dataset.homePrompt,a.focus(),a.setSelectionRange(a.value.length,a.value.length)})}async function YX(n){var c;n.preventDefault();const e=L("#home-input"),t=e.value.trim();if(!t)return;let i;try{i=await window.stillnote.aiKeyStatus()}catch(h){Re(h.message||"Could not check Ollama key status.");return}if(!i.configured){la("ai");return}const r=(await window.stillnote.findRelevantNotes(t)).map(({path:h,title:d,excerpt:u})=>`FILE: ${h}
|
|
4454
4454
|
TITLE: ${d}
|
|
4455
4455
|
CONTENT:
|
|
4456
4456
|
${u}`).join(`
|
|
4457
4457
|
|
|
4458
4458
|
---
|
|
4459
4459
|
|
|
4460
|
-
`),a=L("#ai-model").value.trim()||localStorage.getItem("stillnote-ai-model")||"glm-4.6";S.homeSession.messages.push({role:"user",content:t}),S.homeSession.messages.filter(h=>h.role==="user").length===1&&(S.homeSession.title=t.slice(0,58)),e.value="";const o=L("#home-send");o.disabled=!0,ag();const l=document.createElement("div");l.className="home-bubble assistant loading",l.textContent="Thinking…",L("#home-transcript").append(l);try{const h=S.homeSession.messages.slice(0,-1).slice(-8),d=await window.stillnote.askAi({mode:"ask",model:a,noteName:((c=S.vault)==null?void 0:c.name)||"Workspace",documentType:"vault",document:r,prompt:t,history:h});l.remove(),S.homeSession.messages.push({role:"assistant",content:d.text}),
|
|
4460
|
+
`),a=L("#ai-model").value.trim()||localStorage.getItem("stillnote-ai-model")||"glm-4.6";S.homeSession.messages.push({role:"user",content:t}),S.homeSession.messages.filter(h=>h.role==="user").length===1&&(S.homeSession.title=t.slice(0,58)),e.value="";const o=L("#home-send");o.disabled=!0,ag();const l=document.createElement("div");l.className="home-bubble assistant loading",l.textContent="Thinking…",L("#home-transcript").append(l);try{const h=S.homeSession.messages.slice(0,-1).slice(-8),d=await window.stillnote.askAi({mode:"ask",model:a,noteName:((c=S.vault)==null?void 0:c.name)||"Workspace",documentType:"vault",document:r,prompt:t,history:h});l.remove(),S.homeSession.messages.push({role:"assistant",content:d.text}),QX(),ag(),KT()}catch(h){l.remove();const d=document.createElement("div");d.className="home-bubble assistant error",d.textContent=h.message||"The assistant could not respond.",L("#home-transcript").append(d)}finally{L("#home-send")&&(L("#home-send").disabled=!1)}}function lg(n){const e=atob(n.slice(n.indexOf(",")+1));return Uint8Array.from(e,t=>t.charCodeAt(0))}function jX(n,e,t){const i=Ae.theme({"&":{backgroundColor:"transparent",color:"#393a37",fontSize:"13px",height:"100%"},".cm-scroller":{fontFamily:"ui-monospace, SFMono-Regular, Menlo, monospace",lineHeight:"1.65",overflow:"auto"},".cm-content":{maxWidth:"none",padding:"28px 28px 90px",caretColor:"#a7795d"},".cm-gutters":{backgroundColor:"#f5f4f0",borderRight:"1px solid #e6e4dd",color:"#9a9a91"},".cm-activeLineGutter":{backgroundColor:"#ebe8e1",color:"#55564f"},".cm-activeLine":{backgroundColor:"#f8f7f3"},".cm-foldGutter .cm-gutterElement":{cursor:"pointer"},"&.cm-focused":{outline:"none"},".cm-selectionBackground, ::selection":{backgroundColor:"#e7ded4 !important"},".cm-cursor":{borderLeftColor:"#a7795d"}},{dark:!1});S.active=n,S.view=new Ae({state:vt.create({doc:e,extensions:[Gb(),Zb(),ek(),Nb(),$b(),Ub(),Fb(),x_(),dk(),GA(),Po.of(" "),GX(n),h_(d_),Ae.contentAttributes.of({spellcheck:"false",autocapitalize:"off",autocomplete:"off"}),ec.of([MC,...j_,...__,...$w]),i,Ae.updateListener.of(s=>{s.docChanged&&t===S.navigationId&&eM()})]}),parent:L("#editor-content")})}let gh=null,Oh=null;async function KX(){return Oh||(Oh=Promise.all([i0(()=>import("./pdf-q-5ow4VI.js"),[],import.meta.url),i0(()=>import("./pdf.worker.min-DDoUyrVu.js"),[],import.meta.url)]).then(([n,e])=>(n.GlobalWorkerOptions.workerSrc=e.default,n)).catch(n=>{throw Oh=null,n})),Oh}async function JX(n){if(S.assetPath!==n||!S.assetBytes)throw new Error("The PDF is no longer open.");return S.pdfTextPromise||(S.pdfTextPromise=(async()=>{const e=S.assetBytes.slice(),{getDocument:t}=await KX(),i=await t({data:e,isEvalSupported:!1,useSystemFonts:!0}).promise,s=[];let r=0;const a=135e3;for(let o=1;o<=i.numPages&&r<a;o++){const h=(await(await i.getPage(o)).getTextContent()).items.map(d=>d.str||"").filter(Boolean).join(" ");if(h){const d=`Page ${o}
|
|
4461
4461
|
${h}`;s.push(d.slice(0,a-r)),r+=d.length}}if(i.destroy(),!s.length)throw new Error("No selectable text was found in this PDF. Scanned PDFs need OCR before the assistant can read them.");return`${s.join(`
|
|
4462
4462
|
|
|
4463
4463
|
`)}${r>=a?`
|
|
4464
4464
|
|
|
4465
|
-
[PDF text truncated to fit the assistant context.]`:""}`})()),S.pdfTextPromise.then(e=>{if(S.active!==n||S.assetPath!==n)throw new Error("The PDF changed while its text was being read.");return S.pdfText=e,e})}function
|
|
4465
|
+
[PDF text truncated to fit the assistant context.]`:""}`})()),S.pdfTextPromise.then(e=>{if(S.active!==n||S.assetPath!==n)throw new Error("The PDF changed while its text was being read.");return S.pdfText=e,e})}function ez(){return gh||(gh=new Promise((n,e)=>{const t=document.createElement("script");t.id="occt-import-js",t.src=new URL("./vendor/occt-import-js.js",document.baseURI).href,t.onload=()=>{window.stillnote.loadOcctWasm().then(i=>window.occtimportjs({wasmBinary:new Uint8Array(i)})).then(n,e)},t.onerror=()=>e(new Error("The STEP geometry engine could not be loaded.")),document.head.append(t)}).catch(n=>{throw gh=null,n})),gh}async function JT(n,e){var l,c,h,d,u,f,p,O,g;const t=`.${oa(n)}`,i=lg(e.data),s=new Ia;if(t===".obj"){const m=new hX().parse(new TextDecoder().decode(i)),y=new qf({color:12036757,roughness:.68,metalness:.08,side:wi});m.traverse(T=>{T.isMesh&&(T.material=y,T.geometry.attributes.normal||T.geometry.computeVertexNormals())}),s.add(m)}else if(t===".stl"){const m=new dX().parse(i.buffer);if(!((l=m.attributes.position)!=null&&l.count))throw new Error("No triangles were found in this STL file.");s.add(new pi(m,new qf({color:12036757,roughness:.68,metalness:.08,side:wi})))}else{const m=await ez(),y=m.ReadStepFile(i,{linearUnit:"millimeter",linearDeflectionType:"bounding_box_ratio",linearDeflection:.001,angularDeflection:.5});if(!(y!=null&&y.success)||!((c=y.meshes)!=null&&c.length))throw new Error("No renderable STEP geometry was found.");for(const T of y.meshes){const w=((d=(h=T.attributes)==null?void 0:h.position)==null?void 0:d.array)||[];if(!w.length)continue;const _=new Un;_.setAttribute("position",new tn(w,3)),(f=(u=T.index)==null?void 0:u.array)!=null&&f.length&&_.setIndex(T.index.array),(g=(O=(p=T.attributes)==null?void 0:p.normal)==null?void 0:O.array)!=null&&g.length?_.setAttribute("normal",new tn(T.attributes.normal.array,3)):_.computeVertexNormals();const b=T.color||[.72,.68,.59],k=(C,E)=>Number.isFinite(Number(b[C]))?Number(b[C]):E,v=new rt().setRGB(k(0,.72),k(1,.68),k(2,.59));s.add(new pi(_,new qf({color:v,roughness:.68,metalness:.08,side:wi})))}if(!s.children.length)throw new Error("No renderable STEP faces were found.")}const r=new Rr().setFromObject(s);if(r.isEmpty())throw new Error("This model has no visible geometry.");const a=r.getCenter(new G),o=r.getSize(new G);return s.position.sub(a),s.rotation.x=t===".obj"?0:-Math.PI/2,{group:s,size:o}}async function tz(n,e,t,i){let s=!0,r=0,a=null,o=null,l=null,c=null;const h=()=>{s=!1,cancelAnimationFrame(r),l==null||l.disconnect(),o==null||o.dispose(),c&&c.traverse(d=>{if(d.geometry&&d.geometry.dispose(),d.material)for(const u of Array.isArray(d.material)?d.material:[d.material])u.dispose()}),a==null||a.dispose(),a==null||a.domElement.remove()};i.__disposePreview=h;try{if({group:c}=await JT(e,t),!s||!n.isConnected){h();return}const d=new vT;d.background=new rt(S.theme==="dark"?"#20211e":S.theme==="sepia"?"#f1ecdf":"#f4f4f1"),d.add(c),d.add(new AT(16777215,7828330,2.2));const u=new Nd(16777215,2.7);u.position.set(4,7,8),d.add(u);const f=new Nd(16777215,1.1);f.position.set(-6,2,-5),d.add(f);const p=new Rr().setFromObject(c),O=p.getCenter(new G),g=p.getSize(new G),m=Math.max(g.x,g.y,g.z,.001),y=m*.5,T=new hi(42,1,Math.max(m/1e4,1e-5),m*1e3);T.position.set(y*3.2,y*2.5,y*3.2),T.lookAt(O),a=new NT({antialias:!0,alpha:!1}),a.setPixelRatio(Math.min(window.devicePixelRatio||1,2)),a.outputColorSpace=Ln,n.append(a.domElement),o=new XT(T,a.domElement),o.target.copy(O),o.enableDamping=!0,o.dampingFactor=.075,o.minDistance=y*.15,o.maxDistance=y*80;const w=()=>{s&&(r=requestAnimationFrame(w),o.update(),a.render(d,T))};l=new ResizeObserver(()=>{const _=n.clientWidth,b=n.clientHeight;!_||!b||(a.setSize(_,b,!1),T.aspect=_/b,T.updateProjectionMatrix())}),l.observe(n),n.clientWidth&&n.clientHeight&&(a.setSize(n.clientWidth,n.clientHeight,!1),T.aspect=n.clientWidth/n.clientHeight,T.updateProjectionMatrix()),w()}catch(d){if(!s||!n.isConnected)return;n.textContent=d.message||"3D preview unavailable",n.classList.add("is-error"),h()}}async function nz(n,e,t,i){const s=document.createElement("div");s.className="asset-model-viewport",n.append(s);const r=document.createElement("div");r.className="asset-model-hint",r.textContent="Drag to rotate · scroll to zoom",s.append(r);try{const{group:a}=await JT(e,t);if(i!==S.navigationId||!s.isConnected)return;const o=new vT;o.background=new rt(S.theme==="dark"?"#20211e":S.theme==="sepia"?"#f1ecdf":"#f4f4f1"),o.add(a),o.add(new AT(16777215,7828330,2.2));const l=new Nd(16777215,2.7);l.position.set(4,7,8),o.add(l);const c=new Nd(16777215,1.1);c.position.set(-6,2,-5),o.add(c);const h=new Rr().setFromObject(a),d=h.getCenter(new G),u=h.getSize(new G),f=Math.max(u.x,u.y,u.z,.001),p=f*.5,O=new hi(42,1,Math.max(f/1e4,1e-5),f*1e3);O.position.set(p*3.2,p*2.5,p*3.2),O.lookAt(d);const g=new NT({antialias:!0,alpha:!1});g.setPixelRatio(Math.min(window.devicePixelRatio||1,2)),g.outputColorSpace=Ln,s.append(g.domElement);const m=new XT(O,g.domElement);m.target.copy(d),m.enableDamping=!0,m.dampingFactor=.075,m.minDistance=p*.15,m.maxDistance=p*80;let y=0,T=!0;const w=()=>{T&&(y=requestAnimationFrame(w),m.update(),g.render(o,O))},_=new ResizeObserver(()=>{const v=s.clientWidth,C=s.clientHeight;!v||!C||(g.setSize(v,C,!1),O.aspect=v/C,O.updateProjectionMatrix())});_.observe(s);const b=s.clientWidth,k=s.clientHeight;g.setSize(b,k,!1),O.aspect=b/Math.max(k,1),O.updateProjectionMatrix(),r.remove(),w(),S.assetViewer={destroy(){T=!1,cancelAnimationFrame(y),_.disconnect(),m.dispose(),o.traverse(v=>{if(v.geometry&&v.geometry.dispose(),v.material)for(const C of Array.isArray(v.material)?v.material:[v.material])C.dispose()}),g.dispose(),g.domElement.remove()}}}catch(a){if(i!==S.navigationId||!s.isConnected)return;r.textContent=a.message||"This model could not be rendered.",r.classList.add("is-error")}}async function iz(n,e){const t=await window.stillnote.readAsset(n);if(e!==S.navigationId)return;const i=L("#editor-content"),s=document.createElement("section");s.className="asset-preview-stage",i.replaceChildren(s);const r=`.${oa(n)}`;if(S.assetPath=n,S.assetBytes=r===".pdf"?lg(t.data):null,S.pdfText=null,S.pdfTextPromise=null,t.mime.startsWith("image/")){const a=document.createElement("img");a.className="asset-preview-image",a.src=t.data,a.alt=at(n),a.addEventListener("error",()=>{const o=document.createElement("p");o.className="asset-preview-error",o.textContent="This image format cannot be decoded by the built-in preview.",s.replaceChildren(o)}),s.append(a)}else if(t.mime==="application/pdf"){const a=document.createElement("div");a.className="asset-pdf-shell";const o=document.createElement("iframe");o.className="asset-preview-frame",o.title=at(n),o.src=t.data,a.append(o),s.append(a)}else if([".obj",".stl",".step",".stp"].includes(r))nz(s,n,t,e);else{const a=document.createElement("pre");a.className="asset-preview-text";try{a.textContent=new TextDecoder().decode(lg(t.data))}catch(o){a.textContent=o.message||"This file could not be previewed."}if(e!==S.navigationId)return;s.append(a)}}async function mi(n){var t,i,s,r,a,o,l,c,h,d,u,f,p;L("#note-format-toolbar").hidden=!0,L("#note-editor").classList.remove("has-markdown-editor"),S.home=!1,L("#assistant-toggle").disabled=!1,L("#assistant-toggle").removeAttribute("aria-disabled"),L("#home-button").setAttribute("aria-pressed","false");const e=S.navigationId=(S.navigationId||0)+1;try{const O=S.active;S.pendingStructuredRename&&await S.pendingStructuredRename,n===O&&S.active!==O&&(n=S.active);const g=S.active;if(await qn(),e!==S.navigationId)return;if(n===g&&S.active!==g&&(n=S.active),(i=(t=S.assetViewer)==null?void 0:t.destroy)==null||i.call(t),S.assetViewer=null,S.assetPath=null,S.assetBytes=null,S.pdfText=null,S.pdfTextPromise=null,!n.toLowerCase().endsWith(".md")&&!Fd(n)){const M=S.active!==n;if((s=S.view)==null||s.destroy(),S.view=null,(o=(a=(r=S.structured)==null?void 0:r.desmos)==null?void 0:a.destroy)==null||o.call(a),S.structured=null,S.dirty=!1,S.active=n,M&&(S.chatHistory=[],S.lastTitleValidationMessage=null,xh()),L("#editor-content").replaceChildren(),L("#note-indexes").hidden=!0,L("#note-format-toolbar").hidden=!0,L("#meeting-notes-trigger").hidden=!0,L("#note-editor").classList.remove("has-markdown-editor"),hr(),L("#note-editor").hidden=!1,L("#welcome").hidden=!0,L("#save-state").textContent="Preview",L("#editor-footer").querySelector("span").textContent="PREVIEW",L("#editor-footer").lastElementChild.textContent="LOCAL FILE",Ja(n),Ht(),await iz(n,e),e!==S.navigationId)return;window.stillnote.rememberNote(n).catch(R=>console.error("Could not save active file:",R));return}let m=await window.stillnote.readNote(n);if(e!==S.navigationId)return;if(!n.toLowerCase().endsWith(".md")){const M=S.active!==n;(l=S.view)==null||l.destroy(),S.view=null,(d=(h=(c=S.structured)==null?void 0:c.desmos)==null?void 0:h.destroy)==null||d.call(h),S.structured=null,M&&(S.chatHistory=[],S.lastTitleValidationMessage=null,xh()),L("#editor-content").replaceChildren(),L("#note-indexes").hidden=!0,L("#note-format-toolbar").hidden=!0,L("#meeting-notes-trigger").hidden=!0,L("#note-editor").classList.remove("has-markdown-editor"),jX(n,m,e),S.dirty=!1,L("#save-state").textContent="Saved",L("#note-editor").hidden=!1,L("#welcome").hidden=!0,L("#editor-footer").querySelector("span").textContent=oa(n).toUpperCase(),hr(),Yh(m),Ja(n),Ht(),window.stillnote.rememberNote(n).catch(R=>console.error("Could not save active file:",R));return}const y=m.includes(`\r
|
|
4466
4466
|
`)?`\r
|
|
4467
4467
|
`:`
|
|
4468
|
-
`,T=m.split(/\r?\n/),w=at(n),_=T[0].trim().replace(/^#{1,6}\s+/,"").replace(/\.md$/i,"").trim().toLocaleLowerCase(),b=w.replace(/\.md$/i,"").trim().toLocaleLowerCase();/^#\s+/.test(T[0])||_&&_===b?T[0]=w:T.unshift(w);const k=T.join(y);k!==m&&(await window.stillnote.writeNote(n,k),m=k);const v=kO(m);if(S.view&&(S.view.destroy(),S.view=null),(p=(f=(u=S.structured)==null?void 0:u.desmos)==null?void 0:f.destroy)==null||p.call(f),S.structured=null,hr(),L("#editor-content").replaceChildren(),L("#note-indexes").hidden=!0,v){FO(),L("#meeting-notes-trigger").hidden=!0;const M=S.active!==n;S.active=n,Hl(v.type,v.data,n,w),hr(),S.dirty=!1,L("#save-state").textContent="Saved",Yh(m),window.stillnote.rememberNote(n).catch(R=>console.error("Could not save active note:",R)),M&&(S.chatHistory=[],S.lastTitleValidationMessage=null,xh()),L("#welcome").hidden=!0,L("#note-editor").hidden=!1,Ja(n),Ht();return}const C=Ae.theme({"&":{backgroundColor:"transparent",color:"#393a37",fontSize:"16px",height:"100%"},".cm-scroller":{fontFamily:'"Iowan Old Style", "Palatino Linotype", Georgia, serif',lineHeight:"1.9",overflow:"auto"},".cm-content":{maxWidth:"720px",margin:"0 auto",padding:"42px 28px 90px",caretColor:"#a7795d"},".cm-line":{padding:"0 0"},".cm-gutters":{display:"none"},"&.cm-focused":{outline:"none"},".cm-activeLine":{backgroundColor:"transparent"},".cm-selectionBackground, ::selection":{backgroundColor:"#e7ded4 !important"},".cm-cursor":{borderLeftColor:"#a7795d"},".cm-line:first-child":{fontSize:"30px",fontWeight:"600",letterSpacing:"-.04em",color:"#292a27"}},{dark:!1});S.view&&(S.view.destroy(),S.view=null),S.view=new Ae({state:vt.create({doc:m,extensions:[TX,Gb(),Zb(),$b(),Ub(),Fb(),JE(),x_(),G2({extensions:[y1,_1]}),h_(d_),y$(),Nb(),Ae.lineWrapping,
|
|
4468
|
+
`,T=m.split(/\r?\n/),w=at(n),_=T[0].trim().replace(/^#{1,6}\s+/,"").replace(/\.md$/i,"").trim().toLocaleLowerCase(),b=w.replace(/\.md$/i,"").trim().toLocaleLowerCase();/^#\s+/.test(T[0])||_&&_===b?T[0]=w:T.unshift(w);const k=T.join(y);k!==m&&(await window.stillnote.writeNote(n,k),m=k);const v=kO(m);if(S.view&&(S.view.destroy(),S.view=null),(p=(f=(u=S.structured)==null?void 0:u.desmos)==null?void 0:f.destroy)==null||p.call(f),S.structured=null,hr(),L("#editor-content").replaceChildren(),L("#note-indexes").hidden=!0,v){FO(),L("#meeting-notes-trigger").hidden=!0;const M=S.active!==n;S.active=n,Hl(v.type,v.data,n,w),hr(),S.dirty=!1,L("#save-state").textContent="Saved",Yh(m),window.stillnote.rememberNote(n).catch(R=>console.error("Could not save active note:",R)),M&&(S.chatHistory=[],S.lastTitleValidationMessage=null,xh()),L("#welcome").hidden=!0,L("#note-editor").hidden=!1,Ja(n),Ht();return}const C=Ae.theme({"&":{backgroundColor:"transparent",color:"#393a37",fontSize:"16px",height:"100%"},".cm-scroller":{fontFamily:'"Iowan Old Style", "Palatino Linotype", Georgia, serif',lineHeight:"1.9",overflow:"auto"},".cm-content":{maxWidth:"720px",margin:"0 auto",padding:"42px 28px 90px",caretColor:"#a7795d"},".cm-line":{padding:"0 0"},".cm-gutters":{display:"none"},"&.cm-focused":{outline:"none"},".cm-activeLine":{backgroundColor:"transparent"},".cm-selectionBackground, ::selection":{backgroundColor:"#e7ded4 !important"},".cm-cursor":{borderLeftColor:"#a7795d"},".cm-line:first-child":{fontSize:"30px",fontWeight:"600",letterSpacing:"-.04em",color:"#292a27"}},{dark:!1});S.view&&(S.view.destroy(),S.view=null),S.view=new Ae({state:vt.create({doc:m,extensions:[TX,Gb(),Zb(),$b(),Ub(),Fb(),JE(),x_(),G2({extensions:[y1,_1]}),h_(d_),y$(),Nb(),Ae.lineWrapping,XX,Ae.contentAttributes.of({spellcheck:"false",lang:"en-US"}),ec.of([{key:"Mod-b",run:M=>$s(M,"**")},{key:"Mod-i",run:M=>$s(M,"*")},{key:"Mod-Shift-c",run:M=>$s(M,"`")},{key:"Mod-Shift-x",run:M=>$s(M,"~~")},...pw,...j_,...__,...$w]),C,Ae.updateListener.of(M=>{M.docChanged&&(eM(),ql(M.view),ly(M.view))})]}),parent:L("#editor-content")}),S.view.scrollDOM.addEventListener("scroll",()=>ZT(S.view),{passive:!0}),L("#note-editor").dataset.toolbarPosition=S.toolbarPositions.notes,L("#meeting-notes-trigger").hidden=!1,L("#note-format-toolbar").hidden=S.toolbarPositions.notes==="hidden",L("#note-editor").classList.toggle("has-markdown-editor",S.toolbarPositions.notes!=="hidden"),ql(S.view),Yh(m),L("#save-state").textContent="Saved",S.dirty=!1;const E=S.active!==n;S.active=n,window.stillnote.rememberNote(n).catch(M=>console.error("Could not save active note:",M)),hr(),E&&(S.chatHistory=[],S.lastTitleValidationMessage=null,xh()),L("#welcome").hidden=!0,L("#note-editor").hidden=!1,ly(S.view),L("#breadcrumbs").innerHTML=`<span>${Ut(S.vault.name)}</span><span class="crumb-slash">/</span><strong>${Ut(n.split("/").map(at).join(" / "))}</strong>`,L(".location-note").textContent=at(n),Ht()}catch(O){Re(O.message||"Could not open note.")}}L("#editor-content").addEventListener("contextmenu",n=>{if(!n.target.closest(".cm-editor")||!S.view)return;if(n.target.closest(".cm-wiki-media-preview")){n.preventDefault();return}const e=n.target.closest("math[data-equation]");if(e){n.preventDefault(),n.stopPropagation(),ay(e.dataset.equation,n.clientX,n.clientY);return}const t=S.view.posAtCoords({x:n.clientX,y:n.clientY});if(t!=null){const i=S.view.state.doc.lineAt(t),s=/\$([^$\n]+)\$/g;let r;for(;r=s.exec(i.text);)if(t>=i.from+r.index&&t<=i.from+r.index+r[0].length){n.preventDefault(),n.stopPropagation(),ay(r[1],n.clientX,n.clientY);return}}VX(S.view,n)});L("#editor-content").addEventListener("click",n=>{var e;!n.target.closest(".cm-editor")||n.target.closest(".cm-wiki-media-preview")||!S.view||!((e=S.active)!=null&&e.toLocaleLowerCase().endsWith(".md"))||HT(S.view,n)});L("#note-format-toolbar").addEventListener("mousedown",n=>n.preventDefault());L("#note-format-toolbar").addEventListener("click",n=>{var s;const e=n.target.closest("[data-format]");if(!e||!S.view)return;const t=S.view,i={bold:()=>$s(t,"**"),italic:()=>$s(t,"*"),code:()=>$s(t,"`"),strike:()=>$s(t,"~~"),heading1:()=>Yo(t,"#","heading"),heading2:()=>Yo(t,"##","heading"),bullet:()=>Yo(t,"- ","bullet"),ordered:()=>Yo(t,"1. ","ordered"),checklist:()=>Yo(t,"- [ ] ","task"),highlight:()=>$s(t,"=")};(s=i[e.dataset.format])==null||s.call(i),t.focus()});function eM(){var s;S.dirty=!0,L("#save-state").textContent="Unsaved changes";const n=S.view.state.doc.toString();if(Yh(n),!((s=S.active)!=null&&s.toLowerCase().endsWith(".md"))){clearTimeout(S.saveTimer),S.saveTimer=setTimeout(qn,650);return}const e=S.view.state.doc.line(1).text,i=/[<>:"/\\|?*\u0000-\u001f]/.test(e)?_o(e.replace(/\.md$/i,"").trim()):null;i&&i!==S.lastTitleValidationMessage&&Re(i),S.lastTitleValidationMessage=i,clearTimeout(S.saveTimer),S.saveTimer=setTimeout(qn,650)}function sz(n){return n==="/"||n==="\\"?"A note title cannot contain / or \\; those characters separate folders.":n===":"?"A note title cannot contain a colon (:).":/[<>|?*"]/u.test(n)?`A note title cannot contain ${n}; that character is reserved in file names.`:"A note title cannot contain control characters."}function _o(n){const e=n.trim();if(!e)return"A note title cannot be empty.";const t=e.match(/[<>:"/\\|?*\u0000-\u001f]/);return t?sz(t[0]):e==="."||e===".."?"A note title cannot be “.” or “..”.":e.endsWith(".")?"A note title cannot end with a period.":null}function Yh(n){const e=n.trim()?n.trim().split(/\s+/).length:0;L("#word-count").textContent=`${e} ${e===1?"word":"words"}`}function hc(n,e,t){return`${e}
|
|
4469
4469
|
<!-- stillnote:type=${n} -->
|
|
4470
4470
|
|
|
4471
4471
|
\`\`\`stillnote-${n}
|
|
4472
4472
|
${JSON.stringify(t,null,2)}
|
|
4473
4473
|
\`\`\`
|
|
4474
|
-
`}function kO(n){const e=n.match(/<!--\s*stillnote:type=(canvas|spreadsheet|graph|tasks)\s*-->[\s\S]*?```stillnote-\1\s*\n([\s\S]*?)\n```/);if(!e)return null;try{return{type:e[1],data:JSON.parse(e[2])}}catch{return{type:e[1],data:null}}}function tM(){return{version:1,width:1200,height:760,elements:[]}}function nM(){return{version:1,columns:8,rows:20,cells:{}}}function iM(){return{version:1,state:null}}function sM(n){return{version:1,listId:n,tasks:[]}}let Ko=null,cy=null;function sz(n){var t;if(!n)return Promise.reject(new Error("Add a Desmos API key in Settings → Graphing to open this graph."));if((t=window.Desmos)!=null&&t.GraphingCalculator&&cy===n)return Promise.resolve(window.Desmos);if((Ko==null?void 0:Ko.key)===n)return Ko.promise;const e=new Promise((i,s)=>{const r=document.createElement("script");r.src=`https://www.desmos.com/api/v1.11/calculator.js?apiKey=${encodeURIComponent(n)}`,r.async=!0,r.onload=()=>{var a;if(!((a=window.Desmos)!=null&&a.GraphingCalculator)){s(new Error("Desmos loaded without its Graphing Calculator API."));return}cy=n,i(window.Desmos)},r.onerror=()=>s(new Error("Could not load Desmos. Check your internet connection and API key.")),document.head.append(r)});return Ko={key:n,promise:e},e}function cg(n){CO(String(n||"").split("|")[0].trim())}async function CO(n){const e=String(n||"").trim(),t=e.indexOf("#"),i=t<0?e:e.slice(0,t).trim(),s=t<0?"":e.slice(t+1).trim(),r=i?RO(i):S.active;if(!r){Re(`No file found for “${i||e}”.`);return}if((r!==S.active||!S.view)&&await mi(r),s&&S.view&&S.active===r){const a=rz(S.view,s);a==null?Re(`No heading or tag “${s}” found in ${at(r)}.`):qT(S.view,a)}}function Sh(n){return String(n||"").toLocaleLowerCase().replace(/<[^>]*>/g,"").replace(/[`*_~]/g,"").trim().replace(/[^\p{L}\p{N}\s-]/gu,"").replace(/\s+/g,"-").replace(/-+/g,"-")}function rz(n,e){let t=e;try{t=decodeURIComponent(e.replace(/\+/g," "))}catch{}const i=Sh(t),s=n.state.doc;let r=!1,a="",o=0,l=new Map;for(let u=1;u<=s.lines;u++){const f=s.line(u),p=f.text,O=p.match(/^\s{0,3}(`{3,}|~{3,})/);if(O){r?O[1][0]===a&&O[1].length>=o&&(r=!1):(r=!0,a=O[1][0],o=O[1].length);continue}if(r)continue;const g=p.match(/^\s{0,3}#{1,6}\s+(.+?)\s*#*\s*$/);if(g){const m=Sh(g[1]),y=l.get(m)||0;if(l.set(m,y+1),(y?`${m}-${y}`:m)===i||m===i)return f.from}if(/^\s*#/.test(p)&&Sh(p.replace(/^\s*#+\s*/,""))===i)return f.from;if(u<s.lines&&p.trim()&&/^\s*(?:=+|-+)\s*$/.test(s.line(u+1).text)){const m=Sh(p.trim()),y=l.get(m)||0;if(l.set(m,y+1),m===i||y&&`${m}-${y}`===i)return f.from}}const h=`#${t.replace(/^#/,"")}`.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),d=new RegExp(`(^|[^\\p{L}\\p{N}_])${h}(?=$|[^\\p{L}\\p{N}_])`,"iu").exec(s.toString());return d?d.index+d[1].length:null}function RO(n){const e=String(n||"").trim().replace(/\\/g,"/").replace(/^\.\//,"").toLocaleLowerCase();if(!e)return null;const t=zs(),i=t.find(o=>o.toLocaleLowerCase()===e);if(i)return i;const s=o=>o.replace(/\.[^./]+$/,"");if(!/\.[^/]+$/.test(e)){const o=t.find(l=>l.toLocaleLowerCase()===`${e}.md`);if(o)return o}const r=t.filter(o=>s(o.toLocaleLowerCase())===s(e));if(r.length===1)return r[0];if(r.length>1)return r.find(o=>o.toLocaleLowerCase().endsWith(".md"))||null;if(e.includes("/"))return null;const a=t.filter(o=>{const l=o.split("/").at(-1).toLocaleLowerCase();return l===e||s(l)===s(e)});return a.length===1?a[0]:a.length>1&&a.find(o=>o.toLocaleLowerCase().endsWith(".md"))||null}function Ct(){const n=S.structured;if(n&&n.type!=="tasks"){const e=JSON.stringify({title:n.title||at(S.active),data:n.data});e!==n.historySnapshot&&(n.historyPending||(n.undoStack.push(n.historySnapshot),n.undoStack.length>100&&n.undoStack.shift(),n.redoStack=[],n.historyPending=!0),n.historySnapshot=e,clearTimeout(n.historyTimer),n.historyTimer=setTimeout(()=>{n.historyPending=!1},600)),gu()}S.dirty=!0,L("#save-state").textContent="Unsaved changes",clearTimeout(S.saveTimer),S.saveTimer=setTimeout(qn,450)}function gu(){const n=S.structured;n&&(document.querySelectorAll('[data-history="undo"]').forEach(e=>e.disabled=!n.undoStack.length),document.querySelectorAll('[data-history="redo"]').forEach(e=>e.disabled=!n.redoStack.length))}async function ia(n){const e=S.structured;if(!e)return;const t=n==="undo"?e.undoStack:e.redoStack,i=n==="undo"?e.redoStack:e.undoStack;if(!t.length)return;clearTimeout(e.historyTimer),e.historyPending=!1,i.push(JSON.stringify({title:e.title||at(S.active),data:e.data}));const s=t.pop(),r=JSON.parse(s),a=e.type,o={undoStack:e.undoStack,redoStack:e.redoStack};e.data=r.data,e.title=r.title,e.historySnapshot=s;let l=S.active;if(r.title&&r.title!==at(l))try{l=await window.stillnote.renameEntry(l,r.title),S.active=l,[S.files,S.tree]=await Promise.all([window.stillnote.listNotes(),window.stillnote.getVaultTree()]),Ht(),Ja(l),window.stillnote.rememberNote(l).catch(()=>{})}catch(c){Re(`Could not restore the file name: ${c.message}`)}Hl(a,r.data,l,r.title||at(l)),Object.assign(S.structured,o,{historySnapshot:s,historyPending:!1}),S.dirty=!0,L("#save-state").textContent="Unsaved changes",clearTimeout(S.saveTimer),S.saveTimer=setTimeout(qn,250),gu()}function Hl(n,e,t,i){var l,c,h,d,u;FO(),L("#meeting-notes-trigger").hidden=!0,(c=(l=S.structured)==null?void 0:l.cleanup)==null||c.call(l);const s=e&&typeof e=="object"?e:n==="canvas"?tM():n==="graph"?iM():n==="tasks"?sM(""):nM();(u=(d=(h=S.structured)==null?void 0:h.desmos)==null?void 0:d.destroy)==null||u.call(d),S.structured={type:n,data:s,title:i,file:t,undoStack:[],redoStack:[],historySnapshot:JSON.stringify({title:i,data:s}),historyPending:!1},hr();const r=L("#editor-content");r.replaceChildren();const a=document.createElement("section");a.className=`structured-editor ${n}-editor`,n==="canvas"&&(a.dataset.toolbarPosition=S.toolbarPositions.canvas),a.innerHTML='<div class="structured-title" contenteditable="true" role="textbox" aria-label="File title" spellcheck="false"></div><div class="structured-toolbar"></div><div class="structured-surface"></div>';const o=a.querySelector(".structured-title");return o.textContent=i,o.addEventListener("input",()=>{S.structured.title=o.textContent.trim(),Ct()}),o.addEventListener("blur",()=>{const f=o.textContent.trim(),p=_o(f);if(p){Re(p),o.textContent=at(S.active);return}const O=S.active,g=S.structured;if(f&&f!==at(O)){const m=(async()=>{try{if(S.active!==O||S.structured!==g||(g.type==="tasks"&&await window.stillnote.renameGoogleTaskList(g.data.listId,f),S.active!==O||S.structured!==g))return;const y=await window.stillnote.renameEntry(O,f);if(S.active!==O||S.structured!==g||(S.active=y,[S.files,S.tree]=await Promise.all([window.stillnote.listNotes(),window.stillnote.getVaultTree()]),S.active!==y||S.structured!==g))return;Ht(),Ja(y),Ct()}catch(y){S.structured===g&&(Re(`Could not rename file: ${y.message}`),o.textContent=at(O),g.type==="tasks"&&(g.title=at(O),await window.stillnote.renameGoogleTaskList(g.data.listId,at(O)).catch(()=>{}),Ct()))}})();return S.pendingStructuredRename=m,m.finally(()=>{S.pendingStructuredRename===m&&(S.pendingStructuredRename=null)}),m}}),r.append(a),n==="canvas"?az(a,s):n==="graph"?rM(a,s):n==="tasks"?cz(a,s):oz(a,s),gu(),a}function Ja(n){L("#breadcrumbs").innerHTML=`<span>${Ut(S.vault.name)}</span><span class="crumb-slash">/</span><strong>${Ut(n.split("/").map(at).join(" / "))}</strong>`,L(".location-note").textContent=at(n)}function az(n,e){const t=n.querySelector(".structured-toolbar"),i=[["red","#d94d48"],["yellow","#d9ae23"],["green","#348562"],["blue","#397dc2"],["black","#20211e"]];t.innerHTML=`<div class="canvas-tool-group" role="toolbar" aria-label="Canvas tools">${[["select","Select and move",fe.cursor],["draw","Pen tool",fe.draw],["shape","Shape tool",fe.shape],["line","Line tool",fe.line],["text","Insert text",fe.text]].map(([E,M,R])=>`<button class="canvas-tool${E==="select"?" active":""}" data-tool="${E}" title="${M}" aria-label="${M}" aria-pressed="${E==="select"}">${R}</button>`).join("")}<span class="canvas-tool-divider"></span><button class="canvas-tool" data-action="rotate" title="Rotate selected 15° clockwise" aria-label="Rotate selected 15 degrees clockwise">${fe.rotate}</button><button class="canvas-tool canvas-delete" data-tool="delete" title="Delete selected" aria-label="Delete selected">${fe.trash}</button><span class="canvas-tool-divider"></span><button class="canvas-tool" data-history="undo" title="Undo (⌘Z)" aria-label="Undo">${fe.undo}</button><button class="canvas-tool" data-history="redo" title="Redo (⌘⇧Z)" aria-label="Redo">${fe.redo}</button></div>`;const s=n.querySelector(".structured-surface");s.innerHTML=`<svg class="canvas-svg" viewBox="0 0 ${e.width||1200} ${e.height||760}" style="width:${e.width||1200}px;height:${e.height||760}px;max-width:none" role="img" aria-label="Drawing canvas" xmlns="http://www.w3.org/2000/svg"></svg>`;const r=s.querySelector("svg"),a=document.createElement("div");a.className="canvas-color-palette",a.setAttribute("role","group"),a.setAttribute("aria-label","Selected item colors"),a.innerHTML=i.map(([E,M])=>`<button class="canvas-color-swatch" data-color="${M}" style="--swatch:${M}" title="${E[0].toUpperCase()+E.slice(1)}" aria-label="${E[0].toUpperCase()+E.slice(1)} color" aria-pressed="false"><svg viewBox="0 0 16 16" aria-hidden="true"><path d="m3 8 3.2 3.2L13 4.8"/></svg></button>`).join(""),s.append(a);const o=document.createElement("div");o.className="canvas-shape-menu",o.setAttribute("role","group"),o.setAttribute("aria-label","Shape options"),o.innerHTML=`<div class="canvas-shape-options">${[["rectangle","Rectangle",fe.rectangle],["ellipse","Ellipse",fe.ellipse],["triangle","Triangle",fe.triangle],["star","Star",fe.star],["speech","Speech bubble",fe.speech]].map(([E,M,R])=>`<button type="button" data-shape="${E}" title="${M}" aria-label="${M}" aria-pressed="false">${R}</button>`).join("")}</div><label class="canvas-star-points" hidden>Points <select aria-label="Star points">${Array.from({length:9},(E,M)=>`<option value="${M+4}"${M===1?" selected":""}>${M+4}</option>`).join("")}</select></label>`,s.append(o);const l=document.createElement("div");l.className="canvas-line-menu",l.setAttribute("role","group"),l.setAttribute("aria-label","Line endpoint styles"),l.innerHTML=`${[["start","Start"],["end","End"]].map(([E,M])=>`<div class="canvas-endpoint-menu" data-endpoint-menu="${E}" role="group" aria-label="${M} endpoint style">${[["none","None",fe.markerNone],["arrow","Arrow",fe.markerArrow],["circle","Circle",fe.markerCircle],["square","Square",fe.markerSquare],["diamond","Diamond",fe.markerDiamond]].map(([R,N,Q])=>`<button type="button" data-endpoint="${E}" data-style="${R}" title="${M}: ${N}" aria-label="${M}: ${N}" aria-pressed="false">${Q}</button>`).join("")}</div>`).join("")}`,s.append(l);const c=document.createElement("div");c.className="canvas-tool-help",c.setAttribute("aria-live","polite"),n.append(c);let h="select",d=new Set,u=null,f=null,p=null,O="#20211e";const g=E=>{const M=String(E||O).toLowerCase();return S.theme==="dark"&&["#20211e","#353630","#373832","#000","#000000"].includes(M)?"#ffffff":E||O},m=E=>{if(E.type==="stroke"){const M=E.points.map(A=>A.x),R=E.points.map(A=>A.y),N=Math.min(...M),Q=Math.min(...R);return{x:N,y:Q,w:Math.max(1,Math.max(...M)-N),h:Math.max(1,Math.max(...R)-Q)}}return E.type==="line"?{x:Math.min(E.x1,E.x2),y:Math.min(E.y1,E.y2),w:Math.max(1,Math.abs(E.x2-E.x1)),h:Math.max(1,Math.abs(E.y2-E.y1))}:E.type==="text"?{x:E.x,y:E.y,w:Math.max(40,E.w||220),h:Math.max(30,E.h||60)}:{x:Math.min(E.x,E.x+E.w),y:Math.min(E.y,E.y+E.h),w:Math.max(1,Math.abs(E.w)),h:Math.max(1,Math.abs(E.h))}},y=E=>{const M=[...E].map(F=>m(e.elements[F])).filter(Boolean);if(!M.length)return null;const R=Math.min(...M.map(F=>F.x)),N=Math.min(...M.map(F=>F.y)),Q=Math.max(...M.map(F=>F.x+F.w)),A=Math.max(...M.map(F=>F.y+F.h));return{x:R,y:N,w:Q-R,h:A-N}},T=(E,M,R,N)=>({x:R.x+(E-R.x)*Math.cos(N)-(M-R.y)*Math.sin(N),y:R.y+(E-R.x)*Math.sin(N)+(M-R.y)*Math.cos(N)}),w=E=>{const M=y(d);if(!M)return;const R={x:M.x+M.w/2,y:M.y+M.h/2},N=E*Math.PI/180;for(const Q of d){const A=e.elements[Q];if(A.type==="stroke")A.points=A.points.map(F=>T(F.x,F.y,R,N));else if(A.type==="line"){const F=T(A.x1,A.y1,R,N),U=T(A.x2,A.y2,R,N);A.x1=F.x,A.y1=F.y,A.x2=U.x,A.y2=U.y}else{const F=m(A),U=T(F.x+F.w/2,F.y+F.h/2,R,N);A.x=U.x-F.w/2,A.y=U.y-F.h/2,A.rotation=((A.rotation||0)+E)%360}}_(),Ct()},_=()=>{r.replaceChildren(),e.elements.forEach((A,F)=>{let U;if(A.type==="stroke")U=document.createElementNS("http://www.w3.org/2000/svg","polyline"),U.setAttribute("points",A.points.map(I=>`${I.x},${I.y}`).join(" ")),U.setAttribute("fill","none"),U.setAttribute("stroke",g(A.color)),U.setAttribute("stroke-width","3"),U.setAttribute("stroke-linecap","round"),U.setAttribute("stroke-linejoin","round");else if(A.type==="line"){U=document.createElementNS("http://www.w3.org/2000/svg","g");const I=document.createElementNS("http://www.w3.org/2000/svg","line");I.setAttribute("x1",A.x1),I.setAttribute("y1",A.y1),I.setAttribute("x2",A.x2),I.setAttribute("y2",A.y2),I.setAttribute("stroke",g(A.color)),I.setAttribute("stroke-width","3"),I.setAttribute("stroke-linecap","round"),U.append(I);const z=A.x2-A.x1,W=A.y2-A.y1,oe=Math.hypot(z,W)||1;for(const[he,we,de,ve,j]of[["start",A.x1,A.y1,A.startMarker||"none",-1],["end",A.x2,A.y2,A.endMarker||"arrow",1]]){if(ve==="none")continue;const K=z/oe*j,ae=W/oe*j;if(ve==="circle"){const ge=document.createElementNS("http://www.w3.org/2000/svg","circle");ge.setAttribute("cx",we),ge.setAttribute("cy",de),ge.setAttribute("r",5),ge.setAttribute("fill",g(A.color)),U.append(ge)}else if(ve==="square"){const ge=document.createElementNS("http://www.w3.org/2000/svg","rect");ge.setAttribute("x",we-4),ge.setAttribute("y",de-4),ge.setAttribute("width",8),ge.setAttribute("height",8),ge.setAttribute("fill",g(A.color)),U.append(ge)}else if(ve==="diamond"){const ge=document.createElementNS("http://www.w3.org/2000/svg","polygon");ge.setAttribute("points",`${we},${de-5} ${we+5},${de} ${we},${de+5} ${we-5},${de}`),ge.setAttribute("fill",g(A.color)),U.append(ge)}else{const ge=we-K*12,Oe=de-ae*12,Ge=-ae*5,_t=K*5,He=document.createElementNS("http://www.w3.org/2000/svg","polygon");He.setAttribute("points",`${we},${de} ${ge+Ge},${Oe+_t} ${ge-Ge},${Oe-_t}`),He.setAttribute("fill",g(A.color)),U.append(He)}}}else if(A.type==="shape"){const I=A.x,z=A.y,W=A.w,oe=A.h;if(U=document.createElementNS("http://www.w3.org/2000/svg",A.shape==="rectangle"?"rect":A.shape==="ellipse"?"ellipse":"polygon"),A.shape==="rectangle")U.setAttribute("x",I),U.setAttribute("y",z),U.setAttribute("width",W),U.setAttribute("height",oe);else if(A.shape==="ellipse")U.setAttribute("cx",I+W/2),U.setAttribute("cy",z+oe/2),U.setAttribute("rx",W/2),U.setAttribute("ry",oe/2);else if(A.shape==="triangle"){const he=A.vertices||[[.5,0],[1,1],[0,1]];U.setAttribute("points",he.map(([we,de])=>`${I+we*W},${z+de*oe}`).join(" "))}else if(A.shape==="star"){const he=Math.max(4,Math.min(12,A.points||5)),we=I+W/2,de=z+oe/2,ve=Math.min(W,oe)/2,j=ve*.46,K=[];for(let ae=0;ae<he*2;ae++){const ge=ae%2?j:ve,Oe=-Math.PI/2+ae*Math.PI/he;K.push(`${we+Math.cos(Oe)*ge},${de+Math.sin(Oe)*ge}`)}U.setAttribute("points",K.join(" "))}else U=document.createElementNS("http://www.w3.org/2000/svg","path"),U.setAttribute("d",`M ${I+W*.12} ${z+oe*.12} H ${I+W*.88} V ${z+oe*.7} H ${I+W*.4} L ${I+W*.22} ${z+oe*.92} V ${z+oe*.7} H ${I+W*.12} Z`);U.setAttribute("fill","none"),U.setAttribute("stroke",g(A.color)),U.setAttribute("stroke-width","3"),U.setAttribute("stroke-linejoin","round"),U.setAttribute("pointer-events","all")}else if(A.type==="rect"||A.type==="ellipse")U=document.createElementNS("http://www.w3.org/2000/svg",A.type==="rect"?"rect":"ellipse"),A.type==="rect"?(U.setAttribute("x",A.x),U.setAttribute("y",A.y),U.setAttribute("width",A.w),U.setAttribute("height",A.h)):(U.setAttribute("cx",A.x+A.w/2),U.setAttribute("cy",A.y+A.h/2),U.setAttribute("rx",Math.abs(A.w/2)),U.setAttribute("ry",Math.abs(A.h/2))),U.setAttribute("fill","none"),U.setAttribute("stroke",g(A.color)),U.setAttribute("stroke-width","3"),U.setAttribute("pointer-events","all");else{U=document.createElementNS("http://www.w3.org/2000/svg","foreignObject"),U.setAttribute("x",A.x),U.setAttribute("y",A.y),U.setAttribute("width",Math.max(40,A.w||220)),U.setAttribute("height",Math.max(30,A.h||60)),U.innerHTML=`<div xmlns="http://www.w3.org/1999/xhtml" class="canvas-text-edit" contenteditable="true" spellcheck="false">${Xd(A.text||"")}</div>`;const I=U.querySelector(".canvas-text-edit");I.addEventListener("focus",()=>{I.textContent=A.text||""}),I.addEventListener("input",()=>{A.text=I.innerText,Ct()}),I.style.color=g(A.color),I.addEventListener("blur",()=>{A.text=aM(I),I.innerHTML=Xd(A.text)})}const q=m(A);A.type!=="stroke"&&A.rotation&&U.setAttribute("transform",`rotate(${A.rotation} ${q.x+q.w/2} ${q.y+q.h/2})`),U.dataset.index=F,d.has(F)&&U.classList.add("is-selected"),r.append(U)});const E=d.size>0&&[...d].every(A=>e.elements[A].type==="line");if(d.size){const A=[...d].map(W=>m(e.elements[W])).filter(Boolean),F=Math.min(...A.map(W=>W.x)),U=Math.min(...A.map(W=>W.y)),q=Math.max(...A.map(W=>W.x+W.w)),I=Math.max(...A.map(W=>W.y+W.h)),z={x:F,y:U,w:q-F,h:I-U};if(!E){const W=document.createElementNS("http://www.w3.org/2000/svg","rect");W.setAttribute("x",z.x-4),W.setAttribute("y",z.y-4),W.setAttribute("width",z.w+8),W.setAttribute("height",z.h+8),W.setAttribute("fill","none"),W.setAttribute("stroke","#9a765a"),W.setAttribute("stroke-dasharray","5 4"),W.setAttribute("pointer-events","none"),r.append(W);for(const[ve,j,K]of[["nw",z.x,z.y],["ne",z.x+z.w,z.y],["sw",z.x,z.y+z.h],["se",z.x+z.w,z.y+z.h]]){const ae=document.createElementNS("http://www.w3.org/2000/svg","rect");ae.setAttribute("x",j-5),ae.setAttribute("y",K-5),ae.setAttribute("width",10),ae.setAttribute("height",10),ae.setAttribute("rx",2),ae.setAttribute("fill","#fff"),ae.setAttribute("stroke","#9a765a"),ae.setAttribute("stroke-width",2),ae.dataset.handle=ve,ae.classList.add("canvas-resize-handle"),r.append(ae)}const oe=z.x+z.w/2,he=Math.max(14,z.y-24),we=document.createElementNS("http://www.w3.org/2000/svg","line");we.setAttribute("x1",oe),we.setAttribute("x2",oe),we.setAttribute("y1",z.y-4),we.setAttribute("y2",he+6),we.setAttribute("stroke","#9a765a"),we.setAttribute("pointer-events","none"),r.append(we);const de=document.createElementNS("http://www.w3.org/2000/svg","circle");de.setAttribute("cx",oe),de.setAttribute("cy",he),de.setAttribute("r",6),de.setAttribute("fill","#fff"),de.setAttribute("stroke","#9a765a"),de.setAttribute("stroke-width",2),de.dataset.handle="rotate",de.classList.add("canvas-rotate-handle"),r.append(de)}for(const W of d){const oe=e.elements[W];if(oe.type==="shape"&&oe.shape==="triangle"){const he={x:oe.x+oe.w/2,y:oe.y+oe.h/2};(oe.vertices||[[.5,0],[1,1],[0,1]]).forEach(([we,de],ve)=>{const j=T(oe.x+we*oe.w,oe.y+de*oe.h,he,(oe.rotation||0)*Math.PI/180),K=document.createElementNS("http://www.w3.org/2000/svg","circle");K.setAttribute("cx",j.x),K.setAttribute("cy",j.y),K.setAttribute("r",5),K.setAttribute("fill","#fff"),K.setAttribute("stroke","#9a765a"),K.setAttribute("stroke-width",2),K.dataset.pointHandle=String(ve),K.dataset.index=String(W),K.classList.add("canvas-point-handle"),r.append(K)})}else if(oe.type==="line")for(const[he,we,de]of[["start",oe.x1,oe.y1],["end",oe.x2,oe.y2]]){const ve=document.createElementNS("http://www.w3.org/2000/svg","circle");ve.setAttribute("cx",we),ve.setAttribute("cy",de),ve.setAttribute("r",8),ve.setAttribute("fill","#fff"),ve.setAttribute("stroke","#9a765a"),ve.setAttribute("stroke-width",2.5),ve.setAttribute("pointer-events","all"),ve.dataset.pointHandle=he,ve.dataset.index=String(W),ve.classList.add("canvas-point-handle"),r.append(ve)}}}if(p){const A=document.createElementNS("http://www.w3.org/2000/svg","rect");A.setAttribute("x",Math.min(p.start.x,p.current.x)),A.setAttribute("y",Math.min(p.start.y,p.current.y)),A.setAttribute("width",Math.abs(p.current.x-p.start.x)),A.setAttribute("height",Math.abs(p.current.y-p.start.y)),A.setAttribute("class","canvas-marquee"),A.setAttribute("pointer-events","none"),r.append(A)}const M=d.size?y(d):null;a.hidden=!M;const R=d.size===1?e.elements[[...d][0]]:null,N=(R==null?void 0:R.type)==="shape"||(R==null?void 0:R.type)==="rect"||(R==null?void 0:R.type)==="ellipse"?R:null,Q=(R==null?void 0:R.type)==="line"?R:null;if(o.hidden=!N,l.hidden=!Q,N){const A=N.shape||(N.type==="rect"?"rectangle":N.type==="ellipse"?"ellipse":"");o.querySelectorAll("[data-shape]").forEach(F=>F.setAttribute("aria-pressed",String(F.dataset.shape===A))),o.querySelector(".canvas-star-points").hidden=A!=="star",o.querySelector("select").value=String(N.points||5)}if(Q)for(const A of["start","end"]){const F=Q[`${A}Marker`]||(A==="end"?"arrow":"none");l.querySelectorAll(`[data-endpoint="${A}"][data-style]`).forEach(U=>U.setAttribute("aria-pressed",String(U.dataset.style===F)))}if(M){const A=r.clientWidth/Math.max(1,e.width||1200),F=(M.x+M.w)*A+10,U=F+a.offsetWidth<=r.clientWidth?F:Math.max(4,M.x*A-a.offsetWidth-10);a.style.left=`${U}px`,a.style.top=`${Math.max(8,M.y*A)}px`;const q=Math.min(Math.max(4,U),Math.max(4,r.clientWidth-190));o.style.left=`${q}px`;const I=Math.max(8,M.y*A+a.offsetHeight+8);o.style.top=`${I}px`}if(Q){const A=r.clientWidth/Math.max(1,e.width||1200);for(const[F,U,q]of[["start",Q.x1,Q.y1],["end",Q.x2,Q.y2]]){const I=l.querySelector(`[data-endpoint-menu="${F}"]`),z=U*A-I.offsetWidth-9;I.style.left=`${z>=2?z:U*A+10}px`,I.style.top=`${Math.max(2,q*A-I.offsetHeight/2)}px`}}a.querySelectorAll("[data-color]").forEach(A=>{const F=A.dataset.color.toLowerCase()===O.toLowerCase();A.classList.toggle("active",F),A.setAttribute("aria-pressed",String(F))})};r.dataset.tool=h;const b=()=>{if(d.size){for(const E of[...d].sort((M,R)=>R-M))e.elements.splice(E,1);d.clear(),_(),Ct()}};S.structured.deleteCanvasSelection=b,t.querySelectorAll("[data-tool]").forEach(E=>E.addEventListener("click",()=>{if(E.dataset.tool==="delete"){b();return}h=E.dataset.tool,r.dataset.tool=h,t.querySelectorAll(".canvas-tool[data-tool]").forEach(M=>{const R=M===E;M.classList.toggle("active",R),M.setAttribute("aria-pressed",String(R))}),v()})),t.querySelector('[data-action="rotate"]').addEventListener("click",()=>w(15)),a.querySelectorAll("[data-color]").forEach(E=>E.addEventListener("click",()=>{O=E.dataset.color;for(const M of d)e.elements[M].color=O;d.size&&(_(),Ct())})),o.querySelectorAll("[data-shape]").forEach(E=>E.addEventListener("click",()=>{const M=d.size===1?e.elements[[...d][0]]:null;["shape","rect","ellipse"].includes(M==null?void 0:M.type)&&(M.type="shape",M.shape=E.dataset.shape,M.shape==="triangle"&&(M.vertices||(M.vertices=[[.5,0],[1,1],[0,1]])),M.shape==="star"&&(M.points||(M.points=5)),_(),Ct())})),o.querySelector("select").addEventListener("change",E=>{const M=d.size===1?e.elements[[...d][0]]:null;(M==null?void 0:M.type)==="shape"&&M.shape==="star"&&(M.points=Number(E.target.value),_(),Ct())}),l.querySelectorAll("button[data-endpoint][data-style]").forEach(E=>E.addEventListener("click",()=>{const M=d.size===1?e.elements[[...d][0]]:null;(M==null?void 0:M.type)==="line"&&(M[`${E.dataset.endpoint}Marker`]=E.dataset.style,_(),Ct())})),t.querySelectorAll("[data-history]").forEach(E=>E.addEventListener("click",()=>ia(E.dataset.history)));const k=E=>{const M=r.createSVGPoint();M.x=E.clientX,M.y=E.clientY;const R=M.matrixTransform(r.getScreenCTM().inverse());return{x:R.x,y:R.y}},v=()=>{const E={select:"Drag selected items to move them. Use the corner handles to resize and the top handle to rotate.",draw:"Drag to draw freehand with the pen.",shape:"Drag to create a bounding box, then choose Rectangle, Ellipse, Triangle, Star, or Speech bubble from the shape menu.",line:"Drag to draw a line. Move either endpoint, or choose its start and end markers from the line menu."};c.textContent=E[h]||"",c.hidden=!E[h]};v(),r.addEventListener("pointerdown",E=>{var A,F;const M=E.target.closest(".sheet-wiki-link");if(M){E.preventDefault(),cg(M.dataset.target);return}if(E.target.closest(".canvas-text-edit")&&h==="select"&&E.detail>=2)return;const N=k(E),Q=Number((A=E.target.closest("[data-index]"))==null?void 0:A.dataset.index);if(h==="select"){const U=E.target.closest("[data-point-handle]");if(U&&Number.isInteger(Q)){f={kind:"point",index:Q,handle:U.dataset.pointHandle,original:structuredClone(e.elements[Q])},r.setPointerCapture(E.pointerId),E.preventDefault(),E.stopPropagation();return}if(E.target.dataset.handle==="rotate"&&d.size){const q=y(d),I={x:q.x+q.w/2,y:q.y+q.h/2},z=Math.atan2(N.y-I.y,N.x-I.x);f={kind:"rotate",start:N,center:I,lastAngle:z,angle:0,originals:new Map([...d].map(W=>[W,structuredClone(e.elements[W])]))},r.setPointerCapture(E.pointerId),E.preventDefault();return}if(E.target.dataset.handle&&d.size){f={kind:"resize",handle:E.target.dataset.handle,start:N,originals:new Map([...d].map(q=>[q,structuredClone(e.elements[q])])),group:y(d)},r.setPointerCapture(E.pointerId),E.preventDefault();return}if(Number.isInteger(Q)){E.shiftKey||E.metaKey||E.ctrlKey?d.has(Q)?d.delete(Q):d.add(Q):d.has(Q)||(d=new Set([Q])),d.has(Q)&&(O=((F=e.elements[[...d][0]])==null?void 0:F.color)||O,f={kind:"move",start:N,originals:new Map([...d].map(q=>[q,structuredClone(e.elements[q])]))},r.setPointerCapture(E.pointerId)),_(),E.preventDefault();return}!E.shiftKey&&!E.metaKey&&!E.ctrlKey&&d.clear(),p={start:N,current:N,additive:E.shiftKey||E.metaKey||E.ctrlKey},r.setPointerCapture(E.pointerId),_();return}if(h==="erase"&&Number.isInteger(Q)){e.elements.splice(Q,1),d.clear(),_(),Ct();return}(h==="draw"||h==="shape"||h==="line")&&Number.isInteger(Q)||(r.setPointerCapture(E.pointerId),h==="draw"?u={type:"stroke",points:[N],color:O}:h==="shape"?u={type:"shape",shape:"rectangle",x:N.x,y:N.y,w:0,h:0,color:O}:h==="line"?u={type:"line",x1:N.x,y1:N.y,x2:N.x,y2:N.y,startMarker:"none",endMarker:"arrow",color:O}:h==="text"&&(u={type:"text",x:N.x,y:N.y,w:0,h:0,text:"",color:O}),u&&(e.elements.push(u),d=new Set([e.elements.length-1]),Ct()))}),r.addEventListener("pointermove",E=>{const M=k(E);if((u||f)&&(clearTimeout(S.structured.historyTimer),S.structured.historyTimer=setTimeout(()=>{S.structured.historyPending=!1},600)),p){p.current=M,_();return}if(f){const R=M.x-f.start.x,N=M.y-f.start.y;if(f.kind==="move")for(const[Q,A]of f.originals){const F=e.elements[Q];F.type==="stroke"?F.points=A.points.map(U=>({x:U.x+R,y:U.y+N})):F.type==="line"?(F.x1=A.x1+R,F.y1=A.y1+N,F.x2=A.x2+R,F.y2=A.y2+N):(F.x=A.x+R,F.y=A.y+N)}else if(f.kind==="point"){const Q=e.elements[f.index],A=f.original;if(Q.type==="line")f.handle==="start"?(Q.x1=M.x,Q.y1=M.y):(Q.x2=M.x,Q.y2=M.y);else if(Q.type==="shape"&&Q.shape==="triangle"){const F={x:A.x+A.w/2,y:A.y+A.h/2},U=T(M.x,M.y,F,-(A.rotation||0)*Math.PI/180);Q.vertices=(A.vertices||[[.5,0],[1,1],[0,1]]).map(([q,I],z)=>z===Number(f.handle)?[Math.max(0,Math.min(1,(U.x-A.x)/A.w)),Math.max(0,Math.min(1,(U.y-A.y)/A.h))]:[q,I])}}else if(f.kind==="rotate"){const Q=Math.atan2(M.y-f.center.y,M.x-f.center.x);let A=Q-f.lastAngle;for(;A>Math.PI;)A-=2*Math.PI;for(;A<-Math.PI;)A+=2*Math.PI;f.angle+=A,f.lastAngle=Q;for(const[F,U]of f.originals){const q=e.elements[F];if(q.type==="stroke")q.points=U.points.map(I=>T(I.x,I.y,f.center,f.angle));else if(q.type==="line"){const I=T(U.x1,U.y1,f.center,f.angle),z=T(U.x2,U.y2,f.center,f.angle);q.x1=I.x,q.y1=I.y,q.x2=z.x,q.y2=z.y}else{const I=m(U),z=T(I.x+I.w/2,I.y+I.h/2,f.center,f.angle);q.x=z.x-I.w/2,q.y=z.y-I.h/2,q.rotation=((U.rotation||0)+f.angle*180/Math.PI)%360}}}else{const Q=f.group,A=f.handle,F=A.includes("e"),U=A.includes("s"),q=A.includes("w"),I=A.includes("n"),z=q?Math.min(Q.x+Q.w-4,M.x):Q.x,W=I?Math.min(Q.y+Q.h-4,M.y):Q.y,oe=F?Math.max(Q.x+4,M.x):Q.x+Q.w,he=U?Math.max(Q.y+4,M.y):Q.y+Q.h,we=(oe-z)/Math.max(1,Q.w),de=(he-W)/Math.max(1,Q.h);for(const[ve,j]of f.originals){const K=e.elements[ve];if(K.type==="stroke")K.points=j.points.map(ae=>({x:z+(ae.x-Q.x)*we,y:W+(ae.y-Q.y)*de}));else if(K.type==="line")K.x1=z+(j.x1-Q.x)*we,K.y1=W+(j.y1-Q.y)*de,K.x2=z+(j.x2-Q.x)*we,K.y2=W+(j.y2-Q.y)*de;else{const ae=m(j);K.x=z+(ae.x-Q.x)*we,K.y=W+(ae.y-Q.y)*de,K.w=ae.w*we,K.h=ae.h*de}}}_();return}u&&(u.type==="stroke"?u.points.push(M):u.type==="line"?(u.x2=M.x,u.y2=M.y):(u.w=M.x-u.x,u.h=M.y-u.y),_())});const C=()=>{if(p){const E={x:Math.min(p.start.x,p.current.x),y:Math.min(p.start.y,p.current.y),w:Math.abs(p.current.x-p.start.x),h:Math.abs(p.current.y-p.start.y)};if(E.w>3||E.h>3){const M=e.elements.map((R,N)=>({i:N,b:m(R)})).filter(({b:R})=>R.x<=E.x+E.w&&R.x+R.w>=E.x&&R.y<=E.y+E.h&&R.y+R.h>=E.y).map(({i:R})=>R);d=p.additive?new Set([...d,...M]):new Set(M)}p=null,_();return}if(f&&(f=null,Ct()),u){const E=u.type,M=u.type==="text"&&Math.max(Math.abs(u.w),Math.abs(u.h))>=12;if(u.type==="text"&&!M||u.type==="line"&&Math.hypot(u.x2-u.x1,u.y2-u.y1)<4?(e.elements.pop(),d.clear()):(u.type==="shape"||u.type==="text")&&(u.w<0&&(u.x+=u.w,u.w=Math.abs(u.w)),u.h<0&&(u.y+=u.h,u.h=Math.abs(u.h)),u.w=Math.max(u.type==="text"?180:4,u.w),u.h=Math.max(u.type==="text"?60:4,u.h)),u=null,(E==="shape"||E==="line")&&(h="select",r.dataset.tool=h,t.querySelectorAll(".canvas-tool[data-tool]").forEach(R=>{const N=R.dataset.tool===h;R.classList.toggle("active",N),R.setAttribute("aria-pressed",String(N))}),v()),Ct(),_(),M){const R=[...d][0],N=r.querySelector('[data-index="'+R+'"] .canvas-text-edit');requestAnimationFrame(()=>N==null?void 0:N.focus())}}};r.addEventListener("pointerup",C),r.addEventListener("pointercancel",C),r.addEventListener("click",E=>{var N;const R=(((N=E.target.closest("[data-link-text]"))==null?void 0:N.getAttribute("data-link-text"))||"").match(/\[\[([^\]]+)\]\]/);R&&cg(R[1])}),_(),S.structured.refreshCanvas=_}async function rM(n,e){const t=n.querySelector(".structured-toolbar");t.innerHTML=`<span>Desmos Graphing Calculator · graph state is saved in this file</span><button data-history="undo" title="Undo (⌘Z)" aria-label="Undo">${fe.undo}</button><button data-history="redo" title="Redo (⌘⇧Z)" aria-label="Redo">${fe.redo}</button>`,t.querySelectorAll("[data-history]").forEach(o=>o.addEventListener("click",()=>ia(o.dataset.history)));const i=n.querySelector(".structured-surface"),s=S.structured,r=(o,l=!1)=>{i.replaceChildren();const c=document.createElement("div");c.className="graph-setup";const h=document.createElement("p");if(h.textContent=o,c.append(h),l){const d=document.createElement("button");d.className="secondary-button",d.textContent="Open Graphing settings",d.addEventListener("click",()=>la("desmos")),c.append(d)}i.append(c)};let a="";try{a=await window.stillnote.getDesmosKey()}catch(o){r(o.message||"Open a vault to use the saved Desmos key.");return}if(!a){In("desmos",!1,"Graphing API key missing"),r("A Desmos API key is required to use the graph editor.",!0);return}try{const o=await sz(a);if(S.structured!==s||!n.isConnected)return;const l=document.createElement("div");l.className="graph-calculator",i.replaceChildren(l);const c=S.theme==="dark"?{colors:["#d1a07e","#84b7a1","#83a9d2","#d88980","#b19bd2","#d7c36f"]}:S.theme==="sepia"?{colors:["#9d7151","#6e927b","#6f89a8","#b46d5e","#92779d","#b09550"]}:{},h=o.GraphingCalculator(l,{expressions:!0,keypad:!0,settingsMenu:!0,zoomButtons:!0,autosize:!0,invertedColors:!1,fontSize:15,border:!1,...c});s.desmos=h,In("desmos",!0,"Graphing API key working"),e.state&&typeof e.state=="object"?h.setState(e.state):e.state=h.getState(),h.clearHistory(),h.observeEvent("change",()=>{S.structured!==s||!S.active||(e.state=h.getState(),Ct())})}catch(o){S.structured===s&&n.isConnected&&(In("desmos",!1,"Graphing API key not working"),r(o.message||"Could not open Desmos.",!0))}}function oz(n,e){const t=n.querySelector(".structured-toolbar");t.innerHTML=`<span>Click a cell to edit · use <[Note]> to link</span><button data-history="undo" title="Undo (⌘Z)" aria-label="Undo">${fe.undo}</button><button data-history="redo" title="Redo (⌘⇧Z)" aria-label="Redo">${fe.redo}</button><button class="sheet-add-row">Add row</button><button class="sheet-add-column">Add column</button>`;const i=n.querySelector(".structured-surface"),s=()=>{let r='<table class="sheet-grid"><thead><tr><th></th>';for(let a=0;a<e.columns;a++)r+=`<th>${hy(a)}</th>`;r+="</tr></thead><tbody>";for(let a=0;a<e.rows;a++){r+=`<tr><th>${a+1}</th>`;for(let o=0;o<e.columns;o++){const l=`${hy(o)}${a+1}`,c=String(e.cells[l]??""),h=c.startsWith("=")?hg(e,l):c;r+=`<td contenteditable="true" data-cell="${l}" spellcheck="false">${Xd(h)}</td>`}r+="</tr>"}r+="</tbody></table>",i.innerHTML=r,i.querySelectorAll("[data-cell]").forEach(a=>{a.addEventListener("focus",()=>{a.textContent=e.cells[a.dataset.cell]||""}),a.addEventListener("input",()=>{e.cells[a.dataset.cell]=a.innerText,Ct(),i.querySelectorAll("[data-cell]").forEach(o=>{if(o===a||document.activeElement===o)return;const l=String(e.cells[o.dataset.cell]??"");o.innerHTML=Xd(l.startsWith("=")?hg(e,o.dataset.cell):l)})}),a.addEventListener("blur",()=>{e.cells[a.dataset.cell]=aM(a),s()})})};i.addEventListener("click",r=>{const a=r.target.closest(".sheet-wiki-link");a&&(r.preventDefault(),r.stopPropagation(),cg(a.dataset.target))}),t.querySelector(".sheet-add-row").addEventListener("click",()=>{e.rows=Math.min(200,e.rows+1),s(),Ct()}),t.querySelector(".sheet-add-column").addEventListener("click",()=>{e.columns=Math.min(26,e.columns+1),s(),Ct()}),s(),t.querySelectorAll("[data-history]").forEach(r=>r.addEventListener("click",()=>ia(r.dataset.history)))}async function lz(n,e,t){const i=String(t||"").trim();if(!i||S.structured!==e||!n.isConnected)return;const s=n.querySelector(".structured-title");if(i===at(S.active)){e.title=i,s.textContent=i;return}const r=_o(i);if(r){Re(`Google list title cannot be used as a file name: ${r}`);return}const a=S.active;try{if(await qn(),S.active!==a||S.structured!==e)return;const o=await window.stillnote.renameEntry(a,i);if(S.active!==a||S.structured!==e)return;S.active=o,e.file=o,e.title=i,s.textContent=i,[S.files,S.tree]=await Promise.all([window.stillnote.listNotes(),window.stillnote.getVaultTree()]),Ht(),Ja(o),window.stillnote.rememberNote(o).catch(()=>{}),Ct()}catch(o){Re(`Google list title changed, but the task sheet could not be renamed: ${o.message}`)}}async function cz(n,e){Array.isArray(e.tasks)||(e.tasks=[]);const t=S.structured;let i=!1;const s=n.querySelector(".structured-toolbar");s.innerHTML=`<span class="task-sheet-status">Loading Google Tasks…</span><button class="secondary-button task-sheet-refresh" type="button" aria-label="Sync with Google Tasks" title="Sync with Google Tasks">${fe.refresh}</button>`;const r=n.querySelector(".structured-surface");r.innerHTML='<form class="task-sheet-add"><input class="settings-input" type="text" maxlength="1024" placeholder="Add a task…" aria-label="New task"><button class="primary-button" type="submit">Add task</button></form><div class="task-sheet-list" aria-live="polite"></div>';const a=s.querySelector(".task-sheet-status"),o=r.querySelector(".task-sheet-list"),l=()=>S.structured===t&&n.isConnected,c=()=>{var g;if(!((g=e.tasks)!=null&&g.length)){o.innerHTML='<div class="task-sheet-empty">No tasks in this list yet.</div>';return}const u=new Map(e.tasks.map((m,y)=>[m.id,{task:m,index:y}])),f=m=>[...m].sort((y,T)=>+!!y.parent-+!!T.parent).map(y=>{const T=e.tasks.indexOf(y),w=y.parent&&u.has(y.parent)?1:0,_=y.due?String(y.due).slice(0,10):"";return`<article class="task-sheet-card${y.status==="completed"?" is-complete":""}${w?" is-subtask":""}${y.starred?" is-starred":""}" data-index="${T}"><div class="task-sheet-row"><input class="task-sheet-complete" type="checkbox" aria-label="Mark ${Ut(y.title)} complete" ${y.status==="completed"?"checked":""}><input class="task-sheet-title" type="text" maxlength="1024" aria-label="Task title" value="${Ut(y.title)}"><button class="task-sheet-star${y.starred?" is-starred":""}" type="button" aria-label="${y.starred?"Unstar":"Star"} task" title="${y.starred?"Unstar task":"Star task"}">${fe.star}</button><button class="icon-button task-sheet-delete" type="button" aria-label="Delete ${Ut(y.title)}" title="Delete task">${fe.trash}</button></div><div class="task-sheet-fields"><label>Due date<input class="task-sheet-due" type="date" value="${Ut(_)}" aria-label="Due date"></label><label class="task-sheet-details-label">Details<textarea class="task-sheet-details" rows="2" maxlength="8192" placeholder="Add details…" aria-label="Task details">${Ut(y.notes||"")}</textarea></label></div>${w?"":'<form class="task-sheet-subtask"><input class="settings-input" type="text" maxlength="1024" placeholder="Add a subtask…" aria-label="New subtask"><button class="secondary-button" type="submit">Add subtask</button></form>'}</article>`}).join(""),p=e.tasks.filter(m=>m.status!=="completed"),O=e.tasks.filter(m=>m.status==="completed");o.innerHTML=`${f(p)}${O.length?`<details class="task-sheet-completed"><summary>Completed <span>${O.length}</span></summary><div class="task-sheet-completed-list">${f(O)}</div></details>`:""}`,!p.length&&!O.length&&(o.innerHTML='<div class="task-sheet-empty">No tasks in this list yet.</div>')},h=async()=>{if(!(i||!l())){i=!0,a.textContent="Syncing…";try{const[u,f]=await Promise.all([window.stillnote.listGoogleTaskLists(),window.stillnote.listGoogleTasks(e.listId)]);if(!l())return;const p=u.find(m=>m.id===e.listId);if(!p)throw new Error("This Google Tasks list no longer exists.");if(await lz(n,t,p.title),!l())return;const O=JSON.stringify(e.tasks),g=new Map(e.tasks.map(m=>[m.id,!!m.starred]));e.tasks=f.map(m=>({id:m.id,title:m.title||"",status:m.status||"needsAction",due:m.due||null,notes:m.notes||"",parent:m.parent||null,starred:g.get(m.id)||!1})),c(),a.textContent=`Synced with Google Tasks · ${e.tasks.length} ${e.tasks.length===1?"task":"tasks"}`,O!==JSON.stringify(e.tasks)&&Ct()}catch(u){l()&&(a.textContent=u.message||"Could not sync Google Tasks")}finally{i=!1}}},d=setInterval(()=>{l()?h():clearInterval(d)},12e4);t.cleanup=()=>clearInterval(d),s.querySelector(".task-sheet-refresh").addEventListener("click",()=>void h()),s.querySelectorAll("[data-history]").forEach(u=>u.addEventListener("click",()=>ia(u.dataset.history))),r.querySelector(".task-sheet-add").addEventListener("submit",async u=>{u.preventDefault();const f=r.querySelector(".task-sheet-add input"),p=f.value.trim();if(!p)return;const O=r.querySelector(".task-sheet-add button");O.disabled=!0;try{const g=await window.stillnote.createGoogleTask(e.listId,p);if(!l())return;e.tasks.push({id:g.id,title:g.title||p,status:g.status||"needsAction",due:g.due||null,notes:g.notes||"",parent:null,starred:!1}),f.value="",c(),Ct(),a.textContent="Task added to Google Tasks"}catch(g){l()&&(a.textContent=g.message||"Could not add task",Re(a.textContent))}finally{O.disabled=!1}}),o.addEventListener("change",async u=>{if(u.target.matches(".task-sheet-due, .task-sheet-details")){const g=u.target.closest("[data-index]"),m=e.tasks[Number(g.dataset.index)],y=u.target.matches(".task-sheet-due")?u.target.value:String(m.due||"").slice(0,10),T=u.target.matches(".task-sheet-details")?u.target.value:m.notes||"",w=u.target.matches(".task-sheet-due")?{due:y?`${y}T00:00:00.000Z`:null}:{notes:T};u.target.disabled=!0;try{const _=await window.stillnote.updateGoogleTask(e.listId,m.id,w);if(!l())return;"due"in w?m.due=_.due||null:m.notes=_.notes||"",Ct(),a.textContent="Task updated in Google Tasks"}catch(_){l()&&("due"in w?u.target.value=String(m.due||"").slice(0,10):u.target.value=m.notes||"",a.textContent=_.message||"Could not update task",Re(a.textContent))}finally{u.target.isConnected&&(u.target.disabled=!1)}return}if(u.target.matches(".task-sheet-title")){const g=u.target.closest("[data-index]"),m=e.tasks[Number(g.dataset.index)],y=u.target.value.trim();if(!y){u.target.value=m.title;return}u.target.disabled=!0;try{const T=await window.stillnote.updateGoogleTask(e.listId,m.id,{title:y});if(!l())return;m.title=T.title||y,u.target.value=m.title,Ct(),a.textContent="Task updated in Google Tasks"}catch(T){l()&&(u.target.value=m.title,a.textContent=T.message||"Could not update task",Re(a.textContent))}finally{u.target.isConnected&&(u.target.disabled=!1)}return}if(!u.target.matches(".task-sheet-complete"))return;const f=u.target.closest("[data-index]"),p=e.tasks[Number(f.dataset.index)],O=u.target.checked?"completed":"needsAction";u.target.disabled=!0;try{const g=await window.stillnote.updateGoogleTask(e.listId,p.id,{status:O});if(!l())return;p.status=g.status||O,c(),Ct(),a.textContent="Task updated in Google Tasks"}catch(g){l()&&(u.target.checked=p.status==="completed",a.textContent=g.message||"Could not update task",Re(a.textContent))}finally{u.target.isConnected&&(u.target.disabled=!1)}}),o.addEventListener("focusin",u=>{const f=u.target.closest(".task-sheet-card");f&&f.classList.add("is-editing")}),o.addEventListener("focusout",u=>{const f=u.target.closest(".task-sheet-card");f&&requestAnimationFrame(()=>{f.isConnected&&!f.contains(document.activeElement)&&f.classList.remove("is-editing")})}),o.addEventListener("click",async u=>{const f=u.target.closest(".task-sheet-star");if(f){const y=f.closest("[data-index]"),T=e.tasks[Number(y.dataset.index)];T.starred=!T.starred,c(),Ct();return}const p=u.target.closest(".task-sheet-delete");if(!p)return;const O=p.closest("[data-index]"),g=Number(O.dataset.index),m=e.tasks[g];p.disabled=!0;try{if(await window.stillnote.deleteGoogleTask(e.listId,m.id),!l())return;e.tasks.splice(g,1),c(),Ct(),a.textContent="Task deleted from Google Tasks"}catch(y){l()&&(p.disabled=!1,a.textContent=y.message||"Could not delete task",Re(a.textContent))}}),o.addEventListener("submit",async u=>{const f=u.target.closest(".task-sheet-subtask");if(!f)return;u.preventDefault();const p=f.closest("[data-index]"),O=e.tasks[Number(p.dataset.index)],m=f.querySelector("input").value.trim();if(!m)return;const y=f.querySelector("button");y.disabled=!0;try{const T=await window.stillnote.createGoogleTask(e.listId,m,O.id);if(!l())return;e.tasks.push({id:T.id,title:T.title||m,status:T.status||"needsAction",due:T.due||null,notes:T.notes||"",parent:T.parent||O.id,starred:!1}),c(),Ct(),a.textContent="Subtask added to Google Tasks"}catch(T){l()&&(a.textContent=T.message||"Could not add subtask",Re(a.textContent))}finally{y.isConnected&&(y.disabled=!1)}}),c(),await h()}function hg(n,e,t=new Set){var r;e=e.toUpperCase();const i=String(n.cells[e]??"").trim();if(!i)return"0";if(!i.startsWith("=")){const a=Number(i);return Number.isFinite(a)?String(a):"#VALUE!"}if(t.has(e))return"#CYCLE!";const s=new Set(t);s.add(e);try{const a=i.slice(1),o=a.match(/[A-Za-z]+[0-9]+|(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?|[()+\-*/^]/g)||[];if(o.join("")!==a.replace(/\s+/g,""))return"#VALUE!";let l=0;const c=()=>{const p=o[l++];if(p==="+"||p==="-"){const g=c();return p==="-"?-g:g}if(p==="("){const g=u();if(o[l++]!==")")throw new Error("#VALUE!");return g}if(!p)throw new Error("#VALUE!");if(/^[A-Za-z]+\d+$/.test(p)){const g=hg(n,p,s);if(g.startsWith("#"))throw new Error(g);return Number(g)}const O=Number(p);if(!Number.isFinite(O))throw new Error("#VALUE!");return O},h=()=>{let p=c();return o[l]==="^"&&(l++,p=Math.pow(p,h())),p},d=()=>{let p=h();for(;o[l]==="*"||o[l]==="/";){const O=o[l++],g=h();if(O==="/"&&g===0)throw new Error("#DIV/0!");p=O==="*"?p*g:p/g}return p},u=()=>{let p=d();for(;o[l]==="+"||o[l]==="-";){const O=o[l++],g=d();p=O==="+"?p+g:p-g}return p},f=u();return l!==o.length||!Number.isFinite(f)?"#VALUE!":String(Number(f.toPrecision(12)))}catch(a){return(r=a.message)!=null&&r.startsWith("#")?a.message:"#VALUE!"}}function hy(n){let e="";for(let t=n+1;t;t=Math.floor((t-1)/26))e=String.fromCharCode(65+(t-1)%26)+e;return e}function Xd(n){const e=String(n),t=/(?:<\[([^\]|]+)(?:\|([^\]]+))?\]>|\[\[([^\]|]+)(?:\|([^\]]+))?\]\])/g;let i="",s=0,r;for(;r=t.exec(e);){i+=Ut(e.slice(s,r.index));const a=(r[1]||r[3]).trim(),o=r[2]||r[4]||a;i+=`<a class="sheet-wiki-link" href="#" data-target="${Ut(a)}">${Ut(o)}</a>`,s=r.index+r[0].length}return i+Ut(e.slice(s))}function aM(n){const e=t=>{if(t.nodeType===Node.TEXT_NODE)return t.nodeValue||"";if(t.nodeType!==Node.ELEMENT_NODE)return"";if(t.matches("a.sheet-wiki-link")){const i=t.dataset.target||"",s=t.textContent||i;return`<[${i}${s!==i?`|${s}`:""}]>`}return[...t.childNodes].map(e).join("")};return[...n.childNodes].map(e).join("")}async function qn(){if(S.savePromise)return await S.savePromise,S.dirty?qn():void 0;if(!S.dirty||!S.active||!S.view&&!S.structured)return;if(clearTimeout(S.saveTimer),S.structured){const s=S.active,r=S.structured,a=(r.title||at(s)).trim()||at(s),o=(async()=>{try{await window.stillnote.writeNote(s,hc(r.type,a,r.data)),S.dirty=!1,L("#save-state").textContent="Saved"}catch(l){L("#save-state").textContent="Save failed",Re(l.message||"Could not save file.")}})();S.savePromise=o;try{await o}finally{S.savePromise=null}return}const n=S.view,e=S.active;let t=!1;const i=(async()=>{try{if(!e.toLowerCase().endsWith(".md")){const d=n.state.doc.toString();await window.stillnote.writeNote(e,d),t=!0,S.view===n&&S.active===e&&(S.dirty=n.state.doc.toString()!==d,L("#save-state").textContent=S.dirty?"Unsaved changes":"Saved");return}const s=n.state.doc.line(1),r=s.text.trim(),a=(r||at(e)).replace(/\.md$/i,"").trim()||at(e);s.text!==a&&n.dispatch({changes:{from:s.from,to:s.to,insert:a}});const o=n.state.doc.toString();await window.stillnote.writeNote(e,o),t=!0;const l=_o(r.replace(/\.md$/i,"").trim());if(l){S.dirty=n.state.doc.toString()!==o,L("#save-state").textContent=S.dirty?"Unsaved changes":"Saved",S.lastTitleValidationMessage!==l&&Re(l),S.lastTitleValidationMessage=l;return}let c=e;const h=at(e);if(a!==h)try{c=await window.stillnote.renameEntry(e,a)}catch(d){S.dirty=n.state.doc.toString()!==o,L("#save-state").textContent=S.dirty?"Unsaved changes":"Saved",Re(`Note saved, but it could not be renamed: ${d.message}`);return}c!==e&&(S.active=c,[S.files,S.tree]=await Promise.all([window.stillnote.listNotes(),window.stillnote.getVaultTree()]),Ht(),L("#breadcrumbs").innerHTML=`<span>${Ut(S.vault.name)}</span><span class="crumb-slash">/</span><strong>${Ut(c.split("/").map(at).join(" / "))}</strong>`,L(".location-note").textContent=at(c),window.stillnote.rememberNote(c).catch(d=>console.error("Could not save active note:",d))),S.view===n&&S.active===c&&(S.dirty=n.state.doc.toString()!==o,L("#save-state").textContent=S.dirty?"Unsaved changes":"Saved")}catch(s){L("#save-state").textContent="Save failed",Re(s.message)}})();S.savePromise=i;try{await i}finally{S.savePromise=null}if(t&&S.dirty)return qn()}async function Ou(n=""){var t;if(!S.vault)return qs();const e=`Untitled ${S.files.filter(i=>at(i).startsWith("Untitled")).length+1}`;try{const i=await window.stillnote.createNote(e,n);[S.files,S.tree]=await Promise.all([window.stillnote.listNotes(),window.stillnote.getVaultTree()]),Ht(),await mi(i),(t=S.view)==null||t.focus()}catch(i){Re(i.message||"Could not create note.")}}async function hz(){const n=L("#rename-form"),e=n.querySelector(".rename-actions"),t=document.createElement("label");t.className="code-type-picker",t.textContent="File type";const i=document.createElement("select");i.className="settings-input",i.setAttribute("aria-label","Code file type"),i.replaceChildren(...rg.map(([c,h])=>{const d=document.createElement("option");return d.value=h,d.textContent=`${c} (${h})`,d})),t.append(i),e.before(t);const s=await Su("Create code file","Untitled","Create file"),r=i.value;if(t.remove(),!(s!=null&&s.trim()))return null;const a=s.trim(),o=rg.map(([,c])=>c).find(c=>a.toLocaleLowerCase().endsWith(c));return`${o?a.slice(0,-o.length):a}${r}`}async function oM(n=""){var t;if(!S.vault)return qs();const e=await hz();if(e)try{const i=await window.stillnote.createCodeFile(e,n);[S.files,S.tree]=await Promise.all([window.stillnote.listNotes(),window.stillnote.getVaultTree()]),Ht(),await mi(i),(t=S.view)==null||t.focus()}catch(i){Re(i.message||"Could not create code file.")}}async function eo(n,e=""){if(!S.vault)return qs();const t=n==="canvas"?"Canvas":n==="graph"?"Graph":"Spreadsheet",i=`Untitled ${t} ${S.files.filter(s=>at(s).startsWith(`Untitled ${t}`)).length+1}`;try{const s=await window.stillnote.createNote(i,e),r=n==="canvas"?tM():n==="graph"?iM():nM();await window.stillnote.writeNote(s,hc(n,i,r)),[S.files,S.tree]=await Promise.all([window.stillnote.listNotes(),window.stillnote.getVaultTree()]),Ht(),await mi(s)}catch(s){Re(s.message||`Could not create ${t.toLowerCase()}.`)}}async function lM(n=""){var t;if(!S.vault)return qs();const e=await window.stillnote.googleTasksStatus().catch(()=>null);if(!(e!=null&&e.clientIdConfigured)||!e.connected){Re("Connect Google Tasks in Settings before creating a task sheet."),la("tasks");return}try{const i=await window.stillnote.listGoogleTaskLists(),s=await dz(i);if(!s)return;let r=s.list,a="";if(s.create){if(a=(t=await Su("New Google Tasks list","","Create list"))==null?void 0:t.trim(),!a)return;const u=_o(a);if(u){Re(u);return}}const o=String(a||r.title||"").trim(),l=_o(o);if(l){Re(`This Google Tasks list title cannot be used as a file name: ${l}`);return}const c=[n,`${o}.md`].filter(Boolean).join("/");if(S.files.some(u=>u.toLocaleLowerCase()===c.toLocaleLowerCase())){Re("A file with this title already exists in that folder.");return}s.create&&(r=await window.stillnote.createGoogleTaskList(o));const h=await window.stillnote.createNote(o,n),d=sM(r.id);await window.stillnote.writeNote(h,hc("tasks",o,d)),[S.files,S.tree]=await Promise.all([window.stillnote.listNotes(),window.stillnote.getVaultTree()]),Ht(),await mi(h)}catch(i){Re(i.message||"Could not create a Google Tasks sheet.")}}function dz(n){if(!n.length)return Promise.resolve({create:!0});const e=document.createElement("div");e.className="rename-overlay task-list-picker";const t=n.map(s=>`<option value="${Ut(s.id)}">${Ut(s.title)}</option>`).join("");e.innerHTML=`<section class="rename-dialog" role="dialog" aria-modal="true" aria-labelledby="task-list-picker-title"><h2 id="task-list-picker-title">Choose a Google Tasks list</h2><select class="settings-input task-list-picker-select">${t}</select><div class="rename-actions"><button type="button" class="secondary-button" data-choice="cancel">Cancel</button><button type="button" class="secondary-button" data-choice="create">Create new list</button><button type="button" class="primary-button" data-choice="use">Use selected list</button></div></section>`,document.body.append(e);const i=e.querySelector("select");return i.focus(),new Promise(s=>{const r=a=>{e.remove(),s(a)};e.querySelector('[data-choice="cancel"]').addEventListener("click",()=>r(null)),e.querySelector('[data-choice="create"]').addEventListener("click",()=>r({create:!0})),e.querySelector('[data-choice="use"]').addEventListener("click",()=>r({list:n.find(a=>a.id===i.value)})),e.addEventListener("click",a=>{a.target===e&&r(null)})})}function uz(n,e=""){const t=L("#new-file-menu");t.replaceChildren();const i=[["New note",()=>Ou(e)],["New code file…",()=>oM(e)],["New canvas",()=>eo("canvas",e)],["New spreadsheet",()=>eo("spreadsheet",e)],["New graph",()=>eo("graph",e)],["New task sheet",()=>lM(e)]];for(const[r,a]of i){const o=document.createElement("button");o.className="context-action",o.textContent=r,o.addEventListener("click",()=>{t.hidden=!0,a()}),t.append(o)}const s=n.getBoundingClientRect();t.hidden=!1,t.style.left=`${Math.max(8,Math.min(s.left,window.innerWidth-205))}px`,t.style.top=`${Math.min(s.bottom+4,window.innerHeight-t.offsetHeight-8)}px`}async function QO(n=""){if(!S.vault)return qs();const e=await Su("Create folder","","Create");if(e!=null&&e.trim())try{const t=await window.stillnote.createFolder(n,e);n&&S.collapsed.delete(n),t&&S.collapsed.delete(t),[S.files,S.tree]=await Promise.all([window.stillnote.listNotes(),window.stillnote.getVaultTree()]),Ht()}catch(t){Re(t.message||"Could not create folder.")}}async function fz(){S.vault&&([S.files,S.tree]=await Promise.all([window.stillnote.listNotes(),window.stillnote.getVaultTree()]),Ht())}function Yl(n,e){return!(!n||n.path===e||n.type==="folder"&&e.startsWith(`${n.path}/`))}function zd(){var n;document.querySelectorAll(".dragging,.drop-target,.root-drop-target").forEach(e=>e.classList.remove("dragging","drop-target","root-drop-target")),(n=L("#note-list"))==null||n.classList.remove("asset-upload-target")}function Na(n){var e;return!S.draggedItem&&Array.from(((e=n.dataTransfer)==null?void 0:e.types)||[]).includes("Files")}async function cM(n,e=""){var i;n.preventDefault(),n.stopPropagation(),zd();const t=Array.from(((i=n.dataTransfer)==null?void 0:i.files)||[]);if(t.length)try{if(t.length>100)throw new Error("Upload up to 100 files at a time.");const s=t.find(o=>o.size>250*1024*1024);if(s)throw new Error(`${s.name} is larger than the 250 MB upload limit.`);const r=await Promise.all(t.map(async o=>({name:o.name,data:await o.arrayBuffer()}))),a=await window.stillnote.uploadAssets(e,r);if([S.files,S.tree]=await Promise.all([window.stillnote.listNotes(),window.stillnote.getVaultTree()]),e)for(const[o,l]of e.split("/").entries())S.collapsed.delete(e.split("/").slice(0,o+1).join("/"));Ht(),Re(`${a.length} file${a.length===1?"":"s"} added`)}catch(s){Re(s.message||"Files could not be uploaded.")}}function dy(n,e){n.draggable=!0,n.addEventListener("dragstart",t=>{S.draggedItem={path:e.path,type:e.type},t.dataTransfer.effectAllowed="move",t.dataTransfer.setData("application/x-stillnote-path",e.path),t.dataTransfer.setData("application/x-stillnote-type",e.type),n.classList.add("dragging")}),n.addEventListener("dragend",()=>{S.draggedItem=null,zd()}),n.addEventListener("dragover",t=>{Na(t)&&(t.preventDefault(),t.dataTransfer.dropEffect="copy",n.classList.add("drop-target"))}),n.addEventListener("drop",t=>{Na(t)&&cM(t,e.type==="folder"?e.path:"")}),e.type==="folder"&&(n.addEventListener("dragover",t=>{Na(t)||Yl(S.draggedItem,e.path)&&(t.preventDefault(),t.dataTransfer.dropEffect="move",n.classList.add("drop-target"))}),n.addEventListener("dragleave",()=>n.classList.remove("drop-target")),n.addEventListener("drop",t=>{if(Na(t))return;t.preventDefault(),t.stopPropagation();const i=S.draggedItem;S.draggedItem=null,zd(),Yl(i,e.path)&&hM(i,e.path)}))}L("#note-list").addEventListener("dragover",n=>{Na(n)&&(n.preventDefault(),n.dataTransfer.dropEffect="copy",L("#note-list").classList.add("asset-upload-target"))});L("#note-list").addEventListener("dragleave",n=>{L("#note-list").contains(n.relatedTarget)||L("#note-list").classList.remove("asset-upload-target")});L("#note-list").addEventListener("drop",n=>{Na(n)&&cM(n,""),L("#note-list").classList.remove("asset-upload-target")});async function hM(n,e){var t;if(!(!n||!Yl(n,e)))try{const i=S.active;await qn();const s=n.type==="note"&&i===n.path&&S.active!==n.path?S.active:n.path,r=await window.stillnote.moveEntry(s,e);let a=S.active;S.active===s?a=r:n.type==="folder"&&((t=S.active)!=null&&t.startsWith(`${s}/`))&&(a=`${r}${S.active.slice(s.length)}`);const o=new Set;for(const l of S.collapsed)l===s?o.add(r):n.type==="folder"&&l.startsWith(`${s}/`)?o.add(`${r}${l.slice(s.length)}`):o.add(l);S.collapsed=o,e&&S.collapsed.delete(e),[S.files,S.tree]=await Promise.all([window.stillnote.listNotes(),window.stillnote.getVaultTree()]),Ht(),a!==S.active&&(S.active=null,await mi(a)),Re("Item moved")}catch(i){Re(i.message||"Could not move item.")}}L(".explorer-heading").addEventListener("dragover",n=>{!S.draggedItem||!Yl(S.draggedItem,"")||(n.preventDefault(),n.dataTransfer.dropEffect="move",L(".explorer-heading").classList.add("root-drop-target"))});L(".explorer-heading").addEventListener("dragleave",()=>L(".explorer-heading").classList.remove("root-drop-target"));L(".explorer-heading").addEventListener("drop",n=>{if(!S.draggedItem||!Yl(S.draggedItem,""))return;n.preventDefault(),n.stopPropagation();const e=S.draggedItem;S.draggedItem=null,zd(),hM(e,"")});function uy(n,e){n.preventDefault(),n.stopPropagation();const t=L("#explorer-context-menu");t.replaceChildren();const i=(a,o,l=!1)=>{const c=document.createElement("button");c.className=`context-action${l?" danger":""}`,c.textContent=a,c.addEventListener("click",()=>{LO(),o()}),t.append(c)};if(e.type==="folder"){i("New note here",()=>Ou(e.path)),i("New code file here…",()=>oM(e.path)),i("New canvas here",()=>eo("canvas",e.path)),i("New spreadsheet here",()=>eo("spreadsheet",e.path)),i("New graph here",()=>eo("graph",e.path)),i("New task sheet here",()=>lM(e.path)),i("New folder here",()=>QO(e.path));const a=document.createElement("div");a.className="context-separator",t.append(a)}else i("Copy link",()=>{window.stillnote.copyFileLink(e.path).then(()=>Re("Link copied")).catch(a=>Re(a.message||"Could not copy link."))});i("Rename…",()=>gz(e)),i("Delete…",()=>Oz(e),!0),t.hidden=!1;const s=190,r=t.offsetHeight;t.style.left=`${Math.max(8,Math.min(n.clientX,window.innerWidth-s-8))}px`,t.style.top=`${Math.max(8,Math.min(n.clientY,window.innerHeight-r-8))}px`}function LO(){L("#explorer-context-menu").hidden=!0}function pz(n,e){return Su(`Rename ${e}`,n,"Rename")}function Su(n,e="",t="Create"){const i=L("#rename-overlay"),s=L("#rename-input");return L("#rename-title").textContent=n,L("#rename-form").querySelector('[type="submit"]').textContent=t,s.value=e,i.hidden=!1,requestAnimationFrame(()=>{s.focus(),e&&s.select()}),new Promise(r=>{qh=r})}function xu(n=null){if(!qh)return;const e=qh;qh=null,L("#rename-overlay").hidden=!0,e(n)}function mz(n,e){return L("#delete-title").textContent=`Delete “${n}”?`,L("#delete-description").textContent=e,L("#delete-overlay").hidden=!1,requestAnimationFrame(()=>L("#delete-confirm").focus()),new Promise(t=>{Hh=t})}function vu(n=!1){if(!Hh)return;const e=Hh;Hh=null,L("#delete-overlay").hidden=!0,e(n)}async function gz(n){var s,r;const e=S.active,t=n.type==="note"?at(n.name):n.name,i=await pz(t,n.type);if(!(!(i!=null&&i.trim())||i.trim()===t))try{await qn();const a=n.type==="note"&&e===n.path&&S.active!==n.path?S.active:n.path;if(n.type==="note"&&n.format==="tasks"){const c=kO(await window.stillnote.readNote(a));(c==null?void 0:c.type)==="tasks"&&((s=c.data)!=null&&s.listId)&&await window.stillnote.renameGoogleTaskList(c.data.listId,i.trim())}const o=await window.stillnote.renameEntry(a,i.trim());let l=S.active;S.active===a?l=o:n.type==="folder"&&((r=S.active)!=null&&r.startsWith(`${a}/`))&&(l=`${o}${S.active.slice(a.length)}`),[S.files,S.tree]=await Promise.all([window.stillnote.listNotes(),window.stillnote.getVaultTree()]),n.type==="folder"&&S.collapsed.delete(a)&&S.collapsed.add(o),Ht(),l!==S.active&&(S.active=null,await mi(l))}catch(a){Re(a.message||"Could not rename item.")}}async function Oz(n){var i,s,r,a,o,l;const e=n.type==="note"?at(n.name):n.name,t=n.type==="folder"?"This also deletes everything inside it.":"This deletes this file from the vault.";if(await mz(e,t))try{const c=S.active;await qn();const h=n.type==="note"&&c===n.path&&S.active!==n.path?S.active:n.path,d=zs(),u=n.type==="note"?[h]:d.filter(O=>O.startsWith(`${h}/`)),f=!!(S.active&&u.includes(S.active)),p=f?d.indexOf(S.active):d.indexOf(h);if(await window.stillnote.deleteEntry(h),[S.files,S.tree]=await Promise.all([window.stillnote.listNotes(),window.stillnote.getVaultTree()]),Ht(),f){(i=S.view)==null||i.destroy(),S.view=null,(a=(r=(s=S.structured)==null?void 0:s.desmos)==null?void 0:r.destroy)==null||a.call(r),S.structured=null,(l=(o=S.assetViewer)==null?void 0:o.destroy)==null||l.call(o),S.assetViewer=null,S.dirty=!1,S.active=null,await window.stillnote.rememberNote(null);const O=zs();O.length?await mi(O[Math.max(0,Math.min(p,O.length-1))]):AO()}Re(`${n.type==="folder"?"Folder":"File"} deleted`)}catch(c){Re(c.message||"Could not delete item.")}}function dM(){const n=L("#topbar-search");if(n.classList.contains("is-open")){L("#search-input").focus();return}n.classList.add("is-open"),L(".search-trigger").setAttribute("aria-expanded","true"),L("#search-input").value="",OM(""),L("#search-input").focus()}function $O(){L("#topbar-search").classList.remove("is-open"),L(".search-trigger").setAttribute("aria-expanded","false")}function uM(n){var e,t,i,s,r;S.theme=["light","sepia","dark"].includes(n)?n:"light",L(".app-shell").dataset.theme=S.theme,localStorage.setItem("stillnote-theme",S.theme),(t=(e=S.structured)==null?void 0:e.refreshCanvas)==null||t.call(e),(r=(s=(i=S.structured)==null?void 0:i.desmos)==null?void 0:s.updateSettings)==null||r.call(s,{invertedColors:!1}),document.querySelectorAll(".theme-card").forEach(a=>a.setAttribute("aria-pressed",String(a.dataset.theme===S.theme)))}function Sz(){uM(localStorage.getItem("stillnote-theme")||"light"),window.stillnote.restoreSession().then(async n=>{n&&(await jT(n),n.lastNote&&zs().includes(n.lastNote)?await mi(n.lastNote):zs().length?await mi(zs()[0]):AO())}).catch(n=>console.error("Could not restore workspace:",n))}function fM(n){document.querySelectorAll(".settings-tab").forEach(e=>e.classList.toggle("active",e.dataset.tab===n)),document.querySelectorAll(".settings-section").forEach(e=>{const t=e.dataset.section===n;e.classList.toggle("active",t),e.hidden=!t}),n==="dictionary"&&cc(),n==="tasks"&&wo(!0)}function pM(n,e){var t;if(n==="notes"){if(!["left","right","bottom","hidden"].includes(e))return;S.toolbarPositions.notes=e,localStorage.setItem("stillnote-notes-toolbar-position",e);const i=L("#note-editor");i.dataset.toolbarPosition=e;const s=!!(S.view&&!S.structured&&e!=="hidden");L("#note-format-toolbar").hidden=!s,i.classList.toggle("has-markdown-editor",s)}else{if(!["left","right","bottom"].includes(e))return;S.toolbarPositions.canvas=e,localStorage.setItem("stillnote-canvas-toolbar-position",e),((t=S.structured)==null?void 0:t.type)==="canvas"&&(document.querySelector(".canvas-editor").dataset.toolbarPosition=e)}}async function DO(){const n=L("#ai-key-status");try{const e=await window.stillnote.aiKeyStatus();n.textContent=e.vaultOpen?e.configured?"Key saved in this vault":"No key saved":"Open a vault to save keys",n.className=`key-status${e.configured?" configured":""}`,In("ai",e.configured,e.configured?"API key saved":"API key missing"),L("#save-ai-key").disabled=!e.secureStorageAvailable||!e.vaultOpen,L("#remove-ai-key").disabled=!e.vaultOpen,e.secureStorageAvailable||(n.textContent="Secure key storage is unavailable")}catch{n.textContent="Could not check key status",In("ai",!1,"Could not check API key")}}async function mM(){const n=await window.stillnote.desmosKeyStatus().catch(()=>({configured:!1,vaultOpen:!1,secureStorageAvailable:!1})),e=n.vaultOpen?n.configured?"API key saved in this vault":"API key missing":"Open a vault to save keys";In("desmos",n.configured,e),L("#save-desmos-key").disabled=!n.vaultOpen||!n.secureStorageAvailable,L("#remove-desmos-key").disabled=!n.vaultOpen}function In(n,e,t){const i=document.querySelector(`[data-health="${n}"]`);if(!i)return;i.innerHTML=e?fe.statusCheck:fe.statusX,i.classList.toggle("is-ok",!!e),i.classList.toggle("is-off",!e),i.title=t;const s=i.closest(".settings-tab"),r=s&&[...s.querySelectorAll("span:not(.settings-health-indicator)")].map(a=>a.textContent.trim()).filter(Boolean).at(-1);s&&s.setAttribute("aria-label",`${r||n}: ${t}`)}let dg=0;async function la(n="theme"){var i,s;const e=L("#settings-overlay"),t=L(".settings-modal");dg++,e.hidden=!1,xo(e,{opacity:[0,1],duration:bo(120),ease:"outQuad"}),xo(t,{opacity:[0,1],scale:[.985,1],duration:bo(150),ease:"outQuad"}),fM(n),L("#directory-name").textContent=((i=S.vault)==null?void 0:i.name)||"No folder open",L("#directory-path").textContent=((s=S.vault)==null?void 0:s.path)||"Choose a folder to see its location.",In("directory",!!S.vault,S.vault?"Folder open":"No folder open"),L("#ai-model").value=localStorage.getItem("stillnote-ai-model")||"glm-4.6",L("#desmos-api-key").value=S.vault?await window.stillnote.getDesmosKey().catch(()=>""):"",await mM(),L("#notes-toolbar-position").value=S.toolbarPositions.notes,L("#canvas-toolbar-position").value=S.toolbarPositions.canvas,syncProofreadingSettings(),DO(),IO(),wo(!0)}async function wo(n=!1){const e=L("#google-tasks-status");try{const t=await window.stillnote.googleTasksStatus();n&&(L("#google-tasks-client-id").value=t.clientId||""),L("#save-google-tasks-client").disabled=!t.secureStorageAvailable||!t.vaultOpen,L("#connect-google-tasks").disabled=!t.vaultOpen||!t.clientIdConfigured||!t.clientSecretConfigured||!t.secureStorageAvailable,L("#disconnect-google-tasks").disabled=!t.connected,t.connected?(await window.stillnote.listGoogleTaskLists(),e.textContent="Connected and responding",e.className="key-status configured",In("tasks",!0,"Google Tasks connection working")):(e.textContent=t.vaultOpen?t.clientIdConfigured?t.clientSecretConfigured?"Not connected":"Client secret needed":"Client ID needed":"Open a vault to save credentials",e.className="key-status",In("tasks",!1,t.vaultOpen?t.clientIdConfigured?t.clientSecretConfigured?"Google account not connected":"Client secret missing":"Client ID missing":"Open a vault first")),t.secureStorageAvailable||(e.textContent="Secure storage is unavailable")}catch(t){e.textContent=t.message||"Could not check Google Tasks",e.className="key-status error",L("#disconnect-google-tasks").disabled=!1,In("tasks",!1,"Google Tasks connection not working")}}async function IO(){const n=L("#ai-model"),e=L("#ai-model-status"),t=localStorage.getItem("stillnote-ai-model")||"glm-4.6";n.disabled=!0,e.textContent="Loading available models…";try{const i=await window.stillnote.listAiModels();In("ai",!0,"AI API key working");const s=[...new Set([t,...i].filter(Boolean))];n.replaceChildren(...s.map(r=>{const a=document.createElement("option");return a.value=r,a.textContent=r,a})),n.value=s.includes(t)?t:i[0]||t,localStorage.setItem("stillnote-ai-model",n.value),e.textContent=i.length?`${i.length} models available from Ollama Cloud.`:"No models were returned for this account."}catch(i){In("ai",!1,"AI API key not working");const s=document.createElement("option");s.value=t,s.textContent=`${t} (saved selection)`,n.replaceChildren(s),n.value=t,e.textContent=i.message||"Save a valid API key to load available models."}finally{n.disabled=!1}}function UO(){const n=L("#settings-overlay"),e=L(".settings-modal"),t=++dg;xo(e,{opacity:[1,0],scale:[1,.99],duration:bo(90),ease:"inQuad"}),xo(n,{opacity:[1,0],duration:bo(100),ease:"inQuad",onComplete:()=>{t===dg&&(n.hidden=!0,n.style.opacity="",e.style.opacity="",e.style.transform="")}})}function xh(){L("#assistant-messages").innerHTML='<div class="assistant-welcome"><div class="assistant-welcome-icon">'+fe.assistant+"</div><strong>What would you like to do?</strong><p>Ask a question about this note, or ask me to edit it.</p></div>"}function Bd(n){n&&S.home||(S.assistantOpen=n,L(".workspace").classList.toggle("assistant-open",n),L("#assistant-toggle").setAttribute("aria-pressed",String(n)),n&&L("#assistant-input").focus())}function xz(){const n=L(".workspace"),e=L("#sidebar-resizer"),t=L("#assistant-resizer"),i=()=>{n.style.setProperty("--sidebar-width",`${S.sidebarWidth}px`),n.style.setProperty("--assistant-width",`${S.assistantWidth}px`),e.setAttribute("aria-valuenow",String(S.sidebarWidth)),t.setAttribute("aria-valuenow",String(S.assistantWidth))},s=(a,o)=>{const l=n.getBoundingClientRect();if(a==="explorer"){const c=Math.max(190,Math.min(440,l.width-(S.assistantOpen?S.assistantWidth:0)-340));S.sidebarWidth=Math.max(190,Math.min(c,o-l.left))}else{const c=S.sidebarOpen?S.sidebarWidth:0,h=Math.max(280,Math.min(560,l.width-c-340));S.assistantWidth=Math.max(280,Math.min(h,l.right-o))}i()};let r=null;for(const[a,o]of[[e,"explorer"],[t,"assistant"]])a.addEventListener("pointerdown",l=>{var c;l.button===0&&(l.preventDefault(),r=o,a.classList.add("is-active"),document.body.classList.add("resizing-panels"),(c=a.setPointerCapture)==null||c.call(a,l.pointerId))}),a.addEventListener("keydown",l=>{if(!["ArrowLeft","ArrowRight"].includes(l.key))return;l.preventDefault();const c=l.shiftKey?40:16,h=l.key==="ArrowRight"?c:-c,d=n.getBoundingClientRect(),u=o==="explorer"?d.left+S.sidebarWidth+h:d.right-S.assistantWidth-h;s(o,u)});window.addEventListener("pointermove",a=>{r&&s(r,a.clientX)}),window.addEventListener("pointerup",()=>{r&&(r=null,document.body.classList.remove("resizing-panels"),e.classList.remove("is-active"),t.classList.remove("is-active"),localStorage.setItem("stillnote-sidebar-width",String(S.sidebarWidth)),localStorage.setItem("stillnote-assistant-width",String(S.assistantWidth)))}),i()}function Ds(n,e){const t=document.createElement("div");return t.className=`chat-bubble ${n}`,t.textContent=e,L("#assistant-messages").append(t),L("#assistant-messages").scrollTop=L("#assistant-messages").scrollHeight,t}function xl(){var n;return S.structured?hc(S.structured.type,S.structured.title||at(S.active),S.structured.data):((n=S.view)==null?void 0:n.state.doc.toString())||""}function hr(){var i,s;const n=document.querySelector('.assistant-mode[data-mode="edit"]'),e=((i=S.structured)==null?void 0:i.type)==="tasks",t=(s=S.active)==null?void 0:s.toLowerCase().endsWith(".pdf");n&&(n.disabled=!!t,n.title=t?"PDF files are read-only":""),t&&S.assistantMode==="edit"&&(S.assistantMode="ask",document.querySelectorAll(".assistant-mode").forEach(r=>r.classList.toggle("active",r.dataset.mode==="ask"))),n&&(n.textContent=e?"Add tasks":"Edit note"),L("#assistant-input").placeholder=t?"Ask about this PDF…":S.assistantMode==="edit"?e?"Describe tasks to add…":`Describe a change to this ${Fd(S.active||"")?"code file":"note"}…`:e?"Ask about this task sheet…":`Ask about this ${Fd(S.active||"")?"code file":"note"}…`}async function vz(n,e,t){const i=S.structured;if(!i||i.type!=="tasks"||S.active!==e||xl()!==t)throw new Error("The task sheet changed while Ollama was working. Please try again.");if(!Array.isArray(n)||!n.length)return 0;if(n.length>30)throw new Error("Ollama returned too many tasks to add at once.");const s=n.map(o=>{const l=String((o==null?void 0:o.title)||"").trim(),c=String((o==null?void 0:o.notes)||"").trim(),h=String((o==null?void 0:o.due)||"").trim(),d=String((o==null?void 0:o.parentTitle)||"").trim();if(!l||l.length>1024)throw new Error("Ollama returned a task with an invalid title.");if(c.length>8192)throw new Error(`Details for “${l}” are too long.`);if(h&&(!/^\d{4}-\d{2}-\d{2}$/.test(h)||Number.isNaN(Date.parse(`${h}T00:00:00Z`))))throw new Error(`Ollama returned an invalid due date for “${l}”.`);return{title:l,notes:c,due:h,parentTitle:d}}),r=new Map(i.data.tasks.map(o=>[o.title.toLocaleLowerCase(),o]));let a=0;try{for(const o of s){if(S.structured!==i||S.active!==e)throw new Error("The task sheet was closed before all tasks were added.");const l=o.parentTitle?r.get(o.parentTitle.toLocaleLowerCase()):null;if(o.parentTitle&&!l)throw new Error(`Could not find parent task “${o.parentTitle}”. Add parent tasks before their subtasks.`);const c=await window.stillnote.createGoogleTask(i.data.listId,o.title,l==null?void 0:l.id);if(S.structured!==i||S.active!==e)throw new Error(`Added “${c.title||o.title}” to Google Tasks, but the task sheet was closed before Stillnote could refresh.`);const h={id:c.id,title:c.title||o.title,status:c.status||"needsAction",due:c.due||null,notes:c.notes||"",parent:c.parent||(l==null?void 0:l.id)||null,starred:!1};if(i.data.tasks.push(h),r.set(h.title.toLocaleLowerCase(),h),a++,o.notes||o.due){const d={};o.notes&&(d.notes=o.notes),o.due&&(d.due=`${o.due}T00:00:00.000Z`);try{const u=await window.stillnote.updateGoogleTask(i.data.listId,h.id,d);if(S.structured!==i||S.active!==e)throw new Error("The task sheet was closed before the task details could be updated.");h.notes=u.notes||o.notes,h.due=u.due||(o.due?`${o.due}T00:00:00.000Z`:null)}catch(u){throw new Error(`Added “${h.title}”, but its details could not be saved: ${u.message}`)}}Ct()}}catch(o){throw a&&S.structured===i&&S.active===e&&(Ct(),Hl("tasks",i.data,e,i.title||at(e))),o}return Hl("tasks",i.data,e,i.title||at(e)),a}function yz(n,e,t,i){var c;if(S.active!==t||xl()!==i)return Ds("assistant error","The document changed while I was working, so I did not apply the edit. Please send the request again."),!1;let s=e;const r=((c=S.structured)==null?void 0:c.type)||null;if(r){const h=kO(e);if(!h||h.type!==r)return Ds("assistant error",`The assistant returned invalid ${r} data, so I did not apply the edit.`),!1;const d=S.structured;d.data=h.data,Ct();const u={undoStack:d.undoStack,redoStack:d.redoStack,historySnapshot:d.historySnapshot,historyPending:d.historyPending,historyTimer:d.historyTimer};Hl(r,d.data,t,d.title||at(t)),Object.assign(S.structured,u),gu(),s=xl()}else{if(!S.view)return Ds("assistant error","The note is no longer open, so I did not apply the edit."),!1;S.view.dispatch({changes:{from:0,to:S.view.state.doc.length,insert:s}}),S.view.focus()}const a=document.createElement("p");a.textContent="I updated the document.",n.append(a);const o=document.createElement("button");o.className="undo-ai-edit-button",o.type="button",o.textContent="Undo changes";let l=!0;return o.addEventListener("click",()=>{if(S.active!==t){Re("Open the edited document to undo or redo this change.");return}const h=l?s:i;if(xl()!==h){Re("The document has changed since the AI edit; undo was not applied.");return}if(r)ia(l?"undo":"redo");else{if(!S.view){Re("Open the edited document to undo or redo this change.");return}S.view.dispatch({changes:{from:0,to:S.view.state.doc.length,insert:l?i:s}}),S.view.focus()}l=!l,o.textContent=l?"Undo changes":"Redo changes"}),n.append(o),L("#assistant-messages").scrollTop=L("#assistant-messages").scrollHeight,!0}async function bz(n){var h;n.preventDefault();const e=L("#assistant-input").value.trim();if(!e)return;const t=S.active,i=!!(t!=null&&t.toLowerCase().endsWith(".pdf"));if(!t||!S.view&&!S.structured&&!i){Re("Open a note, code file, PDF, canvas, spreadsheet, or graph before using the assistant.");return}let s;try{s=await window.stillnote.aiKeyStatus()}catch(d){Re(d.message||"Could not check Ollama key status.");return}if(!s.configured){la("ai");return}const r=i?"ask":S.assistantMode,a=i?"pdf":((h=S.structured)==null?void 0:h.type)||(Fd(t)?"code":"markdown"),o=L("#ai-model").value.trim()||localStorage.getItem("stillnote-ai-model")||"glm-4.6";localStorage.setItem("stillnote-ai-model",o);const l=L(".assistant-welcome");l&&l.remove(),Ds("user",e);const c=Ds("assistant loading","Thinking…");L("#assistant-input").value="",L("#assistant-send").disabled=!0;try{const d=i?await KX(t):xl();if(S.active!==t)throw new Error("The active file changed before the assistant request started. Please send it again.");const u=await window.stillnote.askAi({mode:r,model:o,noteName:at(t),documentType:a,document:d,prompt:e,history:S.chatHistory});if(c.remove(),a==="tasks"&&u.kind==="tasks"){const f=await vz(u.tasks,t,d),p=f?`Added ${f} ${f===1?"task":"tasks"} to Google Tasks.`:"No tasks were added.";Ds("assistant",p),S.chatHistory.push({role:"user",content:e},{role:"assistant",content:p})}else if(r==="edit"&&u.kind==="edit"){const f=document.createElement("div");f.className="chat-bubble assistant",L("#assistant-messages").append(f),yz(f,u.text,t,d)?S.chatHistory.push({role:"user",content:e},{role:"assistant",content:"Applied the requested changes to the document."}):f.remove()}else Ds("assistant",u.text),S.chatHistory.push({role:"user",content:e},{role:"assistant",content:u.text});S.chatHistory=S.chatHistory.slice(-8)}catch(d){c.remove(),Ds("assistant error",d.message||"The assistant could not respond.")}finally{L("#assistant-send").disabled=!1}}let fi=!1,NO=0,ug=null,zi="",gn=null,fg=null,To=Promise.resolve(),pg=Promise.resolve(),es=null,_z=0;const ol=new Map;let Fa=null,Ti=null,vl=null,ur=null,yl=[],bl=0,to=0,Mo=Promise.resolve();function ui(n,e=fi){const t=L("#meeting-notes-trigger");t.title=n,t.setAttribute("aria-label",n),t.classList.toggle("is-recording",e),t.classList.toggle("has-transcript",!!(gn&&zi.trim())&&!e),t.setAttribute("aria-pressed",String(e))}function fy(){const n=Math.max(0,Math.floor((Date.now()-NO)/1e3)),e=String(Math.floor(n/60)).padStart(2,"0"),t=String(n%60).padStart(2,"0");L("#meeting-notes-trigger .meeting-duration").textContent=`${e}:${t}`}function yu(){clearInterval(ug),ug=null,NO=0,L("#meeting-notes-trigger .meeting-duration").hidden=!0}function wz(){if(!gn)return;const n=gn,e=zi;To=To.catch(()=>{}).then(()=>window.stillnote.writeMeetingTranscript(n,e))}async function Vd(){const n=gn;gn=null,n&&(await Mo.catch(()=>{}),await To.catch(()=>{}),await window.stillnote.clearMeetingTranscript(n).catch(()=>{})),zi="",ui("Click to start recording",!1)}function FO(){yu(),fi&&(fi=!1,to++,bu(!1)),gn&&Vd()}function Tz(){return es||(es=new Worker(new URL(""+new URL("whisper-worker-DcYN39bN.js",import.meta.url).href,import.meta.url),{type:"module"}),es.addEventListener("message",({data:n})=>{var t;const e=ol.get(n.id);if(n.type==="progress"){if(fi){const i=Number.isFinite((t=n.progress)==null?void 0:t.progress)?` ${Math.round(n.progress.progress)}%`:"";ui(`Downloading local Whisper model${i}…`)}return}e&&(ol.delete(n.id),n.type==="result"?e.resolve(n.text):e.reject(new Error(n.message||"Local Whisper could not transcribe this audio.")))}),es.addEventListener("error",n=>{const e=new Error(n.message||"The local Whisper worker stopped unexpectedly.");for(const t of ol.values())t.reject(e);ol.clear(),es==null||es.terminate(),es=null}),es)}function Mz(n){const e=Tz(),t=++_z,i=n.slice();return new Promise((s,r)=>{ol.set(t,{resolve:s,reject:r}),e.postMessage({type:"transcribe",id:t,audio:i.buffer},[i.buffer])})}function Pz(n,e){const i=e/16e3,s=new Float32Array(Math.floor(n.length/i));for(let r=0;r<s.length;r++){const a=r*i,o=Math.floor(a),l=a-o;s[r]=n[o]*(1-l)+(n[Math.min(o+1,n.length-1)]||0)*l}return s}function Ez(n,e){const t=Pz(n,(Ti==null?void 0:Ti.sampleRate)||48e3);let i=0;for(let s=0;s<t.length;s+=16)i+=t[s]*t[s];!t.length||Math.sqrt(i/Math.ceil(t.length/16))<.004||(Mo=Mo.then(async()=>{if(e!==to||!gn)return;fi&&ui("Transcribing locally with Whisper Small…");const s=await Mz(t);e!==to||!gn||!s||(zi=`${zi} ${s}`.trim(),wz(),fi&&ui("Recording locally with Whisper Small…"))}).catch(s=>{if(e!==to)return;fi=!1,yu(),bu(!1);const r=`Local Whisper stopped: ${s.message}`;ui(r,!1),Re(r)}))}function gM(n=!1){if(!yl.length||!Ti)return;const e=Ti.sampleRate;if(!n&&bl<e*30)return;const t=new Float32Array(bl);let i=0;for(const s of yl)t.set(s,i),i+=s.length;yl=[],bl=0,Ez(t,to)}async function bu(n){if(n&&gM(!0),ur){ur.onaudioprocess=null;try{ur.disconnect()}catch{}}if(vl)try{vl.disconnect()}catch{}Fa==null||Fa.getTracks().forEach(t=>t.stop());const e=Ti;ur=null,vl=null,Fa=null,Ti=null,e&&e.state!=="closed"&&await e.close().catch(()=>{})}async function Az(){Fa=await navigator.mediaDevices.getUserMedia({audio:{channelCount:1,echoCancellation:!0,noiseSuppression:!0},video:!1}),Ti=new AudioContext,await Ti.resume(),vl=Ti.createMediaStreamSource(Fa),ur=Ti.createScriptProcessor(4096,1,1),ur.onaudioprocess=n=>{if(n.outputBuffer.getChannelData(0).fill(0),!fi)return;const e=n.inputBuffer.getChannelData(0).slice();yl.push(e),bl+=e.length,gM()},vl.connect(ur),ur.connect(Ti.destination)}async function kz(){try{to++,yl=[],bl=0,zi="",fg=null,gn=await window.stillnote.createMeetingTranscript(),To=Promise.resolve(),Mo=Promise.resolve(),fi=!0,await Az(),NO=Date.now(),fy(),L("#meeting-notes-trigger .meeting-duration").hidden=!1,ug=setInterval(fy,250),ui("Recording locally; click when finished to create a summary and save the transcript. Whisper Small downloads on first use.")}catch(n){fi=!1,yu(),await bu(!1);const e=gn;gn=null,e&&window.stillnote.clearMeetingTranscript(e).catch(()=>{}),ui(n.message||"Could not start recording",!1),Re(n.message||"Could not start recording.")}}function Cz(){return fi?(fi=!1,yu(),ui("Finishing transcription and creating summary…",!1),pg=(async()=>{try{await bu(!0),await Mo,await To,gn&&(zi=await window.stillnote.readMeetingTranscript(gn))}catch(n){Re(n.message||"Could not finish the local transcript.")}return Rz(),{transcript:zi,id:gn}})(),pg):(async()=>(await Mo,await To,gn&&(zi=await window.stillnote.readMeetingTranscript(gn)),{transcript:zi,id:gn}))()}async function Rz(){const n=zi.trim();if(!n){ui("No speech was captured; click to record again",!1),Vd();return}if(!S.view||!S.active||S.home){ui("Open a note to insert meeting notes",!1);return}const e=S.active,t=S.view.state.doc.toString(),i=L("#ai-model").value.trim()||localStorage.getItem("stillnote-ai-model")||"glm-4.6";try{const s=e.includes("/")?e.slice(0,e.lastIndexOf("/")):"",r=at(e).replace(/\.md$/i,""),a=new Date().toLocaleString([],{year:"numeric",month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"}).replace(/[/:]/g,"-"),o=`${r} transcript ${a}`,l=await window.stillnote.createNote(o,s);if(await window.stillnote.writeNote(l,`${at(l)}
|
|
4474
|
+
`}function kO(n){const e=n.match(/<!--\s*stillnote:type=(canvas|spreadsheet|graph|tasks)\s*-->[\s\S]*?```stillnote-\1\s*\n([\s\S]*?)\n```/);if(!e)return null;try{return{type:e[1],data:JSON.parse(e[2])}}catch{return{type:e[1],data:null}}}function tM(){return{version:1,width:1200,height:760,elements:[]}}function nM(){return{version:1,columns:8,rows:20,cells:{}}}function iM(){return{version:1,state:null}}function sM(n){return{version:1,listId:n,tasks:[]}}let Ko=null,cy=null;function rz(n){var t;if(!n)return Promise.reject(new Error("Add a Desmos API key in Settings → Graphing to open this graph."));if((t=window.Desmos)!=null&&t.GraphingCalculator&&cy===n)return Promise.resolve(window.Desmos);if((Ko==null?void 0:Ko.key)===n)return Ko.promise;const e=new Promise((i,s)=>{const r=document.createElement("script");r.src=`https://www.desmos.com/api/v1.11/calculator.js?apiKey=${encodeURIComponent(n)}`,r.async=!0,r.onload=()=>{var a;if(!((a=window.Desmos)!=null&&a.GraphingCalculator)){s(new Error("Desmos loaded without its Graphing Calculator API."));return}cy=n,i(window.Desmos)},r.onerror=()=>s(new Error("Could not load Desmos. Check your internet connection and API key.")),document.head.append(r)});return Ko={key:n,promise:e},e}function cg(n){CO(String(n||"").split("|")[0].trim())}async function CO(n){const e=String(n||"").trim(),t=e.indexOf("#"),i=t<0?e:e.slice(0,t).trim(),s=t<0?"":e.slice(t+1).trim(),r=i?RO(i):S.active;if(!r){Re(`No file found for “${i||e}”.`);return}if((r!==S.active||!S.view)&&await mi(r),s&&S.view&&S.active===r){const a=az(S.view,s);a==null?Re(`No heading or tag “${s}” found in ${at(r)}.`):qT(S.view,a)}}function Sh(n){return String(n||"").toLocaleLowerCase().replace(/<[^>]*>/g,"").replace(/[`*_~]/g,"").trim().replace(/[^\p{L}\p{N}\s-]/gu,"").replace(/\s+/g,"-").replace(/-+/g,"-")}function az(n,e){let t=e;try{t=decodeURIComponent(e.replace(/\+/g," "))}catch{}const i=Sh(t),s=n.state.doc;let r=!1,a="",o=0,l=new Map;for(let u=1;u<=s.lines;u++){const f=s.line(u),p=f.text,O=p.match(/^\s{0,3}(`{3,}|~{3,})/);if(O){r?O[1][0]===a&&O[1].length>=o&&(r=!1):(r=!0,a=O[1][0],o=O[1].length);continue}if(r)continue;const g=p.match(/^\s{0,3}#{1,6}\s+(.+?)\s*#*\s*$/);if(g){const m=Sh(g[1]),y=l.get(m)||0;if(l.set(m,y+1),(y?`${m}-${y}`:m)===i||m===i)return f.from}if(/^\s*#/.test(p)&&Sh(p.replace(/^\s*#+\s*/,""))===i)return f.from;if(u<s.lines&&p.trim()&&/^\s*(?:=+|-+)\s*$/.test(s.line(u+1).text)){const m=Sh(p.trim()),y=l.get(m)||0;if(l.set(m,y+1),m===i||y&&`${m}-${y}`===i)return f.from}}const h=`#${t.replace(/^#/,"")}`.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),d=new RegExp(`(^|[^\\p{L}\\p{N}_])${h}(?=$|[^\\p{L}\\p{N}_])`,"iu").exec(s.toString());return d?d.index+d[1].length:null}function RO(n){const e=String(n||"").trim().replace(/\\/g,"/").replace(/^\.\//,"").toLocaleLowerCase();if(!e)return null;const t=zs(),i=t.find(o=>o.toLocaleLowerCase()===e);if(i)return i;const s=o=>o.replace(/\.[^./]+$/,"");if(!/\.[^/]+$/.test(e)){const o=t.find(l=>l.toLocaleLowerCase()===`${e}.md`);if(o)return o}const r=t.filter(o=>s(o.toLocaleLowerCase())===s(e));if(r.length===1)return r[0];if(r.length>1)return r.find(o=>o.toLocaleLowerCase().endsWith(".md"))||null;if(e.includes("/"))return null;const a=t.filter(o=>{const l=o.split("/").at(-1).toLocaleLowerCase();return l===e||s(l)===s(e)});return a.length===1?a[0]:a.length>1&&a.find(o=>o.toLocaleLowerCase().endsWith(".md"))||null}function Ct(){const n=S.structured;if(n&&n.type!=="tasks"){const e=JSON.stringify({title:n.title||at(S.active),data:n.data});e!==n.historySnapshot&&(n.historyPending||(n.undoStack.push(n.historySnapshot),n.undoStack.length>100&&n.undoStack.shift(),n.redoStack=[],n.historyPending=!0),n.historySnapshot=e,clearTimeout(n.historyTimer),n.historyTimer=setTimeout(()=>{n.historyPending=!1},600)),gu()}S.dirty=!0,L("#save-state").textContent="Unsaved changes",clearTimeout(S.saveTimer),S.saveTimer=setTimeout(qn,450)}function gu(){const n=S.structured;n&&(document.querySelectorAll('[data-history="undo"]').forEach(e=>e.disabled=!n.undoStack.length),document.querySelectorAll('[data-history="redo"]').forEach(e=>e.disabled=!n.redoStack.length))}async function ia(n){const e=S.structured;if(!e)return;const t=n==="undo"?e.undoStack:e.redoStack,i=n==="undo"?e.redoStack:e.undoStack;if(!t.length)return;clearTimeout(e.historyTimer),e.historyPending=!1,i.push(JSON.stringify({title:e.title||at(S.active),data:e.data}));const s=t.pop(),r=JSON.parse(s),a=e.type,o={undoStack:e.undoStack,redoStack:e.redoStack};e.data=r.data,e.title=r.title,e.historySnapshot=s;let l=S.active;if(r.title&&r.title!==at(l))try{l=await window.stillnote.renameEntry(l,r.title),S.active=l,[S.files,S.tree]=await Promise.all([window.stillnote.listNotes(),window.stillnote.getVaultTree()]),Ht(),Ja(l),window.stillnote.rememberNote(l).catch(()=>{})}catch(c){Re(`Could not restore the file name: ${c.message}`)}Hl(a,r.data,l,r.title||at(l)),Object.assign(S.structured,o,{historySnapshot:s,historyPending:!1}),S.dirty=!0,L("#save-state").textContent="Unsaved changes",clearTimeout(S.saveTimer),S.saveTimer=setTimeout(qn,250),gu()}function Hl(n,e,t,i){var l,c,h,d,u;FO(),L("#meeting-notes-trigger").hidden=!0,(c=(l=S.structured)==null?void 0:l.cleanup)==null||c.call(l);const s=e&&typeof e=="object"?e:n==="canvas"?tM():n==="graph"?iM():n==="tasks"?sM(""):nM();(u=(d=(h=S.structured)==null?void 0:h.desmos)==null?void 0:d.destroy)==null||u.call(d),S.structured={type:n,data:s,title:i,file:t,undoStack:[],redoStack:[],historySnapshot:JSON.stringify({title:i,data:s}),historyPending:!1},hr();const r=L("#editor-content");r.replaceChildren();const a=document.createElement("section");a.className=`structured-editor ${n}-editor`,n==="canvas"&&(a.dataset.toolbarPosition=S.toolbarPositions.canvas),a.innerHTML='<div class="structured-title" contenteditable="true" role="textbox" aria-label="File title" spellcheck="false"></div><div class="structured-toolbar"></div><div class="structured-surface"></div>';const o=a.querySelector(".structured-title");return o.textContent=i,o.addEventListener("input",()=>{S.structured.title=o.textContent.trim(),Ct()}),o.addEventListener("blur",()=>{const f=o.textContent.trim(),p=_o(f);if(p){Re(p),o.textContent=at(S.active);return}const O=S.active,g=S.structured;if(f&&f!==at(O)){const m=(async()=>{try{if(S.active!==O||S.structured!==g||(g.type==="tasks"&&await window.stillnote.renameGoogleTaskList(g.data.listId,f),S.active!==O||S.structured!==g))return;const y=await window.stillnote.renameEntry(O,f);if(S.active!==O||S.structured!==g||(S.active=y,[S.files,S.tree]=await Promise.all([window.stillnote.listNotes(),window.stillnote.getVaultTree()]),S.active!==y||S.structured!==g))return;Ht(),Ja(y),Ct()}catch(y){S.structured===g&&(Re(`Could not rename file: ${y.message}`),o.textContent=at(O),g.type==="tasks"&&(g.title=at(O),await window.stillnote.renameGoogleTaskList(g.data.listId,at(O)).catch(()=>{}),Ct()))}})();return S.pendingStructuredRename=m,m.finally(()=>{S.pendingStructuredRename===m&&(S.pendingStructuredRename=null)}),m}}),r.append(a),n==="canvas"?oz(a,s):n==="graph"?rM(a,s):n==="tasks"?hz(a,s):lz(a,s),gu(),a}function Ja(n){L("#breadcrumbs").innerHTML=`<span>${Ut(S.vault.name)}</span><span class="crumb-slash">/</span><strong>${Ut(n.split("/").map(at).join(" / "))}</strong>`,L(".location-note").textContent=at(n)}function oz(n,e){const t=n.querySelector(".structured-toolbar"),i=[["red","#d94d48"],["yellow","#d9ae23"],["green","#348562"],["blue","#397dc2"],["black","#20211e"]];t.innerHTML=`<div class="canvas-tool-group" role="toolbar" aria-label="Canvas tools">${[["select","Select and move",fe.cursor],["draw","Pen tool",fe.draw],["shape","Shape tool",fe.shape],["line","Line tool",fe.line],["text","Insert text",fe.text]].map(([E,M,R])=>`<button class="canvas-tool${E==="select"?" active":""}" data-tool="${E}" title="${M}" aria-label="${M}" aria-pressed="${E==="select"}">${R}</button>`).join("")}<span class="canvas-tool-divider"></span><button class="canvas-tool" data-action="rotate" title="Rotate selected 15° clockwise" aria-label="Rotate selected 15 degrees clockwise">${fe.rotate}</button><button class="canvas-tool canvas-delete" data-tool="delete" title="Delete selected" aria-label="Delete selected">${fe.trash}</button><span class="canvas-tool-divider"></span><button class="canvas-tool" data-history="undo" title="Undo (⌘Z)" aria-label="Undo">${fe.undo}</button><button class="canvas-tool" data-history="redo" title="Redo (⌘⇧Z)" aria-label="Redo">${fe.redo}</button></div>`;const s=n.querySelector(".structured-surface");s.innerHTML=`<svg class="canvas-svg" viewBox="0 0 ${e.width||1200} ${e.height||760}" style="width:${e.width||1200}px;height:${e.height||760}px;max-width:none" role="img" aria-label="Drawing canvas" xmlns="http://www.w3.org/2000/svg"></svg>`;const r=s.querySelector("svg"),a=document.createElement("div");a.className="canvas-color-palette",a.setAttribute("role","group"),a.setAttribute("aria-label","Selected item colors"),a.innerHTML=i.map(([E,M])=>`<button class="canvas-color-swatch" data-color="${M}" style="--swatch:${M}" title="${E[0].toUpperCase()+E.slice(1)}" aria-label="${E[0].toUpperCase()+E.slice(1)} color" aria-pressed="false"><svg viewBox="0 0 16 16" aria-hidden="true"><path d="m3 8 3.2 3.2L13 4.8"/></svg></button>`).join(""),s.append(a);const o=document.createElement("div");o.className="canvas-shape-menu",o.setAttribute("role","group"),o.setAttribute("aria-label","Shape options"),o.innerHTML=`<div class="canvas-shape-options">${[["rectangle","Rectangle",fe.rectangle],["ellipse","Ellipse",fe.ellipse],["triangle","Triangle",fe.triangle],["star","Star",fe.star],["speech","Speech bubble",fe.speech]].map(([E,M,R])=>`<button type="button" data-shape="${E}" title="${M}" aria-label="${M}" aria-pressed="false">${R}</button>`).join("")}</div><label class="canvas-star-points" hidden>Points <select aria-label="Star points">${Array.from({length:9},(E,M)=>`<option value="${M+4}"${M===1?" selected":""}>${M+4}</option>`).join("")}</select></label>`,s.append(o);const l=document.createElement("div");l.className="canvas-line-menu",l.setAttribute("role","group"),l.setAttribute("aria-label","Line endpoint styles"),l.innerHTML=`${[["start","Start"],["end","End"]].map(([E,M])=>`<div class="canvas-endpoint-menu" data-endpoint-menu="${E}" role="group" aria-label="${M} endpoint style">${[["none","None",fe.markerNone],["arrow","Arrow",fe.markerArrow],["circle","Circle",fe.markerCircle],["square","Square",fe.markerSquare],["diamond","Diamond",fe.markerDiamond]].map(([R,N,Q])=>`<button type="button" data-endpoint="${E}" data-style="${R}" title="${M}: ${N}" aria-label="${M}: ${N}" aria-pressed="false">${Q}</button>`).join("")}</div>`).join("")}`,s.append(l);const c=document.createElement("div");c.className="canvas-tool-help",c.setAttribute("aria-live","polite"),n.append(c);let h="select",d=new Set,u=null,f=null,p=null,O="#20211e";const g=E=>{const M=String(E||O).toLowerCase();return S.theme==="dark"&&["#20211e","#353630","#373832","#000","#000000"].includes(M)?"#ffffff":E||O},m=E=>{if(E.type==="stroke"){const M=E.points.map(A=>A.x),R=E.points.map(A=>A.y),N=Math.min(...M),Q=Math.min(...R);return{x:N,y:Q,w:Math.max(1,Math.max(...M)-N),h:Math.max(1,Math.max(...R)-Q)}}return E.type==="line"?{x:Math.min(E.x1,E.x2),y:Math.min(E.y1,E.y2),w:Math.max(1,Math.abs(E.x2-E.x1)),h:Math.max(1,Math.abs(E.y2-E.y1))}:E.type==="text"?{x:E.x,y:E.y,w:Math.max(40,E.w||220),h:Math.max(30,E.h||60)}:{x:Math.min(E.x,E.x+E.w),y:Math.min(E.y,E.y+E.h),w:Math.max(1,Math.abs(E.w)),h:Math.max(1,Math.abs(E.h))}},y=E=>{const M=[...E].map(F=>m(e.elements[F])).filter(Boolean);if(!M.length)return null;const R=Math.min(...M.map(F=>F.x)),N=Math.min(...M.map(F=>F.y)),Q=Math.max(...M.map(F=>F.x+F.w)),A=Math.max(...M.map(F=>F.y+F.h));return{x:R,y:N,w:Q-R,h:A-N}},T=(E,M,R,N)=>({x:R.x+(E-R.x)*Math.cos(N)-(M-R.y)*Math.sin(N),y:R.y+(E-R.x)*Math.sin(N)+(M-R.y)*Math.cos(N)}),w=E=>{const M=y(d);if(!M)return;const R={x:M.x+M.w/2,y:M.y+M.h/2},N=E*Math.PI/180;for(const Q of d){const A=e.elements[Q];if(A.type==="stroke")A.points=A.points.map(F=>T(F.x,F.y,R,N));else if(A.type==="line"){const F=T(A.x1,A.y1,R,N),U=T(A.x2,A.y2,R,N);A.x1=F.x,A.y1=F.y,A.x2=U.x,A.y2=U.y}else{const F=m(A),U=T(F.x+F.w/2,F.y+F.h/2,R,N);A.x=U.x-F.w/2,A.y=U.y-F.h/2,A.rotation=((A.rotation||0)+E)%360}}_(),Ct()},_=()=>{r.replaceChildren(),e.elements.forEach((A,F)=>{let U;if(A.type==="stroke")U=document.createElementNS("http://www.w3.org/2000/svg","polyline"),U.setAttribute("points",A.points.map(I=>`${I.x},${I.y}`).join(" ")),U.setAttribute("fill","none"),U.setAttribute("stroke",g(A.color)),U.setAttribute("stroke-width","3"),U.setAttribute("stroke-linecap","round"),U.setAttribute("stroke-linejoin","round");else if(A.type==="line"){U=document.createElementNS("http://www.w3.org/2000/svg","g");const I=document.createElementNS("http://www.w3.org/2000/svg","line");I.setAttribute("x1",A.x1),I.setAttribute("y1",A.y1),I.setAttribute("x2",A.x2),I.setAttribute("y2",A.y2),I.setAttribute("stroke",g(A.color)),I.setAttribute("stroke-width","3"),I.setAttribute("stroke-linecap","round"),U.append(I);const z=A.x2-A.x1,W=A.y2-A.y1,oe=Math.hypot(z,W)||1;for(const[he,we,de,ve,j]of[["start",A.x1,A.y1,A.startMarker||"none",-1],["end",A.x2,A.y2,A.endMarker||"arrow",1]]){if(ve==="none")continue;const K=z/oe*j,ae=W/oe*j;if(ve==="circle"){const ge=document.createElementNS("http://www.w3.org/2000/svg","circle");ge.setAttribute("cx",we),ge.setAttribute("cy",de),ge.setAttribute("r",5),ge.setAttribute("fill",g(A.color)),U.append(ge)}else if(ve==="square"){const ge=document.createElementNS("http://www.w3.org/2000/svg","rect");ge.setAttribute("x",we-4),ge.setAttribute("y",de-4),ge.setAttribute("width",8),ge.setAttribute("height",8),ge.setAttribute("fill",g(A.color)),U.append(ge)}else if(ve==="diamond"){const ge=document.createElementNS("http://www.w3.org/2000/svg","polygon");ge.setAttribute("points",`${we},${de-5} ${we+5},${de} ${we},${de+5} ${we-5},${de}`),ge.setAttribute("fill",g(A.color)),U.append(ge)}else{const ge=we-K*12,Oe=de-ae*12,Ge=-ae*5,_t=K*5,He=document.createElementNS("http://www.w3.org/2000/svg","polygon");He.setAttribute("points",`${we},${de} ${ge+Ge},${Oe+_t} ${ge-Ge},${Oe-_t}`),He.setAttribute("fill",g(A.color)),U.append(He)}}}else if(A.type==="shape"){const I=A.x,z=A.y,W=A.w,oe=A.h;if(U=document.createElementNS("http://www.w3.org/2000/svg",A.shape==="rectangle"?"rect":A.shape==="ellipse"?"ellipse":"polygon"),A.shape==="rectangle")U.setAttribute("x",I),U.setAttribute("y",z),U.setAttribute("width",W),U.setAttribute("height",oe);else if(A.shape==="ellipse")U.setAttribute("cx",I+W/2),U.setAttribute("cy",z+oe/2),U.setAttribute("rx",W/2),U.setAttribute("ry",oe/2);else if(A.shape==="triangle"){const he=A.vertices||[[.5,0],[1,1],[0,1]];U.setAttribute("points",he.map(([we,de])=>`${I+we*W},${z+de*oe}`).join(" "))}else if(A.shape==="star"){const he=Math.max(4,Math.min(12,A.points||5)),we=I+W/2,de=z+oe/2,ve=Math.min(W,oe)/2,j=ve*.46,K=[];for(let ae=0;ae<he*2;ae++){const ge=ae%2?j:ve,Oe=-Math.PI/2+ae*Math.PI/he;K.push(`${we+Math.cos(Oe)*ge},${de+Math.sin(Oe)*ge}`)}U.setAttribute("points",K.join(" "))}else U=document.createElementNS("http://www.w3.org/2000/svg","path"),U.setAttribute("d",`M ${I+W*.12} ${z+oe*.12} H ${I+W*.88} V ${z+oe*.7} H ${I+W*.4} L ${I+W*.22} ${z+oe*.92} V ${z+oe*.7} H ${I+W*.12} Z`);U.setAttribute("fill","none"),U.setAttribute("stroke",g(A.color)),U.setAttribute("stroke-width","3"),U.setAttribute("stroke-linejoin","round"),U.setAttribute("pointer-events","all")}else if(A.type==="rect"||A.type==="ellipse")U=document.createElementNS("http://www.w3.org/2000/svg",A.type==="rect"?"rect":"ellipse"),A.type==="rect"?(U.setAttribute("x",A.x),U.setAttribute("y",A.y),U.setAttribute("width",A.w),U.setAttribute("height",A.h)):(U.setAttribute("cx",A.x+A.w/2),U.setAttribute("cy",A.y+A.h/2),U.setAttribute("rx",Math.abs(A.w/2)),U.setAttribute("ry",Math.abs(A.h/2))),U.setAttribute("fill","none"),U.setAttribute("stroke",g(A.color)),U.setAttribute("stroke-width","3"),U.setAttribute("pointer-events","all");else{U=document.createElementNS("http://www.w3.org/2000/svg","foreignObject"),U.setAttribute("x",A.x),U.setAttribute("y",A.y),U.setAttribute("width",Math.max(40,A.w||220)),U.setAttribute("height",Math.max(30,A.h||60)),U.innerHTML=`<div xmlns="http://www.w3.org/1999/xhtml" class="canvas-text-edit" contenteditable="true" spellcheck="false">${Xd(A.text||"")}</div>`;const I=U.querySelector(".canvas-text-edit");I.addEventListener("focus",()=>{I.textContent=A.text||""}),I.addEventListener("input",()=>{A.text=I.innerText,Ct()}),I.style.color=g(A.color),I.addEventListener("blur",()=>{A.text=aM(I),I.innerHTML=Xd(A.text)})}const q=m(A);A.type!=="stroke"&&A.rotation&&U.setAttribute("transform",`rotate(${A.rotation} ${q.x+q.w/2} ${q.y+q.h/2})`),U.dataset.index=F,d.has(F)&&U.classList.add("is-selected"),r.append(U)});const E=d.size>0&&[...d].every(A=>e.elements[A].type==="line");if(d.size){const A=[...d].map(W=>m(e.elements[W])).filter(Boolean),F=Math.min(...A.map(W=>W.x)),U=Math.min(...A.map(W=>W.y)),q=Math.max(...A.map(W=>W.x+W.w)),I=Math.max(...A.map(W=>W.y+W.h)),z={x:F,y:U,w:q-F,h:I-U};if(!E){const W=document.createElementNS("http://www.w3.org/2000/svg","rect");W.setAttribute("x",z.x-4),W.setAttribute("y",z.y-4),W.setAttribute("width",z.w+8),W.setAttribute("height",z.h+8),W.setAttribute("fill","none"),W.setAttribute("stroke","#9a765a"),W.setAttribute("stroke-dasharray","5 4"),W.setAttribute("pointer-events","none"),r.append(W);for(const[ve,j,K]of[["nw",z.x,z.y],["ne",z.x+z.w,z.y],["sw",z.x,z.y+z.h],["se",z.x+z.w,z.y+z.h]]){const ae=document.createElementNS("http://www.w3.org/2000/svg","rect");ae.setAttribute("x",j-5),ae.setAttribute("y",K-5),ae.setAttribute("width",10),ae.setAttribute("height",10),ae.setAttribute("rx",2),ae.setAttribute("fill","#fff"),ae.setAttribute("stroke","#9a765a"),ae.setAttribute("stroke-width",2),ae.dataset.handle=ve,ae.classList.add("canvas-resize-handle"),r.append(ae)}const oe=z.x+z.w/2,he=Math.max(14,z.y-24),we=document.createElementNS("http://www.w3.org/2000/svg","line");we.setAttribute("x1",oe),we.setAttribute("x2",oe),we.setAttribute("y1",z.y-4),we.setAttribute("y2",he+6),we.setAttribute("stroke","#9a765a"),we.setAttribute("pointer-events","none"),r.append(we);const de=document.createElementNS("http://www.w3.org/2000/svg","circle");de.setAttribute("cx",oe),de.setAttribute("cy",he),de.setAttribute("r",6),de.setAttribute("fill","#fff"),de.setAttribute("stroke","#9a765a"),de.setAttribute("stroke-width",2),de.dataset.handle="rotate",de.classList.add("canvas-rotate-handle"),r.append(de)}for(const W of d){const oe=e.elements[W];if(oe.type==="shape"&&oe.shape==="triangle"){const he={x:oe.x+oe.w/2,y:oe.y+oe.h/2};(oe.vertices||[[.5,0],[1,1],[0,1]]).forEach(([we,de],ve)=>{const j=T(oe.x+we*oe.w,oe.y+de*oe.h,he,(oe.rotation||0)*Math.PI/180),K=document.createElementNS("http://www.w3.org/2000/svg","circle");K.setAttribute("cx",j.x),K.setAttribute("cy",j.y),K.setAttribute("r",5),K.setAttribute("fill","#fff"),K.setAttribute("stroke","#9a765a"),K.setAttribute("stroke-width",2),K.dataset.pointHandle=String(ve),K.dataset.index=String(W),K.classList.add("canvas-point-handle"),r.append(K)})}else if(oe.type==="line")for(const[he,we,de]of[["start",oe.x1,oe.y1],["end",oe.x2,oe.y2]]){const ve=document.createElementNS("http://www.w3.org/2000/svg","circle");ve.setAttribute("cx",we),ve.setAttribute("cy",de),ve.setAttribute("r",8),ve.setAttribute("fill","#fff"),ve.setAttribute("stroke","#9a765a"),ve.setAttribute("stroke-width",2.5),ve.setAttribute("pointer-events","all"),ve.dataset.pointHandle=he,ve.dataset.index=String(W),ve.classList.add("canvas-point-handle"),r.append(ve)}}}if(p){const A=document.createElementNS("http://www.w3.org/2000/svg","rect");A.setAttribute("x",Math.min(p.start.x,p.current.x)),A.setAttribute("y",Math.min(p.start.y,p.current.y)),A.setAttribute("width",Math.abs(p.current.x-p.start.x)),A.setAttribute("height",Math.abs(p.current.y-p.start.y)),A.setAttribute("class","canvas-marquee"),A.setAttribute("pointer-events","none"),r.append(A)}const M=d.size?y(d):null;a.hidden=!M;const R=d.size===1?e.elements[[...d][0]]:null,N=(R==null?void 0:R.type)==="shape"||(R==null?void 0:R.type)==="rect"||(R==null?void 0:R.type)==="ellipse"?R:null,Q=(R==null?void 0:R.type)==="line"?R:null;if(o.hidden=!N,l.hidden=!Q,N){const A=N.shape||(N.type==="rect"?"rectangle":N.type==="ellipse"?"ellipse":"");o.querySelectorAll("[data-shape]").forEach(F=>F.setAttribute("aria-pressed",String(F.dataset.shape===A))),o.querySelector(".canvas-star-points").hidden=A!=="star",o.querySelector("select").value=String(N.points||5)}if(Q)for(const A of["start","end"]){const F=Q[`${A}Marker`]||(A==="end"?"arrow":"none");l.querySelectorAll(`[data-endpoint="${A}"][data-style]`).forEach(U=>U.setAttribute("aria-pressed",String(U.dataset.style===F)))}if(M){const A=r.clientWidth/Math.max(1,e.width||1200),F=(M.x+M.w)*A+10,U=F+a.offsetWidth<=r.clientWidth?F:Math.max(4,M.x*A-a.offsetWidth-10);a.style.left=`${U}px`,a.style.top=`${Math.max(8,M.y*A)}px`;const q=Math.min(Math.max(4,U),Math.max(4,r.clientWidth-190));o.style.left=`${q}px`;const I=Math.max(8,M.y*A+a.offsetHeight+8);o.style.top=`${I}px`}if(Q){const A=r.clientWidth/Math.max(1,e.width||1200);for(const[F,U,q]of[["start",Q.x1,Q.y1],["end",Q.x2,Q.y2]]){const I=l.querySelector(`[data-endpoint-menu="${F}"]`),z=U*A-I.offsetWidth-9;I.style.left=`${z>=2?z:U*A+10}px`,I.style.top=`${Math.max(2,q*A-I.offsetHeight/2)}px`}}a.querySelectorAll("[data-color]").forEach(A=>{const F=A.dataset.color.toLowerCase()===O.toLowerCase();A.classList.toggle("active",F),A.setAttribute("aria-pressed",String(F))})};r.dataset.tool=h;const b=()=>{if(d.size){for(const E of[...d].sort((M,R)=>R-M))e.elements.splice(E,1);d.clear(),_(),Ct()}};S.structured.deleteCanvasSelection=b,t.querySelectorAll("[data-tool]").forEach(E=>E.addEventListener("click",()=>{if(E.dataset.tool==="delete"){b();return}h=E.dataset.tool,r.dataset.tool=h,t.querySelectorAll(".canvas-tool[data-tool]").forEach(M=>{const R=M===E;M.classList.toggle("active",R),M.setAttribute("aria-pressed",String(R))}),v()})),t.querySelector('[data-action="rotate"]').addEventListener("click",()=>w(15)),a.querySelectorAll("[data-color]").forEach(E=>E.addEventListener("click",()=>{O=E.dataset.color;for(const M of d)e.elements[M].color=O;d.size&&(_(),Ct())})),o.querySelectorAll("[data-shape]").forEach(E=>E.addEventListener("click",()=>{const M=d.size===1?e.elements[[...d][0]]:null;["shape","rect","ellipse"].includes(M==null?void 0:M.type)&&(M.type="shape",M.shape=E.dataset.shape,M.shape==="triangle"&&(M.vertices||(M.vertices=[[.5,0],[1,1],[0,1]])),M.shape==="star"&&(M.points||(M.points=5)),_(),Ct())})),o.querySelector("select").addEventListener("change",E=>{const M=d.size===1?e.elements[[...d][0]]:null;(M==null?void 0:M.type)==="shape"&&M.shape==="star"&&(M.points=Number(E.target.value),_(),Ct())}),l.querySelectorAll("button[data-endpoint][data-style]").forEach(E=>E.addEventListener("click",()=>{const M=d.size===1?e.elements[[...d][0]]:null;(M==null?void 0:M.type)==="line"&&(M[`${E.dataset.endpoint}Marker`]=E.dataset.style,_(),Ct())})),t.querySelectorAll("[data-history]").forEach(E=>E.addEventListener("click",()=>ia(E.dataset.history)));const k=E=>{const M=r.createSVGPoint();M.x=E.clientX,M.y=E.clientY;const R=M.matrixTransform(r.getScreenCTM().inverse());return{x:R.x,y:R.y}},v=()=>{const E={select:"Drag selected items to move them. Use the corner handles to resize and the top handle to rotate.",draw:"Drag to draw freehand with the pen.",shape:"Drag to create a bounding box, then choose Rectangle, Ellipse, Triangle, Star, or Speech bubble from the shape menu.",line:"Drag to draw a line. Move either endpoint, or choose its start and end markers from the line menu."};c.textContent=E[h]||"",c.hidden=!E[h]};v(),r.addEventListener("pointerdown",E=>{var A,F;const M=E.target.closest(".sheet-wiki-link");if(M){E.preventDefault(),cg(M.dataset.target);return}if(E.target.closest(".canvas-text-edit")&&h==="select"&&E.detail>=2)return;const N=k(E),Q=Number((A=E.target.closest("[data-index]"))==null?void 0:A.dataset.index);if(h==="select"){const U=E.target.closest("[data-point-handle]");if(U&&Number.isInteger(Q)){f={kind:"point",index:Q,handle:U.dataset.pointHandle,original:structuredClone(e.elements[Q])},r.setPointerCapture(E.pointerId),E.preventDefault(),E.stopPropagation();return}if(E.target.dataset.handle==="rotate"&&d.size){const q=y(d),I={x:q.x+q.w/2,y:q.y+q.h/2},z=Math.atan2(N.y-I.y,N.x-I.x);f={kind:"rotate",start:N,center:I,lastAngle:z,angle:0,originals:new Map([...d].map(W=>[W,structuredClone(e.elements[W])]))},r.setPointerCapture(E.pointerId),E.preventDefault();return}if(E.target.dataset.handle&&d.size){f={kind:"resize",handle:E.target.dataset.handle,start:N,originals:new Map([...d].map(q=>[q,structuredClone(e.elements[q])])),group:y(d)},r.setPointerCapture(E.pointerId),E.preventDefault();return}if(Number.isInteger(Q)){E.shiftKey||E.metaKey||E.ctrlKey?d.has(Q)?d.delete(Q):d.add(Q):d.has(Q)||(d=new Set([Q])),d.has(Q)&&(O=((F=e.elements[[...d][0]])==null?void 0:F.color)||O,f={kind:"move",start:N,originals:new Map([...d].map(q=>[q,structuredClone(e.elements[q])]))},r.setPointerCapture(E.pointerId)),_(),E.preventDefault();return}!E.shiftKey&&!E.metaKey&&!E.ctrlKey&&d.clear(),p={start:N,current:N,additive:E.shiftKey||E.metaKey||E.ctrlKey},r.setPointerCapture(E.pointerId),_();return}if(h==="erase"&&Number.isInteger(Q)){e.elements.splice(Q,1),d.clear(),_(),Ct();return}(h==="draw"||h==="shape"||h==="line")&&Number.isInteger(Q)||(r.setPointerCapture(E.pointerId),h==="draw"?u={type:"stroke",points:[N],color:O}:h==="shape"?u={type:"shape",shape:"rectangle",x:N.x,y:N.y,w:0,h:0,color:O}:h==="line"?u={type:"line",x1:N.x,y1:N.y,x2:N.x,y2:N.y,startMarker:"none",endMarker:"arrow",color:O}:h==="text"&&(u={type:"text",x:N.x,y:N.y,w:0,h:0,text:"",color:O}),u&&(e.elements.push(u),d=new Set([e.elements.length-1]),Ct()))}),r.addEventListener("pointermove",E=>{const M=k(E);if((u||f)&&(clearTimeout(S.structured.historyTimer),S.structured.historyTimer=setTimeout(()=>{S.structured.historyPending=!1},600)),p){p.current=M,_();return}if(f){const R=M.x-f.start.x,N=M.y-f.start.y;if(f.kind==="move")for(const[Q,A]of f.originals){const F=e.elements[Q];F.type==="stroke"?F.points=A.points.map(U=>({x:U.x+R,y:U.y+N})):F.type==="line"?(F.x1=A.x1+R,F.y1=A.y1+N,F.x2=A.x2+R,F.y2=A.y2+N):(F.x=A.x+R,F.y=A.y+N)}else if(f.kind==="point"){const Q=e.elements[f.index],A=f.original;if(Q.type==="line")f.handle==="start"?(Q.x1=M.x,Q.y1=M.y):(Q.x2=M.x,Q.y2=M.y);else if(Q.type==="shape"&&Q.shape==="triangle"){const F={x:A.x+A.w/2,y:A.y+A.h/2},U=T(M.x,M.y,F,-(A.rotation||0)*Math.PI/180);Q.vertices=(A.vertices||[[.5,0],[1,1],[0,1]]).map(([q,I],z)=>z===Number(f.handle)?[Math.max(0,Math.min(1,(U.x-A.x)/A.w)),Math.max(0,Math.min(1,(U.y-A.y)/A.h))]:[q,I])}}else if(f.kind==="rotate"){const Q=Math.atan2(M.y-f.center.y,M.x-f.center.x);let A=Q-f.lastAngle;for(;A>Math.PI;)A-=2*Math.PI;for(;A<-Math.PI;)A+=2*Math.PI;f.angle+=A,f.lastAngle=Q;for(const[F,U]of f.originals){const q=e.elements[F];if(q.type==="stroke")q.points=U.points.map(I=>T(I.x,I.y,f.center,f.angle));else if(q.type==="line"){const I=T(U.x1,U.y1,f.center,f.angle),z=T(U.x2,U.y2,f.center,f.angle);q.x1=I.x,q.y1=I.y,q.x2=z.x,q.y2=z.y}else{const I=m(U),z=T(I.x+I.w/2,I.y+I.h/2,f.center,f.angle);q.x=z.x-I.w/2,q.y=z.y-I.h/2,q.rotation=((U.rotation||0)+f.angle*180/Math.PI)%360}}}else{const Q=f.group,A=f.handle,F=A.includes("e"),U=A.includes("s"),q=A.includes("w"),I=A.includes("n"),z=q?Math.min(Q.x+Q.w-4,M.x):Q.x,W=I?Math.min(Q.y+Q.h-4,M.y):Q.y,oe=F?Math.max(Q.x+4,M.x):Q.x+Q.w,he=U?Math.max(Q.y+4,M.y):Q.y+Q.h,we=(oe-z)/Math.max(1,Q.w),de=(he-W)/Math.max(1,Q.h);for(const[ve,j]of f.originals){const K=e.elements[ve];if(K.type==="stroke")K.points=j.points.map(ae=>({x:z+(ae.x-Q.x)*we,y:W+(ae.y-Q.y)*de}));else if(K.type==="line")K.x1=z+(j.x1-Q.x)*we,K.y1=W+(j.y1-Q.y)*de,K.x2=z+(j.x2-Q.x)*we,K.y2=W+(j.y2-Q.y)*de;else{const ae=m(j);K.x=z+(ae.x-Q.x)*we,K.y=W+(ae.y-Q.y)*de,K.w=ae.w*we,K.h=ae.h*de}}}_();return}u&&(u.type==="stroke"?u.points.push(M):u.type==="line"?(u.x2=M.x,u.y2=M.y):(u.w=M.x-u.x,u.h=M.y-u.y),_())});const C=()=>{if(p){const E={x:Math.min(p.start.x,p.current.x),y:Math.min(p.start.y,p.current.y),w:Math.abs(p.current.x-p.start.x),h:Math.abs(p.current.y-p.start.y)};if(E.w>3||E.h>3){const M=e.elements.map((R,N)=>({i:N,b:m(R)})).filter(({b:R})=>R.x<=E.x+E.w&&R.x+R.w>=E.x&&R.y<=E.y+E.h&&R.y+R.h>=E.y).map(({i:R})=>R);d=p.additive?new Set([...d,...M]):new Set(M)}p=null,_();return}if(f&&(f=null,Ct()),u){const E=u.type,M=u.type==="text"&&Math.max(Math.abs(u.w),Math.abs(u.h))>=12;if(u.type==="text"&&!M||u.type==="line"&&Math.hypot(u.x2-u.x1,u.y2-u.y1)<4?(e.elements.pop(),d.clear()):(u.type==="shape"||u.type==="text")&&(u.w<0&&(u.x+=u.w,u.w=Math.abs(u.w)),u.h<0&&(u.y+=u.h,u.h=Math.abs(u.h)),u.w=Math.max(u.type==="text"?180:4,u.w),u.h=Math.max(u.type==="text"?60:4,u.h)),u=null,(E==="shape"||E==="line")&&(h="select",r.dataset.tool=h,t.querySelectorAll(".canvas-tool[data-tool]").forEach(R=>{const N=R.dataset.tool===h;R.classList.toggle("active",N),R.setAttribute("aria-pressed",String(N))}),v()),Ct(),_(),M){const R=[...d][0],N=r.querySelector('[data-index="'+R+'"] .canvas-text-edit');requestAnimationFrame(()=>N==null?void 0:N.focus())}}};r.addEventListener("pointerup",C),r.addEventListener("pointercancel",C),r.addEventListener("click",E=>{var N;const R=(((N=E.target.closest("[data-link-text]"))==null?void 0:N.getAttribute("data-link-text"))||"").match(/\[\[([^\]]+)\]\]/);R&&cg(R[1])}),_(),S.structured.refreshCanvas=_}async function rM(n,e){const t=n.querySelector(".structured-toolbar");t.innerHTML=`<span>Desmos Graphing Calculator · graph state is saved in this file</span><button data-history="undo" title="Undo (⌘Z)" aria-label="Undo">${fe.undo}</button><button data-history="redo" title="Redo (⌘⇧Z)" aria-label="Redo">${fe.redo}</button>`,t.querySelectorAll("[data-history]").forEach(o=>o.addEventListener("click",()=>ia(o.dataset.history)));const i=n.querySelector(".structured-surface"),s=S.structured,r=(o,l=!1)=>{i.replaceChildren();const c=document.createElement("div");c.className="graph-setup";const h=document.createElement("p");if(h.textContent=o,c.append(h),l){const d=document.createElement("button");d.className="secondary-button",d.textContent="Open Graphing settings",d.addEventListener("click",()=>la("desmos")),c.append(d)}i.append(c)};let a="";try{a=await window.stillnote.getDesmosKey()}catch(o){r(o.message||"Open a vault to use the saved Desmos key.");return}if(!a){In("desmos",!1,"Graphing API key missing"),r("A Desmos API key is required to use the graph editor.",!0);return}try{const o=await rz(a);if(S.structured!==s||!n.isConnected)return;const l=document.createElement("div");l.className="graph-calculator",i.replaceChildren(l);const c=S.theme==="dark"?{colors:["#d1a07e","#84b7a1","#83a9d2","#d88980","#b19bd2","#d7c36f"]}:S.theme==="sepia"?{colors:["#9d7151","#6e927b","#6f89a8","#b46d5e","#92779d","#b09550"]}:{},h=o.GraphingCalculator(l,{expressions:!0,keypad:!0,settingsMenu:!0,zoomButtons:!0,autosize:!0,invertedColors:!1,fontSize:15,border:!1,...c});s.desmos=h,In("desmos",!0,"Graphing API key working"),e.state&&typeof e.state=="object"?h.setState(e.state):e.state=h.getState(),h.clearHistory(),h.observeEvent("change",()=>{S.structured!==s||!S.active||(e.state=h.getState(),Ct())})}catch(o){S.structured===s&&n.isConnected&&(In("desmos",!1,"Graphing API key not working"),r(o.message||"Could not open Desmos.",!0))}}function lz(n,e){const t=n.querySelector(".structured-toolbar");t.innerHTML=`<span>Click a cell to edit · use <[Note]> to link</span><button data-history="undo" title="Undo (⌘Z)" aria-label="Undo">${fe.undo}</button><button data-history="redo" title="Redo (⌘⇧Z)" aria-label="Redo">${fe.redo}</button><button class="sheet-add-row">Add row</button><button class="sheet-add-column">Add column</button>`;const i=n.querySelector(".structured-surface"),s=()=>{let r='<table class="sheet-grid"><thead><tr><th></th>';for(let a=0;a<e.columns;a++)r+=`<th>${hy(a)}</th>`;r+="</tr></thead><tbody>";for(let a=0;a<e.rows;a++){r+=`<tr><th>${a+1}</th>`;for(let o=0;o<e.columns;o++){const l=`${hy(o)}${a+1}`,c=String(e.cells[l]??""),h=c.startsWith("=")?hg(e,l):c;r+=`<td contenteditable="true" data-cell="${l}" spellcheck="false">${Xd(h)}</td>`}r+="</tr>"}r+="</tbody></table>",i.innerHTML=r,i.querySelectorAll("[data-cell]").forEach(a=>{a.addEventListener("focus",()=>{a.textContent=e.cells[a.dataset.cell]||""}),a.addEventListener("input",()=>{e.cells[a.dataset.cell]=a.innerText,Ct(),i.querySelectorAll("[data-cell]").forEach(o=>{if(o===a||document.activeElement===o)return;const l=String(e.cells[o.dataset.cell]??"");o.innerHTML=Xd(l.startsWith("=")?hg(e,o.dataset.cell):l)})}),a.addEventListener("blur",()=>{e.cells[a.dataset.cell]=aM(a),s()})})};i.addEventListener("click",r=>{const a=r.target.closest(".sheet-wiki-link");a&&(r.preventDefault(),r.stopPropagation(),cg(a.dataset.target))}),t.querySelector(".sheet-add-row").addEventListener("click",()=>{e.rows=Math.min(200,e.rows+1),s(),Ct()}),t.querySelector(".sheet-add-column").addEventListener("click",()=>{e.columns=Math.min(26,e.columns+1),s(),Ct()}),s(),t.querySelectorAll("[data-history]").forEach(r=>r.addEventListener("click",()=>ia(r.dataset.history)))}async function cz(n,e,t){const i=String(t||"").trim();if(!i||S.structured!==e||!n.isConnected)return;const s=n.querySelector(".structured-title");if(i===at(S.active)){e.title=i,s.textContent=i;return}const r=_o(i);if(r){Re(`Google list title cannot be used as a file name: ${r}`);return}const a=S.active;try{if(await qn(),S.active!==a||S.structured!==e)return;const o=await window.stillnote.renameEntry(a,i);if(S.active!==a||S.structured!==e)return;S.active=o,e.file=o,e.title=i,s.textContent=i,[S.files,S.tree]=await Promise.all([window.stillnote.listNotes(),window.stillnote.getVaultTree()]),Ht(),Ja(o),window.stillnote.rememberNote(o).catch(()=>{}),Ct()}catch(o){Re(`Google list title changed, but the task sheet could not be renamed: ${o.message}`)}}async function hz(n,e){Array.isArray(e.tasks)||(e.tasks=[]);const t=S.structured;let i=!1;const s=n.querySelector(".structured-toolbar");s.innerHTML=`<span class="task-sheet-status">Loading Google Tasks…</span><button class="secondary-button task-sheet-refresh" type="button" aria-label="Sync with Google Tasks" title="Sync with Google Tasks">${fe.refresh}</button>`;const r=n.querySelector(".structured-surface");r.innerHTML='<form class="task-sheet-add"><input class="settings-input" type="text" maxlength="1024" placeholder="Add a task…" aria-label="New task"><button class="primary-button" type="submit">Add task</button></form><div class="task-sheet-list" aria-live="polite"></div>';const a=s.querySelector(".task-sheet-status"),o=r.querySelector(".task-sheet-list"),l=()=>S.structured===t&&n.isConnected,c=()=>{var g;if(!((g=e.tasks)!=null&&g.length)){o.innerHTML='<div class="task-sheet-empty">No tasks in this list yet.</div>';return}const u=new Map(e.tasks.map((m,y)=>[m.id,{task:m,index:y}])),f=m=>[...m].sort((y,T)=>+!!y.parent-+!!T.parent).map(y=>{const T=e.tasks.indexOf(y),w=y.parent&&u.has(y.parent)?1:0,_=y.due?String(y.due).slice(0,10):"";return`<article class="task-sheet-card${y.status==="completed"?" is-complete":""}${w?" is-subtask":""}${y.starred?" is-starred":""}" data-index="${T}"><div class="task-sheet-row"><input class="task-sheet-complete" type="checkbox" aria-label="Mark ${Ut(y.title)} complete" ${y.status==="completed"?"checked":""}><input class="task-sheet-title" type="text" maxlength="1024" aria-label="Task title" value="${Ut(y.title)}"><button class="task-sheet-star${y.starred?" is-starred":""}" type="button" aria-label="${y.starred?"Unstar":"Star"} task" title="${y.starred?"Unstar task":"Star task"}">${fe.star}</button><button class="icon-button task-sheet-delete" type="button" aria-label="Delete ${Ut(y.title)}" title="Delete task">${fe.trash}</button></div><div class="task-sheet-fields"><label>Due date<input class="task-sheet-due" type="date" value="${Ut(_)}" aria-label="Due date"></label><label class="task-sheet-details-label">Details<textarea class="task-sheet-details" rows="2" maxlength="8192" placeholder="Add details…" aria-label="Task details">${Ut(y.notes||"")}</textarea></label></div>${w?"":'<form class="task-sheet-subtask"><input class="settings-input" type="text" maxlength="1024" placeholder="Add a subtask…" aria-label="New subtask"><button class="secondary-button" type="submit">Add subtask</button></form>'}</article>`}).join(""),p=e.tasks.filter(m=>m.status!=="completed"),O=e.tasks.filter(m=>m.status==="completed");o.innerHTML=`${f(p)}${O.length?`<details class="task-sheet-completed"><summary>Completed <span>${O.length}</span></summary><div class="task-sheet-completed-list">${f(O)}</div></details>`:""}`,!p.length&&!O.length&&(o.innerHTML='<div class="task-sheet-empty">No tasks in this list yet.</div>')},h=async()=>{if(!(i||!l())){i=!0,a.textContent="Syncing…";try{const[u,f]=await Promise.all([window.stillnote.listGoogleTaskLists(),window.stillnote.listGoogleTasks(e.listId)]);if(!l())return;const p=u.find(m=>m.id===e.listId);if(!p)throw new Error("This Google Tasks list no longer exists.");if(await cz(n,t,p.title),!l())return;const O=JSON.stringify(e.tasks),g=new Map(e.tasks.map(m=>[m.id,!!m.starred]));e.tasks=f.map(m=>({id:m.id,title:m.title||"",status:m.status||"needsAction",due:m.due||null,notes:m.notes||"",parent:m.parent||null,starred:g.get(m.id)||!1})),c(),a.textContent=`Synced with Google Tasks · ${e.tasks.length} ${e.tasks.length===1?"task":"tasks"}`,O!==JSON.stringify(e.tasks)&&Ct()}catch(u){l()&&(a.textContent=u.message||"Could not sync Google Tasks")}finally{i=!1}}},d=setInterval(()=>{l()?h():clearInterval(d)},12e4);t.cleanup=()=>clearInterval(d),s.querySelector(".task-sheet-refresh").addEventListener("click",()=>void h()),s.querySelectorAll("[data-history]").forEach(u=>u.addEventListener("click",()=>ia(u.dataset.history))),r.querySelector(".task-sheet-add").addEventListener("submit",async u=>{u.preventDefault();const f=r.querySelector(".task-sheet-add input"),p=f.value.trim();if(!p)return;const O=r.querySelector(".task-sheet-add button");O.disabled=!0;try{const g=await window.stillnote.createGoogleTask(e.listId,p);if(!l())return;e.tasks.push({id:g.id,title:g.title||p,status:g.status||"needsAction",due:g.due||null,notes:g.notes||"",parent:null,starred:!1}),f.value="",c(),Ct(),a.textContent="Task added to Google Tasks"}catch(g){l()&&(a.textContent=g.message||"Could not add task",Re(a.textContent))}finally{O.disabled=!1}}),o.addEventListener("change",async u=>{if(u.target.matches(".task-sheet-due, .task-sheet-details")){const g=u.target.closest("[data-index]"),m=e.tasks[Number(g.dataset.index)],y=u.target.matches(".task-sheet-due")?u.target.value:String(m.due||"").slice(0,10),T=u.target.matches(".task-sheet-details")?u.target.value:m.notes||"",w=u.target.matches(".task-sheet-due")?{due:y?`${y}T00:00:00.000Z`:null}:{notes:T};u.target.disabled=!0;try{const _=await window.stillnote.updateGoogleTask(e.listId,m.id,w);if(!l())return;"due"in w?m.due=_.due||null:m.notes=_.notes||"",Ct(),a.textContent="Task updated in Google Tasks"}catch(_){l()&&("due"in w?u.target.value=String(m.due||"").slice(0,10):u.target.value=m.notes||"",a.textContent=_.message||"Could not update task",Re(a.textContent))}finally{u.target.isConnected&&(u.target.disabled=!1)}return}if(u.target.matches(".task-sheet-title")){const g=u.target.closest("[data-index]"),m=e.tasks[Number(g.dataset.index)],y=u.target.value.trim();if(!y){u.target.value=m.title;return}u.target.disabled=!0;try{const T=await window.stillnote.updateGoogleTask(e.listId,m.id,{title:y});if(!l())return;m.title=T.title||y,u.target.value=m.title,Ct(),a.textContent="Task updated in Google Tasks"}catch(T){l()&&(u.target.value=m.title,a.textContent=T.message||"Could not update task",Re(a.textContent))}finally{u.target.isConnected&&(u.target.disabled=!1)}return}if(!u.target.matches(".task-sheet-complete"))return;const f=u.target.closest("[data-index]"),p=e.tasks[Number(f.dataset.index)],O=u.target.checked?"completed":"needsAction";u.target.disabled=!0;try{const g=await window.stillnote.updateGoogleTask(e.listId,p.id,{status:O});if(!l())return;p.status=g.status||O,c(),Ct(),a.textContent="Task updated in Google Tasks"}catch(g){l()&&(u.target.checked=p.status==="completed",a.textContent=g.message||"Could not update task",Re(a.textContent))}finally{u.target.isConnected&&(u.target.disabled=!1)}}),o.addEventListener("focusin",u=>{const f=u.target.closest(".task-sheet-card");f&&f.classList.add("is-editing")}),o.addEventListener("focusout",u=>{const f=u.target.closest(".task-sheet-card");f&&requestAnimationFrame(()=>{f.isConnected&&!f.contains(document.activeElement)&&f.classList.remove("is-editing")})}),o.addEventListener("click",async u=>{const f=u.target.closest(".task-sheet-star");if(f){const y=f.closest("[data-index]"),T=e.tasks[Number(y.dataset.index)];T.starred=!T.starred,c(),Ct();return}const p=u.target.closest(".task-sheet-delete");if(!p)return;const O=p.closest("[data-index]"),g=Number(O.dataset.index),m=e.tasks[g];p.disabled=!0;try{if(await window.stillnote.deleteGoogleTask(e.listId,m.id),!l())return;e.tasks.splice(g,1),c(),Ct(),a.textContent="Task deleted from Google Tasks"}catch(y){l()&&(p.disabled=!1,a.textContent=y.message||"Could not delete task",Re(a.textContent))}}),o.addEventListener("submit",async u=>{const f=u.target.closest(".task-sheet-subtask");if(!f)return;u.preventDefault();const p=f.closest("[data-index]"),O=e.tasks[Number(p.dataset.index)],m=f.querySelector("input").value.trim();if(!m)return;const y=f.querySelector("button");y.disabled=!0;try{const T=await window.stillnote.createGoogleTask(e.listId,m,O.id);if(!l())return;e.tasks.push({id:T.id,title:T.title||m,status:T.status||"needsAction",due:T.due||null,notes:T.notes||"",parent:T.parent||O.id,starred:!1}),c(),Ct(),a.textContent="Subtask added to Google Tasks"}catch(T){l()&&(a.textContent=T.message||"Could not add subtask",Re(a.textContent))}finally{y.isConnected&&(y.disabled=!1)}}),c(),await h()}function hg(n,e,t=new Set){var r;e=e.toUpperCase();const i=String(n.cells[e]??"").trim();if(!i)return"0";if(!i.startsWith("=")){const a=Number(i);return Number.isFinite(a)?String(a):"#VALUE!"}if(t.has(e))return"#CYCLE!";const s=new Set(t);s.add(e);try{const a=i.slice(1),o=a.match(/[A-Za-z]+[0-9]+|(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?|[()+\-*/^]/g)||[];if(o.join("")!==a.replace(/\s+/g,""))return"#VALUE!";let l=0;const c=()=>{const p=o[l++];if(p==="+"||p==="-"){const g=c();return p==="-"?-g:g}if(p==="("){const g=u();if(o[l++]!==")")throw new Error("#VALUE!");return g}if(!p)throw new Error("#VALUE!");if(/^[A-Za-z]+\d+$/.test(p)){const g=hg(n,p,s);if(g.startsWith("#"))throw new Error(g);return Number(g)}const O=Number(p);if(!Number.isFinite(O))throw new Error("#VALUE!");return O},h=()=>{let p=c();return o[l]==="^"&&(l++,p=Math.pow(p,h())),p},d=()=>{let p=h();for(;o[l]==="*"||o[l]==="/";){const O=o[l++],g=h();if(O==="/"&&g===0)throw new Error("#DIV/0!");p=O==="*"?p*g:p/g}return p},u=()=>{let p=d();for(;o[l]==="+"||o[l]==="-";){const O=o[l++],g=d();p=O==="+"?p+g:p-g}return p},f=u();return l!==o.length||!Number.isFinite(f)?"#VALUE!":String(Number(f.toPrecision(12)))}catch(a){return(r=a.message)!=null&&r.startsWith("#")?a.message:"#VALUE!"}}function hy(n){let e="";for(let t=n+1;t;t=Math.floor((t-1)/26))e=String.fromCharCode(65+(t-1)%26)+e;return e}function Xd(n){const e=String(n),t=/(?:<\[([^\]|]+)(?:\|([^\]]+))?\]>|\[\[([^\]|]+)(?:\|([^\]]+))?\]\])/g;let i="",s=0,r;for(;r=t.exec(e);){i+=Ut(e.slice(s,r.index));const a=(r[1]||r[3]).trim(),o=r[2]||r[4]||a;i+=`<a class="sheet-wiki-link" href="#" data-target="${Ut(a)}">${Ut(o)}</a>`,s=r.index+r[0].length}return i+Ut(e.slice(s))}function aM(n){const e=t=>{if(t.nodeType===Node.TEXT_NODE)return t.nodeValue||"";if(t.nodeType!==Node.ELEMENT_NODE)return"";if(t.matches("a.sheet-wiki-link")){const i=t.dataset.target||"",s=t.textContent||i;return`<[${i}${s!==i?`|${s}`:""}]>`}return[...t.childNodes].map(e).join("")};return[...n.childNodes].map(e).join("")}async function qn(){if(S.savePromise)return await S.savePromise,S.dirty?qn():void 0;if(!S.dirty||!S.active||!S.view&&!S.structured)return;if(clearTimeout(S.saveTimer),S.structured){const s=S.active,r=S.structured,a=(r.title||at(s)).trim()||at(s),o=(async()=>{try{await window.stillnote.writeNote(s,hc(r.type,a,r.data)),S.dirty=!1,L("#save-state").textContent="Saved"}catch(l){L("#save-state").textContent="Save failed",Re(l.message||"Could not save file.")}})();S.savePromise=o;try{await o}finally{S.savePromise=null}return}const n=S.view,e=S.active;let t=!1;const i=(async()=>{try{if(!e.toLowerCase().endsWith(".md")){const d=n.state.doc.toString();await window.stillnote.writeNote(e,d),t=!0,S.view===n&&S.active===e&&(S.dirty=n.state.doc.toString()!==d,L("#save-state").textContent=S.dirty?"Unsaved changes":"Saved");return}const s=n.state.doc.line(1),r=s.text.trim(),a=(r||at(e)).replace(/\.md$/i,"").trim()||at(e);s.text!==a&&n.dispatch({changes:{from:s.from,to:s.to,insert:a}});const o=n.state.doc.toString();await window.stillnote.writeNote(e,o),t=!0;const l=_o(r.replace(/\.md$/i,"").trim());if(l){S.dirty=n.state.doc.toString()!==o,L("#save-state").textContent=S.dirty?"Unsaved changes":"Saved",S.lastTitleValidationMessage!==l&&Re(l),S.lastTitleValidationMessage=l;return}let c=e;const h=at(e);if(a!==h)try{c=await window.stillnote.renameEntry(e,a)}catch(d){S.dirty=n.state.doc.toString()!==o,L("#save-state").textContent=S.dirty?"Unsaved changes":"Saved",Re(`Note saved, but it could not be renamed: ${d.message}`);return}c!==e&&(S.active=c,[S.files,S.tree]=await Promise.all([window.stillnote.listNotes(),window.stillnote.getVaultTree()]),Ht(),L("#breadcrumbs").innerHTML=`<span>${Ut(S.vault.name)}</span><span class="crumb-slash">/</span><strong>${Ut(c.split("/").map(at).join(" / "))}</strong>`,L(".location-note").textContent=at(c),window.stillnote.rememberNote(c).catch(d=>console.error("Could not save active note:",d))),S.view===n&&S.active===c&&(S.dirty=n.state.doc.toString()!==o,L("#save-state").textContent=S.dirty?"Unsaved changes":"Saved")}catch(s){L("#save-state").textContent="Save failed",Re(s.message)}})();S.savePromise=i;try{await i}finally{S.savePromise=null}if(t&&S.dirty)return qn()}async function Ou(n=""){var t;if(!S.vault)return qs();const e=`Untitled ${S.files.filter(i=>at(i).startsWith("Untitled")).length+1}`;try{const i=await window.stillnote.createNote(e,n);[S.files,S.tree]=await Promise.all([window.stillnote.listNotes(),window.stillnote.getVaultTree()]),Ht(),await mi(i),(t=S.view)==null||t.focus()}catch(i){Re(i.message||"Could not create note.")}}async function dz(){const n=L("#rename-form"),e=n.querySelector(".rename-actions"),t=document.createElement("label");t.className="code-type-picker",t.textContent="File type";const i=document.createElement("select");i.className="settings-input",i.setAttribute("aria-label","Code file type"),i.replaceChildren(...rg.map(([c,h])=>{const d=document.createElement("option");return d.value=h,d.textContent=`${c} (${h})`,d})),t.append(i),e.before(t);const s=await Su("Create code file","Untitled","Create file"),r=i.value;if(t.remove(),!(s!=null&&s.trim()))return null;const a=s.trim(),o=rg.map(([,c])=>c).find(c=>a.toLocaleLowerCase().endsWith(c));return`${o?a.slice(0,-o.length):a}${r}`}async function oM(n=""){var t;if(!S.vault)return qs();const e=await dz();if(e)try{const i=await window.stillnote.createCodeFile(e,n);[S.files,S.tree]=await Promise.all([window.stillnote.listNotes(),window.stillnote.getVaultTree()]),Ht(),await mi(i),(t=S.view)==null||t.focus()}catch(i){Re(i.message||"Could not create code file.")}}async function eo(n,e=""){if(!S.vault)return qs();const t=n==="canvas"?"Canvas":n==="graph"?"Graph":"Spreadsheet",i=`Untitled ${t} ${S.files.filter(s=>at(s).startsWith(`Untitled ${t}`)).length+1}`;try{const s=await window.stillnote.createNote(i,e),r=n==="canvas"?tM():n==="graph"?iM():nM();await window.stillnote.writeNote(s,hc(n,i,r)),[S.files,S.tree]=await Promise.all([window.stillnote.listNotes(),window.stillnote.getVaultTree()]),Ht(),await mi(s)}catch(s){Re(s.message||`Could not create ${t.toLowerCase()}.`)}}async function lM(n=""){var t;if(!S.vault)return qs();const e=await window.stillnote.googleTasksStatus().catch(()=>null);if(!(e!=null&&e.clientIdConfigured)||!e.connected){Re("Connect Google Tasks in Settings before creating a task sheet."),la("tasks");return}try{const i=await window.stillnote.listGoogleTaskLists(),s=await uz(i);if(!s)return;let r=s.list,a="";if(s.create){if(a=(t=await Su("New Google Tasks list","","Create list"))==null?void 0:t.trim(),!a)return;const u=_o(a);if(u){Re(u);return}}const o=String(a||r.title||"").trim(),l=_o(o);if(l){Re(`This Google Tasks list title cannot be used as a file name: ${l}`);return}const c=[n,`${o}.md`].filter(Boolean).join("/");if(S.files.some(u=>u.toLocaleLowerCase()===c.toLocaleLowerCase())){Re("A file with this title already exists in that folder.");return}s.create&&(r=await window.stillnote.createGoogleTaskList(o));const h=await window.stillnote.createNote(o,n),d=sM(r.id);await window.stillnote.writeNote(h,hc("tasks",o,d)),[S.files,S.tree]=await Promise.all([window.stillnote.listNotes(),window.stillnote.getVaultTree()]),Ht(),await mi(h)}catch(i){Re(i.message||"Could not create a Google Tasks sheet.")}}function uz(n){if(!n.length)return Promise.resolve({create:!0});const e=document.createElement("div");e.className="rename-overlay task-list-picker";const t=n.map(s=>`<option value="${Ut(s.id)}">${Ut(s.title)}</option>`).join("");e.innerHTML=`<section class="rename-dialog" role="dialog" aria-modal="true" aria-labelledby="task-list-picker-title"><h2 id="task-list-picker-title">Choose a Google Tasks list</h2><select class="settings-input task-list-picker-select">${t}</select><div class="rename-actions"><button type="button" class="secondary-button" data-choice="cancel">Cancel</button><button type="button" class="secondary-button" data-choice="create">Create new list</button><button type="button" class="primary-button" data-choice="use">Use selected list</button></div></section>`,document.body.append(e);const i=e.querySelector("select");return i.focus(),new Promise(s=>{const r=a=>{e.remove(),s(a)};e.querySelector('[data-choice="cancel"]').addEventListener("click",()=>r(null)),e.querySelector('[data-choice="create"]').addEventListener("click",()=>r({create:!0})),e.querySelector('[data-choice="use"]').addEventListener("click",()=>r({list:n.find(a=>a.id===i.value)})),e.addEventListener("click",a=>{a.target===e&&r(null)})})}function fz(n,e=""){const t=L("#new-file-menu");t.replaceChildren();const i=[["New note",()=>Ou(e)],["New code file…",()=>oM(e)],["New canvas",()=>eo("canvas",e)],["New spreadsheet",()=>eo("spreadsheet",e)],["New graph",()=>eo("graph",e)],["New task sheet",()=>lM(e)]];for(const[r,a]of i){const o=document.createElement("button");o.className="context-action",o.textContent=r,o.addEventListener("click",()=>{t.hidden=!0,a()}),t.append(o)}const s=n.getBoundingClientRect();t.hidden=!1,t.style.left=`${Math.max(8,Math.min(s.left,window.innerWidth-205))}px`,t.style.top=`${Math.min(s.bottom+4,window.innerHeight-t.offsetHeight-8)}px`}async function QO(n=""){if(!S.vault)return qs();const e=await Su("Create folder","","Create");if(e!=null&&e.trim())try{const t=await window.stillnote.createFolder(n,e);n&&S.collapsed.delete(n),t&&S.collapsed.delete(t),[S.files,S.tree]=await Promise.all([window.stillnote.listNotes(),window.stillnote.getVaultTree()]),Ht()}catch(t){Re(t.message||"Could not create folder.")}}async function pz(){S.vault&&([S.files,S.tree]=await Promise.all([window.stillnote.listNotes(),window.stillnote.getVaultTree()]),Ht())}function Yl(n,e){return!(!n||n.path===e||n.type==="folder"&&e.startsWith(`${n.path}/`))}function zd(){var n;document.querySelectorAll(".dragging,.drop-target,.root-drop-target").forEach(e=>e.classList.remove("dragging","drop-target","root-drop-target")),(n=L("#note-list"))==null||n.classList.remove("asset-upload-target")}function Na(n){var e;return!S.draggedItem&&Array.from(((e=n.dataTransfer)==null?void 0:e.types)||[]).includes("Files")}async function cM(n,e=""){var i;n.preventDefault(),n.stopPropagation(),zd();const t=Array.from(((i=n.dataTransfer)==null?void 0:i.files)||[]);if(t.length)try{if(t.length>100)throw new Error("Upload up to 100 files at a time.");const s=t.find(o=>o.size>250*1024*1024);if(s)throw new Error(`${s.name} is larger than the 250 MB upload limit.`);const r=await Promise.all(t.map(async o=>({name:o.name,data:await o.arrayBuffer()}))),a=await window.stillnote.uploadAssets(e,r);if([S.files,S.tree]=await Promise.all([window.stillnote.listNotes(),window.stillnote.getVaultTree()]),e)for(const[o,l]of e.split("/").entries())S.collapsed.delete(e.split("/").slice(0,o+1).join("/"));Ht(),Re(`${a.length} file${a.length===1?"":"s"} added`)}catch(s){Re(s.message||"Files could not be uploaded.")}}function dy(n,e){n.draggable=!0,n.addEventListener("dragstart",t=>{S.draggedItem={path:e.path,type:e.type},t.dataTransfer.effectAllowed="move",t.dataTransfer.setData("application/x-stillnote-path",e.path),t.dataTransfer.setData("application/x-stillnote-type",e.type),n.classList.add("dragging")}),n.addEventListener("dragend",()=>{S.draggedItem=null,zd()}),n.addEventListener("dragover",t=>{Na(t)&&(t.preventDefault(),t.dataTransfer.dropEffect="copy",n.classList.add("drop-target"))}),n.addEventListener("drop",t=>{Na(t)&&cM(t,e.type==="folder"?e.path:"")}),e.type==="folder"&&(n.addEventListener("dragover",t=>{Na(t)||Yl(S.draggedItem,e.path)&&(t.preventDefault(),t.dataTransfer.dropEffect="move",n.classList.add("drop-target"))}),n.addEventListener("dragleave",()=>n.classList.remove("drop-target")),n.addEventListener("drop",t=>{if(Na(t))return;t.preventDefault(),t.stopPropagation();const i=S.draggedItem;S.draggedItem=null,zd(),Yl(i,e.path)&&hM(i,e.path)}))}L("#note-list").addEventListener("dragover",n=>{Na(n)&&(n.preventDefault(),n.dataTransfer.dropEffect="copy",L("#note-list").classList.add("asset-upload-target"))});L("#note-list").addEventListener("dragleave",n=>{L("#note-list").contains(n.relatedTarget)||L("#note-list").classList.remove("asset-upload-target")});L("#note-list").addEventListener("drop",n=>{Na(n)&&cM(n,""),L("#note-list").classList.remove("asset-upload-target")});async function hM(n,e){var t;if(!(!n||!Yl(n,e)))try{const i=S.active;await qn();const s=n.type==="note"&&i===n.path&&S.active!==n.path?S.active:n.path,r=await window.stillnote.moveEntry(s,e);let a=S.active;S.active===s?a=r:n.type==="folder"&&((t=S.active)!=null&&t.startsWith(`${s}/`))&&(a=`${r}${S.active.slice(s.length)}`);const o=new Set;for(const l of S.collapsed)l===s?o.add(r):n.type==="folder"&&l.startsWith(`${s}/`)?o.add(`${r}${l.slice(s.length)}`):o.add(l);S.collapsed=o,e&&S.collapsed.delete(e),[S.files,S.tree]=await Promise.all([window.stillnote.listNotes(),window.stillnote.getVaultTree()]),Ht(),a!==S.active&&(S.active=null,await mi(a)),Re("Item moved")}catch(i){Re(i.message||"Could not move item.")}}L(".explorer-heading").addEventListener("dragover",n=>{!S.draggedItem||!Yl(S.draggedItem,"")||(n.preventDefault(),n.dataTransfer.dropEffect="move",L(".explorer-heading").classList.add("root-drop-target"))});L(".explorer-heading").addEventListener("dragleave",()=>L(".explorer-heading").classList.remove("root-drop-target"));L(".explorer-heading").addEventListener("drop",n=>{if(!S.draggedItem||!Yl(S.draggedItem,""))return;n.preventDefault(),n.stopPropagation();const e=S.draggedItem;S.draggedItem=null,zd(),hM(e,"")});function uy(n,e){n.preventDefault(),n.stopPropagation();const t=L("#explorer-context-menu");t.replaceChildren();const i=(a,o,l=!1)=>{const c=document.createElement("button");c.className=`context-action${l?" danger":""}`,c.textContent=a,c.addEventListener("click",()=>{LO(),o()}),t.append(c)};if(e.type==="folder"){i("New note here",()=>Ou(e.path)),i("New code file here…",()=>oM(e.path)),i("New canvas here",()=>eo("canvas",e.path)),i("New spreadsheet here",()=>eo("spreadsheet",e.path)),i("New graph here",()=>eo("graph",e.path)),i("New task sheet here",()=>lM(e.path)),i("New folder here",()=>QO(e.path));const a=document.createElement("div");a.className="context-separator",t.append(a)}else i("Copy link",()=>{window.stillnote.copyFileLink(e.path).then(()=>Re("Link copied")).catch(a=>Re(a.message||"Could not copy link."))});i("Rename…",()=>Oz(e)),i("Delete…",()=>Sz(e),!0),t.hidden=!1;const s=190,r=t.offsetHeight;t.style.left=`${Math.max(8,Math.min(n.clientX,window.innerWidth-s-8))}px`,t.style.top=`${Math.max(8,Math.min(n.clientY,window.innerHeight-r-8))}px`}function LO(){L("#explorer-context-menu").hidden=!0}function mz(n,e){return Su(`Rename ${e}`,n,"Rename")}function Su(n,e="",t="Create"){const i=L("#rename-overlay"),s=L("#rename-input");return L("#rename-title").textContent=n,L("#rename-form").querySelector('[type="submit"]').textContent=t,s.value=e,i.hidden=!1,requestAnimationFrame(()=>{s.focus(),e&&s.select()}),new Promise(r=>{qh=r})}function xu(n=null){if(!qh)return;const e=qh;qh=null,L("#rename-overlay").hidden=!0,e(n)}function gz(n,e){return L("#delete-title").textContent=`Delete “${n}”?`,L("#delete-description").textContent=e,L("#delete-overlay").hidden=!1,requestAnimationFrame(()=>L("#delete-confirm").focus()),new Promise(t=>{Hh=t})}function vu(n=!1){if(!Hh)return;const e=Hh;Hh=null,L("#delete-overlay").hidden=!0,e(n)}async function Oz(n){var s,r;const e=S.active,t=n.type==="note"?at(n.name):n.name,i=await mz(t,n.type);if(!(!(i!=null&&i.trim())||i.trim()===t))try{await qn();const a=n.type==="note"&&e===n.path&&S.active!==n.path?S.active:n.path;if(n.type==="note"&&n.format==="tasks"){const c=kO(await window.stillnote.readNote(a));(c==null?void 0:c.type)==="tasks"&&((s=c.data)!=null&&s.listId)&&await window.stillnote.renameGoogleTaskList(c.data.listId,i.trim())}const o=await window.stillnote.renameEntry(a,i.trim());let l=S.active;S.active===a?l=o:n.type==="folder"&&((r=S.active)!=null&&r.startsWith(`${a}/`))&&(l=`${o}${S.active.slice(a.length)}`),[S.files,S.tree]=await Promise.all([window.stillnote.listNotes(),window.stillnote.getVaultTree()]),n.type==="folder"&&S.collapsed.delete(a)&&S.collapsed.add(o),Ht(),l!==S.active&&(S.active=null,await mi(l))}catch(a){Re(a.message||"Could not rename item.")}}async function Sz(n){var i,s,r,a,o,l;const e=n.type==="note"?at(n.name):n.name,t=n.type==="folder"?"This also deletes everything inside it.":"This deletes this file from the vault.";if(await gz(e,t))try{const c=S.active;await qn();const h=n.type==="note"&&c===n.path&&S.active!==n.path?S.active:n.path,d=zs(),u=n.type==="note"?[h]:d.filter(O=>O.startsWith(`${h}/`)),f=!!(S.active&&u.includes(S.active)),p=f?d.indexOf(S.active):d.indexOf(h);if(await window.stillnote.deleteEntry(h),[S.files,S.tree]=await Promise.all([window.stillnote.listNotes(),window.stillnote.getVaultTree()]),Ht(),f){(i=S.view)==null||i.destroy(),S.view=null,(a=(r=(s=S.structured)==null?void 0:s.desmos)==null?void 0:r.destroy)==null||a.call(r),S.structured=null,(l=(o=S.assetViewer)==null?void 0:o.destroy)==null||l.call(o),S.assetViewer=null,S.dirty=!1,S.active=null,await window.stillnote.rememberNote(null);const O=zs();O.length?await mi(O[Math.max(0,Math.min(p,O.length-1))]):AO()}Re(`${n.type==="folder"?"Folder":"File"} deleted`)}catch(c){Re(c.message||"Could not delete item.")}}function dM(){const n=L("#topbar-search");if(n.classList.contains("is-open")){L("#search-input").focus();return}n.classList.add("is-open"),L(".search-trigger").setAttribute("aria-expanded","true"),L("#search-input").value="",OM(""),L("#search-input").focus()}function $O(){L("#topbar-search").classList.remove("is-open"),L(".search-trigger").setAttribute("aria-expanded","false")}function uM(n){var e,t,i,s,r;S.theme=["light","sepia","dark"].includes(n)?n:"light",L(".app-shell").dataset.theme=S.theme,localStorage.setItem("stillnote-theme",S.theme),(t=(e=S.structured)==null?void 0:e.refreshCanvas)==null||t.call(e),(r=(s=(i=S.structured)==null?void 0:i.desmos)==null?void 0:s.updateSettings)==null||r.call(s,{invertedColors:!1}),document.querySelectorAll(".theme-card").forEach(a=>a.setAttribute("aria-pressed",String(a.dataset.theme===S.theme)))}function xz(){uM(localStorage.getItem("stillnote-theme")||"light"),window.stillnote.restoreSession().then(async n=>{n&&(await jT(n),n.lastNote&&zs().includes(n.lastNote)?await mi(n.lastNote):zs().length?await mi(zs()[0]):AO())}).catch(n=>console.error("Could not restore workspace:",n))}function fM(n){document.querySelectorAll(".settings-tab").forEach(e=>e.classList.toggle("active",e.dataset.tab===n)),document.querySelectorAll(".settings-section").forEach(e=>{const t=e.dataset.section===n;e.classList.toggle("active",t),e.hidden=!t}),n==="dictionary"&&cc(),n==="tasks"&&wo(!0)}function pM(n,e){var t;if(n==="notes"){if(!["left","right","bottom","hidden"].includes(e))return;S.toolbarPositions.notes=e,localStorage.setItem("stillnote-notes-toolbar-position",e);const i=L("#note-editor");i.dataset.toolbarPosition=e;const s=!!(S.view&&!S.structured&&e!=="hidden");L("#note-format-toolbar").hidden=!s,i.classList.toggle("has-markdown-editor",s)}else{if(!["left","right","bottom"].includes(e))return;S.toolbarPositions.canvas=e,localStorage.setItem("stillnote-canvas-toolbar-position",e),((t=S.structured)==null?void 0:t.type)==="canvas"&&(document.querySelector(".canvas-editor").dataset.toolbarPosition=e)}}async function DO(){const n=L("#ai-key-status");try{const e=await window.stillnote.aiKeyStatus();n.textContent=e.vaultOpen?e.configured?"Key saved in this vault":"No key saved":"Open a vault to save keys",n.className=`key-status${e.configured?" configured":""}`,In("ai",e.configured,e.configured?"API key saved":"API key missing"),L("#save-ai-key").disabled=!e.secureStorageAvailable||!e.vaultOpen,L("#remove-ai-key").disabled=!e.vaultOpen,e.secureStorageAvailable||(n.textContent="Secure key storage is unavailable")}catch{n.textContent="Could not check key status",In("ai",!1,"Could not check API key")}}async function mM(){const n=await window.stillnote.desmosKeyStatus().catch(()=>({configured:!1,vaultOpen:!1,secureStorageAvailable:!1})),e=n.vaultOpen?n.configured?"API key saved in this vault":"API key missing":"Open a vault to save keys";In("desmos",n.configured,e),L("#save-desmos-key").disabled=!n.vaultOpen||!n.secureStorageAvailable,L("#remove-desmos-key").disabled=!n.vaultOpen}function In(n,e,t){const i=document.querySelector(`[data-health="${n}"]`);if(!i)return;i.innerHTML=e?fe.statusCheck:fe.statusX,i.classList.toggle("is-ok",!!e),i.classList.toggle("is-off",!e),i.title=t;const s=i.closest(".settings-tab"),r=s&&[...s.querySelectorAll("span:not(.settings-health-indicator)")].map(a=>a.textContent.trim()).filter(Boolean).at(-1);s&&s.setAttribute("aria-label",`${r||n}: ${t}`)}let dg=0;async function la(n="theme"){var i,s;const e=L("#settings-overlay"),t=L(".settings-modal");dg++,e.hidden=!1,xo(e,{opacity:[0,1],duration:bo(120),ease:"outQuad"}),xo(t,{opacity:[0,1],scale:[.985,1],duration:bo(150),ease:"outQuad"}),fM(n),L("#directory-name").textContent=((i=S.vault)==null?void 0:i.name)||"No folder open",L("#directory-path").textContent=((s=S.vault)==null?void 0:s.path)||"Choose a folder to see its location.",In("directory",!!S.vault,S.vault?"Folder open":"No folder open"),L("#ai-model").value=localStorage.getItem("stillnote-ai-model")||"glm-4.6",L("#desmos-api-key").value=S.vault?await window.stillnote.getDesmosKey().catch(()=>""):"",await mM(),L("#notes-toolbar-position").value=S.toolbarPositions.notes,L("#canvas-toolbar-position").value=S.toolbarPositions.canvas,syncProofreadingSettings(),DO(),IO(),wo(!0)}async function wo(n=!1){const e=L("#google-tasks-status");try{const t=await window.stillnote.googleTasksStatus();n&&(L("#google-tasks-client-id").value=t.clientId||""),L("#save-google-tasks-client").disabled=!t.secureStorageAvailable||!t.vaultOpen,L("#connect-google-tasks").disabled=!t.vaultOpen||!t.clientIdConfigured||!t.clientSecretConfigured||!t.secureStorageAvailable,L("#disconnect-google-tasks").disabled=!t.connected,t.connected?(await window.stillnote.listGoogleTaskLists(),e.textContent="Connected and responding",e.className="key-status configured",In("tasks",!0,"Google Tasks connection working")):(e.textContent=t.vaultOpen?t.clientIdConfigured?t.clientSecretConfigured?"Not connected":"Client secret needed":"Client ID needed":"Open a vault to save credentials",e.className="key-status",In("tasks",!1,t.vaultOpen?t.clientIdConfigured?t.clientSecretConfigured?"Google account not connected":"Client secret missing":"Client ID missing":"Open a vault first")),t.secureStorageAvailable||(e.textContent="Secure storage is unavailable")}catch(t){e.textContent=t.message||"Could not check Google Tasks",e.className="key-status error",L("#disconnect-google-tasks").disabled=!1,In("tasks",!1,"Google Tasks connection not working")}}async function IO(){const n=L("#ai-model"),e=L("#ai-model-status"),t=localStorage.getItem("stillnote-ai-model")||"glm-4.6";n.disabled=!0,e.textContent="Loading available models…";try{const i=await window.stillnote.listAiModels();In("ai",!0,"AI API key working");const s=[...new Set([t,...i].filter(Boolean))];n.replaceChildren(...s.map(r=>{const a=document.createElement("option");return a.value=r,a.textContent=r,a})),n.value=s.includes(t)?t:i[0]||t,localStorage.setItem("stillnote-ai-model",n.value),e.textContent=i.length?`${i.length} models available from Ollama Cloud.`:"No models were returned for this account."}catch(i){In("ai",!1,"AI API key not working");const s=document.createElement("option");s.value=t,s.textContent=`${t} (saved selection)`,n.replaceChildren(s),n.value=t,e.textContent=i.message||"Save a valid API key to load available models."}finally{n.disabled=!1}}function UO(){const n=L("#settings-overlay"),e=L(".settings-modal"),t=++dg;xo(e,{opacity:[1,0],scale:[1,.99],duration:bo(90),ease:"inQuad"}),xo(n,{opacity:[1,0],duration:bo(100),ease:"inQuad",onComplete:()=>{t===dg&&(n.hidden=!0,n.style.opacity="",e.style.opacity="",e.style.transform="")}})}function xh(){L("#assistant-messages").innerHTML='<div class="assistant-welcome"><div class="assistant-welcome-icon">'+fe.assistant+"</div><strong>What would you like to do?</strong><p>Ask a question about this note, or ask me to edit it.</p></div>"}function Bd(n){n&&S.home||(S.assistantOpen=n,L(".workspace").classList.toggle("assistant-open",n),L("#assistant-toggle").setAttribute("aria-pressed",String(n)),n&&L("#assistant-input").focus())}function vz(){const n=L(".workspace"),e=L("#sidebar-resizer"),t=L("#assistant-resizer"),i=()=>{n.style.setProperty("--sidebar-width",`${S.sidebarWidth}px`),n.style.setProperty("--assistant-width",`${S.assistantWidth}px`),e.setAttribute("aria-valuenow",String(S.sidebarWidth)),t.setAttribute("aria-valuenow",String(S.assistantWidth))},s=(a,o)=>{const l=n.getBoundingClientRect();if(a==="explorer"){const c=Math.max(190,Math.min(440,l.width-(S.assistantOpen?S.assistantWidth:0)-340));S.sidebarWidth=Math.max(190,Math.min(c,o-l.left))}else{const c=S.sidebarOpen?S.sidebarWidth:0,h=Math.max(280,Math.min(560,l.width-c-340));S.assistantWidth=Math.max(280,Math.min(h,l.right-o))}i()};let r=null;for(const[a,o]of[[e,"explorer"],[t,"assistant"]])a.addEventListener("pointerdown",l=>{var c;l.button===0&&(l.preventDefault(),r=o,a.classList.add("is-active"),document.body.classList.add("resizing-panels"),(c=a.setPointerCapture)==null||c.call(a,l.pointerId))}),a.addEventListener("keydown",l=>{if(!["ArrowLeft","ArrowRight"].includes(l.key))return;l.preventDefault();const c=l.shiftKey?40:16,h=l.key==="ArrowRight"?c:-c,d=n.getBoundingClientRect(),u=o==="explorer"?d.left+S.sidebarWidth+h:d.right-S.assistantWidth-h;s(o,u)});window.addEventListener("pointermove",a=>{r&&s(r,a.clientX)}),window.addEventListener("pointerup",()=>{r&&(r=null,document.body.classList.remove("resizing-panels"),e.classList.remove("is-active"),t.classList.remove("is-active"),localStorage.setItem("stillnote-sidebar-width",String(S.sidebarWidth)),localStorage.setItem("stillnote-assistant-width",String(S.assistantWidth)))}),i()}function Ds(n,e){const t=document.createElement("div");return t.className=`chat-bubble ${n}`,t.textContent=e,L("#assistant-messages").append(t),L("#assistant-messages").scrollTop=L("#assistant-messages").scrollHeight,t}function xl(){var n;return S.structured?hc(S.structured.type,S.structured.title||at(S.active),S.structured.data):((n=S.view)==null?void 0:n.state.doc.toString())||""}function hr(){var i,s;const n=document.querySelector('.assistant-mode[data-mode="edit"]'),e=((i=S.structured)==null?void 0:i.type)==="tasks",t=(s=S.active)==null?void 0:s.toLowerCase().endsWith(".pdf");n&&(n.disabled=!!t,n.title=t?"PDF files are read-only":""),t&&S.assistantMode==="edit"&&(S.assistantMode="ask",document.querySelectorAll(".assistant-mode").forEach(r=>r.classList.toggle("active",r.dataset.mode==="ask"))),n&&(n.textContent=e?"Add tasks":"Edit note"),L("#assistant-input").placeholder=t?"Ask about this PDF…":S.assistantMode==="edit"?e?"Describe tasks to add…":`Describe a change to this ${Fd(S.active||"")?"code file":"note"}…`:e?"Ask about this task sheet…":`Ask about this ${Fd(S.active||"")?"code file":"note"}…`}async function yz(n,e,t){const i=S.structured;if(!i||i.type!=="tasks"||S.active!==e||xl()!==t)throw new Error("The task sheet changed while Ollama was working. Please try again.");if(!Array.isArray(n)||!n.length)return 0;if(n.length>30)throw new Error("Ollama returned too many tasks to add at once.");const s=n.map(o=>{const l=String((o==null?void 0:o.title)||"").trim(),c=String((o==null?void 0:o.notes)||"").trim(),h=String((o==null?void 0:o.due)||"").trim(),d=String((o==null?void 0:o.parentTitle)||"").trim();if(!l||l.length>1024)throw new Error("Ollama returned a task with an invalid title.");if(c.length>8192)throw new Error(`Details for “${l}” are too long.`);if(h&&(!/^\d{4}-\d{2}-\d{2}$/.test(h)||Number.isNaN(Date.parse(`${h}T00:00:00Z`))))throw new Error(`Ollama returned an invalid due date for “${l}”.`);return{title:l,notes:c,due:h,parentTitle:d}}),r=new Map(i.data.tasks.map(o=>[o.title.toLocaleLowerCase(),o]));let a=0;try{for(const o of s){if(S.structured!==i||S.active!==e)throw new Error("The task sheet was closed before all tasks were added.");const l=o.parentTitle?r.get(o.parentTitle.toLocaleLowerCase()):null;if(o.parentTitle&&!l)throw new Error(`Could not find parent task “${o.parentTitle}”. Add parent tasks before their subtasks.`);const c=await window.stillnote.createGoogleTask(i.data.listId,o.title,l==null?void 0:l.id);if(S.structured!==i||S.active!==e)throw new Error(`Added “${c.title||o.title}” to Google Tasks, but the task sheet was closed before Stillnote could refresh.`);const h={id:c.id,title:c.title||o.title,status:c.status||"needsAction",due:c.due||null,notes:c.notes||"",parent:c.parent||(l==null?void 0:l.id)||null,starred:!1};if(i.data.tasks.push(h),r.set(h.title.toLocaleLowerCase(),h),a++,o.notes||o.due){const d={};o.notes&&(d.notes=o.notes),o.due&&(d.due=`${o.due}T00:00:00.000Z`);try{const u=await window.stillnote.updateGoogleTask(i.data.listId,h.id,d);if(S.structured!==i||S.active!==e)throw new Error("The task sheet was closed before the task details could be updated.");h.notes=u.notes||o.notes,h.due=u.due||(o.due?`${o.due}T00:00:00.000Z`:null)}catch(u){throw new Error(`Added “${h.title}”, but its details could not be saved: ${u.message}`)}}Ct()}}catch(o){throw a&&S.structured===i&&S.active===e&&(Ct(),Hl("tasks",i.data,e,i.title||at(e))),o}return Hl("tasks",i.data,e,i.title||at(e)),a}function bz(n,e,t,i){var c;if(S.active!==t||xl()!==i)return Ds("assistant error","The document changed while I was working, so I did not apply the edit. Please send the request again."),!1;let s=e;const r=((c=S.structured)==null?void 0:c.type)||null;if(r){const h=kO(e);if(!h||h.type!==r)return Ds("assistant error",`The assistant returned invalid ${r} data, so I did not apply the edit.`),!1;const d=S.structured;d.data=h.data,Ct();const u={undoStack:d.undoStack,redoStack:d.redoStack,historySnapshot:d.historySnapshot,historyPending:d.historyPending,historyTimer:d.historyTimer};Hl(r,d.data,t,d.title||at(t)),Object.assign(S.structured,u),gu(),s=xl()}else{if(!S.view)return Ds("assistant error","The note is no longer open, so I did not apply the edit."),!1;S.view.dispatch({changes:{from:0,to:S.view.state.doc.length,insert:s}}),S.view.focus()}const a=document.createElement("p");a.textContent="I updated the document.",n.append(a);const o=document.createElement("button");o.className="undo-ai-edit-button",o.type="button",o.textContent="Undo changes";let l=!0;return o.addEventListener("click",()=>{if(S.active!==t){Re("Open the edited document to undo or redo this change.");return}const h=l?s:i;if(xl()!==h){Re("The document has changed since the AI edit; undo was not applied.");return}if(r)ia(l?"undo":"redo");else{if(!S.view){Re("Open the edited document to undo or redo this change.");return}S.view.dispatch({changes:{from:0,to:S.view.state.doc.length,insert:l?i:s}}),S.view.focus()}l=!l,o.textContent=l?"Undo changes":"Redo changes"}),n.append(o),L("#assistant-messages").scrollTop=L("#assistant-messages").scrollHeight,!0}async function _z(n){var h;n.preventDefault();const e=L("#assistant-input").value.trim();if(!e)return;const t=S.active,i=!!(t!=null&&t.toLowerCase().endsWith(".pdf"));if(!t||!S.view&&!S.structured&&!i){Re("Open a note, code file, PDF, canvas, spreadsheet, or graph before using the assistant.");return}let s;try{s=await window.stillnote.aiKeyStatus()}catch(d){Re(d.message||"Could not check Ollama key status.");return}if(!s.configured){la("ai");return}const r=i?"ask":S.assistantMode,a=i?"pdf":((h=S.structured)==null?void 0:h.type)||(Fd(t)?"code":"markdown"),o=L("#ai-model").value.trim()||localStorage.getItem("stillnote-ai-model")||"glm-4.6";localStorage.setItem("stillnote-ai-model",o);const l=L(".assistant-welcome");l&&l.remove(),Ds("user",e);const c=Ds("assistant loading","Thinking…");L("#assistant-input").value="",L("#assistant-send").disabled=!0;try{const d=i?await JX(t):xl();if(S.active!==t)throw new Error("The active file changed before the assistant request started. Please send it again.");const u=await window.stillnote.askAi({mode:r,model:o,noteName:at(t),documentType:a,document:d,prompt:e,history:S.chatHistory});if(c.remove(),a==="tasks"&&u.kind==="tasks"){const f=await yz(u.tasks,t,d),p=f?`Added ${f} ${f===1?"task":"tasks"} to Google Tasks.`:"No tasks were added.";Ds("assistant",p),S.chatHistory.push({role:"user",content:e},{role:"assistant",content:p})}else if(r==="edit"&&u.kind==="edit"){const f=document.createElement("div");f.className="chat-bubble assistant",L("#assistant-messages").append(f),bz(f,u.text,t,d)?S.chatHistory.push({role:"user",content:e},{role:"assistant",content:"Applied the requested changes to the document."}):f.remove()}else Ds("assistant",u.text),S.chatHistory.push({role:"user",content:e},{role:"assistant",content:u.text});S.chatHistory=S.chatHistory.slice(-8)}catch(d){c.remove(),Ds("assistant error",d.message||"The assistant could not respond.")}finally{L("#assistant-send").disabled=!1}}let fi=!1,NO=0,ug=null,zi="",gn=null,fg=null,To=Promise.resolve(),pg=Promise.resolve(),es=null,wz=0;const ol=new Map;let Fa=null,Ti=null,vl=null,ur=null,yl=[],bl=0,to=0,Mo=Promise.resolve();function ui(n,e=fi){const t=L("#meeting-notes-trigger");t.title=n,t.setAttribute("aria-label",n),t.classList.toggle("is-recording",e),t.classList.toggle("has-transcript",!!(gn&&zi.trim())&&!e),t.setAttribute("aria-pressed",String(e))}function fy(){const n=Math.max(0,Math.floor((Date.now()-NO)/1e3)),e=String(Math.floor(n/60)).padStart(2,"0"),t=String(n%60).padStart(2,"0");L("#meeting-notes-trigger .meeting-duration").textContent=`${e}:${t}`}function yu(){clearInterval(ug),ug=null,NO=0,L("#meeting-notes-trigger .meeting-duration").hidden=!0}function Tz(){if(!gn)return;const n=gn,e=zi;To=To.catch(()=>{}).then(()=>window.stillnote.writeMeetingTranscript(n,e))}async function Vd(){const n=gn;gn=null,n&&(await Mo.catch(()=>{}),await To.catch(()=>{}),await window.stillnote.clearMeetingTranscript(n).catch(()=>{})),zi="",ui("Click to start recording",!1)}function FO(){yu(),fi&&(fi=!1,to++,bu(!1)),gn&&Vd()}function Mz(){return es||(es=new Worker(new URL(""+new URL("whisper-worker-DcYN39bN.js",import.meta.url).href,import.meta.url),{type:"module"}),es.addEventListener("message",({data:n})=>{var t;const e=ol.get(n.id);if(n.type==="progress"){if(fi){const i=Number.isFinite((t=n.progress)==null?void 0:t.progress)?` ${Math.round(n.progress.progress)}%`:"";ui(`Downloading local Whisper model${i}…`)}return}e&&(ol.delete(n.id),n.type==="result"?e.resolve(n.text):e.reject(new Error(n.message||"Local Whisper could not transcribe this audio.")))}),es.addEventListener("error",n=>{const e=new Error(n.message||"The local Whisper worker stopped unexpectedly.");for(const t of ol.values())t.reject(e);ol.clear(),es==null||es.terminate(),es=null}),es)}function Pz(n){const e=Mz(),t=++wz,i=n.slice();return new Promise((s,r)=>{ol.set(t,{resolve:s,reject:r}),e.postMessage({type:"transcribe",id:t,audio:i.buffer},[i.buffer])})}function Ez(n,e){const i=e/16e3,s=new Float32Array(Math.floor(n.length/i));for(let r=0;r<s.length;r++){const a=r*i,o=Math.floor(a),l=a-o;s[r]=n[o]*(1-l)+(n[Math.min(o+1,n.length-1)]||0)*l}return s}function Az(n,e){const t=Ez(n,(Ti==null?void 0:Ti.sampleRate)||48e3);let i=0;for(let s=0;s<t.length;s+=16)i+=t[s]*t[s];!t.length||Math.sqrt(i/Math.ceil(t.length/16))<.004||(Mo=Mo.then(async()=>{if(e!==to||!gn)return;fi&&ui("Transcribing locally with Whisper Small…");const s=await Pz(t);e!==to||!gn||!s||(zi=`${zi} ${s}`.trim(),Tz(),fi&&ui("Recording locally with Whisper Small…"))}).catch(s=>{if(e!==to)return;fi=!1,yu(),bu(!1);const r=`Local Whisper stopped: ${s.message}`;ui(r,!1),Re(r)}))}function gM(n=!1){if(!yl.length||!Ti)return;const e=Ti.sampleRate;if(!n&&bl<e*30)return;const t=new Float32Array(bl);let i=0;for(const s of yl)t.set(s,i),i+=s.length;yl=[],bl=0,Az(t,to)}async function bu(n){if(n&&gM(!0),ur){ur.onaudioprocess=null;try{ur.disconnect()}catch{}}if(vl)try{vl.disconnect()}catch{}Fa==null||Fa.getTracks().forEach(t=>t.stop());const e=Ti;ur=null,vl=null,Fa=null,Ti=null,e&&e.state!=="closed"&&await e.close().catch(()=>{})}async function kz(){Fa=await navigator.mediaDevices.getUserMedia({audio:{channelCount:1,echoCancellation:!0,noiseSuppression:!0},video:!1}),Ti=new AudioContext,await Ti.resume(),vl=Ti.createMediaStreamSource(Fa),ur=Ti.createScriptProcessor(4096,1,1),ur.onaudioprocess=n=>{if(n.outputBuffer.getChannelData(0).fill(0),!fi)return;const e=n.inputBuffer.getChannelData(0).slice();yl.push(e),bl+=e.length,gM()},vl.connect(ur),ur.connect(Ti.destination)}async function Cz(){try{to++,yl=[],bl=0,zi="",fg=null,gn=await window.stillnote.createMeetingTranscript(),To=Promise.resolve(),Mo=Promise.resolve(),fi=!0,await kz(),NO=Date.now(),fy(),L("#meeting-notes-trigger .meeting-duration").hidden=!1,ug=setInterval(fy,250),ui("Recording locally; click when finished to create a summary and save the transcript. Whisper Small downloads on first use.")}catch(n){fi=!1,yu(),await bu(!1);const e=gn;gn=null,e&&window.stillnote.clearMeetingTranscript(e).catch(()=>{}),ui(n.message||"Could not start recording",!1),Re(n.message||"Could not start recording.")}}function Rz(){return fi?(fi=!1,yu(),ui("Finishing transcription and creating summary…",!1),pg=(async()=>{try{await bu(!0),await Mo,await To,gn&&(zi=await window.stillnote.readMeetingTranscript(gn))}catch(n){Re(n.message||"Could not finish the local transcript.")}return Qz(),{transcript:zi,id:gn}})(),pg):(async()=>(await Mo,await To,gn&&(zi=await window.stillnote.readMeetingTranscript(gn)),{transcript:zi,id:gn}))()}async function Qz(){const n=zi.trim();if(!n){ui("No speech was captured; click to record again",!1),Vd();return}if(!S.view||!S.active||S.home){ui("Open a note to insert meeting notes",!1);return}const e=S.active,t=S.view.state.doc.toString(),i=L("#ai-model").value.trim()||localStorage.getItem("stillnote-ai-model")||"glm-4.6";try{const s=e.includes("/")?e.slice(0,e.lastIndexOf("/")):"",r=at(e).replace(/\.md$/i,""),a=new Date().toLocaleString([],{year:"numeric",month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"}).replace(/[/:]/g,"-"),o=`${r} transcript ${a}`,l=await window.stillnote.createNote(o,s);if(await window.stillnote.writeNote(l,`${at(l)}
|
|
4475
4475
|
|
|
4476
4476
|
${n}
|
|
4477
4477
|
`),fg=l,[S.files,S.tree]=await Promise.all([window.stillnote.listNotes(),window.stillnote.getVaultTree()]),Ht(),!(await window.stillnote.aiKeyStatus().catch(()=>({configured:!1}))).configured){ui("Transcript saved; add your Ollama key in Settings → AI settings to create the summary",!1),la("ai");return}if(n.length>1e5){ui("Transcript saved; it is too long to summarize automatically",!1),Re("Transcript saved, but it is too long to summarize automatically.");return}const h=await window.stillnote.askAi({mode:"edit",model:i,noteName:at(e),documentType:"markdown",document:t,prompt:`Summarize this meeting/class/seminar transcript into clear notes. Preserve all existing content and the title line exactly, and append the summary at the very bottom of the note. Include key points, decisions, and action items when present. Do not invent details. Do not use Markdown tables. The full transcript is saved in the linked note <[${l.replace(/\.md$/i,"")}]>.
|
|
@@ -4480,4 +4480,4 @@ Transcript:
|
|
|
4480
4480
|
${n}`});if(h.kind!=="edit"||S.active!==e||!S.view||S.view.state.doc.toString()!==t)throw new Error("The note changed while the recording was being processed.");const d=`${h.text.replace(/\s*$/,"")}
|
|
4481
4481
|
|
|
4482
4482
|
Full transcript: <[${l.replace(/\.md$/i,"")}]>
|
|
4483
|
-
`;S.view.dispatch({changes:{from:0,to:S.view.state.doc.length,insert:d}}),S.view.focus(),Re("Meeting summary added and transcript saved"),await Vd()}catch(s){ui(`Transcript${fg?" saved":""}; ${s.message||"could not create notes"}`,!1),Re(s.message||"Could not create meeting notes.")}}L("#meeting-notes-trigger").addEventListener("click",()=>{fi?pg=
|
|
4483
|
+
`;S.view.dispatch({changes:{from:0,to:S.view.state.doc.length,insert:d}}),S.view.focus(),Re("Meeting summary added and transcript saved"),await Vd()}catch(s){ui(`Transcript${fg?" saved":""}; ${s.message||"could not create notes"}`,!1),Re(s.message||"Could not create meeting notes.")}}L("#meeting-notes-trigger").addEventListener("click",()=>{fi?pg=Rz():gn?Vd():Cz()});function OM(n){const e=L("#search-results");if(e.innerHTML="",!n.trim()){e.innerHTML='<div class="search-hint">Type to find a note by title</div>';return}const t=S.files.filter(i=>at(i).toLowerCase().includes(n.toLowerCase()));if(!t.length){e.innerHTML='<div class="search-hint">No matching notes</div>';return}for(const i of t.slice(0,8)){const s=document.createElement("button");s.className="search-result",s.innerHTML=`${fe.file}<span>${Ut(at(i))}</span><small>${Ut(i.includes("/")?i.split("/").slice(0,-1).join("/"):"Notes")}</small>`,s.addEventListener("click",()=>{$O(),mi(i)}),e.append(s)}}L(".vault-switcher").addEventListener("click",qs);L("#open-vault").addEventListener("click",()=>S.vault&&!S.files.length?Ou():qs());L("#new-file").addEventListener("click",n=>{n.stopPropagation(),fz(n.currentTarget)});document.addEventListener("click",n=>{!n.target.closest("#new-file-menu")&&!n.target.closest("#new-file")&&(L("#new-file-menu").hidden=!0)});L(".search-trigger").addEventListener("click",dM);L("#search-input").addEventListener("input",n=>OM(n.target.value));document.addEventListener("click",n=>{L("#topbar-search").classList.contains("is-open")&&!L("#topbar-search").contains(n.target)&&$O()});L("#refresh-notes").addEventListener("click",async()=>{await pz()});L("#expand-folders").addEventListener("click",()=>YT(!0));L("#collapse-folders").addEventListener("click",()=>YT(!1));L("#new-folder").addEventListener("click",()=>QO());document.addEventListener("click",n=>{!L("#explorer-context-menu").hidden&&!L("#explorer-context-menu").contains(n.target)&&LO()});document.addEventListener("click",n=>{!L("#editor-context-menu").hidden&&!L("#editor-context-menu").contains(n.target)&&pu()});L(".sidebar-toggle").addEventListener("click",()=>{S.sidebarOpen=!S.sidebarOpen,L(".workspace").classList.toggle("sidebar-collapsed",!S.sidebarOpen)});L("#settings-button").addEventListener("click",()=>la());L("#settings-close").addEventListener("click",UO);L("#settings-overlay").addEventListener("click",n=>{n.target===L("#settings-overlay")&&UO()});L("#rename-form").addEventListener("submit",n=>{n.preventDefault(),xu(L("#rename-input").value.trim())});L("#rename-cancel").addEventListener("click",()=>xu());L("#rename-overlay").addEventListener("click",n=>{n.target===L("#rename-overlay")&&xu()});L("#delete-cancel").addEventListener("click",()=>vu(!1));L("#delete-confirm").addEventListener("click",()=>vu(!0));L("#delete-overlay").addEventListener("click",n=>{n.target===L("#delete-overlay")&&vu(!1)});document.querySelectorAll(".settings-tab").forEach(n=>n.addEventListener("click",()=>fM(n.dataset.tab)));L("#custom-dictionary-form").addEventListener("submit",n=>{n.preventDefault(),WT(L("#custom-dictionary-input").value)&&(L("#custom-dictionary-input").value="")});L("#notes-toolbar-position").addEventListener("change",n=>pM("notes",n.target.value));L("#canvas-toolbar-position").addEventListener("change",n=>pM("canvas",n.target.value));document.querySelectorAll(".theme-card").forEach(n=>n.addEventListener("click",()=>uM(n.dataset.theme)));L("#change-directory").addEventListener("click",async()=>{var n,e;await qs(),L("#directory-name").textContent=((n=S.vault)==null?void 0:n.name)||"No folder open",L("#directory-path").textContent=((e=S.vault)==null?void 0:e.path)||"Choose a folder to see its location."});L("#save-ai-key").addEventListener("click",async()=>{try{await window.stillnote.saveAiKey(L("#ai-key").value),L("#ai-key").value="",await DO(),await IO(),Re("Ollama Cloud key saved securely")}catch(n){L("#ai-key-status").textContent=n.message,L("#ai-key-status").className="key-status error"}});L("#remove-ai-key").addEventListener("click",async()=>{await window.stillnote.clearAiKey(),L("#ai-key").value="",await DO(),await IO()});L("#save-google-tasks-client").addEventListener("click",async()=>{try{await window.stillnote.saveGoogleTasksCredentials(L("#google-tasks-client-id").value,L("#google-tasks-client-secret").value),L("#google-tasks-client-secret").value="",await wo(),Re("Google OAuth credentials saved securely")}catch(n){L("#google-tasks-status").textContent=n.message||"Could not save client ID",L("#google-tasks-status").className="key-status error"}});L("#connect-google-tasks").addEventListener("click",async()=>{const n=L("#connect-google-tasks");n.disabled=!0,L("#google-tasks-status").textContent="Waiting for Google sign-in…";try{await window.stillnote.connectGoogleTasks(),await wo(),Re("Google Tasks connected")}catch(e){await wo(),L("#google-tasks-status").textContent=`Connection failed: ${e.message||"Could not connect Google Tasks"}`,L("#google-tasks-status").className="key-status error",In("tasks",!1,"Google Tasks connection failed")}});L("#disconnect-google-tasks").addEventListener("click",async()=>{try{await window.stillnote.disconnectGoogleTasks(),await wo(),Re("Google Tasks disconnected")}catch(n){Re(n.message||"Could not disconnect Google Tasks")}});function SM(){var e,t,i;if(((e=S.structured)==null?void 0:e.type)!=="graph")return;const n=document.querySelector(".graph-editor");(i=(t=S.structured.desmos)==null?void 0:t.destroy)==null||i.call(t),S.structured.desmos=null,n&&rM(n,S.structured.data)}L("#save-desmos-key").addEventListener("click",async()=>{const n=L("#desmos-api-key").value.trim();if(!n){Re("Enter a Desmos API key first.");return}try{await window.stillnote.saveDesmosKey(n),In("desmos",!0,"API key saved in this vault"),Re("Desmos key saved securely in this vault"),SM()}catch(e){Re(e.message||"Could not save the Desmos key.")}});L("#remove-desmos-key").addEventListener("click",async()=>{var n,e,t;try{await window.stillnote.clearDesmosKey()}catch(i){Re(i.message||"Could not remove the Desmos key.");return}L("#desmos-api-key").value="",In("desmos",!1,"API key missing"),(t=(e=(n=S.structured)==null?void 0:n.desmos)==null?void 0:e.destroy)==null||t.call(e),S.structured&&(S.structured.desmos=null),SM(),Re("Desmos API key removed")});L("#ai-model").addEventListener("change",()=>localStorage.setItem("stillnote-ai-model",L("#ai-model").value||"glm-4.6"));L("#assistant-toggle").addEventListener("click",()=>Bd(!S.assistantOpen));L("#home-button").addEventListener("click",()=>{var n;S.home?(n=L("#home-input"))==null||n.focus():HX()});document.querySelectorAll(".assistant-mode").forEach(n=>n.addEventListener("click",()=>{S.assistantMode=n.dataset.mode,document.querySelectorAll(".assistant-mode").forEach(e=>e.classList.toggle("active",e===n)),hr()}));L("#assistant-form").addEventListener("submit",_z);L("#assistant-input").addEventListener("keydown",n=>{n.key==="Enter"&&!n.shiftKey&&!n.isComposing&&(n.preventDefault(),L("#assistant-form").requestSubmit())});document.addEventListener("keydown",n=>{var t;const e=n.metaKey||n.ctrlKey;if(((t=S.structured)==null?void 0:t.type)==="canvas"&&n.key==="Backspace"&&S.structured.deleteCanvasSelection&&!n.target.closest('input,textarea,[contenteditable="true"]')&&S.structured.data.elements.length&&document.querySelector(".canvas-svg .is-selected")){n.preventDefault(),S.structured.deleteCanvasSelection();return}if(S.structured&&e&&n.key.toLowerCase()==="z"){n.preventDefault(),ia(n.shiftKey?"redo":"undo");return}if(S.structured&&e&&n.key.toLowerCase()==="y"){n.preventDefault(),ia("redo");return}if(n.key==="Escape"&&!L("#rename-overlay").hidden){n.preventDefault(),xu();return}if(n.key==="Escape"&&!L("#delete-overlay").hidden){n.preventDefault(),vu(!1);return}e&&n.key.toLowerCase()==="k"&&(n.preventDefault(),dM()),n.key==="Escape"&&L("#topbar-search").classList.contains("is-open")&&$O(),n.key==="Escape"&&!L("#settings-overlay").hidden&&UO(),n.key==="Escape"&&!L("#explorer-context-menu").hidden&&LO(),n.key==="Escape"&&!L("#editor-context-menu").hidden&&pu(),n.key==="Escape"&&S.assistantOpen&&Bd(!1),e&&n.key.toLowerCase()==="n"&&n.shiftKey?(n.preventDefault(),QO()):e&&n.key.toLowerCase()==="n"&&(n.preventDefault(),Ou()),e&&n.key.toLowerCase()==="s"&&(n.preventDefault(),qn()),e&&n.key.toLowerCase()==="p"&&(n.preventDefault(),qX()),e&&n.key.toLowerCase()==="o"&&(n.preventDefault(),qs()),e&&n.key===","&&(n.preventDefault(),la()),e&&n.shiftKey&&n.key.toLowerCase()==="a"&&(n.preventDefault(),Bd(!S.assistantOpen))});window.addEventListener("beforeunload",()=>{var n,e;(e=(n=S.assetViewer)==null?void 0:n.destroy)==null||e.call(n),S.dirty&&S.active&&S.view?window.stillnote.writeNote(S.active,S.view.state.doc.toString()):S.dirty&&S.active&&S.structured&&window.stillnote.writeNote(S.active,hc(S.structured.type,S.structured.title||at(S.active),S.structured.data))});xz();
|