@nuniapp/widget 0.1.9 → 0.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -258,7 +258,7 @@ interface MarkUpOptions {
258
258
  /** Resolves with the marked-up image, or null when cancelled. */
259
259
  type MarkUp = (image: Blob, options: MarkUpOptions) => Promise<Blob | null>;
260
260
  //#endregion
261
- //#region src/tools.d.ts
261
+ //#region src/screenshot-tools.d.ts
262
262
  /**
263
263
  * The code loaded on demand once someone comments (a separate chunk for npm
264
264
  * users, a separate script for the CDN build): taking the screenshot and
package/dist/index.js CHANGED
@@ -176,7 +176,7 @@ function buildCommentPrompt(comment, options = {}) {
176
176
  }
177
177
  //#endregion
178
178
  //#region src/config.ts
179
- const VERSION = "0.1.9";
179
+ const VERSION = "0.1.10";
180
180
  function resolveConfig(options) {
181
181
  return {
182
182
  project: options.project,
@@ -9269,7 +9269,7 @@ function unmount(state) {
9269
9269
  * down the widget it was created for.
9270
9270
  */
9271
9271
  function init(options) {
9272
- return mount(options, { loadScreenshot: () => import("./tools-gIAPu66h.js").then((m) => m.screenshotTools) });
9272
+ return mount(options, { loadScreenshot: () => import("./screenshot-tools-Dk-xNV0c.js").then((m) => m.screenshotTools) });
9273
9273
  }
9274
9274
  //#endregion
9275
9275
  export { VERSION, init, EN as messages };
@@ -796,4 +796,4 @@ a.item { color: inherit; text-decoration: none; }
796
796
  :host([data-position$="left"]) .toolbar { left: 12px; }
797
797
  :host([data-position^="top"]) .toolbar { top: 12px; }
798
798
  }
799
- `,this.markLayer=G(`div`,{class:`marks`,"aria-hidden":`true`}),this.pinLayer=G(`div`,{class:`pins`}),this.overlayLayer=G(`div`,{class:`overlay`}),this.uiLayer=G(`div`,{class:`ui`}),this.modalLayer=G(`div`,{class:`modal`}),this.selectButton=G(`button`,{class:`select-btn`,type:`button`,hidden:!0,title:this.withKey(`commentSelection`,`commentSelectionKey`),onmousedown:e=>e.preventDefault(),onpointerdown:e=>e.preventDefault(),onclick:()=>this.commentOnSelection()},K(J.comment),this.t(`comment`)),this.live=G(`div`,{class:`sr`,role:`status`,"aria-live":`polite`}),this.root.append(r,this.markLayer,this.pinLayer,this.overlayLayer,this.uiLayer,this.modalLayer,this.selectButton,this.live),this.uiLayer.addEventListener(`keydown`,e=>this.trapFocus(e)),this.root.addEventListener(`click`,e=>{this.toolbarDropped&&(e.preventDefault(),e.stopPropagation())},!0),this.api=new hi(e)}t(e,t){return this.i18n.t(e,t)}withKey(e,t){let n=this.config.hotkey;return n?this.t(t,{key:n.toUpperCase()}):this.t(e)}applyAppearance(){let{theme:e,accentColor:t,zIndex:n}=this.config;this.host.dataset.position=this.position,this.host.dataset.theme=e,n!==null&&(this.host.style.zIndex=String(n));let r=t?Ci(t):null;if(!r)return;let[i,a,o]=r;this.host.style.setProperty(`--n-accent`,`rgb(${i}, ${a}, ${o})`),this.host.style.setProperty(`--n-accent-soft`,`rgba(${i}, ${a}, ${o}, 0.14)`),this.host.style.setProperty(`--n-accent-fg`,wi(r))}start(){document.body.appendChild(this.host),ji(this.secret).then(e=>{this.secretHash=e,this.render()}),this.api.touch(location.origin),this.cleanups.push(this.api.onStatus(e=>{this.status=e,this.render()})),this.cleanups.push(this.api.onPages(e=>{this.pages=e,this.render()})),this.ownerToken&&this.watchSession(this.ownerToken),this.readDeepLink(),this.subscribePage(),this.cleanups.push(Ai(()=>{this.readDeepLink(),this.subscribePage()}));let e=e=>this.onKeyDown(e),t=()=>this.scheduleLayout(),n=e=>this.onMessage(e);window.addEventListener(`keydown`,e,!0),window.addEventListener(`scroll`,t,{capture:!0,passive:!0}),window.addEventListener(`resize`,t,{passive:!0}),window.addEventListener(`message`,n);let r=()=>this.scheduleSelection(),i=e=>{e.composedPath().includes(this.host)||(this.pointerDown=!0,this.scheduleSelection(),this.closeCardFromOutside(e))},a=()=>{this.pointerDown=!1,this.scheduleSelection()};document.addEventListener(`selectionchange`,r),document.addEventListener(`pointerdown`,i,!0),document.addEventListener(`pointerup`,a,!0),this.cleanups.push(()=>{document.removeEventListener(`selectionchange`,r),document.removeEventListener(`pointerdown`,i,!0),document.removeEventListener(`pointerup`,a,!0),cancelAnimationFrame(this.selectionFrame)}),this.cleanups.push(()=>{window.removeEventListener(`keydown`,e,!0),window.removeEventListener(`scroll`,t,!0),window.removeEventListener(`resize`,t),window.removeEventListener(`message`,n)});let o=new MutationObserver(e=>{e.every(e=>this.host.contains(e.target)||e.target===this.host)||this.scheduleResolve()});o.observe(document.body,{childList:!0,subtree:!0,characterData:!0,attributes:!0,attributeFilter:[`class`,`style`,`hidden`,`open`,`id`]});let s=new ResizeObserver(()=>this.scheduleLayout());s.observe(document.documentElement),this.cleanups.push(()=>{o.disconnect(),s.disconnect()}),this.render()}destroy(){this.setPicking(!1),this.endToolbarDrag?.(),this.pageUnsub?.(),this.sessionUnsub?.(),this.ownerDetailUnsub?.(),this.threadUnsub?.(),this.mineUnsub?.(),clearTimeout(this.pinReportTimer),this.resolveRun++;for(let e of this.scopeWatchers.values())e();this.scopeWatchers.clear();for(let e of this.cleanups)e();cancelAnimationFrame(this.layoutFrame),clearTimeout(this.resolveTimer),clearTimeout(this.toastTimer),this.host.remove(),this.api.close()}currentPageKey(){let e=new URL(location.href);return this.config.getPageKey(e)}subscribePage(){let e=this.currentPageKey();e===this.pageKey&&this.pageUnsub||(this.pageKey=e,this.pageUnsub?.(),this.comments=[],this.extraComment=null,this.loaded=!1,this.placements.clear(),this.pinReported.clear(),clearTimeout(this.pinReportTimer),this.card=null,this.activeId=null,this.pageUnsub=this.api.onPage(e,e=>{let t=this.extraComment,n=t&&!e.some(e=>e._id===t._id)?[...e,t]:e;this.comments=n.sort((e,t)=>e.createdAt-t.createdAt),this.loaded=!0,this.resolvePlacements(this.placements.size>0,this.deepLinkId??void 0),this.openDeepLink(),this.render()},()=>{}),this.render())}watchSession(e){this.sessionUnsub?.(),this.sessionUnsub=this.api.onSession(e,e=>{e.valid?this.ownerName=e.ownerName??this.t(`owner`):(this.ownerName=null,this.ownerToken=null,Y(X.session(this.config.project),null),this.sessionUnsub?.(),this.sessionUnsub=null),this.render()})}syncOwnerDetail(){let e=this.ownerToken,t=this.card?.kind===`thread`&&this.isOwner&&e?this.card.id:null;t!==this.ownerDetailId&&(this.ownerDetailUnsub?.(),this.ownerDetailUnsub=null,this.ownerDetail=null,this.ownerDetailLoaded=!1,this.ownerDetailId=t,t&&e&&(this.ownerDetailUnsub=this.api.onOwnerComment(t,e,e=>{this.ownerDetailId===t&&(this.ownerDetail=e,this.ownerDetailLoaded=!0,this.render())})))}syncThread(){let e=this.card?.kind===`thread`?this.card.id:null;e!==this.threadId&&(this.threadUnsub?.(),this.threadUnsub=null,this.thread=null,this.threadId=e,e&&(this.threadUnsub=this.api.onThread(e,t=>{this.threadId===e&&(this.thread=t,this.render())})))}get isOwner(){return!!(this.ownerToken&&this.ownerName)}isMine(e){return!!this.secretHash&&e.authorKeyHash===this.secretHash}visibleComments(){return this.comments.filter(e=>e.status===(this.panelOpen&&this.tab===`resolved`?`resolved`:`open`)||this.card?.kind===`thread`&&this.card.id===e._id)}scheduleResolve(){clearTimeout(this.resolveTimer),this.resolveTimer=window.setTimeout(()=>this.resolvePlacements(!0),200)}stillPlaced(e){let t=this.placements.get(e._id);if(!t?.element?.isConnected)return!1;let n=e.anchor.quote;if(n)return t.range!==void 0&&Ki(t.range.toString())===n.exact;let r=w(t.element),i=e.anchor.text;return!i||r===i||T(r,i)>.8}resolvePlacements(e,t){let n=++this.resolveRun,r=new Set(this.comments.map(e=>e._id));for(let e of this.placements.keys())r.has(e)||this.placements.delete(e);let i=this.comments.filter(t=>!(e&&this.stillPlaced(t))),a=t?i.findIndex(e=>e._id===t):-1;a>0&&i.unshift(...i.splice(a,1));let o=Ot(),s={isIgnored:this.isIgnored,document},c=()=>{if(n!==this.resolveRun)return;let t=performance.now();for(;i.length;){let e=i.shift(),n=Kt(e.anchor,document,s,o);if(this.placements.set(e._id,{element:n.element,confidence:n.confidence,range:n.range}),performance.now()-t>8)break}if(this.watchScopes(),this.renderPins(),this.layout(),i.length){qi(c);return}this.schedulePinReport(),(e||n>1)&&this.panelOpen&&this.placementSummary()!==this.shownPlacements&&this.render()};c()}schedulePinReport(){clearTimeout(this.pinReportTimer),this.pinReportTimer=window.setTimeout(()=>{if(!this.loaded||document.visibilityState!==`visible`)return;let e=[],t=[];for(let n of this.comments){if(n.status!==`open`||n.page.path!==this.pageKey)continue;let r=this.placements.get(n._id);if(!r)continue;let i=!r.element;if(i!==(this.pinReported.get(n._id)??!!n.pinLost)){if(e.length+t.length>=b.pinReportMax)break;this.pinReported.set(n._id,i),(i?e:t).push(n._id)}}(e.length||t.length)&&this.api.reportPins(this.pageKey,e,t)},3e3)}placementSummary(){return this.comments.map(e=>{let t=this.placements.get(e._id);return t?.element?t.confidence===`low`?`~`:`+`:`-`}).join(``)}watchScopes(){let e=/* @__PURE__ */ new Set;for(let{element:t}of this.placements.values()){let n=t;for(let t=0;n&&t<8;t++){let t=qe(n);if(t===document)break;e.add(t),n=E(t)?t.host:Ye(t)}}for(let[t,n]of this.scopeWatchers)e.has(t)||(n(),this.scopeWatchers.delete(t));for(let t of e)this.scopeWatchers.has(t)||this.scopeWatchers.set(t,this.watchScope(t))}watchScope(e){let t=new MutationObserver(()=>this.scheduleResolve()),n=E(e)?null:e;t.observe(n?n.body??n.documentElement:e,{childList:!0,subtree:!0,characterData:!0,attributes:!0,attributeFilter:[`class`,`style`,`hidden`,`open`,`id`]});let r=()=>this.scheduleLayout(),i=n?.defaultView??e;return i.addEventListener(`scroll`,r,{capture:!0,passive:!0}),n?.defaultView?.addEventListener(`resize`,r,{passive:!0}),()=>{t.disconnect(),i.removeEventListener(`scroll`,r,!0),n?.defaultView?.removeEventListener(`resize`,r)}}pinPoint(e){let t=this.placements.get(e._id),n=t?.element;return!n||!De(n)||D(n,document).clipped?null:this.anchorPoint(e.anchor,n,t.range)}anchorPoint(e,t,n){if(n&&n.startContainer.ownerDocument===document){let e=Wi(n).at(-1);if(e)return{x:e.right,y:e.top+e.height/2}}let r=D(t,document);return{x:r.left+e.offset.x*r.width,y:r.top+e.offset.y*r.height}}renderMarks(){let e=[],t=(t,n)=>{let r=G(`div`,{class:n});Object.assign(r.style,{left:`${t.left}px`,top:`${t.top}px`,width:`${t.width}px`,height:`${t.height}px`}),e.push(r)},n=(e,n,r,i)=>{if(n){if(r&&r.startContainer.ownerDocument===document)for(let e of Wi(r))t(e,i?`mark mark-active`:`mark`);if(i){let r=Gi(e,n);r&&t(r,`area`)}}};if(this.card?.kind===`composer`){let{draft:e}=this.card;n(e.anchor,e.element,e.range,!0)}for(let e of this.visibleComments()){let t=this.placements.get(e._id),r=this.activeId===e._id;(r||e.status===`open`&&e.anchor.quote)&&(this.pins.get(e._id)?.hidden||n(e.anchor,t?.element,t?.range,r))}this.markLayer.replaceChildren(...e)}scheduleLayout(){this.layoutFrame||(this.layoutFrame=requestAnimationFrame(()=>{this.layoutFrame=0,this.layout()}))}layout(){let e=window.innerWidth,t=window.innerHeight,n=[];this.pinPositions.clear();for(let r of this.visibleComments()){let i=this.pins.get(r._id);if(!i)continue;let a=this.pinPoint(r);if(i.hidden=!(a&&a.x>=-10&&a.y>=-10&&a.x<=e+10&&a.y<=t+10),!a)continue;let o=a.y,s=a.x;for(;n.some(e=>Math.abs(e.x-s)<14&&Math.abs(e.y-o)<14);)s+=18;n.push({x:s,y:o}),this.pinPositions.set(r._id,{x:s,y:o}),i.style.transform=`translate(${Math.round(s)}px, ${Math.round(o)}px)`}this.renderMarks(),this.positionCard(),this.picking&&(this.hoverEl||this.dragBox)&&this.renderHighlight(),this.placeSelectButton()}setPicking(e){if(e||(this.repinId=null),this.picking===e)return;this.picking=e;let t=document.documentElement;if(this.dragStart=null,this.dragBox=null,e){this.card=null,window.matchMedia(Yi).matches&&(this.panelOpen=!1),this.pickDocs=[document,...Ji(document)];for(let e of this.pickDocs){e.documentElement.classList.add(Hi),this.injectCursorStyle(e),e.addEventListener(`pointermove`,this.onPickMove,!0),e.addEventListener(`click`,this.onPickClick,!0);for(let t of Ui)e.addEventListener(t,this.swallow,{capture:!0,passive:!1});e!==document&&e.addEventListener(`keydown`,this.onFrameKey,!0)}}else{t.classList.remove(Hi),this.hoverEl=null;for(let e of this.pickDocs){e.documentElement?.classList.remove(Hi),e.removeEventListener(`pointermove`,this.onPickMove,!0),e.removeEventListener(`click`,this.onPickClick,!0);for(let t of Ui)e.removeEventListener(t,this.swallow,!0);e.removeEventListener(`keydown`,this.onFrameKey,!0)}this.pickDocs=[]}this.render()}injectCursorStyle(e){if(e.getElementById(`nuni-cursor-style`))return;let t=e.createElement(`style`);t.id=`nuni-cursor-style`,t.textContent=`html.${Hi}, html.${Hi} * { cursor: crosshair !important; }`,(e.head??e.documentElement).appendChild(t),this.cleanups.push(()=>t.remove())}fromPage(e){let t=e.composedPath();if(t.includes(this.host))return null;let n=t[0]??e.target;return n&&n.nodeType===1?n:null}commentOnArea(e){let t=Tt(document,e,this.isIgnored),n=Dt(t,e,{ignoreAttributePrefixes:[],document});this.openComposer({anchor:n,element:t})}pageSelection(){let e=document.getSelection();if(!e||e.isCollapsed||!e.rangeCount)return null;let t=e.getRangeAt(0),n=t.commonAncestorContainer,r=n.nodeType===1?n:n.parentElement;return!r||r===this.host||this.host.contains(r)||r.closest(`input, textarea, select, [contenteditable]`)||r.closest(`[data-nuni]`)?null:Ki(t.toString())?t:null}commentOnSelection(){let e=this.pageSelection();if(!e)return;let t=wt(e,{ignoreAttributePrefixes:[],document});if(!t)return;let n=e.cloneRange();document.getSelection()?.removeAllRanges(),this.selection=null,this.openComposer({...t,range:n})}scheduleSelection(){this.selectionFrame||(this.selectionFrame=requestAnimationFrame(()=>{this.selectionFrame=0,this.selection=this.picking||this.pointerDown?null:this.pageSelection(),this.placeSelectButton()}))}placeSelectButton(){let e=this.selectButton,t=this.selection,n=t?Wi(t).at(-1):void 0,r=window.innerWidth,i=window.innerHeight;if(!t||!n||n.bottom<0||n.top>i){e.hidden=!0;return}e.hidden=!1;let a=e.offsetWidth||96,o=e.offsetHeight||32,s=n.bottom+8;s+o>i-8&&(s=n.top-o-8);let c=Math.max(8,Math.min(n.right-a/2,r-a-8));e.style.transform=`translate(${Math.round(c)}px, ${Math.round(s)}px)`}openComposer(e){let{element:t}=e,n=this.repinId;if(this.setPicking(!1),n){this.movePin(n,e);return}if(this.config.capture.dom)try{e.dom=xe(t)}catch{}e.suggestFrom=Ri(e.anchor,t),this.card={kind:`composer`,draft:e},this.activeId=null,this.render(),this.focusComposer(),e.screenshot=this.takeScreenshot(e)}canScreenshot(e){return!!this.runtime.loadScreenshot&&e.element.ownerDocument===document}async takeScreenshot(e){let t=this.runtime.loadScreenshot;if(!t||!this.canScreenshot(e))return null;let n=getComputedStyle(this.host).getPropertyValue(`--n-accent`).trim()||`#d6246e`;try{await new Promise(e=>setTimeout(e,60));let r=await t(),{range:i,anchor:a,element:o}=e,s=i?()=>i.getBoundingClientRect():a.region?()=>{let e=Gi(a,o);return{left:e.left,top:e.top,right:e.left+e.width,bottom:e.top+e.height}}:void 0;return r?await r.capture(o,{exclude:this.host,accent:n,focus:s}):null}catch{return null}}collectContext(e){let{collectors:t}=this.runtime,n={},r=t.console(),i=t.network();return r.length&&(n.console=r),i.length&&(n.network=i),e.dom&&(n.dom=e.dom),Object.keys(n).length?n:void 0}async attachScreenshot(e,t){try{let n=await t;n&&await this.api.uploadScreenshot(e,this.secret,n)}catch{}}async attachImages(e,t){let n=t.images??[];Xi(t);try{for(let t of n)await this.api.uploadImage(e,this.secret,t.blob)}catch(e){this.showToast(e instanceof W?e.message:this.t(`imageFailed`))}}canAttach(e){return this.config.images&&!!this.status?.claimed&&(e.images?.length??0)<b.imagesPerComment}async addImages(e,t){e.error=void 0;for(let n of t){if((e.images?.length??0)>=b.imagesPerComment){e.error=this.t(`tooManyImages`,{count:b.imagesPerComment});break}let t=await yi(n);if(!t){e.error=this.t(`imageUnreadable`);continue}(e.images??(e.images=[])).push({blob:t,url:URL.createObjectURL(t)})}this.render(),this.positionCard()}async markUpScreenshot(e){let t=this.runtime.loadScreenshot;if(!t||!e.screenshot||e.preparingMarkup)return;e.preparingMarkup=!0,e.error=void 0,this.render();let[n,r]=await Promise.all([t(),e.screenshot]);if(e.preparingMarkup=!1,!n||!r){this.setDraftError(e,this.t(`noScreenshot`));return}this.markingUp=!0;try{let t=await n.markUp(r,{container:this.modalLayer,color:`#e5484d`,labels:{title:this.t(`markUpTitle`),box:this.t(`markUpBox`),arrow:this.t(`markUpArrow`),pen:this.t(`markUpPen`),undo:this.t(`markUpUndo`),cancel:this.t(`cancel`),done:this.t(`markUpDone`),failed:this.t(`markUpFailed`)}});t&&(e.images??(e.images=[])).push({blob:t,url:URL.createObjectURL(t)})}finally{this.markingUp=!1}this.render(),this.positionCard()}copyForAgent(e){let t=this.ownerDetail?._id===e._id?this.ownerDetail:null,n=this.threadId===e._id?this.thread?.replies:void 0;Si(m(t??{...e,replies:n},{includeContext:!!t})).then(e=>this.showToast(e?this.t(`copied`):this.t(`copyFailed`)))}renderHighlight(){if(this.overlayLayer.replaceChildren(),!this.picking)return;let e=window.matchMedia(Yi).matches;if(this.overlayLayer.append(G(`div`,{class:`pick-hint`},this.repinId?this.t(`movePinHint`):e?this.t(`pickHintMobile`):[G(`span`,{},this.t(`pickHint`)),G(`span`,{class:`pick-keys`},this.t(`pickHintKeys`))])),this.dragBox){let e=G(`div`,{class:`highlight drag-box`});Object.assign(e.style,{left:`${this.dragBox.left}px`,top:`${this.dragBox.top}px`,width:`${this.dragBox.width}px`,height:`${this.dragBox.height}px`}),this.overlayLayer.append(e);return}let t=this.hoverEl;if(!t||t===t.ownerDocument.documentElement)return;let n=D(t,document),r=G(`div`,{class:`highlight`},G(`span`,{class:`highlight-label`},$i(t)));Object.assign(r.style,{left:`${n.left-2}px`,top:`${n.top-2}px`,width:`${n.width+4}px`,height:`${n.height+4}px`}),this.overlayLayer.append(r)}onKeyDown(e){if(this.markingUp)return;let t=e.composedPath().includes(this.host);if(e.key===`Escape`){if(this.confirming)this.answer(!1);else if(this.picking)this.setPicking(!1);else if(this.card)this.closeCard();else if(this.panelOpen&&this.search)this.search=``,this.render();else if(this.panelOpen)this.togglePanel(!1);else return;e.stopPropagation();return}if(Zi(e.composedPath()[0]??e.target)||e.metaKey||e.ctrlKey||e.altKey||this.picking&&!t&&this.onPickKey(e)||t&&this.confirming||e.repeat)return;let n=this.config.hotkey;n&&e.key.toLowerCase()===n&&(e.preventDefault(),!this.picking&&this.pageSelection()?this.commentOnSelection():this.setPicking(!this.picking))}onPickKey(e){if(![`ArrowUp`,`ArrowDown`,`ArrowLeft`,`ArrowRight`,`Enter`].includes(e.key))return!1;e.preventDefault(),e.stopPropagation();let t=this.hoverEl;if(!t||!t.isConnected)return this.movePickTo(this.keyboardStart()),!0;if(e.key===`Enter`){let e=t.getBoundingClientRect(),n=St(t,{x:e.left+e.width/2,y:e.top+e.height/2},{ignoreAttributePrefixes:[],document});return this.openComposer({anchor:n,element:t}),!0}let n=t=>{for(;t&&(t===this.host||!De(t));)t=e.key===`ArrowLeft`?t.previousElementSibling:t.nextElementSibling;return t},r=t.ownerDocument.body;return e.key===`ArrowUp`?t.parentElement&&t!==r&&(t=t.parentElement):t=e.key===`ArrowDown`?n(t.firstElementChild)??t:e.key===`ArrowLeft`?n(t.previousElementSibling)??t:n(t.nextElementSibling)??t,this.movePickTo(t),!0}keyboardStart(){let e=document.activeElement;if(e&&e!==document.body&&e!==this.host)return e;let t=document.elementsFromPoint(window.innerWidth/2,window.innerHeight/2).find(e=>!this.isIgnored(e));return t?Yt(t):document.body}movePickTo(e){this.hoverEl=e,e.scrollIntoView({block:`nearest`,inline:`nearest`}),this.live.textContent=this.t(`picked`,{element:$i(e)}),this.renderHighlight()}trapFocus(e){if(e.key!==`Tab`)return;let t=e.composedPath()[0]?.closest?.(`.confirm, [data-card], .panel`);if(!t)return;let n=Array.from(t.querySelectorAll(`button:not([disabled]), input, textarea, a[href], [tabindex="0"]`)).filter(e=>!e.closest(`[hidden]`));if(!n.length)return;let r=n[0],i=n[n.length-1],a=this.root.activeElement;e.shiftKey&&a===r?(e.preventDefault(),i.focus()):!e.shiftKey&&a===i&&(e.preventDefault(),r.focus())}keepFocus(){if(this.returnFocus)return;let e=this.root.activeElement;if(e){this.returnFocus=e.dataset.focusKey??e;return}let t=document.activeElement;this.returnFocus=t&&t!==document.body&&t!==this.host?t:null}restoreFocus(){let e=this.returnFocus;this.returnFocus=null;let t=typeof e==`string`?this.uiLayer.querySelector(`[data-focus-key="${e}"]`):e;t?.isConnected&&t.focus({preventScroll:!0})}ask(e,t){this.confirming?.done(!1);let n=this.root.activeElement?.dataset.focusKey??null;return new Promise(r=>{this.confirming={message:e,action:t,done:r,from:n},this.focusNext=`[data-focus-key="confirm-cancel"]`,this.render()})}answer(e){let t=this.confirming;t&&(this.confirming=null,!e&&t.from&&(this.focusNext=`[data-focus-key="${t.from}"]`),this.render(),t.done(e))}renderConfirm(){let e=this.confirming;return e?G(`div`,{class:`confirm-backdrop`,onclick:()=>this.answer(!1)},G(`div`,{class:`confirm`,role:`alertdialog`,"aria-modal":`true`,"aria-labelledby":`nuni-confirm-text`,onclick:e=>e.stopPropagation()},G(`p`,{id:`nuni-confirm-text`},e.message),G(`div`,{class:`row`},G(`span`,{class:`spacer`}),G(`button`,{class:`btn btn-ghost`,type:`button`,"data-focus-key":`confirm-cancel`,onclick:()=>this.answer(!1)},this.t(`cancel`)),G(`button`,{class:`btn btn-danger-solid`,type:`button`,"data-focus-key":`confirm-ok`,onclick:()=>this.answer(!0)},e.action)))):null}openClaim(){let e=new URL(`${this.config.appUrl}/dashboard/claim`);e.searchParams.set(`project`,this.config.project),e.searchParams.set(`origin`,location.origin),window.open(e.toString(),`nuni-claim`,`popup,width=480,height=680`)||(location.href=e.toString())}onMessage(e){let t;try{t=new URL(this.config.appUrl).origin}catch{return}if(e.origin!==t)return;let n=e.data;n&&n.type===`nuni:session`&&n.project===this.config.project&&typeof n.token==`string`&&n.token.startsWith(`nuni_s_`)&&(this.ownerToken=n.token,Y(X.session(this.config.project),n.token),this.watchSession(n.token),this.showToast(this.t(`signedIn`)))}readDeepLink(){let e=new URL(location.href),t=e.searchParams.get(`nuni`);t&&(this.deepLinkId=t,e.searchParams.delete(`nuni`),history.replaceState(history.state,``,e.toString()))}openDeepLink(){let e=this.deepLinkId;if(!e||!this.loaded)return;this.deepLinkId=null;let t=this.comments.find(t=>t._id===e);if(t){this.focusDeepLinked(t);return}this.api.getComment(e).then(e=>{if(!e||e.page.path!==this.pageKey){this.showToast(this.t(`linkGone`));return}this.extraComment=e,this.comments=[...this.comments.filter(t=>t._id!==e._id),e],this.resolvePlacements(!1,e._id),this.focusDeepLinked(e)})}focusDeepLinked(e){this.focusComment(e._id)}focusComment(e){let t=this.placements.get(e),n=this.comments.find(t=>t._id===e);t?.element&&n&&Fi(t.element,()=>this.anchorPoint(n.anchor,t.element,t.range)),this.openThread(e),window.matchMedia(Yi).matches&&(this.panelOpen=!1),this.render(),setTimeout(()=>this.scheduleLayout(),400)}async submitDraft(e,t,r){let i=r.trim().slice(0,b.nameMaxLength),a=t.trim();if(!i)return this.setDraftError(e,this.t(`enterName`));let o=e.suggesting?e.suggestFrom:null,s=(e.suggestion??o??``).trim();if(o!=null&&(!s||s===o))return this.setDraftError(e,this.t(`changeTextFirst`));if(s.length>b.quoteMaxLength)return this.setDraftError(e,this.t(`suggestionTooLong`,{count:b.quoteMaxLength}));let c=o==null?void 0:{before:o,after:s};if(!a&&!c)return this.setDraftError(e,this.t(`writeFirst`));if(a.length>b.bodyMaxLength)return this.setDraftError(e,this.t(`commentTooLong`,{count:b.bodyMaxLength}));this.name=i,Y(X.name,i),e.sending=!0,e.error=void 0,this.render();let l=n(location.href),u=e.screenshot;try{let t=await this.api.createComment({body:a,suggestion:c,authorName:i,authorSecret:this.secret,page:{...l,path:this.pageKey,title:document.title.slice(0,300)},anchor:e.anchor,viewport:{w:window.innerWidth,h:window.innerHeight,dpr:window.devicePixelRatio||1},context:this.collectContext(e)});u&&this.attachScreenshot(t,u),e.images?.length&&this.attachImages(t,e),this.placements.set(t,{element:e.element,confidence:`exact`,range:e.range}),this.card?.kind===`composer`&&this.card.draft===e&&(this.card=null),this.showToast(this.t(`added`))}catch(t){e.sending=!1,e.error=t instanceof W?t.message:this.t(`postFailed`)}this.render()}setDraftError(e,t){e.error=t,this.render()}async act(e,t,n){let r=this.card;r?.kind===`thread`&&(r.busy=!0,r.error=void 0,this.render());try{return await t(),n&&this.showToast(n),this.card?.kind===`thread`&&this.card.id===e&&(this.card.busy=!1,this.card.editing=!1),this.render(),!0}catch(t){return this.card?.kind===`thread`&&this.card.id===e&&(this.card.busy=!1,this.card.error=t instanceof Error?t.message:this.t(`failed`)),this.render(),!1}}resolveComment(e){let t=this.ownerToken;t&&this.act(e._id,()=>this.api.resolve(e._id,t),this.t(`resolved`)).then(t=>{t&&!(this.panelOpen&&this.tab===`resolved`)&&this.card?.kind===`thread`&&this.card.id===e._id&&this.closeCard()})}reopenComment(e){let t=this.ownerToken;t&&this.act(e._id,()=>this.api.reopen(e._id,t),this.t(`reopened`))}closeAsOutdated(e){let t=this.ownerToken;t&&this.act(e._id,()=>this.api.resolve(e._id,t,`outdated`),this.t(`closedOutdated`)).then(t=>{t&&this.card?.kind===`thread`&&this.card.id===e._id&&this.closeCard()})}startMovePin(e){this.ownerToken&&(this.setPicking(!0),this.repinId=e._id,this.render())}async movePin(e,t){let n=this.ownerToken;if(!n)return;let r=this.placements.get(e);this.placements.set(e,{element:t.element,confidence:`exact`,range:t.range}),this.pinReported.set(e,!1);try{await this.api.repin(e,t.anchor,n),this.showToast(this.t(`pinMoved`))}catch(t){r?this.placements.set(e,r):this.placements.delete(e),this.showToast(t instanceof W?t.message:this.t(`failed`))}this.focusComment(e)}async deleteComment(e){if(!await this.ask(this.t(`confirmDeleteComment`),this.t(`delete`)))return;let t=this.ownerToken,n=this.isMine(e)?()=>this.api.deleteOwn(e._id,this.secret):t?()=>this.api.remove(e._id,t):null;n&&this.act(e._id,n,this.t(`deleted`)).then(t=>{t&&(this.extraComment?._id===e._id&&(this.extraComment=null),this.comments=this.comments.filter(t=>t._id!==e._id),this.placements.delete(e._id),this.closeCard())})}isMyReply(e){return!!this.secretHash&&e.authorKeyHash===this.secretHash}async sendReply(e,t,n){let r=this.card;if(r?.kind!==`thread`||r.id!==e._id)return;let i=(this.isOwner?this.ownerName:n)?.trim().slice(0,b.nameMaxLength),a=t.trim();if(a){if(!i){r.error=this.t(`enterName`),this.render();return}if(a.length>b.bodyMaxLength){r.error=this.t(`replyTooLong`,{count:b.bodyMaxLength}),this.render();return}this.isOwner||(this.name=i,Y(X.name,i)),r.sendingReply=!0,r.error=void 0,this.render();try{await this.api.createReply({commentId:e._id,body:a,authorName:i,authorSecret:this.secret,sessionToken:this.ownerToken??void 0});let t=this.uiLayer.querySelector(`[data-focus-key="reply"]`);t&&(t.value=``)}catch(e){r.error=e instanceof W?e.message:this.t(`replyFailed`)}r.sendingReply=!1,this.render()}}toggleReaction(e,t,n){this.api.toggleReaction(e._id,t,n,this.secret).catch(t=>{this.card?.kind===`thread`&&this.card.id===e._id&&(this.card.error=t instanceof Error?t.message:this.t(`reactFailed`),this.render())})}async deleteReply(e,t){if(!await this.ask(this.t(`confirmDeleteReply`),this.t(`delete`)))return;let n=this.ownerToken,r=this.isMyReply(t)?()=>this.api.deleteReply(t._id,this.secret):n?()=>this.api.removeReply(t._id,n):null;r&&this.act(e._id,r,this.t(`replyDeleted`))}saveReplyEdit(e,t,n){this.act(e._id,()=>this.api.editReply(t._id,this.secret,n),this.t(`saved`)).then(e=>{e&&this.card?.kind===`thread`&&(this.card.replyEditing=void 0,this.render())})}saveEdit(e,t,n){this.act(e._id,()=>this.api.editOwn(e._id,this.secret,t,n),this.t(`saved`))}copyNewTextButton(e){return G(`button`,{class:`cmp-link`,type:`button`,onclick:()=>void Si(e).then(e=>this.showToast(this.t(e?`newTextCopied`:`copyFailed`)))},this.t(`copyNewText`))}showToast(e){this.toast=e,clearTimeout(this.toastTimer),this.toastTimer=window.setTimeout(()=>{this.toast=null,this.render()},2400),this.render()}togglePanel(e=!this.panelOpen){e!==this.panelOpen&&(this.panelOpen=e,e&&!this.mineUnsub&&(this.mineUnsub=this.api.onMine(this.secret,e=>{this.mine=e,this.render()})),e?(this.keepFocus(),this.focusNext=`.panel [role="tab"][aria-selected="true"]`,window.matchMedia(Yi).matches&&(this.card=null)):this.search=``,this.render(),e&&this.uiLayer.querySelector(`.panel .item[aria-current="true"]`)?.scrollIntoView({block:`nearest`}),!e&&!this.card&&this.restoreFocus())}closeCardFromOutside(e){this.card&&!this.picking&&!this.confirming&&e.isPrimary&&(this.markingUp||ia(e)||[...this.uiLayer.querySelector(`[data-card]`)?.querySelectorAll(`textarea`)??[]].some(e=>e.value.trim())||this.card.kind===`composer`&&this.card.draft.images?.length||(this.panelOpen||(this.returnFocus=null),this.closeCard()))}closeCard(){this.card?.kind===`composer`&&Xi(this.card.draft);let e=this.card!==null;this.card=null,this.activeId=null,this.render(),e&&!this.panelOpen&&this.restoreFocus()}openThread(e){this.keepFocus(),this.activeId=e,this.lastViewedId=e,Y(X.lastViewed(this.config.project),e),this.card={kind:`thread`,id:e},this.focusNext=`[data-card="thread"] .card-close`}render(){this.syncOwnerDetail(),this.syncThread(),this.renderPins(),this.renderUi(),this.renderHighlight(),this.layout()}renderPins(){let e=this.visibleComments(),t=new Set(e.map(e=>e._id));for(let[e,n]of this.pins)t.has(e)||(n.remove(),this.pins.delete(e));for(let t of e){let e=this.pins.get(t._id);if(!e){e=G(`button`,{class:`pin`,type:`button`,hidden:!0});let n=t._id;e.addEventListener(`click`,e=>{e.stopPropagation(),this.card?.kind===`thread`&&this.card.id===n?this.closeCard():(this.openThread(n),this.render())}),this.pins.set(t._id,e),this.pinLayer.append(e)}e.textContent=bi(t.authorName),e.style.background=xi(t.authorName),e.setAttribute(`aria-label`,this.t(`pinLabel`,{name:t.authorName,body:(t.body||t.suggestion?.after||``).slice(0,80)})),t.replyCount?e.dataset.replies=String(t.replyCount):delete e.dataset.replies,e.dataset.status=t.status,e.dataset.active=String(this.activeId===t._id),e.dataset.confidence=this.placements.get(t._id)?.confidence??`lost`}if(this.pinLayer.querySelector(`.pin-draft`)?.remove(),this.card?.kind===`composer`){let{draft:e}=this.card,{x:t,y:n}=this.anchorPoint(e.anchor,e.element,e.range),r=G(`div`,{class:`pin pin-draft pin-pending`,"aria-hidden":`true`},this.name?bi(this.name):`+`);r.style.background=this.name?xi(this.name):`var(--n-accent)`,r.style.transform=`translate(${Math.round(t)}px, ${Math.round(n)}px)`,this.pinLayer.append(r)}}renderUi(){this.shownPlacements=this.placementSummary();let e=[this.renderToolbar()];this.panelOpen&&e.push(this.renderPanel());let t=this.renderCard();t&&e.push(t),this.toast&&e.push(G(`div`,{class:`toast`,role:`status`},this.toast));let n=this.renderConfirm();n&&e.push(n);let r=this.root.activeElement,i=r?.dataset.focusKey,a=r instanceof HTMLTextAreaElement||r instanceof HTMLInputElement?{start:r.selectionStart,end:r.selectionEnd}:null;this.uiLayer.replaceChildren(...e);let o=this.focusNext;this.focusNext=null;let s=o?this.uiLayer.querySelector(o):null;if(s)s.focus();else if(i){let e=this.uiLayer.querySelector(`[data-focus-key="${i}"]`);e?.focus(),a&&(e instanceof HTMLTextAreaElement||e instanceof HTMLInputElement)&&e.setSelectionRange(a.start,a.end)}this.positionCard()}renderToolbar(){let e=this.comments.filter(e=>e.status===`open`).length,t=this.toolbarDrag?.moving?this.toolbarDrag:null;return G(`div`,{class:`toolbar`,role:`toolbar`,"aria-label":this.t(`toolbar`),"data-dragging":!!t,style:t&&`transform: translate(${t.dx}px, ${t.dy}px)`,onpointerdown:e=>this.startToolbarDrag(e)},G(`button`,{class:`tb-btn`,type:`button`,"aria-pressed":String(this.picking),"data-focus-key":`tb-comment`,"aria-label":this.picking?this.t(`cancelAdding`):this.t(`addComment`),title:this.withKey(`addComment`,`addCommentKey`),onclick:()=>this.setPicking(!this.picking)},K(J.comment),G(`span`,{class:`tb-label`},this.picking?this.t(`pickElement`):this.config.label??this.t(`comment`))),G(`button`,{class:`tb-btn`,type:`button`,"aria-pressed":String(this.panelOpen),"data-focus-key":`tb-panel`,"aria-label":this.t(`openCount`,{count:e}),title:this.t(`allComments`),onclick:()=>this.togglePanel()},K(J.list),G(`span`,{class:`tb-count`},String(e))))}startToolbarDrag(e){if(e.button!==0||!e.isPrimary)return;this.endToolbarDrag?.();let t={id:e.pointerId,x:e.clientX,y:e.clientY,dx:0,dy:0,moving:!1};this.toolbarDrag=t;let n=()=>this.uiLayer.querySelector(`.toolbar`),r=e=>{e.pointerId===t.id&&(t.dx=e.clientX-t.x,t.dy=e.clientY-t.y,!(!t.moving&&Math.hypot(t.dx,t.dy)<5)&&(t.moving||(t.moving=!0,this.host.dataset.dragging=``,n()?.setAttribute(`data-dragging`,``)),e.preventDefault(),n()?.style.setProperty(`transform`,`translate(${t.dx}px, ${t.dy}px)`)))},i=e=>{e.pointerId===t.id&&(this.endToolbarDrag?.(),t.moving&&this.dropToolbar(n(),!0))},a=e=>{e instanceof PointerEvent&&e.pointerId!==t.id||(this.endToolbarDrag?.(),t.moving&&this.dropToolbar(n(),!1))};window.addEventListener(`pointermove`,r,!0),window.addEventListener(`pointerup`,i,!0),window.addEventListener(`pointercancel`,a,!0),window.addEventListener(`blur`,a),this.endToolbarDrag=()=>{window.removeEventListener(`pointermove`,r,!0),window.removeEventListener(`pointerup`,i,!0),window.removeEventListener(`pointercancel`,a,!0),window.removeEventListener(`blur`,a),delete this.host.dataset.dragging,this.toolbarDrag=null,this.endToolbarDrag=null}}dropToolbar(e,t){if(this.toolbarDropped=!0,setTimeout(()=>this.toolbarDropped=!1),!e)return;let n=e.getBoundingClientRect();if(t){let e=ra(n.left+n.width/2,n.top+n.height/2);this.position=e,this.host.dataset.position=e,Y(X.position(this.config.project),e===this.config.position?null:e)}e.removeAttribute(`data-dragging`),e.style.removeProperty(`transform`);let r=e.getBoundingClientRect();matchMedia(`(prefers-reduced-motion: reduce)`).matches||e.animate([{transform:`translate(${n.left-r.left}px, ${n.top-r.top}px)`},{transform:`none`}],{duration:320,easing:`cubic-bezier(0.2, 0.9, 0.3, 1.15)`})}renderPanel(){let e=this.comments.filter(e=>e.status===`open`),t=this.comments.filter(e=>e.status===`resolved`),n=this.search.trim().toLocaleLowerCase(),r=(...e)=>!n||e.some(e=>e?.toLocaleLowerCase().includes(n)),i=this.mine??[],a=(this.tab===`open`?e:this.tab===`resolved`?t:i).filter(e=>r(e.body,e.authorName,e.anchor.quote?.exact,e.suggestion?.after,this.tab===`mine`?e.page.path:void 0)),o=a.filter(e=>this.placements.get(e._id)?.element),s=a.filter(e=>!this.placements.get(e._id)?.element),c=this.pages.filter(e=>e.path!==this.pageKey&&r(e.path)),l=e=>[e.suggestion?Bi(e.suggestion):e.anchor.quote?G(`div`,{class:`item-quote`},e.anchor.quote.exact):null,e.body?G(`div`,{class:`item-text`},e.body):null],u=e=>{let t=e.page.path===this.pageKey,n=t?null:ea(e,location),r=e.status===`resolved`;return G(t?`button`:n===null?`div`:`a`,t?{class:`item`,type:`button`,"data-focus-key":`item-${e._id}`,onclick:()=>{this.deepLinkId=e._id,this.openDeepLink()}}:{class:`item`,href:n},G(`div`,{class:`row`},G(`span`,{class:`author`},t?this.t(`thisPage`):e.page.path),G(`span`,{class:`meta`},this.i18n.timeAgo(e.createdAt)),G(`span`,{class:`spacer`}),G(`span`,{class:r?`badge badge-ok`:`badge`},r?K(J.check):null,this.t(r?e.resolution===`outdated`?`outdated`:`resolved`:`statusOpen`))),...l(e))},d=e=>G(`button`,{class:`item`,type:`button`,"aria-current":e._id===this.lastViewedId?`true`:null,"data-focus-key":`item-${e._id}`,onclick:()=>this.focusComment(e._id)},G(`div`,{class:`row`},G(`span`,{class:`avatar`,style:`background:${xi(e.authorName)}`},bi(e.authorName)),G(`span`,{class:`author`},e.authorName),G(`span`,{class:`meta`},this.i18n.timeAgo(e.createdAt)+(e.replyCount?` · ${this.t(`replyCount`,{count:e.replyCount})}`:``)),e.page.origin===location.origin?null:G(`span`,{class:`badge`,title:e.page.origin},new URL(e.page.origin).host),e.resolution===`outdated`?G(`span`,{class:`badge`},this.t(`outdated`)):null),...l(e)),f=[];if(this.tab===`mine`?this.mine?a.length?f.push(...a.map(u)):f.push(G(`div`,{class:`empty`},n?this.t(`noMatches`,{query:this.search.trim()}):this.t(`noYours`))):f.push(G(`div`,{class:`empty`},this.t(`loading`))):this.loaded?!a.length&&n?f.push(G(`div`,{class:`empty`},this.t(`noMatches`,{query:this.search.trim()}))):a.length?(f.push(...o.map(d)),s.length&&(f.push(G(`div`,{class:`section-label`},this.t(`notFoundHere`))),f.push(...s.map(d)))):f.push(G(`div`,{class:`empty`},this.tab===`open`?this.withKey(`noOpen`,`noOpenKey`):this.t(`noResolved`))):f.push(G(`div`,{class:`empty`},this.t(`loading`))),c.length&&this.tab!==`mine`){f.push(G(`div`,{class:`section-label`},this.t(`otherPages`)));for(let e of c.slice(0,20)){let t=ta(e.path,location);f.push(G(t===null?`div`:`a`,t===null?{class:`item`}:{class:`item`,href:t},G(`div`,{class:`row`},G(`span`,{class:`author`},e.path),G(`span`,{class:`spacer`}),G(`span`,{class:`badge`},this.t(`openOnPage`,{count:e.count})))))}}return G(`div`,{class:`panel`,role:`dialog`,"aria-label":this.t(`comments`)},G(`div`,{class:`panel-head`},G(`div`,{class:`panel-title`},this.t(`comments`)),G(`button`,{class:`btn btn-ghost btn-icon`,type:`button`,"aria-label":this.t(`close`),onclick:()=>this.togglePanel(!1)},K(J.close))),this.comments.length||this.mine?.length?G(`div`,{class:`panel-search`},K(J.search),G(`input`,{class:`field`,type:`search`,value:this.search,placeholder:this.t(`searchComments`),"aria-label":this.t(`searchComments`),"aria-controls":`nuni-panel-list`,"data-focus-key":`panel-search`,oninput:e=>{this.search=e.target.value,this.render()}})):null,G(`div`,{class:`tabs`,role:`tablist`,"aria-label":this.t(`comments`),onkeydown:e=>{let t=e.key;if(![`ArrowLeft`,`ArrowRight`,`Home`,`End`].includes(t))return;e.preventDefault();let n=Vi.indexOf(this.tab),r=Vi.length-1;this.tab=Vi[t===`Home`?0:t===`End`?r:t===`ArrowRight`?(n+1)%Vi.length:(n+r)%Vi.length],this.focusNext=`[data-focus-key="tab-${this.tab}"]`,this.render()}},Vi.map(n=>G(`button`,{class:`tab`,role:`tab`,type:`button`,id:`nuni-tab-${n}`,"data-focus-key":`tab-${n}`,"aria-selected":String(this.tab===n),"aria-controls":`nuni-panel-list`,tabindex:this.tab===n?0:-1,onclick:()=>{this.tab=n,this.render()}},n===`open`?this.t(`tabOpen`,{count:e.length}):n===`resolved`?this.t(`tabResolved`,{count:t.length}):this.mine?this.t(`tabYours`,{count:this.mine.length}):this.t(`yours`)))),G(`div`,{class:`panel-list`,id:`nuni-panel-list`,role:`tabpanel`,"aria-labelledby":`nuni-tab-${this.tab}`},...f),this.status&&!this.status.claimed&&!this.isOwner?this.renderPanelFooter():null)}renderPanelFooter(){return G(`div`,{class:`panel-foot`},G(`div`,{class:`row`},G(`span`,{class:`meta`},this.t(`ownSite`)),G(`span`,{class:`spacer`}),G(`button`,{class:`btn`,type:`button`,onclick:()=>this.openClaim()},K(J.github),this.t(`claim`))))}renderComposer(e,t){let n=!this.name,r=G(`span`,{class:`avatar cmp-avatar`,"aria-hidden":`true`}),i=e=>{let t=e.trim();r.classList.toggle(`avatar-empty`,!t),t?(r.textContent=bi(t),r.style.background=xi(t)):(r.replaceChildren(K(J.user)),r.style.background=``)},a=G(`input`,{class:`cmp-name`,placeholder:this.t(`yourName`),value:this.name,maxlength:b.nameMaxLength,autocomplete:`name`,"data-focus-key":`name`,"aria-label":this.t(`yourName`)}),o=e.suggestFrom??null,s=!!e.suggesting&&o!==null,c=G(`textarea`,{class:`cmp-text`,placeholder:this.t(s?`addNote`:`leaveComment`),maxlength:b.bodyMaxLength,rows:3,"data-focus-key":`body`,"aria-label":this.t(`comment`)}),l=s?G(`textarea`,{class:`cmp-suggest`,maxlength:b.quoteMaxLength,rows:1,"data-focus-key":`suggestion`,"aria-label":this.t(`newText`)}):null;l&&(l.value=e.suggestion??o??``);let u=()=>!!c.value.trim()||!!(l&&l.value.trim()&&l.value.trim()!==o),d=this.uiLayer.querySelector(`[data-focus-key="body"]`);d&&(c.value=d.value);let f=this.uiLayer.querySelector(`[data-focus-key="name"]`);f&&(a.value=f.value),i(n?a.value:this.name),a.addEventListener(`input`,()=>i(a.value));let p=G(`span`,{class:`cmp-count`,"aria-live":`polite`}),m=G(`button`,{class:`cmp-post`,type:`submit`,disabled:!!e.sending||!u()},e.sending?this.t(`posting`):this.t(`post`),K(J.arrowUp)),h=()=>{m.disabled=!!e.sending||!u();let t=b.bodyMaxLength-c.value.length;p.textContent=t<=b.bodyMaxLength*.1?this.t(`charsLeft`,{count:t}):``;for(let e of[c,l])e&&(e.style.height=`auto`,e.style.height=`${e.scrollHeight+2}px`)};c.addEventListener(`input`,()=>{h(),this.positionCard()}),l?.addEventListener(`input`,()=>{e.suggestion=l.value,h(),this.positionCard()}),requestAnimationFrame(()=>{c.isConnected&&(h(),this.positionCard())});let g=()=>void this.submitDraft(e,c.value,n?a.value:this.name);for(let e of[c,l])e?.addEventListener(`keydown`,e=>{e.key===`Enter`&&(e.metaKey||e.ctrlKey)&&(e.preventDefault(),g())});let _=this.canAttach(e),v=_?G(`input`,{type:`file`,accept:gi.join(`,`),multiple:!0,hidden:!0,tabindex:-1,"aria-hidden":`true`,onchange:t=>{let n=t.target,r=[...n.files??[]];n.value=``,this.addImages(e,r)}}):null;_&&c.addEventListener(`paste`,t=>{let n=[...t.clipboardData?.files??[]].filter(e=>gi.includes(e.type));n.length&&(t.preventDefault(),this.addImages(e,n))});let y=t=>{e.suggesting=t,e.error=void 0,this.render();let n=this.uiLayer.querySelector(`[data-focus-key="${t?`suggestion`:`body`}"]`);n?.focus(),t&&n?.select()};return G(`form`,{class:`${t} composer`,"data-card":`composer`,onsubmit:e=>{e.preventDefault(),g()}},G(`div`,{class:`cmp-head`},r,n?a:G(`span`,{class:`author`},this.name),G(`span`,{class:`spacer`}),n?null:G(`button`,{class:`cmp-link`,type:`button`,onclick:()=>{this.name=``,this.render(),this.focusComposer()}},this.t(`notYou`))),s?G(`div`,{class:`suggest`},G(`div`,{class:`suggest-label`},this.t(`suggestedEdit`),G(`span`,{class:`spacer`}),G(`button`,{class:`cmp-link`,type:`button`,onclick:()=>y(!1)},this.t(`removeSuggestion`))),G(`del`,{},o),l):e.anchor.quote?G(`blockquote`,{class:`quote`},e.anchor.quote.exact):null,c,e.images?.length?G(`div`,{class:`cmp-images`},G(`div`,{class:`cmp-thumbs`},...e.images.map((t,n)=>G(`div`,{class:`cmp-thumb`},G(`img`,{src:t.url,alt:this.t(`imageN`,{n:n+1})}),G(`button`,{class:`cmp-thumb-remove`,type:`button`,"aria-label":this.t(`removeImage`,{n:n+1}),title:this.t(`removeImage`,{n:n+1}),onclick:()=>{URL.revokeObjectURL(t.url),e.images?.splice(n,1),this.render(),this.positionCard()}},K(J.close))))),G(`p`,{class:`cmp-images-note`},this.t(`imagesPublic`))):null,e.error?G(`div`,{class:`error cmp-error`,role:`alert`},e.error):null,G(`div`,{class:`cmp-foot`},G(`span`,{class:`cmp-keys`,title:this.t(`send`,{key:this.i18n.mod})},G(`kbd`,{},this.i18n.mod),G(`kbd`,{},`↵`)),o!==null&&!s?G(`button`,{class:`cmp-link cmp-suggest-btn`,type:`button`,onclick:()=>y(!0)},K(J.edit),this.t(`suggestEdit`)):null,_?G(`button`,{class:`icon-btn`,type:`button`,"aria-label":this.t(`addImage`),title:this.t(`addImage`),onclick:()=>v?.click()},K(J.image)):null,_&&this.canScreenshot(e)?G(`button`,{class:`icon-btn`,type:`button`,"aria-label":this.t(`markUpScreenshot`),title:this.t(e.preparingMarkup?`preparingScreenshot`:`markUpScreenshot`),disabled:!!e.preparingMarkup,onclick:()=>void this.markUpScreenshot(e)},K(J.pen)):null,v,p,G(`span`,{class:`spacer`}),m),G(`button`,{class:`icon-btn cmp-close`,type:`button`,"aria-label":this.t(`cancel`),title:this.t(`cancel`),onclick:()=>this.closeCard()},K(J.close)))}renderCard(){let e=this.card;if(!e)return null;let t=`card${window.matchMedia(Yi).matches?` sheet`:``}`;if(e.kind===`composer`)return this.renderComposer(e.draft,t);let n=this.comments.find(t=>t._id===e.id);if(!n)return null;let r=this.isMine(n),i=this.isOwner,a=this.placements.get(n._id),o;if(e.editing){let t=G(`textarea`,{class:`field`,maxlength:b.bodyMaxLength,placeholder:n.suggestion?this.t(`addNote`):null,"data-focus-key":`edit`,"aria-label":this.t(`comment`)}),r=this.uiLayer.querySelector(`[data-focus-key="edit"]`);t.value=r?r.value:n.body;let i=n.suggestion?G(`textarea`,{class:`field`,rows:2,maxlength:b.quoteMaxLength,"data-focus-key":`edit-suggestion`,"aria-label":this.t(`newText`)}):null;if(i&&n.suggestion){let e=this.uiLayer.querySelector(`[data-focus-key="edit-suggestion"]`);i.value=e?e.value:n.suggestion.after}o=G(`div`,{class:`card-body`},n.suggestion&&i?G(`div`,{class:`suggest`},G(`div`,{class:`suggest-label`},this.t(`suggestedEdit`)),G(`del`,{},n.suggestion.before),i):null,t,G(`div`,{class:`row`},G(`span`,{class:`spacer`}),G(`button`,{class:`btn btn-ghost`,type:`button`,onclick:()=>{e.editing=!1,this.render()}},this.t(`cancel`)),G(`button`,{class:`btn btn-primary`,type:`button`,disabled:!!e.busy,onclick:()=>this.saveEdit(n,t.value,i?.value)},this.t(`save`))))}else{let t=[n.status===`resolved`?G(`span`,{class:`badge badge-ok`},K(J.check),this.t(n.resolution===`outdated`?`outdated`:`resolved`)):null,n.page.origin===location.origin?null:G(`span`,{class:`badge`,title:this.t(`leftOn`,{origin:n.page.origin})},new URL(n.page.origin).host),a?.confidence===`low`?G(`span`,{class:`badge`,title:this.t(`approximateHint`)},this.t(`approximate`)):null,a?.element?null:G(`span`,{class:`badge`,title:this.t(`originallyOn`,{text:n.anchor.text||n.anchor.tag})},this.t(`notFound`))].filter(e=>e!==null),s=i&&!(this.ownerDetailLoaded&&this.ownerDetailId===n._id),c=n.status===`resolved`;o=G(`div`,{class:`card-body msg`},G(`div`,{class:`card-head`},Qi(n.authorName),G(`span`,{class:`author`},n.authorName),G(`span`,{class:`meta`},this.i18n.timeAgo(n.createdAt)+(n.editedAt?` · ${this.t(`edited`)}`:``)),G(`span`,{class:`spacer`}),i?G(`button`,{class:`icon-btn${c?` is-resolved`:``}`,type:`button`,"aria-label":this.t(c?`reopen`:`resolve`),title:this.t(c?`reopen`:`resolve`),disabled:!!e.busy,onclick:()=>c?this.reopenComment(n):this.resolveComment(n)},K(J.check)):null,G(`button`,{class:`icon-btn card-close`,type:`button`,"aria-label":this.t(`close`),title:this.t(`close`),onclick:()=>this.closeCard()},K(J.close))),G(`div`,{class:`msg-main`},n.suggestion?zi(n.suggestion,this.t(`suggestedEdit`),i?this.copyNewTextButton(n.suggestion.after):null):n.anchor.quote?G(`blockquote`,{class:`quote`},n.anchor.quote.exact):null,n.body?G(`div`,{class:`comment-body`},n.body):null,this.threadId===n._id&&this.thread?.images?.length?G(`div`,{class:`images`},...this.thread.images.map((e,t)=>G(`a`,{href:e,target:`_blank`,rel:`noreferrer`,title:this.t(`openImage`)},G(`img`,{src:e,alt:this.t(`imageN`,{n:t+1}),loading:`lazy`})))):null,this.ownerDetail?._id===n._id&&this.ownerDetail.screenshotUrl?G(`a`,{class:`shot`,href:this.ownerDetail.screenshotUrl,target:`_blank`,rel:`noreferrer`,title:this.t(`openScreenshot`)},G(`img`,{src:this.ownerDetail.screenshotUrl,alt:this.t(`screenshotTaken`)})):null,t.length?G(`div`,{class:`badges`},...t):null,i&&!c&&!a?.element?G(`div`,{class:`lost`},G(`p`,{},this.t(`lostHint`)),G(`div`,{class:`row`},G(`button`,{class:`btn`,type:`button`,onclick:()=>this.startMovePin(n)},K(J.target),this.t(`movePin`)),G(`button`,{class:`btn btn-ghost`,type:`button`,disabled:!!e.busy,onclick:()=>this.closeAsOutdated(n)},this.t(`closeOutdated`)))):null,G(`div`,{class:`msg-foot`},this.renderReactions(n,n._id),G(`span`,{class:`spacer`}),G(`button`,{class:`icon-btn`,type:`button`,"aria-label":this.t(`copyForAgent`),title:s?this.t(`loadingContext`):this.t(`copyForAgentHint`),disabled:s,onclick:()=>this.copyForAgent(n)},K(J.bot)),i&&a?.element?G(`button`,{class:`icon-btn`,type:`button`,"aria-label":this.t(`movePin`),title:this.t(`movePin`),onclick:()=>this.startMovePin(n)},K(J.target)):null,r?G(`button`,{class:`icon-btn`,type:`button`,"aria-label":this.t(`edit`),title:this.t(`edit`),onclick:()=>{e.editing=!0,this.render()}},K(J.edit)):null,r||i?G(`button`,{class:`icon-btn icon-btn-danger`,type:`button`,"aria-label":this.t(`delete`),title:this.t(`delete`),"data-focus-key":`delete`,disabled:!!e.busy,onclick:()=>void this.deleteComment(n)},K(J.trash)):null),e.error?G(`div`,{class:`error`,role:`alert`},e.error):null))}return G(`div`,{class:t,"data-card":`thread`,role:`dialog`,"aria-label":this.t(`commentBy`,{name:n.authorName})},o,e.editing?null:this.renderThread(n))}renderReactions(e,t,n=!0){let r=this.card;if(r?.kind!==`thread`)return null;let i=this.threadId===e._id&&this.thread?this.thread.reactions.filter(e=>e.targetId===t):[],a=r.picker===t;return!n&&!i.length&&!a?null:G(`div`,{class:`reactions`},...i.map(n=>{let r=n.authorKeyHashes.includes(this.secretHash);return G(`button`,{class:`reaction`,type:`button`,"aria-pressed":String(r),"aria-label":`${n.emoji} ${n.count}${r?`, including you`:``}`,onclick:()=>this.toggleReaction(e,t,n.emoji)},`${n.emoji} ${n.count}`)}),n?this.reactionAdd(t,`reaction reaction-add`):null,a?G(`div`,{class:`reaction-picker`,role:`group`,"aria-label":this.t(`reactions`)},...ee.map(n=>G(`button`,{class:`reaction`,type:`button`,"aria-label":this.t(`reactWith`,{emoji:n}),onclick:()=>{r.picker=null,this.toggleReaction(e,t,n),this.render()}},n))):null)}reactionAdd(e,t){let n=this.card;if(n?.kind!==`thread`)return null;let r=n.picker===e;return G(`button`,{class:t,type:`button`,"aria-label":this.t(`addReaction`),"aria-expanded":String(r),title:this.t(`addReaction`),onclick:()=>{n.picker=r?null:e,this.render()}},K(J.smile))}renderThread(e){let t=this.card;if(t?.kind!==`thread`)return null;let n=this.threadId===e._id?this.thread?.replies??[]:[],r=this.isOwner,i=n.map(n=>{let i=this.isMyReply(n);if(t.replyEditing===n._id){let r=G(`textarea`,{class:`field`,maxlength:b.bodyMaxLength,"data-focus-key":`reply-edit-${n._id}`,"aria-label":this.t(`editReply`)}),i=this.uiLayer.querySelector(`[data-focus-key="reply-edit-${n._id}"]`);return r.value=i?i.value:n.body,G(`div`,{class:`reply`},r,G(`div`,{class:`row`},G(`span`,{class:`spacer`}),G(`button`,{class:`btn btn-ghost`,type:`button`,onclick:()=>{t.replyEditing=void 0,this.render()}},this.t(`cancel`)),G(`button`,{class:`btn btn-primary`,type:`button`,disabled:!!t.busy,onclick:()=>this.saveReplyEdit(e,n,r.value)},this.t(`save`))))}return G(`div`,{class:`reply msg`,"data-reply":n._id},G(`div`,{class:`card-head`},Qi(n.authorName),G(`span`,{class:`author`},n.authorName),n.isOwner?G(`span`,{class:`badge badge-owner`},this.t(`owner`)):null,G(`span`,{class:`meta`},this.i18n.timeAgo(n.createdAt)+(n.editedAt?` · ${this.t(`edited`)}`:``)),G(`span`,{class:`spacer`}),G(`span`,{class:`msg-tools`},this.reactionAdd(n._id,`icon-btn`),i?G(`button`,{class:`icon-btn`,type:`button`,"aria-label":this.t(`editReply`),title:this.t(`edit`),onclick:()=>{t.replyEditing=n._id,this.render()}},K(J.edit)):null,i||r?G(`button`,{class:`icon-btn icon-btn-danger`,type:`button`,"aria-label":this.t(`deleteReply`),title:this.t(`delete`),"data-focus-key":`delete-${n._id}`,disabled:!!t.busy,onclick:()=>void this.deleteReply(e,n)},K(J.trash)):null)),G(`div`,{class:`msg-main`},G(`div`,{class:`comment-body`},n.body),this.renderReactions(e,n._id,!1)))}),a=!r&&!this.name,o=G(`input`,{class:`reply-name`,placeholder:this.t(`yourName`),value:this.name,maxlength:b.nameMaxLength,autocomplete:`name`,"data-focus-key":`reply-name`,"aria-label":this.t(`yourName`)}),s=this.uiLayer.querySelector(`[data-focus-key="reply-name"]`);s&&(o.value=s.value);let c=G(`textarea`,{class:`reply-text`,placeholder:n.length?this.t(`reply`):this.t(`replyFirst`),maxlength:b.bodyMaxLength,rows:1,"data-focus-key":`reply`,"aria-label":this.t(`reply`)}),l=this.uiLayer.querySelector(`[data-focus-key="reply"]`);l&&(c.value=l.value);let u=G(`button`,{class:`reply-send`,type:`submit`,"aria-label":this.t(`sendReply`),title:this.t(`sendReply`),disabled:!!t.sendingReply||!c.value.trim()},K(J.arrowUp)),d=()=>{u.disabled=!!t.sendingReply||!c.value.trim(),c.style.height=`auto`,c.style.height=`${c.scrollHeight}px`};c.addEventListener(`input`,d),requestAnimationFrame(()=>{c.isConnected&&d()});let f=()=>void this.sendReply(e,c.value,a?o.value:this.name);return c.addEventListener(`keydown`,e=>{e.key===`Enter`&&(e.metaKey||e.ctrlKey)&&(e.preventDefault(),f())}),G(`div`,{class:`thread`},i.length?G(`div`,{class:`replies`,role:`list`,"aria-label":this.t(`replyCount`,{count:i.length})},...i.map(e=>(e.setAttribute(`role`,`listitem`),e))):null,G(`form`,{class:`reply-form`,onsubmit:e=>{e.preventDefault(),f()}},a?o:null,G(`div`,{class:`reply-row`},c,u)))}positionCard(){let e=this.uiLayer.querySelector(`[data-card]`);if(!e||e.classList.contains(`sheet`))return;let t=null;if(this.card?.kind===`composer`){let{draft:e}=this.card;t=this.anchorPoint(e.anchor,e.element,e.range)}else if(this.card?.kind===`thread`){let e=this.comments.find(e=>this.card?.kind===`thread`&&e._id===this.card.id);t=e?this.pinPositions.get(e._id)??this.pinPoint(e):null}let n=e.offsetWidth||320,r=e.offsetHeight||160,i=window.innerWidth,a=window.innerHeight,o,s;if(t)o=t.x+36,s=t.y-28,o+n>i-12&&(o=t.x-n-12);else{let{position:e}=this;o=e.endsWith(`left`)?16:e.endsWith(`center`)?(i-n)/2:i-n-16,s=e.startsWith(`top`)?72:a-r-72}o=Math.max(12,Math.min(o,i-n-12)),s=Math.max(12,Math.min(s,a-r-12)),e.style.left=`${Math.round(o)}px`,e.style.top=`${Math.round(s)}px`}focusComposer(){requestAnimationFrame(()=>{this.uiLayer.querySelector(this.name?`[data-focus-key="body"]`:`[data-focus-key="name"]`)?.focus()})}};function ra(e,t){let n=window.innerWidth,r=e<n/3?`left`:e>n*2/3?`right`:`center`;return`${t<window.innerHeight/2?`top`:`bottom`}-${r}`}function ia(e){let t=e.composedPath()[0];if(!(t instanceof Element))return!1;let n=document.documentElement;if(t===n)return e.clientX>=n.clientWidth||e.clientY>=n.clientHeight;if(!(t.scrollHeight>t.clientHeight||t.scrollWidth>t.clientWidth))return!1;let r=t.getBoundingClientRect();return e.clientX-r.left-t.clientLeft>=t.clientWidth||e.clientY-r.top-t.clientTop>=t.clientHeight}function aa(e){let t=[e.convexUrl,e.convexSiteUrl].flatMap(e=>{try{return[new URL(e).origin]}catch{return[]}});return e=>{try{return t.includes(new URL(e,location.href).origin)}catch{return!1}}}let Z=null;function oa(e,t){let n={destroy(){}};if(typeof window>`u`||typeof document>`u`)return n;if(!v(e.project))return console.warn(`[nuni] "${e.project}" is not a valid project ID. Run \`npx @nuniapp/cli@latest init\` to get one.`),n;if(Z?.project===e.project)return sa(Z);Z&&ca(Z);let r=S(e),i={project:e.project,widget:null,collectors:ge(r.capture,aa(r)),timer:0,handles:0};Z=i;let a=()=>{if(Z===i){if(!document.body){i.timer=window.setTimeout(a,50);return}i.widget=new na(r,{collectors:i.collectors,loadScreenshot:r.capture.screenshot?t.loadScreenshot:null}),i.widget.start()}},o=window.requestIdleCallback;return o?o(a,{timeout:1500}):i.timer=window.setTimeout(a,1),sa(i)}function sa(e){e.handles++;let t=!1;return{destroy(){t||(t=!0,e.handles--,e.handles<=0&&Z===e&&ca(e))}}}function ca(e){clearTimeout(e.timer),e.widget?.destroy(),e.widget=null,e.collectors.stop(),Z===e&&(Z=null)}let la=document.currentScript??document.querySelector(`script[data-project][src*='nuni']`),ua=null;function da(){return ua??(ua=new Promise(e=>{if(window.__nuniScreenshot)return e(window.__nuniScreenshot);let t=document.createElement(`script`);t.src=new URL(`nuni-screenshot.global.js`,la.src).href,t.async=!0,t.onload=()=>e(window.__nuniScreenshot??null),t.onerror=()=>{ua=null,e(null)},document.head.appendChild(t)})),ua}function fa(e){return oa(e,{loadScreenshot:la?.src?da:null})}window.Nuni={init:fa,version:`0.1.9`};function Q(e){if(e!==void 0)return!/^(false|0|off|no)$/i.test(e.trim())}let $=la?.dataset;$?.project&&fa({project:$.project,convexUrl:$.convexUrl,convexSiteUrl:$.convexSiteUrl,appUrl:$.appUrl,pageKey:$.pageKey,position:$.position,accentColor:$.accentColor,theme:$.theme,label:$.label,hotkey:$.hotkey===void 0?void 0:Q($.hotkey)!==!1&&$.hotkey,zIndex:$.zIndex===void 0?void 0:Number($.zIndex),locale:$.locale,images:Q($.images),capture:{console:Q($.captureConsole),network:Q($.captureNetwork),dom:Q($.captureDom),screenshot:Q($.captureScreenshot)}})})();
799
+ `,this.markLayer=G(`div`,{class:`marks`,"aria-hidden":`true`}),this.pinLayer=G(`div`,{class:`pins`}),this.overlayLayer=G(`div`,{class:`overlay`}),this.uiLayer=G(`div`,{class:`ui`}),this.modalLayer=G(`div`,{class:`modal`}),this.selectButton=G(`button`,{class:`select-btn`,type:`button`,hidden:!0,title:this.withKey(`commentSelection`,`commentSelectionKey`),onmousedown:e=>e.preventDefault(),onpointerdown:e=>e.preventDefault(),onclick:()=>this.commentOnSelection()},K(J.comment),this.t(`comment`)),this.live=G(`div`,{class:`sr`,role:`status`,"aria-live":`polite`}),this.root.append(r,this.markLayer,this.pinLayer,this.overlayLayer,this.uiLayer,this.modalLayer,this.selectButton,this.live),this.uiLayer.addEventListener(`keydown`,e=>this.trapFocus(e)),this.root.addEventListener(`click`,e=>{this.toolbarDropped&&(e.preventDefault(),e.stopPropagation())},!0),this.api=new hi(e)}t(e,t){return this.i18n.t(e,t)}withKey(e,t){let n=this.config.hotkey;return n?this.t(t,{key:n.toUpperCase()}):this.t(e)}applyAppearance(){let{theme:e,accentColor:t,zIndex:n}=this.config;this.host.dataset.position=this.position,this.host.dataset.theme=e,n!==null&&(this.host.style.zIndex=String(n));let r=t?Ci(t):null;if(!r)return;let[i,a,o]=r;this.host.style.setProperty(`--n-accent`,`rgb(${i}, ${a}, ${o})`),this.host.style.setProperty(`--n-accent-soft`,`rgba(${i}, ${a}, ${o}, 0.14)`),this.host.style.setProperty(`--n-accent-fg`,wi(r))}start(){document.body.appendChild(this.host),ji(this.secret).then(e=>{this.secretHash=e,this.render()}),this.api.touch(location.origin),this.cleanups.push(this.api.onStatus(e=>{this.status=e,this.render()})),this.cleanups.push(this.api.onPages(e=>{this.pages=e,this.render()})),this.ownerToken&&this.watchSession(this.ownerToken),this.readDeepLink(),this.subscribePage(),this.cleanups.push(Ai(()=>{this.readDeepLink(),this.subscribePage()}));let e=e=>this.onKeyDown(e),t=()=>this.scheduleLayout(),n=e=>this.onMessage(e);window.addEventListener(`keydown`,e,!0),window.addEventListener(`scroll`,t,{capture:!0,passive:!0}),window.addEventListener(`resize`,t,{passive:!0}),window.addEventListener(`message`,n);let r=()=>this.scheduleSelection(),i=e=>{e.composedPath().includes(this.host)||(this.pointerDown=!0,this.scheduleSelection(),this.closeCardFromOutside(e))},a=()=>{this.pointerDown=!1,this.scheduleSelection()};document.addEventListener(`selectionchange`,r),document.addEventListener(`pointerdown`,i,!0),document.addEventListener(`pointerup`,a,!0),this.cleanups.push(()=>{document.removeEventListener(`selectionchange`,r),document.removeEventListener(`pointerdown`,i,!0),document.removeEventListener(`pointerup`,a,!0),cancelAnimationFrame(this.selectionFrame)}),this.cleanups.push(()=>{window.removeEventListener(`keydown`,e,!0),window.removeEventListener(`scroll`,t,!0),window.removeEventListener(`resize`,t),window.removeEventListener(`message`,n)});let o=new MutationObserver(e=>{e.every(e=>this.host.contains(e.target)||e.target===this.host)||this.scheduleResolve()});o.observe(document.body,{childList:!0,subtree:!0,characterData:!0,attributes:!0,attributeFilter:[`class`,`style`,`hidden`,`open`,`id`]});let s=new ResizeObserver(()=>this.scheduleLayout());s.observe(document.documentElement),this.cleanups.push(()=>{o.disconnect(),s.disconnect()}),this.render()}destroy(){this.setPicking(!1),this.endToolbarDrag?.(),this.pageUnsub?.(),this.sessionUnsub?.(),this.ownerDetailUnsub?.(),this.threadUnsub?.(),this.mineUnsub?.(),clearTimeout(this.pinReportTimer),this.resolveRun++;for(let e of this.scopeWatchers.values())e();this.scopeWatchers.clear();for(let e of this.cleanups)e();cancelAnimationFrame(this.layoutFrame),clearTimeout(this.resolveTimer),clearTimeout(this.toastTimer),this.host.remove(),this.api.close()}currentPageKey(){let e=new URL(location.href);return this.config.getPageKey(e)}subscribePage(){let e=this.currentPageKey();e===this.pageKey&&this.pageUnsub||(this.pageKey=e,this.pageUnsub?.(),this.comments=[],this.extraComment=null,this.loaded=!1,this.placements.clear(),this.pinReported.clear(),clearTimeout(this.pinReportTimer),this.card=null,this.activeId=null,this.pageUnsub=this.api.onPage(e,e=>{let t=this.extraComment,n=t&&!e.some(e=>e._id===t._id)?[...e,t]:e;this.comments=n.sort((e,t)=>e.createdAt-t.createdAt),this.loaded=!0,this.resolvePlacements(this.placements.size>0,this.deepLinkId??void 0),this.openDeepLink(),this.render()},()=>{}),this.render())}watchSession(e){this.sessionUnsub?.(),this.sessionUnsub=this.api.onSession(e,e=>{e.valid?this.ownerName=e.ownerName??this.t(`owner`):(this.ownerName=null,this.ownerToken=null,Y(X.session(this.config.project),null),this.sessionUnsub?.(),this.sessionUnsub=null),this.render()})}syncOwnerDetail(){let e=this.ownerToken,t=this.card?.kind===`thread`&&this.isOwner&&e?this.card.id:null;t!==this.ownerDetailId&&(this.ownerDetailUnsub?.(),this.ownerDetailUnsub=null,this.ownerDetail=null,this.ownerDetailLoaded=!1,this.ownerDetailId=t,t&&e&&(this.ownerDetailUnsub=this.api.onOwnerComment(t,e,e=>{this.ownerDetailId===t&&(this.ownerDetail=e,this.ownerDetailLoaded=!0,this.render())})))}syncThread(){let e=this.card?.kind===`thread`?this.card.id:null;e!==this.threadId&&(this.threadUnsub?.(),this.threadUnsub=null,this.thread=null,this.threadId=e,e&&(this.threadUnsub=this.api.onThread(e,t=>{this.threadId===e&&(this.thread=t,this.render())})))}get isOwner(){return!!(this.ownerToken&&this.ownerName)}isMine(e){return!!this.secretHash&&e.authorKeyHash===this.secretHash}visibleComments(){return this.comments.filter(e=>e.status===(this.panelOpen&&this.tab===`resolved`?`resolved`:`open`)||this.card?.kind===`thread`&&this.card.id===e._id)}scheduleResolve(){clearTimeout(this.resolveTimer),this.resolveTimer=window.setTimeout(()=>this.resolvePlacements(!0),200)}stillPlaced(e){let t=this.placements.get(e._id);if(!t?.element?.isConnected)return!1;let n=e.anchor.quote;if(n)return t.range!==void 0&&Ki(t.range.toString())===n.exact;let r=w(t.element),i=e.anchor.text;return!i||r===i||T(r,i)>.8}resolvePlacements(e,t){let n=++this.resolveRun,r=new Set(this.comments.map(e=>e._id));for(let e of this.placements.keys())r.has(e)||this.placements.delete(e);let i=this.comments.filter(t=>!(e&&this.stillPlaced(t))),a=t?i.findIndex(e=>e._id===t):-1;a>0&&i.unshift(...i.splice(a,1));let o=Ot(),s={isIgnored:this.isIgnored,document},c=()=>{if(n!==this.resolveRun)return;let t=performance.now();for(;i.length;){let e=i.shift(),n=Kt(e.anchor,document,s,o);if(this.placements.set(e._id,{element:n.element,confidence:n.confidence,range:n.range}),performance.now()-t>8)break}if(this.watchScopes(),this.renderPins(),this.layout(),i.length){qi(c);return}this.schedulePinReport(),(e||n>1)&&this.panelOpen&&this.placementSummary()!==this.shownPlacements&&this.render()};c()}schedulePinReport(){clearTimeout(this.pinReportTimer),this.pinReportTimer=window.setTimeout(()=>{if(!this.loaded||document.visibilityState!==`visible`)return;let e=[],t=[];for(let n of this.comments){if(n.status!==`open`||n.page.path!==this.pageKey)continue;let r=this.placements.get(n._id);if(!r)continue;let i=!r.element;if(i!==(this.pinReported.get(n._id)??!!n.pinLost)){if(e.length+t.length>=b.pinReportMax)break;this.pinReported.set(n._id,i),(i?e:t).push(n._id)}}(e.length||t.length)&&this.api.reportPins(this.pageKey,e,t)},3e3)}placementSummary(){return this.comments.map(e=>{let t=this.placements.get(e._id);return t?.element?t.confidence===`low`?`~`:`+`:`-`}).join(``)}watchScopes(){let e=/* @__PURE__ */ new Set;for(let{element:t}of this.placements.values()){let n=t;for(let t=0;n&&t<8;t++){let t=qe(n);if(t===document)break;e.add(t),n=E(t)?t.host:Ye(t)}}for(let[t,n]of this.scopeWatchers)e.has(t)||(n(),this.scopeWatchers.delete(t));for(let t of e)this.scopeWatchers.has(t)||this.scopeWatchers.set(t,this.watchScope(t))}watchScope(e){let t=new MutationObserver(()=>this.scheduleResolve()),n=E(e)?null:e;t.observe(n?n.body??n.documentElement:e,{childList:!0,subtree:!0,characterData:!0,attributes:!0,attributeFilter:[`class`,`style`,`hidden`,`open`,`id`]});let r=()=>this.scheduleLayout(),i=n?.defaultView??e;return i.addEventListener(`scroll`,r,{capture:!0,passive:!0}),n?.defaultView?.addEventListener(`resize`,r,{passive:!0}),()=>{t.disconnect(),i.removeEventListener(`scroll`,r,!0),n?.defaultView?.removeEventListener(`resize`,r)}}pinPoint(e){let t=this.placements.get(e._id),n=t?.element;return!n||!De(n)||D(n,document).clipped?null:this.anchorPoint(e.anchor,n,t.range)}anchorPoint(e,t,n){if(n&&n.startContainer.ownerDocument===document){let e=Wi(n).at(-1);if(e)return{x:e.right,y:e.top+e.height/2}}let r=D(t,document);return{x:r.left+e.offset.x*r.width,y:r.top+e.offset.y*r.height}}renderMarks(){let e=[],t=(t,n)=>{let r=G(`div`,{class:n});Object.assign(r.style,{left:`${t.left}px`,top:`${t.top}px`,width:`${t.width}px`,height:`${t.height}px`}),e.push(r)},n=(e,n,r,i)=>{if(n){if(r&&r.startContainer.ownerDocument===document)for(let e of Wi(r))t(e,i?`mark mark-active`:`mark`);if(i){let r=Gi(e,n);r&&t(r,`area`)}}};if(this.card?.kind===`composer`){let{draft:e}=this.card;n(e.anchor,e.element,e.range,!0)}for(let e of this.visibleComments()){let t=this.placements.get(e._id),r=this.activeId===e._id;(r||e.status===`open`&&e.anchor.quote)&&(this.pins.get(e._id)?.hidden||n(e.anchor,t?.element,t?.range,r))}this.markLayer.replaceChildren(...e)}scheduleLayout(){this.layoutFrame||(this.layoutFrame=requestAnimationFrame(()=>{this.layoutFrame=0,this.layout()}))}layout(){let e=window.innerWidth,t=window.innerHeight,n=[];this.pinPositions.clear();for(let r of this.visibleComments()){let i=this.pins.get(r._id);if(!i)continue;let a=this.pinPoint(r);if(i.hidden=!(a&&a.x>=-10&&a.y>=-10&&a.x<=e+10&&a.y<=t+10),!a)continue;let o=a.y,s=a.x;for(;n.some(e=>Math.abs(e.x-s)<14&&Math.abs(e.y-o)<14);)s+=18;n.push({x:s,y:o}),this.pinPositions.set(r._id,{x:s,y:o}),i.style.transform=`translate(${Math.round(s)}px, ${Math.round(o)}px)`}this.renderMarks(),this.positionCard(),this.picking&&(this.hoverEl||this.dragBox)&&this.renderHighlight(),this.placeSelectButton()}setPicking(e){if(e||(this.repinId=null),this.picking===e)return;this.picking=e;let t=document.documentElement;if(this.dragStart=null,this.dragBox=null,e){this.card=null,window.matchMedia(Yi).matches&&(this.panelOpen=!1),this.pickDocs=[document,...Ji(document)];for(let e of this.pickDocs){e.documentElement.classList.add(Hi),this.injectCursorStyle(e),e.addEventListener(`pointermove`,this.onPickMove,!0),e.addEventListener(`click`,this.onPickClick,!0);for(let t of Ui)e.addEventListener(t,this.swallow,{capture:!0,passive:!1});e!==document&&e.addEventListener(`keydown`,this.onFrameKey,!0)}}else{t.classList.remove(Hi),this.hoverEl=null;for(let e of this.pickDocs){e.documentElement?.classList.remove(Hi),e.removeEventListener(`pointermove`,this.onPickMove,!0),e.removeEventListener(`click`,this.onPickClick,!0);for(let t of Ui)e.removeEventListener(t,this.swallow,!0);e.removeEventListener(`keydown`,this.onFrameKey,!0)}this.pickDocs=[]}this.render()}injectCursorStyle(e){if(e.getElementById(`nuni-cursor-style`))return;let t=e.createElement(`style`);t.id=`nuni-cursor-style`,t.textContent=`html.${Hi}, html.${Hi} * { cursor: crosshair !important; }`,(e.head??e.documentElement).appendChild(t),this.cleanups.push(()=>t.remove())}fromPage(e){let t=e.composedPath();if(t.includes(this.host))return null;let n=t[0]??e.target;return n&&n.nodeType===1?n:null}commentOnArea(e){let t=Tt(document,e,this.isIgnored),n=Dt(t,e,{ignoreAttributePrefixes:[],document});this.openComposer({anchor:n,element:t})}pageSelection(){let e=document.getSelection();if(!e||e.isCollapsed||!e.rangeCount)return null;let t=e.getRangeAt(0),n=t.commonAncestorContainer,r=n.nodeType===1?n:n.parentElement;return!r||r===this.host||this.host.contains(r)||r.closest(`input, textarea, select, [contenteditable]`)||r.closest(`[data-nuni]`)?null:Ki(t.toString())?t:null}commentOnSelection(){let e=this.pageSelection();if(!e)return;let t=wt(e,{ignoreAttributePrefixes:[],document});if(!t)return;let n=e.cloneRange();document.getSelection()?.removeAllRanges(),this.selection=null,this.openComposer({...t,range:n})}scheduleSelection(){this.selectionFrame||(this.selectionFrame=requestAnimationFrame(()=>{this.selectionFrame=0,this.selection=this.picking||this.pointerDown?null:this.pageSelection(),this.placeSelectButton()}))}placeSelectButton(){let e=this.selectButton,t=this.selection,n=t?Wi(t).at(-1):void 0,r=window.innerWidth,i=window.innerHeight;if(!t||!n||n.bottom<0||n.top>i){e.hidden=!0;return}e.hidden=!1;let a=e.offsetWidth||96,o=e.offsetHeight||32,s=n.bottom+8;s+o>i-8&&(s=n.top-o-8);let c=Math.max(8,Math.min(n.right-a/2,r-a-8));e.style.transform=`translate(${Math.round(c)}px, ${Math.round(s)}px)`}openComposer(e){let{element:t}=e,n=this.repinId;if(this.setPicking(!1),n){this.movePin(n,e);return}if(this.config.capture.dom)try{e.dom=xe(t)}catch{}e.suggestFrom=Ri(e.anchor,t),this.card={kind:`composer`,draft:e},this.activeId=null,this.render(),this.focusComposer(),e.screenshot=this.takeScreenshot(e)}canScreenshot(e){return!!this.runtime.loadScreenshot&&e.element.ownerDocument===document}async takeScreenshot(e){let t=this.runtime.loadScreenshot;if(!t||!this.canScreenshot(e))return null;let n=getComputedStyle(this.host).getPropertyValue(`--n-accent`).trim()||`#d6246e`;try{await new Promise(e=>setTimeout(e,60));let r=await t(),{range:i,anchor:a,element:o}=e,s=i?()=>i.getBoundingClientRect():a.region?()=>{let e=Gi(a,o);return{left:e.left,top:e.top,right:e.left+e.width,bottom:e.top+e.height}}:void 0;return r?await r.capture(o,{exclude:this.host,accent:n,focus:s}):null}catch{return null}}collectContext(e){let{collectors:t}=this.runtime,n={},r=t.console(),i=t.network();return r.length&&(n.console=r),i.length&&(n.network=i),e.dom&&(n.dom=e.dom),Object.keys(n).length?n:void 0}async attachScreenshot(e,t){try{let n=await t;n&&await this.api.uploadScreenshot(e,this.secret,n)}catch{}}async attachImages(e,t){let n=t.images??[];Xi(t);try{for(let t of n)await this.api.uploadImage(e,this.secret,t.blob)}catch(e){this.showToast(e instanceof W?e.message:this.t(`imageFailed`))}}canAttach(e){return this.config.images&&!!this.status?.claimed&&(e.images?.length??0)<b.imagesPerComment}async addImages(e,t){e.error=void 0;for(let n of t){if((e.images?.length??0)>=b.imagesPerComment){e.error=this.t(`tooManyImages`,{count:b.imagesPerComment});break}let t=await yi(n);if(!t){e.error=this.t(`imageUnreadable`);continue}(e.images??(e.images=[])).push({blob:t,url:URL.createObjectURL(t)})}this.render(),this.positionCard()}async markUpScreenshot(e){let t=this.runtime.loadScreenshot;if(!t||!e.screenshot||e.preparingMarkup)return;e.preparingMarkup=!0,e.error=void 0,this.render();let[n,r]=await Promise.all([t(),e.screenshot]);if(e.preparingMarkup=!1,!n||!r){this.setDraftError(e,this.t(`noScreenshot`));return}this.markingUp=!0;try{let t=await n.markUp(r,{container:this.modalLayer,color:`#e5484d`,labels:{title:this.t(`markUpTitle`),box:this.t(`markUpBox`),arrow:this.t(`markUpArrow`),pen:this.t(`markUpPen`),undo:this.t(`markUpUndo`),cancel:this.t(`cancel`),done:this.t(`markUpDone`),failed:this.t(`markUpFailed`)}});t&&(e.images??(e.images=[])).push({blob:t,url:URL.createObjectURL(t)})}finally{this.markingUp=!1}this.render(),this.positionCard()}copyForAgent(e){let t=this.ownerDetail?._id===e._id?this.ownerDetail:null,n=this.threadId===e._id?this.thread?.replies:void 0;Si(m(t??{...e,replies:n},{includeContext:!!t})).then(e=>this.showToast(e?this.t(`copied`):this.t(`copyFailed`)))}renderHighlight(){if(this.overlayLayer.replaceChildren(),!this.picking)return;let e=window.matchMedia(Yi).matches;if(this.overlayLayer.append(G(`div`,{class:`pick-hint`},this.repinId?this.t(`movePinHint`):e?this.t(`pickHintMobile`):[G(`span`,{},this.t(`pickHint`)),G(`span`,{class:`pick-keys`},this.t(`pickHintKeys`))])),this.dragBox){let e=G(`div`,{class:`highlight drag-box`});Object.assign(e.style,{left:`${this.dragBox.left}px`,top:`${this.dragBox.top}px`,width:`${this.dragBox.width}px`,height:`${this.dragBox.height}px`}),this.overlayLayer.append(e);return}let t=this.hoverEl;if(!t||t===t.ownerDocument.documentElement)return;let n=D(t,document),r=G(`div`,{class:`highlight`},G(`span`,{class:`highlight-label`},$i(t)));Object.assign(r.style,{left:`${n.left-2}px`,top:`${n.top-2}px`,width:`${n.width+4}px`,height:`${n.height+4}px`}),this.overlayLayer.append(r)}onKeyDown(e){if(this.markingUp)return;let t=e.composedPath().includes(this.host);if(e.key===`Escape`){if(this.confirming)this.answer(!1);else if(this.picking)this.setPicking(!1);else if(this.card)this.closeCard();else if(this.panelOpen&&this.search)this.search=``,this.render();else if(this.panelOpen)this.togglePanel(!1);else return;e.stopPropagation();return}if(Zi(e.composedPath()[0]??e.target)||e.metaKey||e.ctrlKey||e.altKey||this.picking&&!t&&this.onPickKey(e)||t&&this.confirming||e.repeat)return;let n=this.config.hotkey;n&&e.key.toLowerCase()===n&&(e.preventDefault(),!this.picking&&this.pageSelection()?this.commentOnSelection():this.setPicking(!this.picking))}onPickKey(e){if(![`ArrowUp`,`ArrowDown`,`ArrowLeft`,`ArrowRight`,`Enter`].includes(e.key))return!1;e.preventDefault(),e.stopPropagation();let t=this.hoverEl;if(!t||!t.isConnected)return this.movePickTo(this.keyboardStart()),!0;if(e.key===`Enter`){let e=t.getBoundingClientRect(),n=St(t,{x:e.left+e.width/2,y:e.top+e.height/2},{ignoreAttributePrefixes:[],document});return this.openComposer({anchor:n,element:t}),!0}let n=t=>{for(;t&&(t===this.host||!De(t));)t=e.key===`ArrowLeft`?t.previousElementSibling:t.nextElementSibling;return t},r=t.ownerDocument.body;return e.key===`ArrowUp`?t.parentElement&&t!==r&&(t=t.parentElement):t=e.key===`ArrowDown`?n(t.firstElementChild)??t:e.key===`ArrowLeft`?n(t.previousElementSibling)??t:n(t.nextElementSibling)??t,this.movePickTo(t),!0}keyboardStart(){let e=document.activeElement;if(e&&e!==document.body&&e!==this.host)return e;let t=document.elementsFromPoint(window.innerWidth/2,window.innerHeight/2).find(e=>!this.isIgnored(e));return t?Yt(t):document.body}movePickTo(e){this.hoverEl=e,e.scrollIntoView({block:`nearest`,inline:`nearest`}),this.live.textContent=this.t(`picked`,{element:$i(e)}),this.renderHighlight()}trapFocus(e){if(e.key!==`Tab`)return;let t=e.composedPath()[0]?.closest?.(`.confirm, [data-card], .panel`);if(!t)return;let n=Array.from(t.querySelectorAll(`button:not([disabled]), input, textarea, a[href], [tabindex="0"]`)).filter(e=>!e.closest(`[hidden]`));if(!n.length)return;let r=n[0],i=n[n.length-1],a=this.root.activeElement;e.shiftKey&&a===r?(e.preventDefault(),i.focus()):!e.shiftKey&&a===i&&(e.preventDefault(),r.focus())}keepFocus(){if(this.returnFocus)return;let e=this.root.activeElement;if(e){this.returnFocus=e.dataset.focusKey??e;return}let t=document.activeElement;this.returnFocus=t&&t!==document.body&&t!==this.host?t:null}restoreFocus(){let e=this.returnFocus;this.returnFocus=null;let t=typeof e==`string`?this.uiLayer.querySelector(`[data-focus-key="${e}"]`):e;t?.isConnected&&t.focus({preventScroll:!0})}ask(e,t){this.confirming?.done(!1);let n=this.root.activeElement?.dataset.focusKey??null;return new Promise(r=>{this.confirming={message:e,action:t,done:r,from:n},this.focusNext=`[data-focus-key="confirm-cancel"]`,this.render()})}answer(e){let t=this.confirming;t&&(this.confirming=null,!e&&t.from&&(this.focusNext=`[data-focus-key="${t.from}"]`),this.render(),t.done(e))}renderConfirm(){let e=this.confirming;return e?G(`div`,{class:`confirm-backdrop`,onclick:()=>this.answer(!1)},G(`div`,{class:`confirm`,role:`alertdialog`,"aria-modal":`true`,"aria-labelledby":`nuni-confirm-text`,onclick:e=>e.stopPropagation()},G(`p`,{id:`nuni-confirm-text`},e.message),G(`div`,{class:`row`},G(`span`,{class:`spacer`}),G(`button`,{class:`btn btn-ghost`,type:`button`,"data-focus-key":`confirm-cancel`,onclick:()=>this.answer(!1)},this.t(`cancel`)),G(`button`,{class:`btn btn-danger-solid`,type:`button`,"data-focus-key":`confirm-ok`,onclick:()=>this.answer(!0)},e.action)))):null}openClaim(){let e=new URL(`${this.config.appUrl}/dashboard/claim`);e.searchParams.set(`project`,this.config.project),e.searchParams.set(`origin`,location.origin),window.open(e.toString(),`nuni-claim`,`popup,width=480,height=680`)||(location.href=e.toString())}onMessage(e){let t;try{t=new URL(this.config.appUrl).origin}catch{return}if(e.origin!==t)return;let n=e.data;n&&n.type===`nuni:session`&&n.project===this.config.project&&typeof n.token==`string`&&n.token.startsWith(`nuni_s_`)&&(this.ownerToken=n.token,Y(X.session(this.config.project),n.token),this.watchSession(n.token),this.showToast(this.t(`signedIn`)))}readDeepLink(){let e=new URL(location.href),t=e.searchParams.get(`nuni`);t&&(this.deepLinkId=t,e.searchParams.delete(`nuni`),history.replaceState(history.state,``,e.toString()))}openDeepLink(){let e=this.deepLinkId;if(!e||!this.loaded)return;this.deepLinkId=null;let t=this.comments.find(t=>t._id===e);if(t){this.focusDeepLinked(t);return}this.api.getComment(e).then(e=>{if(!e||e.page.path!==this.pageKey){this.showToast(this.t(`linkGone`));return}this.extraComment=e,this.comments=[...this.comments.filter(t=>t._id!==e._id),e],this.resolvePlacements(!1,e._id),this.focusDeepLinked(e)})}focusDeepLinked(e){this.focusComment(e._id)}focusComment(e){let t=this.placements.get(e),n=this.comments.find(t=>t._id===e);t?.element&&n&&Fi(t.element,()=>this.anchorPoint(n.anchor,t.element,t.range)),this.openThread(e),window.matchMedia(Yi).matches&&(this.panelOpen=!1),this.render(),setTimeout(()=>this.scheduleLayout(),400)}async submitDraft(e,t,r){let i=r.trim().slice(0,b.nameMaxLength),a=t.trim();if(!i)return this.setDraftError(e,this.t(`enterName`));let o=e.suggesting?e.suggestFrom:null,s=(e.suggestion??o??``).trim();if(o!=null&&(!s||s===o))return this.setDraftError(e,this.t(`changeTextFirst`));if(s.length>b.quoteMaxLength)return this.setDraftError(e,this.t(`suggestionTooLong`,{count:b.quoteMaxLength}));let c=o==null?void 0:{before:o,after:s};if(!a&&!c)return this.setDraftError(e,this.t(`writeFirst`));if(a.length>b.bodyMaxLength)return this.setDraftError(e,this.t(`commentTooLong`,{count:b.bodyMaxLength}));this.name=i,Y(X.name,i),e.sending=!0,e.error=void 0,this.render();let l=n(location.href),u=e.screenshot;try{let t=await this.api.createComment({body:a,suggestion:c,authorName:i,authorSecret:this.secret,page:{...l,path:this.pageKey,title:document.title.slice(0,300)},anchor:e.anchor,viewport:{w:window.innerWidth,h:window.innerHeight,dpr:window.devicePixelRatio||1},context:this.collectContext(e)});u&&this.attachScreenshot(t,u),e.images?.length&&this.attachImages(t,e),this.placements.set(t,{element:e.element,confidence:`exact`,range:e.range}),this.card?.kind===`composer`&&this.card.draft===e&&(this.card=null),this.showToast(this.t(`added`))}catch(t){e.sending=!1,e.error=t instanceof W?t.message:this.t(`postFailed`)}this.render()}setDraftError(e,t){e.error=t,this.render()}async act(e,t,n){let r=this.card;r?.kind===`thread`&&(r.busy=!0,r.error=void 0,this.render());try{return await t(),n&&this.showToast(n),this.card?.kind===`thread`&&this.card.id===e&&(this.card.busy=!1,this.card.editing=!1),this.render(),!0}catch(t){return this.card?.kind===`thread`&&this.card.id===e&&(this.card.busy=!1,this.card.error=t instanceof Error?t.message:this.t(`failed`)),this.render(),!1}}resolveComment(e){let t=this.ownerToken;t&&this.act(e._id,()=>this.api.resolve(e._id,t),this.t(`resolved`)).then(t=>{t&&!(this.panelOpen&&this.tab===`resolved`)&&this.card?.kind===`thread`&&this.card.id===e._id&&this.closeCard()})}reopenComment(e){let t=this.ownerToken;t&&this.act(e._id,()=>this.api.reopen(e._id,t),this.t(`reopened`))}closeAsOutdated(e){let t=this.ownerToken;t&&this.act(e._id,()=>this.api.resolve(e._id,t,`outdated`),this.t(`closedOutdated`)).then(t=>{t&&this.card?.kind===`thread`&&this.card.id===e._id&&this.closeCard()})}startMovePin(e){this.ownerToken&&(this.setPicking(!0),this.repinId=e._id,this.render())}async movePin(e,t){let n=this.ownerToken;if(!n)return;let r=this.placements.get(e);this.placements.set(e,{element:t.element,confidence:`exact`,range:t.range}),this.pinReported.set(e,!1);try{await this.api.repin(e,t.anchor,n),this.showToast(this.t(`pinMoved`))}catch(t){r?this.placements.set(e,r):this.placements.delete(e),this.showToast(t instanceof W?t.message:this.t(`failed`))}this.focusComment(e)}async deleteComment(e){if(!await this.ask(this.t(`confirmDeleteComment`),this.t(`delete`)))return;let t=this.ownerToken,n=this.isMine(e)?()=>this.api.deleteOwn(e._id,this.secret):t?()=>this.api.remove(e._id,t):null;n&&this.act(e._id,n,this.t(`deleted`)).then(t=>{t&&(this.extraComment?._id===e._id&&(this.extraComment=null),this.comments=this.comments.filter(t=>t._id!==e._id),this.placements.delete(e._id),this.closeCard())})}isMyReply(e){return!!this.secretHash&&e.authorKeyHash===this.secretHash}async sendReply(e,t,n){let r=this.card;if(r?.kind!==`thread`||r.id!==e._id)return;let i=(this.isOwner?this.ownerName:n)?.trim().slice(0,b.nameMaxLength),a=t.trim();if(a){if(!i){r.error=this.t(`enterName`),this.render();return}if(a.length>b.bodyMaxLength){r.error=this.t(`replyTooLong`,{count:b.bodyMaxLength}),this.render();return}this.isOwner||(this.name=i,Y(X.name,i)),r.sendingReply=!0,r.error=void 0,this.render();try{await this.api.createReply({commentId:e._id,body:a,authorName:i,authorSecret:this.secret,sessionToken:this.ownerToken??void 0});let t=this.uiLayer.querySelector(`[data-focus-key="reply"]`);t&&(t.value=``)}catch(e){r.error=e instanceof W?e.message:this.t(`replyFailed`)}r.sendingReply=!1,this.render()}}toggleReaction(e,t,n){this.api.toggleReaction(e._id,t,n,this.secret).catch(t=>{this.card?.kind===`thread`&&this.card.id===e._id&&(this.card.error=t instanceof Error?t.message:this.t(`reactFailed`),this.render())})}async deleteReply(e,t){if(!await this.ask(this.t(`confirmDeleteReply`),this.t(`delete`)))return;let n=this.ownerToken,r=this.isMyReply(t)?()=>this.api.deleteReply(t._id,this.secret):n?()=>this.api.removeReply(t._id,n):null;r&&this.act(e._id,r,this.t(`replyDeleted`))}saveReplyEdit(e,t,n){this.act(e._id,()=>this.api.editReply(t._id,this.secret,n),this.t(`saved`)).then(e=>{e&&this.card?.kind===`thread`&&(this.card.replyEditing=void 0,this.render())})}saveEdit(e,t,n){this.act(e._id,()=>this.api.editOwn(e._id,this.secret,t,n),this.t(`saved`))}copyNewTextButton(e){return G(`button`,{class:`cmp-link`,type:`button`,onclick:()=>void Si(e).then(e=>this.showToast(this.t(e?`newTextCopied`:`copyFailed`)))},this.t(`copyNewText`))}showToast(e){this.toast=e,clearTimeout(this.toastTimer),this.toastTimer=window.setTimeout(()=>{this.toast=null,this.render()},2400),this.render()}togglePanel(e=!this.panelOpen){e!==this.panelOpen&&(this.panelOpen=e,e&&!this.mineUnsub&&(this.mineUnsub=this.api.onMine(this.secret,e=>{this.mine=e,this.render()})),e?(this.keepFocus(),this.focusNext=`.panel [role="tab"][aria-selected="true"]`,window.matchMedia(Yi).matches&&(this.card=null)):this.search=``,this.render(),e&&this.uiLayer.querySelector(`.panel .item[aria-current="true"]`)?.scrollIntoView({block:`nearest`}),!e&&!this.card&&this.restoreFocus())}closeCardFromOutside(e){this.card&&!this.picking&&!this.confirming&&e.isPrimary&&(this.markingUp||ia(e)||[...this.uiLayer.querySelector(`[data-card]`)?.querySelectorAll(`textarea`)??[]].some(e=>e.value.trim())||this.card.kind===`composer`&&this.card.draft.images?.length||(this.panelOpen||(this.returnFocus=null),this.closeCard()))}closeCard(){this.card?.kind===`composer`&&Xi(this.card.draft);let e=this.card!==null;this.card=null,this.activeId=null,this.render(),e&&!this.panelOpen&&this.restoreFocus()}openThread(e){this.keepFocus(),this.activeId=e,this.lastViewedId=e,Y(X.lastViewed(this.config.project),e),this.card={kind:`thread`,id:e},this.focusNext=`[data-card="thread"] .card-close`}render(){this.syncOwnerDetail(),this.syncThread(),this.renderPins(),this.renderUi(),this.renderHighlight(),this.layout()}renderPins(){let e=this.visibleComments(),t=new Set(e.map(e=>e._id));for(let[e,n]of this.pins)t.has(e)||(n.remove(),this.pins.delete(e));for(let t of e){let e=this.pins.get(t._id);if(!e){e=G(`button`,{class:`pin`,type:`button`,hidden:!0});let n=t._id;e.addEventListener(`click`,e=>{e.stopPropagation(),this.card?.kind===`thread`&&this.card.id===n?this.closeCard():(this.openThread(n),this.render())}),this.pins.set(t._id,e),this.pinLayer.append(e)}e.textContent=bi(t.authorName),e.style.background=xi(t.authorName),e.setAttribute(`aria-label`,this.t(`pinLabel`,{name:t.authorName,body:(t.body||t.suggestion?.after||``).slice(0,80)})),t.replyCount?e.dataset.replies=String(t.replyCount):delete e.dataset.replies,e.dataset.status=t.status,e.dataset.active=String(this.activeId===t._id),e.dataset.confidence=this.placements.get(t._id)?.confidence??`lost`}if(this.pinLayer.querySelector(`.pin-draft`)?.remove(),this.card?.kind===`composer`){let{draft:e}=this.card,{x:t,y:n}=this.anchorPoint(e.anchor,e.element,e.range),r=G(`div`,{class:`pin pin-draft pin-pending`,"aria-hidden":`true`},this.name?bi(this.name):`+`);r.style.background=this.name?xi(this.name):`var(--n-accent)`,r.style.transform=`translate(${Math.round(t)}px, ${Math.round(n)}px)`,this.pinLayer.append(r)}}renderUi(){this.shownPlacements=this.placementSummary();let e=[this.renderToolbar()];this.panelOpen&&e.push(this.renderPanel());let t=this.renderCard();t&&e.push(t),this.toast&&e.push(G(`div`,{class:`toast`,role:`status`},this.toast));let n=this.renderConfirm();n&&e.push(n);let r=this.root.activeElement,i=r?.dataset.focusKey,a=r instanceof HTMLTextAreaElement||r instanceof HTMLInputElement?{start:r.selectionStart,end:r.selectionEnd}:null;this.uiLayer.replaceChildren(...e);let o=this.focusNext;this.focusNext=null;let s=o?this.uiLayer.querySelector(o):null;if(s)s.focus();else if(i){let e=this.uiLayer.querySelector(`[data-focus-key="${i}"]`);e?.focus(),a&&(e instanceof HTMLTextAreaElement||e instanceof HTMLInputElement)&&e.setSelectionRange(a.start,a.end)}this.positionCard()}renderToolbar(){let e=this.comments.filter(e=>e.status===`open`).length,t=this.toolbarDrag?.moving?this.toolbarDrag:null;return G(`div`,{class:`toolbar`,role:`toolbar`,"aria-label":this.t(`toolbar`),"data-dragging":!!t,style:t&&`transform: translate(${t.dx}px, ${t.dy}px)`,onpointerdown:e=>this.startToolbarDrag(e)},G(`button`,{class:`tb-btn`,type:`button`,"aria-pressed":String(this.picking),"data-focus-key":`tb-comment`,"aria-label":this.picking?this.t(`cancelAdding`):this.t(`addComment`),title:this.withKey(`addComment`,`addCommentKey`),onclick:()=>this.setPicking(!this.picking)},K(J.comment),G(`span`,{class:`tb-label`},this.picking?this.t(`pickElement`):this.config.label??this.t(`comment`))),G(`button`,{class:`tb-btn`,type:`button`,"aria-pressed":String(this.panelOpen),"data-focus-key":`tb-panel`,"aria-label":this.t(`openCount`,{count:e}),title:this.t(`allComments`),onclick:()=>this.togglePanel()},K(J.list),G(`span`,{class:`tb-count`},String(e))))}startToolbarDrag(e){if(e.button!==0||!e.isPrimary)return;this.endToolbarDrag?.();let t={id:e.pointerId,x:e.clientX,y:e.clientY,dx:0,dy:0,moving:!1};this.toolbarDrag=t;let n=()=>this.uiLayer.querySelector(`.toolbar`),r=e=>{e.pointerId===t.id&&(t.dx=e.clientX-t.x,t.dy=e.clientY-t.y,!(!t.moving&&Math.hypot(t.dx,t.dy)<5)&&(t.moving||(t.moving=!0,this.host.dataset.dragging=``,n()?.setAttribute(`data-dragging`,``)),e.preventDefault(),n()?.style.setProperty(`transform`,`translate(${t.dx}px, ${t.dy}px)`)))},i=e=>{e.pointerId===t.id&&(this.endToolbarDrag?.(),t.moving&&this.dropToolbar(n(),!0))},a=e=>{e instanceof PointerEvent&&e.pointerId!==t.id||(this.endToolbarDrag?.(),t.moving&&this.dropToolbar(n(),!1))};window.addEventListener(`pointermove`,r,!0),window.addEventListener(`pointerup`,i,!0),window.addEventListener(`pointercancel`,a,!0),window.addEventListener(`blur`,a),this.endToolbarDrag=()=>{window.removeEventListener(`pointermove`,r,!0),window.removeEventListener(`pointerup`,i,!0),window.removeEventListener(`pointercancel`,a,!0),window.removeEventListener(`blur`,a),delete this.host.dataset.dragging,this.toolbarDrag=null,this.endToolbarDrag=null}}dropToolbar(e,t){if(this.toolbarDropped=!0,setTimeout(()=>this.toolbarDropped=!1),!e)return;let n=e.getBoundingClientRect();if(t){let e=ra(n.left+n.width/2,n.top+n.height/2);this.position=e,this.host.dataset.position=e,Y(X.position(this.config.project),e===this.config.position?null:e)}e.removeAttribute(`data-dragging`),e.style.removeProperty(`transform`);let r=e.getBoundingClientRect();matchMedia(`(prefers-reduced-motion: reduce)`).matches||e.animate([{transform:`translate(${n.left-r.left}px, ${n.top-r.top}px)`},{transform:`none`}],{duration:320,easing:`cubic-bezier(0.2, 0.9, 0.3, 1.15)`})}renderPanel(){let e=this.comments.filter(e=>e.status===`open`),t=this.comments.filter(e=>e.status===`resolved`),n=this.search.trim().toLocaleLowerCase(),r=(...e)=>!n||e.some(e=>e?.toLocaleLowerCase().includes(n)),i=this.mine??[],a=(this.tab===`open`?e:this.tab===`resolved`?t:i).filter(e=>r(e.body,e.authorName,e.anchor.quote?.exact,e.suggestion?.after,this.tab===`mine`?e.page.path:void 0)),o=a.filter(e=>this.placements.get(e._id)?.element),s=a.filter(e=>!this.placements.get(e._id)?.element),c=this.pages.filter(e=>e.path!==this.pageKey&&r(e.path)),l=e=>[e.suggestion?Bi(e.suggestion):e.anchor.quote?G(`div`,{class:`item-quote`},e.anchor.quote.exact):null,e.body?G(`div`,{class:`item-text`},e.body):null],u=e=>{let t=e.page.path===this.pageKey,n=t?null:ea(e,location),r=e.status===`resolved`;return G(t?`button`:n===null?`div`:`a`,t?{class:`item`,type:`button`,"data-focus-key":`item-${e._id}`,onclick:()=>{this.deepLinkId=e._id,this.openDeepLink()}}:{class:`item`,href:n},G(`div`,{class:`row`},G(`span`,{class:`author`},t?this.t(`thisPage`):e.page.path),G(`span`,{class:`meta`},this.i18n.timeAgo(e.createdAt)),G(`span`,{class:`spacer`}),G(`span`,{class:r?`badge badge-ok`:`badge`},r?K(J.check):null,this.t(r?e.resolution===`outdated`?`outdated`:`resolved`:`statusOpen`))),...l(e))},d=e=>G(`button`,{class:`item`,type:`button`,"aria-current":e._id===this.lastViewedId?`true`:null,"data-focus-key":`item-${e._id}`,onclick:()=>this.focusComment(e._id)},G(`div`,{class:`row`},G(`span`,{class:`avatar`,style:`background:${xi(e.authorName)}`},bi(e.authorName)),G(`span`,{class:`author`},e.authorName),G(`span`,{class:`meta`},this.i18n.timeAgo(e.createdAt)+(e.replyCount?` · ${this.t(`replyCount`,{count:e.replyCount})}`:``)),e.page.origin===location.origin?null:G(`span`,{class:`badge`,title:e.page.origin},new URL(e.page.origin).host),e.resolution===`outdated`?G(`span`,{class:`badge`},this.t(`outdated`)):null),...l(e)),f=[];if(this.tab===`mine`?this.mine?a.length?f.push(...a.map(u)):f.push(G(`div`,{class:`empty`},n?this.t(`noMatches`,{query:this.search.trim()}):this.t(`noYours`))):f.push(G(`div`,{class:`empty`},this.t(`loading`))):this.loaded?!a.length&&n?f.push(G(`div`,{class:`empty`},this.t(`noMatches`,{query:this.search.trim()}))):a.length?(f.push(...o.map(d)),s.length&&(f.push(G(`div`,{class:`section-label`},this.t(`notFoundHere`))),f.push(...s.map(d)))):f.push(G(`div`,{class:`empty`},this.tab===`open`?this.withKey(`noOpen`,`noOpenKey`):this.t(`noResolved`))):f.push(G(`div`,{class:`empty`},this.t(`loading`))),c.length&&this.tab!==`mine`){f.push(G(`div`,{class:`section-label`},this.t(`otherPages`)));for(let e of c.slice(0,20)){let t=ta(e.path,location);f.push(G(t===null?`div`:`a`,t===null?{class:`item`}:{class:`item`,href:t},G(`div`,{class:`row`},G(`span`,{class:`author`},e.path),G(`span`,{class:`spacer`}),G(`span`,{class:`badge`},this.t(`openOnPage`,{count:e.count})))))}}return G(`div`,{class:`panel`,role:`dialog`,"aria-label":this.t(`comments`)},G(`div`,{class:`panel-head`},G(`div`,{class:`panel-title`},this.t(`comments`)),G(`button`,{class:`btn btn-ghost btn-icon`,type:`button`,"aria-label":this.t(`close`),onclick:()=>this.togglePanel(!1)},K(J.close))),this.comments.length||this.mine?.length?G(`div`,{class:`panel-search`},K(J.search),G(`input`,{class:`field`,type:`search`,value:this.search,placeholder:this.t(`searchComments`),"aria-label":this.t(`searchComments`),"aria-controls":`nuni-panel-list`,"data-focus-key":`panel-search`,oninput:e=>{this.search=e.target.value,this.render()}})):null,G(`div`,{class:`tabs`,role:`tablist`,"aria-label":this.t(`comments`),onkeydown:e=>{let t=e.key;if(![`ArrowLeft`,`ArrowRight`,`Home`,`End`].includes(t))return;e.preventDefault();let n=Vi.indexOf(this.tab),r=Vi.length-1;this.tab=Vi[t===`Home`?0:t===`End`?r:t===`ArrowRight`?(n+1)%Vi.length:(n+r)%Vi.length],this.focusNext=`[data-focus-key="tab-${this.tab}"]`,this.render()}},Vi.map(n=>G(`button`,{class:`tab`,role:`tab`,type:`button`,id:`nuni-tab-${n}`,"data-focus-key":`tab-${n}`,"aria-selected":String(this.tab===n),"aria-controls":`nuni-panel-list`,tabindex:this.tab===n?0:-1,onclick:()=>{this.tab=n,this.render()}},n===`open`?this.t(`tabOpen`,{count:e.length}):n===`resolved`?this.t(`tabResolved`,{count:t.length}):this.mine?this.t(`tabYours`,{count:this.mine.length}):this.t(`yours`)))),G(`div`,{class:`panel-list`,id:`nuni-panel-list`,role:`tabpanel`,"aria-labelledby":`nuni-tab-${this.tab}`},...f),this.status&&!this.status.claimed&&!this.isOwner?this.renderPanelFooter():null)}renderPanelFooter(){return G(`div`,{class:`panel-foot`},G(`div`,{class:`row`},G(`span`,{class:`meta`},this.t(`ownSite`)),G(`span`,{class:`spacer`}),G(`button`,{class:`btn`,type:`button`,onclick:()=>this.openClaim()},K(J.github),this.t(`claim`))))}renderComposer(e,t){let n=!this.name,r=G(`span`,{class:`avatar cmp-avatar`,"aria-hidden":`true`}),i=e=>{let t=e.trim();r.classList.toggle(`avatar-empty`,!t),t?(r.textContent=bi(t),r.style.background=xi(t)):(r.replaceChildren(K(J.user)),r.style.background=``)},a=G(`input`,{class:`cmp-name`,placeholder:this.t(`yourName`),value:this.name,maxlength:b.nameMaxLength,autocomplete:`name`,"data-focus-key":`name`,"aria-label":this.t(`yourName`)}),o=e.suggestFrom??null,s=!!e.suggesting&&o!==null,c=G(`textarea`,{class:`cmp-text`,placeholder:this.t(s?`addNote`:`leaveComment`),maxlength:b.bodyMaxLength,rows:3,"data-focus-key":`body`,"aria-label":this.t(`comment`)}),l=s?G(`textarea`,{class:`cmp-suggest`,maxlength:b.quoteMaxLength,rows:1,"data-focus-key":`suggestion`,"aria-label":this.t(`newText`)}):null;l&&(l.value=e.suggestion??o??``);let u=()=>!!c.value.trim()||!!(l&&l.value.trim()&&l.value.trim()!==o),d=this.uiLayer.querySelector(`[data-focus-key="body"]`);d&&(c.value=d.value);let f=this.uiLayer.querySelector(`[data-focus-key="name"]`);f&&(a.value=f.value),i(n?a.value:this.name),a.addEventListener(`input`,()=>i(a.value));let p=G(`span`,{class:`cmp-count`,"aria-live":`polite`}),m=G(`button`,{class:`cmp-post`,type:`submit`,disabled:!!e.sending||!u()},e.sending?this.t(`posting`):this.t(`post`),K(J.arrowUp)),h=()=>{m.disabled=!!e.sending||!u();let t=b.bodyMaxLength-c.value.length;p.textContent=t<=b.bodyMaxLength*.1?this.t(`charsLeft`,{count:t}):``;for(let e of[c,l])e&&(e.style.height=`auto`,e.style.height=`${e.scrollHeight+2}px`)};c.addEventListener(`input`,()=>{h(),this.positionCard()}),l?.addEventListener(`input`,()=>{e.suggestion=l.value,h(),this.positionCard()}),requestAnimationFrame(()=>{c.isConnected&&(h(),this.positionCard())});let g=()=>void this.submitDraft(e,c.value,n?a.value:this.name);for(let e of[c,l])e?.addEventListener(`keydown`,e=>{e.key===`Enter`&&(e.metaKey||e.ctrlKey)&&(e.preventDefault(),g())});let _=this.canAttach(e),v=_?G(`input`,{type:`file`,accept:gi.join(`,`),multiple:!0,hidden:!0,tabindex:-1,"aria-hidden":`true`,onchange:t=>{let n=t.target,r=[...n.files??[]];n.value=``,this.addImages(e,r)}}):null;_&&c.addEventListener(`paste`,t=>{let n=[...t.clipboardData?.files??[]].filter(e=>gi.includes(e.type));n.length&&(t.preventDefault(),this.addImages(e,n))});let y=t=>{e.suggesting=t,e.error=void 0,this.render();let n=this.uiLayer.querySelector(`[data-focus-key="${t?`suggestion`:`body`}"]`);n?.focus(),t&&n?.select()};return G(`form`,{class:`${t} composer`,"data-card":`composer`,onsubmit:e=>{e.preventDefault(),g()}},G(`div`,{class:`cmp-head`},r,n?a:G(`span`,{class:`author`},this.name),G(`span`,{class:`spacer`}),n?null:G(`button`,{class:`cmp-link`,type:`button`,onclick:()=>{this.name=``,this.render(),this.focusComposer()}},this.t(`notYou`))),s?G(`div`,{class:`suggest`},G(`div`,{class:`suggest-label`},this.t(`suggestedEdit`),G(`span`,{class:`spacer`}),G(`button`,{class:`cmp-link`,type:`button`,onclick:()=>y(!1)},this.t(`removeSuggestion`))),G(`del`,{},o),l):e.anchor.quote?G(`blockquote`,{class:`quote`},e.anchor.quote.exact):null,c,e.images?.length?G(`div`,{class:`cmp-images`},G(`div`,{class:`cmp-thumbs`},...e.images.map((t,n)=>G(`div`,{class:`cmp-thumb`},G(`img`,{src:t.url,alt:this.t(`imageN`,{n:n+1})}),G(`button`,{class:`cmp-thumb-remove`,type:`button`,"aria-label":this.t(`removeImage`,{n:n+1}),title:this.t(`removeImage`,{n:n+1}),onclick:()=>{URL.revokeObjectURL(t.url),e.images?.splice(n,1),this.render(),this.positionCard()}},K(J.close))))),G(`p`,{class:`cmp-images-note`},this.t(`imagesPublic`))):null,e.error?G(`div`,{class:`error cmp-error`,role:`alert`},e.error):null,G(`div`,{class:`cmp-foot`},G(`span`,{class:`cmp-keys`,title:this.t(`send`,{key:this.i18n.mod})},G(`kbd`,{},this.i18n.mod),G(`kbd`,{},`↵`)),o!==null&&!s?G(`button`,{class:`cmp-link cmp-suggest-btn`,type:`button`,onclick:()=>y(!0)},K(J.edit),this.t(`suggestEdit`)):null,_?G(`button`,{class:`icon-btn`,type:`button`,"aria-label":this.t(`addImage`),title:this.t(`addImage`),onclick:()=>v?.click()},K(J.image)):null,_&&this.canScreenshot(e)?G(`button`,{class:`icon-btn`,type:`button`,"aria-label":this.t(`markUpScreenshot`),title:this.t(e.preparingMarkup?`preparingScreenshot`:`markUpScreenshot`),disabled:!!e.preparingMarkup,onclick:()=>void this.markUpScreenshot(e)},K(J.pen)):null,v,p,G(`span`,{class:`spacer`}),m),G(`button`,{class:`icon-btn cmp-close`,type:`button`,"aria-label":this.t(`cancel`),title:this.t(`cancel`),onclick:()=>this.closeCard()},K(J.close)))}renderCard(){let e=this.card;if(!e)return null;let t=`card${window.matchMedia(Yi).matches?` sheet`:``}`;if(e.kind===`composer`)return this.renderComposer(e.draft,t);let n=this.comments.find(t=>t._id===e.id);if(!n)return null;let r=this.isMine(n),i=this.isOwner,a=this.placements.get(n._id),o;if(e.editing){let t=G(`textarea`,{class:`field`,maxlength:b.bodyMaxLength,placeholder:n.suggestion?this.t(`addNote`):null,"data-focus-key":`edit`,"aria-label":this.t(`comment`)}),r=this.uiLayer.querySelector(`[data-focus-key="edit"]`);t.value=r?r.value:n.body;let i=n.suggestion?G(`textarea`,{class:`field`,rows:2,maxlength:b.quoteMaxLength,"data-focus-key":`edit-suggestion`,"aria-label":this.t(`newText`)}):null;if(i&&n.suggestion){let e=this.uiLayer.querySelector(`[data-focus-key="edit-suggestion"]`);i.value=e?e.value:n.suggestion.after}o=G(`div`,{class:`card-body`},n.suggestion&&i?G(`div`,{class:`suggest`},G(`div`,{class:`suggest-label`},this.t(`suggestedEdit`)),G(`del`,{},n.suggestion.before),i):null,t,G(`div`,{class:`row`},G(`span`,{class:`spacer`}),G(`button`,{class:`btn btn-ghost`,type:`button`,onclick:()=>{e.editing=!1,this.render()}},this.t(`cancel`)),G(`button`,{class:`btn btn-primary`,type:`button`,disabled:!!e.busy,onclick:()=>this.saveEdit(n,t.value,i?.value)},this.t(`save`))))}else{let t=[n.status===`resolved`?G(`span`,{class:`badge badge-ok`},K(J.check),this.t(n.resolution===`outdated`?`outdated`:`resolved`)):null,n.page.origin===location.origin?null:G(`span`,{class:`badge`,title:this.t(`leftOn`,{origin:n.page.origin})},new URL(n.page.origin).host),a?.confidence===`low`?G(`span`,{class:`badge`,title:this.t(`approximateHint`)},this.t(`approximate`)):null,a?.element?null:G(`span`,{class:`badge`,title:this.t(`originallyOn`,{text:n.anchor.text||n.anchor.tag})},this.t(`notFound`))].filter(e=>e!==null),s=i&&!(this.ownerDetailLoaded&&this.ownerDetailId===n._id),c=n.status===`resolved`;o=G(`div`,{class:`card-body msg`},G(`div`,{class:`card-head`},Qi(n.authorName),G(`span`,{class:`author`},n.authorName),G(`span`,{class:`meta`},this.i18n.timeAgo(n.createdAt)+(n.editedAt?` · ${this.t(`edited`)}`:``)),G(`span`,{class:`spacer`}),i?G(`button`,{class:`icon-btn${c?` is-resolved`:``}`,type:`button`,"aria-label":this.t(c?`reopen`:`resolve`),title:this.t(c?`reopen`:`resolve`),disabled:!!e.busy,onclick:()=>c?this.reopenComment(n):this.resolveComment(n)},K(J.check)):null,G(`button`,{class:`icon-btn card-close`,type:`button`,"aria-label":this.t(`close`),title:this.t(`close`),onclick:()=>this.closeCard()},K(J.close))),G(`div`,{class:`msg-main`},n.suggestion?zi(n.suggestion,this.t(`suggestedEdit`),i?this.copyNewTextButton(n.suggestion.after):null):n.anchor.quote?G(`blockquote`,{class:`quote`},n.anchor.quote.exact):null,n.body?G(`div`,{class:`comment-body`},n.body):null,this.threadId===n._id&&this.thread?.images?.length?G(`div`,{class:`images`},...this.thread.images.map((e,t)=>G(`a`,{href:e,target:`_blank`,rel:`noreferrer`,title:this.t(`openImage`)},G(`img`,{src:e,alt:this.t(`imageN`,{n:t+1}),loading:`lazy`})))):null,this.ownerDetail?._id===n._id&&this.ownerDetail.screenshotUrl?G(`a`,{class:`shot`,href:this.ownerDetail.screenshotUrl,target:`_blank`,rel:`noreferrer`,title:this.t(`openScreenshot`)},G(`img`,{src:this.ownerDetail.screenshotUrl,alt:this.t(`screenshotTaken`)})):null,t.length?G(`div`,{class:`badges`},...t):null,i&&!c&&!a?.element?G(`div`,{class:`lost`},G(`p`,{},this.t(`lostHint`)),G(`div`,{class:`row`},G(`button`,{class:`btn`,type:`button`,onclick:()=>this.startMovePin(n)},K(J.target),this.t(`movePin`)),G(`button`,{class:`btn btn-ghost`,type:`button`,disabled:!!e.busy,onclick:()=>this.closeAsOutdated(n)},this.t(`closeOutdated`)))):null,G(`div`,{class:`msg-foot`},this.renderReactions(n,n._id),G(`span`,{class:`spacer`}),G(`button`,{class:`icon-btn`,type:`button`,"aria-label":this.t(`copyForAgent`),title:s?this.t(`loadingContext`):this.t(`copyForAgentHint`),disabled:s,onclick:()=>this.copyForAgent(n)},K(J.bot)),i&&a?.element?G(`button`,{class:`icon-btn`,type:`button`,"aria-label":this.t(`movePin`),title:this.t(`movePin`),onclick:()=>this.startMovePin(n)},K(J.target)):null,r?G(`button`,{class:`icon-btn`,type:`button`,"aria-label":this.t(`edit`),title:this.t(`edit`),onclick:()=>{e.editing=!0,this.render()}},K(J.edit)):null,r||i?G(`button`,{class:`icon-btn icon-btn-danger`,type:`button`,"aria-label":this.t(`delete`),title:this.t(`delete`),"data-focus-key":`delete`,disabled:!!e.busy,onclick:()=>void this.deleteComment(n)},K(J.trash)):null),e.error?G(`div`,{class:`error`,role:`alert`},e.error):null))}return G(`div`,{class:t,"data-card":`thread`,role:`dialog`,"aria-label":this.t(`commentBy`,{name:n.authorName})},o,e.editing?null:this.renderThread(n))}renderReactions(e,t,n=!0){let r=this.card;if(r?.kind!==`thread`)return null;let i=this.threadId===e._id&&this.thread?this.thread.reactions.filter(e=>e.targetId===t):[],a=r.picker===t;return!n&&!i.length&&!a?null:G(`div`,{class:`reactions`},...i.map(n=>{let r=n.authorKeyHashes.includes(this.secretHash);return G(`button`,{class:`reaction`,type:`button`,"aria-pressed":String(r),"aria-label":`${n.emoji} ${n.count}${r?`, including you`:``}`,onclick:()=>this.toggleReaction(e,t,n.emoji)},`${n.emoji} ${n.count}`)}),n?this.reactionAdd(t,`reaction reaction-add`):null,a?G(`div`,{class:`reaction-picker`,role:`group`,"aria-label":this.t(`reactions`)},...ee.map(n=>G(`button`,{class:`reaction`,type:`button`,"aria-label":this.t(`reactWith`,{emoji:n}),onclick:()=>{r.picker=null,this.toggleReaction(e,t,n),this.render()}},n))):null)}reactionAdd(e,t){let n=this.card;if(n?.kind!==`thread`)return null;let r=n.picker===e;return G(`button`,{class:t,type:`button`,"aria-label":this.t(`addReaction`),"aria-expanded":String(r),title:this.t(`addReaction`),onclick:()=>{n.picker=r?null:e,this.render()}},K(J.smile))}renderThread(e){let t=this.card;if(t?.kind!==`thread`)return null;let n=this.threadId===e._id?this.thread?.replies??[]:[],r=this.isOwner,i=n.map(n=>{let i=this.isMyReply(n);if(t.replyEditing===n._id){let r=G(`textarea`,{class:`field`,maxlength:b.bodyMaxLength,"data-focus-key":`reply-edit-${n._id}`,"aria-label":this.t(`editReply`)}),i=this.uiLayer.querySelector(`[data-focus-key="reply-edit-${n._id}"]`);return r.value=i?i.value:n.body,G(`div`,{class:`reply`},r,G(`div`,{class:`row`},G(`span`,{class:`spacer`}),G(`button`,{class:`btn btn-ghost`,type:`button`,onclick:()=>{t.replyEditing=void 0,this.render()}},this.t(`cancel`)),G(`button`,{class:`btn btn-primary`,type:`button`,disabled:!!t.busy,onclick:()=>this.saveReplyEdit(e,n,r.value)},this.t(`save`))))}return G(`div`,{class:`reply msg`,"data-reply":n._id},G(`div`,{class:`card-head`},Qi(n.authorName),G(`span`,{class:`author`},n.authorName),n.isOwner?G(`span`,{class:`badge badge-owner`},this.t(`owner`)):null,G(`span`,{class:`meta`},this.i18n.timeAgo(n.createdAt)+(n.editedAt?` · ${this.t(`edited`)}`:``)),G(`span`,{class:`spacer`}),G(`span`,{class:`msg-tools`},this.reactionAdd(n._id,`icon-btn`),i?G(`button`,{class:`icon-btn`,type:`button`,"aria-label":this.t(`editReply`),title:this.t(`edit`),onclick:()=>{t.replyEditing=n._id,this.render()}},K(J.edit)):null,i||r?G(`button`,{class:`icon-btn icon-btn-danger`,type:`button`,"aria-label":this.t(`deleteReply`),title:this.t(`delete`),"data-focus-key":`delete-${n._id}`,disabled:!!t.busy,onclick:()=>void this.deleteReply(e,n)},K(J.trash)):null)),G(`div`,{class:`msg-main`},G(`div`,{class:`comment-body`},n.body),this.renderReactions(e,n._id,!1)))}),a=!r&&!this.name,o=G(`input`,{class:`reply-name`,placeholder:this.t(`yourName`),value:this.name,maxlength:b.nameMaxLength,autocomplete:`name`,"data-focus-key":`reply-name`,"aria-label":this.t(`yourName`)}),s=this.uiLayer.querySelector(`[data-focus-key="reply-name"]`);s&&(o.value=s.value);let c=G(`textarea`,{class:`reply-text`,placeholder:n.length?this.t(`reply`):this.t(`replyFirst`),maxlength:b.bodyMaxLength,rows:1,"data-focus-key":`reply`,"aria-label":this.t(`reply`)}),l=this.uiLayer.querySelector(`[data-focus-key="reply"]`);l&&(c.value=l.value);let u=G(`button`,{class:`reply-send`,type:`submit`,"aria-label":this.t(`sendReply`),title:this.t(`sendReply`),disabled:!!t.sendingReply||!c.value.trim()},K(J.arrowUp)),d=()=>{u.disabled=!!t.sendingReply||!c.value.trim(),c.style.height=`auto`,c.style.height=`${c.scrollHeight}px`};c.addEventListener(`input`,d),requestAnimationFrame(()=>{c.isConnected&&d()});let f=()=>void this.sendReply(e,c.value,a?o.value:this.name);return c.addEventListener(`keydown`,e=>{e.key===`Enter`&&(e.metaKey||e.ctrlKey)&&(e.preventDefault(),f())}),G(`div`,{class:`thread`},i.length?G(`div`,{class:`replies`,role:`list`,"aria-label":this.t(`replyCount`,{count:i.length})},...i.map(e=>(e.setAttribute(`role`,`listitem`),e))):null,G(`form`,{class:`reply-form`,onsubmit:e=>{e.preventDefault(),f()}},a?o:null,G(`div`,{class:`reply-row`},c,u)))}positionCard(){let e=this.uiLayer.querySelector(`[data-card]`);if(!e||e.classList.contains(`sheet`))return;let t=null;if(this.card?.kind===`composer`){let{draft:e}=this.card;t=this.anchorPoint(e.anchor,e.element,e.range)}else if(this.card?.kind===`thread`){let e=this.comments.find(e=>this.card?.kind===`thread`&&e._id===this.card.id);t=e?this.pinPositions.get(e._id)??this.pinPoint(e):null}let n=e.offsetWidth||320,r=e.offsetHeight||160,i=window.innerWidth,a=window.innerHeight,o,s;if(t)o=t.x+36,s=t.y-28,o+n>i-12&&(o=t.x-n-12);else{let{position:e}=this;o=e.endsWith(`left`)?16:e.endsWith(`center`)?(i-n)/2:i-n-16,s=e.startsWith(`top`)?72:a-r-72}o=Math.max(12,Math.min(o,i-n-12)),s=Math.max(12,Math.min(s,a-r-12)),e.style.left=`${Math.round(o)}px`,e.style.top=`${Math.round(s)}px`}focusComposer(){requestAnimationFrame(()=>{this.uiLayer.querySelector(this.name?`[data-focus-key="body"]`:`[data-focus-key="name"]`)?.focus()})}};function ra(e,t){let n=window.innerWidth,r=e<n/3?`left`:e>n*2/3?`right`:`center`;return`${t<window.innerHeight/2?`top`:`bottom`}-${r}`}function ia(e){let t=e.composedPath()[0];if(!(t instanceof Element))return!1;let n=document.documentElement;if(t===n)return e.clientX>=n.clientWidth||e.clientY>=n.clientHeight;if(!(t.scrollHeight>t.clientHeight||t.scrollWidth>t.clientWidth))return!1;let r=t.getBoundingClientRect();return e.clientX-r.left-t.clientLeft>=t.clientWidth||e.clientY-r.top-t.clientTop>=t.clientHeight}function aa(e){let t=[e.convexUrl,e.convexSiteUrl].flatMap(e=>{try{return[new URL(e).origin]}catch{return[]}});return e=>{try{return t.includes(new URL(e,location.href).origin)}catch{return!1}}}let Z=null;function oa(e,t){let n={destroy(){}};if(typeof window>`u`||typeof document>`u`)return n;if(!v(e.project))return console.warn(`[nuni] "${e.project}" is not a valid project ID. Run \`npx @nuniapp/cli@latest init\` to get one.`),n;if(Z?.project===e.project)return sa(Z);Z&&ca(Z);let r=S(e),i={project:e.project,widget:null,collectors:ge(r.capture,aa(r)),timer:0,handles:0};Z=i;let a=()=>{if(Z===i){if(!document.body){i.timer=window.setTimeout(a,50);return}i.widget=new na(r,{collectors:i.collectors,loadScreenshot:r.capture.screenshot?t.loadScreenshot:null}),i.widget.start()}},o=window.requestIdleCallback;return o?o(a,{timeout:1500}):i.timer=window.setTimeout(a,1),sa(i)}function sa(e){e.handles++;let t=!1;return{destroy(){t||(t=!0,e.handles--,e.handles<=0&&Z===e&&ca(e))}}}function ca(e){clearTimeout(e.timer),e.widget?.destroy(),e.widget=null,e.collectors.stop(),Z===e&&(Z=null)}let la=document.currentScript??document.querySelector(`script[data-project][src*='nuni']`),ua=null;function da(){return ua??(ua=new Promise(e=>{if(window.__nuniScreenshot)return e(window.__nuniScreenshot);let t=document.createElement(`script`);t.src=new URL(`nuni-screenshot.global.js`,la.src).href,t.async=!0,t.onload=()=>e(window.__nuniScreenshot??null),t.onerror=()=>{ua=null,e(null)},document.head.appendChild(t)})),ua}function fa(e){return oa(e,{loadScreenshot:la?.src?da:null})}window.Nuni={init:fa,version:`0.1.10`};function Q(e){if(e!==void 0)return!/^(false|0|off|no)$/i.test(e.trim())}let $=la?.dataset;$?.project&&fa({project:$.project,convexUrl:$.convexUrl,convexSiteUrl:$.convexSiteUrl,appUrl:$.appUrl,pageKey:$.pageKey,position:$.position,accentColor:$.accentColor,theme:$.theme,label:$.label,hotkey:$.hotkey===void 0?void 0:Q($.hotkey)!==!1&&$.hotkey,zIndex:$.zIndex===void 0?void 0:Number($.zIndex),locale:$.locale,images:Q($.images),capture:{console:Q($.captureConsole),network:Q($.captureNetwork),dom:Q($.captureDom),screenshot:Q($.captureScreenshot)}})})();
@@ -1485,7 +1485,7 @@ const captureScreenshot = async (el, options) => {
1485
1485
  return encodeCanvas(canvas, LIMITS.screenshotMaxBytes);
1486
1486
  };
1487
1487
  //#endregion
1488
- //#region src/tools.ts
1488
+ //#region src/screenshot-tools.ts
1489
1489
  /**
1490
1490
  * The code loaded on demand once someone comments (a separate chunk for npm
1491
1491
  * users, a separate script for the CDN build): taking the screenshot and
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nuniapp/widget",
3
- "version": "0.1.9",
3
+ "version": "0.1.10",
4
4
  "description": "Pin comments to anything on your site. Talk it through with your team.",
5
5
  "license": "MIT",
6
6
  "type": "module",