dsh-office-kit 0.3.1 → 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client.js +3 -3
- package/dist/client.js.map +1 -1
- package/dist/index.js +17 -11
- package/package.json +1 -1
- package/postinstall.mjs +41 -18
- package/python/office_cli.py +10 -1
package/dist/client.js
CHANGED
|
@@ -2,8 +2,8 @@ window.__ModuleLoader__.load({id:"dsh-office-kit",factory:(require)=>{var module
|
|
|
2
2
|
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("@deepseek-ai/dsh-client-ui-primitives"),t=require("react"),n=require("react/jsx-runtime");const r=[{id:`documents`,label:`Documents`,description:`Create, edit, render, and verify Word documents (.docx).`,hint:`DOCX`,skill:`office-documents`,command:`documents`,extensions:[`.docx`]},{id:`pdf`,label:`PDF`,description:`Create, read, edit, render, and verify PDF files.`,hint:`PDF`,skill:`office-pdf`,command:`pdf`,extensions:[`.pdf`]},{id:`presentations`,label:`Presentations`,description:`Create, edit, render, and verify slide decks (.pptx).`,hint:`PPTX`,skill:`office-presentations`,command:`presentations`,extensions:[`.pptx`]},{id:`spreadsheets`,label:`Spreadsheets`,description:`Create, edit, recalculate, render, and verify workbooks (.xlsx).`,hint:`XLSX`,skill:`office-spreadsheets`,command:`spreadsheets`,extensions:[`.xlsx`]}];function i(e){return r.find(t=>t.id===e)}function a(e){return r.find(t=>t.command===e)}const o=`dsh-office-kit`,s=`office`,c=`office`,l=`conversation.user.text.node`,u=`sidebar.right.tab.document.actions`,d=`officeAnnotation`,f=`<office-annotations>`,p=`</office-annotations>`,m=`canvas[role="img"][aria-label]`,h=`canvas.fortune-sheet-canvas`,g=2e4;function _(e,t){return e.replace(/\{(\w+)\}/gu,(e,n)=>t[n]??e)}function v(e){let t=[];for(let n of e.replace(/\r\n?/gu,`
|
|
3
3
|
`).split(`
|
|
4
4
|
`)){let e=n.replace(/\s+/gu,` `).trim();e.length>0&&t.push(e)}return t.join(`
|
|
5
|
-
`)}function y(e,t){let n=Math.min(e.left,t.left),r=Math.min(e.top,t.top);return{left:n,top:r,width:Math.max(e.left+e.width,t.left+t.width)-n,height:Math.max(e.top+e.height,t.top+t.height)-r}}function b(e,t){let n=Math.max(e.left,t.left),r=Math.max(e.top,t.top),i=Math.min(e.left+e.width,t.left+t.width)-n,a=Math.min(e.top+e.height,t.top+t.height)-r;return i>0&&a>0?{left:n,top:r,width:i,height:a}:void 0}function ee(e,t){return b({left:e.left-3,top:e.top-3,width:e.width+6,height:e.height+6},t)}function x(e,t,n){return t>=e.left&&t<=e.left+e.width&&n>=e.top&&n<=e.top+e.height}function S(e,t,n){return{left:Math.max(8,Math.min(e.left,n.width-t.width-8)),top:Math.max(8,Math.min(e.top>=t.height+8?e.top-t.height:e.top+e.height,n.height-t.height-8))}}function te(e,t,n){let r;for(let i of e){let e=i.box;(i.rects??[e]).some(e=>t>=e.left-8&&t<=e.left+e.width+8&&n>=e.top-4&&n<=e.top+e.height+4)&&(!r||e.width*e.height<r.box.width*r.box.height)&&(r=i)}return r}function C(e){let t=[];for(let n of[...e].sort((e,t)=>e.box.top-t.box.top||e.box.left-t.box.left)){if(!n.text.trim()||n.box.width<=0||n.box.height<=0)continue;let e=t.find(e=>Math.abs(e.box.top-n.box.top)<Math.min(e.box.height,n.box.height)*.45&&n.box.left>=e.box.left&&n.box.left-(e.box.left+e.box.width)<n.box.height*2);e?(e.text+=` ${n.text}`,e.box=y(e.box,n.box),e.rects.push(n.box)):t.push({text:n.text,box:n.box,rects:[n.box]})}let n=[];for(let e of t){let t=n.findLast(t=>{let n=e.box.top-(t.last.top+t.last.height),r=Math.min(t.last.left+t.last.width,e.box.left+e.box.width)-Math.max(t.last.left,e.box.left);return n>=-e.box.height*.2&&n<=Math.min(t.last.height,e.box.height)*.7&&r>0&&Math.abs(t.last.left-e.box.left)<e.box.height*2&&Math.max(t.last.height,e.box.height)/Math.min(t.last.height,e.box.height)<1.4});t?(t.text+=`\n${e.text}`,t.box=y(t.box,e.box),t.rects.push(...e.rects),t.last=e.box):n.push({...e,last:e.box})}return n.map(({text:e,box:t,rects:n})=>({text:v(e),box:t,rects:n}))}function ne(e){let t=e.parentElement;if(!t)return[];let n=document.createTreeWalker(t,NodeFilter.SHOW_TEXT),r=[];for(let e=n.nextNode();e;e=n.nextNode()){if(!e.textContent?.trim())continue;let t=document.createRange();t.selectNodeContents(e);let n=t.getBoundingClientRect();n.width>0&&n.height>0&&r.push({text:e.textContent,box:{left:n.left,top:n.top,width:n.width,height:n.height}})}return C(r)}function re(e){let t=e.parentElement;for(;t&&getComputedStyle(t).display===`contents`;)t=t.parentElement;return t?.parentElement?{header:t,root:t.parentElement}:void 0}function ie(e,t,n){let r=[...e.querySelectorAll(m)],i=r.findIndex(e=>x(e.getBoundingClientRect(),t,n)&&e.getBoundingClientRect().width>0);return i<0?void 0:{canvas:r[i],page:i+1}}function ae(e,t,n){let r=[...e.querySelectorAll(h)].find(e=>x(e.getBoundingClientRect(),t,n)&&e.getBoundingClientRect().width>0);return r?{canvas:r}:void 0}function w(e,t){if(t.width<=0||t.height<=0)throw Error(`annotation.emptyPage`);let n=b(e,t);if(!n)throw Error(`annotation.emptyRegion`);return{left:(n.left-t.left)/t.width,top:(n.top-t.top)/t.height,width:n.width/t.width,height:n.height/t.height}}async function oe(e,t,n=4e6,r=1/0){let i=e.canvas;if(!i||i.width<=0||i.height<=0)throw Error(`annotation.captureFailed`);let a=i.getBoundingClientRect(),o=e.region??w(e.box,a),s=i.width*o.width,c=i.height*o.height,l=Math.min(1,Math.sqrt(n/(s*c)),r/s,r/c);if(!Number.isFinite(l)||l<=0)throw Error(`annotation.captureFailed`);let u=document.createElement(`canvas`);u.width=Math.max(1,Math.floor(s*l)),u.height=Math.max(1,Math.floor(c*l));let d=u.getContext(`2d`);if(!d)throw Error(`annotation.captureFailed`);d.drawImage(i,o.left*i.width,o.top*i.height,s,c,0,0,u.width,u.height);let f=await new Promise((e,t)=>u.toBlob(n=>n?e(n):t(Error(`annotation.captureFailed`)),`image/png`));return new File([f],t,{type:`image/png`})}function T(e){if(typeof e!=`object`||!e)return!1;let t=e,n=(e,t)=>typeof e==`string`&&e.length<=t;if(!n(t.target,2e4)||!n(t.fileName,1e3)||!n(t.text,2e4)||!n(t.requirement,2e4)||!t.requirement.trim()||t.page!==void 0&&(!Number.isSafeInteger(t.page)||t.page<1)||t.imageName!==void 0&&!n(t.imageName,1e3)||t.sheet!==void 0&&(!n(t.sheet,1e3)||!t.sheet.trim())||t.range!==void 0&&(!n(t.range,100)||!t.range.trim())||t.unmapped!==void 0&&t.unmapped!==!0)return!1;if(t.region!==void 0){let e=t.region;if(!e||![`left`,`top`,`width`,`height`].every(t=>typeof e[t]==`number`&&Number.isFinite(e[t])&&e[t]>=0&&e[t]<=1)||e.width<=0||e.height<=0||e.left+e.width>1.000001||e.top+e.height>1.000001)return!1}return!0}function E(e){if(!e.length||e.length>50||!e.every(T))throw Error(`annotation.invalid`);let t=JSON.stringify(e).replace(/</gu,`\\u003c`);if(t.length>12e5)throw Error(`annotation.tooLarge`);return`${f}\n${t}\n${p}`}const D={id:d,order:10,match(e,t){for(let n=e.indexOf(f,t);n>=0;n=e.indexOf(f,n+20)){let t=e.indexOf(p,n+20);if(t<0)return;let r=e.slice(n+20,t).trim();if(!(r.length>12e5))try{let e=JSON.parse(r);if(Array.isArray(e)&&e.length>0&&e.length<=50&&e.every(T))return{id:d,start:n,end:t+21,data:{items:e}}}catch{}}}};function se({items:e,inputActions:t,intake:n,limits:r,existingImages:i,deferSubmit:a}){let o=E(e.map(e=>e.annotation)),s=e.flatMap(e=>e.file?[e.file]:[]);if(s.length&&!n)throw Error(`annotation.intakeUnavailable`);if(s.length&&r&&(s.some(e=>!r.mediaTypes.includes(e.type)||e.size>r.maxImageBytes)||i.length+s.length>r.maxImagesPerMessage||[...i,...s].reduce((e,t)=>e+t.size,0)>r.maxMessageImageBytes))throw Error(`annotation.imageLimit`);let c=t.captureInsertion(),l=s.length?n.create(s):[];if(l.length&&!t.addAttachments(l.map(e=>e.id)))throw n.release(l),Error(`annotation.sendFailed`);if(!t.insertText(`\n${o}\n`,{...c,start:c.end})){for(let e of l)t.removeAttachment(e.id);throw n?.release(l),Error(`annotation.sendFailed`)}try{return t.persistDraft(),a?`draft`:(t.submit(),`sent`)}catch{return`draft`}}function O({node:e,interactive:r,openAnnotation:i,t:a}){let o=(0,t.useId)(),s=(0,t.useRef)(null),c=(0,t.useRef)(null),[l,u]=(0,t.useState)(!1),d=_(a(`annotation.count`),{count:String(e.data.items.length)});return(0,t.useLayoutEffect)(()=>{let e=c.current,t=s.current;if(!e||!t)return;if(!l){e.hidePopover?.();return}e.showPopover?.();let n=()=>{let n={width:document.documentElement.clientWidth,height:window.innerHeight},{left:r,top:i}=S(t.getBoundingClientRect(),e.getBoundingClientRect(),n);e.style.left=`${r}px`,e.style.top=`${i}px`},r=t=>{t.target instanceof Node&&e.contains(t.target)||u(!1)},i=new ResizeObserver(n);return i.observe(t),i.observe(e),window.addEventListener(`resize`,n),document.addEventListener(`scroll`,r,!0),n(),()=>{e.hidePopover?.(),i.disconnect(),window.removeEventListener(`resize`,n),document.removeEventListener(`scroll`,r,!0)}},[l]),(0,n.jsxs)(`span`,{ref:s,className:`dsh-office-annotation-reference`,onPointerEnter:()=>u(!0),onPointerLeave:e=>{(!(e.relatedTarget instanceof Node)||!e.currentTarget.contains(e.relatedTarget))&&u(!1)},onFocus:()=>u(!0),onBlur:e=>{e.currentTarget.contains(e.relatedTarget)||u(!1)},onKeyDown:e=>{e.key===`Escape`&&(e.preventDefault(),e.stopPropagation(),c.current?.contains(e.target)&&s.current?.querySelector(`button`)?.focus(),u(!1))},children:[(0,n.jsx)(`button`,{type:`button`,id:`${o}-trigger`,"aria-haspopup":`dialog`,"aria-controls":o,"aria-expanded":l,children:d}),(0,n.jsx)(`span`,{ref:c,popover:`manual`,className:`dsh-office-annotation-popover`,"data-open":l,id:o,role:`dialog`,"aria-labelledby":`${o}-trigger`,children:(0,n.jsx)(`span`,{className:`dsh-office-annotation-list`,children:e.data.items.map((e,t)=>(0,n.jsxs)(`span`,{className:`dsh-office-annotation-item`,children:[(0,n.jsx)(`span`,{className:`dsh-office-annotation-source`,children:r?(0,n.jsx)(`button`,{type:`button`,onClick:()=>i(e.target),title:e.target,children:e.fileName}):(0,n.jsx)(`span`,{children:e.fileName})}),(0,n.jsx)(`span`,{className:`dsh-office-annotation-requirement`,children:e.requirement})]},t))})})]})}function k(e){return/\.(?:pdf|docx?|pptx|xlsx)$/iu.test(e.absolutePath)?(0,n.jsx)(A,{...e},e.absolutePath):null}function A({absolutePath:e,pendingAnnotations:r,intake:i,inputActions:a,useInput:o,useProjection:s,t:c}){let l=(0,t.useRef)(null),u=(0,t.useRef)(null),d=(0,t.useRef)(null),f=(0,t.useRef)(),[p,v]=(0,t.useState)(),[y,x]=(0,t.useState)(!1),[S,C]=(0,t.useState)(),[T,E]=(0,t.useState)(),[D,O]=(0,t.useState)(``),[k,A]=(0,t.useState)(),[j,M]=(0,t.useState)(!1),[N,P]=(0,t.useState)(!1),[F,I]=(0,t.useState)(()=>r.get(e)??[]),[ce,L]=(0,t.useState)(!1),R=(0,t.useId)(),[z,B]=(0,t.useState)(``),V=o(e=>e),H=s(`imageLimits`),U=/\.pdf$/iu.test(e),W=/\.xlsx$/iu.test(e),G=U||W,le=W?h:m,ue=e.replace(/\\/gu,`/`).split(`/`).pop()??e,K=(0,t.useRef)(0),q=(0,t.useRef)(),J=(0,t.useRef)(),Y=(0,t.useRef)(),de=V.phase!==`plain`;(0,t.useEffect)(()=>{F.length?r.set(e,F):r.delete(e)},[e,F,r]);function X(){K.current++,E(void 0),A(void 0),M(!1),O(``)}function Z(){clearTimeout(q.current),J.current=void 0,P(!1),C(void 0)}(0,t.useEffect)(()=>{let e=l.current,t=e&&re(e);if(!t)return;let{header:n,root:r}=t;f.current=r;let i=0,a=()=>{cancelAnimationFrame(i),i=requestAnimationFrame(()=>{Y.current=void 0;let e=r.getBoundingClientRect(),t=Math.max(e.top,n.getBoundingClientRect().bottom,0),i=Math.min(e.bottom,window.innerHeight),a=Math.max(0,e.left),o=Math.min(e.right,window.innerWidth),s=[...r.querySelectorAll(le)].find(e=>e.getBoundingClientRect().width>0),c=r.isConnected&&!r.closest(`[hidden], [aria-hidden="true"]`)&&getComputedStyle(r).visibility===`visible`;v(c&&e.height>40&&s&&o>a&&i>t?{left:a,top:t,width:o-a,height:i-t}:void 0),E(e=>{if(!e?.canvas||!e.region)return e;let t=e.canvas.getBoundingClientRect(),n=e.region,r={left:t.left+n.left*t.width,top:t.top+n.top*t.height,width:n.width*t.width,height:n.height*t.height};return Object.keys(r).every(t=>r[t]===e.box[t])?e:{...e,box:r}})})},o=new ResizeObserver(a);o.observe(r);let s=new MutationObserver(t=>{t.some(t=>!e.contains(t.target))&&a()});s.observe(r,{childList:!0,subtree:!0,attributes:!0,attributeFilter:[`hidden`,`aria-hidden`,`class`,`style`]});for(let e=r.parentElement;e;e=e.parentElement)s.observe(e,{attributes:!0});return window.addEventListener(`resize`,a),r.addEventListener(`transitionend`,a),r.addEventListener(`scroll`,a,!0),a(),()=>{K.current++,clearTimeout(q.current),cancelAnimationFrame(i),o.disconnect(),s.disconnect(),window.removeEventListener(`resize`,a),r.removeEventListener(`transitionend`,a),r.removeEventListener(`scroll`,a,!0),f.current=void 0}},[]),(0,t.useEffect)(()=>{if(!T)return;let e=e=>{e.target instanceof Node&&!u.current?.contains(e.target)&&X()};return document.addEventListener(`pointerdown`,e,!0),u.current?.querySelector(`input`)?.focus(),()=>{document.removeEventListener(`pointerdown`,e,!0)}},[T]),(0,t.useEffect)(()=>{y&&d.current?.focus()},[y]);function fe(e,t){let n=f.current;if(!n)return;let r=n.querySelector(le)?.parentElement;for(;r&&r!==n&&!/auto|scroll/u.test(getComputedStyle(r).overflowY);)r=r.parentElement;r?.scrollBy({left:e,top:t}),C(void 0)}(0,t.useEffect)(()=>{let e=d.current;if(!y||!e||!p)return;let t=e=>{e.preventDefault();let t=e.deltaMode===1?16:e.deltaMode===2?p.height:1;fe(e.deltaX*t,e.deltaY*t)};return e.addEventListener(`wheel`,t,{passive:!1}),()=>e.removeEventListener(`wheel`,t)},[y,p]);function pe(e,t){let n=f.current;if(n)return W?ae(n,e,t):ie(n,e,t)}function me(e,t){if(W||!f.current)return;let n=ie(f.current,e,t);if(!n)return;let r=n.canvas.getBoundingClientRect();(Y.current?.canvas!==n.canvas||Y.current.box.left!==r.left||Y.current.box.top!==r.top||Y.current.box.width!==r.width||Y.current.box.height!==r.height)&&(Y.current={canvas:n.canvas,box:r,paragraphs:ne(n.canvas)});let i=te(Y.current.paragraphs,e,t);return i?{...i,...n}:void 0}function he(e,t){let n=J.current;if(!n)return;let r=b({left:Math.min(n.x,e),top:Math.min(n.y,t),width:Math.abs(e-n.x),height:Math.abs(t-n.y)},n.canvas.getBoundingClientRect());if(!r)return;let i=Y.current?.canvas===n.canvas?Y.current.paragraphs:ne(n.canvas),a=W?``:i.filter(e=>(e.rects??[e.box]).some(e=>b(e,r))).map(e=>e.text).join(`
|
|
6
|
-
`).slice(0,g);return{canvas:n.canvas,page:n.page,box:r,region:w(r,n.canvas.getBoundingClientRect()),text:a}}function ge(e){if(e.button!==0||!f.current||G&&!i)return;let t=pe(e.clientX,e.clientY);if(!t)return;e.preventDefault(),X();let n={...t,x:e.clientX,y:e.clientY,lastX:e.clientX,lastY:e.clientY,region:!1};J.current=n,e.currentTarget.setPointerCapture(e.pointerId),q.current=setTimeout(()=>{J.current===n&&(n.region=!0,P(!0),C(he(n.lastX,n.lastY)))},350)}function _e(e){let t=J.current;t&&(t.lastX=e.clientX,t.lastY=e.clientY,!t.region&&Math.hypot(e.clientX-t.x,e.clientY-t.y)>=6&&(clearTimeout(q.current),t.region=!0,P(!0))),C(t?.region?he(e.clientX,e.clientY):me(e.clientX,e.clientY))}async function ve(e){X();let t=K.current;B(``);let n=e.canvas?.getBoundingClientRect(),r=n?ee(e.box,n):e.box;if(!r)return;let i=n?w(r,n):e.region,a={...e,box:r,region:i};if(E(a),G){M(!0);try{let n=e.page===void 0?`region`:`p${e.page}`,r=await oe(a,`${ue}-${n}-${Date.now()}.png`,H?.maxImagePixels,H?.maxImageDimension);K.current===t&&A(r)}catch{K.current===t&&B(c(`annotation.captureFailed`))}finally{K.current===t&&M(!1)}}}function ye(e){let t=J.current;if(clearTimeout(q.current),!t)return;let n=t.region?he(e.clientX,e.clientY):me(e.clientX,e.clientY),r=Math.hypot(e.clientX-t.x,e.clientY-t.y);Z(),n&&(t.region?n.box.width>=6&&n.box.height>=6:r<6)&&ve(n)}function be(){if(!T||!D.trim()||G&&!k||F.length>=50)return;let t={target:e,fileName:ue,page:T.page,text:T.text.slice(0,g),requirement:D.trim(),region:T.region,imageName:k?.name,...W?{unmapped:!0}:{}};I(e=>[...e,{annotation:t,file:k}]),X()}function xe(){if(!de)try{let e=se({items:F,inputActions:a,intake:i,limits:H,existingImages:i?.images(V.attachmentIds)??[],deferSubmit:!!V.draft.trim()||V.attachmentIds.length>0});I([]),L(!1),x(!1),X(),B(e===`draft`?c(`annotation.draftReady`):``)}catch(e){let t=e instanceof Error?e.message:`annotation.sendFailed`;B(c(t.startsWith(`annotation.`)?t:`annotation.sendFailed`))}}let Q=T??S,Se=Q&&!T&&!N&&Q.canvas?ee(Q.box,Q.canvas.getBoundingClientRect()):Q?.box,$=Se&&p?b(Se,p):void 0,Ce=p?Math.min(360,p.width-16):0,we=p&&T?Math.max(p.left+8,Math.min(T.box.left,p.left+p.width-Ce-8)):0,Te=p&&T?Math.max(p.top+4,Math.min(T.box.top+T.box.height+6,p.top+p.height-56)):0;return(0,n.jsxs)(`span`,{ref:l,className:`dsh-office-annotate`,onKeyDown:e=>{if(!y||e.key!==`Escape`)return;e.preventDefault(),e.stopPropagation();let t=!!T||!!J.current;X(),Z(),t?d.current?.focus():(x(!1),l.current?.querySelector(`button`)?.focus())},children:[(0,n.jsx)(`button`,{type:`button`,className:`dsh-office-annotate-toggle`,"aria-pressed":y,disabled:!p||G&&!i,title:c(G&&!i?`annotation.intakeUnavailable`:p?`annotation.help`:`annotation.unavailable`),onClick:()=>{x(e=>!e),X(),Z()},children:c(`annotation.ask`)}),G&&!i&&(0,n.jsx)(`span`,{role:`status`,className:`dsh-office-annotate-unavailable`,children:c(`annotation.intakeUnavailable`)}),y&&p&&(0,n.jsx)(`div`,{ref:d,className:`dsh-office-annotate-surface`,tabIndex:0,style:{left:p.left,top:p.top,width:p.width,height:p.height},role:`region`,"aria-label":c(`annotation.help`),onPointerDown:ge,onPointerMove:_e,onPointerUp:ye,onPointerCancel:Z,onLostPointerCapture:Z,onKeyDown:e=>{if(e.key===`PageDown`||e.key===`PageUp`)e.preventDefault(),fe(0,p.height*(e.key===`PageDown`?.8:-.8));else if(e.key===`ArrowDown`||e.key===`ArrowUp`){e.preventDefault();let t=[...f.current.querySelectorAll(`canvas[role="img"][aria-label]`)].flatMap((e,t)=>ne(e).filter(e=>b(e.box,p)).map(n=>({...n,canvas:e,page:t+1}))),n=t.findIndex(e=>e.canvas===S?.canvas&&e.text===S.text&&e.box.top===S.box.top),r=n<0?e.key===`ArrowDown`?0:t.length-1:Math.max(0,Math.min(t.length-1,n+(e.key===`ArrowDown`?1:-1)));C(t[r])}else(e.key===`Enter`||e.key===` `)&&S&&(e.preventDefault(),ve(S))},onPointerLeave:()=>{J.current||C(void 0)}}),y&&$&&(0,n.jsx)(`span`,{className:`dsh-office-annotate-highlight`,"data-selected":T||N?`true`:void 0,style:{left:$.left,top:$.top,width:$.width,height:$.height}}),y&&T&&p&&(0,n.jsxs)(`form`,{ref:u,className:`dsh-office-annotate-composer`,style:{left:we,top:Te,width:Ce},"aria-label":c(`annotation.ask`),"aria-busy":j,onSubmit:e=>{e.preventDefault(),be()},children:[(0,n.jsx)(`input`,{type:`text`,"aria-label":c(`annotation.placeholder`),placeholder:c(`annotation.placeholder`),value:D,maxLength:2e4,onChange:e=>O(e.target.value),onKeyDown:e=>{e.key===`Enter`&&e.nativeEvent.isComposing&&e.preventDefault()}}),(0,n.jsx)(`button`,{type:`submit`,"aria-label":c(j?`annotation.capturing`:`annotation.add`),title:c(j?`annotation.capturing`:`annotation.add`),disabled:!D.trim()||j||G&&!k||F.length>=50,children:(0,n.jsx)(`svg`,{width:`18`,height:`18`,viewBox:`0 0 24 24`,fill:`none`,"aria-hidden":`true`,children:(0,n.jsx)(`path`,{d:`m5 12 4 4L19 6`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`})})})]}),(y||F.length>0||z)&&p&&(0,n.jsx)(`div`,{className:`dsh-office-annotate-rail-position`,style:{left:p.left,width:p.width,bottom:Math.max(0,window.innerHeight-p.top-p.height)+12,"--dsh-office-annotation-width":`${p.width}px`,"--dsh-office-annotation-height":`${p.height}px`},children:(0,n.jsxs)(`div`,{className:`dsh-office-annotate-rail`,children:[z&&(0,n.jsx)(`p`,{role:`alert`,children:z}),(0,n.jsxs)(`div`,{className:`dsh-office-annotate-rail-actions`,children:[(0,n.jsxs)(`div`,{className:`dsh-office-annotate-summary`,"data-dismissed":ce?`true`:void 0,onPointerEnter:()=>L(!1),onFocus:()=>L(!1),onKeyDown:e=>{e.key===`Escape`&&(e.stopPropagation(),e.currentTarget.querySelector(`button`)?.focus(),L(!0))},children:[(0,n.jsx)(`button`,{type:`button`,"aria-haspopup":`dialog`,"aria-controls":R,disabled:!F.length,children:_(c(`annotation.count`),{count:String(F.length)})}),F.length>0&&(0,n.jsx)(`div`,{id:R,role:`dialog`,"aria-label":_(c(`annotation.count`),{count:String(F.length)}),className:`dsh-office-annotate-popover`,children:(0,n.jsx)(`ul`,{children:F.map((e,t)=>(0,n.jsx)(`li`,{children:(0,n.jsxs)(`div`,{children:[(0,n.jsxs)(`span`,{className:`dsh-office-annotation-source`,children:[(0,n.jsx)(`span`,{title:e.annotation.target,children:e.annotation.fileName}),e.annotation.page&&(0,n.jsx)(`span`,{children:_(c(`annotation.page`),{page:String(e.annotation.page)})})]}),e.annotation.text&&(0,n.jsx)(`span`,{className:`dsh-office-annotation-original`,children:e.annotation.text}),(0,n.jsx)(`span`,{className:`dsh-office-annotation-requirement`,title:e.annotation.requirement,children:e.annotation.requirement})]})},e.annotation.imageName??t))})})]}),(0,n.jsx)(`button`,{type:`button`,onClick:()=>{I([]),x(!1),L(!1),B(``),X(),Z()},children:c(`annotation.cancel`)}),(0,n.jsx)(`button`,{type:`button`,className:`dsh-office-annotate-primary`,disabled:!F.length||de,onClick:xe,children:c(`annotation.send`)})]})]})})]})}function j(e){let{size:t=16,...n}=e;return{width:t,height:t,viewBox:`0 0 16 16`,fill:`none`,"aria-hidden":!0,...n}}function M(e){return(0,n.jsx)(`svg`,{...j(e),children:(0,n.jsx)(`path`,{fill:`currentColor`,fillRule:`evenodd`,clipRule:`evenodd`,d:`M5 13.5h6a1.5 1.5 0 0 0 1.5-1.5V7.243a1.5 1.5 0 0 0-.44-1.061L8.819 2.939a1.5 1.5 0 0 0-1.06-.439H5A1.5 1.5 0 0 0 3.5 4v8A1.5 1.5 0 0 0 5 13.5m9-6.257a3 3 0 0 0-.879-2.122L9.88 1.88A3 3 0 0 0 7.757 1H5a3 3 0 0 0-3 3v8a3 3 0 0 0 3 3h6a3 3 0 0 0 3-3zM5 8.25a.75.75 0 0 1 .75-.75h4.5a.75.75 0 0 1 0 1.5h-4.5A.75.75 0 0 1 5 8.25m.75 2.25a.75.75 0 0 0 0 1.5h2.5a.75.75 0 0 0 0-1.5z`})})}function N(e){return(0,n.jsx)(`svg`,{...j(e),children:(0,n.jsx)(`path`,{fill:`currentColor`,fillRule:`evenodd`,clipRule:`evenodd`,d:`M11 13.5H5A1.5 1.5 0 0 1 3.5 12V4A1.5 1.5 0 0 1 5 2.5h2.757a1.5 1.5 0 0 1 1.061.44l3.243 3.242a1.5 1.5 0 0 1 .439 1.06V12a1.5 1.5 0 0 1-1.5 1.5m2.121-8.379A3 3 0 0 1 14 7.243V12a3 3 0 0 1-3 3H5a3 3 0 0 1-3-3V4a3 3 0 0 1 3-3h2.757a3 3 0 0 1 2.122.879zM6.5 6.5a.75.75 0 0 0-.75.75v4a.75.75 0 0 0 1.5 0v-.75H8.5a2 2 0 1 0 0-4zm2 2.5H7.25V8H8.5a.5.5 0 0 1 0 1`})})}function P(e){return(0,n.jsx)(`svg`,{...j(e),children:(0,n.jsx)(`path`,{fill:`currentColor`,fillRule:`evenodd`,clipRule:`evenodd`,d:`M12 3H4a1.5 1.5 0 0 0-1.5 1.5v4A1.5 1.5 0 0 0 4 10h8a1.5 1.5 0 0 0 1.5-1.5v-4A1.5 1.5 0 0 0 12 3M4 1.5a3 3 0 0 0-3 3v4a3 3 0 0 0 3 3h3.25V13h-2.5a.75.75 0 0 0 0 1.5h6.5a.75.75 0 0 0 0-1.5h-2.5v-1.5H12a3 3 0 0 0 3-3v-4a3 3 0 0 0-3-3z`})})}function F(e){return(0,n.jsx)(`svg`,{...j(e),children:(0,n.jsx)(`path`,{fill:`currentColor`,fillRule:`evenodd`,clipRule:`evenodd`,d:`M9.25 3.5h-2.5v2h2.5zM4 3.5h1.25v2H2.5V5A1.5 1.5 0 0 1 4 3.5M2.5 7h2.75v2H2.5zm0 3.5v.5A1.5 1.5 0 0 0 4 12.5h1.25v-2zm4.25 0v2h2.5v-2zm4 0v2H12a1.5 1.5 0 0 0 1.5-1.5v-.5zM13.5 9h-2.75V7h2.75zM9.25 9h-2.5V7h2.5zm1.5-5.5v2h2.75V5A1.5 1.5 0 0 0 12 3.5zM4 2a3 3 0 0 0-3 3v6a3 3 0 0 0 3 3h8a3 3 0 0 0 3-3V5a3 3 0 0 0-3-3z`})})}const I={documents:M,pdf:N,presentations:P,spreadsheets:F};function ce({node:e,raw:t,interactive:r,openOffice:a,officeLabel:o}){let s=i(e.data.feature);if(s==null)return(0,n.jsx)(`span`,{children:t});let c=I[s.id],l=(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(c,{className:`dsh-office-ref-icon`,size:14}),(0,n.jsx)(`span`,{children:o(s.id)})]});return r?(0,n.jsx)(`button`,{type:`button`,className:`dsh-office-ref`,title:t,"data-interactive":!0,onClick:()=>a(s.id),children:l}):(0,n.jsx)(`span`,{className:`dsh-office-ref`,title:t,children:l})}function L(){if(typeof document>`u`)return()=>{};let e=document.querySelector(`style[data-plugin-css="dsh-office-kit/reference.css"]`)??document.createElement(`style`);return e.dataset.plugin=o,e.dataset.pluginCss=`dsh-office-kit/reference.css`,e.textContent=`
|
|
5
|
+
`)}function y(e,t){let n=Math.min(e.left,t.left),r=Math.min(e.top,t.top);return{left:n,top:r,width:Math.max(e.left+e.width,t.left+t.width)-n,height:Math.max(e.top+e.height,t.top+t.height)-r}}function b(e,t){let n=Math.max(e.left,t.left),r=Math.max(e.top,t.top),i=Math.min(e.left+e.width,t.left+t.width)-n,a=Math.min(e.top+e.height,t.top+t.height)-r;return i>0&&a>0?{left:n,top:r,width:i,height:a}:void 0}function ee(e,t){return b({left:e.left-3,top:e.top-3,width:e.width+6,height:e.height+6},t)}function x(e,t,n){return t>=e.left&&t<=e.left+e.width&&n>=e.top&&n<=e.top+e.height}function S(e,t,n){return{left:Math.max(8,Math.min(e.left,n.width-t.width-8)),top:Math.max(8,Math.min(e.top>=t.height+8?e.top-t.height:e.top+e.height,n.height-t.height-8))}}function te(e,t,n){let r;for(let i of e){let e=i.box;(i.rects??[e]).some(e=>t>=e.left-8&&t<=e.left+e.width+8&&n>=e.top-4&&n<=e.top+e.height+4)&&(!r||e.width*e.height<r.box.width*r.box.height)&&(r=i)}return r}function C(e){let t=[];for(let n of[...e].sort((e,t)=>e.box.top-t.box.top||e.box.left-t.box.left)){if(!n.text.trim()||n.box.width<=0||n.box.height<=0)continue;let e=t.find(e=>Math.abs(e.box.top-n.box.top)<Math.min(e.box.height,n.box.height)*.45&&n.box.left>=e.box.left&&n.box.left-(e.box.left+e.box.width)<n.box.height*2);e?(e.text+=` ${n.text}`,e.box=y(e.box,n.box),e.rects.push(n.box)):t.push({text:n.text,box:n.box,rects:[n.box]})}let n=[];for(let e of t){let t=n.findLast(t=>{let n=e.box.top-(t.last.top+t.last.height),r=Math.min(t.last.left+t.last.width,e.box.left+e.box.width)-Math.max(t.last.left,e.box.left);return n>=-e.box.height*.2&&n<=Math.min(t.last.height,e.box.height)*.7&&r>0&&Math.abs(t.last.left-e.box.left)<e.box.height*2&&Math.max(t.last.height,e.box.height)/Math.min(t.last.height,e.box.height)<1.4});t?(t.text+=`\n${e.text}`,t.box=y(t.box,e.box),t.rects.push(...e.rects),t.last=e.box):n.push({...e,last:e.box})}return n.map(({text:e,box:t,rects:n})=>({text:v(e),box:t,rects:n}))}function ne(e){let t=e.parentElement;if(!t)return[];let n=document.createTreeWalker(t,NodeFilter.SHOW_TEXT),r=[];for(let e=n.nextNode();e;e=n.nextNode()){if(!e.textContent?.trim())continue;let t=document.createRange();t.selectNodeContents(e);let n=t.getBoundingClientRect();n.width>0&&n.height>0&&r.push({text:e.textContent,box:{left:n.left,top:n.top,width:n.width,height:n.height}})}return C(r)}function re(e){let t=e.parentElement;for(;t&&getComputedStyle(t).display===`contents`;)t=t.parentElement;return t?.parentElement?{header:t,root:t.parentElement}:void 0}function ie(e,t,n){let r=[...e.querySelectorAll(m)],i=r.findIndex(e=>x(e.getBoundingClientRect(),t,n)&&e.getBoundingClientRect().width>0);return i<0?void 0:{canvas:r[i],page:i+1}}function ae(e,t,n){let r=[...e.querySelectorAll(h)].find(e=>x(e.getBoundingClientRect(),t,n)&&e.getBoundingClientRect().width>0);return r?{canvas:r}:void 0}function w(e,t){if(t.width<=0||t.height<=0)throw Error(`annotation.emptyPage`);let n=b(e,t);if(!n)throw Error(`annotation.emptyRegion`);return{left:(n.left-t.left)/t.width,top:(n.top-t.top)/t.height,width:n.width/t.width,height:n.height/t.height}}async function oe(e,t,n=4e6,r=1/0){let i=e.canvas;if(!i||i.width<=0||i.height<=0)throw Error(`annotation.captureFailed`);let a=i.getBoundingClientRect(),o=e.region??w(e.box,a),s=i.width*o.width,c=i.height*o.height,l=Math.min(1,Math.sqrt(n/(s*c)),r/s,r/c);if(!Number.isFinite(l)||l<=0)throw Error(`annotation.captureFailed`);let u=document.createElement(`canvas`);u.width=Math.max(1,Math.floor(s*l)),u.height=Math.max(1,Math.floor(c*l));let d=u.getContext(`2d`);if(!d)throw Error(`annotation.captureFailed`);d.drawImage(i,o.left*i.width,o.top*i.height,s,c,0,0,u.width,u.height);let f=await new Promise((e,t)=>u.toBlob(n=>n?e(n):t(Error(`annotation.captureFailed`)),`image/png`));return new File([f],t,{type:`image/png`})}function T(e){if(typeof e!=`object`||!e)return!1;let t=e,n=(e,t)=>typeof e==`string`&&e.length<=t;if(!n(t.target,2e4)||!n(t.fileName,1e3)||!n(t.text,2e4)||!n(t.requirement,2e4)||!t.requirement.trim()||t.page!==void 0&&(!Number.isSafeInteger(t.page)||t.page<1)||t.imageName!==void 0&&!n(t.imageName,1e3)||t.sheet!==void 0&&(!n(t.sheet,1e3)||!t.sheet.trim())||t.range!==void 0&&(!n(t.range,100)||!t.range.trim())||t.unmapped!==void 0&&t.unmapped!==!0)return!1;if(t.region!==void 0){let e=t.region;if(!e||![`left`,`top`,`width`,`height`].every(t=>typeof e[t]==`number`&&Number.isFinite(e[t])&&e[t]>=0&&e[t]<=1)||e.width<=0||e.height<=0||e.left+e.width>1.000001||e.top+e.height>1.000001)return!1}return!0}function E(e){if(!e.length||e.length>50||!e.every(T))throw Error(`annotation.invalid`);let t=JSON.stringify(e).replace(/</gu,`\\u003c`);if(t.length>12e5)throw Error(`annotation.tooLarge`);return`${f}\n${t}\n${p}`}const D={id:d,order:10,match(e,t){for(let n=e.indexOf(f,t);n>=0;n=e.indexOf(f,n+20)){let t=e.indexOf(p,n+20);if(t<0)return;let r=e.slice(n+20,t).trim();if(!(r.length>12e5))try{let e=JSON.parse(r);if(Array.isArray(e)&&e.length>0&&e.length<=50&&e.every(T))return{id:d,start:n,end:t+21,data:{items:e}}}catch{}}}};function se({items:e,inputActions:t,intake:n,limits:r,existingImages:i,deferSubmit:a}){let o=E(e.map(e=>e.annotation)),s=e.flatMap(e=>e.file?[e.file]:[]);if(s.length&&!n)throw Error(`annotation.intakeUnavailable`);if(s.length&&r&&(s.some(e=>!r.mediaTypes.includes(e.type)||e.size>r.maxImageBytes)||i.length+s.length>r.maxImagesPerMessage||[...i,...s].reduce((e,t)=>e+t.size,0)>r.maxMessageImageBytes))throw Error(`annotation.imageLimit`);let c=t.captureInsertion(),l=s.length?n.create(s):[];if(l.length&&!t.addAttachments(l.map(e=>e.id)))throw n.release(l),Error(`annotation.sendFailed`);if(!t.insertText(`\n${o}\n`,{...c,start:c.end})){for(let e of l)t.removeAttachment(e.id);throw n?.release(l),Error(`annotation.sendFailed`)}try{return t.persistDraft(),a?`draft`:(t.submit(),`sent`)}catch{return`draft`}}function ce({node:e,interactive:r,openAnnotation:i,t:a}){let o=(0,t.useId)(),s=(0,t.useRef)(null),c=(0,t.useRef)(null),[l,u]=(0,t.useState)(!1),d=_(a(`annotation.count`),{count:String(e.data.items.length)});return(0,t.useLayoutEffect)(()=>{let e=c.current,t=s.current;if(!e||!t)return;if(!l){e.hidePopover?.();return}e.showPopover?.();let n=()=>{let n={width:document.documentElement.clientWidth,height:window.innerHeight},{left:r,top:i}=S(t.getBoundingClientRect(),e.getBoundingClientRect(),n);e.style.left=`${r}px`,e.style.top=`${i}px`},r=t=>{t.target instanceof Node&&e.contains(t.target)||u(!1)},i=new ResizeObserver(n);return i.observe(t),i.observe(e),window.addEventListener(`resize`,n),document.addEventListener(`scroll`,r,!0),n(),()=>{e.hidePopover?.(),i.disconnect(),window.removeEventListener(`resize`,n),document.removeEventListener(`scroll`,r,!0)}},[l]),(0,n.jsxs)(`span`,{ref:s,className:`dsh-office-annotation-reference`,onPointerEnter:()=>u(!0),onPointerLeave:e=>{(!(e.relatedTarget instanceof Node)||!e.currentTarget.contains(e.relatedTarget))&&u(!1)},onFocus:()=>u(!0),onBlur:e=>{e.currentTarget.contains(e.relatedTarget)||u(!1)},onKeyDown:e=>{e.key===`Escape`&&(e.preventDefault(),e.stopPropagation(),c.current?.contains(e.target)&&s.current?.querySelector(`button`)?.focus(),u(!1))},children:[(0,n.jsx)(`button`,{type:`button`,id:`${o}-trigger`,"aria-haspopup":`dialog`,"aria-controls":o,"aria-expanded":l,children:d}),(0,n.jsx)(`span`,{ref:c,popover:`manual`,className:`dsh-office-annotation-popover`,"data-open":l,id:o,role:`dialog`,"aria-labelledby":`${o}-trigger`,children:(0,n.jsx)(`span`,{className:`dsh-office-annotation-list`,children:e.data.items.map((e,t)=>(0,n.jsxs)(`span`,{className:`dsh-office-annotation-item`,children:[(0,n.jsx)(`span`,{className:`dsh-office-annotation-source`,children:r?(0,n.jsx)(`button`,{type:`button`,onClick:()=>i(e.target),title:e.target,children:e.fileName}):(0,n.jsx)(`span`,{children:e.fileName})}),(0,n.jsx)(`span`,{className:`dsh-office-annotation-requirement`,children:e.requirement})]},t))})})]})}function O(e){return/\.(?:pdf|docx?|pptx|xlsx)$/iu.test(e.absolutePath)?(0,n.jsx)(le,{...e},e.absolutePath):null}function le({absolutePath:e,pendingAnnotations:r,intake:i,inputActions:a,useInput:o,useProjection:s,t:c}){let l=(0,t.useRef)(null),u=(0,t.useRef)(null),d=(0,t.useRef)(null),f=(0,t.useRef)(),[p,v]=(0,t.useState)(),[y,x]=(0,t.useState)(!1),[S,C]=(0,t.useState)(),[T,E]=(0,t.useState)(),[D,ce]=(0,t.useState)(``),[O,le]=(0,t.useState)(),[k,A]=(0,t.useState)(!1),[j,M]=(0,t.useState)(!1),[N,P]=(0,t.useState)(()=>r.get(e)??[]),[F,I]=(0,t.useState)(!1),L=(0,t.useId)(),[R,z]=(0,t.useState)(``),B=o(e=>e),V=s(`imageLimits`),ue=/\.pdf$/iu.test(e),H=/\.xlsx$/iu.test(e),U=ue||H,W=H?h:m,G=e.replace(/\\/gu,`/`).split(`/`).pop()??e,K=(0,t.useRef)(0),q=(0,t.useRef)(),J=(0,t.useRef)(),Y=(0,t.useRef)(),de=B.phase!==`plain`;(0,t.useEffect)(()=>{N.length?r.set(e,N):r.delete(e)},[e,N,r]);function X(){K.current++,E(void 0),le(void 0),A(!1),ce(``)}function Z(){clearTimeout(q.current),J.current=void 0,M(!1),C(void 0)}(0,t.useEffect)(()=>{let e=l.current,t=e&&re(e);if(!t)return;let{header:n,root:r}=t;f.current=r;let i=0,a=()=>{cancelAnimationFrame(i),i=requestAnimationFrame(()=>{Y.current=void 0;let e=r.getBoundingClientRect(),t=Math.max(e.top,n.getBoundingClientRect().bottom,0),i=Math.min(e.bottom,window.innerHeight),a=Math.max(0,e.left),o=Math.min(e.right,window.innerWidth),s=[...r.querySelectorAll(W)].find(e=>e.getBoundingClientRect().width>0),c=r.isConnected&&!r.closest(`[hidden], [aria-hidden="true"]`)&&getComputedStyle(r).visibility===`visible`;v(c&&e.height>40&&s&&o>a&&i>t?{left:a,top:t,width:o-a,height:i-t}:void 0),E(e=>{if(!e?.canvas||!e.region)return e;let t=e.canvas.getBoundingClientRect(),n=e.region,r={left:t.left+n.left*t.width,top:t.top+n.top*t.height,width:n.width*t.width,height:n.height*t.height};return Object.keys(r).every(t=>r[t]===e.box[t])?e:{...e,box:r}})})},o=new ResizeObserver(a);o.observe(r);let s=new MutationObserver(t=>{t.some(t=>!e.contains(t.target))&&a()});s.observe(r,{childList:!0,subtree:!0,attributes:!0,attributeFilter:[`hidden`,`aria-hidden`,`class`,`style`]});for(let e=r.parentElement;e;e=e.parentElement)s.observe(e,{attributes:!0});return window.addEventListener(`resize`,a),r.addEventListener(`transitionend`,a),r.addEventListener(`scroll`,a,!0),a(),()=>{K.current++,clearTimeout(q.current),cancelAnimationFrame(i),o.disconnect(),s.disconnect(),window.removeEventListener(`resize`,a),r.removeEventListener(`transitionend`,a),r.removeEventListener(`scroll`,a,!0),f.current=void 0}},[]),(0,t.useEffect)(()=>{if(!T)return;let e=e=>{e.target instanceof Node&&!u.current?.contains(e.target)&&X()};return document.addEventListener(`pointerdown`,e,!0),u.current?.querySelector(`input`)?.focus(),()=>{document.removeEventListener(`pointerdown`,e,!0)}},[T]),(0,t.useEffect)(()=>{y&&d.current?.focus()},[y]);function fe(e,t){let n=f.current;if(!n)return;let r=n.querySelector(W)?.parentElement;for(;r&&r!==n&&!/auto|scroll/u.test(getComputedStyle(r).overflowY);)r=r.parentElement;r?.scrollBy({left:e,top:t}),C(void 0)}(0,t.useEffect)(()=>{let e=d.current;if(!y||!e||!p)return;let t=e=>{e.preventDefault();let t=e.deltaMode===1?16:e.deltaMode===2?p.height:1;fe(e.deltaX*t,e.deltaY*t)};return e.addEventListener(`wheel`,t,{passive:!1}),()=>e.removeEventListener(`wheel`,t)},[y,p]);function pe(e,t){let n=f.current;if(n)return H?ae(n,e,t):ie(n,e,t)}function me(e,t){if(H||!f.current)return;let n=ie(f.current,e,t);if(!n)return;let r=n.canvas.getBoundingClientRect();(Y.current?.canvas!==n.canvas||Y.current.box.left!==r.left||Y.current.box.top!==r.top||Y.current.box.width!==r.width||Y.current.box.height!==r.height)&&(Y.current={canvas:n.canvas,box:r,paragraphs:ne(n.canvas)});let i=te(Y.current.paragraphs,e,t);return i?{...i,...n}:void 0}function he(e,t){let n=J.current;if(!n)return;let r=b({left:Math.min(n.x,e),top:Math.min(n.y,t),width:Math.abs(e-n.x),height:Math.abs(t-n.y)},n.canvas.getBoundingClientRect());if(!r)return;let i=Y.current?.canvas===n.canvas?Y.current.paragraphs:ne(n.canvas),a=H?``:i.filter(e=>(e.rects??[e.box]).some(e=>b(e,r))).map(e=>e.text).join(`
|
|
6
|
+
`).slice(0,g);return{canvas:n.canvas,page:n.page,box:r,region:w(r,n.canvas.getBoundingClientRect()),text:a}}function ge(e){if(e.button!==0||!f.current||U&&!i)return;let t=pe(e.clientX,e.clientY);if(!t)return;e.preventDefault(),X();let n={...t,x:e.clientX,y:e.clientY,lastX:e.clientX,lastY:e.clientY,region:!1};J.current=n,e.currentTarget.setPointerCapture(e.pointerId),q.current=setTimeout(()=>{J.current===n&&(n.region=!0,M(!0),C(he(n.lastX,n.lastY)))},350)}function _e(e){let t=J.current;t&&(t.lastX=e.clientX,t.lastY=e.clientY,!t.region&&Math.hypot(e.clientX-t.x,e.clientY-t.y)>=6&&(clearTimeout(q.current),t.region=!0,M(!0))),C(t?.region?he(e.clientX,e.clientY):me(e.clientX,e.clientY))}async function ve(e){X();let t=K.current;z(``);let n=e.canvas?.getBoundingClientRect(),r=n?ee(e.box,n):e.box;if(!r)return;let i=n?w(r,n):e.region,a={...e,box:r,region:i};if(E(a),U){A(!0);try{let n=e.page===void 0?`region`:`p${e.page}`,r=await oe(a,`${G}-${n}-${Date.now()}.png`,V?.maxImagePixels,V?.maxImageDimension);K.current===t&&le(r)}catch{K.current===t&&z(c(`annotation.captureFailed`))}finally{K.current===t&&A(!1)}}}function ye(e){let t=J.current;if(clearTimeout(q.current),!t)return;let n=t.region?he(e.clientX,e.clientY):me(e.clientX,e.clientY),r=Math.hypot(e.clientX-t.x,e.clientY-t.y);Z(),n&&(t.region?n.box.width>=6&&n.box.height>=6:r<6)&&ve(n)}function be(){if(!T||!D.trim()||U&&!O||N.length>=50)return;let t={target:e,fileName:G,page:T.page,text:T.text.slice(0,g),requirement:D.trim(),region:T.region,imageName:O?.name,...H?{unmapped:!0}:{}};P(e=>[...e,{annotation:t,file:O}]),X()}function xe(){if(!de)try{let e=se({items:N,inputActions:a,intake:i,limits:V,existingImages:i?.images(B.attachmentIds)??[],deferSubmit:!!B.draft.trim()||B.attachmentIds.length>0});P([]),I(!1),x(!1),X(),z(e===`draft`?c(`annotation.draftReady`):``)}catch(e){let t=e instanceof Error?e.message:`annotation.sendFailed`;z(c(t.startsWith(`annotation.`)?t:`annotation.sendFailed`))}}let Q=T??S,Se=Q&&!T&&!j&&Q.canvas?ee(Q.box,Q.canvas.getBoundingClientRect()):Q?.box,$=Se&&p?b(Se,p):void 0,Ce=p?Math.min(360,p.width-16):0,we=p&&T?Math.max(p.left+8,Math.min(T.box.left,p.left+p.width-Ce-8)):0,Te=p&&T?Math.max(p.top+4,Math.min(T.box.top+T.box.height+6,p.top+p.height-56)):0;return(0,n.jsxs)(`span`,{ref:l,className:`dsh-office-annotate`,onKeyDown:e=>{if(!y||e.key!==`Escape`)return;e.preventDefault(),e.stopPropagation();let t=!!T||!!J.current;X(),Z(),t?d.current?.focus():(x(!1),l.current?.querySelector(`button`)?.focus())},children:[(0,n.jsx)(`button`,{type:`button`,className:`dsh-office-annotate-toggle`,"aria-pressed":y,disabled:!p||U&&!i,title:c(U&&!i?`annotation.intakeUnavailable`:p?`annotation.help`:`annotation.unavailable`),onClick:()=>{x(e=>!e),X(),Z()},children:c(`annotation.ask`)}),U&&!i&&(0,n.jsx)(`span`,{role:`status`,className:`dsh-office-annotate-unavailable`,children:c(`annotation.intakeUnavailable`)}),y&&p&&(0,n.jsx)(`div`,{ref:d,className:`dsh-office-annotate-surface`,tabIndex:0,style:{left:p.left,top:p.top,width:p.width,height:p.height},role:`region`,"aria-label":c(`annotation.help`),onPointerDown:ge,onPointerMove:_e,onPointerUp:ye,onPointerCancel:Z,onLostPointerCapture:Z,onKeyDown:e=>{if(e.key===`PageDown`||e.key===`PageUp`)e.preventDefault(),fe(0,p.height*(e.key===`PageDown`?.8:-.8));else if(e.key===`ArrowDown`||e.key===`ArrowUp`){e.preventDefault();let t=[...f.current.querySelectorAll(`canvas[role="img"][aria-label]`)].flatMap((e,t)=>ne(e).filter(e=>b(e.box,p)).map(n=>({...n,canvas:e,page:t+1}))),n=t.findIndex(e=>e.canvas===S?.canvas&&e.text===S.text&&e.box.top===S.box.top),r=n<0?e.key===`ArrowDown`?0:t.length-1:Math.max(0,Math.min(t.length-1,n+(e.key===`ArrowDown`?1:-1)));C(t[r])}else(e.key===`Enter`||e.key===` `)&&S&&(e.preventDefault(),ve(S))},onPointerLeave:()=>{J.current||C(void 0)}}),y&&$&&(0,n.jsx)(`span`,{className:`dsh-office-annotate-highlight`,"data-selected":T||j?`true`:void 0,style:{left:$.left,top:$.top,width:$.width,height:$.height}}),y&&T&&p&&(0,n.jsxs)(`form`,{ref:u,className:`dsh-office-annotate-composer`,style:{left:we,top:Te,width:Ce},"aria-label":c(`annotation.ask`),"aria-busy":k,onSubmit:e=>{e.preventDefault(),be()},children:[(0,n.jsx)(`input`,{type:`text`,"aria-label":c(`annotation.placeholder`),placeholder:c(`annotation.placeholder`),value:D,maxLength:2e4,onChange:e=>ce(e.target.value),onKeyDown:e=>{e.key===`Enter`&&e.nativeEvent.isComposing&&e.preventDefault()}}),(0,n.jsx)(`button`,{type:`submit`,"aria-label":c(k?`annotation.capturing`:`annotation.add`),title:c(k?`annotation.capturing`:`annotation.add`),disabled:!D.trim()||k||U&&!O||N.length>=50,children:(0,n.jsx)(`svg`,{width:`18`,height:`18`,viewBox:`0 0 24 24`,fill:`none`,"aria-hidden":`true`,children:(0,n.jsx)(`path`,{d:`m5 12 4 4L19 6`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`})})})]}),(y||N.length>0||R)&&p&&(0,n.jsx)(`div`,{className:`dsh-office-annotate-rail-position`,style:{left:p.left,width:p.width,bottom:Math.max(0,window.innerHeight-p.top-p.height)+12,"--dsh-office-annotation-width":`${p.width}px`,"--dsh-office-annotation-height":`${p.height}px`},children:(0,n.jsxs)(`div`,{className:`dsh-office-annotate-rail`,children:[R&&(0,n.jsx)(`p`,{role:`alert`,children:R}),(0,n.jsxs)(`div`,{className:`dsh-office-annotate-rail-actions`,children:[(0,n.jsxs)(`div`,{className:`dsh-office-annotate-summary`,"data-dismissed":F?`true`:void 0,onPointerEnter:()=>I(!1),onFocus:()=>I(!1),onKeyDown:e=>{e.key===`Escape`&&(e.stopPropagation(),e.currentTarget.querySelector(`button`)?.focus(),I(!0))},children:[(0,n.jsx)(`button`,{type:`button`,"aria-haspopup":`dialog`,"aria-controls":L,disabled:!N.length,children:_(c(`annotation.count`),{count:String(N.length)})}),N.length>0&&(0,n.jsx)(`div`,{id:L,role:`dialog`,"aria-label":_(c(`annotation.count`),{count:String(N.length)}),className:`dsh-office-annotate-popover`,children:(0,n.jsx)(`ul`,{children:N.map((e,t)=>(0,n.jsx)(`li`,{children:(0,n.jsxs)(`div`,{children:[(0,n.jsxs)(`span`,{className:`dsh-office-annotation-source`,children:[(0,n.jsx)(`span`,{title:e.annotation.target,children:e.annotation.fileName}),e.annotation.page&&(0,n.jsx)(`span`,{children:_(c(`annotation.page`),{page:String(e.annotation.page)})})]}),e.annotation.text&&(0,n.jsx)(`span`,{className:`dsh-office-annotation-original`,children:e.annotation.text}),(0,n.jsx)(`span`,{className:`dsh-office-annotation-requirement`,title:e.annotation.requirement,children:e.annotation.requirement})]})},e.annotation.imageName??t))})})]}),(0,n.jsx)(`button`,{type:`button`,onClick:()=>{P([]),x(!1),I(!1),z(``),X(),Z()},children:c(`annotation.cancel`)}),(0,n.jsx)(`button`,{type:`button`,className:`dsh-office-annotate-primary`,disabled:!N.length||de,onClick:xe,children:c(`annotation.send`)})]})]})})]})}function k(e){let{size:t=16,...n}=e;return{width:t,height:t,viewBox:`0 0 16 16`,fill:`none`,"aria-hidden":!0,...n}}function A(e){return(0,n.jsx)(`svg`,{...k(e),children:(0,n.jsx)(`path`,{fill:`currentColor`,fillRule:`evenodd`,clipRule:`evenodd`,d:`M5 13.5h6a1.5 1.5 0 0 0 1.5-1.5V7.243a1.5 1.5 0 0 0-.44-1.061L8.819 2.939a1.5 1.5 0 0 0-1.06-.439H5A1.5 1.5 0 0 0 3.5 4v8A1.5 1.5 0 0 0 5 13.5m9-6.257a3 3 0 0 0-.879-2.122L9.88 1.88A3 3 0 0 0 7.757 1H5a3 3 0 0 0-3 3v8a3 3 0 0 0 3 3h6a3 3 0 0 0 3-3zM5 8.25a.75.75 0 0 1 .75-.75h4.5a.75.75 0 0 1 0 1.5h-4.5A.75.75 0 0 1 5 8.25m.75 2.25a.75.75 0 0 0 0 1.5h2.5a.75.75 0 0 0 0-1.5z`})})}function j(e){return(0,n.jsx)(`svg`,{...k(e),children:(0,n.jsx)(`path`,{fill:`currentColor`,fillRule:`evenodd`,clipRule:`evenodd`,d:`M11 13.5H5A1.5 1.5 0 0 1 3.5 12V4A1.5 1.5 0 0 1 5 2.5h2.757a1.5 1.5 0 0 1 1.061.44l3.243 3.242a1.5 1.5 0 0 1 .439 1.06V12a1.5 1.5 0 0 1-1.5 1.5m2.121-8.379A3 3 0 0 1 14 7.243V12a3 3 0 0 1-3 3H5a3 3 0 0 1-3-3V4a3 3 0 0 1 3-3h2.757a3 3 0 0 1 2.122.879zM6.5 6.5a.75.75 0 0 0-.75.75v4a.75.75 0 0 0 1.5 0v-.75H8.5a2 2 0 1 0 0-4zm2 2.5H7.25V8H8.5a.5.5 0 0 1 0 1`})})}function M(e){return(0,n.jsx)(`svg`,{...k(e),children:(0,n.jsx)(`path`,{fill:`currentColor`,fillRule:`evenodd`,clipRule:`evenodd`,d:`M12 3H4a1.5 1.5 0 0 0-1.5 1.5v4A1.5 1.5 0 0 0 4 10h8a1.5 1.5 0 0 0 1.5-1.5v-4A1.5 1.5 0 0 0 12 3M4 1.5a3 3 0 0 0-3 3v4a3 3 0 0 0 3 3h3.25V13h-2.5a.75.75 0 0 0 0 1.5h6.5a.75.75 0 0 0 0-1.5h-2.5v-1.5H12a3 3 0 0 0 3-3v-4a3 3 0 0 0-3-3z`})})}function N(e){return(0,n.jsx)(`svg`,{...k(e),children:(0,n.jsx)(`path`,{fill:`currentColor`,fillRule:`evenodd`,clipRule:`evenodd`,d:`M9.25 3.5h-2.5v2h2.5zM4 3.5h1.25v2H2.5V5A1.5 1.5 0 0 1 4 3.5M2.5 7h2.75v2H2.5zm0 3.5v.5A1.5 1.5 0 0 0 4 12.5h1.25v-2zm4.25 0v2h2.5v-2zm4 0v2H12a1.5 1.5 0 0 0 1.5-1.5v-.5zM13.5 9h-2.75V7h2.75zM9.25 9h-2.5V7h2.5zm1.5-5.5v2h2.75V5A1.5 1.5 0 0 0 12 3.5zM4 2a3 3 0 0 0-3 3v6a3 3 0 0 0 3 3h8a3 3 0 0 0 3-3V5a3 3 0 0 0-3-3z`})})}const P={documents:A,pdf:j,presentations:M,spreadsheets:N};function F(e){return`Use the "${e.skill}" skill for this request and follow its instructions before creating, editing, or rendering files.`}function I(e){return`/${e.command}\n\n${F(e)}`}const L={id:c,order:20,match(e,t){let n=/(?<!\S)\/([\w-]+)(?!\S)/gu;n.lastIndex=t;for(let t=n.exec(e);t!==null;t=n.exec(e)){let n=a(t[1]??``);if(n===void 0)continue;let r=t.index,i=r+t[0].length,o=e.slice(i),s=o.length-o.trimStart().length,l=F(n);return{id:c,start:r,end:o.startsWith(l,s)?i+s+l.length:i,data:{feature:n.id}}}}};function R({node:e,raw:t,interactive:r,openOffice:a,officeLabel:o}){let s=i(e.data.feature);if(s==null)return(0,n.jsx)(`span`,{children:t});let c=P[s.id],l=`/${s.command}`,u=(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(c,{className:`dsh-office-ref-icon`,size:14}),(0,n.jsx)(`span`,{children:o(s.id)})]});return r?(0,n.jsx)(`button`,{type:`button`,className:`dsh-office-ref`,title:l,"data-interactive":!0,onClick:()=>a(s.id),children:u}):(0,n.jsx)(`span`,{className:`dsh-office-ref`,title:l,children:u})}function z(){if(typeof document>`u`)return()=>{};let e=document.querySelector(`style[data-plugin-css="dsh-office-kit/reference.css"]`)??document.createElement(`style`);return e.dataset.plugin=o,e.dataset.pluginCss=`dsh-office-kit/reference.css`,e.textContent=`
|
|
7
7
|
.dsh-office-ref {
|
|
8
8
|
display: inline-flex;
|
|
9
9
|
align-items: center;
|
|
@@ -262,6 +262,6 @@ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require
|
|
|
262
262
|
.dsh-office-annotation-reference .dsh-office-annotation-original { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--dsw-alias-label-tertiary); font-size: 12px; }
|
|
263
263
|
.dsh-office-annotate .dsh-office-annotation-requirement,
|
|
264
264
|
.dsh-office-annotation-reference .dsh-office-annotation-requirement { display: block; white-space: pre-wrap; overflow-wrap: anywhere; }
|
|
265
|
-
`,document.head.appendChild(e),()=>e.remove()}const
|
|
265
|
+
`,document.head.appendChild(e),()=>e.remove()}const B=[`inputTriggers`,`sessions`,`slots`,`locale`,`remote`,`remote.skills`,`sidebarRight`,`uiConversation`,`conversation`],V={"menu.group":`办公`,"menu.documents.label":`文档`,"menu.documents.description":`创建、读取、编辑和渲染 DOCX 文档`,"menu.pdf.label":`PDF 文档`,"menu.pdf.description":`读取、创建、检查、渲染和验证 PDF`,"menu.presentations.label":`演示文稿`,"menu.presentations.description":`创建、编辑、渲染和导出 PPTX 演示文稿`,"menu.spreadsheets.label":`电子表格`,"menu.spreadsheets.description":`创建、编辑、计算和导出 XLSX 电子表格`,"annotation.ask":`请求修改`,"annotation.cancel":`取消`,"annotation.send":`发送`,"annotation.add":`添加标注`,"annotation.placeholder":`说明要怎么改…`,"annotation.page":`第 {page} 页`,"annotation.count":`{count} 条注释`,"annotation.remove":`删除第 {index} 条注释`,"annotation.image":`位置截图:{name}`,"annotation.help":`悬停吸附段落,点击输入要求;长按拖动框选区域,松开添加标注。方向键选择,Enter 确认,Esc 退出。`,"annotation.unavailable":`等待文档页面渲染;当前预览不支持标注`,"annotation.capturing":`正在截图…`,"annotation.captureFailed":`截图失败,请重新选择区域`,"annotation.intakeUnavailable":`当前 DSH 版本不支持从侧栏添加截图附件,PDF 与表格标注已禁用`,"annotation.imageLimit":`截图超过当前模型的数量或大小限制,请减少标注后重试`,"annotation.sendFailed":`未能加入会话,请重试;标注仍保留`,"annotation.draftReady":`标注和截图已保留在会话输入框,请在那里确认发送`,"annotation.invalid":`标注内容无效,请重新添加`,"annotation.tooLarge":`标注内容过长,请减少后重试`,"annotation.emptyPage":`页面尚未渲染,请重试`,"annotation.emptyRegion":`请选择页面内的区域`},ue={"menu.group":`Office`,"menu.documents.label":`Documents`,"menu.documents.description":`Create, read, edit, and render DOCX documents`,"menu.pdf.label":`PDF documents`,"menu.pdf.description":`Read, create, inspect, render, and verify PDFs`,"menu.presentations.label":`Presentations`,"menu.presentations.description":`Create, edit, render, and export PPTX decks`,"menu.spreadsheets.label":`Spreadsheets`,"menu.spreadsheets.description":`Create, edit, calculate, and export XLSX workbooks`,"annotation.ask":`Request changes`,"annotation.cancel":`Cancel`,"annotation.send":`Send`,"annotation.add":`Add annotation`,"annotation.placeholder":`Describe the change…`,"annotation.page":`page {page}`,"annotation.count":`{count} annotations`,"annotation.remove":`Remove annotation {index}`,"annotation.image":`Location screenshot: {name}`,"annotation.help":`Hover to select a paragraph; click to comment. Hold and drag to select a region. Arrow keys select, Enter confirms, Esc exits.`,"annotation.unavailable":`Waiting for rendered pages; this preview cannot be annotated yet`,"annotation.capturing":`Capturing…`,"annotation.captureFailed":`Screenshot failed; please select the region again`,"annotation.intakeUnavailable":`This DSH version cannot add screenshots from the sidebar; PDF and spreadsheet annotation is disabled`,"annotation.imageLimit":`Screenshots exceed the current model’s count or size limits; remove some annotations and retry`,"annotation.sendFailed":`Could not add annotations to the conversation; your annotations are retained`,"annotation.draftReady":`Annotations and screenshots are kept in the conversation input; confirm sending there`,"annotation.invalid":`Invalid annotation; please add it again`,"annotation.tooLarge":`Annotations are too long; remove some and retry`,"annotation.emptyPage":`The page has not rendered yet; please retry`,"annotation.emptyRegion":`Select a region inside the page`};function H(e){return encodeURIComponent(e).replace(/%3A/gi,`:`)}function U(e){return e.split(`/`).map(H).join(`/`)}function W(e,t){let n=t.replace(/\\/g,`/`).replace(/^(?:\.\/)+/u,``);return`dsh-resource://file/session/${H(e)}/${U(n)}`}function G(e,t,n){let r=n.replace(/\\/g,`/`),i=t?.replace(/\\/g,`/`).replace(/\/+$/u,``)??``;return/^(?:\/|[A-Za-z]:\/|\\\\)/u.test(r)&&i!==``&&r.startsWith(`${i}/`)?W(e,r.slice(i.length+1)):W(e,r)}function K(t){let n=t.sessions,f=t.remote.skills,p=t.locale.bind(o),m=new Map,h=new Map;t.effect(()=>z(),`office-suite: styles`),t.effect(()=>t.locale.register(o,{zh:V,en:ue}),`office-suite: dictionaries`);function g(e){let t=m.get(e);if(t!==void 0)return t;let r=new AbortController,i=(async()=>{if(n.binding(e)===void 0)throw Error(`office catalog requires a retained session "${e}"`);return n.using(e,{source:`officeCatalog`,signal:r.signal},async t=>{r.signal.throwIfAborted();let n=t.binding.session.getSnapshot();if(n.openState!==`open`)throw n.openError??Error(`session "${e}" is not open`);let i=await f.list({sessionId:e},r.signal);if(r.signal.throwIfAborted(),!i.ok)throw Error(`skills/list failed: ${i.error.code}: ${i.error.message}`);return i.value.skills})})(),a={abort:r,promise:i};return m.set(e,a),i.then(e=>{a.settled=e},()=>{m.get(e)===a&&m.delete(e)}),a}function _(e,r,a){let o=i(r);if(o===void 0)return!1;let s=a.find(e=>e.name===o.skill);if(s?.path===void 0)return!1;let c=n.list.getSnapshot().byId[e]?.cwd;try{return t.sidebarRight.openResource(G(e,c,s.path)),!0}catch(e){return console.error(`[dsh-office-kit] reference preview failed:`,e),!1}}let v={trigger:`/`,name:s,order:1,async candidates(t,{query:n,signal:i}){if(i.aborted)return[];let a=r.map(e=>{let t=P[e.id];return{name:e.command,label:p(`menu.${e.id}.label`),description:p(`menu.${e.id}.description`),section:p(`menu.group`),icon:t}});return n.length===0?a:(0,e.rankByName)(a,n)},lexicon(){return r.map(e=>e.command)},openReference(e,{ref:t}){let n=i(t);if(n===void 0)return!1;let r=m.get(e.sessionId)?.settled;if(r!==void 0)return _(e.sessionId,n.id,r);let a=g(e.sessionId);return a.promise.then(t=>{a.abort.signal.aborted||_(e.sessionId,n.id,t)}).catch(e=>{a.abort.signal.aborted||console.error(`[dsh-office-kit] reference preview failed:`,e)}),!0},onPick({candidate:e}){let t=a(e.name);if(t!==void 0)return{insert:{source:s,ref:t.id,label:p(`menu.${t.id}.label`),appearance:`file`,clipboardText:`/${t.command}`}}},codec:{clipboardText(e){let t=i(e);return t===void 0?`/${e}`:`/${t.command}`},async serialize(e){let t=i(e);return t===void 0?`/documents`:I(t)}}};t.effect(()=>t.uiConversation.userText.register(L),`office-suite: transcript chip`),t.effect(()=>t.slots.inject(l,()=>t.slots.register({name:l,key:c,priority:100,inject:e=>({openOffice:t=>{v.openReference?.({sessionId:e},{ref:t,appearance:`file`})},officeLabel:e=>p(`menu.${e}.label`)})},R)),`office-suite: transcript chip slot`);function y(e){let r=t.conversation,i=typeof r.createDrafts==`function`&&typeof r.releaseDraftAttachments==`function`&&typeof r.resolveDraftAttachments==`function`,a=h.get(e);return a||(a=new Map,h.set(e,a)),{pendingAnnotations:a,intake:i?{create:t=>r.createDrafts(e,t),release:e=>r.releaseDraftAttachments(e),images:e=>r.resolveDraftAttachments(e).filter(e=>e.kind===`image`).map(e=>e.file)}:void 0,openAnnotation:r=>{try{let i=n.list.getSnapshot().byId[e]?.cwd;t.sidebarRight.openResource(G(e,i,r))}catch(e){console.error(`[dsh-office-kit] annotation preview failed:`,e)}}}}t.effect(()=>t.uiConversation.userText.register(D),`office-suite: annotations`),t.effect(()=>t.slots.inject(l,()=>t.slots.register({name:l,key:d,priority:100,locale:o,inject:y},ce)),`office-suite: annotation references`),t.effect(()=>t.slots.inject(u,()=>t.slots.register({name:u,id:`office-annotations`,order:20,locale:o,inject:y},O)),`office-suite: annotation tool`);let b=t.inputTriggers;t.effect(()=>{let e=b.registerSource(v);return()=>{e();for(let e of m.values())e.abort.abort();m.clear(),h.clear()}},`office-suite: slash source`)}exports.apply=K,exports.inject=B;
|
|
266
266
|
return module.exports;}});
|
|
267
267
|
//# sourceMappingURL=client.js.map
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","names":[],"sources":["../src/features.ts","../src/client/constants.ts","../src/client/quote.ts","../src/client/annotation.ts","../src/client/annotation-reference.tsx","../src/client/document-annotation.tsx","../src/client/icons.tsx","../src/client/office-reference.tsx","../src/client/styles.ts","../src/client/index.ts"],"sourcesContent":["/** Stable identifiers for the four Office entry points. */\nexport type OfficeFeatureId = 'documents' | 'pdf' | 'presentations' | 'spreadsheets'\n\n/** One user-facing Office entry, its skill, and the file types it owns. */\nexport interface OfficeFeature {\n readonly id: OfficeFeatureId\n /** Friendly name used by the '/' menu, chip, and preview. */\n readonly label: string\n /** One-line menu description. */\n readonly description: string\n /** Detail shown after a chip is inserted. */\n readonly hint: string\n /** Skill registered with the DSH skill registry. */\n readonly skill: string\n /** Slash token without the leading '/'. */\n readonly command: string\n /** File extensions shown in menus and documentation. */\n readonly extensions: readonly string[]\n}\n\n/** The four entries, in menu order. */\nexport const OFFICE_FEATURES: readonly OfficeFeature[] = [\n {\n id: 'documents',\n label: 'Documents',\n description: 'Create, edit, render, and verify Word documents (.docx).',\n hint: 'DOCX',\n skill: 'office-documents',\n command: 'documents',\n extensions: ['.docx'],\n },\n {\n id: 'pdf',\n label: 'PDF',\n description: 'Create, read, edit, render, and verify PDF files.',\n hint: 'PDF',\n skill: 'office-pdf',\n command: 'pdf',\n extensions: ['.pdf'],\n },\n {\n id: 'presentations',\n label: 'Presentations',\n description: 'Create, edit, render, and verify slide decks (.pptx).',\n hint: 'PPTX',\n skill: 'office-presentations',\n command: 'presentations',\n extensions: ['.pptx'],\n },\n {\n id: 'spreadsheets',\n label: 'Spreadsheets',\n description: 'Create, edit, recalculate, render, and verify workbooks (.xlsx).',\n hint: 'XLSX',\n skill: 'office-spreadsheets',\n command: 'spreadsheets',\n extensions: ['.xlsx'],\n },\n]\n\n/** Resolve a feature by its stable id; unknown ids are not Office entries. */\nexport function featureById(id: string): OfficeFeature | undefined {\n return OFFICE_FEATURES.find(feature => feature.id === id)\n}\n\n/** Resolve a feature by its slash token (without '/'). */\nexport function featureByCommand(command: string): OfficeFeature | undefined {\n return OFFICE_FEATURES.find(feature => feature.command === command)\n}\n","/** Locale namespace and slash source owned by this plugin. */\nexport const OFFICE_NS = 'dsh-office-kit'\nexport const OFFICE_SOURCE = 'office'\nexport const OFFICE_CHIP = 'office'\nexport const OFFICE_CHIP_SLOT = 'conversation.user.text.node'\n\n/** Additive, session-scoped toolbar contribution inside the official file preview. */\nexport const ANNOTATION_SLOT = 'sidebar.right.tab.document.actions'\nexport const ANNOTATION_ID = 'office-annotations'\nexport const ANNOTATION_ORDER = 20\nexport const ANNOTATION_PRIORITY = 100\nexport const ANNOTATION_NODE = 'officeAnnotation'\nexport const ANNOTATION_OPEN = '<office-annotations>'\nexport const ANNOTATION_CLOSE = '</office-annotations>'\nexport const OFFICE_STYLE_ID = 'dsh-office-kit/reference.css'\nexport const FILE_ADDRESS_PREFIX = 'dsh-resource://file/'\nexport const SESSION_FILE_PREFIX = `${FILE_ADDRESS_PREFIX}session/`\n\n/** Only semantic selectors: no dependency on another plugin's CSS/data attributes. */\nexport const ANNOTATION_CANVAS_SELECTOR = 'canvas[role=\"img\"][aria-label]'\n/** Spreadsheet previews paint one grid canvas instead of paged PDF surfaces. */\nexport const ANNOTATION_SPREADSHEET_CANVAS_SELECTOR = 'canvas.fortune-sheet-canvas'\n/** Gravity UI Icons 2.21.0 CommentFill (MIT); original retained in assets/icons/comment-fill.svg. */\nexport const ANNOTATION_CURSOR = `url(\"data:image/svg+xml,${encodeURIComponent('<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" fill=\"none\" viewBox=\"0 0 16 16\"><path fill=\"#466eff\" fill-rule=\"evenodd\" d=\"M8 13c3.866 0 7-2 7-6s-3.134-6-7-6-7 2-7 6c0 2.16.914 3.737 2.364 4.73l.09 2.161a1.157 1.157 0 0 0 1.857.872l2.322-1.77Q7.816 13 8 13\" clip-rule=\"evenodd\"/></svg>')}\") 4 18, crosshair`\nexport const ANNOTATION_HOLD_MS = 350\nexport const ANNOTATION_MIN_REGION = 6\nexport const ANNOTATION_PADDING = 3\nexport const ANNOTATION_HIT_X = 8\nexport const ANNOTATION_HIT_Y = 4\nexport const ANNOTATION_MAX_ITEMS = 50\nexport const ANNOTATION_MAX_TEXT = 20000\nexport const ANNOTATION_MAX_PAYLOAD = 1200000\nexport const ANNOTATION_MAX_PIXELS = 4000000\n","import type { QuotePrompt } from './types'\nimport { SESSION_FILE_PREFIX } from './constants'\n\nfunction decodeSegment(segment: string): string {\n try {\n return decodeURIComponent(segment)\n }\n catch {\n return segment\n }\n}\n\n/** Replace every `{name}` placeholder with its value. */\nexport function fillTemplate(template: string, values: Record<string, string>): string {\n return template.replace(/\\{(\\w+)\\}/gu, (match, name: string) => values[name] ?? match)\n}\n\n/**\n * Collapse what a PDF text layer emits: one line per visual line, padded with\n * spaces and interleaved empty lines.\n */\nexport function normalizeSelection(raw: string): string {\n const lines: string[] = []\n for (const line of raw.replace(/\\r\\n?/gu, '\\n').split('\\n')) {\n const collapsed = line.replace(/\\s+/gu, ' ').trim()\n if (collapsed.length > 0)\n lines.push(collapsed)\n }\n return lines.join('\\n')\n}\n\n/** Quote each line so the agent reads the selection as the document's own words. */\nexport function quoteLines(text: string): string {\n return text.split('\\n').map(line => `> ${line}`).join('\\n')\n}\n\n/** Path part of a `scheme://authority/path` address, apart from its origin. */\nconst PATH_AFTER_ORIGIN = /^(?:[^:/?#]+:)?\\/\\/[^/]+\\/(.*)$/u\n\nfunction pathOf(address: string): string | undefined {\n return PATH_AFTER_ORIGIN.exec(address)?.[1]\n}\n\n/** Last path segment of a preview address: the file's display name. */\nexport function fileNameOf(address: string | undefined): string | undefined {\n if (address === undefined)\n return undefined\n const segment = pathOf(address)?.split('/').pop()\n if (segment === undefined || segment.length === 0)\n return undefined\n const name = decodeSegment(segment)\n return name.length === 0 ? undefined : name\n}\n\n/** Workspace-relative path of a session file address; undefined for other resources. */\nexport function sessionRelativePath(address: string | undefined): string | undefined {\n if (address === undefined || !address.startsWith(SESSION_FILE_PREFIX))\n return undefined\n const rest = address.slice(SESSION_FILE_PREFIX.length)\n const slash = rest.indexOf('/')\n if (slash < 0)\n return undefined\n const path = rest.slice(slash + 1)\n if (path.length === 0)\n return undefined\n return path.split('/').map(decodeSegment).join('/')\n}\n\n/** The message inserted into the composer: target, quoted source, and requirement. */\nexport function composeQuote(prompt: QuotePrompt): string {\n const title = prompt.pageLabel === undefined ? prompt.target : `${prompt.target} · ${prompt.pageLabel}`\n return [\n `${prompt.heading}${title}`,\n '',\n prompt.originalLabel,\n quoteLines(prompt.text),\n '',\n `${prompt.requirementLabel}${prompt.requirement}`,\n ].join('\\n')\n}\n","import type { UserTextRule } from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport type { AnnotationParagraph, AnnotationRect, AnnotationSelection, AnnotationSendInput, AnnotationTextRun, OfficeAnnotation } from './types'\nimport { ANNOTATION_CANVAS_SELECTOR, ANNOTATION_CLOSE, ANNOTATION_HIT_X, ANNOTATION_HIT_Y, ANNOTATION_MAX_ITEMS, ANNOTATION_MAX_PAYLOAD, ANNOTATION_MAX_PIXELS, ANNOTATION_MAX_TEXT, ANNOTATION_NODE, ANNOTATION_OPEN, ANNOTATION_PADDING, ANNOTATION_SPREADSHEET_CANVAS_SELECTOR } from './constants'\nimport { normalizeSelection } from './quote'\n\nexport function unionRect(a: AnnotationRect, b: AnnotationRect): AnnotationRect {\n const left = Math.min(a.left, b.left)\n const top = Math.min(a.top, b.top)\n return { left, top, width: Math.max(a.left + a.width, b.left + b.width) - left, height: Math.max(a.top + a.height, b.top + b.height) - top }\n}\n\nexport function intersectRect(a: AnnotationRect, b: AnnotationRect): AnnotationRect | undefined {\n const left = Math.max(a.left, b.left)\n const top = Math.max(a.top, b.top)\n const width = Math.min(a.left + a.width, b.left + b.width) - left\n const height = Math.min(a.top + a.height, b.top + b.height) - top\n return width > 0 && height > 0 ? { left, top, width, height } : undefined\n}\n\n/** Leave breathing room around text/regions without extending outside the painted page. */\nexport function paddedRect(box: AnnotationRect, page: AnnotationRect): AnnotationRect | undefined {\n return intersectRect({ left: box.left - ANNOTATION_PADDING, top: box.top - ANNOTATION_PADDING, width: box.width + ANNOTATION_PADDING * 2, height: box.height + ANNOTATION_PADDING * 2 }, page)\n}\n\nexport function containsPoint(box: AnnotationRect, x: number, y: number): boolean {\n return x >= box.left && x <= box.left + box.width && y >= box.top && y <= box.top + box.height\n}\n\n/** Viewport coordinates for a native top-layer popover, independent of chat clipping ancestors. */\nexport function annotationPopoverPosition(anchor: AnnotationRect, popup: Pick<AnnotationRect, 'width' | 'height'>, viewport: Pick<AnnotationRect, 'width' | 'height'>): Pick<AnnotationRect, 'left' | 'top'> {\n return {\n left: Math.max(8, Math.min(anchor.left, viewport.width - popup.width - 8)),\n top: Math.max(8, Math.min(anchor.top >= popup.height + 8 ? anchor.top - popup.height : anchor.top + anchor.height, viewport.height - popup.height - 8)),\n }\n}\n\n/** Small hit slop bridges text edges without expanding the displayed paragraph outline. */\nexport function paragraphAtPoint(paragraphs: readonly AnnotationParagraph[], x: number, y: number): AnnotationParagraph | undefined {\n let hit: AnnotationParagraph | undefined\n for (const paragraph of paragraphs) {\n const box = paragraph.box\n if ((paragraph.rects ?? [box]).some(rect => x >= rect.left - ANNOTATION_HIT_X && x <= rect.left + rect.width + ANNOTATION_HIT_X\n && y >= rect.top - ANNOTATION_HIT_Y && y <= rect.top + rect.height + ANNOTATION_HIT_Y)\n && (!hit || box.width * box.height < hit.box.width * hit.box.height)) {\n hit = paragraph\n }\n }\n return hit\n}\n\n/** PDF text is positioned, not semantic: recover lines, then separate columns and paragraph gaps. */\nexport function groupParagraphs(runs: readonly AnnotationTextRun[]): AnnotationParagraph[] {\n const lines: { text: string, box: AnnotationRect, rects: AnnotationRect[] }[] = []\n for (const run of [...runs].sort((a, b) => a.box.top - b.box.top || a.box.left - b.box.left)) {\n if (!run.text.trim() || run.box.width <= 0 || run.box.height <= 0)\n continue\n const line = lines.find(item => Math.abs(item.box.top - run.box.top) < Math.min(item.box.height, run.box.height) * 0.45\n && run.box.left >= item.box.left && run.box.left - (item.box.left + item.box.width) < run.box.height * 2)\n if (line) {\n line.text += ` ${run.text}`\n line.box = unionRect(line.box, run.box)\n line.rects.push(run.box)\n }\n else {\n lines.push({ text: run.text, box: run.box, rects: [run.box] })\n }\n }\n const paragraphs: { text: string, box: AnnotationRect, rects: AnnotationRect[], last: AnnotationRect }[] = []\n for (const line of lines) {\n const paragraph = paragraphs.findLast((item) => {\n const gap = line.box.top - (item.last.top + item.last.height)\n const overlap = Math.min(item.last.left + item.last.width, line.box.left + line.box.width) - Math.max(item.last.left, line.box.left)\n return gap >= -line.box.height * 0.2 && gap <= Math.min(item.last.height, line.box.height) * 0.7\n && overlap > 0 && Math.abs(item.last.left - line.box.left) < line.box.height * 2\n && Math.max(item.last.height, line.box.height) / Math.min(item.last.height, line.box.height) < 1.4\n })\n if (paragraph) {\n paragraph.text += `\\n${line.text}`\n paragraph.box = unionRect(paragraph.box, line.box)\n paragraph.rects.push(...line.rects)\n paragraph.last = line.box\n }\n else {\n paragraphs.push({ ...line, last: line.box })\n }\n }\n return paragraphs.map(({ text, box, rects }) => ({ text: normalizeSelection(text), box, rects }))\n}\n\n/** Read only the accessible page canvas's sibling text layer, without private PDF.js state. */\nexport function canvasParagraphs(canvas: HTMLCanvasElement): AnnotationParagraph[] {\n const surface = canvas.parentElement\n if (!surface)\n return []\n const walker = document.createTreeWalker(surface, NodeFilter.SHOW_TEXT)\n const runs: AnnotationTextRun[] = []\n for (let node = walker.nextNode(); node; node = walker.nextNode()) {\n if (!node.textContent?.trim())\n continue\n const range = document.createRange()\n range.selectNodeContents(node)\n const box = range.getBoundingClientRect()\n if (box.width > 0 && box.height > 0)\n runs.push({ text: node.textContent, box: { left: box.left, top: box.top, width: box.width, height: box.height } })\n }\n // ponytail: visual paragraphs in PDF/Office previews, replace with a public paragraph API when provided.\n return groupParagraphs(runs)\n}\n\n/** Slot outlets are display:contents wrappers, not the document header itself. */\nexport function annotationPreview(anchor: HTMLElement): { header: HTMLElement, root: HTMLElement } | undefined {\n let header = anchor.parentElement\n while (header && getComputedStyle(header).display === 'contents')\n header = header.parentElement\n return header?.parentElement ? { header, root: header.parentElement } : undefined\n}\n\nexport function canvasAt(preview: HTMLElement, x: number, y: number): { canvas: HTMLCanvasElement, page: number } | undefined {\n const canvases = [...preview.querySelectorAll<HTMLCanvasElement>(ANNOTATION_CANVAS_SELECTOR)]\n const index = canvases.findIndex(canvas => containsPoint(canvas.getBoundingClientRect(), x, y) && canvas.getBoundingClientRect().width > 0)\n return index < 0 ? undefined : { canvas: canvases[index]!, page: index + 1 }\n}\n\n/** A workbook is one unpaged grid canvas: it locates pixels, never a page number. */\nexport function spreadsheetAt(preview: HTMLElement, x: number, y: number): { canvas: HTMLCanvasElement } | undefined {\n const canvas = [...preview.querySelectorAll<HTMLCanvasElement>(ANNOTATION_SPREADSHEET_CANVAS_SELECTOR)].find(item => containsPoint(item.getBoundingClientRect(), x, y) && item.getBoundingClientRect().width > 0)\n return canvas ? { canvas } : undefined\n}\n\nexport function normalizedRegion(box: AnnotationRect, page: AnnotationRect): AnnotationRect {\n if (page.width <= 0 || page.height <= 0)\n throw new Error('annotation.emptyPage')\n const clipped = intersectRect(box, page)\n if (!clipped)\n throw new Error('annotation.emptyRegion')\n return { left: (clipped.left - page.left) / page.width, top: (clipped.top - page.top) / page.height, width: clipped.width / page.width, height: clipped.height / page.height }\n}\n\n/** Copy the selected pixels now, before a zoom, rerender, or tab switch can change the page. */\nexport async function captureAnnotation(selection: AnnotationSelection, name: string, pixelLimit = ANNOTATION_MAX_PIXELS, dimensionLimit = Infinity): Promise<File> {\n const canvas = selection.canvas\n if (!canvas || canvas.width <= 0 || canvas.height <= 0)\n throw new Error('annotation.captureFailed')\n const painted = canvas.getBoundingClientRect()\n const region = selection.region ?? normalizedRegion(selection.box, painted)\n const width = canvas.width * region.width\n const height = canvas.height * region.height\n const scale = Math.min(1, Math.sqrt(pixelLimit / (width * height)), dimensionLimit / width, dimensionLimit / height)\n if (!Number.isFinite(scale) || scale <= 0)\n throw new Error('annotation.captureFailed')\n const output = document.createElement('canvas')\n output.width = Math.max(1, Math.floor(width * scale))\n output.height = Math.max(1, Math.floor(height * scale))\n const context = output.getContext('2d')\n if (!context)\n throw new Error('annotation.captureFailed')\n context.drawImage(canvas, region.left * canvas.width, region.top * canvas.height, width, height, 0, 0, output.width, output.height)\n const blob = await new Promise<Blob>((resolve, reject) => output.toBlob(value => value ? resolve(value) : reject(new Error('annotation.captureFailed')), 'image/png'))\n return new File([blob], name, { type: 'image/png' })\n}\n\nfunction isAnnotation(value: unknown): value is OfficeAnnotation {\n if (typeof value !== 'object' || value === null)\n return false\n const item = value as Record<string, unknown>\n const string = (value: unknown, max: number): boolean => typeof value === 'string' && value.length <= max\n if (!string(item.target, ANNOTATION_MAX_TEXT) || !string(item.fileName, 1000) || !string(item.text, ANNOTATION_MAX_TEXT)\n || !string(item.requirement, ANNOTATION_MAX_TEXT) || !(item.requirement as string).trim()\n || (item.page !== undefined && (!Number.isSafeInteger(item.page) || (item.page as number) < 1))\n || (item.imageName !== undefined && !string(item.imageName, 1000))\n || (item.sheet !== undefined && (!string(item.sheet, 1000) || !(item.sheet as string).trim()))\n || (item.range !== undefined && (!string(item.range, 100) || !(item.range as string).trim()))\n || (item.unmapped !== undefined && item.unmapped !== true)) {\n return false\n }\n if (item.region !== undefined) {\n const region = item.region as Record<string, unknown> | null\n if (!region || !['left', 'top', 'width', 'height'].every(key => typeof region[key] === 'number' && Number.isFinite(region[key]) && (region[key] as number) >= 0 && (region[key] as number) <= 1))\n return false\n if ((region.width as number) <= 0 || (region.height as number) <= 0\n || (region.left as number) + (region.width as number) > 1.000001 || (region.top as number) + (region.height as number) > 1.000001) {\n return false\n }\n }\n return true\n}\n\n/** Plain text in the normal user message is the durable source of truth; no new Session event. */\nexport function serializeAnnotations(items: readonly OfficeAnnotation[]): string {\n if (!items.length || items.length > ANNOTATION_MAX_ITEMS || !items.every(isAnnotation))\n throw new Error('annotation.invalid')\n const payload = JSON.stringify(items).replace(/</gu, '\\\\u003c')\n if (payload.length > ANNOTATION_MAX_PAYLOAD)\n throw new Error('annotation.tooLarge')\n return `${ANNOTATION_OPEN}\\n${payload}\\n${ANNOTATION_CLOSE}`\n}\n\nexport const annotationRule: UserTextRule<'officeAnnotation'> = {\n id: ANNOTATION_NODE,\n order: 10,\n match(text, from) {\n for (let start = text.indexOf(ANNOTATION_OPEN, from); start >= 0; start = text.indexOf(ANNOTATION_OPEN, start + ANNOTATION_OPEN.length)) {\n const end = text.indexOf(ANNOTATION_CLOSE, start + ANNOTATION_OPEN.length)\n if (end < 0)\n return undefined\n const payload = text.slice(start + ANNOTATION_OPEN.length, end).trim()\n if (payload.length > ANNOTATION_MAX_PAYLOAD)\n continue\n try {\n const items: unknown = JSON.parse(payload)\n if (Array.isArray(items) && items.length > 0 && items.length <= ANNOTATION_MAX_ITEMS && items.every(isAnnotation))\n return { id: ANNOTATION_NODE, start, end: end + ANNOTATION_CLOSE.length, data: { items } }\n }\n catch { /* Invalid/foreign markers remain visible as ordinary text. */ }\n }\n return undefined\n },\n}\n\n/** Prepare one synchronous input transaction; admitted or restored drafts belong to the composer. */\nexport function sendAnnotations({ items, inputActions, intake, limits, existingImages, deferSubmit }: AnnotationSendInput): 'sent' | 'draft' {\n const text = serializeAnnotations(items.map(item => item.annotation))\n const files = items.flatMap(item => item.file ? [item.file] : [])\n if (files.length && !intake)\n throw new Error('annotation.intakeUnavailable')\n if (files.length && limits) {\n if (files.some(file => !limits.mediaTypes.includes(file.type) || file.size > limits.maxImageBytes)\n || existingImages.length + files.length > limits.maxImagesPerMessage\n || [...existingImages, ...files].reduce((sum, file) => sum + file.size, 0) > limits.maxMessageImageBytes) {\n throw new Error('annotation.imageLimit')\n }\n }\n const span = inputActions.captureInsertion()\n const drafts = files.length ? intake!.create(files) : []\n if (drafts.length && !inputActions.addAttachments(drafts.map(item => item.id))) {\n intake!.release(drafts)\n throw new Error('annotation.sendFailed')\n }\n if (!inputActions.insertText(`\\n${text}\\n`, { ...span, start: span.end })) {\n for (const draft of drafts)\n inputActions.removeAttachment(draft.id)\n intake?.release(drafts)\n throw new Error('annotation.sendFailed')\n }\n try {\n inputActions.persistDraft()\n if (deferSubmit)\n return 'draft'\n inputActions.submit()\n return 'sent'\n }\n catch {\n // The text and files are already in the composer; never discard or duplicate them on retry.\n return 'draft'\n }\n}\n","import type { UserTextNodeProps } from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { ReactElement } from 'react'\nimport type { OFFICE_NS } from './constants'\nimport type { AnnotationInjected } from './types'\nimport { useId, useLayoutEffect, useRef, useState } from 'react'\nimport { annotationPopoverPosition } from './annotation'\nimport { fillTemplate } from './quote'\n\ntype Props = UserTextNodeProps<'officeAnnotation'> & PropsLocale<typeof OFFICE_NS> & Pick<AnnotationInjected, 'openAnnotation'>\n\n/** The native top layer escapes chat clipping without moving UI outside its slot. */\nexport function AnnotationReference({ node, interactive, openAnnotation, t }: Props): ReactElement {\n const popupId = useId()\n const anchor = useRef<HTMLSpanElement>(null)\n const popup = useRef<HTMLSpanElement>(null)\n const [open, setOpen] = useState(false)\n const label = fillTemplate(t('annotation.count'), { count: String(node.data.items.length) })\n\n useLayoutEffect(() => {\n const element = popup.current\n const trigger = anchor.current\n if (!element || !trigger)\n return\n if (!open) {\n element.hidePopover?.()\n return\n }\n element.showPopover?.()\n const position = (): void => {\n const viewport = { width: document.documentElement.clientWidth, height: window.innerHeight }\n const { left, top } = annotationPopoverPosition(trigger.getBoundingClientRect(), element.getBoundingClientRect(), viewport)\n element.style.left = `${left}px`\n element.style.top = `${top}px`\n }\n const scroll = (event: Event): void => {\n if (event.target instanceof Node && element.contains(event.target))\n return\n setOpen(false)\n }\n const resize = new ResizeObserver(position)\n resize.observe(trigger)\n resize.observe(element)\n window.addEventListener('resize', position)\n document.addEventListener('scroll', scroll, true)\n position()\n return () => {\n element.hidePopover?.()\n resize.disconnect()\n window.removeEventListener('resize', position)\n document.removeEventListener('scroll', scroll, true)\n }\n }, [open])\n\n return (\n <span\n ref={anchor}\n className=\"dsh-office-annotation-reference\"\n onPointerEnter={() => setOpen(true)}\n onPointerLeave={(event) => {\n if (!(event.relatedTarget instanceof Node) || !event.currentTarget.contains(event.relatedTarget))\n setOpen(false)\n }}\n onFocus={() => setOpen(true)}\n onBlur={(event) => {\n if (!event.currentTarget.contains(event.relatedTarget))\n setOpen(false)\n }}\n onKeyDown={(event) => {\n if (event.key === 'Escape') {\n event.preventDefault()\n event.stopPropagation()\n if (popup.current?.contains(event.target as Node))\n anchor.current?.querySelector('button')?.focus()\n setOpen(false)\n }\n }}\n >\n <button type=\"button\" id={`${popupId}-trigger`} aria-haspopup=\"dialog\" aria-controls={popupId} aria-expanded={open}>{label}</button>\n <span ref={popup} {...{ popover: 'manual' }} className=\"dsh-office-annotation-popover\" data-open={open} id={popupId} role=\"dialog\" aria-labelledby={`${popupId}-trigger`}>\n <span className=\"dsh-office-annotation-list\">\n {node.data.items.map((item, index) => (\n <span className=\"dsh-office-annotation-item\" key={index}>\n <span className=\"dsh-office-annotation-source\">\n {interactive\n ? <button type=\"button\" onClick={() => openAnnotation(item.target)} title={item.target}>{item.fileName}</button>\n : <span>{item.fileName}</span>}\n </span>\n <span className=\"dsh-office-annotation-requirement\">{item.requirement}</span>\n </span>\n ))}\n </span>\n </span>\n </span>\n )\n}\n","import type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { CSSProperties, PointerEvent, ReactElement } from 'react'\nimport type { OFFICE_NS } from './constants'\nimport type { AnnotationInjected, AnnotationRect, AnnotationSelection, PendingAnnotation } from './types'\nimport { useEffect, useId, useRef, useState } from 'react'\nimport { annotationPreview, canvasAt, canvasParagraphs, captureAnnotation, intersectRect, normalizedRegion, paddedRect, paragraphAtPoint, sendAnnotations, spreadsheetAt } from './annotation'\nimport { ANNOTATION_CANVAS_SELECTOR, ANNOTATION_HOLD_MS, ANNOTATION_MAX_ITEMS, ANNOTATION_MAX_TEXT, ANNOTATION_MIN_REGION, ANNOTATION_SPREADSHEET_CANVAS_SELECTOR } from './constants'\nimport { fillTemplate } from './quote'\n\ntype Props = PropsRuntime<'sidebar.right.tab.document.actions'> & PropsLocale<typeof OFFICE_NS> & AnnotationInjected\n\n/** This slot is rendered by the document header; every overlay stays in this React subtree. */\nexport function DocumentAnnotation(props: Props): ReactElement | null {\n if (!/\\.(?:pdf|docx?|pptx|xlsx)$/iu.test(props.absolutePath))\n return null\n return <AnnotationTool key={props.absolutePath} {...props} />\n}\n\nfunction AnnotationTool({ absolutePath, pendingAnnotations, intake, inputActions, useInput, useProjection, t }: Props): ReactElement {\n const anchor = useRef<HTMLSpanElement>(null)\n const form = useRef<HTMLFormElement>(null)\n const surface = useRef<HTMLDivElement>(null)\n const preview = useRef<HTMLElement>()\n const [bounds, setBounds] = useState<AnnotationRect>()\n const [active, setActive] = useState(false)\n const [hover, setHover] = useState<AnnotationSelection>()\n const [selection, setSelection] = useState<AnnotationSelection>()\n const [requirement, setRequirement] = useState('')\n const [image, setImage] = useState<File>()\n const [capturing, setCapturing] = useState(false)\n const [dragging, setDragging] = useState(false)\n const [items, setItems] = useState<readonly PendingAnnotation[]>(() => pendingAnnotations.get(absolutePath) ?? [])\n const [summaryDismissed, setSummaryDismissed] = useState(false)\n const summaryId = useId()\n const [error, setError] = useState('')\n const input = useInput(state => state)\n const limits = useProjection('imageLimits')\n const isPdf = /\\.pdf$/iu.test(absolutePath)\n const isSpreadsheet = /\\.xlsx$/iu.test(absolutePath)\n /** Formats whose page/region is only legible as a screenshot attachment. */\n const captures = isPdf || isSpreadsheet\n const canvasSelector = isSpreadsheet ? ANNOTATION_SPREADSHEET_CANVAS_SELECTOR : ANNOTATION_CANVAS_SELECTOR\n const fileName = absolutePath.replace(/\\\\/gu, '/').split('/').pop() ?? absolutePath\n const revision = useRef(0)\n const hold = useRef<ReturnType<typeof setTimeout>>()\n const gesture = useRef<{ x: number, y: number, lastX: number, lastY: number, canvas: HTMLCanvasElement, page?: number, region: boolean }>()\n const cache = useRef<{ canvas: HTMLCanvasElement, box: AnnotationRect, paragraphs: ReturnType<typeof canvasParagraphs> }>()\n const disabled = input.phase !== 'plain'\n\n useEffect(() => {\n if (items.length)\n pendingAnnotations.set(absolutePath, items)\n else\n pendingAnnotations.delete(absolutePath)\n }, [absolutePath, items, pendingAnnotations])\n\n function dismiss(): void {\n revision.current++\n setSelection(undefined)\n setImage(undefined)\n setCapturing(false)\n setRequirement('')\n }\n\n function cancelGesture(): void {\n clearTimeout(hold.current)\n gesture.current = undefined\n setDragging(false)\n setHover(undefined)\n }\n\n useEffect(() => {\n const node = anchor.current\n const container = node && annotationPreview(node)\n if (!container)\n return\n const { header, root } = container\n preview.current = root\n let frame = 0\n const measure = (): void => {\n cancelAnimationFrame(frame)\n frame = requestAnimationFrame(() => {\n cache.current = undefined\n const rect = root.getBoundingClientRect()\n const top = Math.max(rect.top, header.getBoundingClientRect().bottom, 0)\n const bottom = Math.min(rect.bottom, window.innerHeight)\n const left = Math.max(0, rect.left)\n const right = Math.min(rect.right, window.innerWidth)\n const canvas = [...root.querySelectorAll<HTMLCanvasElement>(canvasSelector)].find(canvas => canvas.getBoundingClientRect().width > 0)\n const visible = root.isConnected && !root.closest('[hidden], [aria-hidden=\"true\"]') && getComputedStyle(root).visibility === 'visible'\n setBounds(visible && rect.height > 40 && canvas && right > left && bottom > top\n ? { left, top, width: right - left, height: bottom - top }\n : undefined)\n // Keep the saved page-relative region and comment when viewport geometry changes.\n setSelection((previous) => {\n if (!previous?.canvas || !previous.region)\n return previous\n const page = previous.canvas.getBoundingClientRect()\n const region = previous.region\n const box = { left: page.left + region.left * page.width, top: page.top + region.top * page.height, width: region.width * page.width, height: region.height * page.height }\n return Object.keys(box).every(key => box[key as keyof AnnotationRect] === previous.box[key as keyof AnnotationRect]) ? previous : { ...previous, box }\n })\n })\n }\n const resize = new ResizeObserver(measure)\n resize.observe(root)\n const mutation = new MutationObserver((records) => {\n if (records.some(record => !node.contains(record.target)))\n measure()\n })\n mutation.observe(root, { childList: true, subtree: true, attributes: true, attributeFilter: ['hidden', 'aria-hidden', 'class', 'style'] })\n for (let parent = root.parentElement; parent; parent = parent.parentElement)\n mutation.observe(parent, { attributes: true })\n window.addEventListener('resize', measure)\n root.addEventListener('transitionend', measure)\n root.addEventListener('scroll', measure, true)\n measure()\n return () => {\n revision.current++\n clearTimeout(hold.current)\n cancelAnimationFrame(frame)\n resize.disconnect()\n mutation.disconnect()\n window.removeEventListener('resize', measure)\n root.removeEventListener('transitionend', measure)\n root.removeEventListener('scroll', measure, true)\n preview.current = undefined\n }\n }, [])\n\n useEffect(() => {\n if (!selection)\n return\n const dismissOutside = (event: globalThis.PointerEvent): void => {\n if (event.target instanceof Node && !form.current?.contains(event.target))\n dismiss()\n }\n document.addEventListener('pointerdown', dismissOutside, true)\n form.current?.querySelector('input')?.focus()\n return () => {\n document.removeEventListener('pointerdown', dismissOutside, true)\n }\n }, [selection])\n\n useEffect(() => {\n if (active)\n surface.current?.focus()\n }, [active])\n\n function scrollPreview(x: number, y: number): void {\n const root = preview.current\n if (!root)\n return\n let scroll = root.querySelector(canvasSelector)?.parentElement\n while (scroll && scroll !== root && !/auto|scroll/u.test(getComputedStyle(scroll).overflowY))\n scroll = scroll.parentElement\n scroll?.scrollBy({ left: x, top: y })\n setHover(undefined)\n }\n\n useEffect(() => {\n const node = surface.current\n if (!active || !node || !bounds)\n return\n const wheel = (event: WheelEvent): void => {\n event.preventDefault()\n const unit = event.deltaMode === 1 ? 16 : event.deltaMode === 2 ? bounds.height : 1\n scrollPreview(event.deltaX * unit, event.deltaY * unit)\n }\n node.addEventListener('wheel', wheel, { passive: false })\n return () => node.removeEventListener('wheel', wheel)\n }, [active, bounds])\n\n function surfaceAt(x: number, y: number): { canvas: HTMLCanvasElement, page?: number } | undefined {\n const root = preview.current\n if (!root)\n return undefined\n return isSpreadsheet ? spreadsheetAt(root, x, y) : canvasAt(root, x, y)\n }\n\n function paragraphAt(x: number, y: number): AnnotationSelection | undefined {\n // A workbook grid has no text layer: only a dragged region can locate anything.\n if (isSpreadsheet || !preview.current)\n return undefined\n const page = canvasAt(preview.current, x, y)\n if (!page)\n return undefined\n const box = page.canvas.getBoundingClientRect()\n if (cache.current?.canvas !== page.canvas || cache.current.box.left !== box.left || cache.current.box.top !== box.top\n || cache.current.box.width !== box.width || cache.current.box.height !== box.height) {\n cache.current = { canvas: page.canvas, box, paragraphs: canvasParagraphs(page.canvas) }\n }\n const paragraph = paragraphAtPoint(cache.current.paragraphs, x, y)\n return paragraph ? { ...paragraph, ...page } : undefined\n }\n\n function regionSelection(x: number, y: number): AnnotationSelection | undefined {\n const start = gesture.current\n if (!start)\n return undefined\n const box = intersectRect({ left: Math.min(start.x, x), top: Math.min(start.y, y), width: Math.abs(x - start.x), height: Math.abs(y - start.y) }, start.canvas.getBoundingClientRect())\n if (!box)\n return undefined\n const paragraphs = cache.current?.canvas === start.canvas ? cache.current.paragraphs : canvasParagraphs(start.canvas)\n const text = isSpreadsheet ? '' : paragraphs.filter(item => (item.rects ?? [item.box]).some(rect => intersectRect(rect, box))).map(item => item.text).join('\\n').slice(0, ANNOTATION_MAX_TEXT)\n return { canvas: start.canvas, page: start.page, box, region: normalizedRegion(box, start.canvas.getBoundingClientRect()), text }\n }\n\n function pointerDown(event: PointerEvent<HTMLDivElement>): void {\n if (event.button !== 0 || !preview.current || (captures && !intake))\n return\n const page = surfaceAt(event.clientX, event.clientY)\n if (!page)\n return\n event.preventDefault()\n dismiss()\n const start = { ...page, x: event.clientX, y: event.clientY, lastX: event.clientX, lastY: event.clientY, region: false }\n gesture.current = start\n event.currentTarget.setPointerCapture(event.pointerId)\n hold.current = setTimeout(() => {\n if (gesture.current !== start)\n return\n start.region = true\n setDragging(true)\n setHover(regionSelection(start.lastX, start.lastY))\n }, ANNOTATION_HOLD_MS)\n }\n\n function pointerMove(event: PointerEvent<HTMLDivElement>): void {\n const start = gesture.current\n if (start) {\n start.lastX = event.clientX\n start.lastY = event.clientY\n if (!start.region && Math.hypot(event.clientX - start.x, event.clientY - start.y) >= ANNOTATION_MIN_REGION) {\n clearTimeout(hold.current)\n start.region = true\n setDragging(true)\n }\n }\n setHover(start?.region ? regionSelection(event.clientX, event.clientY) : paragraphAt(event.clientX, event.clientY))\n }\n\n async function openSelection(value: AnnotationSelection): Promise<void> {\n dismiss()\n const current = revision.current\n setError('')\n const page = value.canvas?.getBoundingClientRect()\n const box = page ? paddedRect(value.box, page) : value.box\n if (!box)\n return\n const region = page ? normalizedRegion(box, page) : value.region\n const frozen = { ...value, box, region }\n setSelection(frozen)\n if (!captures)\n return\n setCapturing(true)\n try {\n const label = value.page === undefined ? 'region' : `p${value.page}`\n const file = await captureAnnotation(frozen, `${fileName}-${label}-${Date.now()}.png`, limits?.maxImagePixels, limits?.maxImageDimension)\n if (revision.current === current)\n setImage(file)\n }\n catch {\n if (revision.current === current)\n setError(t('annotation.captureFailed'))\n }\n finally {\n if (revision.current === current)\n setCapturing(false)\n }\n }\n\n function pointerUp(event: PointerEvent<HTMLDivElement>): void {\n const start = gesture.current\n clearTimeout(hold.current)\n if (!start)\n return\n const value = start.region ? regionSelection(event.clientX, event.clientY) : paragraphAt(event.clientX, event.clientY)\n const moved = Math.hypot(event.clientX - start.x, event.clientY - start.y)\n cancelGesture()\n if (value && (start.region ? value.box.width >= ANNOTATION_MIN_REGION && value.box.height >= ANNOTATION_MIN_REGION : moved < ANNOTATION_MIN_REGION))\n void openSelection(value)\n }\n\n function add(): void {\n if (!selection || !requirement.trim() || (captures && !image) || items.length >= ANNOTATION_MAX_ITEMS)\n return\n const annotation = {\n target: absolutePath,\n fileName,\n page: selection.page,\n text: selection.text.slice(0, ANNOTATION_MAX_TEXT),\n requirement: requirement.trim(),\n region: selection.region,\n imageName: image?.name,\n // The workbook preview exposes no selection API we control, so the region stays raw.\n ...(isSpreadsheet ? { unmapped: true as const } : {}),\n }\n setItems(previous => [...previous, { annotation, file: image }])\n dismiss()\n }\n\n function send(): void {\n if (disabled)\n return\n try {\n const result = sendAnnotations({\n items,\n inputActions,\n intake,\n limits,\n existingImages: intake?.images(input.attachmentIds) ?? [],\n deferSubmit: !!input.draft.trim() || input.attachmentIds.length > 0,\n })\n setItems([])\n setSummaryDismissed(false)\n setActive(false)\n dismiss()\n setError(result === 'draft' ? t('annotation.draftReady') : '')\n }\n catch (error) {\n const key = error instanceof Error ? error.message : 'annotation.sendFailed'\n setError(t(key.startsWith('annotation.') ? key : 'annotation.sendFailed'))\n }\n }\n\n const highlight = selection ?? hover\n const highlightBox = highlight && !selection && !dragging && highlight.canvas\n ? paddedRect(highlight.box, highlight.canvas.getBoundingClientRect())\n : highlight?.box\n const clippedHighlight = highlightBox && bounds ? intersectRect(highlightBox, bounds) : undefined\n const formWidth = bounds ? Math.min(360, bounds.width - 16) : 0\n const formLeft = bounds && selection ? Math.max(bounds.left + 8, Math.min(selection.box.left, bounds.left + bounds.width - formWidth - 8)) : 0\n const formTop = bounds && selection ? Math.max(bounds.top + 4, Math.min(selection.box.top + selection.box.height + 6, bounds.top + bounds.height - 56)) : 0\n\n return (\n <span\n ref={anchor}\n className=\"dsh-office-annotate\"\n onKeyDown={(event) => {\n if (!active || event.key !== 'Escape')\n return\n event.preventDefault()\n event.stopPropagation()\n const hasSelection = !!selection || !!gesture.current\n dismiss()\n cancelGesture()\n if (hasSelection) {\n surface.current?.focus()\n }\n else {\n setActive(false)\n anchor.current?.querySelector('button')?.focus()\n }\n }}\n >\n <button\n type=\"button\"\n className=\"dsh-office-annotate-toggle\"\n aria-pressed={active}\n disabled={!bounds || (captures && !intake)}\n title={captures && !intake ? t('annotation.intakeUnavailable') : !bounds ? t('annotation.unavailable') : t('annotation.help')}\n onClick={() => {\n setActive(value => !value)\n dismiss()\n cancelGesture()\n }}\n >\n {t('annotation.ask')}\n </button>\n {captures && !intake && <span role=\"status\" className=\"dsh-office-annotate-unavailable\">{t('annotation.intakeUnavailable')}</span>}\n {active && bounds && (\n <div\n ref={surface}\n className=\"dsh-office-annotate-surface\"\n tabIndex={0}\n style={{ left: bounds.left, top: bounds.top, width: bounds.width, height: bounds.height }}\n role=\"region\"\n aria-label={t('annotation.help')}\n onPointerDown={pointerDown}\n onPointerMove={pointerMove}\n onPointerUp={pointerUp}\n onPointerCancel={cancelGesture}\n onLostPointerCapture={cancelGesture}\n onKeyDown={(event) => {\n if (event.key === 'PageDown' || event.key === 'PageUp') {\n event.preventDefault()\n scrollPreview(0, bounds.height * (event.key === 'PageDown' ? 0.8 : -0.8))\n }\n else if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault()\n const paragraphs = [...preview.current!.querySelectorAll<HTMLCanvasElement>(ANNOTATION_CANVAS_SELECTOR)].flatMap((canvas, index) => canvasParagraphs(canvas).filter(item => intersectRect(item.box, bounds)).map(item => ({ ...item, canvas, page: index + 1 })))\n const current = paragraphs.findIndex(item => item.canvas === hover?.canvas && item.text === hover.text && item.box.top === hover.box.top)\n const index = current < 0 ? (event.key === 'ArrowDown' ? 0 : paragraphs.length - 1) : Math.max(0, Math.min(paragraphs.length - 1, current + (event.key === 'ArrowDown' ? 1 : -1)))\n setHover(paragraphs[index])\n }\n else if ((event.key === 'Enter' || event.key === ' ') && hover) {\n event.preventDefault()\n void openSelection(hover)\n }\n }}\n onPointerLeave={() => {\n if (!gesture.current)\n setHover(undefined)\n }}\n />\n )}\n {active && clippedHighlight && (\n <span className=\"dsh-office-annotate-highlight\" data-selected={selection || dragging ? 'true' : undefined} style={{ left: clippedHighlight.left, top: clippedHighlight.top, width: clippedHighlight.width, height: clippedHighlight.height }} />\n )}\n {active && selection && bounds && (\n <form\n ref={form}\n className=\"dsh-office-annotate-composer\"\n style={{ left: formLeft, top: formTop, width: formWidth }}\n aria-label={t('annotation.ask')}\n aria-busy={capturing}\n onSubmit={(event) => {\n event.preventDefault()\n add()\n }}\n >\n <input\n type=\"text\"\n aria-label={t('annotation.placeholder')}\n placeholder={t('annotation.placeholder')}\n value={requirement}\n maxLength={ANNOTATION_MAX_TEXT}\n onChange={event => setRequirement(event.target.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter' && event.nativeEvent.isComposing)\n event.preventDefault()\n }}\n />\n <button type=\"submit\" aria-label={t(capturing ? 'annotation.capturing' : 'annotation.add')} title={t(capturing ? 'annotation.capturing' : 'annotation.add')} disabled={!requirement.trim() || capturing || (captures && !image) || items.length >= ANNOTATION_MAX_ITEMS}>\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\"><path d=\"m5 12 4 4L19 6\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" /></svg>\n </button>\n </form>\n )}\n {(active || items.length > 0 || error) && bounds && (\n <div className=\"dsh-office-annotate-rail-position\" style={{ 'left': bounds.left, 'width': bounds.width, 'bottom': Math.max(0, window.innerHeight - bounds.top - bounds.height) + 12, '--dsh-office-annotation-width': `${bounds.width}px`, '--dsh-office-annotation-height': `${bounds.height}px` } as CSSProperties}>\n <div className=\"dsh-office-annotate-rail\">\n {error && <p role=\"alert\">{error}</p>}\n <div className=\"dsh-office-annotate-rail-actions\">\n <div\n className=\"dsh-office-annotate-summary\"\n data-dismissed={summaryDismissed ? 'true' : undefined}\n onPointerEnter={() => setSummaryDismissed(false)}\n onFocus={() => setSummaryDismissed(false)}\n onKeyDown={(event) => {\n if (event.key === 'Escape') {\n event.stopPropagation()\n event.currentTarget.querySelector('button')?.focus()\n setSummaryDismissed(true)\n }\n }}\n >\n <button type=\"button\" aria-haspopup=\"dialog\" aria-controls={summaryId} disabled={!items.length}>{fillTemplate(t('annotation.count'), { count: String(items.length) })}</button>\n {items.length > 0 && (\n <div id={summaryId} role=\"dialog\" aria-label={fillTemplate(t('annotation.count'), { count: String(items.length) })} className=\"dsh-office-annotate-popover\">\n <ul>\n {items.map((item, index) => (\n <li key={item.annotation.imageName ?? index}>\n <div>\n <span className=\"dsh-office-annotation-source\">\n <span title={item.annotation.target}>{item.annotation.fileName}</span>\n {item.annotation.page && <span>{fillTemplate(t('annotation.page'), { page: String(item.annotation.page) })}</span>}\n </span>\n {item.annotation.text && <span className=\"dsh-office-annotation-original\">{item.annotation.text}</span>}\n <span className=\"dsh-office-annotation-requirement\" title={item.annotation.requirement}>{item.annotation.requirement}</span>\n </div>\n </li>\n ))}\n </ul>\n </div>\n )}\n </div>\n <button\n type=\"button\"\n onClick={() => {\n setItems([])\n setActive(false)\n setSummaryDismissed(false)\n setError('')\n dismiss()\n cancelGesture()\n }}\n >\n {t('annotation.cancel')}\n </button>\n <button type=\"button\" className=\"dsh-office-annotate-primary\" disabled={!items.length || disabled} onClick={send}>{t('annotation.send')}</button>\n </div>\n </div>\n </div>\n )}\n </span>\n )\n}\n","import type { ReactElement, SVGProps } from 'react'\nimport type { OfficeFeatureId } from '../features'\n\n/*\n * Icons from Gravity UI Icons (MIT), https://github.com/gravity-ui/icons.\n * The original SVG files and license are vendored in assets/icons/.\n */\n\ntype OfficeIconProps = SVGProps<SVGSVGElement> & { size?: number }\n\nfunction frame(props: OfficeIconProps): SVGProps<SVGSVGElement> {\n const { size = 16, ...rest } = props\n return {\n 'width': size,\n 'height': size,\n 'viewBox': '0 0 16 16',\n 'fill': 'none',\n 'aria-hidden': true,\n ...rest,\n }\n}\n\n/** file-text: a document page with text lines. */\nexport function DocumentsIcon(props: OfficeIconProps): ReactElement {\n return (\n <svg {...frame(props)}>\n <path\n fill=\"currentColor\"\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M5 13.5h6a1.5 1.5 0 0 0 1.5-1.5V7.243a1.5 1.5 0 0 0-.44-1.061L8.819 2.939a1.5 1.5 0 0 0-1.06-.439H5A1.5 1.5 0 0 0 3.5 4v8A1.5 1.5 0 0 0 5 13.5m9-6.257a3 3 0 0 0-.879-2.122L9.88 1.88A3 3 0 0 0 7.757 1H5a3 3 0 0 0-3 3v8a3 3 0 0 0 3 3h6a3 3 0 0 0 3-3zM5 8.25a.75.75 0 0 1 .75-.75h4.5a.75.75 0 0 1 0 1.5h-4.5A.75.75 0 0 1 5 8.25m.75 2.25a.75.75 0 0 0 0 1.5h2.5a.75.75 0 0 0 0-1.5z\"\n />\n </svg>\n )\n}\n\n/** file-letter-p: a document page with a P badge. */\nexport function PdfIcon(props: OfficeIconProps): ReactElement {\n return (\n <svg {...frame(props)}>\n <path\n fill=\"currentColor\"\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M11 13.5H5A1.5 1.5 0 0 1 3.5 12V4A1.5 1.5 0 0 1 5 2.5h2.757a1.5 1.5 0 0 1 1.061.44l3.243 3.242a1.5 1.5 0 0 1 .439 1.06V12a1.5 1.5 0 0 1-1.5 1.5m2.121-8.379A3 3 0 0 1 14 7.243V12a3 3 0 0 1-3 3H5a3 3 0 0 1-3-3V4a3 3 0 0 1 3-3h2.757a3 3 0 0 1 2.122.879zM6.5 6.5a.75.75 0 0 0-.75.75v4a.75.75 0 0 0 1.5 0v-.75H8.5a2 2 0 1 0 0-4zm2 2.5H7.25V8H8.5a.5.5 0 0 1 0 1\"\n />\n </svg>\n )\n}\n\n/** display: a presentation screen. */\nexport function PresentationsIcon(props: OfficeIconProps): ReactElement {\n return (\n <svg {...frame(props)}>\n <path\n fill=\"currentColor\"\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M12 3H4a1.5 1.5 0 0 0-1.5 1.5v4A1.5 1.5 0 0 0 4 10h8a1.5 1.5 0 0 0 1.5-1.5v-4A1.5 1.5 0 0 0 12 3M4 1.5a3 3 0 0 0-3 3v4a3 3 0 0 0 3 3h3.25V13h-2.5a.75.75 0 0 0 0 1.5h6.5a.75.75 0 0 0 0-1.5h-2.5v-1.5H12a3 3 0 0 0 3-3v-4a3 3 0 0 0-3-3z\"\n />\n </svg>\n )\n}\n\n/** layout-cells: a spreadsheet grid. */\nexport function SpreadsheetsIcon(props: OfficeIconProps): ReactElement {\n return (\n <svg {...frame(props)}>\n <path\n fill=\"currentColor\"\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M9.25 3.5h-2.5v2h2.5zM4 3.5h1.25v2H2.5V5A1.5 1.5 0 0 1 4 3.5M2.5 7h2.75v2H2.5zm0 3.5v.5A1.5 1.5 0 0 0 4 12.5h1.25v-2zm4.25 0v2h2.5v-2zm4 0v2H12a1.5 1.5 0 0 0 1.5-1.5v-.5zM13.5 9h-2.75V7h2.75zM9.25 9h-2.5V7h2.5zm1.5-5.5v2h2.75V5A1.5 1.5 0 0 0 12 3.5zM4 2a3 3 0 0 0-3 3v6a3 3 0 0 0 3 3h8a3 3 0 0 0 3-3V5a3 3 0 0 0-3-3z\"\n />\n </svg>\n )\n}\n\nexport const OFFICE_ICONS: Record<OfficeFeatureId, (props: OfficeIconProps) => ReactElement> = {\n documents: DocumentsIcon,\n pdf: PdfIcon,\n presentations: PresentationsIcon,\n spreadsheets: SpreadsheetsIcon,\n}\n","import type { UserTextNodeProps } from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport type { ReactElement } from 'react'\nimport type { OfficeChipInjected } from './types'\nimport { featureById } from '../features'\nimport { OFFICE_ICONS } from './icons'\n\ntype Props = UserTextNodeProps<'office'> & OfficeChipInjected\n\n/** Render the office reference chip with its format glyph. */\nexport function OfficeReference({ node, raw, interactive, openOffice, officeLabel }: Props): ReactElement {\n const feature = featureById(node.data.feature)\n if (feature == null)\n return <span>{raw}</span>\n\n const Icon = OFFICE_ICONS[feature.id]\n const content = (\n <>\n <Icon className=\"dsh-office-ref-icon\" size={14} />\n <span>{officeLabel(feature.id)}</span>\n </>\n )\n\n if (!interactive) {\n return (\n <span className=\"dsh-office-ref\" title={raw}>\n {content}\n </span>\n )\n }\n\n return (\n <button\n type=\"button\"\n className=\"dsh-office-ref\"\n title={raw}\n data-interactive\n onClick={() => openOffice(feature.id)}\n >\n {content}\n </button>\n )\n}\n","import { ANNOTATION_CURSOR, OFFICE_NS, OFFICE_STYLE_ID } from './constants'\n\n/** One plugin-scoped style tag; the disposer owns removal. */\nexport function mountOfficeStyles(): () => void {\n if (typeof document === 'undefined')\n return () => {}\n\n const style = document.querySelector<HTMLStyleElement>(`style[data-plugin-css=\"${OFFICE_STYLE_ID}\"]`) ?? document.createElement('style')\n style.dataset.plugin = OFFICE_NS\n style.dataset.pluginCss = OFFICE_STYLE_ID\n style.textContent = `\n.dsh-office-ref {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n max-width: 100%;\n height: calc(20px + var(--dsh-content-font-delta, 0px));\n padding: 0 6px;\n border: 0.5px solid var(--dsw-alias-border-l3);\n border-radius: var(--dsw-radius-sm);\n background: var(--dsw-alias-bg-base);\n color: var(--dsw-alias-label-secondary);\n font: inherit;\n line-height: 1;\n vertical-align: baseline;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.dsh-office-ref[data-interactive] { cursor: pointer; }\n.dsh-office-ref[data-interactive]:hover {\n background: var(--dsw-alias-interactive-bg-hover-solid);\n color: var(--dsw-alias-label-primary);\n}\n.dsh-office-ref[data-interactive]:focus-visible {\n outline: 2px solid var(--dsw-alias-state-business-primary);\n outline-offset: 1px;\n}\n.dsh-office-ref-icon { flex: none; color: var(--dsw-alias-label-tertiary); }\n.dsh-office-ref[data-interactive]:hover .dsh-office-ref-icon { color: inherit; }\n.dsh-office-annotate { display: inline-flex; flex: none; }\n.dsh-office-annotate,\n.dsh-office-annotation-reference { font: 400 12px/18px var(--dsw-font-family, system-ui, sans-serif); }\n.dsh-office-annotate *,\n.dsh-office-annotation-reference * { box-sizing: border-box; }\n.dsh-office-annotate button,\n.dsh-office-annotation-reference button {\n border: 0.5px solid var(--dsw-alias-border-l2);\n border-radius: var(--dsw-radius-md);\n padding: 5px 9px;\n color: var(--dsw-alias-label-primary);\n background: var(--dsw-alias-bg-base);\n font: inherit;\n font-size: 12px;\n line-height: 1.4;\n cursor: pointer;\n}\n.dsh-office-annotate button:disabled { opacity: .45; cursor: not-allowed; }\n.dsh-office-annotate button:hover:not(:disabled),\n.dsh-office-annotation-reference button:hover { background: var(--dsw-alias-interactive-bg-hover-solid); }\n.dsh-office-annotate button:focus-visible,\n.dsh-office-annotation-reference button:focus-visible {\n outline: 2px solid var(--dsw-alias-state-business-primary);\n outline-offset: 2px;\n}\n.dsh-office-annotate .dsh-office-annotate-toggle {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n height: 24px;\n padding: 0 8px;\n line-height: 1;\n}\n.dsh-office-annotate .dsh-office-annotate-toggle[aria-pressed=\"true\"],\n.dsh-office-annotate .dsh-office-annotate-primary {\n color: var(--dsw-alias-state-business-primary);\n border-color: var(--dsw-alias-state-business-primary);\n background: color-mix(in srgb, var(--dsw-alias-state-business-primary) 10%, var(--dsw-alias-bg-base));\n}\n.dsh-office-annotate .dsh-office-annotate-surface {\n position: fixed;\n z-index: 40;\n touch-action: none;\n user-select: none;\n outline: none;\n cursor: ${ANNOTATION_CURSOR};\n}\n.dsh-office-annotate .dsh-office-annotate-highlight {\n position: fixed;\n z-index: 41;\n box-sizing: border-box;\n pointer-events: none;\n border: 1.25px solid var(--dsw-alias-state-business-primary);\n border-radius: 3px;\n}\n.dsh-office-annotate .dsh-office-annotate-highlight[data-selected=\"true\"] {\n border-style: dashed;\n background: color-mix(in srgb, var(--dsw-alias-state-business-primary) 8%, transparent);\n}\n.dsh-office-annotate .dsh-office-annotate-composer {\n position: fixed;\n z-index: 42;\n box-sizing: border-box;\n border: 0.5px solid var(--dsw-alias-border-l2);\n border-radius: var(--dsw-radius-md);\n background: var(--dsw-alias-bg-layer-2);\n color: var(--dsw-alias-label-primary);\n box-shadow: var(--dsw-shadow-lv2);\n}\n.dsh-office-annotate .dsh-office-annotate-composer {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 4px;\n border-radius: 999px;\n}\n.dsh-office-annotate .dsh-office-annotate-composer input:focus-visible { outline: none; }\n.dsh-office-annotate .dsh-office-annotate-composer input {\n box-sizing: border-box;\n min-width: 0;\n width: 100%;\n padding: 6px 10px;\n border: 0;\n border-radius: 999px;\n color: var(--dsw-alias-label-primary);\n background: transparent;\n font: inherit;\n font-size: 12px;\n line-height: 1.5;\n}\n.dsh-office-annotate .dsh-office-annotate-composer button {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n padding: 0;\n border: 0;\n border-radius: 50%;\n color: var(--dsw-alias-state-business-primary);\n background: color-mix(in srgb, var(--dsw-alias-state-business-primary) 10%, var(--dsw-alias-bg-base));\n}\n.dsh-office-annotate .dsh-office-annotate-composer button svg { width: 14px; height: 14px; }\n.dsh-office-annotate .dsh-office-annotate-rail-position {\n position: fixed;\n z-index: 42;\n display: flex;\n justify-content: center;\n padding: 0 8px;\n pointer-events: none;\n}\n.dsh-office-annotate .dsh-office-annotate-rail {\n position: relative;\n width: max-content;\n max-width: 100%;\n padding: 4px 6px;\n border-radius: 10px;\n background: var(--dsw-alias-toast-bg);\n color: var(--dsw-alias-toast-label);\n font: 500 12px/18px var(--dsw-font-family, system-ui, sans-serif);\n box-shadow: var(--dsw-shadow-lv3);\n pointer-events: auto;\n}\n.dsh-office-annotate .dsh-office-annotate-rail-actions { display: flex; align-items: center; justify-content: center; gap: 4px; }\n.dsh-office-annotate .dsh-office-annotate-rail-actions > button,\n.dsh-office-annotate .dsh-office-annotate-summary > button {\n height: 26px;\n padding: 0 8px;\n border: 0;\n border-radius: 8px;\n background: transparent;\n color: inherit;\n font: inherit;\n white-space: nowrap;\n}\n.dsh-office-annotate .dsh-office-annotate-summary { padding-right: 4px; border-right: 1px solid color-mix(in srgb, var(--dsw-alias-toast-label) 25%, transparent); }\n.dsh-office-annotate .dsh-office-annotate-rail-actions > button:hover:not(:disabled),\n.dsh-office-annotate .dsh-office-annotate-summary > button:hover:not(:disabled) { background: color-mix(in srgb, var(--dsw-alias-toast-label) 12%, transparent); }\n.dsh-office-annotate .dsh-office-annotate-rail-actions > .dsh-office-annotate-primary { background: var(--dsw-alias-state-business-primary); color: var(--dsw-alias-toast-label); }\n.dsh-office-annotate .dsh-office-annotate-rail-actions > .dsh-office-annotate-primary:hover:not(:disabled) { background: color-mix(in srgb, var(--dsw-alias-state-business-primary) 85%, var(--dsw-alias-toast-label)); }\n.dsh-office-annotate .dsh-office-annotate-rail p { max-width: min(360px, calc(var(--dsh-office-annotation-width) - 48px)); margin: 0 0 6px; font-size: 12px; overflow-wrap: anywhere; }\n.dsh-office-annotate .dsh-office-annotate-popover {\n display: none;\n position: absolute;\n bottom: 100%;\n left: 50%;\n width: min(320px, calc(var(--dsh-office-annotation-width, 100vw) - 16px), calc(100vw - 16px));\n box-sizing: border-box;\n padding-bottom: 8px;\n transform: translateX(-50%);\n}\n.dsh-office-annotate .dsh-office-annotate-summary:not([data-dismissed=\"true\"]):is(:hover, :focus-within) > .dsh-office-annotate-popover { display: block; }\n.dsh-office-annotation-reference { display: inline-block; position: relative; max-width: 100%; vertical-align: baseline; font: inherit; }\n.dsh-office-annotation-reference > button {\n max-width: 100%;\n padding: 0;\n border: 0;\n border-radius: 0;\n background: transparent;\n color: var(--dsw-alias-link);\n font: inherit;\n font-family: var(--dsw-font-markdown-code-font-family);\n font-weight: 500;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n vertical-align: baseline;\n}\n.dsh-office-annotation-reference > button:hover {\n background: transparent;\n text-decoration: underline dotted;\n text-underline-offset: 3px;\n}\n.dsh-office-annotation-reference .dsh-office-annotation-popover {\n display: none;\n position: fixed;\n z-index: 44;\n inset: auto;\n width: min(320px, calc(100vw - 16px));\n max-height: calc(100vh - 16px);\n box-sizing: border-box;\n margin: 0;\n padding: 4px 0;\n border: 0;\n background: transparent;\n color: var(--dsw-alias-label-primary);\n overflow: visible;\n text-align: left;\n font: 400 12px/18px var(--dsw-font-family, system-ui, sans-serif);\n}\n.dsh-office-annotation-reference .dsh-office-annotation-popover[data-open=\"true\"] { display: block; }\n.dsh-office-annotation-reference .dsh-office-annotation-popover::backdrop { pointer-events: none; }\n.dsh-office-annotate .dsh-office-annotate-popover > ul,\n.dsh-office-annotation-reference .dsh-office-annotation-list {\n display: flex;\n flex-direction: column;\n box-sizing: border-box;\n max-height: min(340px, 45vh);\n margin: 0;\n padding: 0 8px;\n font: 400 12px/18px var(--dsw-font-family, system-ui, sans-serif);\n text-align: left;\n overflow: auto;\n list-style: none;\n border: 0.5px solid var(--dsw-alias-border-l2);\n border-radius: var(--dsw-radius-md);\n background: var(--dsw-alias-bg-layer-2);\n color: var(--dsw-alias-label-primary);\n box-shadow: var(--dsw-shadow-lv2);\n}\n.dsh-office-annotate .dsh-office-annotate-popover > ul { max-height: min(340px, 45vh, max(40px, calc(var(--dsh-office-annotation-height, 100vh) - 80px))); }\n.dsh-office-annotate .dsh-office-annotate-popover li,\n.dsh-office-annotation-reference .dsh-office-annotation-item { display: flex; flex: none; flex-direction: column; gap: 3px; min-width: 0; padding: 8px 0; }\n.dsh-office-annotate .dsh-office-annotate-popover li > div { display: flex; flex-direction: column; gap: 3px; min-width: 0; }\n.dsh-office-annotate .dsh-office-annotate-popover .dsh-office-annotation-requirement { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.dsh-office-annotate .dsh-office-annotate-popover li + li,\n.dsh-office-annotation-reference .dsh-office-annotation-item + .dsh-office-annotation-item { border-top: .5px solid var(--dsw-alias-border-l3); }\n.dsh-office-annotate .dsh-office-annotation-source,\n.dsh-office-annotation-reference .dsh-office-annotation-source { display: flex; align-items: baseline; gap: 8px; color: var(--dsw-alias-label-tertiary); font-size: 12px; }\n.dsh-office-annotation-reference .dsh-office-annotation-source button { padding: 0; border: 0; color: var(--dsw-alias-state-business-primary); text-align: left; }\n.dsh-office-annotate .dsh-office-annotation-source > :first-child,\n.dsh-office-annotation-reference .dsh-office-annotation-source > :first-child { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.dsh-office-annotate .dsh-office-annotation-source > :not(:first-child),\n.dsh-office-annotation-reference .dsh-office-annotation-source > :not(:first-child) { flex: none; }\n.dsh-office-annotate .dsh-office-annotation-original,\n.dsh-office-annotation-reference .dsh-office-annotation-original { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--dsw-alias-label-tertiary); font-size: 12px; }\n.dsh-office-annotate .dsh-office-annotation-requirement,\n.dsh-office-annotation-reference .dsh-office-annotation-requirement { display: block; white-space: pre-wrap; overflow-wrap: anywhere; }\n`\n document.head.appendChild(style)\n return () => style.remove()\n}\n","import type { Context as ClientContext } from '@deepseek-ai/cordis'\nimport type {} from '@deepseek-ai/dsh-api-remotes/client'\nimport type {} from '@deepseek-ai/dsh-api-session-controller/client'\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\nimport type { UserTextRule } from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport type { InputTriggerSource } from '@deepseek-ai/dsh-client-ui-input-trigger/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-renderer/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-sidebar-right/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-slots'\nimport type { OfficeFeatureId } from '../features'\nimport type { AnnotationController, AnnotationInjected, PendingAnnotation } from './types'\nimport { rankByName } from '@deepseek-ai/dsh-client-ui-primitives'\nimport { featureByCommand, featureById, OFFICE_FEATURES } from '../features'\nimport { annotationRule } from './annotation'\nimport { AnnotationReference } from './annotation-reference'\nimport { ANNOTATION_ID, ANNOTATION_NODE, ANNOTATION_ORDER, ANNOTATION_PRIORITY, ANNOTATION_SLOT, FILE_ADDRESS_PREFIX, OFFICE_CHIP, OFFICE_CHIP_SLOT, OFFICE_NS, OFFICE_SOURCE } from './constants'\nimport { DocumentAnnotation } from './document-annotation'\nimport { OFFICE_ICONS } from './icons'\nimport { OfficeReference } from './office-reference'\nimport { mountOfficeStyles } from './styles'\n\n/** Client services used by this half. */\nexport const inject = [\n 'inputTriggers',\n 'sessions',\n 'slots',\n 'locale',\n 'remote',\n 'remote.skills',\n 'sidebarRight',\n 'uiConversation',\n 'conversation',\n]\n\nconst zh = {\n 'menu.group': '办公',\n 'menu.documents.label': '文档',\n 'menu.documents.description': '创建、读取、编辑和渲染 DOCX 文档',\n 'menu.pdf.label': 'PDF 文档',\n 'menu.pdf.description': '读取、创建、检查、渲染和验证 PDF',\n 'menu.presentations.label': '演示文稿',\n 'menu.presentations.description': '创建、编辑、渲染和导出 PPTX 演示文稿',\n 'menu.spreadsheets.label': '电子表格',\n 'menu.spreadsheets.description': '创建、编辑、计算和导出 XLSX 电子表格',\n 'annotation.ask': '请求修改',\n 'annotation.cancel': '取消',\n 'annotation.send': '发送',\n 'annotation.add': '添加标注',\n 'annotation.placeholder': '说明要怎么改…',\n 'annotation.page': '第 {page} 页',\n 'annotation.count': '{count} 条注释',\n 'annotation.remove': '删除第 {index} 条注释',\n 'annotation.image': '位置截图:{name}',\n 'annotation.help': '悬停吸附段落,点击输入要求;长按拖动框选区域,松开添加标注。方向键选择,Enter 确认,Esc 退出。',\n 'annotation.unavailable': '等待文档页面渲染;当前预览不支持标注',\n 'annotation.capturing': '正在截图…',\n 'annotation.captureFailed': '截图失败,请重新选择区域',\n 'annotation.intakeUnavailable': '当前 DSH 版本不支持从侧栏添加截图附件,PDF 与表格标注已禁用',\n 'annotation.imageLimit': '截图超过当前模型的数量或大小限制,请减少标注后重试',\n 'annotation.sendFailed': '未能加入会话,请重试;标注仍保留',\n 'annotation.draftReady': '标注和截图已保留在会话输入框,请在那里确认发送',\n 'annotation.invalid': '标注内容无效,请重新添加',\n 'annotation.tooLarge': '标注内容过长,请减少后重试',\n 'annotation.emptyPage': '页面尚未渲染,请重试',\n 'annotation.emptyRegion': '请选择页面内的区域',\n} as const\n\nconst en: Record<keyof typeof zh, string> = {\n 'menu.group': 'Office',\n 'menu.documents.label': 'Documents',\n 'menu.documents.description': 'Create, read, edit, and render DOCX documents',\n 'menu.pdf.label': 'PDF documents',\n 'menu.pdf.description': 'Read, create, inspect, render, and verify PDFs',\n 'menu.presentations.label': 'Presentations',\n 'menu.presentations.description': 'Create, edit, render, and export PPTX decks',\n 'menu.spreadsheets.label': 'Spreadsheets',\n 'menu.spreadsheets.description': 'Create, edit, calculate, and export XLSX workbooks',\n 'annotation.ask': 'Request changes',\n 'annotation.cancel': 'Cancel',\n 'annotation.send': 'Send',\n 'annotation.add': 'Add annotation',\n 'annotation.placeholder': 'Describe the change…',\n 'annotation.page': 'page {page}',\n 'annotation.count': '{count} annotations',\n 'annotation.remove': 'Remove annotation {index}',\n 'annotation.image': 'Location screenshot: {name}',\n 'annotation.help': 'Hover to select a paragraph; click to comment. Hold and drag to select a region. Arrow keys select, Enter confirms, Esc exits.',\n 'annotation.unavailable': 'Waiting for rendered pages; this preview cannot be annotated yet',\n 'annotation.capturing': 'Capturing…',\n 'annotation.captureFailed': 'Screenshot failed; please select the region again',\n 'annotation.intakeUnavailable': 'This DSH version cannot add screenshots from the sidebar; PDF and spreadsheet annotation is disabled',\n 'annotation.imageLimit': 'Screenshots exceed the current model’s count or size limits; remove some annotations and retry',\n 'annotation.sendFailed': 'Could not add annotations to the conversation; your annotations are retained',\n 'annotation.draftReady': 'Annotations and screenshots are kept in the conversation input; confirm sending there',\n 'annotation.invalid': 'Invalid annotation; please add it again',\n 'annotation.tooLarge': 'Annotations are too long; remove some and retry',\n 'annotation.emptyPage': 'The page has not rendered yet; please retry',\n 'annotation.emptyRegion': 'Select a region inside the page',\n}\n\ninterface OfficeSkillSummary {\n readonly name: string\n readonly path?: string\n}\n\ninterface CatalogEntry {\n readonly abort: AbortController\n readonly promise: Promise<readonly OfficeSkillSummary[]>\n settled?: readonly OfficeSkillSummary[]\n}\n\nfunction encodeSegment(segment: string): string {\n return encodeURIComponent(segment).replace(/%3A/gi, ':')\n}\n\nfunction encodePath(path: string): string {\n return path.split('/').map(encodeSegment).join('/')\n}\n\nfunction sessionFileAddress(sessionId: string, path: string): string {\n const normalized = path.replace(/\\\\/g, '/').replace(/^(?:\\.\\/)+/u, '')\n return `${FILE_ADDRESS_PREFIX}session/${encodeSegment(sessionId)}/${encodePath(normalized)}`\n}\n\nfunction fileAddressFor(sessionId: string, cwd: string | undefined, path: string): string {\n const normalized = path.replace(/\\\\/g, '/')\n const root = cwd?.replace(/\\\\/g, '/').replace(/\\/+$/u, '') ?? ''\n if (!/^(?:\\/|[A-Za-z]:\\/|\\\\\\\\)/u.test(normalized))\n return sessionFileAddress(sessionId, normalized)\n if (root !== '' && normalized.startsWith(`${root}/`))\n return sessionFileAddress(sessionId, normalized.slice(root.length + 1))\n return sessionFileAddress(sessionId, normalized)\n}\n\ninterface OfficeSkillCatalog {\n list: (input: { sessionId: string }, signal?: AbortSignal) => Promise<\n | { ok: true, value: { skills: readonly OfficeSkillSummary[] } }\n | { ok: false, error: { code: string, message: string } }\n >\n}\n\ninterface OfficeSessionReference {\n readonly binding: {\n readonly session: {\n getSnapshot: () => { openState: string, openError?: Error }\n }\n }\n}\n\n/**\n * The small public Session face this client needs. The installed DSH assembly\n * also ships a host `dsh-session` augmentation that widens `ctx.sessions` with\n * an incompatible `SessionStore`, so narrow through the documented client face.\n */\ninterface OfficeSessions {\n binding: (sessionId: string) => unknown\n using: <T>(\n sessionId: string,\n options: { source: string, signal: AbortSignal },\n fn: (reference: OfficeSessionReference) => Promise<T>,\n ) => Promise<T>\n list: {\n getSnapshot: () => { byId: Record<string, { cwd?: string } | undefined> }\n }\n}\n\n/** Register the `/` source, transcript chip, and right-sidebar preview. */\nexport function apply(ctx: ClientContext): void {\n const sessions = ctx.sessions as unknown as OfficeSessions\n const remoteSkills = (ctx.remote as unknown as { skills: OfficeSkillCatalog }).skills\n const t = ctx.locale.bind(OFFICE_NS)\n const entries = new Map<string, CatalogEntry>()\n const pendingAnnotations = new Map<string, Map<string, readonly PendingAnnotation[]>>()\n\n ctx.effect(() => mountOfficeStyles(), 'office-suite: styles')\n ctx.effect(() => ctx.locale.register(OFFICE_NS, { zh, en }), 'office-suite: dictionaries')\n\n function catalogFor(sessionId: string): CatalogEntry {\n const existing = entries.get(sessionId)\n if (existing !== undefined)\n return existing\n\n const abort = new AbortController()\n const promise = (async () => {\n if (sessions.binding(sessionId) === undefined)\n throw new Error(`office catalog requires a retained session \"${sessionId}\"`)\n return sessions.using(sessionId, { source: 'officeCatalog', signal: abort.signal }, async (reference) => {\n abort.signal.throwIfAborted()\n const state = reference.binding.session.getSnapshot()\n if (state.openState !== 'open')\n throw state.openError ?? new Error(`session \"${sessionId}\" is not open`)\n const result = await remoteSkills.list({ sessionId }, abort.signal)\n abort.signal.throwIfAborted()\n if (!result.ok)\n throw new Error(`skills/list failed: ${result.error.code}: ${result.error.message}`)\n return result.value.skills\n })\n })()\n\n const entry: CatalogEntry = { abort, promise }\n entries.set(sessionId, entry)\n promise.then((skills) => {\n entry.settled = skills\n }, () => {\n if (entries.get(sessionId) === entry)\n entries.delete(sessionId)\n })\n return entry\n }\n\n function openSkill(sessionId: string, feature: OfficeFeatureId, catalog: readonly OfficeSkillSummary[]): boolean {\n const definition = featureById(feature)\n if (definition === undefined)\n return false\n const skill = catalog.find(item => item.name === definition.skill)\n if (skill?.path === undefined)\n return false\n const cwd = sessions.list.getSnapshot().byId[sessionId]?.cwd\n try {\n ctx.sidebarRight.openResource(fileAddressFor(sessionId, cwd, skill.path))\n return true\n }\n catch (error) {\n console.error('[dsh-office-kit] reference preview failed:', error)\n return false\n }\n }\n\n const source: InputTriggerSource = {\n trigger: '/',\n name: OFFICE_SOURCE,\n order: 1,\n async candidates(_session, { query, signal }) {\n if (signal.aborted)\n return []\n const items = OFFICE_FEATURES.map((feature) => {\n const Icon = OFFICE_ICONS[feature.id]\n return {\n name: feature.command,\n label: t(`menu.${feature.id}.label`),\n description: t(`menu.${feature.id}.description`),\n section: t('menu.group'),\n icon: Icon,\n }\n })\n return query.length === 0 ? items : rankByName(items, query)\n },\n lexicon() {\n return OFFICE_FEATURES.map(feature => feature.command)\n },\n openReference(session, { ref }) {\n const feature = featureById(ref)\n if (feature === undefined)\n return false\n\n const settled = entries.get(session.sessionId)?.settled\n if (settled !== undefined)\n return openSkill(session.sessionId, feature.id, settled)\n\n const entry = catalogFor(session.sessionId)\n entry.promise.then((catalog) => {\n if (!entry.abort.signal.aborted)\n openSkill(session.sessionId, feature.id, catalog)\n }).catch((error) => {\n if (!entry.abort.signal.aborted)\n console.error('[dsh-office-kit] reference preview failed:', error)\n })\n return true\n },\n onPick({ candidate }) {\n const feature = featureByCommand(candidate.name)\n if (feature === undefined)\n return undefined\n return {\n insert: {\n source: OFFICE_SOURCE,\n ref: feature.id,\n label: t(`menu.${feature.id}.label`),\n appearance: 'file',\n clipboardText: `/${feature.command}`,\n },\n }\n },\n codec: {\n clipboardText(ref) {\n const feature = featureById(ref)\n return feature === undefined ? `/${ref}` : `/${feature.command}`\n },\n async serialize(ref) {\n const feature = featureById(ref)\n if (feature === undefined)\n return '/documents'\n return `/${feature.command}\\n\\nUse the \"${feature.skill}\" skill for this request and follow its instructions before creating, editing, or rendering files.`\n },\n },\n }\n\n const rule: UserTextRule<'office'> = {\n id: OFFICE_CHIP,\n order: 20,\n match(text, from) {\n const tokens = /(?<!\\S)\\/([\\w-]+)(?!\\S)/gu\n tokens.lastIndex = from\n for (let token = tokens.exec(text); token !== null; token = tokens.exec(text)) {\n const feature = featureByCommand(token[1] ?? '')\n if (feature === undefined)\n continue\n return {\n id: OFFICE_CHIP,\n start: token.index,\n end: token.index + token[0].length,\n data: { feature: feature.id },\n }\n }\n return undefined\n },\n }\n\n ctx.effect(() => ctx.uiConversation.userText.register(rule), 'office-suite: transcript chip')\n\n ctx.effect(() => ctx.slots.inject(OFFICE_CHIP_SLOT, () => ctx.slots.register({\n name: OFFICE_CHIP_SLOT,\n key: OFFICE_CHIP,\n priority: 100,\n inject: (sessionId: string) => ({\n openOffice: (feature: OfficeFeatureId) => {\n source.openReference?.({ sessionId: sessionId as never }, { ref: feature, appearance: 'file' })\n },\n officeLabel: (feature: OfficeFeatureId) => t(`menu.${feature}.label`),\n }),\n }, OfficeReference)), 'office-suite: transcript chip slot')\n\n function annotationDependencies(sessionId: string): AnnotationInjected {\n const controller = ctx.conversation as unknown as Partial<AnnotationController>\n const compatible = typeof controller.createDrafts === 'function'\n && typeof controller.releaseDraftAttachments === 'function'\n && typeof controller.resolveDraftAttachments === 'function'\n let pending = pendingAnnotations.get(sessionId)\n if (!pending) {\n pending = new Map()\n pendingAnnotations.set(sessionId, pending)\n }\n return {\n pendingAnnotations: pending,\n // ponytail: current DSH concrete File intake only, replace with outward intake API when exported.\n intake: compatible\n ? {\n create: files => controller.createDrafts!(sessionId as never, files),\n release: drafts => controller.releaseDraftAttachments!(drafts),\n images: ids => controller.resolveDraftAttachments!(ids).filter(item => item.kind === 'image').map(item => item.file),\n }\n : undefined,\n openAnnotation: (target) => {\n try {\n const cwd = sessions.list.getSnapshot().byId[sessionId]?.cwd\n ctx.sidebarRight.openResource(fileAddressFor(sessionId, cwd, target))\n }\n catch (error) {\n console.error('[dsh-office-kit] annotation preview failed:', error)\n }\n },\n }\n }\n\n ctx.effect(() => ctx.uiConversation.userText.register(annotationRule), 'office-suite: annotations')\n ctx.effect(() => ctx.slots.inject(OFFICE_CHIP_SLOT, () => ctx.slots.register({\n name: OFFICE_CHIP_SLOT,\n key: ANNOTATION_NODE,\n priority: ANNOTATION_PRIORITY,\n locale: OFFICE_NS,\n inject: annotationDependencies,\n }, AnnotationReference)), 'office-suite: annotation references')\n ctx.effect(() => ctx.slots.inject(ANNOTATION_SLOT, () => ctx.slots.register({\n name: ANNOTATION_SLOT,\n id: ANNOTATION_ID,\n order: ANNOTATION_ORDER,\n locale: OFFICE_NS,\n inject: annotationDependencies,\n }, DocumentAnnotation)), 'office-suite: annotation tool')\n\n const inputTriggers = ctx.inputTriggers\n ctx.effect(() => {\n const unregister = inputTriggers.registerSource(source)\n return () => {\n unregister()\n for (const entry of entries.values())\n entry.abort.abort()\n entries.clear()\n pendingAnnotations.clear()\n }\n }, 'office-suite: slash source')\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"client.js","names":[],"sources":["../src/features.ts","../src/client/constants.ts","../src/client/quote.ts","../src/client/annotation.ts","../src/client/annotation-reference.tsx","../src/client/document-annotation.tsx","../src/client/icons.tsx","../src/client/office-chip.ts","../src/client/office-reference.tsx","../src/client/styles.ts","../src/client/index.ts"],"sourcesContent":["/** Stable identifiers for the four Office entry points. */\nexport type OfficeFeatureId = 'documents' | 'pdf' | 'presentations' | 'spreadsheets'\n\n/** One user-facing Office entry, its skill, and the file types it owns. */\nexport interface OfficeFeature {\n readonly id: OfficeFeatureId\n /** Friendly name used by the '/' menu, chip, and preview. */\n readonly label: string\n /** One-line menu description. */\n readonly description: string\n /** Detail shown after a chip is inserted. */\n readonly hint: string\n /** Skill registered with the DSH skill registry. */\n readonly skill: string\n /** Slash token without the leading '/'. */\n readonly command: string\n /** File extensions shown in menus and documentation. */\n readonly extensions: readonly string[]\n}\n\n/** The four entries, in menu order. */\nexport const OFFICE_FEATURES: readonly OfficeFeature[] = [\n {\n id: 'documents',\n label: 'Documents',\n description: 'Create, edit, render, and verify Word documents (.docx).',\n hint: 'DOCX',\n skill: 'office-documents',\n command: 'documents',\n extensions: ['.docx'],\n },\n {\n id: 'pdf',\n label: 'PDF',\n description: 'Create, read, edit, render, and verify PDF files.',\n hint: 'PDF',\n skill: 'office-pdf',\n command: 'pdf',\n extensions: ['.pdf'],\n },\n {\n id: 'presentations',\n label: 'Presentations',\n description: 'Create, edit, render, and verify slide decks (.pptx).',\n hint: 'PPTX',\n skill: 'office-presentations',\n command: 'presentations',\n extensions: ['.pptx'],\n },\n {\n id: 'spreadsheets',\n label: 'Spreadsheets',\n description: 'Create, edit, recalculate, render, and verify workbooks (.xlsx).',\n hint: 'XLSX',\n skill: 'office-spreadsheets',\n command: 'spreadsheets',\n extensions: ['.xlsx'],\n },\n]\n\n/** Resolve a feature by its stable id; unknown ids are not Office entries. */\nexport function featureById(id: string): OfficeFeature | undefined {\n return OFFICE_FEATURES.find(feature => feature.id === id)\n}\n\n/** Resolve a feature by its slash token (without '/'). */\nexport function featureByCommand(command: string): OfficeFeature | undefined {\n return OFFICE_FEATURES.find(feature => feature.command === command)\n}\n","/** Locale namespace and slash source owned by this plugin. */\nexport const OFFICE_NS = 'dsh-office-kit'\nexport const OFFICE_SOURCE = 'office'\nexport const OFFICE_CHIP = 'office'\nexport const OFFICE_CHIP_SLOT = 'conversation.user.text.node'\n\n/** Additive, session-scoped toolbar contribution inside the official file preview. */\nexport const ANNOTATION_SLOT = 'sidebar.right.tab.document.actions'\nexport const ANNOTATION_ID = 'office-annotations'\nexport const ANNOTATION_ORDER = 20\nexport const ANNOTATION_PRIORITY = 100\nexport const ANNOTATION_NODE = 'officeAnnotation'\nexport const ANNOTATION_OPEN = '<office-annotations>'\nexport const ANNOTATION_CLOSE = '</office-annotations>'\nexport const OFFICE_STYLE_ID = 'dsh-office-kit/reference.css'\nexport const FILE_ADDRESS_PREFIX = 'dsh-resource://file/'\nexport const SESSION_FILE_PREFIX = `${FILE_ADDRESS_PREFIX}session/`\n\n/** Only semantic selectors: no dependency on another plugin's CSS/data attributes. */\nexport const ANNOTATION_CANVAS_SELECTOR = 'canvas[role=\"img\"][aria-label]'\n/** Spreadsheet previews paint one grid canvas instead of paged PDF surfaces. */\nexport const ANNOTATION_SPREADSHEET_CANVAS_SELECTOR = 'canvas.fortune-sheet-canvas'\n/** Gravity UI Icons 2.21.0 CommentFill (MIT); original retained in assets/icons/comment-fill.svg. */\nexport const ANNOTATION_CURSOR = `url(\"data:image/svg+xml,${encodeURIComponent('<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" fill=\"none\" viewBox=\"0 0 16 16\"><path fill=\"#466eff\" fill-rule=\"evenodd\" d=\"M8 13c3.866 0 7-2 7-6s-3.134-6-7-6-7 2-7 6c0 2.16.914 3.737 2.364 4.73l.09 2.161a1.157 1.157 0 0 0 1.857.872l2.322-1.77Q7.816 13 8 13\" clip-rule=\"evenodd\"/></svg>')}\") 4 18, crosshair`\nexport const ANNOTATION_HOLD_MS = 350\nexport const ANNOTATION_MIN_REGION = 6\nexport const ANNOTATION_PADDING = 3\nexport const ANNOTATION_HIT_X = 8\nexport const ANNOTATION_HIT_Y = 4\nexport const ANNOTATION_MAX_ITEMS = 50\nexport const ANNOTATION_MAX_TEXT = 20000\nexport const ANNOTATION_MAX_PAYLOAD = 1200000\nexport const ANNOTATION_MAX_PIXELS = 4000000\n","import type { QuotePrompt } from './types'\nimport { SESSION_FILE_PREFIX } from './constants'\n\nfunction decodeSegment(segment: string): string {\n try {\n return decodeURIComponent(segment)\n }\n catch {\n return segment\n }\n}\n\n/** Replace every `{name}` placeholder with its value. */\nexport function fillTemplate(template: string, values: Record<string, string>): string {\n return template.replace(/\\{(\\w+)\\}/gu, (match, name: string) => values[name] ?? match)\n}\n\n/**\n * Collapse what a PDF text layer emits: one line per visual line, padded with\n * spaces and interleaved empty lines.\n */\nexport function normalizeSelection(raw: string): string {\n const lines: string[] = []\n for (const line of raw.replace(/\\r\\n?/gu, '\\n').split('\\n')) {\n const collapsed = line.replace(/\\s+/gu, ' ').trim()\n if (collapsed.length > 0)\n lines.push(collapsed)\n }\n return lines.join('\\n')\n}\n\n/** Quote each line so the agent reads the selection as the document's own words. */\nexport function quoteLines(text: string): string {\n return text.split('\\n').map(line => `> ${line}`).join('\\n')\n}\n\n/** Path part of a `scheme://authority/path` address, apart from its origin. */\nconst PATH_AFTER_ORIGIN = /^(?:[^:/?#]+:)?\\/\\/[^/]+\\/(.*)$/u\n\nfunction pathOf(address: string): string | undefined {\n return PATH_AFTER_ORIGIN.exec(address)?.[1]\n}\n\n/** Last path segment of a preview address: the file's display name. */\nexport function fileNameOf(address: string | undefined): string | undefined {\n if (address === undefined)\n return undefined\n const segment = pathOf(address)?.split('/').pop()\n if (segment === undefined || segment.length === 0)\n return undefined\n const name = decodeSegment(segment)\n return name.length === 0 ? undefined : name\n}\n\n/** Workspace-relative path of a session file address; undefined for other resources. */\nexport function sessionRelativePath(address: string | undefined): string | undefined {\n if (address === undefined || !address.startsWith(SESSION_FILE_PREFIX))\n return undefined\n const rest = address.slice(SESSION_FILE_PREFIX.length)\n const slash = rest.indexOf('/')\n if (slash < 0)\n return undefined\n const path = rest.slice(slash + 1)\n if (path.length === 0)\n return undefined\n return path.split('/').map(decodeSegment).join('/')\n}\n\n/** The message inserted into the composer: target, quoted source, and requirement. */\nexport function composeQuote(prompt: QuotePrompt): string {\n const title = prompt.pageLabel === undefined ? prompt.target : `${prompt.target} · ${prompt.pageLabel}`\n return [\n `${prompt.heading}${title}`,\n '',\n prompt.originalLabel,\n quoteLines(prompt.text),\n '',\n `${prompt.requirementLabel}${prompt.requirement}`,\n ].join('\\n')\n}\n","import type { UserTextRule } from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport type { AnnotationParagraph, AnnotationRect, AnnotationSelection, AnnotationSendInput, AnnotationTextRun, OfficeAnnotation } from './types'\nimport { ANNOTATION_CANVAS_SELECTOR, ANNOTATION_CLOSE, ANNOTATION_HIT_X, ANNOTATION_HIT_Y, ANNOTATION_MAX_ITEMS, ANNOTATION_MAX_PAYLOAD, ANNOTATION_MAX_PIXELS, ANNOTATION_MAX_TEXT, ANNOTATION_NODE, ANNOTATION_OPEN, ANNOTATION_PADDING, ANNOTATION_SPREADSHEET_CANVAS_SELECTOR } from './constants'\nimport { normalizeSelection } from './quote'\n\nexport function unionRect(a: AnnotationRect, b: AnnotationRect): AnnotationRect {\n const left = Math.min(a.left, b.left)\n const top = Math.min(a.top, b.top)\n return { left, top, width: Math.max(a.left + a.width, b.left + b.width) - left, height: Math.max(a.top + a.height, b.top + b.height) - top }\n}\n\nexport function intersectRect(a: AnnotationRect, b: AnnotationRect): AnnotationRect | undefined {\n const left = Math.max(a.left, b.left)\n const top = Math.max(a.top, b.top)\n const width = Math.min(a.left + a.width, b.left + b.width) - left\n const height = Math.min(a.top + a.height, b.top + b.height) - top\n return width > 0 && height > 0 ? { left, top, width, height } : undefined\n}\n\n/** Leave breathing room around text/regions without extending outside the painted page. */\nexport function paddedRect(box: AnnotationRect, page: AnnotationRect): AnnotationRect | undefined {\n return intersectRect({ left: box.left - ANNOTATION_PADDING, top: box.top - ANNOTATION_PADDING, width: box.width + ANNOTATION_PADDING * 2, height: box.height + ANNOTATION_PADDING * 2 }, page)\n}\n\nexport function containsPoint(box: AnnotationRect, x: number, y: number): boolean {\n return x >= box.left && x <= box.left + box.width && y >= box.top && y <= box.top + box.height\n}\n\n/** Viewport coordinates for a native top-layer popover, independent of chat clipping ancestors. */\nexport function annotationPopoverPosition(anchor: AnnotationRect, popup: Pick<AnnotationRect, 'width' | 'height'>, viewport: Pick<AnnotationRect, 'width' | 'height'>): Pick<AnnotationRect, 'left' | 'top'> {\n return {\n left: Math.max(8, Math.min(anchor.left, viewport.width - popup.width - 8)),\n top: Math.max(8, Math.min(anchor.top >= popup.height + 8 ? anchor.top - popup.height : anchor.top + anchor.height, viewport.height - popup.height - 8)),\n }\n}\n\n/** Small hit slop bridges text edges without expanding the displayed paragraph outline. */\nexport function paragraphAtPoint(paragraphs: readonly AnnotationParagraph[], x: number, y: number): AnnotationParagraph | undefined {\n let hit: AnnotationParagraph | undefined\n for (const paragraph of paragraphs) {\n const box = paragraph.box\n if ((paragraph.rects ?? [box]).some(rect => x >= rect.left - ANNOTATION_HIT_X && x <= rect.left + rect.width + ANNOTATION_HIT_X\n && y >= rect.top - ANNOTATION_HIT_Y && y <= rect.top + rect.height + ANNOTATION_HIT_Y)\n && (!hit || box.width * box.height < hit.box.width * hit.box.height)) {\n hit = paragraph\n }\n }\n return hit\n}\n\n/** PDF text is positioned, not semantic: recover lines, then separate columns and paragraph gaps. */\nexport function groupParagraphs(runs: readonly AnnotationTextRun[]): AnnotationParagraph[] {\n const lines: { text: string, box: AnnotationRect, rects: AnnotationRect[] }[] = []\n for (const run of [...runs].sort((a, b) => a.box.top - b.box.top || a.box.left - b.box.left)) {\n if (!run.text.trim() || run.box.width <= 0 || run.box.height <= 0)\n continue\n const line = lines.find(item => Math.abs(item.box.top - run.box.top) < Math.min(item.box.height, run.box.height) * 0.45\n && run.box.left >= item.box.left && run.box.left - (item.box.left + item.box.width) < run.box.height * 2)\n if (line) {\n line.text += ` ${run.text}`\n line.box = unionRect(line.box, run.box)\n line.rects.push(run.box)\n }\n else {\n lines.push({ text: run.text, box: run.box, rects: [run.box] })\n }\n }\n const paragraphs: { text: string, box: AnnotationRect, rects: AnnotationRect[], last: AnnotationRect }[] = []\n for (const line of lines) {\n const paragraph = paragraphs.findLast((item) => {\n const gap = line.box.top - (item.last.top + item.last.height)\n const overlap = Math.min(item.last.left + item.last.width, line.box.left + line.box.width) - Math.max(item.last.left, line.box.left)\n return gap >= -line.box.height * 0.2 && gap <= Math.min(item.last.height, line.box.height) * 0.7\n && overlap > 0 && Math.abs(item.last.left - line.box.left) < line.box.height * 2\n && Math.max(item.last.height, line.box.height) / Math.min(item.last.height, line.box.height) < 1.4\n })\n if (paragraph) {\n paragraph.text += `\\n${line.text}`\n paragraph.box = unionRect(paragraph.box, line.box)\n paragraph.rects.push(...line.rects)\n paragraph.last = line.box\n }\n else {\n paragraphs.push({ ...line, last: line.box })\n }\n }\n return paragraphs.map(({ text, box, rects }) => ({ text: normalizeSelection(text), box, rects }))\n}\n\n/** Read only the accessible page canvas's sibling text layer, without private PDF.js state. */\nexport function canvasParagraphs(canvas: HTMLCanvasElement): AnnotationParagraph[] {\n const surface = canvas.parentElement\n if (!surface)\n return []\n const walker = document.createTreeWalker(surface, NodeFilter.SHOW_TEXT)\n const runs: AnnotationTextRun[] = []\n for (let node = walker.nextNode(); node; node = walker.nextNode()) {\n if (!node.textContent?.trim())\n continue\n const range = document.createRange()\n range.selectNodeContents(node)\n const box = range.getBoundingClientRect()\n if (box.width > 0 && box.height > 0)\n runs.push({ text: node.textContent, box: { left: box.left, top: box.top, width: box.width, height: box.height } })\n }\n // ponytail: visual paragraphs in PDF/Office previews, replace with a public paragraph API when provided.\n return groupParagraphs(runs)\n}\n\n/** Slot outlets are display:contents wrappers, not the document header itself. */\nexport function annotationPreview(anchor: HTMLElement): { header: HTMLElement, root: HTMLElement } | undefined {\n let header = anchor.parentElement\n while (header && getComputedStyle(header).display === 'contents')\n header = header.parentElement\n return header?.parentElement ? { header, root: header.parentElement } : undefined\n}\n\nexport function canvasAt(preview: HTMLElement, x: number, y: number): { canvas: HTMLCanvasElement, page: number } | undefined {\n const canvases = [...preview.querySelectorAll<HTMLCanvasElement>(ANNOTATION_CANVAS_SELECTOR)]\n const index = canvases.findIndex(canvas => containsPoint(canvas.getBoundingClientRect(), x, y) && canvas.getBoundingClientRect().width > 0)\n return index < 0 ? undefined : { canvas: canvases[index]!, page: index + 1 }\n}\n\n/** A workbook is one unpaged grid canvas: it locates pixels, never a page number. */\nexport function spreadsheetAt(preview: HTMLElement, x: number, y: number): { canvas: HTMLCanvasElement } | undefined {\n const canvas = [...preview.querySelectorAll<HTMLCanvasElement>(ANNOTATION_SPREADSHEET_CANVAS_SELECTOR)].find(item => containsPoint(item.getBoundingClientRect(), x, y) && item.getBoundingClientRect().width > 0)\n return canvas ? { canvas } : undefined\n}\n\nexport function normalizedRegion(box: AnnotationRect, page: AnnotationRect): AnnotationRect {\n if (page.width <= 0 || page.height <= 0)\n throw new Error('annotation.emptyPage')\n const clipped = intersectRect(box, page)\n if (!clipped)\n throw new Error('annotation.emptyRegion')\n return { left: (clipped.left - page.left) / page.width, top: (clipped.top - page.top) / page.height, width: clipped.width / page.width, height: clipped.height / page.height }\n}\n\n/** Copy the selected pixels now, before a zoom, rerender, or tab switch can change the page. */\nexport async function captureAnnotation(selection: AnnotationSelection, name: string, pixelLimit = ANNOTATION_MAX_PIXELS, dimensionLimit = Infinity): Promise<File> {\n const canvas = selection.canvas\n if (!canvas || canvas.width <= 0 || canvas.height <= 0)\n throw new Error('annotation.captureFailed')\n const painted = canvas.getBoundingClientRect()\n const region = selection.region ?? normalizedRegion(selection.box, painted)\n const width = canvas.width * region.width\n const height = canvas.height * region.height\n const scale = Math.min(1, Math.sqrt(pixelLimit / (width * height)), dimensionLimit / width, dimensionLimit / height)\n if (!Number.isFinite(scale) || scale <= 0)\n throw new Error('annotation.captureFailed')\n const output = document.createElement('canvas')\n output.width = Math.max(1, Math.floor(width * scale))\n output.height = Math.max(1, Math.floor(height * scale))\n const context = output.getContext('2d')\n if (!context)\n throw new Error('annotation.captureFailed')\n context.drawImage(canvas, region.left * canvas.width, region.top * canvas.height, width, height, 0, 0, output.width, output.height)\n const blob = await new Promise<Blob>((resolve, reject) => output.toBlob(value => value ? resolve(value) : reject(new Error('annotation.captureFailed')), 'image/png'))\n return new File([blob], name, { type: 'image/png' })\n}\n\nfunction isAnnotation(value: unknown): value is OfficeAnnotation {\n if (typeof value !== 'object' || value === null)\n return false\n const item = value as Record<string, unknown>\n const string = (value: unknown, max: number): boolean => typeof value === 'string' && value.length <= max\n if (!string(item.target, ANNOTATION_MAX_TEXT) || !string(item.fileName, 1000) || !string(item.text, ANNOTATION_MAX_TEXT)\n || !string(item.requirement, ANNOTATION_MAX_TEXT) || !(item.requirement as string).trim()\n || (item.page !== undefined && (!Number.isSafeInteger(item.page) || (item.page as number) < 1))\n || (item.imageName !== undefined && !string(item.imageName, 1000))\n || (item.sheet !== undefined && (!string(item.sheet, 1000) || !(item.sheet as string).trim()))\n || (item.range !== undefined && (!string(item.range, 100) || !(item.range as string).trim()))\n || (item.unmapped !== undefined && item.unmapped !== true)) {\n return false\n }\n if (item.region !== undefined) {\n const region = item.region as Record<string, unknown> | null\n if (!region || !['left', 'top', 'width', 'height'].every(key => typeof region[key] === 'number' && Number.isFinite(region[key]) && (region[key] as number) >= 0 && (region[key] as number) <= 1))\n return false\n if ((region.width as number) <= 0 || (region.height as number) <= 0\n || (region.left as number) + (region.width as number) > 1.000001 || (region.top as number) + (region.height as number) > 1.000001) {\n return false\n }\n }\n return true\n}\n\n/** Plain text in the normal user message is the durable source of truth; no new Session event. */\nexport function serializeAnnotations(items: readonly OfficeAnnotation[]): string {\n if (!items.length || items.length > ANNOTATION_MAX_ITEMS || !items.every(isAnnotation))\n throw new Error('annotation.invalid')\n const payload = JSON.stringify(items).replace(/</gu, '\\\\u003c')\n if (payload.length > ANNOTATION_MAX_PAYLOAD)\n throw new Error('annotation.tooLarge')\n return `${ANNOTATION_OPEN}\\n${payload}\\n${ANNOTATION_CLOSE}`\n}\n\nexport const annotationRule: UserTextRule<'officeAnnotation'> = {\n id: ANNOTATION_NODE,\n order: 10,\n match(text, from) {\n for (let start = text.indexOf(ANNOTATION_OPEN, from); start >= 0; start = text.indexOf(ANNOTATION_OPEN, start + ANNOTATION_OPEN.length)) {\n const end = text.indexOf(ANNOTATION_CLOSE, start + ANNOTATION_OPEN.length)\n if (end < 0)\n return undefined\n const payload = text.slice(start + ANNOTATION_OPEN.length, end).trim()\n if (payload.length > ANNOTATION_MAX_PAYLOAD)\n continue\n try {\n const items: unknown = JSON.parse(payload)\n if (Array.isArray(items) && items.length > 0 && items.length <= ANNOTATION_MAX_ITEMS && items.every(isAnnotation))\n return { id: ANNOTATION_NODE, start, end: end + ANNOTATION_CLOSE.length, data: { items } }\n }\n catch { /* Invalid/foreign markers remain visible as ordinary text. */ }\n }\n return undefined\n },\n}\n\n/** Prepare one synchronous input transaction; admitted or restored drafts belong to the composer. */\nexport function sendAnnotations({ items, inputActions, intake, limits, existingImages, deferSubmit }: AnnotationSendInput): 'sent' | 'draft' {\n const text = serializeAnnotations(items.map(item => item.annotation))\n const files = items.flatMap(item => item.file ? [item.file] : [])\n if (files.length && !intake)\n throw new Error('annotation.intakeUnavailable')\n if (files.length && limits) {\n if (files.some(file => !limits.mediaTypes.includes(file.type) || file.size > limits.maxImageBytes)\n || existingImages.length + files.length > limits.maxImagesPerMessage\n || [...existingImages, ...files].reduce((sum, file) => sum + file.size, 0) > limits.maxMessageImageBytes) {\n throw new Error('annotation.imageLimit')\n }\n }\n const span = inputActions.captureInsertion()\n const drafts = files.length ? intake!.create(files) : []\n if (drafts.length && !inputActions.addAttachments(drafts.map(item => item.id))) {\n intake!.release(drafts)\n throw new Error('annotation.sendFailed')\n }\n if (!inputActions.insertText(`\\n${text}\\n`, { ...span, start: span.end })) {\n for (const draft of drafts)\n inputActions.removeAttachment(draft.id)\n intake?.release(drafts)\n throw new Error('annotation.sendFailed')\n }\n try {\n inputActions.persistDraft()\n if (deferSubmit)\n return 'draft'\n inputActions.submit()\n return 'sent'\n }\n catch {\n // The text and files are already in the composer; never discard or duplicate them on retry.\n return 'draft'\n }\n}\n","import type { UserTextNodeProps } from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { ReactElement } from 'react'\nimport type { OFFICE_NS } from './constants'\nimport type { AnnotationInjected } from './types'\nimport { useId, useLayoutEffect, useRef, useState } from 'react'\nimport { annotationPopoverPosition } from './annotation'\nimport { fillTemplate } from './quote'\n\ntype Props = UserTextNodeProps<'officeAnnotation'> & PropsLocale<typeof OFFICE_NS> & Pick<AnnotationInjected, 'openAnnotation'>\n\n/** The native top layer escapes chat clipping without moving UI outside its slot. */\nexport function AnnotationReference({ node, interactive, openAnnotation, t }: Props): ReactElement {\n const popupId = useId()\n const anchor = useRef<HTMLSpanElement>(null)\n const popup = useRef<HTMLSpanElement>(null)\n const [open, setOpen] = useState(false)\n const label = fillTemplate(t('annotation.count'), { count: String(node.data.items.length) })\n\n useLayoutEffect(() => {\n const element = popup.current\n const trigger = anchor.current\n if (!element || !trigger)\n return\n if (!open) {\n element.hidePopover?.()\n return\n }\n element.showPopover?.()\n const position = (): void => {\n const viewport = { width: document.documentElement.clientWidth, height: window.innerHeight }\n const { left, top } = annotationPopoverPosition(trigger.getBoundingClientRect(), element.getBoundingClientRect(), viewport)\n element.style.left = `${left}px`\n element.style.top = `${top}px`\n }\n const scroll = (event: Event): void => {\n if (event.target instanceof Node && element.contains(event.target))\n return\n setOpen(false)\n }\n const resize = new ResizeObserver(position)\n resize.observe(trigger)\n resize.observe(element)\n window.addEventListener('resize', position)\n document.addEventListener('scroll', scroll, true)\n position()\n return () => {\n element.hidePopover?.()\n resize.disconnect()\n window.removeEventListener('resize', position)\n document.removeEventListener('scroll', scroll, true)\n }\n }, [open])\n\n return (\n <span\n ref={anchor}\n className=\"dsh-office-annotation-reference\"\n onPointerEnter={() => setOpen(true)}\n onPointerLeave={(event) => {\n if (!(event.relatedTarget instanceof Node) || !event.currentTarget.contains(event.relatedTarget))\n setOpen(false)\n }}\n onFocus={() => setOpen(true)}\n onBlur={(event) => {\n if (!event.currentTarget.contains(event.relatedTarget))\n setOpen(false)\n }}\n onKeyDown={(event) => {\n if (event.key === 'Escape') {\n event.preventDefault()\n event.stopPropagation()\n if (popup.current?.contains(event.target as Node))\n anchor.current?.querySelector('button')?.focus()\n setOpen(false)\n }\n }}\n >\n <button type=\"button\" id={`${popupId}-trigger`} aria-haspopup=\"dialog\" aria-controls={popupId} aria-expanded={open}>{label}</button>\n <span ref={popup} {...{ popover: 'manual' }} className=\"dsh-office-annotation-popover\" data-open={open} id={popupId} role=\"dialog\" aria-labelledby={`${popupId}-trigger`}>\n <span className=\"dsh-office-annotation-list\">\n {node.data.items.map((item, index) => (\n <span className=\"dsh-office-annotation-item\" key={index}>\n <span className=\"dsh-office-annotation-source\">\n {interactive\n ? <button type=\"button\" onClick={() => openAnnotation(item.target)} title={item.target}>{item.fileName}</button>\n : <span>{item.fileName}</span>}\n </span>\n <span className=\"dsh-office-annotation-requirement\">{item.requirement}</span>\n </span>\n ))}\n </span>\n </span>\n </span>\n )\n}\n","import type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { CSSProperties, PointerEvent, ReactElement } from 'react'\nimport type { OFFICE_NS } from './constants'\nimport type { AnnotationInjected, AnnotationRect, AnnotationSelection, PendingAnnotation } from './types'\nimport { useEffect, useId, useRef, useState } from 'react'\nimport { annotationPreview, canvasAt, canvasParagraphs, captureAnnotation, intersectRect, normalizedRegion, paddedRect, paragraphAtPoint, sendAnnotations, spreadsheetAt } from './annotation'\nimport { ANNOTATION_CANVAS_SELECTOR, ANNOTATION_HOLD_MS, ANNOTATION_MAX_ITEMS, ANNOTATION_MAX_TEXT, ANNOTATION_MIN_REGION, ANNOTATION_SPREADSHEET_CANVAS_SELECTOR } from './constants'\nimport { fillTemplate } from './quote'\n\ntype Props = PropsRuntime<'sidebar.right.tab.document.actions'> & PropsLocale<typeof OFFICE_NS> & AnnotationInjected\n\n/** This slot is rendered by the document header; every overlay stays in this React subtree. */\nexport function DocumentAnnotation(props: Props): ReactElement | null {\n if (!/\\.(?:pdf|docx?|pptx|xlsx)$/iu.test(props.absolutePath))\n return null\n return <AnnotationTool key={props.absolutePath} {...props} />\n}\n\nfunction AnnotationTool({ absolutePath, pendingAnnotations, intake, inputActions, useInput, useProjection, t }: Props): ReactElement {\n const anchor = useRef<HTMLSpanElement>(null)\n const form = useRef<HTMLFormElement>(null)\n const surface = useRef<HTMLDivElement>(null)\n const preview = useRef<HTMLElement>()\n const [bounds, setBounds] = useState<AnnotationRect>()\n const [active, setActive] = useState(false)\n const [hover, setHover] = useState<AnnotationSelection>()\n const [selection, setSelection] = useState<AnnotationSelection>()\n const [requirement, setRequirement] = useState('')\n const [image, setImage] = useState<File>()\n const [capturing, setCapturing] = useState(false)\n const [dragging, setDragging] = useState(false)\n const [items, setItems] = useState<readonly PendingAnnotation[]>(() => pendingAnnotations.get(absolutePath) ?? [])\n const [summaryDismissed, setSummaryDismissed] = useState(false)\n const summaryId = useId()\n const [error, setError] = useState('')\n const input = useInput(state => state)\n const limits = useProjection('imageLimits')\n const isPdf = /\\.pdf$/iu.test(absolutePath)\n const isSpreadsheet = /\\.xlsx$/iu.test(absolutePath)\n /** Formats whose page/region is only legible as a screenshot attachment. */\n const captures = isPdf || isSpreadsheet\n const canvasSelector = isSpreadsheet ? ANNOTATION_SPREADSHEET_CANVAS_SELECTOR : ANNOTATION_CANVAS_SELECTOR\n const fileName = absolutePath.replace(/\\\\/gu, '/').split('/').pop() ?? absolutePath\n const revision = useRef(0)\n const hold = useRef<ReturnType<typeof setTimeout>>()\n const gesture = useRef<{ x: number, y: number, lastX: number, lastY: number, canvas: HTMLCanvasElement, page?: number, region: boolean }>()\n const cache = useRef<{ canvas: HTMLCanvasElement, box: AnnotationRect, paragraphs: ReturnType<typeof canvasParagraphs> }>()\n const disabled = input.phase !== 'plain'\n\n useEffect(() => {\n if (items.length)\n pendingAnnotations.set(absolutePath, items)\n else\n pendingAnnotations.delete(absolutePath)\n }, [absolutePath, items, pendingAnnotations])\n\n function dismiss(): void {\n revision.current++\n setSelection(undefined)\n setImage(undefined)\n setCapturing(false)\n setRequirement('')\n }\n\n function cancelGesture(): void {\n clearTimeout(hold.current)\n gesture.current = undefined\n setDragging(false)\n setHover(undefined)\n }\n\n useEffect(() => {\n const node = anchor.current\n const container = node && annotationPreview(node)\n if (!container)\n return\n const { header, root } = container\n preview.current = root\n let frame = 0\n const measure = (): void => {\n cancelAnimationFrame(frame)\n frame = requestAnimationFrame(() => {\n cache.current = undefined\n const rect = root.getBoundingClientRect()\n const top = Math.max(rect.top, header.getBoundingClientRect().bottom, 0)\n const bottom = Math.min(rect.bottom, window.innerHeight)\n const left = Math.max(0, rect.left)\n const right = Math.min(rect.right, window.innerWidth)\n const canvas = [...root.querySelectorAll<HTMLCanvasElement>(canvasSelector)].find(canvas => canvas.getBoundingClientRect().width > 0)\n const visible = root.isConnected && !root.closest('[hidden], [aria-hidden=\"true\"]') && getComputedStyle(root).visibility === 'visible'\n setBounds(visible && rect.height > 40 && canvas && right > left && bottom > top\n ? { left, top, width: right - left, height: bottom - top }\n : undefined)\n // Keep the saved page-relative region and comment when viewport geometry changes.\n setSelection((previous) => {\n if (!previous?.canvas || !previous.region)\n return previous\n const page = previous.canvas.getBoundingClientRect()\n const region = previous.region\n const box = { left: page.left + region.left * page.width, top: page.top + region.top * page.height, width: region.width * page.width, height: region.height * page.height }\n return Object.keys(box).every(key => box[key as keyof AnnotationRect] === previous.box[key as keyof AnnotationRect]) ? previous : { ...previous, box }\n })\n })\n }\n const resize = new ResizeObserver(measure)\n resize.observe(root)\n const mutation = new MutationObserver((records) => {\n if (records.some(record => !node.contains(record.target)))\n measure()\n })\n mutation.observe(root, { childList: true, subtree: true, attributes: true, attributeFilter: ['hidden', 'aria-hidden', 'class', 'style'] })\n for (let parent = root.parentElement; parent; parent = parent.parentElement)\n mutation.observe(parent, { attributes: true })\n window.addEventListener('resize', measure)\n root.addEventListener('transitionend', measure)\n root.addEventListener('scroll', measure, true)\n measure()\n return () => {\n revision.current++\n clearTimeout(hold.current)\n cancelAnimationFrame(frame)\n resize.disconnect()\n mutation.disconnect()\n window.removeEventListener('resize', measure)\n root.removeEventListener('transitionend', measure)\n root.removeEventListener('scroll', measure, true)\n preview.current = undefined\n }\n }, [])\n\n useEffect(() => {\n if (!selection)\n return\n const dismissOutside = (event: globalThis.PointerEvent): void => {\n if (event.target instanceof Node && !form.current?.contains(event.target))\n dismiss()\n }\n document.addEventListener('pointerdown', dismissOutside, true)\n form.current?.querySelector('input')?.focus()\n return () => {\n document.removeEventListener('pointerdown', dismissOutside, true)\n }\n }, [selection])\n\n useEffect(() => {\n if (active)\n surface.current?.focus()\n }, [active])\n\n function scrollPreview(x: number, y: number): void {\n const root = preview.current\n if (!root)\n return\n let scroll = root.querySelector(canvasSelector)?.parentElement\n while (scroll && scroll !== root && !/auto|scroll/u.test(getComputedStyle(scroll).overflowY))\n scroll = scroll.parentElement\n scroll?.scrollBy({ left: x, top: y })\n setHover(undefined)\n }\n\n useEffect(() => {\n const node = surface.current\n if (!active || !node || !bounds)\n return\n const wheel = (event: WheelEvent): void => {\n event.preventDefault()\n const unit = event.deltaMode === 1 ? 16 : event.deltaMode === 2 ? bounds.height : 1\n scrollPreview(event.deltaX * unit, event.deltaY * unit)\n }\n node.addEventListener('wheel', wheel, { passive: false })\n return () => node.removeEventListener('wheel', wheel)\n }, [active, bounds])\n\n function surfaceAt(x: number, y: number): { canvas: HTMLCanvasElement, page?: number } | undefined {\n const root = preview.current\n if (!root)\n return undefined\n return isSpreadsheet ? spreadsheetAt(root, x, y) : canvasAt(root, x, y)\n }\n\n function paragraphAt(x: number, y: number): AnnotationSelection | undefined {\n // A workbook grid has no text layer: only a dragged region can locate anything.\n if (isSpreadsheet || !preview.current)\n return undefined\n const page = canvasAt(preview.current, x, y)\n if (!page)\n return undefined\n const box = page.canvas.getBoundingClientRect()\n if (cache.current?.canvas !== page.canvas || cache.current.box.left !== box.left || cache.current.box.top !== box.top\n || cache.current.box.width !== box.width || cache.current.box.height !== box.height) {\n cache.current = { canvas: page.canvas, box, paragraphs: canvasParagraphs(page.canvas) }\n }\n const paragraph = paragraphAtPoint(cache.current.paragraphs, x, y)\n return paragraph ? { ...paragraph, ...page } : undefined\n }\n\n function regionSelection(x: number, y: number): AnnotationSelection | undefined {\n const start = gesture.current\n if (!start)\n return undefined\n const box = intersectRect({ left: Math.min(start.x, x), top: Math.min(start.y, y), width: Math.abs(x - start.x), height: Math.abs(y - start.y) }, start.canvas.getBoundingClientRect())\n if (!box)\n return undefined\n const paragraphs = cache.current?.canvas === start.canvas ? cache.current.paragraphs : canvasParagraphs(start.canvas)\n const text = isSpreadsheet ? '' : paragraphs.filter(item => (item.rects ?? [item.box]).some(rect => intersectRect(rect, box))).map(item => item.text).join('\\n').slice(0, ANNOTATION_MAX_TEXT)\n return { canvas: start.canvas, page: start.page, box, region: normalizedRegion(box, start.canvas.getBoundingClientRect()), text }\n }\n\n function pointerDown(event: PointerEvent<HTMLDivElement>): void {\n if (event.button !== 0 || !preview.current || (captures && !intake))\n return\n const page = surfaceAt(event.clientX, event.clientY)\n if (!page)\n return\n event.preventDefault()\n dismiss()\n const start = { ...page, x: event.clientX, y: event.clientY, lastX: event.clientX, lastY: event.clientY, region: false }\n gesture.current = start\n event.currentTarget.setPointerCapture(event.pointerId)\n hold.current = setTimeout(() => {\n if (gesture.current !== start)\n return\n start.region = true\n setDragging(true)\n setHover(regionSelection(start.lastX, start.lastY))\n }, ANNOTATION_HOLD_MS)\n }\n\n function pointerMove(event: PointerEvent<HTMLDivElement>): void {\n const start = gesture.current\n if (start) {\n start.lastX = event.clientX\n start.lastY = event.clientY\n if (!start.region && Math.hypot(event.clientX - start.x, event.clientY - start.y) >= ANNOTATION_MIN_REGION) {\n clearTimeout(hold.current)\n start.region = true\n setDragging(true)\n }\n }\n setHover(start?.region ? regionSelection(event.clientX, event.clientY) : paragraphAt(event.clientX, event.clientY))\n }\n\n async function openSelection(value: AnnotationSelection): Promise<void> {\n dismiss()\n const current = revision.current\n setError('')\n const page = value.canvas?.getBoundingClientRect()\n const box = page ? paddedRect(value.box, page) : value.box\n if (!box)\n return\n const region = page ? normalizedRegion(box, page) : value.region\n const frozen = { ...value, box, region }\n setSelection(frozen)\n if (!captures)\n return\n setCapturing(true)\n try {\n const label = value.page === undefined ? 'region' : `p${value.page}`\n const file = await captureAnnotation(frozen, `${fileName}-${label}-${Date.now()}.png`, limits?.maxImagePixels, limits?.maxImageDimension)\n if (revision.current === current)\n setImage(file)\n }\n catch {\n if (revision.current === current)\n setError(t('annotation.captureFailed'))\n }\n finally {\n if (revision.current === current)\n setCapturing(false)\n }\n }\n\n function pointerUp(event: PointerEvent<HTMLDivElement>): void {\n const start = gesture.current\n clearTimeout(hold.current)\n if (!start)\n return\n const value = start.region ? regionSelection(event.clientX, event.clientY) : paragraphAt(event.clientX, event.clientY)\n const moved = Math.hypot(event.clientX - start.x, event.clientY - start.y)\n cancelGesture()\n if (value && (start.region ? value.box.width >= ANNOTATION_MIN_REGION && value.box.height >= ANNOTATION_MIN_REGION : moved < ANNOTATION_MIN_REGION))\n void openSelection(value)\n }\n\n function add(): void {\n if (!selection || !requirement.trim() || (captures && !image) || items.length >= ANNOTATION_MAX_ITEMS)\n return\n const annotation = {\n target: absolutePath,\n fileName,\n page: selection.page,\n text: selection.text.slice(0, ANNOTATION_MAX_TEXT),\n requirement: requirement.trim(),\n region: selection.region,\n imageName: image?.name,\n // The workbook preview exposes no selection API we control, so the region stays raw.\n ...(isSpreadsheet ? { unmapped: true as const } : {}),\n }\n setItems(previous => [...previous, { annotation, file: image }])\n dismiss()\n }\n\n function send(): void {\n if (disabled)\n return\n try {\n const result = sendAnnotations({\n items,\n inputActions,\n intake,\n limits,\n existingImages: intake?.images(input.attachmentIds) ?? [],\n deferSubmit: !!input.draft.trim() || input.attachmentIds.length > 0,\n })\n setItems([])\n setSummaryDismissed(false)\n setActive(false)\n dismiss()\n setError(result === 'draft' ? t('annotation.draftReady') : '')\n }\n catch (error) {\n const key = error instanceof Error ? error.message : 'annotation.sendFailed'\n setError(t(key.startsWith('annotation.') ? key : 'annotation.sendFailed'))\n }\n }\n\n const highlight = selection ?? hover\n const highlightBox = highlight && !selection && !dragging && highlight.canvas\n ? paddedRect(highlight.box, highlight.canvas.getBoundingClientRect())\n : highlight?.box\n const clippedHighlight = highlightBox && bounds ? intersectRect(highlightBox, bounds) : undefined\n const formWidth = bounds ? Math.min(360, bounds.width - 16) : 0\n const formLeft = bounds && selection ? Math.max(bounds.left + 8, Math.min(selection.box.left, bounds.left + bounds.width - formWidth - 8)) : 0\n const formTop = bounds && selection ? Math.max(bounds.top + 4, Math.min(selection.box.top + selection.box.height + 6, bounds.top + bounds.height - 56)) : 0\n\n return (\n <span\n ref={anchor}\n className=\"dsh-office-annotate\"\n onKeyDown={(event) => {\n if (!active || event.key !== 'Escape')\n return\n event.preventDefault()\n event.stopPropagation()\n const hasSelection = !!selection || !!gesture.current\n dismiss()\n cancelGesture()\n if (hasSelection) {\n surface.current?.focus()\n }\n else {\n setActive(false)\n anchor.current?.querySelector('button')?.focus()\n }\n }}\n >\n <button\n type=\"button\"\n className=\"dsh-office-annotate-toggle\"\n aria-pressed={active}\n disabled={!bounds || (captures && !intake)}\n title={captures && !intake ? t('annotation.intakeUnavailable') : !bounds ? t('annotation.unavailable') : t('annotation.help')}\n onClick={() => {\n setActive(value => !value)\n dismiss()\n cancelGesture()\n }}\n >\n {t('annotation.ask')}\n </button>\n {captures && !intake && <span role=\"status\" className=\"dsh-office-annotate-unavailable\">{t('annotation.intakeUnavailable')}</span>}\n {active && bounds && (\n <div\n ref={surface}\n className=\"dsh-office-annotate-surface\"\n tabIndex={0}\n style={{ left: bounds.left, top: bounds.top, width: bounds.width, height: bounds.height }}\n role=\"region\"\n aria-label={t('annotation.help')}\n onPointerDown={pointerDown}\n onPointerMove={pointerMove}\n onPointerUp={pointerUp}\n onPointerCancel={cancelGesture}\n onLostPointerCapture={cancelGesture}\n onKeyDown={(event) => {\n if (event.key === 'PageDown' || event.key === 'PageUp') {\n event.preventDefault()\n scrollPreview(0, bounds.height * (event.key === 'PageDown' ? 0.8 : -0.8))\n }\n else if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault()\n const paragraphs = [...preview.current!.querySelectorAll<HTMLCanvasElement>(ANNOTATION_CANVAS_SELECTOR)].flatMap((canvas, index) => canvasParagraphs(canvas).filter(item => intersectRect(item.box, bounds)).map(item => ({ ...item, canvas, page: index + 1 })))\n const current = paragraphs.findIndex(item => item.canvas === hover?.canvas && item.text === hover.text && item.box.top === hover.box.top)\n const index = current < 0 ? (event.key === 'ArrowDown' ? 0 : paragraphs.length - 1) : Math.max(0, Math.min(paragraphs.length - 1, current + (event.key === 'ArrowDown' ? 1 : -1)))\n setHover(paragraphs[index])\n }\n else if ((event.key === 'Enter' || event.key === ' ') && hover) {\n event.preventDefault()\n void openSelection(hover)\n }\n }}\n onPointerLeave={() => {\n if (!gesture.current)\n setHover(undefined)\n }}\n />\n )}\n {active && clippedHighlight && (\n <span className=\"dsh-office-annotate-highlight\" data-selected={selection || dragging ? 'true' : undefined} style={{ left: clippedHighlight.left, top: clippedHighlight.top, width: clippedHighlight.width, height: clippedHighlight.height }} />\n )}\n {active && selection && bounds && (\n <form\n ref={form}\n className=\"dsh-office-annotate-composer\"\n style={{ left: formLeft, top: formTop, width: formWidth }}\n aria-label={t('annotation.ask')}\n aria-busy={capturing}\n onSubmit={(event) => {\n event.preventDefault()\n add()\n }}\n >\n <input\n type=\"text\"\n aria-label={t('annotation.placeholder')}\n placeholder={t('annotation.placeholder')}\n value={requirement}\n maxLength={ANNOTATION_MAX_TEXT}\n onChange={event => setRequirement(event.target.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter' && event.nativeEvent.isComposing)\n event.preventDefault()\n }}\n />\n <button type=\"submit\" aria-label={t(capturing ? 'annotation.capturing' : 'annotation.add')} title={t(capturing ? 'annotation.capturing' : 'annotation.add')} disabled={!requirement.trim() || capturing || (captures && !image) || items.length >= ANNOTATION_MAX_ITEMS}>\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\"><path d=\"m5 12 4 4L19 6\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" /></svg>\n </button>\n </form>\n )}\n {(active || items.length > 0 || error) && bounds && (\n <div className=\"dsh-office-annotate-rail-position\" style={{ 'left': bounds.left, 'width': bounds.width, 'bottom': Math.max(0, window.innerHeight - bounds.top - bounds.height) + 12, '--dsh-office-annotation-width': `${bounds.width}px`, '--dsh-office-annotation-height': `${bounds.height}px` } as CSSProperties}>\n <div className=\"dsh-office-annotate-rail\">\n {error && <p role=\"alert\">{error}</p>}\n <div className=\"dsh-office-annotate-rail-actions\">\n <div\n className=\"dsh-office-annotate-summary\"\n data-dismissed={summaryDismissed ? 'true' : undefined}\n onPointerEnter={() => setSummaryDismissed(false)}\n onFocus={() => setSummaryDismissed(false)}\n onKeyDown={(event) => {\n if (event.key === 'Escape') {\n event.stopPropagation()\n event.currentTarget.querySelector('button')?.focus()\n setSummaryDismissed(true)\n }\n }}\n >\n <button type=\"button\" aria-haspopup=\"dialog\" aria-controls={summaryId} disabled={!items.length}>{fillTemplate(t('annotation.count'), { count: String(items.length) })}</button>\n {items.length > 0 && (\n <div id={summaryId} role=\"dialog\" aria-label={fillTemplate(t('annotation.count'), { count: String(items.length) })} className=\"dsh-office-annotate-popover\">\n <ul>\n {items.map((item, index) => (\n <li key={item.annotation.imageName ?? index}>\n <div>\n <span className=\"dsh-office-annotation-source\">\n <span title={item.annotation.target}>{item.annotation.fileName}</span>\n {item.annotation.page && <span>{fillTemplate(t('annotation.page'), { page: String(item.annotation.page) })}</span>}\n </span>\n {item.annotation.text && <span className=\"dsh-office-annotation-original\">{item.annotation.text}</span>}\n <span className=\"dsh-office-annotation-requirement\" title={item.annotation.requirement}>{item.annotation.requirement}</span>\n </div>\n </li>\n ))}\n </ul>\n </div>\n )}\n </div>\n <button\n type=\"button\"\n onClick={() => {\n setItems([])\n setActive(false)\n setSummaryDismissed(false)\n setError('')\n dismiss()\n cancelGesture()\n }}\n >\n {t('annotation.cancel')}\n </button>\n <button type=\"button\" className=\"dsh-office-annotate-primary\" disabled={!items.length || disabled} onClick={send}>{t('annotation.send')}</button>\n </div>\n </div>\n </div>\n )}\n </span>\n )\n}\n","import type { ReactElement, SVGProps } from 'react'\nimport type { OfficeFeatureId } from '../features'\n\n/*\n * Icons from Gravity UI Icons (MIT), https://github.com/gravity-ui/icons.\n * The original SVG files and license are vendored in assets/icons/.\n */\n\ntype OfficeIconProps = SVGProps<SVGSVGElement> & { size?: number }\n\nfunction frame(props: OfficeIconProps): SVGProps<SVGSVGElement> {\n const { size = 16, ...rest } = props\n return {\n 'width': size,\n 'height': size,\n 'viewBox': '0 0 16 16',\n 'fill': 'none',\n 'aria-hidden': true,\n ...rest,\n }\n}\n\n/** file-text: a document page with text lines. */\nexport function DocumentsIcon(props: OfficeIconProps): ReactElement {\n return (\n <svg {...frame(props)}>\n <path\n fill=\"currentColor\"\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M5 13.5h6a1.5 1.5 0 0 0 1.5-1.5V7.243a1.5 1.5 0 0 0-.44-1.061L8.819 2.939a1.5 1.5 0 0 0-1.06-.439H5A1.5 1.5 0 0 0 3.5 4v8A1.5 1.5 0 0 0 5 13.5m9-6.257a3 3 0 0 0-.879-2.122L9.88 1.88A3 3 0 0 0 7.757 1H5a3 3 0 0 0-3 3v8a3 3 0 0 0 3 3h6a3 3 0 0 0 3-3zM5 8.25a.75.75 0 0 1 .75-.75h4.5a.75.75 0 0 1 0 1.5h-4.5A.75.75 0 0 1 5 8.25m.75 2.25a.75.75 0 0 0 0 1.5h2.5a.75.75 0 0 0 0-1.5z\"\n />\n </svg>\n )\n}\n\n/** file-letter-p: a document page with a P badge. */\nexport function PdfIcon(props: OfficeIconProps): ReactElement {\n return (\n <svg {...frame(props)}>\n <path\n fill=\"currentColor\"\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M11 13.5H5A1.5 1.5 0 0 1 3.5 12V4A1.5 1.5 0 0 1 5 2.5h2.757a1.5 1.5 0 0 1 1.061.44l3.243 3.242a1.5 1.5 0 0 1 .439 1.06V12a1.5 1.5 0 0 1-1.5 1.5m2.121-8.379A3 3 0 0 1 14 7.243V12a3 3 0 0 1-3 3H5a3 3 0 0 1-3-3V4a3 3 0 0 1 3-3h2.757a3 3 0 0 1 2.122.879zM6.5 6.5a.75.75 0 0 0-.75.75v4a.75.75 0 0 0 1.5 0v-.75H8.5a2 2 0 1 0 0-4zm2 2.5H7.25V8H8.5a.5.5 0 0 1 0 1\"\n />\n </svg>\n )\n}\n\n/** display: a presentation screen. */\nexport function PresentationsIcon(props: OfficeIconProps): ReactElement {\n return (\n <svg {...frame(props)}>\n <path\n fill=\"currentColor\"\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M12 3H4a1.5 1.5 0 0 0-1.5 1.5v4A1.5 1.5 0 0 0 4 10h8a1.5 1.5 0 0 0 1.5-1.5v-4A1.5 1.5 0 0 0 12 3M4 1.5a3 3 0 0 0-3 3v4a3 3 0 0 0 3 3h3.25V13h-2.5a.75.75 0 0 0 0 1.5h6.5a.75.75 0 0 0 0-1.5h-2.5v-1.5H12a3 3 0 0 0 3-3v-4a3 3 0 0 0-3-3z\"\n />\n </svg>\n )\n}\n\n/** layout-cells: a spreadsheet grid. */\nexport function SpreadsheetsIcon(props: OfficeIconProps): ReactElement {\n return (\n <svg {...frame(props)}>\n <path\n fill=\"currentColor\"\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M9.25 3.5h-2.5v2h2.5zM4 3.5h1.25v2H2.5V5A1.5 1.5 0 0 1 4 3.5M2.5 7h2.75v2H2.5zm0 3.5v.5A1.5 1.5 0 0 0 4 12.5h1.25v-2zm4.25 0v2h2.5v-2zm4 0v2H12a1.5 1.5 0 0 0 1.5-1.5v-.5zM13.5 9h-2.75V7h2.75zM9.25 9h-2.5V7h2.5zm1.5-5.5v2h2.75V5A1.5 1.5 0 0 0 12 3.5zM4 2a3 3 0 0 0-3 3v6a3 3 0 0 0 3 3h8a3 3 0 0 0 3-3V5a3 3 0 0 0-3-3z\"\n />\n </svg>\n )\n}\n\nexport const OFFICE_ICONS: Record<OfficeFeatureId, (props: OfficeIconProps) => ReactElement> = {\n documents: DocumentsIcon,\n pdf: PdfIcon,\n presentations: PresentationsIcon,\n spreadsheets: SpreadsheetsIcon,\n}\n","import type { UserTextRule } from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport type { OfficeFeature } from '../features'\nimport { featureByCommand } from '../features'\nimport { OFFICE_CHIP } from './constants'\n\n/** Model-facing instruction appended to a picked slash token; the transcript hides it. */\nexport function officeInstruction(feature: OfficeFeature): string {\n return `Use the \"${feature.skill}\" skill for this request and follow its instructions before creating, editing, or rendering files.`\n}\n\n/** What the composer sends for one reference chip: the slash token, then the instruction. */\nexport function serializeOfficeCommand(feature: OfficeFeature): string {\n return `/${feature.command}\\n\\n${officeInstruction(feature)}`\n}\n\n/** One chip covers the token plus the instruction the composer appended after it. */\nexport const officeChipRule: UserTextRule<'office'> = {\n id: OFFICE_CHIP,\n order: 20,\n match(text, from) {\n const tokens = /(?<!\\S)\\/([\\w-]+)(?!\\S)/gu\n tokens.lastIndex = from\n for (let token = tokens.exec(text); token !== null; token = tokens.exec(text)) {\n const feature = featureByCommand(token[1] ?? '')\n if (feature === undefined)\n continue\n const start = token.index\n const tokenEnd = start + token[0].length\n const rest = text.slice(tokenEnd)\n const lead = rest.length - rest.trimStart().length\n const instruction = officeInstruction(feature)\n return {\n id: OFFICE_CHIP,\n start,\n end: rest.startsWith(instruction, lead) ? tokenEnd + lead + instruction.length : tokenEnd,\n data: { feature: feature.id },\n }\n }\n return undefined\n },\n}\n","import type { UserTextNodeProps } from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport type { ReactElement } from 'react'\nimport type { OfficeChipInjected } from './types'\nimport { featureById } from '../features'\nimport { OFFICE_ICONS } from './icons'\n\ntype Props = UserTextNodeProps<'office'> & OfficeChipInjected\n\n/** Render the office reference chip with its format glyph. */\nexport function OfficeReference({ node, raw, interactive, openOffice, officeLabel }: Props): ReactElement {\n const feature = featureById(node.data.feature)\n if (feature == null)\n return <span>{raw}</span>\n\n const Icon = OFFICE_ICONS[feature.id]\n const title = `/${feature.command}`\n const content = (\n <>\n <Icon className=\"dsh-office-ref-icon\" size={14} />\n <span>{officeLabel(feature.id)}</span>\n </>\n )\n\n if (!interactive) {\n return (\n <span className=\"dsh-office-ref\" title={title}>\n {content}\n </span>\n )\n }\n\n return (\n <button\n type=\"button\"\n className=\"dsh-office-ref\"\n title={title}\n data-interactive\n onClick={() => openOffice(feature.id)}\n >\n {content}\n </button>\n )\n}\n","import { ANNOTATION_CURSOR, OFFICE_NS, OFFICE_STYLE_ID } from './constants'\n\n/** One plugin-scoped style tag; the disposer owns removal. */\nexport function mountOfficeStyles(): () => void {\n if (typeof document === 'undefined')\n return () => {}\n\n const style = document.querySelector<HTMLStyleElement>(`style[data-plugin-css=\"${OFFICE_STYLE_ID}\"]`) ?? document.createElement('style')\n style.dataset.plugin = OFFICE_NS\n style.dataset.pluginCss = OFFICE_STYLE_ID\n style.textContent = `\n.dsh-office-ref {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n max-width: 100%;\n height: calc(20px + var(--dsh-content-font-delta, 0px));\n padding: 0 6px;\n border: 0.5px solid var(--dsw-alias-border-l3);\n border-radius: var(--dsw-radius-sm);\n background: var(--dsw-alias-bg-base);\n color: var(--dsw-alias-label-secondary);\n font: inherit;\n line-height: 1;\n vertical-align: baseline;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.dsh-office-ref[data-interactive] { cursor: pointer; }\n.dsh-office-ref[data-interactive]:hover {\n background: var(--dsw-alias-interactive-bg-hover-solid);\n color: var(--dsw-alias-label-primary);\n}\n.dsh-office-ref[data-interactive]:focus-visible {\n outline: 2px solid var(--dsw-alias-state-business-primary);\n outline-offset: 1px;\n}\n.dsh-office-ref-icon { flex: none; color: var(--dsw-alias-label-tertiary); }\n.dsh-office-ref[data-interactive]:hover .dsh-office-ref-icon { color: inherit; }\n.dsh-office-annotate { display: inline-flex; flex: none; }\n.dsh-office-annotate,\n.dsh-office-annotation-reference { font: 400 12px/18px var(--dsw-font-family, system-ui, sans-serif); }\n.dsh-office-annotate *,\n.dsh-office-annotation-reference * { box-sizing: border-box; }\n.dsh-office-annotate button,\n.dsh-office-annotation-reference button {\n border: 0.5px solid var(--dsw-alias-border-l2);\n border-radius: var(--dsw-radius-md);\n padding: 5px 9px;\n color: var(--dsw-alias-label-primary);\n background: var(--dsw-alias-bg-base);\n font: inherit;\n font-size: 12px;\n line-height: 1.4;\n cursor: pointer;\n}\n.dsh-office-annotate button:disabled { opacity: .45; cursor: not-allowed; }\n.dsh-office-annotate button:hover:not(:disabled),\n.dsh-office-annotation-reference button:hover { background: var(--dsw-alias-interactive-bg-hover-solid); }\n.dsh-office-annotate button:focus-visible,\n.dsh-office-annotation-reference button:focus-visible {\n outline: 2px solid var(--dsw-alias-state-business-primary);\n outline-offset: 2px;\n}\n.dsh-office-annotate .dsh-office-annotate-toggle {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n height: 24px;\n padding: 0 8px;\n line-height: 1;\n}\n.dsh-office-annotate .dsh-office-annotate-toggle[aria-pressed=\"true\"],\n.dsh-office-annotate .dsh-office-annotate-primary {\n color: var(--dsw-alias-state-business-primary);\n border-color: var(--dsw-alias-state-business-primary);\n background: color-mix(in srgb, var(--dsw-alias-state-business-primary) 10%, var(--dsw-alias-bg-base));\n}\n.dsh-office-annotate .dsh-office-annotate-surface {\n position: fixed;\n z-index: 40;\n touch-action: none;\n user-select: none;\n outline: none;\n cursor: ${ANNOTATION_CURSOR};\n}\n.dsh-office-annotate .dsh-office-annotate-highlight {\n position: fixed;\n z-index: 41;\n box-sizing: border-box;\n pointer-events: none;\n border: 1.25px solid var(--dsw-alias-state-business-primary);\n border-radius: 3px;\n}\n.dsh-office-annotate .dsh-office-annotate-highlight[data-selected=\"true\"] {\n border-style: dashed;\n background: color-mix(in srgb, var(--dsw-alias-state-business-primary) 8%, transparent);\n}\n.dsh-office-annotate .dsh-office-annotate-composer {\n position: fixed;\n z-index: 42;\n box-sizing: border-box;\n border: 0.5px solid var(--dsw-alias-border-l2);\n border-radius: var(--dsw-radius-md);\n background: var(--dsw-alias-bg-layer-2);\n color: var(--dsw-alias-label-primary);\n box-shadow: var(--dsw-shadow-lv2);\n}\n.dsh-office-annotate .dsh-office-annotate-composer {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 4px;\n border-radius: 999px;\n}\n.dsh-office-annotate .dsh-office-annotate-composer input:focus-visible { outline: none; }\n.dsh-office-annotate .dsh-office-annotate-composer input {\n box-sizing: border-box;\n min-width: 0;\n width: 100%;\n padding: 6px 10px;\n border: 0;\n border-radius: 999px;\n color: var(--dsw-alias-label-primary);\n background: transparent;\n font: inherit;\n font-size: 12px;\n line-height: 1.5;\n}\n.dsh-office-annotate .dsh-office-annotate-composer button {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n padding: 0;\n border: 0;\n border-radius: 50%;\n color: var(--dsw-alias-state-business-primary);\n background: color-mix(in srgb, var(--dsw-alias-state-business-primary) 10%, var(--dsw-alias-bg-base));\n}\n.dsh-office-annotate .dsh-office-annotate-composer button svg { width: 14px; height: 14px; }\n.dsh-office-annotate .dsh-office-annotate-rail-position {\n position: fixed;\n z-index: 42;\n display: flex;\n justify-content: center;\n padding: 0 8px;\n pointer-events: none;\n}\n.dsh-office-annotate .dsh-office-annotate-rail {\n position: relative;\n width: max-content;\n max-width: 100%;\n padding: 4px 6px;\n border-radius: 10px;\n background: var(--dsw-alias-toast-bg);\n color: var(--dsw-alias-toast-label);\n font: 500 12px/18px var(--dsw-font-family, system-ui, sans-serif);\n box-shadow: var(--dsw-shadow-lv3);\n pointer-events: auto;\n}\n.dsh-office-annotate .dsh-office-annotate-rail-actions { display: flex; align-items: center; justify-content: center; gap: 4px; }\n.dsh-office-annotate .dsh-office-annotate-rail-actions > button,\n.dsh-office-annotate .dsh-office-annotate-summary > button {\n height: 26px;\n padding: 0 8px;\n border: 0;\n border-radius: 8px;\n background: transparent;\n color: inherit;\n font: inherit;\n white-space: nowrap;\n}\n.dsh-office-annotate .dsh-office-annotate-summary { padding-right: 4px; border-right: 1px solid color-mix(in srgb, var(--dsw-alias-toast-label) 25%, transparent); }\n.dsh-office-annotate .dsh-office-annotate-rail-actions > button:hover:not(:disabled),\n.dsh-office-annotate .dsh-office-annotate-summary > button:hover:not(:disabled) { background: color-mix(in srgb, var(--dsw-alias-toast-label) 12%, transparent); }\n.dsh-office-annotate .dsh-office-annotate-rail-actions > .dsh-office-annotate-primary { background: var(--dsw-alias-state-business-primary); color: var(--dsw-alias-toast-label); }\n.dsh-office-annotate .dsh-office-annotate-rail-actions > .dsh-office-annotate-primary:hover:not(:disabled) { background: color-mix(in srgb, var(--dsw-alias-state-business-primary) 85%, var(--dsw-alias-toast-label)); }\n.dsh-office-annotate .dsh-office-annotate-rail p { max-width: min(360px, calc(var(--dsh-office-annotation-width) - 48px)); margin: 0 0 6px; font-size: 12px; overflow-wrap: anywhere; }\n.dsh-office-annotate .dsh-office-annotate-popover {\n display: none;\n position: absolute;\n bottom: 100%;\n left: 50%;\n width: min(320px, calc(var(--dsh-office-annotation-width, 100vw) - 16px), calc(100vw - 16px));\n box-sizing: border-box;\n padding-bottom: 8px;\n transform: translateX(-50%);\n}\n.dsh-office-annotate .dsh-office-annotate-summary:not([data-dismissed=\"true\"]):is(:hover, :focus-within) > .dsh-office-annotate-popover { display: block; }\n.dsh-office-annotation-reference { display: inline-block; position: relative; max-width: 100%; vertical-align: baseline; font: inherit; }\n.dsh-office-annotation-reference > button {\n max-width: 100%;\n padding: 0;\n border: 0;\n border-radius: 0;\n background: transparent;\n color: var(--dsw-alias-link);\n font: inherit;\n font-family: var(--dsw-font-markdown-code-font-family);\n font-weight: 500;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n vertical-align: baseline;\n}\n.dsh-office-annotation-reference > button:hover {\n background: transparent;\n text-decoration: underline dotted;\n text-underline-offset: 3px;\n}\n.dsh-office-annotation-reference .dsh-office-annotation-popover {\n display: none;\n position: fixed;\n z-index: 44;\n inset: auto;\n width: min(320px, calc(100vw - 16px));\n max-height: calc(100vh - 16px);\n box-sizing: border-box;\n margin: 0;\n padding: 4px 0;\n border: 0;\n background: transparent;\n color: var(--dsw-alias-label-primary);\n overflow: visible;\n text-align: left;\n font: 400 12px/18px var(--dsw-font-family, system-ui, sans-serif);\n}\n.dsh-office-annotation-reference .dsh-office-annotation-popover[data-open=\"true\"] { display: block; }\n.dsh-office-annotation-reference .dsh-office-annotation-popover::backdrop { pointer-events: none; }\n.dsh-office-annotate .dsh-office-annotate-popover > ul,\n.dsh-office-annotation-reference .dsh-office-annotation-list {\n display: flex;\n flex-direction: column;\n box-sizing: border-box;\n max-height: min(340px, 45vh);\n margin: 0;\n padding: 0 8px;\n font: 400 12px/18px var(--dsw-font-family, system-ui, sans-serif);\n text-align: left;\n overflow: auto;\n list-style: none;\n border: 0.5px solid var(--dsw-alias-border-l2);\n border-radius: var(--dsw-radius-md);\n background: var(--dsw-alias-bg-layer-2);\n color: var(--dsw-alias-label-primary);\n box-shadow: var(--dsw-shadow-lv2);\n}\n.dsh-office-annotate .dsh-office-annotate-popover > ul { max-height: min(340px, 45vh, max(40px, calc(var(--dsh-office-annotation-height, 100vh) - 80px))); }\n.dsh-office-annotate .dsh-office-annotate-popover li,\n.dsh-office-annotation-reference .dsh-office-annotation-item { display: flex; flex: none; flex-direction: column; gap: 3px; min-width: 0; padding: 8px 0; }\n.dsh-office-annotate .dsh-office-annotate-popover li > div { display: flex; flex-direction: column; gap: 3px; min-width: 0; }\n.dsh-office-annotate .dsh-office-annotate-popover .dsh-office-annotation-requirement { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.dsh-office-annotate .dsh-office-annotate-popover li + li,\n.dsh-office-annotation-reference .dsh-office-annotation-item + .dsh-office-annotation-item { border-top: .5px solid var(--dsw-alias-border-l3); }\n.dsh-office-annotate .dsh-office-annotation-source,\n.dsh-office-annotation-reference .dsh-office-annotation-source { display: flex; align-items: baseline; gap: 8px; color: var(--dsw-alias-label-tertiary); font-size: 12px; }\n.dsh-office-annotation-reference .dsh-office-annotation-source button { padding: 0; border: 0; color: var(--dsw-alias-state-business-primary); text-align: left; }\n.dsh-office-annotate .dsh-office-annotation-source > :first-child,\n.dsh-office-annotation-reference .dsh-office-annotation-source > :first-child { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.dsh-office-annotate .dsh-office-annotation-source > :not(:first-child),\n.dsh-office-annotation-reference .dsh-office-annotation-source > :not(:first-child) { flex: none; }\n.dsh-office-annotate .dsh-office-annotation-original,\n.dsh-office-annotation-reference .dsh-office-annotation-original { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--dsw-alias-label-tertiary); font-size: 12px; }\n.dsh-office-annotate .dsh-office-annotation-requirement,\n.dsh-office-annotation-reference .dsh-office-annotation-requirement { display: block; white-space: pre-wrap; overflow-wrap: anywhere; }\n`\n document.head.appendChild(style)\n return () => style.remove()\n}\n","import type { Context as ClientContext } from '@deepseek-ai/cordis'\nimport type {} from '@deepseek-ai/dsh-api-remotes/client'\nimport type {} from '@deepseek-ai/dsh-api-session-controller/client'\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\nimport type { InputTriggerSource } from '@deepseek-ai/dsh-client-ui-input-trigger/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-renderer/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-sidebar-right/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-slots'\nimport type { OfficeFeatureId } from '../features'\nimport type { AnnotationController, AnnotationInjected, PendingAnnotation } from './types'\nimport { rankByName } from '@deepseek-ai/dsh-client-ui-primitives'\nimport { featureByCommand, featureById, OFFICE_FEATURES } from '../features'\nimport { annotationRule } from './annotation'\nimport { AnnotationReference } from './annotation-reference'\nimport { ANNOTATION_ID, ANNOTATION_NODE, ANNOTATION_ORDER, ANNOTATION_PRIORITY, ANNOTATION_SLOT, FILE_ADDRESS_PREFIX, OFFICE_CHIP, OFFICE_CHIP_SLOT, OFFICE_NS, OFFICE_SOURCE } from './constants'\nimport { DocumentAnnotation } from './document-annotation'\nimport { OFFICE_ICONS } from './icons'\nimport { officeChipRule, serializeOfficeCommand } from './office-chip'\nimport { OfficeReference } from './office-reference'\nimport { mountOfficeStyles } from './styles'\n\n/** Client services used by this half. */\nexport const inject = [\n 'inputTriggers',\n 'sessions',\n 'slots',\n 'locale',\n 'remote',\n 'remote.skills',\n 'sidebarRight',\n 'uiConversation',\n 'conversation',\n]\n\nconst zh = {\n 'menu.group': '办公',\n 'menu.documents.label': '文档',\n 'menu.documents.description': '创建、读取、编辑和渲染 DOCX 文档',\n 'menu.pdf.label': 'PDF 文档',\n 'menu.pdf.description': '读取、创建、检查、渲染和验证 PDF',\n 'menu.presentations.label': '演示文稿',\n 'menu.presentations.description': '创建、编辑、渲染和导出 PPTX 演示文稿',\n 'menu.spreadsheets.label': '电子表格',\n 'menu.spreadsheets.description': '创建、编辑、计算和导出 XLSX 电子表格',\n 'annotation.ask': '请求修改',\n 'annotation.cancel': '取消',\n 'annotation.send': '发送',\n 'annotation.add': '添加标注',\n 'annotation.placeholder': '说明要怎么改…',\n 'annotation.page': '第 {page} 页',\n 'annotation.count': '{count} 条注释',\n 'annotation.remove': '删除第 {index} 条注释',\n 'annotation.image': '位置截图:{name}',\n 'annotation.help': '悬停吸附段落,点击输入要求;长按拖动框选区域,松开添加标注。方向键选择,Enter 确认,Esc 退出。',\n 'annotation.unavailable': '等待文档页面渲染;当前预览不支持标注',\n 'annotation.capturing': '正在截图…',\n 'annotation.captureFailed': '截图失败,请重新选择区域',\n 'annotation.intakeUnavailable': '当前 DSH 版本不支持从侧栏添加截图附件,PDF 与表格标注已禁用',\n 'annotation.imageLimit': '截图超过当前模型的数量或大小限制,请减少标注后重试',\n 'annotation.sendFailed': '未能加入会话,请重试;标注仍保留',\n 'annotation.draftReady': '标注和截图已保留在会话输入框,请在那里确认发送',\n 'annotation.invalid': '标注内容无效,请重新添加',\n 'annotation.tooLarge': '标注内容过长,请减少后重试',\n 'annotation.emptyPage': '页面尚未渲染,请重试',\n 'annotation.emptyRegion': '请选择页面内的区域',\n} as const\n\nconst en: Record<keyof typeof zh, string> = {\n 'menu.group': 'Office',\n 'menu.documents.label': 'Documents',\n 'menu.documents.description': 'Create, read, edit, and render DOCX documents',\n 'menu.pdf.label': 'PDF documents',\n 'menu.pdf.description': 'Read, create, inspect, render, and verify PDFs',\n 'menu.presentations.label': 'Presentations',\n 'menu.presentations.description': 'Create, edit, render, and export PPTX decks',\n 'menu.spreadsheets.label': 'Spreadsheets',\n 'menu.spreadsheets.description': 'Create, edit, calculate, and export XLSX workbooks',\n 'annotation.ask': 'Request changes',\n 'annotation.cancel': 'Cancel',\n 'annotation.send': 'Send',\n 'annotation.add': 'Add annotation',\n 'annotation.placeholder': 'Describe the change…',\n 'annotation.page': 'page {page}',\n 'annotation.count': '{count} annotations',\n 'annotation.remove': 'Remove annotation {index}',\n 'annotation.image': 'Location screenshot: {name}',\n 'annotation.help': 'Hover to select a paragraph; click to comment. Hold and drag to select a region. Arrow keys select, Enter confirms, Esc exits.',\n 'annotation.unavailable': 'Waiting for rendered pages; this preview cannot be annotated yet',\n 'annotation.capturing': 'Capturing…',\n 'annotation.captureFailed': 'Screenshot failed; please select the region again',\n 'annotation.intakeUnavailable': 'This DSH version cannot add screenshots from the sidebar; PDF and spreadsheet annotation is disabled',\n 'annotation.imageLimit': 'Screenshots exceed the current model’s count or size limits; remove some annotations and retry',\n 'annotation.sendFailed': 'Could not add annotations to the conversation; your annotations are retained',\n 'annotation.draftReady': 'Annotations and screenshots are kept in the conversation input; confirm sending there',\n 'annotation.invalid': 'Invalid annotation; please add it again',\n 'annotation.tooLarge': 'Annotations are too long; remove some and retry',\n 'annotation.emptyPage': 'The page has not rendered yet; please retry',\n 'annotation.emptyRegion': 'Select a region inside the page',\n}\n\ninterface OfficeSkillSummary {\n readonly name: string\n readonly path?: string\n}\n\ninterface CatalogEntry {\n readonly abort: AbortController\n readonly promise: Promise<readonly OfficeSkillSummary[]>\n settled?: readonly OfficeSkillSummary[]\n}\n\nfunction encodeSegment(segment: string): string {\n return encodeURIComponent(segment).replace(/%3A/gi, ':')\n}\n\nfunction encodePath(path: string): string {\n return path.split('/').map(encodeSegment).join('/')\n}\n\nfunction sessionFileAddress(sessionId: string, path: string): string {\n const normalized = path.replace(/\\\\/g, '/').replace(/^(?:\\.\\/)+/u, '')\n return `${FILE_ADDRESS_PREFIX}session/${encodeSegment(sessionId)}/${encodePath(normalized)}`\n}\n\nfunction fileAddressFor(sessionId: string, cwd: string | undefined, path: string): string {\n const normalized = path.replace(/\\\\/g, '/')\n const root = cwd?.replace(/\\\\/g, '/').replace(/\\/+$/u, '') ?? ''\n if (!/^(?:\\/|[A-Za-z]:\\/|\\\\\\\\)/u.test(normalized))\n return sessionFileAddress(sessionId, normalized)\n if (root !== '' && normalized.startsWith(`${root}/`))\n return sessionFileAddress(sessionId, normalized.slice(root.length + 1))\n return sessionFileAddress(sessionId, normalized)\n}\n\ninterface OfficeSkillCatalog {\n list: (input: { sessionId: string }, signal?: AbortSignal) => Promise<\n | { ok: true, value: { skills: readonly OfficeSkillSummary[] } }\n | { ok: false, error: { code: string, message: string } }\n >\n}\n\ninterface OfficeSessionReference {\n readonly binding: {\n readonly session: {\n getSnapshot: () => { openState: string, openError?: Error }\n }\n }\n}\n\n/**\n * The small public Session face this client needs. The installed DSH assembly\n * also ships a host `dsh-session` augmentation that widens `ctx.sessions` with\n * an incompatible `SessionStore`, so narrow through the documented client face.\n */\ninterface OfficeSessions {\n binding: (sessionId: string) => unknown\n using: <T>(\n sessionId: string,\n options: { source: string, signal: AbortSignal },\n fn: (reference: OfficeSessionReference) => Promise<T>,\n ) => Promise<T>\n list: {\n getSnapshot: () => { byId: Record<string, { cwd?: string } | undefined> }\n }\n}\n\n/** Register the `/` source, transcript chip, and right-sidebar preview. */\nexport function apply(ctx: ClientContext): void {\n const sessions = ctx.sessions as unknown as OfficeSessions\n const remoteSkills = (ctx.remote as unknown as { skills: OfficeSkillCatalog }).skills\n const t = ctx.locale.bind(OFFICE_NS)\n const entries = new Map<string, CatalogEntry>()\n const pendingAnnotations = new Map<string, Map<string, readonly PendingAnnotation[]>>()\n\n ctx.effect(() => mountOfficeStyles(), 'office-suite: styles')\n ctx.effect(() => ctx.locale.register(OFFICE_NS, { zh, en }), 'office-suite: dictionaries')\n\n function catalogFor(sessionId: string): CatalogEntry {\n const existing = entries.get(sessionId)\n if (existing !== undefined)\n return existing\n\n const abort = new AbortController()\n const promise = (async () => {\n if (sessions.binding(sessionId) === undefined)\n throw new Error(`office catalog requires a retained session \"${sessionId}\"`)\n return sessions.using(sessionId, { source: 'officeCatalog', signal: abort.signal }, async (reference) => {\n abort.signal.throwIfAborted()\n const state = reference.binding.session.getSnapshot()\n if (state.openState !== 'open')\n throw state.openError ?? new Error(`session \"${sessionId}\" is not open`)\n const result = await remoteSkills.list({ sessionId }, abort.signal)\n abort.signal.throwIfAborted()\n if (!result.ok)\n throw new Error(`skills/list failed: ${result.error.code}: ${result.error.message}`)\n return result.value.skills\n })\n })()\n\n const entry: CatalogEntry = { abort, promise }\n entries.set(sessionId, entry)\n promise.then((skills) => {\n entry.settled = skills\n }, () => {\n if (entries.get(sessionId) === entry)\n entries.delete(sessionId)\n })\n return entry\n }\n\n function openSkill(sessionId: string, feature: OfficeFeatureId, catalog: readonly OfficeSkillSummary[]): boolean {\n const definition = featureById(feature)\n if (definition === undefined)\n return false\n const skill = catalog.find(item => item.name === definition.skill)\n if (skill?.path === undefined)\n return false\n const cwd = sessions.list.getSnapshot().byId[sessionId]?.cwd\n try {\n ctx.sidebarRight.openResource(fileAddressFor(sessionId, cwd, skill.path))\n return true\n }\n catch (error) {\n console.error('[dsh-office-kit] reference preview failed:', error)\n return false\n }\n }\n\n const source: InputTriggerSource = {\n trigger: '/',\n name: OFFICE_SOURCE,\n order: 1,\n async candidates(_session, { query, signal }) {\n if (signal.aborted)\n return []\n const items = OFFICE_FEATURES.map((feature) => {\n const Icon = OFFICE_ICONS[feature.id]\n return {\n name: feature.command,\n label: t(`menu.${feature.id}.label`),\n description: t(`menu.${feature.id}.description`),\n section: t('menu.group'),\n icon: Icon,\n }\n })\n return query.length === 0 ? items : rankByName(items, query)\n },\n lexicon() {\n return OFFICE_FEATURES.map(feature => feature.command)\n },\n openReference(session, { ref }) {\n const feature = featureById(ref)\n if (feature === undefined)\n return false\n\n const settled = entries.get(session.sessionId)?.settled\n if (settled !== undefined)\n return openSkill(session.sessionId, feature.id, settled)\n\n const entry = catalogFor(session.sessionId)\n entry.promise.then((catalog) => {\n if (!entry.abort.signal.aborted)\n openSkill(session.sessionId, feature.id, catalog)\n }).catch((error) => {\n if (!entry.abort.signal.aborted)\n console.error('[dsh-office-kit] reference preview failed:', error)\n })\n return true\n },\n onPick({ candidate }) {\n const feature = featureByCommand(candidate.name)\n if (feature === undefined)\n return undefined\n return {\n insert: {\n source: OFFICE_SOURCE,\n ref: feature.id,\n label: t(`menu.${feature.id}.label`),\n appearance: 'file',\n clipboardText: `/${feature.command}`,\n },\n }\n },\n codec: {\n clipboardText(ref) {\n const feature = featureById(ref)\n return feature === undefined ? `/${ref}` : `/${feature.command}`\n },\n async serialize(ref) {\n const feature = featureById(ref)\n if (feature === undefined)\n return '/documents'\n return serializeOfficeCommand(feature)\n },\n },\n }\n\n ctx.effect(() => ctx.uiConversation.userText.register(officeChipRule), 'office-suite: transcript chip')\n\n ctx.effect(() => ctx.slots.inject(OFFICE_CHIP_SLOT, () => ctx.slots.register({\n name: OFFICE_CHIP_SLOT,\n key: OFFICE_CHIP,\n priority: 100,\n inject: (sessionId: string) => ({\n openOffice: (feature: OfficeFeatureId) => {\n source.openReference?.({ sessionId: sessionId as never }, { ref: feature, appearance: 'file' })\n },\n officeLabel: (feature: OfficeFeatureId) => t(`menu.${feature}.label`),\n }),\n }, OfficeReference)), 'office-suite: transcript chip slot')\n\n function annotationDependencies(sessionId: string): AnnotationInjected {\n const controller = ctx.conversation as unknown as Partial<AnnotationController>\n const compatible = typeof controller.createDrafts === 'function'\n && typeof controller.releaseDraftAttachments === 'function'\n && typeof controller.resolveDraftAttachments === 'function'\n let pending = pendingAnnotations.get(sessionId)\n if (!pending) {\n pending = new Map()\n pendingAnnotations.set(sessionId, pending)\n }\n return {\n pendingAnnotations: pending,\n // ponytail: current DSH concrete File intake only, replace with outward intake API when exported.\n intake: compatible\n ? {\n create: files => controller.createDrafts!(sessionId as never, files),\n release: drafts => controller.releaseDraftAttachments!(drafts),\n images: ids => controller.resolveDraftAttachments!(ids).filter(item => item.kind === 'image').map(item => item.file),\n }\n : undefined,\n openAnnotation: (target) => {\n try {\n const cwd = sessions.list.getSnapshot().byId[sessionId]?.cwd\n ctx.sidebarRight.openResource(fileAddressFor(sessionId, cwd, target))\n }\n catch (error) {\n console.error('[dsh-office-kit] annotation preview failed:', error)\n }\n },\n }\n }\n\n ctx.effect(() => ctx.uiConversation.userText.register(annotationRule), 'office-suite: annotations')\n ctx.effect(() => ctx.slots.inject(OFFICE_CHIP_SLOT, () => ctx.slots.register({\n name: OFFICE_CHIP_SLOT,\n key: ANNOTATION_NODE,\n priority: ANNOTATION_PRIORITY,\n locale: OFFICE_NS,\n inject: annotationDependencies,\n }, AnnotationReference)), 'office-suite: annotation references')\n ctx.effect(() => ctx.slots.inject(ANNOTATION_SLOT, () => ctx.slots.register({\n name: ANNOTATION_SLOT,\n id: ANNOTATION_ID,\n order: ANNOTATION_ORDER,\n locale: OFFICE_NS,\n inject: annotationDependencies,\n }, DocumentAnnotation)), 'office-suite: annotation tool')\n\n const inputTriggers = ctx.inputTriggers\n ctx.effect(() => {\n const unregister = inputTriggers.registerSource(source)\n return () => {\n unregister()\n for (const entry of entries.values())\n entry.abort.abort()\n entries.clear()\n pendingAnnotations.clear()\n }\n }, 'office-suite: slash source')\n}\n"],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -280,18 +280,13 @@ function statusOf(python) {
|
|
|
280
280
|
remedy: runtimeRemedy()
|
|
281
281
|
};
|
|
282
282
|
}
|
|
283
|
-
/**
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
if (expanded !== candidate && !isFile(expanded)) continue;
|
|
289
|
-
const inspection = await inspectPython(expanded);
|
|
290
|
-
if (inspection.compatible && inspection.missing.length === 0) return statusOf(inspection);
|
|
291
|
-
if (inspection.compatible && compatible == null) compatible = inspection;
|
|
292
|
-
last = inspection;
|
|
293
|
-
}
|
|
283
|
+
/** Pick the best interpreter: all dependencies first, then compatible-only, else none. */
|
|
284
|
+
function selectRuntime(inspections) {
|
|
285
|
+
const ready = inspections.find((inspection) => inspection.compatible && inspection.missing.length === 0);
|
|
286
|
+
if (ready != null) return statusOf(ready);
|
|
287
|
+
const compatible = inspections.find((inspection) => inspection.compatible);
|
|
294
288
|
if (compatible != null) return statusOf(compatible);
|
|
289
|
+
const last = inspections[inspections.length - 1];
|
|
295
290
|
return {
|
|
296
291
|
state: "no-interpreter",
|
|
297
292
|
packages: [],
|
|
@@ -300,6 +295,17 @@ async function inspectRuntime(configFile = officePaths().configFile) {
|
|
|
300
295
|
...last?.error == null ? {} : { error: last.error }
|
|
301
296
|
};
|
|
302
297
|
}
|
|
298
|
+
/** Inspect candidates in priority order; the first fully-provisioned interpreter wins. */
|
|
299
|
+
async function inspectRuntime(configFile = officePaths().configFile) {
|
|
300
|
+
const seen = [];
|
|
301
|
+
for (const candidate of [...candidates(configFile), ...await launcherInterpreters()]) for (const expanded of await expandLauncher(candidate)) {
|
|
302
|
+
if (expanded !== candidate && !isFile(expanded)) continue;
|
|
303
|
+
const inspection = await inspectPython(expanded);
|
|
304
|
+
seen.push(inspection);
|
|
305
|
+
if (inspection.compatible && inspection.missing.length === 0) return selectRuntime(seen);
|
|
306
|
+
}
|
|
307
|
+
return selectRuntime(seen);
|
|
308
|
+
}
|
|
303
309
|
/** Run postinstall.mjs as a child process; resolve with an error summary or undefined. */
|
|
304
310
|
function runPostinstall() {
|
|
305
311
|
return new Promise((resolve) => {
|
package/package.json
CHANGED
package/postinstall.mjs
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
18
|
import { spawnSync } from 'node:child_process'
|
|
19
|
-
import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs'
|
|
19
|
+
import { existsSync, mkdirSync, readFileSync, realpathSync, rmSync, writeFileSync } from 'node:fs'
|
|
20
20
|
import { homedir, tmpdir } from 'node:os'
|
|
21
21
|
import { dirname, join } from 'node:path'
|
|
22
22
|
import process from 'node:process'
|
|
@@ -25,15 +25,15 @@ import { fileURLToPath } from 'node:url'
|
|
|
25
25
|
const PACKAGE_ROOT = dirname(fileURLToPath(import.meta.url))
|
|
26
26
|
const IS_WINDOWS = process.platform === 'win32'
|
|
27
27
|
const PYTHON_VERSION = '3.12.10'
|
|
28
|
-
const RUNTIME_DIR = join(homedir(), '.dsh', 'office', 'runtime')
|
|
29
|
-
const VENV_DIR = join(RUNTIME_DIR, 'venv')
|
|
28
|
+
export const RUNTIME_DIR = join(homedir(), '.dsh', 'office', 'runtime')
|
|
29
|
+
export const VENV_DIR = join(RUNTIME_DIR, 'venv')
|
|
30
30
|
const VENV_PYTHON = join(VENV_DIR, IS_WINDOWS ? 'Scripts/python.exe' : 'bin/python')
|
|
31
31
|
const LEGACY_DATA_DIR = IS_WINDOWS
|
|
32
32
|
? join(process.env.LOCALAPPDATA || join(homedir(), 'AppData', 'Local'), 'dsh-office-kit')
|
|
33
33
|
: process.platform === 'darwin'
|
|
34
34
|
? join(homedir(), 'Library', 'Application Support', 'dsh-office-kit')
|
|
35
35
|
: join(process.env.XDG_DATA_HOME || join(homedir(), '.local', 'share'), 'dsh-office-kit')
|
|
36
|
-
const LEGACY_VENV_DIR = join(LEGACY_DATA_DIR, 'venv')
|
|
36
|
+
export const LEGACY_VENV_DIR = join(LEGACY_DATA_DIR, 'venv')
|
|
37
37
|
const LEGACY_VENV_PYTHON = join(LEGACY_VENV_DIR, IS_WINDOWS ? 'Scripts/python.exe' : 'bin/python')
|
|
38
38
|
const CONFIG_DIR = join(process.env.APPDATA || join(homedir(), 'AppData', 'Roaming'), 'dsh-office-kit')
|
|
39
39
|
const CONFIG_FILE = join(CONFIG_DIR, 'config.json')
|
|
@@ -181,6 +181,24 @@ function verifySignature(file) {
|
|
|
181
181
|
}
|
|
182
182
|
}
|
|
183
183
|
|
|
184
|
+
/**
|
|
185
|
+
* Installer switches. PATH is appended by the installer itself (`AppendPath=1`),
|
|
186
|
+
* the install location stays the per-user default (no `TargetDir`), and the
|
|
187
|
+
* `py` launcher is kept so `py -3.12` works.
|
|
188
|
+
*/
|
|
189
|
+
export function installerArguments() {
|
|
190
|
+
return [
|
|
191
|
+
'/quiet',
|
|
192
|
+
'InstallAllUsers=0',
|
|
193
|
+
'AppendPath=1',
|
|
194
|
+
'CompileAll=0',
|
|
195
|
+
'Include_test=0',
|
|
196
|
+
'Include_doc=0',
|
|
197
|
+
'Include_pip=1',
|
|
198
|
+
'SimpleInstall=1',
|
|
199
|
+
]
|
|
200
|
+
}
|
|
201
|
+
|
|
184
202
|
function installPython() {
|
|
185
203
|
if (!IS_WINDOWS) {
|
|
186
204
|
return false
|
|
@@ -191,17 +209,7 @@ function installPython() {
|
|
|
191
209
|
download(url, installer)
|
|
192
210
|
verifySignature(installer)
|
|
193
211
|
log(`installing Python ${PYTHON_VERSION} into the installer default per-user location`)
|
|
194
|
-
const
|
|
195
|
-
'/quiet',
|
|
196
|
-
'InstallAllUsers=0',
|
|
197
|
-
'AppendPath=1',
|
|
198
|
-
'CompileAll=0',
|
|
199
|
-
'Include_test=0',
|
|
200
|
-
'Include_doc=0',
|
|
201
|
-
'Include_pip=1',
|
|
202
|
-
'SimpleInstall=1',
|
|
203
|
-
]
|
|
204
|
-
const result = spawnSync(installer, args, { stdio: 'inherit', timeout: 15 * 60 * 1000 })
|
|
212
|
+
const result = spawnSync(installer, installerArguments(), { stdio: 'inherit', timeout: 15 * 60 * 1000 })
|
|
205
213
|
rmSync(installer, { force: true })
|
|
206
214
|
if (result.status !== 0) {
|
|
207
215
|
throw new Error(`Python installer exited with status ${result.status}`)
|
|
@@ -368,6 +376,21 @@ function readPackageVersion() {
|
|
|
368
376
|
}
|
|
369
377
|
}
|
|
370
378
|
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
379
|
+
function startedFromCli() {
|
|
380
|
+
const entry = process.argv[1]
|
|
381
|
+
if (entry == null) {
|
|
382
|
+
return false
|
|
383
|
+
}
|
|
384
|
+
try {
|
|
385
|
+
return realpathSync(entry) === realpathSync(fileURLToPath(import.meta.url))
|
|
386
|
+
}
|
|
387
|
+
catch {
|
|
388
|
+
return false
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
if (startedFromCli()) {
|
|
393
|
+
const started = Date.now()
|
|
394
|
+
main()
|
|
395
|
+
log(`finished in ${((Date.now() - started) / 1000).toFixed(1)}s`)
|
|
396
|
+
}
|
package/python/office_cli.py
CHANGED
|
@@ -594,6 +594,9 @@ def _pdf_font() -> str:
|
|
|
594
594
|
r"C:\Windows\Fonts\simsun.ttc",
|
|
595
595
|
"/System/Library/Fonts/PingFang.ttc",
|
|
596
596
|
"/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc",
|
|
597
|
+
"/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc",
|
|
598
|
+
"/usr/share/fonts/truetype/wqy/wqy-microhei.ttc",
|
|
599
|
+
"/usr/share/fonts/truetype/arphic/uming.ttc",
|
|
597
600
|
"/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf",
|
|
598
601
|
]
|
|
599
602
|
for candidate in candidates:
|
|
@@ -603,7 +606,13 @@ def _pdf_font() -> str:
|
|
|
603
606
|
return "OfficeCJK"
|
|
604
607
|
except Exception:
|
|
605
608
|
continue
|
|
606
|
-
|
|
609
|
+
try:
|
|
610
|
+
from reportlab.pdfbase.cidfonts import UnicodeCIDFont
|
|
611
|
+
|
|
612
|
+
pdfmetrics.registerFont(UnicodeCIDFont("STSong-Light"))
|
|
613
|
+
return "STSong-Light"
|
|
614
|
+
except Exception:
|
|
615
|
+
return "Helvetica"
|
|
607
616
|
|
|
608
617
|
|
|
609
618
|
def _pdf_flowables(blocks: Iterable[dict[str, Any]], font: str, counters: dict[str, int]):
|