@aceshooting/lyra-ui 8.0.0 → 8.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/CHANGELOG.md +199 -17
  2. package/custom-elements.json +1 -1
  3. package/dist/components/agent-tools/mcp-app/mcp-app.class.js +1 -1
  4. package/dist/components/agent-tools/terminal/terminal.class.js +2 -2
  5. package/dist/components/agent-tools/tool-param-form/tool-param-form.class.d.ts +5 -0
  6. package/dist/components/agent-tools/tool-param-form/tool-param-form.class.js +1 -1
  7. package/dist/components/charts/chart/chart.class.js +1 -1
  8. package/dist/components/conversation/selection-toolbar/selection-toolbar.class.d.ts +5 -0
  9. package/dist/components/conversation/selection-toolbar/selection-toolbar.class.js +1 -1
  10. package/dist/components/conversation/widget-renderer/widget-renderer.class.js +1 -1
  11. package/dist/components/data/data-grid/data-grid.class.js +1 -1
  12. package/dist/components/data/flow-minimap/flow-minimap.class.js +1 -1
  13. package/dist/components/data/graph-query-builder/graph-query-builder.class.d.ts +4 -0
  14. package/dist/components/data/graph-query-builder/graph-query-builder.class.js +1 -1
  15. package/dist/components/data/query-builder/query-builder.class.js +2 -2
  16. package/dist/components/data/table/table.class.js +2 -2
  17. package/dist/components/data/table/table.styles.js +8 -3
  18. package/dist/components/data/tree/tree-item.styles.js +11 -3
  19. package/dist/components/data/tree/tree.class.d.ts +11 -0
  20. package/dist/components/data/tree/tree.class.js +1 -1
  21. package/dist/components/forms/checkbox-group/checkbox-group.class.d.ts +3 -0
  22. package/dist/components/forms/checkbox-group/checkbox-group.class.js +1 -1
  23. package/dist/components/forms/icon-button/icon-button.class.js +1 -1
  24. package/dist/components/forms/locale-picker/locale-picker.class.d.ts +3 -0
  25. package/dist/components/forms/locale-picker/locale-picker.class.js +4 -3
  26. package/dist/components/forms/locale-picker/locale-picker.styles.js +4 -0
  27. package/dist/components/forms/radio/radio-group.class.d.ts +3 -0
  28. package/dist/components/forms/radio/radio-group.class.js +1 -1
  29. package/dist/components/forms/rubric-form/rubric-form.class.d.ts +3 -0
  30. package/dist/components/forms/rubric-form/rubric-form.class.js +1 -1
  31. package/dist/components/forms/switch/switch.styles.js +9 -0
  32. package/dist/components/media/attachment-chip/attachment-chip.class.js +2 -2
  33. package/dist/components/media/avatar/avatar.class.js +2 -2
  34. package/dist/components/media/flag/flag.class.js +2 -2
  35. package/dist/components/retrieval/entity-card/entity-card.class.js +1 -1
  36. package/dist/components/retrieval/knowledge-graph-explorer/knowledge-graph-explorer.class.js +1 -1
  37. package/dist/components/utility/icon/icon.class.js +1 -1
  38. package/dist/components/viewers/archive-viewer/archive-viewer.class.js +1 -1
  39. package/dist/components/viewers/ebook-viewer/ebook-viewer.class.js +1 -1
  40. package/dist/components/viewers/notebook-viewer/notebook-viewer.class.js +3 -2
  41. package/dist/components/viewers/page-rail/page-rail.class.js +2 -0
  42. package/dist/components/viewers/spreadsheet-viewer/spreadsheet-viewer.class.js +1 -1
  43. package/dist/internal/anchor-target.js +1 -1
  44. package/dist/internal/package-metadata.d.ts +1 -1
  45. package/dist/internal/package-metadata.js +1 -1
  46. package/dist/internal/safe-svg.d.ts +13 -0
  47. package/dist/internal/safe-svg.js +1 -0
  48. package/dist/testing/happy-dom-shims.d.ts +4 -0
  49. package/dist/testing/happy-dom-shims.js +1 -1
  50. package/llms/components/lr-attachment-chip.md +18 -10
  51. package/llms/components/lr-checkbox-group.md +2 -0
  52. package/llms/components/lr-graph-query-builder.md +3 -1
  53. package/llms/components/lr-locale-picker.md +6 -4
  54. package/llms/components/lr-radio-group.md +3 -1
  55. package/llms/components/lr-rubric-form.md +2 -0
  56. package/llms/components/lr-tool-param-form.md +3 -0
  57. package/llms/peers.md +3 -3
  58. package/llms-full.txt +36 -15
  59. package/package.json +9 -8
  60. package/vscode-html-data.json +7 -7
  61. package/web-types.json +8 -8
@@ -1,4 +1,4 @@
1
- var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3?target:desc===null?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if(typeof Reflect==="object"&&typeof Reflect.decorate==="function")r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;i>=0;i--)if(d=decorators[i])r=(c<3?d(r):c>3?d(target,key,r):d(target,key))||r;return c>3&&r&&Object.defineProperty(target,key,r),r};import{html,nothing}from"lit";import{property,state}from"lit/decorators.js";import{createRef,ref}from"lit/directives/ref.js";import{LyraElement}from"../../../internal/lyra-element.js";import{isAbortError,isResourceLimitError,LyraUserFacingError,readResponseArrayBuffer,resolveOwnerFetchTarget}from"../../../internal/resource-loader.js";import{getNumberFormat}from"../../../internal/intl-cache.js";import{chevronIcon}from"../../../internal/icons.js";import{srOnly}from"../../../internal/a11y.js";import{Announcer}from"../../../internal/announcer.js";import{announceSearchResult}from"../../../internal/viewer-search.js";import{DocumentAnchorTarget}from"../../../internal/anchor-target.js";import{getEpubJs}from"./ebook-loader.js";import{assertEpubArchiveWithinLimits}from"./epub-resource-guard.js";import{styles}from"./ebook-viewer.styles.js";import{ViewerAnnouncementController}from"../viewer-announcements.js";import{LYRA_DEFAULT_anchorJumped,LYRA_DEFAULT_anchorJumpedToPage,LYRA_DEFAULT_anchorNotFound,LYRA_DEFAULT_collapse,LYRA_DEFAULT_details,LYRA_DEFAULT_documentPreviewEmpty,LYRA_DEFAULT_documentPreviewResourceTooLarge,LYRA_DEFAULT_documentPreviewTypeDocument,LYRA_DEFAULT_documentPreviewUrlNotAllowed,LYRA_DEFAULT_ebookViewerLoadError,LYRA_DEFAULT_ebookViewerNextChapter,LYRA_DEFAULT_ebookViewerPreviousChapter,LYRA_DEFAULT_ebookViewerRegionLabel,LYRA_DEFAULT_loading,LYRA_DEFAULT_loadingDocument,LYRA_DEFAULT_next,LYRA_DEFAULT_open,LYRA_DEFAULT_previous,LYRA_DEFAULT_viewerSearchActiveMatch,LYRA_DEFAULT_viewerSearchMatchCount,LYRA_DEFAULT_viewerSearchNoMatches}from"../../../internal/default-strings.generated.js";const MAX_TOC_ITEMS=1e4;const MAX_TOC_DEPTH=100;const MAX_SEARCH_MATCHES=1e4;const TONE_FILL_TOKEN={accent:{token:"--lr-color-brand-quiet",fallback:"#ddf4ff"},success:{token:"--lr-color-success-quiet",fallback:"#dafbe1"},warning:{token:"--lr-color-warning-quiet",fallback:"#fff8c5"},danger:{token:"--lr-color-danger-quiet",fallback:"#ffebe9"},neutral:{token:"--lr-color-surface-raised",fallback:"#f6f8fa"}};const SEARCH_MATCH_FILL_TOKEN={token:"--lr-color-warning",fallback:"#9a6700"};class LyraEbookViewerBase extends LyraElement{}class LyraEbookViewer extends DocumentAnchorTarget(LyraEbookViewerBase){constructor(){super(...arguments);this.src="";this.name="";this.accessibleLabel="";this.location="";this.anchorKinds=["cfi","text-quote"];this.ebookState={kind:"idle"};this.searchMatches=[];this.searchActiveIndex=-1;this.mountRef=createRef();this.generation=0;this.searchQuery="";this.searchGeneration=0;this.anchorOperationGeneration=0;this.paintedHighlightCfis=[];this.announcements=new ViewerAnnouncementController(this);this.announcer=new Announcer({onFlush:text=>this.announcements.announcePolite(text)});this.previous=()=>{this.runRenditionNavigation("previous")};this.next=()=>{this.runRenditionNavigation("next")}}static{this.defaultStrings={...super.defaultStrings,anchorJumped:LYRA_DEFAULT_anchorJumped,anchorJumpedToPage:LYRA_DEFAULT_anchorJumpedToPage,anchorNotFound:LYRA_DEFAULT_anchorNotFound,collapse:LYRA_DEFAULT_collapse,details:LYRA_DEFAULT_details,documentPreviewEmpty:LYRA_DEFAULT_documentPreviewEmpty,documentPreviewResourceTooLarge:LYRA_DEFAULT_documentPreviewResourceTooLarge,documentPreviewTypeDocument:LYRA_DEFAULT_documentPreviewTypeDocument,documentPreviewUrlNotAllowed:LYRA_DEFAULT_documentPreviewUrlNotAllowed,ebookViewerLoadError:LYRA_DEFAULT_ebookViewerLoadError,ebookViewerNextChapter:LYRA_DEFAULT_ebookViewerNextChapter,ebookViewerPreviousChapter:LYRA_DEFAULT_ebookViewerPreviousChapter,ebookViewerRegionLabel:LYRA_DEFAULT_ebookViewerRegionLabel,loading:LYRA_DEFAULT_loading,loadingDocument:LYRA_DEFAULT_loadingDocument,next:LYRA_DEFAULT_next,open:LYRA_DEFAULT_open,previous:LYRA_DEFAULT_previous,viewerSearchActiveMatch:LYRA_DEFAULT_viewerSearchActiveMatch,viewerSearchMatchCount:LYRA_DEFAULT_viewerSearchMatchCount,viewerSearchNoMatches:LYRA_DEFAULT_viewerSearchNoMatches}}static{this.styles=[LyraElement.styles,styles,srOnly]}updated(changed){super.updated(changed);this.announcements.transition("load",this.ebookState.kind,this.ebookState.kind==="error"?this.ebookState.message:this.localize("loadingDocument"));if(changed.has("src"))this.scheduleAfterUpdate(()=>{void this.load()});if(changed.has("location")){const fromRelocated=this.relocatedLocation===this.location;this.relocatedLocation=void 0;if(!fromRelocated&&this.rendition&&this.location)this.displayLocation(this.location)}if((changed.has("highlights")||changed.has("activeHighlightId"))&&this.rendition){this.repaintHighlights()}}connectedCallback(){super.connectedCallback();const ownerWindow=this.ownerDocument.defaultView;if(ownerWindow)this.announcer.setTimerHost(ownerWindow);this.announcements.connect();if(this.hasUpdated&&this.src.trim())this.scheduleAfterUpdate(()=>{void this.load()})}disconnectedCallback(){this.generation++;this.anchorOperationGeneration++;this.announcer.cancel();this.announcements.disconnect();this.teardown();this.ebookState={kind:"idle"};super.disconnectedCallback()}adoptedCallback(){const ownerWindow=this.ownerDocument.defaultView;if(ownerWindow)this.announcer.setTimerHost(ownerWindow);this.announcements.adopted()}teardown(){this.book?.destroy();this.book=void 0;this.rendition=void 0;this.searchGeneration++;this.searchQuery="";this.searchMatches=[];this.searchActiveIndex=-1;this.searchAnnotationCfi=void 0;this.paintedHighlightCfis=[]}async load(){const generation=++this.generation;const signal=this.beginAbortableLoad();this.teardown();if(!this.src.trim()){this.ebookState={kind:"idle"};return}const fetchTarget=resolveOwnerFetchTarget(this,this.src);if(!fetchTarget){this.failWithLocalizedMessage(this.localize("documentPreviewUrlNotAllowed"));return}this.ebookState={kind:"loading"};let data;let factory;try{[data,factory]=await Promise.all([fetchTarget.view.fetch(fetchTarget.url,signal?{signal}:void 0).then(response=>{if(!response.ok)throw new Error(`${response.status} ${response.statusText}`);return readResponseArrayBuffer(response)}),getEpubJs()]);if(!this.isConnected||generation!==this.generation)return;await assertEpubArchiveWithinLimits(data,void 0,void 0,{signal});if(!this.isConnected||generation!==this.generation)return}catch(error){if(isAbortError(error)||!this.isConnected||generation!==this.generation)return;this.ebookState={kind:"error",message:this.localize(isResourceLimitError(error)?"documentPreviewResourceTooLarge":"ebookViewerLoadError")};this.emit("lr-render-error",{error});return}if(!factory){this.failWithLocalizedMessage(this.localize("ebookViewerLoadError"));return}const mount=this.mountRef.value;if(!mount){this.failWithLocalizedMessage(this.localize("ebookViewerLoadError"));return}let candidateBook;try{const book=factory(data);candidateBook=book;const rendition=book.renderTo(mount,{width:"100%",height:"100%"});await book.ready;if(!this.isConnected||generation!==this.generation){book.destroy();return}await rendition.display(this.location||void 0);if(!this.isConnected||generation!==this.generation){book.destroy();return}rendition.on("relocated",loc=>{const cfi=loc?.start?.cfi??"";const href=loc?.start?.href??"";if(!cfi||cfi===this.location)return;this.relocatedLocation=cfi;this.location=cfi;this.emit("lr-location-change",{cfi,href})});rendition.on("selected",(cfiRange,contents)=>{const selection=contents?.window?.getSelection?.();const text=selection?String(selection.toString()):"";if(!text.trim())return;const rects=selection&&selection.rangeCount>0?Array.from(selection.getRangeAt(0).getClientRects()):[];this.emit("lr-text-select",{text,anchor:{kind:"cfi",cfi:cfiRange},rects})});this.book=book;this.rendition=rendition;candidateBook=void 0;this.ebookState={kind:"ready"};this.repaintHighlights()}catch(error){candidateBook?.destroy();if(isAbortError(error)||!this.isConnected||generation!==this.generation)return;this.ebookState={kind:"error",message:this.localize("ebookViewerLoadError")};this.emit("lr-render-error",{error})}}failWithLocalizedMessage(message){const error=new LyraUserFacingError(message);this.ebookState={kind:"error",message};this.emit("lr-render-error",{error})}reportRenditionFailure(error,rendition,generation){if(!this.isConnected||generation!==this.generation||rendition!==this.rendition)return;this.ebookState={kind:"error",message:this.localize("ebookViewerLoadError")};this.emit("lr-render-error",{error})}displayLocation(location){const rendition=this.rendition;if(!rendition)return;const generation=this.generation;try{void Promise.resolve(rendition.display(location)).catch(error=>{this.reportRenditionFailure(error,rendition,generation)})}catch(error){this.reportRenditionFailure(error,rendition,generation)}}runRenditionNavigation(action){const rendition=this.rendition;if(!rendition)return;const generation=this.generation;try{const task=action==="previous"?rendition.prev():rendition.next();void Promise.resolve(task).catch(error=>{this.reportRenditionFailure(error,rendition,generation)})}catch(error){this.reportRenditionFailure(error,rendition,generation)}}async getToc(){const book=this.book;if(!book)return[];await book.ready;if(this.book!==book)return[];const items=[];const seen=new WeakSet;const stack=(book.navigation?.toc??[]).map(entry=>({entry,level:1})).reverse();while(stack.length>0&&items.length<MAX_TOC_ITEMS){const current=stack.pop();const{entry,level}=current;if(!entry||typeof entry!=="object"||seen.has(entry))continue;seen.add(entry);items.push({id:entry.id||entry.href,label:String(entry.label??"").trim(),href:entry.href,level});if(level>=MAX_TOC_DEPTH||!Array.isArray(entry.subitems))continue;for(let index=entry.subitems.length-1;index>=0;index--){stack.push({entry:entry.subitems[index],level:level+1})}}return items}async scrollToAnchor(target){const operation=++this.anchorOperationGeneration;try{return await super.scrollToAnchor(target)}catch(error){if(operation!==this.anchorOperationGeneration)return false;const rendition=this.rendition;if(rendition)this.reportRenditionFailure(error,rendition,this.generation);this.emit("lr-anchor-result",{found:false});return false}}async applyAnchor(anchor){const rendition=this.rendition;const operation=this.anchorOperationGeneration;if(!rendition)return false;if(anchor.kind==="cfi"){if(operation!==this.anchorOperationGeneration||rendition!==this.rendition)return false;await rendition.display(anchor.cfi);return operation===this.anchorOperationGeneration&&rendition===this.rendition}if(anchor.kind==="text-quote"){const cfi=await this.findTextQuoteCfi(anchor.quote);if(!cfi)return false;if(operation!==this.anchorOperationGeneration||rendition!==this.rendition)return false;await rendition.display(cfi);return operation===this.anchorOperationGeneration&&rendition===this.rendition}return false}async findTextQuoteCfi(quote){const book=this.book;const generation=this.generation;if(!book)return null;const spineItems=book.spine?.spineItems??[];for(const item of spineItems){let loaded=false;try{await item.load(book.load?.bind(book));loaded=true;if(!this.isConnected||generation!==this.generation||this.book!==book)return null;const results=await item.find(quote)??[];if(!this.isConnected||generation!==this.generation||this.book!==book)return null;if(results.length)return results[0].cfi}catch{continue}finally{if(loaded)item.unload()}}return null}repaintHighlights(){if(!this.rendition)return;for(const cfi of this.paintedHighlightCfis)this.rendition.annotations.remove(cfi,"highlight");this.paintedHighlightCfis=[];for(const highlight of this.highlights){if(highlight.anchor.kind!=="cfi")continue;const cfi=highlight.anchor.cfi;const tone=highlight.tone??"accent";this.rendition.annotations.highlight(cfi,{id:highlight.id},()=>this.emit("lr-highlight-activate",{id:highlight.id}),`lr-hl-${tone}`,this.resolveHighlightFill(TONE_FILL_TOKEN[tone]));this.paintedHighlightCfis.push(cfi)}}async search(query){const generation=++this.searchGeneration;this.searchQuery=query;this.clearSearchAnnotation();if(!this.book||!query.trim()){this.searchMatches=[];this.searchActiveIndex=-1;this.emitSearchChange();return 0}const matches=[];const book=this.book;const spineItems=book.spine?.spineItems??[];for(const item of spineItems){if(generation!==this.searchGeneration)return this.searchMatches.length;let loaded=false;try{await item.load(book.load?.bind(book));loaded=true;if(generation!==this.searchGeneration||this.book!==book)return this.searchMatches.length;const results=await item.find(query)??[];if(generation!==this.searchGeneration||this.book!==book)return this.searchMatches.length;for(const r of results){if(matches.length>=MAX_SEARCH_MATCHES)break;matches.push({cfi:r.cfi,excerpt:r.excerpt??""})}}catch{continue}finally{if(loaded)item.unload()}if(matches.length>=MAX_SEARCH_MATCHES)break}if(generation!==this.searchGeneration)return this.searchMatches.length;this.searchMatches=matches;this.searchActiveIndex=matches.length>0?0:-1;this.emitSearchChange();if(this.searchActiveIndex>=0)await this.showSearchMatch(this.searchActiveIndex,generation);return matches.length}async searchNext(){if(!this.searchMatches.length)return false;const generation=++this.searchGeneration;this.searchActiveIndex=(this.searchActiveIndex+1)%this.searchMatches.length;this.emitSearchChange();return this.showSearchMatch(this.searchActiveIndex,generation)}async searchPrevious(){if(!this.searchMatches.length)return false;const generation=++this.searchGeneration;this.searchActiveIndex=(this.searchActiveIndex-1+this.searchMatches.length)%this.searchMatches.length;this.emitSearchChange();return this.showSearchMatch(this.searchActiveIndex,generation)}clearSearch(){this.searchGeneration++;this.searchQuery="";this.searchMatches=[];this.searchActiveIndex=-1;this.clearSearchAnnotation();this.emit("lr-search-change",{query:"",matchCount:0,activeIndex:-1})}clearSearchAnnotation(){if(this.searchAnnotationCfi)this.rendition?.annotations.remove(this.searchAnnotationCfi,"highlight");this.searchAnnotationCfi=void 0}async showSearchMatch(index,generation=this.searchGeneration){const match=this.searchMatches[index];const rendition=this.rendition;if(!match||!rendition||generation!==this.searchGeneration)return false;this.clearSearchAnnotation();try{await rendition.display(match.cfi)}catch(error){if(generation===this.searchGeneration&&rendition===this.rendition){this.reportRenditionFailure(error,rendition,this.generation)}return false}if(generation!==this.searchGeneration||rendition!==this.rendition||this.searchMatches[index]!==match)return false;try{rendition.annotations.highlight(match.cfi,{},void 0,"lr-ebook-search",this.resolveHighlightFill(SEARCH_MATCH_FILL_TOKEN))}catch(error){this.reportRenditionFailure(error,rendition,this.generation);return false}this.searchAnnotationCfi=match.cfi;return true}emitSearchChange(){this.emit("lr-search-change",{query:this.searchQuery,matchCount:this.searchMatches.length,activeIndex:this.searchActiveIndex});const numberFormat=getNumberFormat(this.effectiveLocale);announceSearchResult((key,fallback,values)=>this.localize(key,fallback,values?Object.fromEntries(Object.entries(values).map(([name,value])=>[name,typeof value==="number"?numberFormat.format(value):value])):void 0),this.announcer,this.searchMatches.length,this.searchActiveIndex)}resolveHighlightFill({token,fallback}){const value=this.ownerDocument.defaultView?.getComputedStyle(this).getPropertyValue(token).trim()??"";return{fill:value||fallback}}renderStatus(){if(this.ebookState.kind==="loading"){return html`<p class="status-note">${this.localize("loadingDocument")}</p>`}if(this.ebookState.kind==="error")return html`<div part="error">${this.ebookState.message}</div>`;if(this.ebookState.kind==="idle"){return html`<p class="status-note">${this.localize("documentPreviewEmpty",void 0,{type:this.localize("documentPreviewTypeDocument")})}</p>`}return nothing}render(){const disabled=this.ebookState.kind!=="ready";return html`
1
+ var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3?target:desc===null?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if(typeof Reflect==="object"&&typeof Reflect.decorate==="function")r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;i>=0;i--)if(d=decorators[i])r=(c<3?d(r):c>3?d(target,key,r):d(target,key))||r;return c>3&&r&&Object.defineProperty(target,key,r),r};import{html,nothing}from"lit";import{property,state}from"lit/decorators.js";import{createRef,ref}from"lit/directives/ref.js";import{LyraElement}from"../../../internal/lyra-element.js";import{isAbortError,isResourceLimitError,LyraUserFacingError,readResponseArrayBuffer,resolveOwnerFetchTarget}from"../../../internal/resource-loader.js";import{getNumberFormat}from"../../../internal/intl-cache.js";import{chevronIcon}from"../../../internal/icons.js";import{srOnly}from"../../../internal/a11y.js";import{Announcer}from"../../../internal/announcer.js";import{announceSearchResult}from"../../../internal/viewer-search.js";import{DocumentAnchorTarget}from"../../../internal/anchor-target.js";import{getEpubJs}from"./ebook-loader.js";import{assertEpubArchiveWithinLimits}from"./epub-resource-guard.js";import{styles}from"./ebook-viewer.styles.js";import{ViewerAnnouncementController}from"../viewer-announcements.js";import{LYRA_DEFAULT_anchorJumped,LYRA_DEFAULT_anchorJumpedToPage,LYRA_DEFAULT_anchorNotFound,LYRA_DEFAULT_collapse,LYRA_DEFAULT_details,LYRA_DEFAULT_documentPreviewEmpty,LYRA_DEFAULT_documentPreviewResourceTooLarge,LYRA_DEFAULT_documentPreviewTypeDocument,LYRA_DEFAULT_documentPreviewUrlNotAllowed,LYRA_DEFAULT_ebookViewerLoadError,LYRA_DEFAULT_ebookViewerNextChapter,LYRA_DEFAULT_ebookViewerPreviousChapter,LYRA_DEFAULT_ebookViewerRegionLabel,LYRA_DEFAULT_loading,LYRA_DEFAULT_loadingDocument,LYRA_DEFAULT_next,LYRA_DEFAULT_open,LYRA_DEFAULT_previous,LYRA_DEFAULT_viewerSearchActiveMatch,LYRA_DEFAULT_viewerSearchMatchCount,LYRA_DEFAULT_viewerSearchNoMatches}from"../../../internal/default-strings.generated.js";const MAX_TOC_ITEMS=1e4;const MAX_TOC_DEPTH=100;const MAX_SEARCH_MATCHES=1e4;const TONE_FILL_TOKEN={accent:{token:"--lr-color-brand-quiet",fallback:"#ddf4ff"},success:{token:"--lr-color-success-quiet",fallback:"#dafbe1"},warning:{token:"--lr-color-warning-quiet",fallback:"#fff8c5"},danger:{token:"--lr-color-danger-quiet",fallback:"#ffebe9"},neutral:{token:"--lr-color-surface-raised",fallback:"#f6f8fa"}};const SEARCH_MATCH_FILL_TOKEN={token:"--lr-color-warning",fallback:"#9a6700"};class LyraEbookViewerBase extends LyraElement{}class LyraEbookViewer extends DocumentAnchorTarget(LyraEbookViewerBase){constructor(){super(...arguments);this.src="";this.name="";this.accessibleLabel="";this.location="";this.anchorKinds=["cfi","text-quote"];this.ebookState={kind:"idle"};this.searchMatches=[];this.searchActiveIndex=-1;this.mountRef=createRef();this.generation=0;this.searchQuery="";this.searchGeneration=0;this.anchorOperationGeneration=0;this.paintedHighlightCfis=[];this.announcements=new ViewerAnnouncementController(this);this.announcer=new Announcer({onFlush:text=>this.announcements.announcePolite(text)});this.previous=()=>{this.runRenditionNavigation("previous")};this.next=()=>{this.runRenditionNavigation("next")}}static{this.defaultStrings={...super.defaultStrings,anchorJumped:LYRA_DEFAULT_anchorJumped,anchorJumpedToPage:LYRA_DEFAULT_anchorJumpedToPage,anchorNotFound:LYRA_DEFAULT_anchorNotFound,collapse:LYRA_DEFAULT_collapse,details:LYRA_DEFAULT_details,documentPreviewEmpty:LYRA_DEFAULT_documentPreviewEmpty,documentPreviewResourceTooLarge:LYRA_DEFAULT_documentPreviewResourceTooLarge,documentPreviewTypeDocument:LYRA_DEFAULT_documentPreviewTypeDocument,documentPreviewUrlNotAllowed:LYRA_DEFAULT_documentPreviewUrlNotAllowed,ebookViewerLoadError:LYRA_DEFAULT_ebookViewerLoadError,ebookViewerNextChapter:LYRA_DEFAULT_ebookViewerNextChapter,ebookViewerPreviousChapter:LYRA_DEFAULT_ebookViewerPreviousChapter,ebookViewerRegionLabel:LYRA_DEFAULT_ebookViewerRegionLabel,loading:LYRA_DEFAULT_loading,loadingDocument:LYRA_DEFAULT_loadingDocument,next:LYRA_DEFAULT_next,open:LYRA_DEFAULT_open,previous:LYRA_DEFAULT_previous,viewerSearchActiveMatch:LYRA_DEFAULT_viewerSearchActiveMatch,viewerSearchMatchCount:LYRA_DEFAULT_viewerSearchMatchCount,viewerSearchNoMatches:LYRA_DEFAULT_viewerSearchNoMatches}}static{this.styles=[LyraElement.styles,styles,srOnly]}updated(changed){super.updated(changed);this.announcements.transition("load",this.ebookState.kind,this.ebookState.kind==="error"?this.ebookState.message:this.localize("loadingDocument"));if(changed.has("src"))this.scheduleAfterUpdate(()=>{void this.load()});if(changed.has("location")){const fromRelocated=this.relocatedLocation===this.location;this.relocatedLocation=void 0;if(!fromRelocated&&this.rendition&&this.location)this.displayLocation(this.location)}if((changed.has("highlights")||changed.has("activeHighlightId"))&&this.rendition){this.repaintHighlights()}}connectedCallback(){super.connectedCallback();const ownerWindow=this.ownerDocument.defaultView;if(ownerWindow)this.announcer.setTimerHost(ownerWindow);this.announcements.connect();if(this.hasUpdated&&this.src.trim())this.scheduleAfterUpdate(()=>{void this.load()})}disconnectedCallback(){this.generation++;this.anchorOperationGeneration++;this.announcer.cancel();this.announcements.disconnect();this.teardown();this.ebookState={kind:"idle"};super.disconnectedCallback()}adoptedCallback(){const ownerWindow=this.ownerDocument.defaultView;if(ownerWindow)this.announcer.setTimerHost(ownerWindow);this.announcements.adopted()}teardown(){this.book?.destroy();this.book=void 0;this.rendition=void 0;this.searchGeneration++;this.searchQuery="";this.searchMatches=[];this.searchActiveIndex=-1;this.searchAnnotationCfi=void 0;this.paintedHighlightCfis=[]}async load(){const generation=++this.generation;const signal=this.beginAbortableLoad();this.teardown();if(!this.src.trim()){this.ebookState={kind:"idle"};return}const fetchTarget=resolveOwnerFetchTarget(this,this.src);if(!fetchTarget){this.failWithLocalizedMessage(this.localize("documentPreviewUrlNotAllowed"));return}this.ebookState={kind:"loading"};let data;let factory;try{[data,factory]=await Promise.all([fetchTarget.view.fetch(fetchTarget.url,signal?{signal}:void 0).then(response=>{if(!response.ok)throw new Error(`${response.status} ${response.statusText}`);return readResponseArrayBuffer(response)}),getEpubJs()]);if(!this.isConnected||generation!==this.generation)return;await assertEpubArchiveWithinLimits(data,void 0,void 0,{signal});if(!this.isConnected||generation!==this.generation)return}catch(error){if(isAbortError(error)||!this.isConnected||generation!==this.generation)return;this.ebookState={kind:"error",message:this.localize(isResourceLimitError(error)?"documentPreviewResourceTooLarge":"ebookViewerLoadError")};this.emit("lr-render-error",{error});return}if(!factory){this.failWithLocalizedMessage(this.localize("ebookViewerLoadError"));return}const mount=this.mountRef.value;if(!mount){this.failWithLocalizedMessage(this.localize("ebookViewerLoadError"));return}let candidateBook;try{const book=factory(data);candidateBook=book;const rendition=book.renderTo(mount,{width:"100%",height:"100%"});await book.ready;if(!this.isConnected||generation!==this.generation){book.destroy();return}await rendition.display(this.location||void 0);if(!this.isConnected||generation!==this.generation){book.destroy();return}rendition.on("relocated",loc=>{const cfi=loc?.start?.cfi??"";const href=loc?.start?.href??"";if(!cfi||cfi===this.location)return;this.relocatedLocation=cfi;this.location=cfi;this.emit("lr-location-change",{cfi,href})});rendition.on("selected",(cfiRange,contents)=>{const selection=contents?.window?.getSelection?.();const text=selection?String(selection.toString()):"";if(!text.trim())return;const rects=selection&&selection.rangeCount>0?Array.from(selection.getRangeAt(0).getClientRects()):[];this.emit("lr-text-select",{text,anchor:{kind:"cfi",cfi:cfiRange},rects})});this.book=book;this.rendition=rendition;candidateBook=void 0;this.ebookState={kind:"ready"};this.repaintHighlights()}catch(error){candidateBook?.destroy();if(isAbortError(error)||!this.isConnected||generation!==this.generation)return;this.ebookState={kind:"error",message:this.localize("ebookViewerLoadError")};this.emit("lr-render-error",{error})}}failWithLocalizedMessage(message){const error=new LyraUserFacingError(message);this.ebookState={kind:"error",message};this.emit("lr-render-error",{error})}reportRenditionFailure(error,rendition,generation){if(!this.isConnected||generation!==this.generation||rendition!==this.rendition)return;this.ebookState={kind:"error",message:this.localize("ebookViewerLoadError")};this.emit("lr-render-error",{error})}displayLocation(location){const rendition=this.rendition;if(!rendition)return;const generation=this.generation;try{void Promise.resolve(rendition.display(location)).catch(error=>{this.reportRenditionFailure(error,rendition,generation)})}catch(error){this.reportRenditionFailure(error,rendition,generation)}}runRenditionNavigation(action){const rendition=this.rendition;if(!rendition)return;const generation=this.generation;try{const task=action==="previous"?rendition.prev():rendition.next();void Promise.resolve(task).catch(error=>{this.reportRenditionFailure(error,rendition,generation)})}catch(error){this.reportRenditionFailure(error,rendition,generation)}}async getToc(){const book=this.book;if(!book)return[];await book.ready;if(this.book!==book)return[];const items=[];const seen=new WeakSet;const stack=(book.navigation?.toc??[]).map(entry=>({entry,level:1})).reverse();while(stack.length>0&&items.length<MAX_TOC_ITEMS){const current=stack.pop();const{entry,level}=current;if(!entry||typeof entry!=="object"||seen.has(entry))continue;seen.add(entry);items.push({id:entry.id||entry.href,label:String(entry.label??"").trim(),href:entry.href,level});if(level>=MAX_TOC_DEPTH||!Array.isArray(entry.subitems))continue;for(let index=entry.subitems.length-1;index>=0;index--){stack.push({entry:entry.subitems[index],level:level+1})}}return items}async scrollToAnchor(target){const operation=++this.anchorOperationGeneration;try{const performScrollToAnchor=Object.getPrototypeOf(LyraEbookViewer.prototype).performScrollToAnchor;return await performScrollToAnchor.call(this,target)}catch(error){if(operation!==this.anchorOperationGeneration)return false;const rendition=this.rendition;if(rendition)this.reportRenditionFailure(error,rendition,this.generation);this.emit("lr-anchor-result",{found:false});return false}}async applyAnchor(anchor){const rendition=this.rendition;const operation=this.anchorOperationGeneration;if(!rendition)return false;if(anchor.kind==="cfi"){if(operation!==this.anchorOperationGeneration||rendition!==this.rendition)return false;await rendition.display(anchor.cfi);return operation===this.anchorOperationGeneration&&rendition===this.rendition}if(anchor.kind==="text-quote"){const cfi=await this.findTextQuoteCfi(anchor.quote);if(!cfi)return false;if(operation!==this.anchorOperationGeneration||rendition!==this.rendition)return false;await rendition.display(cfi);return operation===this.anchorOperationGeneration&&rendition===this.rendition}return false}async findTextQuoteCfi(quote){const book=this.book;const generation=this.generation;if(!book)return null;const spineItems=book.spine?.spineItems??[];for(const item of spineItems){let loaded=false;try{await item.load(book.load?.bind(book));loaded=true;if(!this.isConnected||generation!==this.generation||this.book!==book)return null;const results=await item.find(quote)??[];if(!this.isConnected||generation!==this.generation||this.book!==book)return null;if(results.length)return results[0].cfi}catch{continue}finally{if(loaded)item.unload()}}return null}repaintHighlights(){if(!this.rendition)return;for(const cfi of this.paintedHighlightCfis)this.rendition.annotations.remove(cfi,"highlight");this.paintedHighlightCfis=[];for(const highlight of this.highlights){if(highlight.anchor.kind!=="cfi")continue;const cfi=highlight.anchor.cfi;const tone=highlight.tone??"accent";this.rendition.annotations.highlight(cfi,{id:highlight.id},()=>this.emit("lr-highlight-activate",{id:highlight.id}),`lr-hl-${tone}`,this.resolveHighlightFill(TONE_FILL_TOKEN[tone]));this.paintedHighlightCfis.push(cfi)}}async search(query){const generation=++this.searchGeneration;this.searchQuery=query;this.clearSearchAnnotation();if(!this.book||!query.trim()){this.searchMatches=[];this.searchActiveIndex=-1;this.emitSearchChange();return 0}const matches=[];const book=this.book;const spineItems=book.spine?.spineItems??[];for(const item of spineItems){if(generation!==this.searchGeneration)return this.searchMatches.length;let loaded=false;try{await item.load(book.load?.bind(book));loaded=true;if(generation!==this.searchGeneration||this.book!==book)return this.searchMatches.length;const results=await item.find(query)??[];if(generation!==this.searchGeneration||this.book!==book)return this.searchMatches.length;for(const r of results){if(matches.length>=MAX_SEARCH_MATCHES)break;matches.push({cfi:r.cfi,excerpt:r.excerpt??""})}}catch{continue}finally{if(loaded)item.unload()}if(matches.length>=MAX_SEARCH_MATCHES)break}if(generation!==this.searchGeneration)return this.searchMatches.length;this.searchMatches=matches;this.searchActiveIndex=matches.length>0?0:-1;this.emitSearchChange();if(this.searchActiveIndex>=0)await this.showSearchMatch(this.searchActiveIndex,generation);return matches.length}async searchNext(){if(!this.searchMatches.length)return false;const generation=++this.searchGeneration;this.searchActiveIndex=(this.searchActiveIndex+1)%this.searchMatches.length;this.emitSearchChange();return this.showSearchMatch(this.searchActiveIndex,generation)}async searchPrevious(){if(!this.searchMatches.length)return false;const generation=++this.searchGeneration;this.searchActiveIndex=(this.searchActiveIndex-1+this.searchMatches.length)%this.searchMatches.length;this.emitSearchChange();return this.showSearchMatch(this.searchActiveIndex,generation)}clearSearch(){this.searchGeneration++;this.searchQuery="";this.searchMatches=[];this.searchActiveIndex=-1;this.clearSearchAnnotation();this.emit("lr-search-change",{query:"",matchCount:0,activeIndex:-1})}clearSearchAnnotation(){if(this.searchAnnotationCfi)this.rendition?.annotations.remove(this.searchAnnotationCfi,"highlight");this.searchAnnotationCfi=void 0}async showSearchMatch(index,generation=this.searchGeneration){const match=this.searchMatches[index];const rendition=this.rendition;if(!match||!rendition||generation!==this.searchGeneration)return false;this.clearSearchAnnotation();try{await rendition.display(match.cfi)}catch(error){if(generation===this.searchGeneration&&rendition===this.rendition){this.reportRenditionFailure(error,rendition,this.generation)}return false}if(generation!==this.searchGeneration||rendition!==this.rendition||this.searchMatches[index]!==match)return false;try{rendition.annotations.highlight(match.cfi,{},void 0,"lr-ebook-search",this.resolveHighlightFill(SEARCH_MATCH_FILL_TOKEN))}catch(error){this.reportRenditionFailure(error,rendition,this.generation);return false}this.searchAnnotationCfi=match.cfi;return true}emitSearchChange(){this.emit("lr-search-change",{query:this.searchQuery,matchCount:this.searchMatches.length,activeIndex:this.searchActiveIndex});const numberFormat=getNumberFormat(this.effectiveLocale);announceSearchResult((key,fallback,values)=>this.localize(key,fallback,values?Object.fromEntries(Object.entries(values).map(([name,value])=>[name,typeof value==="number"?numberFormat.format(value):value])):void 0),this.announcer,this.searchMatches.length,this.searchActiveIndex)}resolveHighlightFill({token,fallback}){const value=this.ownerDocument.defaultView?.getComputedStyle(this).getPropertyValue(token).trim()??"";return{fill:value||fallback}}renderStatus(){if(this.ebookState.kind==="loading"){return html`<p class="status-note">${this.localize("loadingDocument")}</p>`}if(this.ebookState.kind==="error")return html`<div part="error">${this.ebookState.message}</div>`;if(this.ebookState.kind==="idle"){return html`<p class="status-note">${this.localize("documentPreviewEmpty",void 0,{type:this.localize("documentPreviewTypeDocument")})}</p>`}return nothing}render(){const disabled=this.ebookState.kind!=="ready";return html`
2
2
  <div part="base" aria-busy=${this.ebookState.kind==="loading"?"true":"false"}>
3
3
  <div part="toolbar">
4
4
  <button part="previous-button" type="button" aria-label=${this.localize("ebookViewerPreviousChapter")} ?disabled=${disabled} @click=${this.previous}>
@@ -1,10 +1,10 @@
1
- var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3?target:desc===null?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if(typeof Reflect==="object"&&typeof Reflect.decorate==="function")r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;i>=0;i--)if(d=decorators[i])r=(c<3?d(r):c>3?d(target,key,r):d(target,key))||r;return c>3&&r&&Object.defineProperty(target,key,r),r};import{html,nothing}from"lit";import{property,query,state}from"lit/decorators.js";import{unsafeHTML}from"lit/directives/unsafe-html.js";import{unsafeSVG}from"lit/directives/unsafe-svg.js";import{styleMap}from"lit/directives/style-map.js";import{LyraElement}from"../../../internal/lyra-element.js";import{specialistTokens}from"../../../internal/specialist-tokens.styles.js";import{DocumentAnchorTarget}from"../../../internal/anchor-target.js";import{isAbortError,isResourceLimitError,LyraUserFacingError,readResponseText,resolveOwnerFetchTarget}from"../../../internal/resource-loader.js";import{srOnly}from"../../../internal/a11y.js";import{finiteCount}from"../../../internal/numbers.js";import{getNumberFormat}from"../../../internal/intl-cache.js";import{createAnsiParser}from"../../../internal/ansi.js";import{loadNotebookSanitizer}from"./dompurify-loader.js";import{styles}from"./notebook-viewer.styles.js";import{sanitizeCssLength}from"../../../internal/safe-css.js";import{ViewerAnnouncementController}from"../viewer-announcements.js";import{LYRA_DEFAULT_anchorJumped,LYRA_DEFAULT_anchorJumpedToPage,LYRA_DEFAULT_anchorNotFound,LYRA_DEFAULT_collapse,LYRA_DEFAULT_details,LYRA_DEFAULT_documentPreviewEmpty,LYRA_DEFAULT_documentPreviewFailedToLoad,LYRA_DEFAULT_documentPreviewResourceTooLarge,LYRA_DEFAULT_documentPreviewTypeDocument,LYRA_DEFAULT_documentPreviewUrlNotAllowed,LYRA_DEFAULT_documentViewerMissingSanitizer,LYRA_DEFAULT_loading,LYRA_DEFAULT_loadingDocument,LYRA_DEFAULT_notebookViewerCodeCell,LYRA_DEFAULT_notebookViewerCollapseOutput,LYRA_DEFAULT_notebookViewerErrorOutput,LYRA_DEFAULT_notebookViewerInPrompt,LYRA_DEFAULT_notebookViewerInPromptEmpty,LYRA_DEFAULT_notebookViewerInvalid,LYRA_DEFAULT_notebookViewerLabel,LYRA_DEFAULT_notebookViewerMarkdownCell,LYRA_DEFAULT_notebookViewerRawCell,LYRA_DEFAULT_notebookViewerShowAllOutput,LYRA_DEFAULT_notebookViewerTooManyCells,LYRA_DEFAULT_notebookViewerUnrenderedOutput,LYRA_DEFAULT_notebookViewerUnsupportedVersion,LYRA_DEFAULT_open}from"../../../internal/default-strings.generated.js";const MAX_CELLS=2e3;const MAX_OUTPUTS=2e4;const MAX_JSON_NODES=1e5;const SUPPORTED_MAJOR=4;const SUPPORTED_MINORS=[0,1,2,3,4,5];function joinSource(source){return Array.isArray(source)?source.join(""):source??""}function isDenseArray(value){for(let index=0;index<value.length;index++){if(!Object.prototype.hasOwnProperty.call(value,index))return false}return true}function joinText(text){if(typeof text==="string")return text;return Array.isArray(text)&&isDenseArray(text)&&text.every(item=>typeof item==="string")?text.join(""):""}function isTextValue(value){return typeof value==="string"||Array.isArray(value)&&isDenseArray(value)&&value.every(item=>typeof item==="string")}function isJsonValue(value){const pending=[value];let nodes=0;while(pending.length){const current=pending.pop();if(++nodes>MAX_JSON_NODES)return false;if(current===null||typeof current==="string"||typeof current==="boolean")continue;if(typeof current==="number"){if(!Number.isFinite(current))return false;continue}if(Array.isArray(current)){if(current.length>MAX_JSON_NODES-nodes-pending.length)return false;for(let index=current.length-1;index>=0;index--)pending.push(current[index]);continue}if(typeof current!=="object")return false;for(const key in current){if(!Object.prototype.hasOwnProperty.call(current,key))continue;if(pending.length>=MAX_JSON_NODES-nodes)return false;pending.push(current[key])}}return true}function isNotebookOutput(value){if(typeof value!=="object"||value===null)return false;const output=value;if(!["stream","error","display_data","execute_result"].includes(String(output["output_type"])))return false;if(output["text"]!==void 0&&!isTextValue(output["text"]))return false;if(output["traceback"]!==void 0&&!isTextValue(output["traceback"]))return false;if(output["ename"]!==void 0&&typeof output["ename"]!=="string")return false;if(output["evalue"]!==void 0&&typeof output["evalue"]!=="string")return false;if(output["name"]!==void 0&&output["name"]!=="stdout"&&output["name"]!=="stderr")return false;const data=output["data"];if(data===void 0)return true;if(typeof data!=="object"||data===null||Array.isArray(data))return false;const mimeData=data;for(const[mime,payload]of Object.entries(mimeData)){if(mime==="application/json"){if(typeof payload==="string"){try{if(!isJsonValue(JSON.parse(payload)))return false}catch{return false}}else if(!isJsonValue(payload))return false}else if(!isTextValue(payload)&&!isJsonValue(payload)){return false}}return true}function isNotebookShape(value){if(typeof value!=="object"||value===null)return false;const v=value;if(!Number.isInteger(v["nbformat"])||!Number.isInteger(v["nbformat_minor"])||!Array.isArray(v["cells"]))return false;const cells=v["cells"];let outputCount=0;for(let index=0;index<cells.length;index++){if(!Object.prototype.hasOwnProperty.call(cells,index))return false;const value2=cells[index];if(typeof value2!=="object"||value2===null)return false;const cell=value2;if(!["markdown","code","raw"].includes(String(cell["cell_type"])))return false;if(!isTextValue(cell["source"]))return false;if(cell["id"]!==void 0&&typeof cell["id"]!=="string")return false;if(cell["execution_count"]!==void 0&&cell["execution_count"]!==null&&(!Number.isInteger(cell["execution_count"])||cell["execution_count"]<0))return false;if(cell["outputs"]===void 0)continue;if(!Array.isArray(cell["outputs"]))return false;if(!isDenseArray(cell["outputs"]))return false;outputCount+=cell["outputs"].length;if(outputCount>MAX_OUTPUTS||!cell["outputs"].every(isNotebookOutput))return false}return true}class LyraNotebookViewerBase extends LyraElement{}class LyraNotebookViewer extends DocumentAnchorTarget(LyraNotebookViewerBase){constructor(){super(...arguments);this.src="";this.name="";this.outputCollapseLines=40;this.maxHeight="";this.anchorKinds=["node-path","fragment"];this.loadState={kind:"idle"};this.expandedOutputs=new Set;this.activeCellIndex=null;this.searchQuery="";this.searchMatches=[];this.activeSearchIndex=-1;this.generation=0;this.sanitizerGeneration=0;this.sanitizerFailureReported=false;this.announcements=new ViewerAnnouncementController(this);this.sanitizedOutputCache=new Map;this.sanitizationTasks=new Map;this.renderCell=(cell,index)=>{const c=cell;const numberFormat=getNumberFormat(this.effectiveLocale);const inCount=c.execution_count==null?this.localize("notebookViewerInPromptEmpty"):this.localize("notebookViewerInPrompt",void 0,{count:numberFormat.format(c.execution_count)});const rowLabel=c.cell_type==="code"?this.localize("notebookViewerCodeCell",void 0,{index:numberFormat.format(index+1)}):c.cell_type==="markdown"?this.localize("notebookViewerMarkdownCell",void 0,{index:numberFormat.format(index+1)}):this.localize("notebookViewerRawCell",void 0,{index:numberFormat.format(index+1)});const active=this.activeCellIndex===index;const part=active?"cell cell-active":"cell";return html`<div part=${part} role="group" aria-label=${rowLabel} data-cell-type=${c.cell_type} ?data-active=${active}>
1
+ var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3?target:desc===null?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if(typeof Reflect==="object"&&typeof Reflect.decorate==="function")r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;i>=0;i--)if(d=decorators[i])r=(c<3?d(r):c>3?d(target,key,r):d(target,key))||r;return c>3&&r&&Object.defineProperty(target,key,r),r};import{html,nothing}from"lit";import{property,query,state}from"lit/decorators.js";import{unsafeHTML}from"lit/directives/unsafe-html.js";import{unsafeSVG}from"lit/directives/unsafe-svg.js";import{styleMap}from"lit/directives/style-map.js";import{LyraElement}from"../../../internal/lyra-element.js";import{specialistTokens}from"../../../internal/specialist-tokens.styles.js";import{DocumentAnchorTarget}from"../../../internal/anchor-target.js";import{isAbortError,isResourceLimitError,LyraUserFacingError,readResponseText,resolveOwnerFetchTarget}from"../../../internal/resource-loader.js";import{srOnly}from"../../../internal/a11y.js";import{finiteCount}from"../../../internal/numbers.js";import{getNumberFormat}from"../../../internal/intl-cache.js";import{createAnsiParser}from"../../../internal/ansi.js";import{loadNotebookSanitizer}from"./dompurify-loader.js";import{styles}from"./notebook-viewer.styles.js";import{sanitizeCssColor,sanitizeCssLength}from"../../../internal/safe-css.js";import{ViewerAnnouncementController}from"../viewer-announcements.js";import{LYRA_DEFAULT_anchorJumped,LYRA_DEFAULT_anchorJumpedToPage,LYRA_DEFAULT_anchorNotFound,LYRA_DEFAULT_collapse,LYRA_DEFAULT_details,LYRA_DEFAULT_documentPreviewEmpty,LYRA_DEFAULT_documentPreviewFailedToLoad,LYRA_DEFAULT_documentPreviewResourceTooLarge,LYRA_DEFAULT_documentPreviewTypeDocument,LYRA_DEFAULT_documentPreviewUrlNotAllowed,LYRA_DEFAULT_documentViewerMissingSanitizer,LYRA_DEFAULT_loading,LYRA_DEFAULT_loadingDocument,LYRA_DEFAULT_notebookViewerCodeCell,LYRA_DEFAULT_notebookViewerCollapseOutput,LYRA_DEFAULT_notebookViewerErrorOutput,LYRA_DEFAULT_notebookViewerInPrompt,LYRA_DEFAULT_notebookViewerInPromptEmpty,LYRA_DEFAULT_notebookViewerInvalid,LYRA_DEFAULT_notebookViewerLabel,LYRA_DEFAULT_notebookViewerMarkdownCell,LYRA_DEFAULT_notebookViewerRawCell,LYRA_DEFAULT_notebookViewerShowAllOutput,LYRA_DEFAULT_notebookViewerTooManyCells,LYRA_DEFAULT_notebookViewerUnrenderedOutput,LYRA_DEFAULT_notebookViewerUnsupportedVersion,LYRA_DEFAULT_open}from"../../../internal/default-strings.generated.js";const MAX_CELLS=2e3;const MAX_OUTPUTS=2e4;const MAX_JSON_NODES=1e5;const SUPPORTED_MAJOR=4;const SUPPORTED_MINORS=[0,1,2,3,4,5];function joinSource(source){return Array.isArray(source)?source.join(""):source??""}function isDenseArray(value){for(let index=0;index<value.length;index++){if(!Object.prototype.hasOwnProperty.call(value,index))return false}return true}function joinText(text){if(typeof text==="string")return text;return Array.isArray(text)&&isDenseArray(text)&&text.every(item=>typeof item==="string")?text.join(""):""}function isTextValue(value){return typeof value==="string"||Array.isArray(value)&&isDenseArray(value)&&value.every(item=>typeof item==="string")}function isJsonValue(value){const pending=[value];let nodes=0;while(pending.length){const current=pending.pop();if(++nodes>MAX_JSON_NODES)return false;if(current===null||typeof current==="string"||typeof current==="boolean")continue;if(typeof current==="number"){if(!Number.isFinite(current))return false;continue}if(Array.isArray(current)){if(current.length>MAX_JSON_NODES-nodes-pending.length)return false;for(let index=current.length-1;index>=0;index--)pending.push(current[index]);continue}if(typeof current!=="object")return false;for(const key in current){if(!Object.prototype.hasOwnProperty.call(current,key))continue;if(pending.length>=MAX_JSON_NODES-nodes)return false;pending.push(current[key])}}return true}function isNotebookOutput(value){if(typeof value!=="object"||value===null)return false;const output=value;if(!["stream","error","display_data","execute_result"].includes(String(output["output_type"])))return false;if(output["text"]!==void 0&&!isTextValue(output["text"]))return false;if(output["traceback"]!==void 0&&!isTextValue(output["traceback"]))return false;if(output["ename"]!==void 0&&typeof output["ename"]!=="string")return false;if(output["evalue"]!==void 0&&typeof output["evalue"]!=="string")return false;if(output["name"]!==void 0&&output["name"]!=="stdout"&&output["name"]!=="stderr")return false;const data=output["data"];if(data===void 0)return true;if(typeof data!=="object"||data===null||Array.isArray(data))return false;const mimeData=data;for(const[mime,payload]of Object.entries(mimeData)){if(mime==="application/json"){if(typeof payload==="string"){try{if(!isJsonValue(JSON.parse(payload)))return false}catch{return false}}else if(!isJsonValue(payload))return false}else if(!isTextValue(payload)&&!isJsonValue(payload)){return false}}return true}function isNotebookShape(value){if(typeof value!=="object"||value===null)return false;const v=value;if(!Number.isInteger(v["nbformat"])||!Number.isInteger(v["nbformat_minor"])||!Array.isArray(v["cells"]))return false;const cells=v["cells"];let outputCount=0;for(let index=0;index<cells.length;index++){if(!Object.prototype.hasOwnProperty.call(cells,index))return false;const value2=cells[index];if(typeof value2!=="object"||value2===null)return false;const cell=value2;if(!["markdown","code","raw"].includes(String(cell["cell_type"])))return false;if(!isTextValue(cell["source"]))return false;if(cell["id"]!==void 0&&typeof cell["id"]!=="string")return false;if(cell["execution_count"]!==void 0&&cell["execution_count"]!==null&&(!Number.isInteger(cell["execution_count"])||cell["execution_count"]<0))return false;if(cell["outputs"]===void 0)continue;if(!Array.isArray(cell["outputs"]))return false;if(!isDenseArray(cell["outputs"]))return false;outputCount+=cell["outputs"].length;if(outputCount>MAX_OUTPUTS||!cell["outputs"].every(isNotebookOutput))return false}return true}class LyraNotebookViewerBase extends LyraElement{}class LyraNotebookViewer extends DocumentAnchorTarget(LyraNotebookViewerBase){constructor(){super(...arguments);this.src="";this.name="";this.outputCollapseLines=40;this.maxHeight="";this.anchorKinds=["node-path","fragment"];this.loadState={kind:"idle"};this.expandedOutputs=new Set;this.activeCellIndex=null;this.searchQuery="";this.searchMatches=[];this.activeSearchIndex=-1;this.generation=0;this.sanitizerGeneration=0;this.sanitizerFailureReported=false;this.announcements=new ViewerAnnouncementController(this);this.sanitizedOutputCache=new Map;this.sanitizationTasks=new Map;this.renderCell=(cell,index)=>{const c=cell;const numberFormat=getNumberFormat(this.effectiveLocale);const inCount=c.execution_count==null?this.localize("notebookViewerInPromptEmpty"):this.localize("notebookViewerInPrompt",void 0,{count:numberFormat.format(c.execution_count)});const rowLabel=c.cell_type==="code"?this.localize("notebookViewerCodeCell",void 0,{index:numberFormat.format(index+1)}):c.cell_type==="markdown"?this.localize("notebookViewerMarkdownCell",void 0,{index:numberFormat.format(index+1)}):this.localize("notebookViewerRawCell",void 0,{index:numberFormat.format(index+1)});const active=this.activeCellIndex===index;const part=active?"cell cell-active":"cell";return html`<div part=${part} role="group" aria-label=${rowLabel} data-cell-type=${c.cell_type} ?data-active=${active}>
2
2
  <div part="cell-gutter">${c.cell_type==="code"?inCount:""}</div>
3
3
  <div part="cell-source">
4
4
  ${c.cell_type==="markdown"?html`<lr-markdown .content=${joinSource(c.source)} escape-html sanitize></lr-markdown>`:c.cell_type==="code"?html`<lr-code-block .code=${joinSource(c.source)} language=${this.notebookLanguage()} line-numbers></lr-code-block>`:html`<pre part="raw-source" tabindex="0">${joinSource(c.source)}</pre>`}
5
5
  ${c.cell_type==="code"&&c.outputs?.length?html`<div part="outputs">${c.outputs.map((o,i)=>this.renderOutput(index,o,i))}</div>`:nothing}
6
6
  </div>
7
- </div>`}}static{this.defaultStrings={...super.defaultStrings,anchorJumped:LYRA_DEFAULT_anchorJumped,anchorJumpedToPage:LYRA_DEFAULT_anchorJumpedToPage,anchorNotFound:LYRA_DEFAULT_anchorNotFound,collapse:LYRA_DEFAULT_collapse,details:LYRA_DEFAULT_details,documentPreviewEmpty:LYRA_DEFAULT_documentPreviewEmpty,documentPreviewFailedToLoad:LYRA_DEFAULT_documentPreviewFailedToLoad,documentPreviewResourceTooLarge:LYRA_DEFAULT_documentPreviewResourceTooLarge,documentPreviewTypeDocument:LYRA_DEFAULT_documentPreviewTypeDocument,documentPreviewUrlNotAllowed:LYRA_DEFAULT_documentPreviewUrlNotAllowed,documentViewerMissingSanitizer:LYRA_DEFAULT_documentViewerMissingSanitizer,loading:LYRA_DEFAULT_loading,loadingDocument:LYRA_DEFAULT_loadingDocument,notebookViewerCodeCell:LYRA_DEFAULT_notebookViewerCodeCell,notebookViewerCollapseOutput:LYRA_DEFAULT_notebookViewerCollapseOutput,notebookViewerErrorOutput:LYRA_DEFAULT_notebookViewerErrorOutput,notebookViewerInPrompt:LYRA_DEFAULT_notebookViewerInPrompt,notebookViewerInPromptEmpty:LYRA_DEFAULT_notebookViewerInPromptEmpty,notebookViewerInvalid:LYRA_DEFAULT_notebookViewerInvalid,notebookViewerLabel:LYRA_DEFAULT_notebookViewerLabel,notebookViewerMarkdownCell:LYRA_DEFAULT_notebookViewerMarkdownCell,notebookViewerRawCell:LYRA_DEFAULT_notebookViewerRawCell,notebookViewerShowAllOutput:LYRA_DEFAULT_notebookViewerShowAllOutput,notebookViewerTooManyCells:LYRA_DEFAULT_notebookViewerTooManyCells,notebookViewerUnrenderedOutput:LYRA_DEFAULT_notebookViewerUnrenderedOutput,notebookViewerUnsupportedVersion:LYRA_DEFAULT_notebookViewerUnsupportedVersion,open:LYRA_DEFAULT_open}}static{this.styles=[LyraElement.styles,specialistTokens,styles,srOnly]}get notebook(){return this._notebook}set notebook(value){const old=this._notebook;this._notebook=value;this.requestUpdate("notebook",old);this.parseInline()}get effectiveOutputCollapseLines(){return finiteCount(this.outputCollapseLines,40)}updated(changed){super.updated(changed);this.announcements.transition("load",this.loadState.kind,this.loadState.kind==="error"?this.loadState.message:this.localize("loadingDocument"));if(changed.has("src")&&!this._notebook)this.scheduleAfterUpdate(()=>{void this.loadFromSrc()})}connectedCallback(){super.connectedCallback();this.announcements.connect();if(this.hasUpdated&&this.src&&this._notebook===void 0){this.scheduleAfterUpdate(()=>{void this.loadFromSrc()})}if(this.hasUpdated&&this._notebook!==void 0&&this.loadState.kind==="loaded"){this.requestUpdate()}}disconnectedCallback(){this.generation++;this.sanitizerGeneration++;this.beginAbortableLoad();this.sanitizedOutputCache.clear();this.sanitizationTasks.clear();this.sanitizerFailureReported=false;if(this._notebook===void 0)this.loadState={kind:"idle"};this.announcements.disconnect();super.disconnectedCallback()}adoptedCallback(){this.announcements.adopted()}parseInline(){if(this._notebook===void 0)return;const generation=++this.generation;try{const raw=typeof this._notebook==="string"?JSON.parse(this._notebook):this._notebook;this.setDoc(raw,generation)}catch(error){this.loadState={kind:"error",message:this.localize("notebookViewerInvalid")};this.emit("lr-render-error",{error})}}async loadFromSrc(){if(this._notebook!==void 0)return;const generation=++this.generation;const signal=this.beginAbortableLoad();if(!this.src){this.loadState={kind:"idle"};return}const fetchTarget=resolveOwnerFetchTarget(this,this.src);if(!fetchTarget){const error=new LyraUserFacingError(this.localize("documentPreviewUrlNotAllowed"));this.loadState={kind:"error",message:error.message};this.emit("lr-render-error",{error});return}this.loadState={kind:"loading"};try{const response=await fetchTarget.view.fetch(fetchTarget.url,signal?{signal}:void 0);if(!this.isConnected||generation!==this.generation)return;if(!response.ok)throw new Error(`${response.status} ${response.statusText}`);const text=await readResponseText(response);if(!this.isConnected||generation!==this.generation)return;this.setDoc(JSON.parse(text),generation)}catch(error){if(isAbortError(error)||!this.isConnected||generation!==this.generation)return;this.loadState={kind:"error",message:error instanceof LyraUserFacingError?error.message:this.localize(isResourceLimitError(error)?"documentPreviewResourceTooLarge":"documentPreviewFailedToLoad")};this.emit("lr-render-error",{error})}}setDoc(raw,generation){if(generation!==this.generation)return;if(!isNotebookShape(raw)){this.loadState={kind:"error",message:this.localize("notebookViewerInvalid")};this.emit("lr-render-error",{error:new Error("invalid notebook shape")});return}if(raw.nbformat!==SUPPORTED_MAJOR||!SUPPORTED_MINORS.includes(raw.nbformat_minor)){this.loadState={kind:"error",message:this.localize("notebookViewerUnsupportedVersion",void 0,{version:`${raw.nbformat}.${raw.nbformat_minor}`})};this.emit("lr-render-error",{error:new Error("unsupported nbformat version")});return}if(raw.cells.length>MAX_CELLS){this.loadState={kind:"error",message:this.localize("notebookViewerTooManyCells")};this.emit("lr-render-error",{error:new Error("too many cells")});return}this.sanitizerGeneration++;this.sanitizedOutputCache.clear();this.sanitizationTasks.clear();this.sanitizerFailureReported=false;this.expandedOutputs=new Set;this.clearSearchState();this.loadState={kind:"loaded",doc:raw};const language=raw.metadata?.language_info?.name??raw.metadata?.kernelspec?.language??"";this.emit("lr-load",{cellCount:raw.cells.length,language})}async applyAnchor(anchor){if(this.loadState.kind!=="loaded")return false;const cells=this.loadState.doc.cells;let index=-1;if(anchor.kind==="node-path"&&Number.isInteger(anchor.path[0]))index=anchor.path[0];else if(anchor.kind==="fragment")index=cells.findIndex(c=>c.id===anchor.id);else return false;if(index<0||index>=cells.length)return false;this.activeCellIndex=index;return true}async search(query2){const q=query2.trim().toLocaleLowerCase(this.effectiveLocale);this.searchQuery=query2;if(this.loadState.kind!=="loaded"||!q){this.searchMatches=[]}else{this.searchMatches=this.loadState.doc.cells.reduce((acc,cell,i)=>{const source=joinSource(cell.source).toLocaleLowerCase(this.effectiveLocale);const outputText=(cell.outputs??[]).map(o=>joinText(o.text)+Object.values(o.data??{}).map(joinText).join("")).join(" ").toLocaleLowerCase(this.effectiveLocale);if(source.includes(q)||outputText.includes(q))acc.push(i);return acc},[])}this.activeSearchIndex=this.searchMatches.length?0:-1;this.activateSearchMatch();this.emitSearchChange();return this.searchMatches.length}async searchNext(){if(!this.searchMatches.length)return false;this.activeSearchIndex=(this.activeSearchIndex+1)%this.searchMatches.length;this.activateSearchMatch();this.emitSearchChange();return true}async searchPrevious(){if(!this.searchMatches.length)return false;this.activeSearchIndex=(this.activeSearchIndex-1+this.searchMatches.length)%this.searchMatches.length;this.activateSearchMatch();this.emitSearchChange();return true}clearSearch(){this.clearSearchState();this.emitSearchChange()}clearSearchState(){this.searchQuery="";this.searchMatches=[];this.activeSearchIndex=-1}activateSearchMatch(){const index=this.searchMatches[this.activeSearchIndex];if(index===void 0)return;this.activeCellIndex=index;this.scheduleAfterUpdate(()=>{this.virtualListEl?.scrollToIndex(index,{align:"auto",behavior:"auto"})})}emitSearchChange(){this.emit("lr-search-change",{query:this.searchQuery,matchCount:this.searchMatches.length,activeIndex:this.activeSearchIndex})}toggleOutput(index){const next=new Set(this.expandedOutputs);if(next.has(index))next.delete(index);else next.add(index);this.expandedOutputs=next}renderAnsiText(text){const segments=createAnsiParser().push(text);return html`${segments.map(seg=>html`<span style=${styleMap(this.segmentStyle(seg.styles))}>${seg.text}</span>`)}`}segmentStyle(s){const fg=s.fg??"var(--lr-color-text)";const bg=s.bg??"transparent";return{"font-weight":s.bold?"bold":"normal",opacity:s.dim?"0.7":"1","font-style":s.italic?"italic":"normal","text-decoration":s.underline?"underline":"none",color:s.inverse?bg:fg,"background-color":s.inverse?fg:bg}}renderTextOutput(index,text,tone){const lines=text.split("\n");const outputCollapseLines=this.effectiveOutputCollapseLines;const collapsible=outputCollapseLines>0&&lines.length>outputCollapseLines;const expanded=this.expandedOutputs.has(index)||!collapsible;const shown=expanded?text:lines.slice(0,outputCollapseLines).join("\n");const part=tone==="danger"?"output output-error":"output";return html`<div part=${part} data-output-type="stream" data-stream=${tone==="danger"?"stderr":"stdout"}
7
+ </div>`}}static{this.defaultStrings={...super.defaultStrings,anchorJumped:LYRA_DEFAULT_anchorJumped,anchorJumpedToPage:LYRA_DEFAULT_anchorJumpedToPage,anchorNotFound:LYRA_DEFAULT_anchorNotFound,collapse:LYRA_DEFAULT_collapse,details:LYRA_DEFAULT_details,documentPreviewEmpty:LYRA_DEFAULT_documentPreviewEmpty,documentPreviewFailedToLoad:LYRA_DEFAULT_documentPreviewFailedToLoad,documentPreviewResourceTooLarge:LYRA_DEFAULT_documentPreviewResourceTooLarge,documentPreviewTypeDocument:LYRA_DEFAULT_documentPreviewTypeDocument,documentPreviewUrlNotAllowed:LYRA_DEFAULT_documentPreviewUrlNotAllowed,documentViewerMissingSanitizer:LYRA_DEFAULT_documentViewerMissingSanitizer,loading:LYRA_DEFAULT_loading,loadingDocument:LYRA_DEFAULT_loadingDocument,notebookViewerCodeCell:LYRA_DEFAULT_notebookViewerCodeCell,notebookViewerCollapseOutput:LYRA_DEFAULT_notebookViewerCollapseOutput,notebookViewerErrorOutput:LYRA_DEFAULT_notebookViewerErrorOutput,notebookViewerInPrompt:LYRA_DEFAULT_notebookViewerInPrompt,notebookViewerInPromptEmpty:LYRA_DEFAULT_notebookViewerInPromptEmpty,notebookViewerInvalid:LYRA_DEFAULT_notebookViewerInvalid,notebookViewerLabel:LYRA_DEFAULT_notebookViewerLabel,notebookViewerMarkdownCell:LYRA_DEFAULT_notebookViewerMarkdownCell,notebookViewerRawCell:LYRA_DEFAULT_notebookViewerRawCell,notebookViewerShowAllOutput:LYRA_DEFAULT_notebookViewerShowAllOutput,notebookViewerTooManyCells:LYRA_DEFAULT_notebookViewerTooManyCells,notebookViewerUnrenderedOutput:LYRA_DEFAULT_notebookViewerUnrenderedOutput,notebookViewerUnsupportedVersion:LYRA_DEFAULT_notebookViewerUnsupportedVersion,open:LYRA_DEFAULT_open}}static{this.styles=[LyraElement.styles,specialistTokens,styles,srOnly]}get notebook(){return this._notebook}set notebook(value){const old=this._notebook;this._notebook=value;this.requestUpdate("notebook",old);this.parseInline()}get effectiveOutputCollapseLines(){return finiteCount(this.outputCollapseLines,40)}updated(changed){super.updated(changed);this.announcements.transition("load",this.loadState.kind,this.loadState.kind==="error"?this.loadState.message:this.localize("loadingDocument"));if(changed.has("src")&&!this._notebook)this.scheduleAfterUpdate(()=>{void this.loadFromSrc()})}connectedCallback(){super.connectedCallback();this.announcements.connect();if(this.hasUpdated&&this.src&&this._notebook===void 0){this.scheduleAfterUpdate(()=>{void this.loadFromSrc()})}if(this.hasUpdated&&this._notebook!==void 0&&this.loadState.kind==="loaded"){this.requestUpdate()}}disconnectedCallback(){this.generation++;this.sanitizerGeneration++;this.beginAbortableLoad();this.sanitizedOutputCache.clear();this.sanitizationTasks.clear();this.sanitizerFailureReported=false;if(this._notebook===void 0)this.loadState={kind:"idle"};this.announcements.disconnect();super.disconnectedCallback()}adoptedCallback(){this.announcements.adopted()}parseInline(){if(this._notebook===void 0)return;const generation=++this.generation;try{const raw=typeof this._notebook==="string"?JSON.parse(this._notebook):this._notebook;this.setDoc(raw,generation)}catch(error){this.loadState={kind:"error",message:this.localize("notebookViewerInvalid")};this.emit("lr-render-error",{error})}}async loadFromSrc(){if(this._notebook!==void 0)return;const generation=++this.generation;const signal=this.beginAbortableLoad();if(!this.src){this.loadState={kind:"idle"};return}const fetchTarget=resolveOwnerFetchTarget(this,this.src);if(!fetchTarget){const error=new LyraUserFacingError(this.localize("documentPreviewUrlNotAllowed"));this.loadState={kind:"error",message:error.message};this.emit("lr-render-error",{error});return}this.loadState={kind:"loading"};try{const response=await fetchTarget.view.fetch(fetchTarget.url,signal?{signal}:void 0);if(!this.isConnected||generation!==this.generation)return;if(!response.ok)throw new Error(`${response.status} ${response.statusText}`);const text=await readResponseText(response);if(!this.isConnected||generation!==this.generation)return;this.setDoc(JSON.parse(text),generation)}catch(error){if(isAbortError(error)||!this.isConnected||generation!==this.generation)return;this.loadState={kind:"error",message:error instanceof LyraUserFacingError?error.message:this.localize(isResourceLimitError(error)?"documentPreviewResourceTooLarge":"documentPreviewFailedToLoad")};this.emit("lr-render-error",{error})}}setDoc(raw,generation){if(generation!==this.generation)return;if(!isNotebookShape(raw)){this.loadState={kind:"error",message:this.localize("notebookViewerInvalid")};this.emit("lr-render-error",{error:new Error("invalid notebook shape")});return}if(raw.nbformat!==SUPPORTED_MAJOR||!SUPPORTED_MINORS.includes(raw.nbformat_minor)){this.loadState={kind:"error",message:this.localize("notebookViewerUnsupportedVersion",void 0,{version:`${raw.nbformat}.${raw.nbformat_minor}`})};this.emit("lr-render-error",{error:new Error("unsupported nbformat version")});return}if(raw.cells.length>MAX_CELLS){this.loadState={kind:"error",message:this.localize("notebookViewerTooManyCells")};this.emit("lr-render-error",{error:new Error("too many cells")});return}this.sanitizerGeneration++;this.sanitizedOutputCache.clear();this.sanitizationTasks.clear();this.sanitizerFailureReported=false;this.expandedOutputs=new Set;this.clearSearchState();this.loadState={kind:"loaded",doc:raw};const language=raw.metadata?.language_info?.name??raw.metadata?.kernelspec?.language??"";this.emit("lr-load",{cellCount:raw.cells.length,language})}async applyAnchor(anchor){if(this.loadState.kind!=="loaded")return false;const cells=this.loadState.doc.cells;let index=-1;if(anchor.kind==="node-path"&&Number.isInteger(anchor.path[0]))index=anchor.path[0];else if(anchor.kind==="fragment")index=cells.findIndex(c=>c.id===anchor.id);else return false;if(index<0||index>=cells.length)return false;this.activeCellIndex=index;return true}async search(query2){const q=query2.trim().toLocaleLowerCase(this.effectiveLocale);this.searchQuery=query2;if(this.loadState.kind!=="loaded"||!q){this.searchMatches=[]}else{this.searchMatches=this.loadState.doc.cells.reduce((acc,cell,i)=>{const source=joinSource(cell.source).toLocaleLowerCase(this.effectiveLocale);const outputText=(cell.outputs??[]).map(o=>joinText(o.text)+Object.values(o.data??{}).map(joinText).join("")).join(" ").toLocaleLowerCase(this.effectiveLocale);if(source.includes(q)||outputText.includes(q))acc.push(i);return acc},[])}this.activeSearchIndex=this.searchMatches.length?0:-1;this.activateSearchMatch();this.emitSearchChange();return this.searchMatches.length}async searchNext(){if(!this.searchMatches.length)return false;this.activeSearchIndex=(this.activeSearchIndex+1)%this.searchMatches.length;this.activateSearchMatch();this.emitSearchChange();return true}async searchPrevious(){if(!this.searchMatches.length)return false;this.activeSearchIndex=(this.activeSearchIndex-1+this.searchMatches.length)%this.searchMatches.length;this.activateSearchMatch();this.emitSearchChange();return true}clearSearch(){this.clearSearchState();this.emitSearchChange()}clearSearchState(){this.searchQuery="";this.searchMatches=[];this.activeSearchIndex=-1}activateSearchMatch(){const index=this.searchMatches[this.activeSearchIndex];if(index===void 0)return;this.activeCellIndex=index;this.scheduleAfterUpdate(()=>{this.virtualListEl?.scrollToIndex(index,{align:"auto",behavior:"auto"})})}emitSearchChange(){this.emit("lr-search-change",{query:this.searchQuery,matchCount:this.searchMatches.length,activeIndex:this.activeSearchIndex})}toggleOutput(index){const next=new Set(this.expandedOutputs);if(next.has(index))next.delete(index);else next.add(index);this.expandedOutputs=next}renderAnsiText(text){const segments=createAnsiParser().push(text);return html`${segments.map(seg=>html`<span style=${styleMap(this.segmentStyle(seg.styles))}>${seg.text}</span>`)}`}segmentStyle(s){const fg=sanitizeCssColor(s.fg)??"var(--lr-color-text)";const bg=sanitizeCssColor(s.bg)??"transparent";return{"font-weight":s.bold?"bold":"normal",opacity:s.dim?"0.7":"1","font-style":s.italic?"italic":"normal","text-decoration":s.underline?"underline":"none",color:s.inverse?bg:fg,"background-color":s.inverse?fg:bg}}renderTextOutput(index,text,tone){const lines=text.split("\n");const outputCollapseLines=this.effectiveOutputCollapseLines;const collapsible=outputCollapseLines>0&&lines.length>outputCollapseLines;const expanded=this.expandedOutputs.has(index)||!collapsible;const shown=expanded?text:lines.slice(0,outputCollapseLines).join("\n");const part=tone==="danger"?"output output-error":"output";return html`<div part=${part} data-output-type="stream" data-stream=${tone==="danger"?"stderr":"stdout"}
8
8
  >${this.renderAnsiText(shown)}${collapsible?html`<button
9
9
  part="output-toggle"
10
10
  type="button"
@@ -27,6 +27,7 @@ var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3
27
27
  .keyFunction=${(item,i)=>item.id??i}
28
28
  .activeId=${this.activeCellIndex??""}
29
29
  @lr-visible-range-changed=${this.stopVirtualListEvent}
30
+ @lr-scroll=${this.stopVirtualListEvent}
30
31
  ></lr-virtual-list>`:this.loadState.kind==="loading"?html`<div part="spinner"><span class="sr-only">${this.localize("loadingDocument")}</span></div>`:this.loadState.kind==="error"?html`<div part="error">${this.loadState.message}</div>`:html`<p>${this.localize("documentPreviewEmpty",void 0,{type:this.localize("documentPreviewTypeDocument")})}</p>`}
31
32
  ${this.renderAnchorLiveRegion()}
32
33
  </div>`}}__decorate([property()],LyraNotebookViewer.prototype,"src",void 0);__decorate([property({attribute:false})],LyraNotebookViewer.prototype,"notebook",null);__decorate([property()],LyraNotebookViewer.prototype,"name",void 0);__decorate([property({type:Number,attribute:"output-collapse-lines"})],LyraNotebookViewer.prototype,"outputCollapseLines",void 0);__decorate([property({attribute:"max-height"})],LyraNotebookViewer.prototype,"maxHeight",void 0);__decorate([state()],LyraNotebookViewer.prototype,"loadState",void 0);__decorate([state()],LyraNotebookViewer.prototype,"expandedOutputs",void 0);__decorate([state()],LyraNotebookViewer.prototype,"activeCellIndex",void 0);__decorate([state()],LyraNotebookViewer.prototype,"searchQuery",void 0);__decorate([state()],LyraNotebookViewer.prototype,"searchMatches",void 0);__decorate([state()],LyraNotebookViewer.prototype,"activeSearchIndex",void 0);__decorate([query("lr-virtual-list")],LyraNotebookViewer.prototype,"virtualListEl",void 0);export{LyraNotebookViewer};
@@ -30,6 +30,8 @@ var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3
30
30
  .keyFunction=${item=>item}
31
31
  .activeId=${this.safePage}
32
32
  @lr-visible-range-changed=${this.stopVirtualListEvent}
33
+ @lr-scroll=${this.stopVirtualListEvent}
34
+ @lr-load-more=${this.stopVirtualListEvent}
33
35
  ></lr-virtual-list>
34
36
  </div>
35
37
  `}}__decorate([property({attribute:false})],LyraPageRail.prototype,"viewer",void 0);__decorate([property()],LyraPageRail.prototype,"for",void 0);__decorate([property({type:Number,attribute:"page-count"})],LyraPageRail.prototype,"pageCount",void 0);__decorate([property({type:Number,reflect:true})],LyraPageRail.prototype,"page",void 0);__decorate([property({attribute:false})],LyraPageRail.prototype,"highlights",void 0);__decorate([property({type:Number,attribute:"thumb-width"})],LyraPageRail.prototype,"thumbWidth",void 0);__decorate([property()],LyraPageRail.prototype,"label",void 0);__decorate([state()],LyraPageRail.prototype,"resolvedPageCount",void 0);__decorate([state()],LyraPageRail.prototype,"thumbnailStates",void 0);__decorate([state()],LyraPageRail.prototype,"allocationWidth",void 0);export{LyraPageRail};
@@ -1,4 +1,4 @@
1
- var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3?target:desc===null?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if(typeof Reflect==="object"&&typeof Reflect.decorate==="function")r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;i>=0;i--)if(d=decorators[i])r=(c<3?d(r):c>3?d(target,key,r):d(target,key))||r;return c>3&&r&&Object.defineProperty(target,key,r),r};import{html,nothing}from"lit";import{property,state}from"lit/decorators.js";import{LyraElement}from"../../../internal/lyra-element.js";import{assertTableDimensions,assertTableSize,isAbortError,isResourceLimitError,LyraResourceLimitError,LyraUserFacingError,readResponseArrayBuffer,resolveOwnerFetchTarget}from"../../../internal/resource-loader.js";import{srOnly}from"../../../internal/a11y.js";import{prefersReducedMotion}from"../../../internal/motion.js";import{DocumentAnchorTarget}from"../../../internal/anchor-target.js";import{parseCellRange}from"../../../internal/cell-range.js";import{loadSheetJsCached}from"./spreadsheet-loader.js";import{styles}from"./spreadsheet-viewer.styles.js";import{assertXlsxArchiveWithinLimits}from"./xlsx-resource-guard.js";import{getNumberFormat}from"../../../internal/intl-cache.js";import{ViewerAnnouncementController}from"../viewer-announcements.js";import{LYRA_DEFAULT_anchorJumped,LYRA_DEFAULT_anchorJumpedToPage,LYRA_DEFAULT_anchorNotFound,LYRA_DEFAULT_collapse,LYRA_DEFAULT_details,LYRA_DEFAULT_documentPreviewEmpty,LYRA_DEFAULT_documentPreviewFailedToLoad,LYRA_DEFAULT_documentPreviewResourceTooLarge,LYRA_DEFAULT_documentPreviewTypeDocument,LYRA_DEFAULT_documentPreviewUrlNotAllowed,LYRA_DEFAULT_highlightWithLabel,LYRA_DEFAULT_loading,LYRA_DEFAULT_loadingDocument,LYRA_DEFAULT_noData,LYRA_DEFAULT_open,LYRA_DEFAULT_search,LYRA_DEFAULT_spreadsheetViewerLabel,LYRA_DEFAULT_spreadsheetViewerUnavailable}from"../../../internal/default-strings.generated.js";const MAX_SPREADSHEET_SHEETS=256;const MAX_SPREADSHEET_CELLS=1e6;const MAX_SEARCH_MATCHES=1e3;function columns(rows){return rows.reduce((max,row)=>Math.max(max,row.length),0)}function cell(value,locale){if(value===void 0||value===null)return"";return typeof value==="number"?getNumberFormat(locale).format(value):String(value)}class LyraSpreadsheetViewerBase extends LyraElement{}class LyraSpreadsheetViewer extends DocumentAnchorTarget(LyraSpreadsheetViewerBase){constructor(){super(...arguments);this.src="";this.name="";this.anchorKinds=["cell-range"];this.fetchState={kind:"idle"};this.activeSheetIndex=0;this.activeRowKey="";this.searchMatches=[];this.searchActiveIndex=-1;this.searchQuery="";this.lastSearchLocale="";this.generation=0;this.loadLibrary=loadSheetJsCached;this.lastLoadSrc="";this.announcements=new ViewerAnnouncementController(this);this.pendingAnimationFrames=new Set;this.onTabsChange=e=>{e.stopPropagation();const match=/^sheet-(\d+)$/.exec(e.detail.tabId);if(match)this.activeSheetIndex=Number(match[1])};this.stopInternalEvent=event=>{event.stopPropagation()}}static{this.defaultStrings={...super.defaultStrings,anchorJumped:LYRA_DEFAULT_anchorJumped,anchorJumpedToPage:LYRA_DEFAULT_anchorJumpedToPage,anchorNotFound:LYRA_DEFAULT_anchorNotFound,collapse:LYRA_DEFAULT_collapse,details:LYRA_DEFAULT_details,documentPreviewEmpty:LYRA_DEFAULT_documentPreviewEmpty,documentPreviewFailedToLoad:LYRA_DEFAULT_documentPreviewFailedToLoad,documentPreviewResourceTooLarge:LYRA_DEFAULT_documentPreviewResourceTooLarge,documentPreviewTypeDocument:LYRA_DEFAULT_documentPreviewTypeDocument,documentPreviewUrlNotAllowed:LYRA_DEFAULT_documentPreviewUrlNotAllowed,highlightWithLabel:LYRA_DEFAULT_highlightWithLabel,loading:LYRA_DEFAULT_loading,loadingDocument:LYRA_DEFAULT_loadingDocument,noData:LYRA_DEFAULT_noData,open:LYRA_DEFAULT_open,search:LYRA_DEFAULT_search,spreadsheetViewerLabel:LYRA_DEFAULT_spreadsheetViewerLabel,spreadsheetViewerUnavailable:LYRA_DEFAULT_spreadsheetViewerUnavailable}}static{this.styles=[LyraElement.styles,styles,srOnly]}connectedCallback(){super.connectedCallback();this.announcements.connect();if(this.hasUpdated&&this.src&&this.src===this.lastLoadSrc){this.scheduleAfterUpdate(()=>{void this.load()})}}disconnectedCallback(){this.generation++;this.cancelPendingAnimationFrames();this.announcements.disconnect();super.disconnectedCallback()}adoptedCallback(){this.cancelPendingAnimationFrames();this.announcements.adopted()}waitForOwnerAnimationFrame(){const owner=this.ownerDocument.defaultView;if(!owner||!this.isConnected)return Promise.resolve(false);return new Promise(resolve=>{const pending={owner,resolve};this.pendingAnimationFrames.add(pending);pending.handle=owner.requestAnimationFrame(()=>{if(!this.pendingAnimationFrames.delete(pending))return;resolve(this.isConnected&&this.ownerDocument.defaultView===owner)})})}cancelPendingAnimationFrames(){const pendingFrames=[...this.pendingAnimationFrames];this.pendingAnimationFrames.clear();for(const pending of pendingFrames){if(pending.handle!==void 0)pending.owner.cancelAnimationFrame(pending.handle);pending.resolve(false)}}willUpdate(changed){super.willUpdate(changed);if(changed.has("src")){this.searchQuery="";this.searchMatches=[];this.searchActiveIndex=-1;this.activeRowKey="";this.activeSheetIndex=0}}updated(changed){super.updated(changed);this.announcements.transition("load",this.fetchState.kind,this.fetchState.kind==="error"?this.fetchState.message:this.localize("loadingDocument"));if(changed.has("src"))this.scheduleAfterUpdate(()=>{void this.load()});const locale=this.effectiveLocale;if(locale!==this.lastSearchLocale){const shouldRecompute=!!this.searchQuery;this.lastSearchLocale=locale;if(shouldRecompute)this.scheduleAfterUpdate(()=>{void this.search(this.searchQuery)},"search")}}async load(){this.lastLoadSrc=this.src;const generation=++this.generation;const signal=this.beginAbortableLoad();if(!this.src){this.fetchState={kind:"idle"};return}const fetchTarget=resolveOwnerFetchTarget(this,this.src);if(!fetchTarget){const error=new LyraUserFacingError(this.localize("documentPreviewUrlNotAllowed"));this.fetchState={kind:"error",message:error.message};this.emit("lr-render-error",{error});return}this.fetchState={kind:"loading"};try{const response=await fetchTarget.view.fetch(fetchTarget.url,signal?{signal}:void 0);if(!this.isConnected||generation!==this.generation)return;if(!response.ok)throw new Error(`${response.status} ${response.statusText}`);const library=await this.loadLibrary();if(!this.isConnected||generation!==this.generation)return;if(!library){const error=new LyraUserFacingError(this.localize("spreadsheetViewerUnavailable"));this.fetchState={kind:"error",message:error.message};this.emit("lr-render-error",{error});return}const source=await readResponseArrayBuffer(response);if(!this.isConnected||generation!==this.generation)return;await assertXlsxArchiveWithinLimits(source,void 0,void 0,{signal});if(!this.isConnected||generation!==this.generation)return;const workbook=library.read(source,{type:"array"});if(!this.isConnected||generation!==this.generation)return;const sheetNames=workbook.SheetNames;if(sheetNames.length>MAX_SPREADSHEET_SHEETS){throw new LyraResourceLimitError("The spreadsheet contains too many sheets.")}const sheets=[];let totalRows=0;let maxColumns=0;let totalCells=0;for(const name of sheetNames){const rows=library.utils.sheet_to_json(workbook.Sheets[name],{header:1});assertTableSize(rows);totalRows+=rows.length;maxColumns=Math.max(maxColumns,columns(rows));totalCells+=rows.reduce((sum,row)=>sum+row.length,0);if(totalCells>MAX_SPREADSHEET_CELLS){throw new LyraResourceLimitError("The spreadsheet contains too many expanded cells.")}assertTableDimensions(totalRows,maxColumns);sheets.push({name,rows})}if(this.isConnected&&generation===this.generation){this.fetchState={kind:"loaded",sheets};if(this.searchQuery)await this.search(this.searchQuery)}}catch(error){if(isAbortError(error)||!this.isConnected||generation!==this.generation)return;this.fetchState={kind:"error",message:this.localize(isResourceLimitError(error)?"documentPreviewResourceTooLarge":"documentPreviewFailedToLoad")};this.emit("lr-render-error",{error})}}cellHighlightsForRow(rawRow,currentSheetName){const seen=new Set;return this.highlights.filter(highlight=>{if(seen.has(highlight.id))return false;seen.add(highlight.id);return true}).flatMap(highlight=>{if(highlight.anchor.kind!=="cell-range")return[];const parsed=parseCellRange(highlight.anchor.range);if(!parsed)return[];const sheetName=highlight.anchor.sheet??parsed.sheet;if(sheetName!==void 0&&sheetName!==currentSheetName)return[];return rawRow-1>=parsed.startRow&&rawRow-1<=parsed.endRow?[{highlight,parsed}]:[]})}renderCell(value,colIndex,rowHighlights,role){const text=cell(value,this.effectiveLocale);const colHighlights=rowHighlights.filter(entry=>colIndex>=entry.parsed.startCol&&colIndex<=entry.parsed.endCol);if(!colHighlights.length)return html`<div part="cell" role=${role}>${text}</div>`;const active=colHighlights.find(entry=>entry.highlight.id===this.activeHighlightId);const primary=active??colHighlights[0];const accessibleLabel=this.localize("highlightWithLabel",void 0,{label:primary.highlight.label?`${text} \u2014 ${primary.highlight.label}`:text});const activate=()=>{this.emit("lr-highlight-activate",{id:primary.highlight.id})};return html`<div
1
+ var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3?target:desc===null?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if(typeof Reflect==="object"&&typeof Reflect.decorate==="function")r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;i>=0;i--)if(d=decorators[i])r=(c<3?d(r):c>3?d(target,key,r):d(target,key))||r;return c>3&&r&&Object.defineProperty(target,key,r),r};import{html,nothing}from"lit";import{property,state}from"lit/decorators.js";import{LyraElement}from"../../../internal/lyra-element.js";import{assertTableDimensions,assertTableSize,isAbortError,isResourceLimitError,LyraResourceLimitError,LyraUserFacingError,readResponseArrayBuffer,resolveOwnerFetchTarget}from"../../../internal/resource-loader.js";import{srOnly}from"../../../internal/a11y.js";import{prefersReducedMotion}from"../../../internal/motion.js";import{DocumentAnchorTarget}from"../../../internal/anchor-target.js";import{parseCellRange}from"../../../internal/cell-range.js";import{loadSheetJsCached}from"./spreadsheet-loader.js";import{styles}from"./spreadsheet-viewer.styles.js";import{assertXlsxArchiveWithinLimits}from"./xlsx-resource-guard.js";import{getNumberFormat}from"../../../internal/intl-cache.js";import{ViewerAnnouncementController}from"../viewer-announcements.js";import{LYRA_DEFAULT_anchorJumped,LYRA_DEFAULT_anchorJumpedToPage,LYRA_DEFAULT_anchorNotFound,LYRA_DEFAULT_collapse,LYRA_DEFAULT_details,LYRA_DEFAULT_documentPreviewEmpty,LYRA_DEFAULT_documentPreviewFailedToLoad,LYRA_DEFAULT_documentPreviewResourceTooLarge,LYRA_DEFAULT_documentPreviewTypeDocument,LYRA_DEFAULT_documentPreviewUrlNotAllowed,LYRA_DEFAULT_highlightWithLabel,LYRA_DEFAULT_loading,LYRA_DEFAULT_loadingDocument,LYRA_DEFAULT_noData,LYRA_DEFAULT_open,LYRA_DEFAULT_search,LYRA_DEFAULT_spreadsheetViewerLabel,LYRA_DEFAULT_spreadsheetViewerUnavailable}from"../../../internal/default-strings.generated.js";const MAX_SPREADSHEET_SHEETS=256;const MAX_SPREADSHEET_CELLS=1e6;const MAX_SEARCH_MATCHES=1e3;function columns(rows){return rows.reduce((max,row)=>Math.max(max,row.length),0)}function cell(value,locale){if(value===void 0||value===null)return"";return typeof value==="number"?getNumberFormat(locale).format(value):String(value)}class LyraSpreadsheetViewerBase extends LyraElement{}class LyraSpreadsheetViewer extends DocumentAnchorTarget(LyraSpreadsheetViewerBase){constructor(){super(...arguments);this.src="";this.name="";this.anchorKinds=["cell-range"];this.fetchState={kind:"idle"};this.activeSheetIndex=0;this.activeRowKey="";this.searchMatches=[];this.searchActiveIndex=-1;this.searchQuery="";this.lastSearchLocale="";this.generation=0;this.loadLibrary=loadSheetJsCached;this.lastLoadSrc="";this.announcements=new ViewerAnnouncementController(this);this.pendingAnimationFrames=new Set;this.onTabsChange=e=>{e.stopPropagation();const match=/^sheet-(\d+)$/.exec(e.detail.tabId);if(match)this.activeSheetIndex=Number(match[1])};this.stopInternalEvent=event=>{event.stopPropagation()}}static{this.defaultStrings={...super.defaultStrings,anchorJumped:LYRA_DEFAULT_anchorJumped,anchorJumpedToPage:LYRA_DEFAULT_anchorJumpedToPage,anchorNotFound:LYRA_DEFAULT_anchorNotFound,collapse:LYRA_DEFAULT_collapse,details:LYRA_DEFAULT_details,documentPreviewEmpty:LYRA_DEFAULT_documentPreviewEmpty,documentPreviewFailedToLoad:LYRA_DEFAULT_documentPreviewFailedToLoad,documentPreviewResourceTooLarge:LYRA_DEFAULT_documentPreviewResourceTooLarge,documentPreviewTypeDocument:LYRA_DEFAULT_documentPreviewTypeDocument,documentPreviewUrlNotAllowed:LYRA_DEFAULT_documentPreviewUrlNotAllowed,highlightWithLabel:LYRA_DEFAULT_highlightWithLabel,loading:LYRA_DEFAULT_loading,loadingDocument:LYRA_DEFAULT_loadingDocument,noData:LYRA_DEFAULT_noData,open:LYRA_DEFAULT_open,search:LYRA_DEFAULT_search,spreadsheetViewerLabel:LYRA_DEFAULT_spreadsheetViewerLabel,spreadsheetViewerUnavailable:LYRA_DEFAULT_spreadsheetViewerUnavailable}}static{this.styles=[LyraElement.styles,styles,srOnly]}connectedCallback(){super.connectedCallback();this.announcements.connect();if(this.hasUpdated&&this.src&&this.src===this.lastLoadSrc){this.scheduleAfterUpdate(()=>{void this.load()})}}disconnectedCallback(){this.generation++;this.cancelPendingAnimationFrames();this.announcements.disconnect();super.disconnectedCallback()}adoptedCallback(){this.cancelPendingAnimationFrames();this.announcements.adopted()}waitForOwnerAnimationFrame(){const owner=this.ownerDocument.defaultView;if(!owner||!this.isConnected)return Promise.resolve(false);return new Promise(resolve=>{const pending={owner,resolve};this.pendingAnimationFrames.add(pending);pending.handle=owner.requestAnimationFrame(()=>{if(!this.pendingAnimationFrames.delete(pending))return;resolve(this.isConnected&&this.ownerDocument.defaultView===owner)})})}cancelPendingAnimationFrames(){const pendingFrames=[...this.pendingAnimationFrames];this.pendingAnimationFrames.clear();for(const pending of pendingFrames){if(pending.handle!==void 0)pending.owner.cancelAnimationFrame(pending.handle);pending.resolve(false)}}willUpdate(changed){super.willUpdate(changed);if(changed.has("src")){this.searchQuery="";this.searchMatches=[];this.searchActiveIndex=-1;this.activeRowKey="";this.activeSheetIndex=0}}updated(changed){super.updated(changed);this.announcements.transition("load",this.fetchState.kind,this.fetchState.kind==="error"?this.fetchState.message:this.localize("loadingDocument"));if(changed.has("src"))this.scheduleAfterUpdate(()=>{void this.load()});const locale=this.effectiveLocale;if(locale!==this.lastSearchLocale){const shouldRecompute=!!this.searchQuery;this.lastSearchLocale=locale;if(shouldRecompute)this.scheduleAfterUpdate(()=>{void this.search(this.searchQuery)},"search")}}async load(){this.lastLoadSrc=this.src;const generation=++this.generation;const signal=this.beginAbortableLoad();if(!this.src){this.fetchState={kind:"idle"};return}const fetchTarget=resolveOwnerFetchTarget(this,this.src);if(!fetchTarget){const error=new LyraUserFacingError(this.localize("documentPreviewUrlNotAllowed"));this.fetchState={kind:"error",message:error.message};this.emit("lr-render-error",{error});return}this.fetchState={kind:"loading"};try{const response=await fetchTarget.view.fetch(fetchTarget.url,signal?{signal}:void 0);if(!this.isConnected||generation!==this.generation)return;if(!response.ok)throw new Error(`${response.status} ${response.statusText}`);const library=await this.loadLibrary();if(!this.isConnected||generation!==this.generation)return;if(!library){const error=new LyraUserFacingError(this.localize("spreadsheetViewerUnavailable"));this.fetchState={kind:"error",message:error.message};this.emit("lr-render-error",{error});return}const source=await readResponseArrayBuffer(response);if(!this.isConnected||generation!==this.generation)return;await assertXlsxArchiveWithinLimits(source,void 0,void 0,{signal});if(!this.isConnected||generation!==this.generation)return;const workbook=library.read(source,{type:"array"});if(!this.isConnected||generation!==this.generation)return;const sheetNames=workbook.SheetNames;if(!Array.isArray(sheetNames)||!sheetNames.every(name=>typeof name==="string")){throw new Error("The xlsx peer returned a malformed workbook.")}if(sheetNames.length>MAX_SPREADSHEET_SHEETS){throw new LyraResourceLimitError("The spreadsheet contains too many sheets.")}const sheets=[];let totalRows=0;let maxColumns=0;let totalCells=0;for(const name of sheetNames){const rows=library.utils.sheet_to_json(workbook.Sheets[name],{header:1});assertTableSize(rows);totalRows+=rows.length;maxColumns=Math.max(maxColumns,columns(rows));totalCells+=rows.reduce((sum,row)=>sum+row.length,0);if(totalCells>MAX_SPREADSHEET_CELLS){throw new LyraResourceLimitError("The spreadsheet contains too many expanded cells.")}assertTableDimensions(totalRows,maxColumns);sheets.push({name,rows})}if(this.isConnected&&generation===this.generation){this.fetchState={kind:"loaded",sheets};if(this.searchQuery)await this.search(this.searchQuery)}}catch(error){if(isAbortError(error)||!this.isConnected||generation!==this.generation)return;this.fetchState={kind:"error",message:this.localize(isResourceLimitError(error)?"documentPreviewResourceTooLarge":"documentPreviewFailedToLoad")};this.emit("lr-render-error",{error})}}cellHighlightsForRow(rawRow,currentSheetName){const seen=new Set;return this.highlights.filter(highlight=>{if(seen.has(highlight.id))return false;seen.add(highlight.id);return true}).flatMap(highlight=>{if(highlight.anchor.kind!=="cell-range")return[];const parsed=parseCellRange(highlight.anchor.range);if(!parsed)return[];const sheetName=highlight.anchor.sheet??parsed.sheet;if(sheetName!==void 0&&sheetName!==currentSheetName)return[];return rawRow-1>=parsed.startRow&&rawRow-1<=parsed.endRow?[{highlight,parsed}]:[]})}renderCell(value,colIndex,rowHighlights,role){const text=cell(value,this.effectiveLocale);const colHighlights=rowHighlights.filter(entry=>colIndex>=entry.parsed.startCol&&colIndex<=entry.parsed.endCol);if(!colHighlights.length)return html`<div part="cell" role=${role}>${text}</div>`;const active=colHighlights.find(entry=>entry.highlight.id===this.activeHighlightId);const primary=active??colHighlights[0];const accessibleLabel=this.localize("highlightWithLabel",void 0,{label:primary.highlight.label?`${text} \u2014 ${primary.highlight.label}`:text});const activate=()=>{this.emit("lr-highlight-activate",{id:primary.highlight.id})};return html`<div
2
2
  part="cell cell-highlight"
3
3
  role=${role}
4
4
  ?data-active=${!!active}
@@ -1,4 +1,4 @@
1
- var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3?target:desc===null?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if(typeof Reflect==="object"&&typeof Reflect.decorate==="function")r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;i>=0;i--)if(d=decorators[i])r=(c<3?d(r):c>3?d(target,key,r):d(target,key))||r;return c>3&&r&&Object.defineProperty(target,key,r),r};import{html}from"lit";import{property,state}from"lit/decorators.js";import{acquireAnnouncementSink}from"./announcer.js";import{isAccessibilityVisible}from"./accessibility-visibility.js";import{LyraElement}from"./lyra-element.js";import{normalizeQuoteText,scopeFromElement,buildQuoteAnchor}from"./text-quote.js";const ANCHOR_RETRY_INTERVAL_MS=250;const ANCHOR_TIMEOUT_MS=5e3;function selectionRange(root){const document=root.ownerDocument;const view=document.defaultView;const renderRoot=root.renderRoot;const shadowRoot=renderRoot?.nodeType===11&&renderRoot.host===root?renderRoot:void 0;const globalSelection=view?.getSelection()??null;if(globalSelection?.getComposedRanges&&shadowRoot){const[composed]=globalSelection.getComposedRanges({shadowRoots:[shadowRoot]});if(!composed)return null;if(composed.startContainer===composed.endContainer&&composed.startOffset===composed.endOffset)return null;const range=document.createRange();range.setStart(composed.startContainer,composed.startOffset);range.setEnd(composed.endContainer,composed.endOffset);return range}const shadowSelection=shadowRoot?.getSelection?.();const selection=shadowSelection??globalSelection;if(!selection||selection.rangeCount===0||selection.isCollapsed)return null;return selection.getRangeAt(0)}function DocumentAnchorTarget(Base){class DocumentAnchorTargetElement extends Base{constructor(){super(...arguments);this.highlights=[];this.activeHighlightId=null;this.anchor=null;this.anchorKinds=[];this.anchorRetryIntervalMs=ANCHOR_RETRY_INTERVAL_MS;this.anchorTimeoutMs=ANCHOR_TIMEOUT_MS;this.anchorAnnouncementText="";this.anchorGeneration=0}connectedCallback(){super.connectedCallback();this.anchorAnnouncementSink??=acquireAnnouncementSink("polite",{document:this.ownerDocument,source:this})}willUpdate(changed){super.willUpdate(changed);if(changed.has("anchor")&&this.anchor!==null){void this.scrollToAnchor(this.anchor).catch(()=>void 0)}}disconnectedCallback(){this.anchorGeneration++;this.cancelAnchorRetry();this.unbindTextSelection();this.anchorAnnouncementSink?.release();this.anchorAnnouncementSink=void 0;super.disconnectedCallback()}async applyAnchor(_anchor){return false}computeSelectionAnchor(range,_text){const scope=scopeFromElement(this.renderRoot);return buildQuoteAnchor(range,scope)}cancelAnchorRetry(){if(this.anchorRetryHandle!==void 0){this.anchorRetryOwner?.clearTimeout(this.anchorRetryHandle);this.anchorRetryHandle=void 0}this.anchorRetryOwner=void 0;const resolveWait=this.anchorRetryResolve;if(resolveWait){this.anchorRetryResolve=void 0;resolveWait()}}async scrollToAnchor(target){const generation=++this.anchorGeneration;this.cancelAnchorRetry();await this.updateComplete;if(generation!==this.anchorGeneration)return false;const highlightId=typeof target==="string"?target:void 0;const anchor=typeof target==="string"?this.highlights.find(h=>h.id===target)?.anchor:target;if(!anchor){this.announceAnchorResult(void 0,false);this.emit("lr-anchor-result",{found:false});return false}const ok=await this.resolveWithRetry(anchor,generation);if(generation!==this.anchorGeneration)return false;if(ok&&highlightId)this.activeHighlightId=highlightId;this.announceAnchorResult(anchor,ok);this.emit("lr-anchor-result",{found:ok});return ok}async resolveWithRetry(anchor,generation){const deadline=Date.now()+this.anchorTimeoutMs;for(;;){if(generation!==this.anchorGeneration)return false;const ok=await this.applyAnchor(anchor);if(generation!==this.anchorGeneration)return false;if(ok)return true;if(Date.now()>=deadline)return false;const view=this.ownerDocument.defaultView;if(!view)return false;await new Promise(resolve=>{this.anchorRetryResolve=resolve;this.anchorRetryOwner=view;let handle;handle=view.setTimeout(()=>{if(this.anchorRetryHandle===handle&&this.anchorRetryOwner===view){this.anchorRetryHandle=void 0;this.anchorRetryOwner=void 0}if(this.anchorRetryResolve===resolve)this.anchorRetryResolve=void 0;resolve()},this.anchorRetryIntervalMs);this.anchorRetryHandle=handle})}}announceAnchorResult(anchor,found){if(!found||!anchor){this.announce(this.localize("anchorNotFound"));return}const page="page"in anchor?anchor.page:void 0;this.announce(page!=null?this.localize("anchorJumpedToPage",void 0,{page}):this.localize("anchorJumped"))}announce(text){if(isAccessibilityVisible(this))this.anchorAnnouncementSink?.announce(text);this.anchorAnnouncementText=text}renderAnchorLiveRegion(){return html`<div
1
+ var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3?target:desc===null?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if(typeof Reflect==="object"&&typeof Reflect.decorate==="function")r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;i>=0;i--)if(d=decorators[i])r=(c<3?d(r):c>3?d(target,key,r):d(target,key))||r;return c>3&&r&&Object.defineProperty(target,key,r),r};import{html}from"lit";import{property,state}from"lit/decorators.js";import{acquireAnnouncementSink}from"./announcer.js";import{isAccessibilityVisible}from"./accessibility-visibility.js";import{LyraElement}from"./lyra-element.js";import{normalizeQuoteText,scopeFromElement,buildQuoteAnchor}from"./text-quote.js";const ANCHOR_RETRY_INTERVAL_MS=250;const ANCHOR_TIMEOUT_MS=5e3;function selectionRange(root){const document=root.ownerDocument;const view=document.defaultView;const renderRoot=root.renderRoot;const shadowRoot=renderRoot?.nodeType===11&&renderRoot.host===root?renderRoot:void 0;const globalSelection=view?.getSelection()??null;if(globalSelection?.getComposedRanges&&shadowRoot){const[composed]=globalSelection.getComposedRanges({shadowRoots:[shadowRoot]});if(!composed)return null;if(composed.startContainer===composed.endContainer&&composed.startOffset===composed.endOffset)return null;const range=document.createRange();range.setStart(composed.startContainer,composed.startOffset);range.setEnd(composed.endContainer,composed.endOffset);return range}const shadowSelection=shadowRoot?.getSelection?.();const selection=shadowSelection??globalSelection;if(!selection||selection.rangeCount===0||selection.isCollapsed)return null;return selection.getRangeAt(0)}function DocumentAnchorTarget(Base){class DocumentAnchorTargetElement extends Base{constructor(){super(...arguments);this.highlights=[];this.activeHighlightId=null;this.anchor=null;this.anchorKinds=[];this.anchorRetryIntervalMs=ANCHOR_RETRY_INTERVAL_MS;this.anchorTimeoutMs=ANCHOR_TIMEOUT_MS;this.anchorAnnouncementText="";this.anchorGeneration=0}connectedCallback(){super.connectedCallback();this.anchorAnnouncementSink??=acquireAnnouncementSink("polite",{document:this.ownerDocument,source:this})}willUpdate(changed){super.willUpdate(changed);if(changed.has("anchor")&&this.anchor!==null){void this.scrollToAnchor(this.anchor).catch(()=>void 0)}}disconnectedCallback(){this.anchorGeneration++;this.cancelAnchorRetry();this.unbindTextSelection();this.anchorAnnouncementSink?.release();this.anchorAnnouncementSink=void 0;super.disconnectedCallback()}async applyAnchor(_anchor){return false}computeSelectionAnchor(range,_text){const scope=scopeFromElement(this.renderRoot);return buildQuoteAnchor(range,scope)}cancelAnchorRetry(){if(this.anchorRetryHandle!==void 0){this.anchorRetryOwner?.clearTimeout(this.anchorRetryHandle);this.anchorRetryHandle=void 0}this.anchorRetryOwner=void 0;const resolveWait=this.anchorRetryResolve;if(resolveWait){this.anchorRetryResolve=void 0;resolveWait()}}async scrollToAnchor(target){const generation=++this.anchorGeneration;try{return await this.performScrollToAnchor(target,generation)}catch{if(generation!==this.anchorGeneration)return false;this.announceAnchorResult(void 0,false);this.emit("lr-anchor-result",{found:false});return false}}async performScrollToAnchor(target,generation=++this.anchorGeneration){this.cancelAnchorRetry();await this.updateComplete;if(generation!==this.anchorGeneration)return false;const highlightId=typeof target==="string"?target:void 0;const anchor=typeof target==="string"?this.highlights.find(h=>h.id===target)?.anchor:target;if(!anchor){this.announceAnchorResult(void 0,false);this.emit("lr-anchor-result",{found:false});return false}const ok=await this.resolveWithRetry(anchor,generation);if(generation!==this.anchorGeneration)return false;if(ok&&highlightId)this.activeHighlightId=highlightId;this.announceAnchorResult(anchor,ok);this.emit("lr-anchor-result",{found:ok});return ok}async resolveWithRetry(anchor,generation){const deadline=Date.now()+this.anchorTimeoutMs;for(;;){if(generation!==this.anchorGeneration)return false;const ok=await this.applyAnchor(anchor);if(generation!==this.anchorGeneration)return false;if(ok)return true;if(Date.now()>=deadline)return false;const view=this.ownerDocument.defaultView;if(!view)return false;await new Promise(resolve=>{this.anchorRetryResolve=resolve;this.anchorRetryOwner=view;let handle;handle=view.setTimeout(()=>{if(this.anchorRetryHandle===handle&&this.anchorRetryOwner===view){this.anchorRetryHandle=void 0;this.anchorRetryOwner=void 0}if(this.anchorRetryResolve===resolve)this.anchorRetryResolve=void 0;resolve()},this.anchorRetryIntervalMs);this.anchorRetryHandle=handle})}}announceAnchorResult(anchor,found){if(!found||!anchor){this.announce(this.localize("anchorNotFound"));return}const page="page"in anchor?anchor.page:void 0;this.announce(page!=null?this.localize("anchorJumpedToPage",void 0,{page}):this.localize("anchorJumped"))}announce(text){if(isAccessibilityVisible(this))this.anchorAnnouncementSink?.announce(text);this.anchorAnnouncementText=text}renderAnchorLiveRegion(){return html`<div
2
2
  part="anchor-live-region"
3
3
  class="sr-only"
4
4
  aria-hidden="true"
@@ -3,4 +3,4 @@
3
3
  * Run `pnpm package-metadata` after changing package identity or version.
4
4
  */
5
5
  export declare const LYRA_PACKAGE_NAME: "@aceshooting/lyra-ui";
6
- export declare const LYRA_PACKAGE_VERSION: "8.0.0";
6
+ export declare const LYRA_PACKAGE_VERSION: "8.2.0";
@@ -1 +1 @@
1
- const LYRA_PACKAGE_NAME="@aceshooting/lyra-ui";const LYRA_PACKAGE_VERSION="8.0.0";export{LYRA_PACKAGE_NAME,LYRA_PACKAGE_VERSION};
1
+ const LYRA_PACKAGE_NAME="@aceshooting/lyra-ui";const LYRA_PACKAGE_VERSION="8.2.0";export{LYRA_PACKAGE_NAME,LYRA_PACKAGE_VERSION};
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Rejects an attribute name that should never survive a raw DOM clone of consumer-supplied SVG
3
+ * content (`<lr-icon>`'s and `<lr-icon-button>`'s slotted custom-content path -- unlike a fetched
4
+ * `src` document, which is sanitized through DOMPurify before it ever reaches the DOM, a slotted
5
+ * clone has no sanitizer in the loop, so this predicate is that path's own trust boundary).
6
+ * Event-handler content attributes (`on*`) execute as inline JS once connected; `href`/
7
+ * `xlink:href` on an SVG `<a>`/`<use>`/`<image>` can carry a `javascript:` URI or reference an
8
+ * external resource. Every other presentational attribute (`d`, `fill`, `stroke`, `viewBox`,
9
+ * `transform`, gradient stops, …) is left untouched -- this is a denylist, not an allowlist,
10
+ * because SVG's legitimate presentation-attribute vocabulary is too large to enumerate without
11
+ * silently breaking real icon markup.
12
+ */
13
+ export declare function isUnsafeSvgCloneAttribute(name: string): boolean;
@@ -0,0 +1 @@
1
+ function isUnsafeSvgCloneAttribute(name){const lower=name.toLowerCase();return lower.startsWith("on")||lower==="href"||lower==="xlink:href"}export{isUnsafeSvgCloneAttribute};
@@ -10,6 +10,9 @@
10
10
  * as a no-op -- `AnchoredValidityController` (the shared validity-refresh controller every
11
11
  * form-associated component uses) calls `internals.setValidity()` on every update, which would
12
12
  * otherwise throw the moment any of those components' `value` changes, not just at construction.
13
+ * `states` is a real `Set` -- several controls (e.g. `lr-input`) call
14
+ * `internals.states.add('blank')`/`.delete('blank')` on every update to drive a custom-state
15
+ * pseudo-class, which would otherwise throw on `add` of `undefined`.
13
16
  *
14
17
  * `attachInternals()` is specified on the `HTMLElement` interface (not `Element`), and every
15
18
  * `lr-*` component is an `HTMLElement` subclass (via `LitElement`), so this patches
@@ -29,6 +32,7 @@ interface StubValidityState {
29
32
  interface StubElementInternals {
30
33
  form: HTMLFormElement | null;
31
34
  labels: NodeList;
35
+ states: Set<string>;
32
36
  validity: StubValidityState;
33
37
  validationMessage: string;
34
38
  willValidate: boolean;
@@ -1 +1 @@
1
- function createStubInternals(){return{form:null,labels:document.createDocumentFragment().querySelectorAll("label"),validity:{valid:true},validationMessage:"",willValidate:true,setFormValue(){},checkValidity(){return true},reportValidity(){return true},setValidity(){}}}function installHappyDomFormAssociatedShims(){if(typeof HTMLElement==="undefined")return;if(typeof HTMLElement.prototype.attachInternals==="function")return;HTMLElement.prototype.attachInternals=function attachInternals(){return createStubInternals()}}function installStubInternalsForTest(_host){return createStubInternals()}export{installHappyDomFormAssociatedShims,installStubInternalsForTest};
1
+ function createStubInternals(){return{form:null,labels:document.createDocumentFragment().querySelectorAll("label"),states:new Set,validity:{valid:true},validationMessage:"",willValidate:true,setFormValue(){},checkValidity(){return true},reportValidity(){return true},setValidity(){}}}function installHappyDomFormAssociatedShims(){if(typeof HTMLElement==="undefined")return;if(typeof HTMLElement.prototype.attachInternals==="function")return;HTMLElement.prototype.attachInternals=function attachInternals(){return createStubInternals()}}function installStubInternalsForTest(_host){return createStubInternals()}export{installHappyDomFormAssociatedShims,installStubInternalsForTest};
@@ -17,18 +17,18 @@
17
17
 
18
18
  A compact chip representing one file queued for (or already part of) a chat message — used in a
19
19
  composer's pre-send attachment tray or a sent message's attachments display. Two independent ways
20
- to populate it: set `file` to a real `File` (fresh from a picker/drop), from which `name`/`size`/
21
- `mime-type` and the image thumbnail are all auto-derived; or set the plain `name`/`size`/
20
+ to populate it: set `file` to a real `File` (fresh from a picker/drop), from which `name`/`bytes`/
21
+ `mime-type` and the image thumbnail are all auto-derived; or set the plain `name`/`bytes`/
22
22
  `mime-type`/`thumbnail-src` props instead, for reconstructing a chip from server-persisted
23
23
  attachment metadata after a page reload, when no real `File` object exists any more. `file` always
24
24
  wins when both are present. When a real `File` or `preview-src` is available, the chip also offers
25
25
  a localized preview action that opens `<lr-document-viewer>` using the same effective MIME type.
26
26
 
27
27
  **Properties:**
28
- - `file?: File` (attribute `false`, i.e. property-only) — when set, `name`/`size`/`mimeType`/the
28
+ - `file?: File` (attribute `false`, i.e. property-only) — when set, `name`/`bytes`/`mimeType`/the
29
29
  image thumbnail are all derived from it, taking precedence over the independent props below
30
30
  - `name: string = ''` — filename, used only while `file` is unset
31
- - `size: number = 0` — file size in bytes, used only while `file` is unset
31
+ - `bytes: number = 0` — file size in bytes, used only while `file` is unset
32
32
  - `mimeType: string = ''` (attribute `mime-type`) — used only while `file` is unset
33
33
  - `thumbnailSrc: string = ''` (attribute `thumbnail-src`) — thumbnail image URL, used only while
34
34
  `file` is unset; rendered whenever present regardless of `mimeType` (no `file`-derived equivalent
@@ -61,6 +61,12 @@ a localized preview action that opens `<lr-document-viewer>` using the same effe
61
61
  - `untitledLabel: string = 'Untitled file'` (attribute `untitled-label`) — fallback filename and
62
62
  tooltip when neither `file` nor `name` supplies a name
63
63
 
64
+ **Renamed in 8.0.0 — breaking:** the byte count is `bytes`, not `size` (same rename as
65
+ `lr-file-icon`'s). Everywhere else in this library `size` names a tier on the shared size ladder,
66
+ and a numeric byte count answering to the same property name is a collision a consumer only
67
+ discovers at runtime. A leftover `size="245000"` is an unknown attribute now: `bytes` stays `0` and
68
+ the `size` part renders nothing.
69
+
64
70
  The component identifies *which* attachment a `lr-remove`/`lr-retry` event is about via the
65
71
  platform's own `id` attribute/property rather than a second, differently-named prop. Set `id="..."`
66
72
  when you have a stable server-side attachment id; when unset and `file` is set, a stable id is
@@ -73,7 +79,9 @@ mimeType, src }`, emitted when the preview action opens the document viewer)
73
79
 
74
80
  **Slots:** none.
75
81
 
76
- **CSS parts:** `base`, `thumbnail`, `meta`, `name`, `size`, `status-text` (the visible text twin of
82
+ **CSS parts:** `base`, `thumbnail`, `meta`, `name`, `size` (the formatted `bytes` count; the part
83
+ keeps its pre-rename name — it is the rendered size *text*, and renaming a part would break shipped
84
+ `::part()` rules for no gain), `status-text` (the visible text twin of
77
85
  the status accent color, so the state is carried in words and not only in color; empty and hidden
78
86
  for `pending`/`done`), `progress`, `progress-fill`, `spinner` (decorative/`aria-hidden` while the
79
87
  adjacent `status-text` supplies the wording), `retry-button`, `preview-button`,
@@ -116,13 +124,13 @@ decimal place), and a negative or non-finite input (`NaN`, `Infinity`) returns `
116
124
  size renders nothing instead of `"NaN B"`.
117
125
 
118
126
  ```html
119
- <lr-attachment-chip name="report.pdf" size="245000" mime-type="application/pdf" status="done"></lr-attachment-chip>
127
+ <lr-attachment-chip name="report.pdf" bytes="245000" mime-type="application/pdf" status="done"></lr-attachment-chip>
120
128
  <lr-attachment-chip id="att-2" status="uploading" progress="42"></lr-attachment-chip>
121
129
  <script type="module">
122
130
  import { formatFileSize } from '@aceshooting/lyra-ui/components/media/attachment-chip/file-size.js';
123
131
 
124
132
  const chip = document.createElement('lr-attachment-chip');
125
- chip.file = pickedFile; // name/size/mime-type/thumbnail all derived from the File
133
+ chip.file = pickedFile; // name/bytes/mime-type/thumbnail all derived from the File
126
134
  chip.addEventListener('lr-remove', (e) => removeAttachment(e.detail.id));
127
135
  chip.addEventListener('lr-retry', (e) => retryUpload(e.detail.id));
128
136
  chip.addEventListener('lr-preview', (e) => console.log(e.detail));
@@ -139,10 +147,10 @@ or to `undefined`, and again on disconnect. Because the same pass that allocates
139
147
  previous entry, reassigning `file` several times before the next paint leaks nothing.
140
148
 
141
149
  **Known gotchas:**
142
- - `file` always wins over `name`/`size`/`mimeType` when both are set — assigning those props while
150
+ - `file` always wins over `name`/`bytes`/`mimeType` when both are set — assigning those props while
143
151
  `file` is also set has no visible effect on the rendered chip.
144
- - A `0`-byte size and an unset size are indistinguishable (there's no separate flag for "genuinely
145
- empty file"); the `size` part is hidden entirely rather than showing a literal `"0 B"`.
152
+ - A `0` `bytes` value and an unset `bytes` value are indistinguishable (there's no separate flag for
153
+ "genuinely empty file"); the `size` part is hidden entirely rather than showing a literal `"0 B"`.
146
154
  - `progress` only renders as a numeric bar when `status="uploading"` **and** `progress` is finite
147
155
  and `> 0`; otherwise it's either nothing (non-`uploading` status) or the indeterminate spinner
148
156
  (`uploading` with no known progress).
@@ -40,6 +40,8 @@ goes back to `valueMissing`. It survives every child toggle, slot change and for
40
40
  Session restore uses a `FormData` state containing the repeated selected strings; it is independent
41
41
  of the control's current `name`, preserves duplicate-value cardinality, waits for early-arriving
42
42
  option children, and falls back to an empty selection for malformed state. Restoration is silent.
43
+ `click()` forwards focus to the first enabled checkbox, so the host behaves like a single control
44
+ rather than a no-op under a `<label>`-driven or programmatic click.
43
45
  **CSS parts:** `form-control`, `form-control-label`, `options` / `form-control-input`, `hint`,
44
46
  `error`.
45
47
  **The required marker.** `required` with a non-empty group `label` paints the library's shared
@@ -33,7 +33,9 @@ restores the control's own computed validity rather than forcing it valid — a
33
33
  field edit) and `form.reset()`, exactly like a native control, where only another
34
34
  `setCustomValidity('')` clears it. The message is caller-supplied and is used verbatim, never
35
35
  localized, and it is whole-control state: it does not land in `errors`, which is keyed by the
36
- csspart of the field a message belongs to.
36
+ csspart of the field a message belongs to. `click()` forwards focus to the first rendered field
37
+ (start/end/hop-limit/direction/save-name, in that order), so the host behaves like a single
38
+ control rather than a no-op under a `<label>`-driven or programmatic click.
37
39
 
38
40
  **Events:** `lr-input`, `lr-validity-change`, `lr-invalid` (no detail; one bubbling/composed alias
39
41
  when the complete builder fails a native validity check),
@@ -8,7 +8,7 @@
8
8
  - **Status** `stable` since `6.0.0` — see the maturity and deprecation policy in `llms/shared.md`
9
9
  - **Deprecations** none
10
10
  - **Optional peers** none
11
- - **Themeable via** 11 parts, 15 custom properties — see this component's own `@csspart`/`@cssprop` list below
11
+ - **Themeable via** 12 parts, 15 custom properties — see this component's own `@csspart`/`@cssprop` list below
12
12
  - **Library-wide behavior** (events, form association, `locale`/`strings`, tokens, TS types): `llms/shared.md`
13
13
 
14
14
  ---
@@ -85,9 +85,11 @@ required picker with nothing committed goes back to `valueMissing`. It survives
85
85
 
86
86
  **Slots:** `label`, `hint`, `error`.
87
87
 
88
- **CSS parts:** `form-control`, `form-control-label`, `trigger`, `listbox`, `option`,
89
- `option-flag` (present only while `showFlags` is on), `option-label`, `option-tag` (the row's
90
- secondary line — the raw BCP-47 tag), `expand-icon`, `hint`, `error`.
88
+ **CSS parts:** `form-control`, `form-control-label`, `trigger`,
89
+ `trigger-flag` (the trigger's leading `<lr-flag>` for the current value, present only while
90
+ `showFlags` is on), `listbox`, `option`, `option-flag` (present only while `showFlags` is on),
91
+ `option-label`, `option-tag` (the row's secondary line — the raw BCP-47 tag), `expand-icon`,
92
+ `hint`, `error`.
91
93
 
92
94
  **The required marker.** `required` with a non-empty `label` paints the library's shared marker on
93
95
  `[part="form-control-label"]` — the one `::after` rule described under "The required-field marker"
@@ -71,4 +71,6 @@ options and its messages, scaled by `size` through the shared control ladder.
71
71
  **Methods:** `setCustomValidity(message = '')` sets or clears a group-level consumer error. A
72
72
  non-empty message raises `customError` and blocks submission; `setCustomValidity('')` and
73
73
  `resetValidity()` restore the group's computed validity, including `valueMissing` when a required
74
- group has no selected radio.
74
+ group has no selected radio. `focus()` moves focus to the selected (or first enabled) radio;
75
+ `click()` mirrors it by activating that same radio, so the group behaves like a single control
76
+ under both APIs rather than leaving `click()` a no-op.
@@ -46,6 +46,8 @@ express ("this item was already annotated by someone else"): a non-empty message
46
46
  required keys, and any key with an unsupported `type`, still hold it invalid. It is independent of
47
47
  the per-key `errors` map, which stays a read-out of this rubric's own field rules, so a message set
48
48
  here is never attributed to one key. It survives every `value`/`keys` write and a form reset.
49
+ `click()` forwards to the active field (the same one a submit-and-next transition auto-focuses),
50
+ so the host behaves like a single control under both a `<label>`-driven and a programmatic click.
49
51
 
50
52
  **CSS parts:** `base` (the outer `role="group"` wrapper), `field` (one key's wrapper), `label`, `description`,
51
53
  `scale` (the rendered score/category/comment control's wrapper), `error` (a field-level validation
@@ -87,6 +87,9 @@ and makes the form invalid instead of being silently accepted.
87
87
  re-runs the validity sync) and a `form.reset()`, matching a native control. The message is
88
88
  whole-control state, so it is deliberately absent from `errors`, which is keyed by schema
89
89
  property; it is caller-supplied content and is used verbatim, never localized.
90
+ - `click(): void` — forwards a host click to the first generated field's control, so the form
91
+ behaves like a single control under both a `<label>`-driven and a programmatic click; a no-op
92
+ while `disabled`.
90
93
 
91
94
  **Events:** `lr-input` (`detail: { value: Record<string, unknown> }` — the full current value
92
95
  object, every property with defaults resolved, not just the field that changed), `lr-validity-change`
package/llms/peers.md CHANGED
@@ -38,7 +38,7 @@ changes the component library version without installing a supported SheetJS rel
38
38
  | `d3-force` | `^3.0.0` | `lr-graph`, `lr-knowledge-graph-explorer` |
39
39
  | `d3-selection` | `^3.0.0` | `lr-graph`, `lr-knowledge-graph-explorer` |
40
40
  | `d3-zoom` | `^3.0.0` | `lr-graph`, `lr-knowledge-graph-explorer` |
41
- | `dompurify` | `^3.4.12` | `lr-docx-viewer`, `lr-email-viewer`, `lr-html-viewer`, `lr-icon`, `lr-include`, `lr-markdown`, `lr-markdown-core`, `lr-message-parts`, `lr-notebook-viewer`, `lr-svg-viewer`, `lr-widget-renderer` |
41
+ | `dompurify` | `^3.4.13` | `lr-docx-viewer`, `lr-email-viewer`, `lr-html-viewer`, `lr-icon`, `lr-include`, `lr-markdown`, `lr-markdown-core`, `lr-message-parts`, `lr-notebook-viewer`, `lr-svg-viewer`, `lr-widget-renderer` |
42
42
  | `emoji-picker-element-data` | `^1.8.0` | `lr-emoji-picker` |
43
43
  | `epubjs` | `^0.3.93` | `lr-ebook-viewer` |
44
44
  | `ical.js` | `^2.2.1` | `lr-calendar-viewer` |
@@ -47,13 +47,13 @@ changes the component library version without installing a supported SheetJS rel
47
47
  | `libphonenumber-js` | `>=1.11.0 <2` | `lr-phone-input` |
48
48
  | `mammoth` | `^1.12.0` | `lr-docx-viewer` |
49
49
  | `maplibre-gl` | `>=5 <7` | `lr-geojson-view`, `lr-map` |
50
- | `marked` | `^18.0.7` | `lr-markdown`, `lr-markdown-core`, `lr-message-parts`, `lr-widget-renderer` |
50
+ | `marked` | `^18.0.9` | `lr-markdown`, `lr-markdown-core`, `lr-message-parts`, `lr-widget-renderer` |
51
51
  | `papaparse` | `^5.5.4` | `lr-csv-viewer`, `lr-dataset-viewer` |
52
52
  | `pdfjs-dist` | `^6.2.108` | `lr-pdf-viewer` |
53
53
  | `postal-mime` | `^2.7.5` | `lr-email-viewer` |
54
54
  | `qrcode` | `^1.5.4` | `lr-qr-code` |
55
55
  | `react` | `>=19 <20` | type-only `@aceshooting/lyra-ui/custom-elements-jsx` entry (no runtime import) |
56
- | `shiki` | `^4.3.1` | `lr-code-block`, `lr-code-block-core`, `lr-diff-view`, `lr-document-compare`, `lr-markdown`, `lr-markdown-core`, `lr-message-parts`, `lr-widget-renderer` |
56
+ | `shiki` | `^4.4.2` | `lr-code-block`, `lr-code-block-core`, `lr-diff-view`, `lr-document-compare`, `lr-markdown`, `lr-markdown-core`, `lr-message-parts`, `lr-widget-renderer` |
57
57
  | `svelte` | `>=5 <6` | type-only `@aceshooting/lyra-ui/svelte` entry (no runtime import) |
58
58
  | `vue` | `>=3.5 <4` | type-only `@aceshooting/lyra-ui/vue` entry (no runtime import) |
59
59
  | `xlsx` | `>=0.20.3 <0.21.0` | `lr-spreadsheet-viewer` |