@aiquants/markdown-explorer 0.0.0-stage → 0.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 (78) hide show
  1. package/CHANGELOG.md +121 -0
  2. package/LICENSE +21 -0
  3. package/README.md +606 -2
  4. package/dist/ExplorerSplit-D2plJRRe.cjs +1 -0
  5. package/dist/ExplorerSplit-DB37U7Kh.js +1362 -0
  6. package/dist/MultiLayout-DCPDu1-l.js +909 -0
  7. package/dist/MultiLayout-UyWxs6Xy.cjs +1 -0
  8. package/dist/TreeLayout-BoyFelK2.js +22 -0
  9. package/dist/TreeLayout-CLWbWjOc.cjs +1 -0
  10. package/dist/client/MarkdownExplorer.d.cts +30 -0
  11. package/dist/client/MarkdownExplorer.d.ts +30 -0
  12. package/dist/client/storage.d.cts +11 -0
  13. package/dist/client/storage.d.ts +11 -0
  14. package/dist/core/config.d.cts +77 -0
  15. package/dist/core/config.d.ts +77 -0
  16. package/dist/core/contracts.d.cts +155 -0
  17. package/dist/core/contracts.d.ts +155 -0
  18. package/dist/core/geometry.d.cts +51 -0
  19. package/dist/core/geometry.d.ts +51 -0
  20. package/dist/core/labels.d.cts +180 -0
  21. package/dist/core/labels.d.ts +180 -0
  22. package/dist/core/location.d.cts +82 -0
  23. package/dist/core/location.d.ts +82 -0
  24. package/dist/core/paths.d.cts +17 -0
  25. package/dist/core/paths.d.ts +17 -0
  26. package/dist/core/revalidation.d.cts +2 -0
  27. package/dist/core/revalidation.d.ts +2 -0
  28. package/dist/core/theme.d.cts +6 -0
  29. package/dist/core/theme.d.ts +6 -0
  30. package/dist/core/treeSettings.d.cts +48 -0
  31. package/dist/core/treeSettings.d.ts +48 -0
  32. package/dist/core/viewSettings.d.cts +15 -0
  33. package/dist/core/viewSettings.d.ts +15 -0
  34. package/dist/dataRoute-Bkfwfp1R.js +194 -0
  35. package/dist/dataRoute-CKbdwkQ7.cjs +1 -0
  36. package/dist/index-BfuAu2GV.js +2107 -0
  37. package/dist/index-Cx3-jSna.cjs +3 -0
  38. package/dist/index.cjs +1 -0
  39. package/dist/index.d.cts +12 -0
  40. package/dist/index.d.ts +12 -0
  41. package/dist/index.js +44 -0
  42. package/dist/location-Oo21lTyV.cjs +1 -0
  43. package/dist/location-fVl2R1ee.js +395 -0
  44. package/dist/sanitizeWorker.cjs +1 -0
  45. package/dist/sanitizeWorker.js +281 -0
  46. package/dist/server/anonymous.d.cts +10 -0
  47. package/dist/server/anonymous.d.ts +10 -0
  48. package/dist/server/createMarkdownExplorer.d.cts +12 -0
  49. package/dist/server/createMarkdownExplorer.d.ts +12 -0
  50. package/dist/server/errors.d.cts +26 -0
  51. package/dist/server/errors.d.ts +26 -0
  52. package/dist/server/fileSystemSource.d.cts +38 -0
  53. package/dist/server/fileSystemSource.d.ts +38 -0
  54. package/dist/server/ports.d.cts +107 -0
  55. package/dist/server/ports.d.ts +107 -0
  56. package/dist/server/sanitizeProtocol.d.cts +17 -0
  57. package/dist/server/sanitizeProtocol.d.ts +17 -0
  58. package/dist/server/sanitizer.d.cts +51 -0
  59. package/dist/server/sanitizer.d.ts +51 -0
  60. package/dist/server/workerPool.d.cts +42 -0
  61. package/dist/server/workerPool.d.ts +42 -0
  62. package/dist/server.cjs +1 -0
  63. package/dist/server.d.cts +7 -0
  64. package/dist/server.d.ts +7 -0
  65. package/dist/server.js +1253 -0
  66. package/dist/storage-Bkb2Axdi.cjs +1 -0
  67. package/dist/storage-DA4ItHzl.js +60 -0
  68. package/dist/storage.cjs +1 -0
  69. package/dist/storage.d.cts +1 -0
  70. package/dist/storage.d.ts +1 -0
  71. package/dist/storage.js +4 -0
  72. package/dist/styles/markdown-explorer.css +3 -0
  73. package/docs/behavior/dom-hooks.md +95 -0
  74. package/docs/behavior/layout.md +215 -0
  75. package/docs/behavior/localization.md +48 -0
  76. package/docs/behavior/security.md +138 -0
  77. package/docs/behavior/url-contract.md +135 -0
  78. package/package.json +141 -3
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const N=require("react/jsx-runtime"),u=require("react"),F=require("./location-Oo21lTyV.cjs"),q=require("./index-Cx3-jSna.cjs"),ne=require("./ExplorerSplit-D2plJRRe.cjs"),k=require("@aiquants/drag-drop-panels"),be=require("./dataRoute-CKbdwkQ7.cjs"),de=require("react-router"),Z=require("./storage-Bkb2Axdi.cjs"),Fe=require("react-dom"),je=0xcbf29ce484222325n,Be=0x100000001b3n,Ve=(1n<<64n)-1n,$e=(1n<<53n)-1n,Ue=new TextEncoder,Ge=e=>{let n=je;for(const t of Ue.encode(e))n=(n^BigInt(t))*Be&Ve;return Number(n&$e)},J=256,Ye=e=>`aqmx-p-${Ge(e).toString(36)}`,Ce=(e,n)=>{const t=Ye(e);let o=t;for(let r=2;n.has(o);r+=1)o=`${t}-${String(r)}`;return o},We=new Map,Ke=(e,n=We)=>{const t=new Set(e.flatMap(r=>n.get(r)??[])),o=new Map;for(const r of e){const s=n.get(r)??Ce(r,t);t.add(s),o.set(r,s)}return o},Oe=(e,n,t)=>{const o=e.columnOf.get(n);return o===void 0?void 0:Math.min(t-1,Math.max(0,o))},Pe=(e,n)=>{const[t,...o]=F.columnGroups(n.logical,n.visible);if(t===void 0)throw new RangeError("[markdown-explorer] there must be at least one visible column");const r=([a,p])=>e.slice(a,p).reduce((l,g)=>l+g.length,0);let s=t;for(const a of o)r(a)<r(s)&&(s=a);let i=s[0];for(let a=s[0];a<s[1];a+=1)(e[a]?.length??0)<(e[i]?.length??0)&&(i=a);return i},X=(e,n)=>{const t=Array.from({length:n.logical},()=>[]),o=[];for(const r of e.docs){const s=Oe(e,r,n.logical);s===void 0?o.push(r):t[s]?.push(r)}for(const r of o)t[Pe(t,n)]?.push(r);return t},Je=(e,n)=>F.columnGroups(e.length,n).map(([t,o])=>e.slice(t,o).flat()),Xe=(e,n,t)=>{const[o,r]=n,s=r-o,i=e.length,a=Array.from({length:s},(d,h)=>{const f=[0];for(const C of e)f.push((f.at(-1)??0)+(t(C)===o+h?1:0));return f}),p=(d,h,f)=>(a[d]?.[f]??0)-(a[d]?.[h]??0),l=Array.from({length:s+1},()=>Array.from({length:i+1},()=>Number.NEGATIVE_INFINITY)),g=Array.from({length:s+1},()=>Array.from({length:i+1},()=>0)),w=l[0];w&&(w[0]=0);for(let d=0;d<s;d+=1)for(let h=0;h<=i;h+=1)for(let f=0;f<=h;f+=1){const C=(l[d]?.[f]??Number.NEGATIVE_INFINITY)+p(d,f,h),E=l[d+1],L=g[d+1];E&&L&&C>(E[h]??Number.NEGATIVE_INFINITY)&&(E[h]=C,L[h]=f)}const P=Array.from({length:s},()=>[]);let O=i;for(let d=s;d>0;d-=1){const h=g[d]?.[O]??0;P[d-1]=e.slice(h,O),O=h}return P},Me=(e,n)=>{const t=n.flat(),o=new Map(e.columnOf);for(const[r,s]of n.entries())for(const i of s)o.delete(i),o.set(i,r);for(const r of o.keys()){if(o.size<=J)break;o.delete(r)}return{docs:t,columnOf:o}},Ze=(e,n,t,o)=>{if(e.docs.includes(n))return{state:e,outcome:"existing"};if(e.docs.length>=o)return{state:e,outcome:"rejected"};const r=X(e,t),s=Oe(e,n,t.logical)??Pe(r,t);r[s]?.push(n);const i=new Map(e.panelIds);return i.set(n,Ce(n,new Set(i.values()))),{state:{...e,...Me(e,r),panelIds:i},outcome:"opened"}},Le=(e,n)=>{if(!e.docs.includes(n))return e;const t=new Set(e.hidden);t.delete(n);const o=new Map(e.panelIds);return o.delete(n),{...e,docs:e.docs.filter(r=>r!==n),hidden:t,panelIds:o,maximized:e.maximized===n?null:e.maximized}},Qe=(e,n,t,o)=>{if(e.hidden.has(n))return{state:Ne(e,n,!1),outcome:"shown"};if(e.docs.includes(n))return{state:Le(e,n),outcome:"closed"};const r=Ze(e,n,t,o);return{state:r.state,outcome:r.outcome==="rejected"?"rejected":"opened"}},en=(e,n,t)=>{if(n===t||!e.docs.includes(n))return{state:e,outcome:"ignored"};if(e.docs.includes(t))return{state:e,outcome:"existing"};const o=new Map(e.columnOf),r=o.get(n);r!==void 0&&(o.delete(t),o.set(t,r));const s=new Set(e.hidden);s.delete(n);const i=new Map(e.panelIds),a=i.get(n);if(a===void 0)throw new Error(`[markdown-explorer] the open document ${JSON.stringify(n)} has no panel id`);return i.delete(n),i.set(t,a),{state:{docs:e.docs.map(p=>p===n?t:p),maximized:e.maximized===n?t:e.maximized,columnOf:o,hidden:s,panelIds:i},outcome:"navigated"}},Ne=(e,n,t)=>{if(!e.docs.includes(n)||e.hidden.has(n)===t)return e;const o=new Set(e.hidden);return t?o.add(n):o.delete(n),{...e,hidden:o,maximized:t&&e.maximized===n?null:e.maximized}},nn=(e,n)=>{if(e.maximized===n||n!==null&&!e.docs.includes(n))return e;if(n===null||!e.hidden.has(n))return{...e,maximized:n};const t=new Set(e.hidden);return t.delete(n),{...e,maximized:n,hidden:t}},tn=(e,n,t)=>{const o=X(e,t),r=new Map;for(const[l,g]of o.entries())for(const w of g)r.set(w,l);const s=new Set(e.docs),i=new Set,a=F.columnGroups(t.logical,t.visible),p=Array.from({length:t.logical},()=>[]);for(const[l,g]of a.entries()){const w=(n[l]??[]).filter(P=>s.has(P)&&!i.has(P));for(const P of w)i.add(P);for(const[P,O]of Xe(w,g,d=>r.get(d)).entries())p[g[0]+P]?.push(...O)}for(const l of e.docs)i.has(l)||p[r.get(l)??0]?.push(l);return p.every((l,g)=>l.length===o[g]?.length&&l.every((w,P)=>o[g]?.[P]===w))?e:{...e,...Me(e,p)}},Q=(e,n)=>{const t=[...new Set(e.docs)].slice(0,n),o=new Set(t),r=e.maximized!==null&&o.has(e.maximized)?e.maximized:null;return{docs:t,maximized:r,columnOf:e.stored.columnOf,hidden:new Set([...e.stored.hidden].filter(s=>o.has(s)&&s!==r)),panelIds:Ke(t,e.panelIds)}},me=(e,n)=>{if(e.docs.every(o=>e.columnOf.has(o)))return e;const t=new Map(e.columnOf);for(const[o,r]of X(e,n).entries())for(const s of r)t.delete(s),t.set(s,o);for(const o of t.keys()){if(t.size<=J)break;t.delete(o)}return{...e,columnOf:t}},Te=1,B=Object.freeze({columnOf:new Map,hidden:new Set}),on=(e,n)=>{if(e===null||e==="")return B;let t;try{t=JSON.parse(e)}catch{return B}if(t===null||typeof t!="object"||Array.isArray(t))return B;const o=t;if(o.v!==Te)return B;const r=new Map;if(Array.isArray(o.columnOf))for(const i of o.columnOf.slice(-J))Array.isArray(i)&&i.length===2&&typeof i[0]=="string"&&i[0]!==""&&Number.isInteger(i[1])&&i[1]>=0&&i[1]<n&&(r.delete(i[0]),r.set(i[0],i[1]));const s=new Set(Array.isArray(o.hidden)?o.hidden.filter(i=>typeof i=="string"&&i!==""):[]);return{columnOf:r,hidden:s}},rn=e=>JSON.stringify({v:Te,columnOf:[...e.columnOf.entries()].slice(-J),hidden:e.docs.filter(n=>e.hidden.has(n))}),oe=(e,n)=>{const t=e.get(n);return t===void 0?be.lastPathSegment(n):t},U=e=>{const n=new Map;for(const[t,o]of e.panelIds)n.set(o,t);return n},fe=e=>{if(!be.isAcceptableDocumentPath(e))throw new RangeError(`[markdown-explorer] not an acceptable document path: ${JSON.stringify(e.slice(0,80))}`)},sn=({config:e,location:n,writeUrl:t,persist:o})=>{const{maxPanels:r,columns:s}=e.multiView,i=q.createEmitter(),a=new Map,p=new Map;let l={layout:Q({docs:n.docs,maximized:n.maximized,stored:B},r),source:n.source,visibleColumns:s,ready:!1,splitDragging:!1,titles:new Map,pendingHashes:new Map},g=!1;const w=c=>g?me(c,{logical:s,visible:l.visibleColumns}):c,P=(c,y)=>F.explorerHref(e,{view:"multi",source:c,docs:y.docs,maximized:y.maximized});let O=P(n.source,n),d=n.source,h=O;const f=[],C=[];let E=null;const L=()=>{if(!(f.length>0))for(const c of C.splice(0))c()},m=c=>{l={...l,...c},i.emit()},S=()=>{if(!l.ready)return;const c=rn(l.layout);c!==E&&(E=c,o(c))},v=(c,y,M)=>{const R=P(c,y);R!==O&&(O=R,d=c,f.push(R),t(R,M))},T=c=>{const y=new Set(c.panelIds.values());for(const b of[...a.keys()])y.has(b)||a.delete(b);for(const b of[...p.keys()])y.has(b)||p.delete(b);const M=new Set(c.docs),R=[...l.titles.keys()].every(b=>M.has(b))?l.titles:new Map([...l.titles].filter(([b])=>M.has(b))),x=[...l.pendingHashes.keys()].every(b=>y.has(b))?l.pendingHashes:new Map([...l.pendingHashes].filter(([b])=>y.has(b)));return{titles:R,pendingHashes:x}},I=c=>c===l.layout?!1:(m({layout:c,...T(c)}),v(d,c,"replace"),S(),!0),_=()=>({logical:s,visible:l.visibleColumns});return{getSnapshot:()=>l,subscribe:i.subscribe,toggle:c=>{fe(c);const{state:y,outcome:M}=Qe(l.layout,c,_(),r);return I(y),M},close:c=>I(Le(l.layout,c)),navigate:(c,y)=>{fe(y);const{state:M,outcome:R}=en(l.layout,c,y);if(R!=="navigated")return R;const x=M.panelIds.get(y);return x!==void 0&&(a.delete(x),p.delete(x)),I(M),R},setHidden:(c,y)=>I(Ne(l.layout,c,y)),maximize:c=>I(nn(l.layout,c)),arrange:c=>I(tn(l.layout,c,{logical:s,visible:c.length})),changeSource:c=>{v(c,l.layout,"push")},observeLocation:c=>{const y=P(c.source,c);if(y===O)return f.length=0,h=y,c.source!==l.source&&m({source:c.source}),L(),!1;if(y===h)return!1;h=y;const M=f.indexOf(y);if(M>=0)return f.splice(0,M+1),c.source!==l.source&&m({source:c.source}),L(),!1;f.length=0,O=y,d=c.source;const R=w(Q({docs:c.docs,maximized:c.maximized,stored:{columnOf:l.layout.columnOf,hidden:l.layout.hidden},panelIds:l.layout.panelIds},r));return m({layout:R,source:c.source,...T(R)}),S(),L(),!0},whenUrlRendered:c=>{C.push(c),L()},loadStored:c=>{m({layout:w(Q({docs:l.layout.docs,maximized:l.layout.maximized,stored:c,panelIds:l.layout.panelIds},r)),ready:!0}),S()},setVisibleColumns:c=>{if(!Number.isInteger(c)||c<1||c>s)throw new RangeError(`[markdown-explorer] visible columns must be an integer in 1..${String(s)}; got ${String(c)}`);g=!0;const y=me(l.layout,{logical:s,visible:c});c===l.visibleColumns&&y===l.layout||(m({visibleColumns:c,layout:y}),y!==l.layout&&S())},setSplitDragging:c=>{c!==l.splitDragging&&m({splitDragging:c})},setTitle:(c,y)=>{!l.layout.docs.includes(c)||l.titles.get(c)===y||m({titles:new Map(l.titles).set(c,y)})},titleOf:c=>oe(l.titles,c),setPendingHash:(c,y)=>{const M=l.pendingHashes.get(c);if(y===null||y===""){if(M===void 0)return;const R=new Map(l.pendingHashes);R.delete(c),m({pendingHashes:R});return}M!==y&&m({pendingHashes:new Map(l.pendingHashes).set(c,y)})},saveReadingPosition:(c,y,M)=>{l.layout.panelIds.get(y)===c&&a.set(c,{doc:y,position:M})},readingPositionOf:(c,y)=>{const M=a.get(c);return M===void 0||M.doc!==y?null:M.position},saveImageView:(c,y,M)=>{p.set(c,{url:y,state:M})},imageViewOf:(c,y)=>{const M=p.get(c);return M===void 0||M.url!==y?null:M.state}}},ln=()=>{const e=new Map;return{hold:(n,t)=>{e.set(n,t),queueMicrotask(()=>{e.get(n)===t&&e.delete(n)})},take:n=>{const t=e.get(n);return e.delete(n),t===void 0?null:t}}},Ie=u.createContext(null),re=()=>{const e=u.use(Ie);if(e===null)throw new Error("[markdown-explorer] multi-view panels must be rendered inside the multi-view stage");return e},cn=(e,n)=>{const t=e.pendingHashes.get(n);return t===void 0?null:t},se="data-aqmx-column-probe",Y="data-panel-id",te="--aqmx-multi-panel-chrome",j=e=>e.endsWith("px")?Number.parseFloat(e):Number.NaN,an=e=>e==="normal"?0:j(e),un=(e,n)=>{const t=e.querySelector(k.SCROLL_ROOT_SELECTOR)?.firstElementChild,o=e.querySelector(`[${se}]`),r=o instanceof HTMLElement?o.getBoundingClientRect().width:Number.NaN;if(!(t instanceof HTMLElement))return{plan:{trackInlineSize:Number.NaN,gap:Number.NaN,minColumnInlineSize:r,logicalColumns:n},stageBlockSize:Number.NaN};const s=getComputedStyle(t),i=t.clientWidth-j(s.paddingLeft)-j(s.paddingRight),a=t.clientHeight-j(s.paddingTop)-j(s.paddingBottom);return{plan:{trackInlineSize:i,gap:an(s.columnGap),minColumnInlineSize:r,logicalColumns:n},stageBlockSize:a}},dn=(e,n)=>{if(e.getClientRects().length===0)return Number.NaN;const t=getComputedStyle(e);return n.getBoundingClientRect().top-e.getBoundingClientRect().top+j(t.paddingBottom)+j(t.borderBottomWidth)},A=(e,n)=>{const t=()=>n(e.getSnapshot());return u.useSyncExternalStore(e.subscribe,t,t)},mn=e=>{const{config:n,storageNamespace:t}=q.useExplorer(),o=de.useNavigate(),r=u.useRef(o),s=Z.storageKeys(t).multiLayout,[i]=u.useState(()=>sn({config:n,location:e,writeUrl:(l,g)=>{r.current(l,q.explorerNavigationOptions(g==="replace"?"browse":"switch-source"))},persist:l=>Z.writeStorage(s,l)}));u.useLayoutEffect(()=>{r.current=o},[o]);const a=de.useLocation(),p=u.useMemo(()=>({location:e,navigated:a}),[e,a]);return u.useLayoutEffect(()=>{i.observeLocation(p.location)},[i,p]),u.useLayoutEffect(()=>{i.loadStored(on(Z.readStorage(s),n.multiView.columns))},[i,s,n]),i},Re="[data-aqdd-scroll-area]",W="data-aqmx-panel-frame",pe="--aqmx-multi-panel-pinned-block-size",fn=e=>{const{docPath:n,panelId:t}=e;if(typeof n!="string"||typeof t!="string")throw new TypeError("[markdown-explorer] a multi-view panel needs string docPath and panelId props");return{docPath:n,panelId:t}},pn=e=>{const n=getComputedStyle(e),t=Number.parseFloat(n.lineHeight);return Number.isFinite(t)?t:Number.parseFloat(n.fontSize)},gn=(e,n,t)=>e.deltaMode===WheelEvent.DOM_DELTA_PAGE?e.deltaY*n.clientHeight:e.deltaMode!==WheelEvent.DOM_DELTA_LINE?e.deltaY:e.deltaY*t(n),V=e=>{const n=e.closest(Re);return n instanceof HTMLElement?n:null},De=e=>{const n=e.firstElementChild;return n instanceof HTMLElement&&getComputedStyle(n).position==="sticky"?n:null},ke=(e,n)=>{const t=n.getBoundingClientRect().top,o=De(e);return o===null?t:Math.max(t,o.getBoundingClientRect().bottom)},ge=(e,n)=>{let t=0,o=e.length;for(;t<o;){const r=t+o>>>1;(e[r]?.getBoundingClientRect().bottom??Number.NEGATIVE_INFINITY)>n?o=r:t=r+1}return t<e.length?t:-1},hn=(e,n)=>{const t=ke(e,n),o=[];let r=e;for(let s=ge([...r.children],t);s>=0;s=ge([...r.children],t)){const i=r.children[s];if(i===void 0)break;o.push(s),r=i}return{scrollTop:n.scrollTop,anchor:o.length===0?null:{path:o,offset:r.getBoundingClientRect().top-t}}},he=(e,n,t)=>{if(n.scrollTop=t.scrollTop,t.anchor===null)return;let o=e;for(const r of t.anchor.path)o=o?.children[r];o!==void 0&&(n.scrollTop+=o.getBoundingClientRect().top-ke(e,n)-t.anchor.offset)},vn=Object.freeze(["data-testid","aria-label","title","href","id","name"]),Ae=e=>JSON.stringify([e.tagName,...vn.map(n=>e.getAttribute(n))]),yn=(e,n)=>{if(n===null||!e.contains(n))return null;const t=[];for(let o=n;o!==e;){const r=o.parentElement;if(r===null)return null;t.unshift([...r.children].indexOf(o)),o=r}return{path:t,signature:Ae(n)}},wn=(e,n,t)=>{let o=e;for(const r of t.path)o=o?.children[r];o instanceof HTMLElement&&Ae(o)===t.signature&&q.focusWithoutScroll(o)||n.focus({preventScroll:!0})},xn=(e,n,t)=>{if(e.shiftKey||Math.abs(e.deltaX)>Math.abs(e.deltaY))return;const o=e.ctrlKey||e.metaKey,r=o?V(n):n.closest(k.SCROLL_ROOT_SELECTOR);if(!(r instanceof HTMLElement))return;const s=gn(e,r,t);(o||En(r,s))&&(e.preventDefault(),r.scrollTop+=s)},En=(e,n)=>n<0?e.scrollTop>0:n>0?Math.ceil(e.scrollTop+e.clientHeight)<e.scrollHeight:!1,Sn=e=>e.scrollHeight>e.clientHeight,bn=(e,n,t)=>{let o=Number.NaN,r=Number.NaN;const s=De(t),i=()=>{const l=dn(e,n);if(!Number.isFinite(l))return;const g=s===null?0:s.getBoundingClientRect().height;g!==r&&(r=g,t.style.setProperty(pe,`${String(g)}px`));const w=l+g;w!==o&&(o=w,e.style.setProperty(te,`${String(w)}px`))};i();let a=null;const p=typeof ResizeObserver>"u"?null:new ResizeObserver(()=>{a===null&&(a=requestAnimationFrame(()=>{a=null,i()}))});return p?.observe(e),p?.observe(n),s!==null&&p?.observe(s),()=>{p?.disconnect(),a!==null&&cancelAnimationFrame(a),e.style.removeProperty(te),t.style.removeProperty(pe)}},Cn=e=>{const{docPath:n,panelId:t}=fn(e),{store:o,Body:r,maximize:s,focusCarry:i}=re(),a=A(o,d=>d.layout.maximized===n),p=A(o,d=>oe(d.titles,n)),l=u.useRef(null),g=u.useRef(null),w=u.useRef(null);u.useEffect(()=>{const d=l.current,h=d===null?null:V(d);if(d===null||h===null||a)return;const f=new Map,C=v=>{const T=f.get(v);if(T!==void 0)return T;const I=pn(v);return f.set(v,I),I},E=v=>xn(v,d,C);let L=!1;const m=()=>{const v=Sn(h);v!==L&&(L=v,v?d.addEventListener("wheel",E,{capture:!0,passive:!1}):d.removeEventListener("wheel",E,{capture:!0}))};m();const S=typeof ResizeObserver>"u"?null:new ResizeObserver(m);return S?.observe(h),S?.observe(d),()=>{S?.disconnect(),d.removeEventListener("wheel",E,{capture:!0})}},[a]),u.useLayoutEffect(()=>{const d=l.current,h=d===null?null:V(d),f=d===null?null:d.closest(`[${Y}]`);if(!(d===null||h===null||!(f instanceof HTMLElement)))return bn(f,h,d)},[]),u.useLayoutEffect(()=>{const d=l.current,h=d===null?null:V(d);if(d===null||h===null)return;const f=o.readingPositionOf(t,n);g.current=f===null?null:{doc:n,position:f},f!==null&&he(d,h,f);let C=null;const E=()=>{C===null&&(C=requestAnimationFrame(()=>{C=null;const L=w.current;L!==null&&o.saveReadingPosition(t,L,hn(d,h))}))};return h.addEventListener("scroll",E,{passive:!0}),()=>{h.removeEventListener("scroll",E),C!==null&&cancelAnimationFrame(C)}},[o,t,n]),u.useLayoutEffect(()=>{const d=l.current,h=d===null?null:d.closest(`[${Y}]`);if(d===null||h===null)return;const f=i.take(t);return f!==null&&wn(h,d,f),()=>{const C=yn(h,h.ownerDocument.activeElement);C!==null&&i.hold(t,C)}},[i,t]);const P=u.useCallback(d=>{const h=l.current,f=h===null?null:V(h);if(h===null||f===null)return;const C=w.current;w.current=d;const E=g.current;g.current=null,E!==null&&E.doc===d?he(h,f,E.position):C!==null&&C!==d&&(f.scrollTop=0)},[]),O=u.useCallback(()=>s(n),[s,n]);return N.jsx("div",{ref:l,role:"group","aria-label":p,className:"aqmx-multi-panel-frame",tabIndex:-1,"data-aqmx-panel-frame":t,"data-aqmx-maximized":a?"true":"false","data-testid":"markdown-explorer-panel-frame",onDoubleClick:a?void 0:O,children:N.jsx(r,{docPath:n,panelId:t,maximized:a,title:p,onContentShown:P})})},On=u.memo(Cn),Pn=e=>{const n=e.closest(Re);if(n===null)throw new Error("[markdown-explorer] a panel's document region is not inside the panel's scroll area");return n},Mn=({docPath:e,panelId:n,maximized:t,title:o,onContentShown:r})=>{const{store:s,followLink:i,revealInPanel:a}=re(),{announcer:p}=q.useExplorer(),l=A(s,E=>cn(E,n)),g=u.useCallback((E,L)=>i(n,e,E,L),[i,n,e]),w=u.useCallback(()=>s.setPendingHash(n,null),[s,n]),P=u.useMemo(()=>({read:E=>s.imageViewOf(n,E),save:(E,L)=>s.saveImageView(n,E,L)}),[s,n]),O=u.useCallback((E,L)=>{L.kind!=="failure"&&s.setTitle(E,L.name),r(E)},[s,r]),d=u.useCallback(E=>{s.whenUrlRendered(()=>p.announce(E))},[s,p]),h=u.useMemo(()=>({scrollerOf:Pn,reveal:E=>a(n,E)}),[a,n]),f=u.useMemo(()=>({kind:"panel",maximized:t,onDocumentLink:g,pendingHash:l,onHashConsumed:w,announceFailure:d,paneScroll:h}),[t,g,l,w,d,h]),C=u.useMemo(()=>({kind:"panel",documentName:o}),[o]);return N.jsxs(q.ImageViewMemoryContext,{value:P,children:[N.jsx(q.DocumentRefreshBar,{path:e,placement:C}),N.jsx(q.DocumentPane,{path:e,variant:f,onDocumentShown:O})]})},ve=()=>typeof HTMLElement<"u"&&typeof HTMLElement.prototype.showPopover=="function"&&typeof HTMLElement.prototype.hidePopover=="function",G=(e,n)=>{const t=e.panelIds.get(n);if(t===void 0)throw new Error(`[markdown-explorer] the open document ${JSON.stringify(n)} has no panel id`);return t},ye=e=>Object.fromEntries(k.generateColumnIds(e).map(n=>[n,[]])),Ln=(e,n)=>{const t=Je(X(e,n),n.visible);return Object.fromEntries(t.map((o,r)=>[k.generateColumnId(r),o.map(s=>G(e,s))]))},Nn=(e,n)=>{const t=U(e);return k.sortColumnIds(Object.keys(n)).map(o=>(n[o]??[]).flatMap(r=>{const s=t.get(r);return s===void 0?[]:[s]}))},Tn=e=>({switchToCustomDragMode:e.panelSwitchToCustomDrag,switchToNormalDragMode:e.panelSwitchToNormalDrag,hidePanel:e.panelHide,maximizePanel:e.panelMaximize,restorePanel:e.panelRestore,closePanel:e.panelClose,movePanelToPreviousColumn:e.panelMovePreviousColumn,movePanelToNextColumn:e.panelMoveNextColumn,movePanelUp:e.panelMoveUp,movePanelDown:e.panelMoveDown,customDragModeBadge:e.panelCustomDragBadge,panelMoved:e.panelMoved,panelMoveUnavailable:e.panelMoveUnavailable,panelDragStarted:e.panelDragStarted,panelDragCancelled:e.panelDragCancelled,hiddenPanels:e.hiddenPanelsTitle,hiddenPanelBadge:e.hiddenPanelBadge,hiddenPanelNotice:e.hiddenPanelNotice,emptyColumn:e.multiColumnEmpty,dropZone:e.multiColumnRegion,dropHere:e.panelDropHere}),le="--aqmx-stage-block",In="--aqmx-multi-panel-body-floor",Rn=`calc(var(${le}) * ${String(F.PANEL_MIN_BLOCK_RATIO)})`,Dn=`max(calc(var(${le}) * ${String(F.PANEL_MAX_BLOCK_RATIO)}), calc(var(${te}) + var(${In})))`,kn=(e,n)=>{const t=Object.entries(e);return t.length!==Object.keys(n).length?!1:t.every(([o,r])=>{const s=n[o];return s!==void 0&&s.length===r.length&&s.every((i,a)=>r[a]===i)})},we=["keydown","pointerdown","wheel","touchstart"],$=new WeakMap,xe=(e,n,t)=>{for(let o=n;o!==null&&o!==t;o=o.parentElement){e.observe(o);for(let r=o.previousElementSibling;r!==null;r=r.previousElementSibling)e.observe(r)}},An=e=>{const n=new Map;for(let t=e.parentElement;t!==null;t=t.parentElement)n.set(t,{top:t.scrollTop,left:t.scrollLeft});return n},K=(e,n,t)=>{$.get(e)?.();const o=e.querySelector(`[${Y}="${n}"]`);if(!(o instanceof HTMLElement))return;const r=t!==null&&o.contains(t)?t:null;let s=new Map;const i=()=>{if(!o.isConnected)return;o.scrollIntoView({block:"nearest",inline:"nearest",behavior:"instant"});const w=r?.isConnected===!0?r:o;w!==o&&w.scrollIntoView({block:"nearest",inline:"nearest",behavior:"instant"}),s=An(w)};if(i(),typeof ResizeObserver>"u")return;const a=new ResizeObserver(i);xe(a,o,o.closest(k.SCROLL_ROOT_SELECTOR)),r!==null&&xe(a,r,o);const{ownerDocument:p}=e,l=w=>{const P=w.target===p?p.scrollingElement:w.target;if(!(P instanceof Element))return;const O=s.get(P);O!==void 0&&(P.scrollTop!==O.top||P.scrollLeft!==O.left)&&g()},g=()=>{a.disconnect();for(const w of we)p.removeEventListener(w,g,!0);p.removeEventListener("scroll",l,!0),$.get(e)===g&&$.delete(e)};for(const w of we)p.addEventListener(w,g,{capture:!0,passive:!0});p.addEventListener("scroll",l,{capture:!0,passive:!0}),$.set(e,g)},_e=(e,n)=>{const t=e.querySelector(`[${W}="${n}"]`);return t instanceof HTMLElement?(K(e,n,null),t.focus({preventScroll:!0}),!0):!1},ie=(e,n)=>{const t=e.querySelector(`[${Y}="${n}"]`);return t instanceof HTMLElement&&t.contains(e.ownerDocument.activeElement)},Ee=(e,n)=>{if(!ie(e,n))return null;const t=[...e.querySelectorAll(`[${W}]`)].map(i=>i.getAttribute(W)),o=t.indexOf(n),r=t[o+1];if(o>=0&&typeof r=="string")return{kind:"panel",panelId:r};const s=t[o-1];return o>0&&typeof s=="string"?{kind:"panel",panelId:s}:{kind:"stage"}},Se=(e,n)=>{requestAnimationFrame(()=>{const t=e.current;t!==null&&(n.kind==="panel"&&_e(t,n.panelId)||t.focus({preventScroll:!0}))})},ze=(e,n)=>{requestAnimationFrame(()=>{const t=e.current;t!==null&&_e(t,n)})},_n=(e,n,t)=>{requestAnimationFrame(()=>{const o=e.current;if(o===null)return;const{activeElement:r,body:s}=o.ownerDocument;if(K(o,n,t&&ie(o,n)?r:null),!t||r!==null&&r!==s&&r.isConnected)return;const i=o.querySelector(`[${W}="${n}"]`);i instanceof HTMLElement&&i.focus({preventScroll:!0})})},zn=({store:e,stageRef:n})=>{const{config:t,labels:o,announcer:r}=q.useExplorer(),{maximize:s}=re(),i=t.multiView.columns,a=A(e,x=>x.layout),p=A(e,x=>x.visibleColumns),l=A(e,x=>x.titles),g=A(e,x=>x.layout.maximized!==null||x.splitDragging),[w,P]=u.useState(!1),[O]=u.useState(()=>ye(p)),d=u.useMemo(()=>Tn(o),[o]),h=u.useCallback(x=>{e.arrange(Nn(e.getSnapshot().layout,x))},[e]),f=k.useDragDropColumns({initialColumnPanels:O,initialPanelVisibility:{},debugConfig:k.DEFAULT_DEBUG_CONFIG,onColumnPanelsChange:h}),{columnPanels:C,setColumnPanels:E}=f,L=u.useRef(g),m=u.useRef(C);u.useLayoutEffect(()=>{L.current=g,m.current=C},[g,C]);const S=u.useCallback(x=>{const b=n.current;if(b===null)return;const{plan:H,stageBlockSize:D}=un(b,i);if(Number.isFinite(D)&&D>0&&b.style.setProperty(le,`${String(D)}px`),L.current&&!x)return;const z=F.replanVisibleColumns(e.getSnapshot().visibleColumns,H);z!==null&&e.setVisibleColumns(z)},[e,n,i]);u.useLayoutEffect(()=>{S(!0),P(!0)},[S]),u.useEffect(()=>{const x=n.current;if(x===null||typeof ResizeObserver>"u")return;let b=null;const H=new ResizeObserver(()=>{b===null&&(b=requestAnimationFrame(()=>{b=null,S(!1)}))}),D=x.querySelector(k.SCROLL_ROOT_SELECTOR)?.firstElementChild,z=x.querySelector(`[${se}]`);return D instanceof Element&&H.observe(D),z instanceof Element&&H.observe(z),()=>{H.disconnect(),b!==null&&cancelAnimationFrame(b)}},[n,S]),u.useEffect(()=>{g||S(!1)},[g,S]);const v=u.useMemo(()=>w?Ln(a,{logical:i,visible:p}):ye(p),[w,a,i,p]);u.useLayoutEffect(()=>{kn(m.current,v)||E(v)},[v,E]);const T=u.useMemo(()=>k.sortColumnIds(Object.keys(C)).map(x=>({id:x,key:x,className:"aqmx-multi-column"})),[C]),I=u.useMemo(()=>a.docs.map(x=>{const b=G(a,x);return{id:b,component:On,title:oe(l,x),props:{docPath:x,panelId:b},minHeight:Rn,maxHeight:Dn}}),[a,l]),_=u.useMemo(()=>Object.fromEntries(a.docs.map(x=>[G(a,x),!a.hidden.has(x)])),[a]),c=a.maximized===null?null:G(a,a.maximized),y=u.useCallback(x=>{const{layout:b}=e.getSnapshot();for(const[H,D]of U(b)){const z=x[H];if(z===void 0||z!==b.hidden.has(D))continue;const ce=e.titleOf(D);if(z){if(!e.setHidden(D,!1))continue;r.announce(o.panelShown(ce)),ze(n,H);continue}const ae=n.current,ue=ae===null?null:Ee(ae,H);e.setHidden(D,!0)&&(r.announce(o.panelHidden(ce)),ue!==null&&Se(n,ue))}},[e,n,r,o]),M=u.useCallback(x=>{const b=U(e.getSnapshot().layout).get(x);if(b===void 0)return;const H=e.titleOf(b),D=n.current,z=D===null?null:Ee(D,x);e.close(b)&&(r.announce(o.panelClosed(H)),z!==null&&Se(n,z))},[e,n,r,o]),R=u.useCallback(x=>{if(x===null){s(null);return}const b=U(e.getSnapshot().layout).get(x);b!==void 0&&s(b)},[e,s]);return N.jsx("div",{className:"aqmx-multi-layout","aria-busy":!w,children:N.jsx(k.DragDropLayout,{columns:T,panels:I,columnPanels:C,onColumnPanelsChange:h,panelVisibility:_,onPanelVisibilityChange:y,dragState:f.dragState,dragOverPosition:f.dragOverPosition,originalPanelPosition:f.originalPanelPosition,dragModes:f.dragModes,debugConfig:k.DEFAULT_DEBUG_CONFIG,panelSizes:f.panelSizes,customDrag:f.customDrag,setPanelRef:f.setPanelRef,onDragStart:f.handleDragStart,onDragEnd:f.handleDragEnd,onPlaceholderDragEnter:f.handlePlaceholderDragEnter,onPlaceholderDragLeave:f.handlePlaceholderDragLeave,onDragOverWithInsert:f.handleDragOverWithInsert,onDropWithInsert:f.handleDropWithInsert,onColumnDragLeave:f.handleColumnDragLeave,onPanelMouseDown:f.handleMouseDown,onPanelSizeInfoClick:f.handlePanelSizeInfoClick,onToggleDragMode:f.toggleDragMode,onPanelClose:M,onPanelMaximizeChange:R,maximizedPanel:c,dragHandle:"header",labels:d,panelClassName:"aqmx-multi-panel"})})},ee={blockStart:"--aqmx-multi-toast-block-start",inlineEnd:"--aqmx-multi-toast-inline-end",room:"--aqmx-multi-toast-room"},Hn=(e,n)=>{const t=n.getBoundingClientRect(),o=[t.left+1,t.left+t.width/2,t.right-1],r=[t.top+1,t.top+t.height/2,t.bottom-1];return o.some(s=>r.some(i=>{const a=n.ownerDocument.elementsFromPoint(s,i),p=a.findIndex(g=>n.contains(g)),l=a.findIndex(g=>e.contains(g));return p!==-1&&l!==-1&&l<p}))},qn=(e,n)=>{const t=n.getBoundingClientRect(),o=n.ownerDocument.documentElement.clientWidth,r=getComputedStyle(n).direction==="rtl";return e.style.setProperty(ee.blockStart,`${String(t.top)}px`),e.style.setProperty(ee.inlineEnd,`${String(r?t.left:o-t.right)}px`),e.style.setProperty(ee.room,`${String(t.width)}px`),e.showPopover(),()=>{e.isConnected&&e.hidePopover()}},Fn=({store:e,body:n,limitNotice:t,onLimitNoticeCovered:o,ref:r})=>{const{config:s,labels:i,announcer:a}=q.useExplorer(),p=u.useRef(null),l=u.useRef(null),g=A(e,m=>m.ready),w=A(e,m=>m.layout.docs.length>0),P=A(e,m=>m.visibleColumns),O=u.use(ne.SheetNoticeSlotContext),d=u.useCallback(m=>{const{layout:S}=e.getSnapshot(),v=S.maximized,T=m===null&&v!==null?S.panelIds.get(v):void 0,I=p.current,_=T!==void 0&&I!==null&&ie(I,T);e.maximize(m)&&(m!==null?a.announce(i.panelMaximized(e.titleOf(m))):v!==null&&a.announce(i.panelRestored(e.titleOf(v))),T!==void 0&&_n(p,T,_))},[e,a,i]),h=u.useCallback((m,S,v,T)=>{if(v===S){e.setPendingHash(m,T);return}const I=e.navigate(S,v);if(I==="navigated"){e.setPendingHash(m,T);return}if(I!=="existing")return;const{layout:_}=e.getSnapshot(),c=_.panelIds.get(v);c!==void 0&&(a.announce(i.panelAlreadyOpen(e.titleOf(v))),_.maximized===null?e.setHidden(v,!1):d(v),e.setPendingHash(c,T),ze(p,c))},[e,a,i,d]);u.useLayoutEffect(()=>{if(t===null||O!==null||!ve())return;const m=l.current,S=p.current;if(m===null||S===null)throw new Error("[markdown-explorer] the panel-limit notice and the stage must be mounted together");return qn(m,S)},[t,O]),u.useEffect(()=>{const m=l.current;if(t===null||m===null)return;const{ownerDocument:S}=m;let v=null;const T=I=>{const _=I.target;_ instanceof Element&&(v!==null&&cancelAnimationFrame(v),v=requestAnimationFrame(()=>{v=null,S.activeElement===_&&m.isConnected&&Hn(m,_)&&o()}))};return S.addEventListener("focusin",T,!0),()=>{S.removeEventListener("focusin",T,!0),v!==null&&cancelAnimationFrame(v)}},[t,O,o]),u.useImperativeHandle(r,()=>({bringIntoView:m=>{requestAnimationFrame(()=>{const S=p.current,v=e.getSnapshot().layout.panelIds.get(m);S!==null&&v!==void 0&&K(S,v,null)})}}),[e]),u.useEffect(()=>{const m=p.current;return()=>{m!==null&&$.get(m)?.()}},[]);const f=u.useCallback((m,S)=>{const v=p.current;v!==null&&K(v,m,S)},[]),[C]=u.useState(ln),E=u.useMemo(()=>({store:e,Body:n,followLink:h,maximize:d,revealInPanel:f,focusCarry:C}),[e,n,h,d,f,C]),L=u.useMemo(()=>Array.from({length:s.multiView.columns},(m,S)=>k.generateColumnId(S)),[s]);return N.jsxs("section",{ref:p,className:"aqmx-multi-stage",tabIndex:-1,"aria-label":i.multiRegion,"aria-busy":w&&!g,"data-testid":"markdown-explorer-stage","data-aqmx-visible-columns":P,children:[N.jsx("span",{className:"aqmx-multi-probe","aria-hidden":"true",[se]:""}),w?g?N.jsx(Ie,{value:E,children:N.jsx(zn,{store:e,stageRef:p})}):N.jsx("div",{className:"aqmx-multi-skeleton","aria-hidden":"true","data-testid":"markdown-explorer-stage-skeleton",children:L.map(m=>N.jsxs("div",{className:"aqmx-skeleton aqmx-multi-skeleton-column",children:[N.jsx("span",{}),N.jsx("span",{}),N.jsx("span",{})]},m))}):N.jsx("div",{className:"aqmx-empty","data-testid":"markdown-explorer-multi-empty",children:N.jsx("p",{className:"aqmx-empty-title",children:i.multiEmpty})}),t===null?null:O!==null?Fe.createPortal(N.jsx("div",{ref:l,className:"aqmx-toast aqmx-multi-toast","data-testid":"markdown-explorer-panel-limit",children:t}),O):N.jsx("div",{ref:l,popover:ve()?"manual":void 0,className:"aqmx-toast aqmx-multi-toast","data-testid":"markdown-explorer-panel-limit",children:t})]})},He=3e3,qe=(e,n)=>{if(n!==null)return n;const[t]=e;return t===void 0?null:t},jn=(e,n,t)=>{switch(n){case"opened":return e.panelOpened(t);case"shown":return e.panelShown(t);case"closed":return e.panelClosed(t);default:{const o=n;throw new RangeError(`[markdown-explorer] unknown toggle outcome ${JSON.stringify(o)}`)}}},Bn=({location:e})=>{const{config:n,labels:t,announcer:o}=q.useExplorer(),r=mn(e),s=A(r,m=>m.layout.docs),i=A(r,m=>m.layout.maximized),a=A(r,m=>m.source),[p,l]=u.useState(!1),g=u.useRef(null),[w,P]=u.useState(0),O=u.useRef(null),d=u.useRef(null);u.useLayoutEffect(()=>{const m=O.current;O.current=null,m!==null&&(r.whenUrlRendered(()=>o.announce(m.announcement)),d.current?.bringIntoView(m.doc))}),u.useEffect(()=>()=>{g.current!==null&&clearTimeout(g.current)},[]);const h=u.useCallback(()=>{g.current!==null&&clearTimeout(g.current),l(!0),g.current=setTimeout(()=>{g.current=null,l(!1)},He)},[]),f=u.useCallback(()=>{g.current!==null&&clearTimeout(g.current),g.current=null,l(!1)},[]),C=u.useCallback(m=>{const S=r.titleOf(m),v=r.toggle(m);v==="rejected"&&h();const T=v==="rejected"?t.panelLimit(n.multiView.maxPanels):jn(t,v,S);if(v==="shown"){O.current={doc:m,announcement:T},P(I=>I+1);return}r.whenUrlRendered(()=>{o.announce(T),v==="opened"&&d.current?.bringIntoView(m)})},[r,h,o,t,n]),E=u.useMemo(()=>new Set(s),[s]),L=u.useMemo(()=>({href:F.explorerHref(n,{view:"tree",source:a,doc:qe(s,i)}),target:"tree"}),[n,a,s,i]);return N.jsx(ne.ExplorerSplit,{view:"multi",explorer:N.jsx(ne.ExplorerPane,{mode:"multi",sourceId:a,currentPath:null,openPaths:E,onOpenDocument:C,onSourceChange:r.changeSource,viewSwitch:L}),content:N.jsx(Fn,{ref:d,store:r,body:Mn,limitNotice:p?t.panelLimit(n.multiView.maxPanels):null,onLimitNoticeCovered:f}),contentCoversPage:i!==null,sheetDismissals:w,onDraggingChange:r.setSplitDragging})};exports.MultiLayout=Bn;exports.PANEL_LIMIT_NOTICE_MS=He;exports.treeSwitchDocument=qe;
@@ -0,0 +1,22 @@
1
+ import { jsx as s, jsxs as S } from "react/jsx-runtime";
2
+ import { useState as f, useMemo as i, useCallback as u } from "react";
3
+ import { e as a, c as g } from "./location-fVl2R1ee.js";
4
+ import { u as P, a as D, D as b, P as C, b as N } from "./index-BfuAu2GV.js";
5
+ import { E as O, a as T, b as M } from "./ExplorerSplit-DB37U7Kh.js";
6
+ const _ = /* @__PURE__ */ new Set(), q = ({ location: l }) => {
7
+ const { config: e } = P(), r = D(), { source: t, doc: o, overrides: n } = l, [m, p] = f(O), d = i(() => ({ gathered: m, onGatheredChange: p }), [m]), h = u((c) => r(a(e, { view: "tree", source: t, doc: c, overrides: n }), "browse"), [r, e, t, n]), v = u((c) => r(a(e, { view: "tree", source: c, doc: o, overrides: n }), "switch-source"), [r, e, o, n]), w = u((c) => r(a(e, { view: "multi", source: t, docs: g(e, c) }), "switch-view"), [r, e, t]), E = i(() => ({ href: a(e, { view: "multi", source: t, docs: o === null ? [] : [o] }), target: "multi" }), [e, t, o]), x = i(() => ({ kind: "page", view: "tree", overrides: n, embed: {} }), [n]);
8
+ return /* @__PURE__ */ s(
9
+ T,
10
+ {
11
+ view: "tree",
12
+ explorer: /* @__PURE__ */ s(M, { mode: "tree", sourceId: t, currentPath: o, openPaths: _, onOpenDocument: h, onSourceChange: v, viewSwitch: E, tray: d, onOpenSelection: w }),
13
+ content: /* @__PURE__ */ S("div", { className: "aqmx-document-column aqmx-tree-document", children: [
14
+ o === null ? null : /* @__PURE__ */ s(b, { path: o, placement: C }),
15
+ /* @__PURE__ */ s(N, { path: o, variant: x })
16
+ ] })
17
+ }
18
+ );
19
+ };
20
+ export {
21
+ q as TreeLayout
22
+ };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("react/jsx-runtime"),r=require("react"),u=require("./location-Oo21lTyV.cjs"),i=require("./index-Cx3-jSna.cjs"),l=require("./ExplorerSplit-D2plJRRe.cjs"),g=new Set,f=({location:p})=>{const{config:e}=i.useExplorer(),n=i.useExplorerNavigate(),{source:o,doc:t,overrides:c}=p,[m,d]=r.useState(l.EMPTY_SELECTION),x=r.useMemo(()=>({gathered:m,onGatheredChange:d}),[m]),h=r.useCallback(s=>n(u.explorerHref(e,{view:"tree",source:o,doc:s,overrides:c}),"browse"),[n,e,o,c]),v=r.useCallback(s=>n(u.explorerHref(e,{view:"tree",source:s,doc:t,overrides:c}),"switch-source"),[n,e,t,c]),S=r.useCallback(s=>n(u.explorerHref(e,{view:"multi",source:o,docs:u.canonicalMultiDocuments(e,s)}),"switch-view"),[n,e,o]),w=r.useMemo(()=>({href:u.explorerHref(e,{view:"multi",source:o,docs:t===null?[]:[t]}),target:"multi"}),[e,o,t]),E=r.useMemo(()=>({kind:"page",view:"tree",overrides:c,embed:{}}),[c]);return a.jsx(l.ExplorerSplit,{view:"tree",explorer:a.jsx(l.ExplorerPane,{mode:"tree",sourceId:o,currentPath:t,openPaths:g,onOpenDocument:h,onSourceChange:v,viewSwitch:w,tray:x,onOpenSelection:S}),content:a.jsxs("div",{className:"aqmx-document-column aqmx-tree-document",children:[t===null?null:a.jsx(i.DocumentRefreshBar,{path:t,placement:i.PAGE_DOCUMENT_REFRESH}),a.jsx(i.DocumentPane,{path:t,variant:E})]})})};exports.TreeLayout=f;
@@ -0,0 +1,30 @@
1
+ import { MarkdownMathDiagnostic } from "@aiquants/markdown";
2
+ import { ReactElement, ReactNode, Ref } from "react";
3
+ import { ExplorerConfig, ExplorerView } from "../core/config.cjs";
4
+ import { ExplorerFailure, ExplorerPageData } from "../core/contracts.cjs";
5
+ import { MarkdownExplorerLabelOverrides, MarkdownExplorerLocale } from "../core/labels.cjs";
6
+ import { ExplorerTheme } from "../core/theme.cjs";
7
+ export type ExplorerFrameRenderer = (frame: {
8
+ readonly view: ExplorerView;
9
+ readonly children: ReactNode;
10
+ }) => ReactNode;
11
+ export type MarkdownExplorerProps = {
12
+ readonly data: ExplorerPageData;
13
+ readonly config: ExplorerConfig;
14
+ readonly storageNamespace: string;
15
+ readonly locale?: MarkdownExplorerLocale;
16
+ readonly labels?: MarkdownExplorerLabelOverrides;
17
+ readonly theme?: ExplorerTheme;
18
+ readonly renderFrame?: ExplorerFrameRenderer;
19
+ readonly renderTreeFailure?: (failure: ExplorerFailure) => ReactNode | undefined;
20
+ readonly lockDocumentScroll?: boolean;
21
+ readonly onMathDiagnostics?: (path: string, diagnostics: readonly MarkdownMathDiagnostic[]) => void;
22
+ };
23
+ export declare const MarkdownExplorer: ({ data: pageData, config, storageNamespace, locale: localeProp, labels: labelOverrides, theme: themeProp, renderFrame, renderTreeFailure, lockDocumentScroll, onMathDiagnostics }: MarkdownExplorerProps) => ReactElement;
24
+ export type ExplorerRootProps = {
25
+ readonly ref?: Ref<HTMLDivElement>;
26
+ readonly theme: ExplorerTheme;
27
+ readonly view: ExplorerView;
28
+ readonly children: ReactNode;
29
+ };
30
+ export declare const ExplorerRoot: ({ ref, theme, view, children }: ExplorerRootProps) => ReactElement;
@@ -0,0 +1,30 @@
1
+ import { MarkdownMathDiagnostic } from "@aiquants/markdown";
2
+ import { ReactElement, ReactNode, Ref } from "react";
3
+ import { ExplorerConfig, ExplorerView } from "../core/config.js";
4
+ import { ExplorerFailure, ExplorerPageData } from "../core/contracts.js";
5
+ import { MarkdownExplorerLabelOverrides, MarkdownExplorerLocale } from "../core/labels.js";
6
+ import { ExplorerTheme } from "../core/theme.js";
7
+ export type ExplorerFrameRenderer = (frame: {
8
+ readonly view: ExplorerView;
9
+ readonly children: ReactNode;
10
+ }) => ReactNode;
11
+ export type MarkdownExplorerProps = {
12
+ readonly data: ExplorerPageData;
13
+ readonly config: ExplorerConfig;
14
+ readonly storageNamespace: string;
15
+ readonly locale?: MarkdownExplorerLocale;
16
+ readonly labels?: MarkdownExplorerLabelOverrides;
17
+ readonly theme?: ExplorerTheme;
18
+ readonly renderFrame?: ExplorerFrameRenderer;
19
+ readonly renderTreeFailure?: (failure: ExplorerFailure) => ReactNode | undefined;
20
+ readonly lockDocumentScroll?: boolean;
21
+ readonly onMathDiagnostics?: (path: string, diagnostics: readonly MarkdownMathDiagnostic[]) => void;
22
+ };
23
+ export declare const MarkdownExplorer: ({ data: pageData, config, storageNamespace, locale: localeProp, labels: labelOverrides, theme: themeProp, renderFrame, renderTreeFailure, lockDocumentScroll, onMathDiagnostics }: MarkdownExplorerProps) => ReactElement;
24
+ export type ExplorerRootProps = {
25
+ readonly ref?: Ref<HTMLDivElement>;
26
+ readonly theme: ExplorerTheme;
27
+ readonly view: ExplorerView;
28
+ readonly children: ReactNode;
29
+ };
30
+ export declare const ExplorerRoot: ({ ref, theme, view, children }: ExplorerRootProps) => ReactElement;
@@ -0,0 +1,11 @@
1
+ export declare const assertStorageNamespace: (namespace: unknown) => void;
2
+ export declare const storageKeys: (namespace: string) => Readonly<{
3
+ treeSettings: `${string}:tree-settings`;
4
+ multiLayout: `${string}:multi-layout`;
5
+ scope: `${string}:scope`;
6
+ treeExpansion: (sourceId: string) => string;
7
+ }>;
8
+ export declare const readStorage: (key: string) => string | null;
9
+ export declare const writeStorage: (key: string, value: string) => void;
10
+ export declare const clearExplorerStorage: (namespace: string) => void;
11
+ export declare const syncStorageScope: (namespace: string, scope: string) => boolean;
@@ -0,0 +1,11 @@
1
+ export declare const assertStorageNamespace: (namespace: unknown) => void;
2
+ export declare const storageKeys: (namespace: string) => Readonly<{
3
+ treeSettings: `${string}:tree-settings`;
4
+ multiLayout: `${string}:multi-layout`;
5
+ scope: `${string}:scope`;
6
+ treeExpansion: (sourceId: string) => string;
7
+ }>;
8
+ export declare const readStorage: (key: string) => string | null;
9
+ export declare const writeStorage: (key: string, value: string) => void;
10
+ export declare const clearExplorerStorage: (namespace: string) => void;
11
+ export declare const syncStorageScope: (namespace: string, scope: string) => boolean;
@@ -0,0 +1,77 @@
1
+ import { EmbedProviderId, MarkdownEmbeds } from "@aiquants/markdown/embeds";
2
+ import { MarkdownStyleOption } from "@aiquants/markdown/viewer-settings";
3
+ import { TreeSettings } from "./treeSettings.cjs";
4
+ export type ExplorerViewSlugs = {
5
+ readonly tree: string;
6
+ readonly multi: string;
7
+ readonly single: string;
8
+ };
9
+ export type ExplorerDocumentStyle = Readonly<MarkdownStyleOption>;
10
+ export type ExplorerView = keyof ExplorerViewSlugs;
11
+ export type ExplorerConfigInput = {
12
+ readonly basePath: string;
13
+ readonly dataPath: string;
14
+ readonly settingsCookie: string;
15
+ readonly views?: Partial<ExplorerViewSlugs>;
16
+ readonly multiView?: {
17
+ readonly maxPanels?: number;
18
+ readonly columns?: number;
19
+ };
20
+ readonly expandAll?: {
21
+ readonly maxFolders?: number;
22
+ readonly maxDepth?: number;
23
+ };
24
+ readonly documentStyles?: readonly ExplorerDocumentStyle[];
25
+ readonly iframeHosts?: readonly string[];
26
+ readonly embeds?: {
27
+ readonly providers?: readonly EmbedProviderId[];
28
+ readonly linkCardEndpoint?: string | null;
29
+ };
30
+ readonly defaultTreeSettings?: Partial<TreeSettings>;
31
+ };
32
+ export type ExplorerConfig = {
33
+ readonly basePath: string;
34
+ readonly dataPath: string;
35
+ readonly settingsCookie: string;
36
+ readonly views: ExplorerViewSlugs;
37
+ readonly multiView: {
38
+ readonly maxPanels: number;
39
+ readonly columns: number;
40
+ };
41
+ readonly expandAll: {
42
+ readonly maxFolders: number;
43
+ readonly maxDepth: number;
44
+ };
45
+ readonly documentStyles: readonly ExplorerDocumentStyle[];
46
+ readonly iframeHosts: readonly string[];
47
+ readonly embeds: MarkdownEmbeds;
48
+ readonly defaultTreeSettings: TreeSettings;
49
+ };
50
+ export declare const DEFAULT_VIEW_SLUGS: ExplorerViewSlugs;
51
+ export declare const MULTI_VIEW_PANEL_LIMITS: Readonly<{
52
+ default: 12;
53
+ min: 1;
54
+ max: 64;
55
+ }>;
56
+ export declare const MULTI_VIEW_COLUMN_LIMITS: Readonly<{
57
+ default: 4;
58
+ min: 1;
59
+ max: 6;
60
+ }>;
61
+ export declare const EXPAND_ALL_FOLDER_LIMITS: Readonly<{
62
+ default: 500;
63
+ min: 1;
64
+ max: 10000;
65
+ }>;
66
+ export declare const EXPAND_ALL_DEPTH_LIMITS: Readonly<{
67
+ default: 16;
68
+ min: 1;
69
+ max: 64;
70
+ }>;
71
+ export declare const defineExplorerConfig: (input: ExplorerConfigInput) => ExplorerConfig;
72
+ export declare const isExplorerSourceId: (value: unknown) => value is string;
73
+ export type ExplorerLocationConfig = ExplorerConfig & {
74
+ readonly sourceIds: readonly string[];
75
+ };
76
+ export declare const withExplorerSources: (config: ExplorerConfig, sourceIds: readonly string[]) => ExplorerLocationConfig;
77
+ export declare const documentStyleNames: (config: ExplorerConfig) => readonly string[];
@@ -0,0 +1,77 @@
1
+ import { EmbedProviderId, MarkdownEmbeds } from "@aiquants/markdown/embeds";
2
+ import { MarkdownStyleOption } from "@aiquants/markdown/viewer-settings";
3
+ import { TreeSettings } from "./treeSettings.js";
4
+ export type ExplorerViewSlugs = {
5
+ readonly tree: string;
6
+ readonly multi: string;
7
+ readonly single: string;
8
+ };
9
+ export type ExplorerDocumentStyle = Readonly<MarkdownStyleOption>;
10
+ export type ExplorerView = keyof ExplorerViewSlugs;
11
+ export type ExplorerConfigInput = {
12
+ readonly basePath: string;
13
+ readonly dataPath: string;
14
+ readonly settingsCookie: string;
15
+ readonly views?: Partial<ExplorerViewSlugs>;
16
+ readonly multiView?: {
17
+ readonly maxPanels?: number;
18
+ readonly columns?: number;
19
+ };
20
+ readonly expandAll?: {
21
+ readonly maxFolders?: number;
22
+ readonly maxDepth?: number;
23
+ };
24
+ readonly documentStyles?: readonly ExplorerDocumentStyle[];
25
+ readonly iframeHosts?: readonly string[];
26
+ readonly embeds?: {
27
+ readonly providers?: readonly EmbedProviderId[];
28
+ readonly linkCardEndpoint?: string | null;
29
+ };
30
+ readonly defaultTreeSettings?: Partial<TreeSettings>;
31
+ };
32
+ export type ExplorerConfig = {
33
+ readonly basePath: string;
34
+ readonly dataPath: string;
35
+ readonly settingsCookie: string;
36
+ readonly views: ExplorerViewSlugs;
37
+ readonly multiView: {
38
+ readonly maxPanels: number;
39
+ readonly columns: number;
40
+ };
41
+ readonly expandAll: {
42
+ readonly maxFolders: number;
43
+ readonly maxDepth: number;
44
+ };
45
+ readonly documentStyles: readonly ExplorerDocumentStyle[];
46
+ readonly iframeHosts: readonly string[];
47
+ readonly embeds: MarkdownEmbeds;
48
+ readonly defaultTreeSettings: TreeSettings;
49
+ };
50
+ export declare const DEFAULT_VIEW_SLUGS: ExplorerViewSlugs;
51
+ export declare const MULTI_VIEW_PANEL_LIMITS: Readonly<{
52
+ default: 12;
53
+ min: 1;
54
+ max: 64;
55
+ }>;
56
+ export declare const MULTI_VIEW_COLUMN_LIMITS: Readonly<{
57
+ default: 4;
58
+ min: 1;
59
+ max: 6;
60
+ }>;
61
+ export declare const EXPAND_ALL_FOLDER_LIMITS: Readonly<{
62
+ default: 500;
63
+ min: 1;
64
+ max: 10000;
65
+ }>;
66
+ export declare const EXPAND_ALL_DEPTH_LIMITS: Readonly<{
67
+ default: 16;
68
+ min: 1;
69
+ max: 64;
70
+ }>;
71
+ export declare const defineExplorerConfig: (input: ExplorerConfigInput) => ExplorerConfig;
72
+ export declare const isExplorerSourceId: (value: unknown) => value is string;
73
+ export type ExplorerLocationConfig = ExplorerConfig & {
74
+ readonly sourceIds: readonly string[];
75
+ };
76
+ export declare const withExplorerSources: (config: ExplorerConfig, sourceIds: readonly string[]) => ExplorerLocationConfig;
77
+ export declare const documentStyleNames: (config: ExplorerConfig) => readonly string[];
@@ -0,0 +1,155 @@
1
+ import { ExplorerViewSettings } from "./viewSettings.cjs";
2
+ export declare const EXPLORER_FAILURE_REASONS: readonly [
3
+ "unauthorized",
4
+ "forbidden",
5
+ "not-found",
6
+ "not-configured",
7
+ "invalid",
8
+ "too-large",
9
+ "unsupported",
10
+ "failed"
11
+ ];
12
+ export type ExplorerFailureReason = (typeof EXPLORER_FAILURE_REASONS)[number];
13
+ export declare const EXPLORER_ENTRY_TYPES: readonly [
14
+ "file",
15
+ "directory"
16
+ ];
17
+ export type ExplorerEntryType = (typeof EXPLORER_ENTRY_TYPES)[number];
18
+ export declare const EXPLORER_MEDIA_TYPES: readonly [
19
+ "video",
20
+ "audio",
21
+ "pdf"
22
+ ];
23
+ export type ExplorerMediaType = (typeof EXPLORER_MEDIA_TYPES)[number];
24
+ export declare const EXPLORER_NOTICE_TONES: readonly [
25
+ "info",
26
+ "warning",
27
+ "danger"
28
+ ];
29
+ export type ExplorerNoticeTone = (typeof EXPLORER_NOTICE_TONES)[number];
30
+ export declare const EXPLORER_DOCUMENT_KINDS: readonly [
31
+ "markdown",
32
+ "text",
33
+ "image",
34
+ "media",
35
+ "file",
36
+ "failure"
37
+ ];
38
+ export type ExplorerDocumentKind = (typeof EXPLORER_DOCUMENT_KINDS)[number];
39
+ export declare const EXPLORER_HEADING_DEPTHS: Readonly<{
40
+ min: 1;
41
+ max: 6;
42
+ }>;
43
+ export declare const EXPLORER_MAX_HEADINGS = 10000;
44
+ export declare const isRootRelativeUrl: (url: unknown) => url is string;
45
+ export declare const EXPLORER_LINK_PROTOCOLS: readonly [
46
+ "http:",
47
+ "https:",
48
+ "mailto:"
49
+ ];
50
+ export type ExplorerFailure = {
51
+ readonly reason: ExplorerFailureReason;
52
+ readonly code?: string;
53
+ };
54
+ export type ExplorerEntry = {
55
+ readonly name: string;
56
+ readonly path: string;
57
+ readonly type: ExplorerEntryType;
58
+ readonly mimeType?: string;
59
+ readonly children?: readonly ExplorerEntry[];
60
+ readonly lazy?: boolean;
61
+ };
62
+ export type ExplorerTreeResult = {
63
+ readonly status: "ok";
64
+ readonly entries: readonly ExplorerEntry[];
65
+ readonly loadedAt: number;
66
+ } | {
67
+ readonly status: "error";
68
+ readonly failure: ExplorerFailure;
69
+ };
70
+ export type ExplorerChildrenResult = {
71
+ readonly status: "ok";
72
+ readonly entries: readonly ExplorerEntry[];
73
+ } | {
74
+ readonly status: "error";
75
+ readonly failure: ExplorerFailure;
76
+ };
77
+ export type ExplorerHeading = {
78
+ readonly text: string;
79
+ readonly depth: number;
80
+ readonly id: string;
81
+ };
82
+ export type ExplorerFailureDocument = {
83
+ readonly kind: "failure";
84
+ readonly failure: ExplorerFailure;
85
+ };
86
+ export type ExplorerDocument = {
87
+ readonly kind: "markdown";
88
+ readonly name: string;
89
+ readonly htmlContent: string;
90
+ readonly headings: readonly ExplorerHeading[];
91
+ } | {
92
+ readonly kind: "text";
93
+ readonly name: string;
94
+ readonly text: string;
95
+ readonly truncated: boolean;
96
+ readonly url: string;
97
+ } | {
98
+ readonly kind: "image";
99
+ readonly name: string;
100
+ readonly url: string;
101
+ } | {
102
+ readonly kind: "media";
103
+ readonly name: string;
104
+ readonly url: string;
105
+ readonly mediaType: ExplorerMediaType;
106
+ } | {
107
+ readonly kind: "file";
108
+ readonly name: string;
109
+ readonly url: string;
110
+ } | ExplorerFailureDocument;
111
+ export type ExplorerNotice = {
112
+ readonly id: string;
113
+ readonly tone: ExplorerNoticeTone;
114
+ readonly title: string;
115
+ readonly body?: string;
116
+ readonly action?: {
117
+ readonly label: string;
118
+ readonly href: string;
119
+ };
120
+ };
121
+ export type ExplorerSourceSummary = {
122
+ readonly id: string;
123
+ readonly label: string;
124
+ };
125
+ export declare const isExplorerFailureReason: (value: unknown) => value is ExplorerFailureReason;
126
+ export declare const isExplorerEntryType: (value: unknown) => value is ExplorerEntryType;
127
+ export declare const isExplorerMediaType: (value: unknown) => value is ExplorerMediaType;
128
+ export declare const isExplorerNoticeTone: (value: unknown) => value is ExplorerNoticeTone;
129
+ export declare const isExplorerDocumentKind: (value: unknown) => value is ExplorerDocumentKind;
130
+ export declare const isExplorerFailureCode: (code: unknown) => code is string;
131
+ export declare const isAcceptableUrl: (url: unknown, protocols: readonly string[]) => url is string;
132
+ export declare const failureViolation: (value: unknown) => string | null;
133
+ export declare const entryViolation: (value: unknown) => string | null;
134
+ export declare const isExplorerChildrenResult: (value: unknown) => value is ExplorerChildrenResult;
135
+ export declare const isExplorerTreeResult: (value: unknown) => value is ExplorerTreeResult;
136
+ export declare const headingViolation: (value: unknown) => string | null;
137
+ export declare const documentViolation: (value: unknown) => string | null;
138
+ export declare const isExplorerDocument: (value: unknown) => value is ExplorerDocument;
139
+ export declare const failureDocument: (reason: ExplorerFailureReason, code?: string) => ExplorerFailureDocument;
140
+ export declare const failureOf: (reason: ExplorerFailureReason, code?: string) => ExplorerFailure;
141
+ export type ExplorerSeededDocument = {
142
+ readonly path: string;
143
+ readonly document: Promise<ExplorerDocument | null>;
144
+ };
145
+ export type ExplorerPageData = {
146
+ readonly scope: string;
147
+ readonly sources: readonly ExplorerSourceSummary[];
148
+ readonly settings: ExplorerViewSettings;
149
+ readonly tree: {
150
+ readonly sourceId: string;
151
+ readonly result: Promise<ExplorerTreeResult | null>;
152
+ } | null;
153
+ readonly documents: readonly ExplorerSeededDocument[];
154
+ readonly notices: Promise<readonly ExplorerNotice[]>;
155
+ };
@@ -0,0 +1,155 @@
1
+ import { ExplorerViewSettings } from "./viewSettings.js";
2
+ export declare const EXPLORER_FAILURE_REASONS: readonly [
3
+ "unauthorized",
4
+ "forbidden",
5
+ "not-found",
6
+ "not-configured",
7
+ "invalid",
8
+ "too-large",
9
+ "unsupported",
10
+ "failed"
11
+ ];
12
+ export type ExplorerFailureReason = (typeof EXPLORER_FAILURE_REASONS)[number];
13
+ export declare const EXPLORER_ENTRY_TYPES: readonly [
14
+ "file",
15
+ "directory"
16
+ ];
17
+ export type ExplorerEntryType = (typeof EXPLORER_ENTRY_TYPES)[number];
18
+ export declare const EXPLORER_MEDIA_TYPES: readonly [
19
+ "video",
20
+ "audio",
21
+ "pdf"
22
+ ];
23
+ export type ExplorerMediaType = (typeof EXPLORER_MEDIA_TYPES)[number];
24
+ export declare const EXPLORER_NOTICE_TONES: readonly [
25
+ "info",
26
+ "warning",
27
+ "danger"
28
+ ];
29
+ export type ExplorerNoticeTone = (typeof EXPLORER_NOTICE_TONES)[number];
30
+ export declare const EXPLORER_DOCUMENT_KINDS: readonly [
31
+ "markdown",
32
+ "text",
33
+ "image",
34
+ "media",
35
+ "file",
36
+ "failure"
37
+ ];
38
+ export type ExplorerDocumentKind = (typeof EXPLORER_DOCUMENT_KINDS)[number];
39
+ export declare const EXPLORER_HEADING_DEPTHS: Readonly<{
40
+ min: 1;
41
+ max: 6;
42
+ }>;
43
+ export declare const EXPLORER_MAX_HEADINGS = 10000;
44
+ export declare const isRootRelativeUrl: (url: unknown) => url is string;
45
+ export declare const EXPLORER_LINK_PROTOCOLS: readonly [
46
+ "http:",
47
+ "https:",
48
+ "mailto:"
49
+ ];
50
+ export type ExplorerFailure = {
51
+ readonly reason: ExplorerFailureReason;
52
+ readonly code?: string;
53
+ };
54
+ export type ExplorerEntry = {
55
+ readonly name: string;
56
+ readonly path: string;
57
+ readonly type: ExplorerEntryType;
58
+ readonly mimeType?: string;
59
+ readonly children?: readonly ExplorerEntry[];
60
+ readonly lazy?: boolean;
61
+ };
62
+ export type ExplorerTreeResult = {
63
+ readonly status: "ok";
64
+ readonly entries: readonly ExplorerEntry[];
65
+ readonly loadedAt: number;
66
+ } | {
67
+ readonly status: "error";
68
+ readonly failure: ExplorerFailure;
69
+ };
70
+ export type ExplorerChildrenResult = {
71
+ readonly status: "ok";
72
+ readonly entries: readonly ExplorerEntry[];
73
+ } | {
74
+ readonly status: "error";
75
+ readonly failure: ExplorerFailure;
76
+ };
77
+ export type ExplorerHeading = {
78
+ readonly text: string;
79
+ readonly depth: number;
80
+ readonly id: string;
81
+ };
82
+ export type ExplorerFailureDocument = {
83
+ readonly kind: "failure";
84
+ readonly failure: ExplorerFailure;
85
+ };
86
+ export type ExplorerDocument = {
87
+ readonly kind: "markdown";
88
+ readonly name: string;
89
+ readonly htmlContent: string;
90
+ readonly headings: readonly ExplorerHeading[];
91
+ } | {
92
+ readonly kind: "text";
93
+ readonly name: string;
94
+ readonly text: string;
95
+ readonly truncated: boolean;
96
+ readonly url: string;
97
+ } | {
98
+ readonly kind: "image";
99
+ readonly name: string;
100
+ readonly url: string;
101
+ } | {
102
+ readonly kind: "media";
103
+ readonly name: string;
104
+ readonly url: string;
105
+ readonly mediaType: ExplorerMediaType;
106
+ } | {
107
+ readonly kind: "file";
108
+ readonly name: string;
109
+ readonly url: string;
110
+ } | ExplorerFailureDocument;
111
+ export type ExplorerNotice = {
112
+ readonly id: string;
113
+ readonly tone: ExplorerNoticeTone;
114
+ readonly title: string;
115
+ readonly body?: string;
116
+ readonly action?: {
117
+ readonly label: string;
118
+ readonly href: string;
119
+ };
120
+ };
121
+ export type ExplorerSourceSummary = {
122
+ readonly id: string;
123
+ readonly label: string;
124
+ };
125
+ export declare const isExplorerFailureReason: (value: unknown) => value is ExplorerFailureReason;
126
+ export declare const isExplorerEntryType: (value: unknown) => value is ExplorerEntryType;
127
+ export declare const isExplorerMediaType: (value: unknown) => value is ExplorerMediaType;
128
+ export declare const isExplorerNoticeTone: (value: unknown) => value is ExplorerNoticeTone;
129
+ export declare const isExplorerDocumentKind: (value: unknown) => value is ExplorerDocumentKind;
130
+ export declare const isExplorerFailureCode: (code: unknown) => code is string;
131
+ export declare const isAcceptableUrl: (url: unknown, protocols: readonly string[]) => url is string;
132
+ export declare const failureViolation: (value: unknown) => string | null;
133
+ export declare const entryViolation: (value: unknown) => string | null;
134
+ export declare const isExplorerChildrenResult: (value: unknown) => value is ExplorerChildrenResult;
135
+ export declare const isExplorerTreeResult: (value: unknown) => value is ExplorerTreeResult;
136
+ export declare const headingViolation: (value: unknown) => string | null;
137
+ export declare const documentViolation: (value: unknown) => string | null;
138
+ export declare const isExplorerDocument: (value: unknown) => value is ExplorerDocument;
139
+ export declare const failureDocument: (reason: ExplorerFailureReason, code?: string) => ExplorerFailureDocument;
140
+ export declare const failureOf: (reason: ExplorerFailureReason, code?: string) => ExplorerFailure;
141
+ export type ExplorerSeededDocument = {
142
+ readonly path: string;
143
+ readonly document: Promise<ExplorerDocument | null>;
144
+ };
145
+ export type ExplorerPageData = {
146
+ readonly scope: string;
147
+ readonly sources: readonly ExplorerSourceSummary[];
148
+ readonly settings: ExplorerViewSettings;
149
+ readonly tree: {
150
+ readonly sourceId: string;
151
+ readonly result: Promise<ExplorerTreeResult | null>;
152
+ } | null;
153
+ readonly documents: readonly ExplorerSeededDocument[];
154
+ readonly notices: Promise<readonly ExplorerNotice[]>;
155
+ };