lexxy 0.9.31.beta → 0.9.32

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.
@@ -7658,7 +7658,8 @@ var Lexxy = {
7658
7658
  // Until 3.3.2 that never came up: attributes admitted by a *functional* ADD_ATTR
7659
7659
  // skipped URI validation entirely (GHSA-cjmm-f4jc-qw8r), which is how data:
7660
7660
  // URLs worked here — and, less happily, how `url="javascript:…"` survived too.
7661
- // The fix restored validation for both.
7661
+ // The fix restored validation for both. The bypass was reported to us by
7662
+ // @petitpois via HackerOne.
7662
7663
  //
7663
7664
  // So `url` is marked URI-safe, which hands the decision to this hook. The hook
7664
7665
  // only ever removes an attribute — it never force-keeps one — so scoping stays
@@ -7681,9 +7682,41 @@ var Lexxy = {
7681
7682
  // ordinary prose like "Q4: results" is not a URI any regex here would accept.
7682
7683
  const URI_BEARING_ATTACHMENT_ATTRIBUTES = [ "url" ];
7683
7684
 
7684
- // DOMPurify's own IS_ALLOWED_URI, reproduced rather than narrowed, so `url` on a
7685
- // non-attachment tag is treated exactly as DOMPurify would have treated it.
7686
- const ALLOWED_URI = /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.-]+(?:[^a-z+.:-]|$))/i;
7685
+ // DOMPurify's own IS_ALLOWED_URI scheme list, reproduced rather than narrowed, so
7686
+ // `url` on a non-attachment tag is treated exactly as DOMPurify would have treated
7687
+ // it. Kept as a source string so allowedUriRegexp() can widen it with an editor's
7688
+ // declared schemes without re-deriving the rest of the pattern.
7689
+ const BASE_URI_SCHEMES = "(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix";
7690
+
7691
+ // A scheme name (not a full pattern), so a caller can't inject regexp syntax.
7692
+ const SCHEME_NAME = /^[a-z][a-z0-9+.-]*$/;
7693
+
7694
+ // The executable schemes, by DOMPurify's own IS_SCRIPT_OR_DATA definition
7695
+ // (/^(?:\w+script|data):/i): javascript, vbscript, …script, and data. Widening the
7696
+ // allowlist to admit one would let it survive on href/object[data], which the
7697
+ // override otherwise defeats — DOMPurify does not re-block a scheme its
7698
+ // ALLOWED_URI_REGEXP accepts. A caller declaring one is dropped, so it stays
7699
+ // refused. This is a closed set (the schemes a browser executes), not a growing
7700
+ // denylist.
7701
+ const EXECUTABLE_SCHEME = /^(?:\w+script|data)$/i;
7702
+
7703
+ // Builds DOMPurify's default IS_ALLOWED_URI, optionally with extra schemes folded
7704
+ // into the scheme alternation. Widening the recognised-safe scheme set is how a
7705
+ // custom-scheme identifier (a mention's `gid://…`) passes validation without
7706
+ // exempting any attribute from it. Passing no schemes reproduces DOMPurify's
7707
+ // default exactly.
7708
+ function allowedUriRegexp(extraSchemes = []) {
7709
+ const extra = extraSchemes
7710
+ .map(scheme => String(scheme).toLowerCase())
7711
+ .filter(scheme => SCHEME_NAME.test(scheme) && !EXECUTABLE_SCHEME.test(scheme))
7712
+ .map(scheme => scheme.replace(/[.+-]/g, "\\$&"));
7713
+
7714
+ const schemes = [ BASE_URI_SCHEMES, ...extra ].join("|");
7715
+
7716
+ return new RegExp(`^(?:(?:${schemes}):|[^a-z]|[a-z+.-]+(?:[^a-z+.:-]|$))`, "i")
7717
+ }
7718
+
7719
+ const ALLOWED_URI = allowedUriRegexp();
7687
7720
 
7688
7721
  // eslint-disable-next-line no-control-regex -- mirrors DOMPurify's own ATTR_WHITESPACE
7689
7722
  const ATTR_WHITESPACE = /[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g;
@@ -7880,7 +7913,17 @@ function buildConfig(allowedElements = null) {
7880
7913
  // default tag and attribute policy stands. `ALLOWED_TAGS: []` would not be a
7881
7914
  // default, it would be a refusal: it strips every tag. An editor that declares
7882
7915
  // an empty allowlist still gets that refusal, because it asked for it.
7883
- if (allowedElements) Object.assign(config, allowlistFor(allowedElements));
7916
+ //
7917
+ // uriSafeSchemes widens the scheme validation rather than exempting an attribute
7918
+ // from it: ALLOWED_URI_REGEXP is set only when an editor declares custom schemes,
7919
+ // so a value like a mention's `gid://…` passes while javascript:/data: stay
7920
+ // refused on every attribute — including href and object[data]. Nothing is taken
7921
+ // out of URI checking, so there is no attribute to guard against exempting.
7922
+ if (allowedElements) {
7923
+ const { uriSafeSchemes, ...tagPolicy } = allowlistFor(allowedElements);
7924
+ if (uriSafeSchemes.length) config.ALLOWED_URI_REGEXP = allowedUriRegexp(uriSafeSchemes);
7925
+ Object.assign(config, tagPolicy);
7926
+ }
7884
7927
 
7885
7928
  // Always assigned, including when we have no policy — `null` is what
7886
7929
  // trustedTypesPolicy() returns then, and `TRUSTED_TYPES_POLICY: null` is
@@ -7903,6 +7946,7 @@ function allowlistFor(allowedElements) {
7903
7946
  // Object.prototype key: `tagAttributes["constructor"]` would answer with a
7904
7947
  // function, and ADD_ATTR would call .includes on it.
7905
7948
  const tagAttributes = Object.create(null);
7949
+ const uriSafeSchemes = [];
7906
7950
 
7907
7951
  // Lowercased, because DOMPurify lowercases ALLOWED_TAGS and calls ADD_ATTR
7908
7952
  // with the lowercased tag and attribute names. Keeping the caller's casing
@@ -7915,6 +7959,15 @@ function allowlistFor(allowedElements) {
7915
7959
 
7916
7960
  tagAttributes[tag] ||= [];
7917
7961
  tagAttributes[tag].push(...attributes);
7962
+
7963
+ // A custom scheme a caller declares is folded into the editor's URI-scheme
7964
+ // allowlist (ALLOWED_URI_REGEXP in buildConfig), so a value like a mention's
7965
+ // `gid="gid://…"` — which DOMPurify otherwise drops as an unknown scheme, even
7966
+ // once the `gid` name is allowed — passes validation. It widens the recognised
7967
+ // schemes, it does not exempt an attribute: javascript:/data: stay refused
7968
+ // everywhere, so there is no navigational attribute to guard. Declared per
7969
+ // element for locality, but a scheme is editor-wide once allowed.
7970
+ uriSafeSchemes.push(...(element.uriSafeSchemes ?? []));
7918
7971
  }
7919
7972
 
7920
7973
  // Only for tags the caller already permits — this widens what an allowed
@@ -7926,7 +7979,8 @@ function allowlistFor(allowedElements) {
7926
7979
  return {
7927
7980
  ALLOWED_TAGS: Object.keys(tagAttributes),
7928
7981
  ALLOWED_ATTR: ALLOWED_HTML_ATTRIBUTES,
7929
- ADD_ATTR: (attribute, tag) => tagAttributes[tag]?.includes(attribute)
7982
+ ADD_ATTR: (attribute, tag) => tagAttributes[tag]?.includes(attribute),
7983
+ uriSafeSchemes
7930
7984
  }
7931
7985
  }
7932
7986
 
@@ -9473,12 +9527,11 @@ class CustomActionTextAttachmentNode extends Ji {
9473
9527
  return Lexxy.global.get("attachmentTagName")
9474
9528
  }
9475
9529
 
9476
- constructor({ tagName, sgid, contentType, innerHtml, plainText } = {}, key) {
9530
+ constructor({ sgid, contentType, innerHtml, plainText } = {}, key) {
9477
9531
  super(key);
9478
9532
 
9479
9533
  const contentTypeNamespace = Lexxy.global.get("attachmentContentTypeNamespace");
9480
9534
 
9481
- this.tagName = tagName || CustomActionTextAttachmentNode.TAG_NAME;
9482
9535
  this.sgid = sgid;
9483
9536
  this.contentType = contentType || `application/vnd.${contentTypeNamespace}.unknown`;
9484
9537
  this.innerHtml = innerHtml;
@@ -9486,7 +9539,7 @@ class CustomActionTextAttachmentNode extends Ji {
9486
9539
  }
9487
9540
 
9488
9541
  createDOM(_config, editor) {
9489
- const figure = createElement(this.tagName, { "content-type": this.contentType, "data-lexxy-decorator": true, draggable: true });
9542
+ const figure = createElement(CustomActionTextAttachmentNode.TAG_NAME, { "content-type": this.contentType, "data-lexxy-decorator": true, draggable: true });
9490
9543
  figure.dataset.lexicalNodeKey = this.__key;
9491
9544
 
9492
9545
  // Resolved from the editor so this content is sanitized with its own
@@ -9529,7 +9582,7 @@ class CustomActionTextAttachmentNode extends Ji {
9529
9582
  }
9530
9583
 
9531
9584
  exportDOM() {
9532
- const attachment = createElement(this.tagName, {
9585
+ const attachment = createElement(CustomActionTextAttachmentNode.TAG_NAME, {
9533
9586
  sgid: this.sgid,
9534
9587
  content: this.innerHtml,
9535
9588
  "content-type": this.contentType
@@ -9542,7 +9595,6 @@ class CustomActionTextAttachmentNode extends Ji {
9542
9595
  return {
9543
9596
  type: "custom_action_text_attachment",
9544
9597
  version: 1,
9545
- tagName: this.tagName,
9546
9598
  sgid: this.sgid,
9547
9599
  contentType: this.contentType,
9548
9600
  innerHtml: this.innerHtml,
@@ -10299,10 +10351,9 @@ class ActionTextAttachmentNode extends Ji {
10299
10351
  return Lexxy.global.get("attachmentTagName")
10300
10352
  }
10301
10353
 
10302
- constructor({ tagName, sgid, src, previewSrc, previewable, previewStatusUrl, pendingPreview, altText, caption, contentType, fileName, fileSize, width, height, uploadError } = {}, key) {
10354
+ constructor({ sgid, src, previewSrc, previewable, previewStatusUrl, pendingPreview, altText, caption, contentType, fileName, fileSize, width, height, uploadError } = {}, key) {
10303
10355
  super(key);
10304
10356
 
10305
- this.tagName = tagName || ActionTextAttachmentNode.TAG_NAME;
10306
10357
  this.sgid = sgid;
10307
10358
  this.src = src;
10308
10359
  this.previewSrc = previewSrc;
@@ -10361,7 +10412,7 @@ class ActionTextAttachmentNode extends Ji {
10361
10412
  }
10362
10413
 
10363
10414
  exportDOM() {
10364
- const attachment = createElement(this.tagName, {
10415
+ const attachment = createElement(ActionTextAttachmentNode.TAG_NAME, {
10365
10416
  sgid: this.sgid,
10366
10417
  previewable: this.previewable || null,
10367
10418
  url: this.src,
@@ -10382,7 +10433,6 @@ class ActionTextAttachmentNode extends Ji {
10382
10433
  return {
10383
10434
  type: "action_text_attachment",
10384
10435
  version: 1,
10385
- tagName: this.tagName,
10386
10436
  sgid: this.sgid,
10387
10437
  src: this.src,
10388
10438
  previewable: this.previewable,
@@ -11152,6 +11202,34 @@ class UploadRequests {
11152
11202
 
11153
11203
  const Ke$1=/^(\d+(?:\.\d+)?)px$/,Ae$1={BOTH:3,COLUMN:2,NO_STATUS:0,ROW:1};let Ee$1 = class Ee extends Bi{__colSpan;__rowSpan;__headerState;__width;__backgroundColor;__verticalAlign;static getType(){return "tablecell"}static clone(e){return new Ee(e.__headerState,e.__colSpan,e.__width,e.__key)}afterCloneFrom(e){super.afterCloneFrom(e),this.__rowSpan=e.__rowSpan,this.__backgroundColor=e.__backgroundColor,this.__verticalAlign=e.__verticalAlign,this.__colSpan=e.__colSpan,this.__headerState=e.__headerState,this.__width=e.__width;}static importDOM(){return {td:e=>({conversion:Me$1,priority:0}),th:e=>({conversion:Me$1,priority:0})}}static importJSON(e){return $e$1().updateFromJSON(e)}updateFromJSON(e){return super.updateFromJSON(e).setHeaderStyles(e.headerState).setColSpan(e.colSpan||1).setRowSpan(e.rowSpan||1).setWidth(e.width||void 0).setBackgroundColor(e.backgroundColor||null).setVerticalAlign(e.verticalAlign||void 0)}constructor(e=Ae$1.NO_STATUS,t=1,n,o){super(o),this.__colSpan=t,this.__rowSpan=1,this.__headerState=e,this.__width=n,this.__backgroundColor=null,this.__verticalAlign=void 0;}createDOM(t){const n=document.createElement(this.getTag());return this.__width&&(n.style.width=`${this.__width}px`),this.__colSpan>1&&(n.colSpan=this.__colSpan),this.__rowSpan>1&&(n.rowSpan=this.__rowSpan),null!==this.__backgroundColor&&(n.style.backgroundColor=this.__backgroundColor),ke$1(this.__verticalAlign)&&(n.style.verticalAlign=this.__verticalAlign),mc(n,t.theme.tableCell,this.hasHeader()&&t.theme.tableCellHeader),n}exportDOM(e){const t=super.exportDOM(e);if(Ys(t.element)){const e=t.element;e.setAttribute("data-temporary-table-cell-lexical-key",this.getKey()),e.style.border="1px solid black",this.__colSpan>1&&(e.colSpan=this.__colSpan),this.__rowSpan>1&&(e.rowSpan=this.__rowSpan),e.style.width=`${this.getWidth()||75}px`,e.style.verticalAlign=this.getVerticalAlign()||"top",e.style.textAlign="start",null===this.__backgroundColor&&this.hasHeader()&&(e.style.backgroundColor="#f2f3f5");}return t}exportJSON(){return {...super.exportJSON(),...ke$1(this.__verticalAlign)&&{verticalAlign:this.__verticalAlign},backgroundColor:this.getBackgroundColor(),colSpan:this.__colSpan,headerState:this.__headerState,rowSpan:this.__rowSpan,width:this.getWidth()}}getColSpan(){return this.getLatest().__colSpan}setColSpan(e){const t=this.getWritable();return t.__colSpan=e,t}getRowSpan(){return this.getLatest().__rowSpan}setRowSpan(e){const t=this.getWritable();return t.__rowSpan=e,t}getTag(){return this.hasHeader()?"th":"td"}setHeaderStyles(e,t=Ae$1.BOTH){const n=this.getWritable();return n.__headerState=e&t|n.__headerState&~t,n}getHeaderStyles(){return this.getLatest().__headerState}setWidth(e){const t=this.getWritable();return t.__width=e,t}getWidth(){return this.getLatest().__width}getBackgroundColor(){return this.getLatest().__backgroundColor}setBackgroundColor(e){const t=this.getWritable();return t.__backgroundColor=e,t}getVerticalAlign(){return this.getLatest().__verticalAlign}setVerticalAlign(e){const t=this.getWritable();return t.__verticalAlign=e||void 0,t}toggleHeaderStyle(e){const t=this.getWritable();return (t.__headerState&e)===e?t.__headerState-=e:t.__headerState+=e,t}hasHeaderState(e){return (this.getHeaderStyles()&e)===e}hasHeader(){return this.getLatest().__headerState!==Ae$1.NO_STATUS}updateDOM(e){return e.__headerState!==this.__headerState||e.__width!==this.__width||e.__colSpan!==this.__colSpan||e.__rowSpan!==this.__rowSpan||e.__backgroundColor!==this.__backgroundColor||e.__verticalAlign!==this.__verticalAlign}isShadowRoot(){return true}collapseAtStart(){return true}canBeEmpty(){return false}canIndent(){return false}};function ke$1(e){return "middle"===e||"bottom"===e}function Me$1(e){const t=e,n=e.nodeName.toLowerCase();let o;Ke$1.test(t.style.width)&&(o=parseFloat(t.style.width));let r=Ae$1.NO_STATUS;if("th"===n){const e=t.getAttribute("scope");if("col"===e)r=Ae$1.COLUMN;else if("row"===e)r=Ae$1.ROW;else {const e=t.parentElement,n=Ys(e)&&"tr"===e.nodeName.toLowerCase()&&Ys(e.parentElement)&&("thead"===e.parentElement.nodeName.toLowerCase()||0===e.rowIndex),o=0===t.cellIndex;n&&(r|=Ae$1.ROW),o&&(r|=Ae$1.COLUMN),r===Ae$1.NO_STATUS&&(r=Ae$1.ROW);}}const l=$e$1(r,t.colSpan,o);l.__rowSpan=t.rowSpan;const s=t.style.backgroundColor;""!==s&&(l.__backgroundColor=s);const i=t.style.verticalAlign;ke$1(i)&&(l.__verticalAlign=i);const c=t.style,a=(c&&c.textDecoration||"").split(" "),u="700"===c.fontWeight||"bold"===c.fontWeight,h=a.includes("line-through"),C="italic"===c.fontStyle,_=a.includes("underline"),S=c.color;return {after:e=>{const t=[];let n=null;const o=()=>{if(n){const e=n.getFirstChild();sr(e)&&1===n.getChildrenSize()&&e.remove();}};for(const r of e)if(Fs(r)||Tr(r)||sr(r)){if(Tr(r)&&(u&&r.toggleFormat("bold"),h&&r.toggleFormat("strikethrough"),C&&r.toggleFormat("italic"),_&&r.toggleFormat("underline"),S)){const e=r.getStyle();e.includes("color:")||r.setStyle(e+`color: ${S};`);}n?n.append(r):(n=eo().append(r),t.push(n));}else t.push(r),o(),n=null;return o(),0===t.length&&t.push(eo()),t},node:l}}function $e$1(e=Ae$1.NO_STATUS,t=1,n){return zs(new Ee$1(e,t,n))}function We$1(e){return e instanceof Ee$1}const ze$1=re$5("INSERT_TABLE_COMMAND");function Le$1(e,...t){const n=new URL("https://lexical.dev/docs/error"),o=new URLSearchParams;o.append("code",e);for(const e of t)o.append("v",e);throw n.search=o.toString(),Error(`Minified Lexical error #${e}; visit ${n.toString()} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`)}let He$1 = class He extends Bi{__height;static getType(){return "tablerow"}static clone(e){return new He(e.__height,e.__key)}afterCloneFrom(e){super.afterCloneFrom(e),this.__height=e.__height;}static importDOM(){return {tr:e=>({conversion:Be$1,priority:0})}}static importJSON(e){return Pe$1().updateFromJSON(e)}updateFromJSON(e){return super.updateFromJSON(e).setHeight(e.height)}constructor(e,t){super(t),this.__height=e;}exportJSON(){const e=this.getHeight();return {...super.exportJSON(),...void 0===e?void 0:{height:e}}}createDOM(t){const n=document.createElement("tr");return this.__height&&(n.style.height=`${this.__height}px`),mc(n,t.theme.tableRow),n}extractWithChild(e,t,n){return "html"===n}isShadowRoot(){return true}setHeight(e){const t=this.getWritable();return t.__height=e,t}getHeight(){return this.getLatest().__height}updateDOM(e){return e.__height!==this.__height}canBeEmpty(){return false}canIndent(){return false}};function Be$1(e){const n=e;let o;return Ke$1.test(n.style.height)&&(o=parseFloat(n.style.height)),{after:e=>Ht$3(e,We$1),node:Pe$1(o)}}function Pe$1(e){return zs(new He$1(e))}function De$1(e){return e instanceof He$1}const Ie$1="undefined"!=typeof window&&void 0!==window.document&&void 0!==window.document.createElement,Ue$1=Ie$1&&"documentMode"in document?document.documentMode:null,Je$1=Ie$1&&/^(?!.*Seamonkey)(?=.*Firefox).*/i.test(navigator.userAgent);function Xe$1(e,t,n=true){const o=Fn();for(let r=0;r<e;r++){const e=Pe$1();for(let o=0;o<t;o++){let t=Ae$1.NO_STATUS;"object"==typeof n?(0===r&&n.rows&&(t|=Ae$1.ROW),0===o&&n.columns&&(t|=Ae$1.COLUMN)):n&&(0===r&&(t|=Ae$1.ROW),0===o&&(t|=Ae$1.COLUMN));const l=$e$1(t),s=eo();s.append(kr()),l.append(s),e.append(l);}o.append(e);}return o}function Ye(e){const t=dl(e,e=>We$1(e));return We$1(t)?t:null}function qe$1(e){const t=dl(e,e=>De$1(e));if(De$1(t))return t;throw new Error("Expected table cell to be inside of table row.")}function je$1(e){const t=dl(e,e=>Rn(e));if(Rn(t))return t;throw new Error("Expected table cell to be inside of table.")}function Ve$1(e){const t=qe$1(e);return je$1(t).getChildren().findIndex(e=>e.is(t))}function Ge$1(e){return qe$1(e).getChildren().findIndex(t=>t.is(e))}Ie$1&&"InputEvent"in window&&!Ue$1&&new window.InputEvent("input");const tt=(e,t)=>e===Ae$1.BOTH||e===t?t:Ae$1.NO_STATUS;function nt(e=true){const t=Qr();Fr(t)||Ot(t)||Le$1(188);const n=t.anchor.getNode(),o=t.focus.getNode(),[r]=yt(n),[l,,s]=yt(o),[,i,c]=wt(s,l,r),{startRow:a}=c,{startRow:u}=i;return e?rt(a+r.__rowSpan>u+l.__rowSpan?r:l,true):rt(u<a?l:r,false)}function rt(e,t=true){const[,,n]=yt(e),[o,r]=wt(n,e,e),l=o[0].length,{startRow:s}=r;let i=null;if(t){const t=s+e.__rowSpan-1,r=o[t],c=Pe$1();for(let e=0;e<l;e++){const{cell:n,startRow:o}=r[e];if(o+n.__rowSpan-1<=t){const t=r[e].cell.__headerState,n=tt(t,Ae$1.COLUMN);c.append($e$1(n).append(eo()));}else n.setRowSpan(n.__rowSpan+1);}const a=n.getChildAtIndex(t);De$1(a)||Le$1(256),a.insertAfter(c),i=c;}else {const e=s,t=o[e],r=Pe$1();for(let n=0;n<l;n++){const{cell:o,startRow:l}=t[n];if(l===e){const e=t[n].cell.__headerState,o=tt(e,Ae$1.COLUMN);r.append($e$1(o).append(eo()));}else o.setRowSpan(o.__rowSpan+1);}const c=n.getChildAtIndex(e);De$1(c)||Le$1(257),c.insertBefore(r),i=r;}return i}function st(e=true){const t=Qr();Fr(t)||Ot(t)||Le$1(188);const n=t.anchor.getNode(),o=t.focus.getNode(),[r]=yt(n),[l,,s]=yt(o),[,i,c]=wt(s,l,r),{startColumn:a}=c,{startColumn:u}=i;return e?ct(a+r.__colSpan>u+l.__colSpan?r:l,true):ct(u<a?l:r,false)}function ct(e,t=true,n=true){const[,,o]=yt(e),[r,l]=wt(o,e,e),s=r.length,{startColumn:i}=l,c=t?i+e.__colSpan-1:i-1,a=o.getFirstChild();De$1(a)||Le$1(120);let u=null;function h(e=Ae$1.NO_STATUS){const t=$e$1(e).append(eo());return null===u&&(u=t),t}let d=a;e:for(let e=0;e<s;e++){if(0!==e){const e=d.getNextSibling();De$1(e)||Le$1(121),d=e;}const t=r[e],n=t[c<0?0:c].cell.__headerState,o=tt(n,Ae$1.ROW);if(c<0){mt(d,h(o));continue}const{cell:l,startColumn:s,startRow:i}=t[c];if(s+l.__colSpan-1<=c){let n=l,r=i,s=c;for(;r!==e&&n.__rowSpan>1;){if(s-=l.__colSpan,!(s>=0)){d.append(h(o));continue e}{const{cell:e,startRow:o}=t[s];n=e,r=o;}}n.insertAfter(h(o));}else l.setColSpan(l.__colSpan+1);}null!==u&&n&&gt(u);const f=o.getColWidths();if(f){const e=[...f],t=c<0?0:c,n=e[t];e.splice(t,0,n),o.setColWidths(e);}return u}function ut(){const e=Qr();Fr(e)||Ot(e)||Le$1(188);const[t,n]=e.isBackward()?[e.focus.getNode(),e.anchor.getNode()]:[e.anchor.getNode(),e.focus.getNode()],[o,,r]=yt(t),[l]=yt(n),[s,i,c]=wt(r,o,l),{startRow:a}=i,{startRow:u}=c,h=u+l.__rowSpan-1;if(s.length===h-a+1)return void r.remove();const d=s[0].length,f=s[h+1],g=r.getChildAtIndex(h+1);for(let e=h;e>=a;e--){for(let t=d-1;t>=0;t--){const{cell:n,startRow:o,startColumn:r}=s[e][t];if(r===t){if(o<a||o+n.__rowSpan-1>h){const e=Math.max(o,a),t=Math.min(n.__rowSpan+o-1,h),r=e<=t?t-e+1:0;n.setRowSpan(n.__rowSpan-r);}if(o>=a&&o+n.__rowSpan-1>h&&e===h){null===g&&Le$1(122);let o=null;for(let n=0;n<t;n++){const t=f[n],r=t.cell;t.startRow===e+1&&(o=r),r.__colSpan>1&&(n+=r.__colSpan-1);}null===o?mt(g,n):o.insertAfter(n);}}}const t=r.getChildAtIndex(e);De$1(t)||Le$1(206,String(e)),t.remove();}if(void 0!==f){const{cell:e}=f[0];gt(e);}else {const e=s[a-1],{cell:t}=e[0];gt(t);}}function dt(){const e=Qr();Fr(e)||Ot(e)||Le$1(188);const t=e.anchor.getNode(),n=e.focus.getNode(),[o,,r]=yt(t),[l]=yt(n),[s,i,c]=wt(r,o,l),{startColumn:a}=i,{startRow:u,startColumn:h}=c,d=Math.min(a,h),f=Math.max(a+o.__colSpan-1,h+l.__colSpan-1),g=f-d+1;if(s[0].length===f-d+1)return r.selectPrevious(),void r.remove();const m=s.length;for(let e=0;e<m;e++)for(let t=d;t<=f;t++){const{cell:n,startColumn:o}=s[e][t];if(o<d){if(t===d){const e=d-o;n.setColSpan(n.__colSpan-Math.min(g,n.__colSpan-e));}}else if(o+n.__colSpan-1>f){if(t===f){const e=f-o+1;n.setColSpan(n.__colSpan-e);}}else n.remove();}const p=s[u],C=a>h?p[a+o.__colSpan]:p[h+l.__colSpan];if(void 0!==C){const{cell:e}=C;gt(e);}else {const e=h<a?p[h-1]:p[a-1],{cell:t}=e;gt(t);}const _=r.getColWidths();if(_){const e=[..._];e.splice(d,g),r.setColWidths(e);}}function gt(e){const t=e.getFirstDescendant();null==t?e.selectStart():t.getParentOrThrow().selectStart();}function mt(e,t){const n=e.getFirstChild();null!==n?n.insertBefore(t):e.append(t);}function pt(e){if(0===e.length)return null;const t=je$1(e[0]),[n]=bt(t,null,null);let o=1/0,r=-1/0,l=1/0,s=-1/0;const i=new Set;for(const t of n)for(const n of t){if(!n||!n.cell)continue;const t=n.cell.getKey();if(!i.has(t)&&e.some(e=>e.is(n.cell))){i.add(t);const e=n.startRow,c=n.startColumn,a=n.cell.__rowSpan||1,u=n.cell.__colSpan||1;o=Math.min(o,e),r=Math.max(r,e+a-1),l=Math.min(l,c),s=Math.max(s,c+u-1);}}if(o===1/0||l===1/0)return null;const c=r-o+1,a=s-l+1,u=n[o][l];if(!u.cell)return null;const h=u.cell;h.setColSpan(a),h.setRowSpan(c);const d=new Set([h.getKey()]);for(let e=o;e<=r;e++)for(let t=l;t<=s;t++){const o=n[e][t];if(!o.cell)continue;const r=o.cell,l=r.getKey();if(!d.has(l)){d.add(l);Ct(r)||h.append(...r.getChildren()),r.remove();}}return 0===h.getChildrenSize()&&h.append(eo()),h}function Ct(e){if(1!==e.getChildrenSize())return false;const t=e.getFirstChildOrThrow();return !(!no(t)||!t.isEmpty())}function St(e){const[t,n,o]=yt(e),r=t.__colSpan,l=t.__rowSpan;if(1===r&&1===l)return;const[s,i]=wt(o,t,t),{startColumn:c,startRow:a}=i,u=t.__headerState&Ae$1.COLUMN,h=Array.from({length:r},(e,t)=>{let n=u;for(let e=0;0!==n&&e<s.length;e++)n&=s[e][t+c].cell.__headerState;return n}),d=t.__headerState&Ae$1.ROW,f=Array.from({length:l},(e,t)=>{let n=d;for(let e=0;0!==n&&e<s[0].length;e++)n&=s[t+a][e].cell.__headerState;return n});if(r>1){for(let e=1;e<r;e++)t.insertAfter($e$1(h[e]|f[0]).append(eo()));t.setColSpan(1);}if(l>1){let e;for(let t=1;t<l;t++){const o=a+t,l=s[o];e=(e||n).getNextSibling(),De$1(e)||Le$1(125);let i=null;for(let e=0;e<c;e++){const t=l[e],n=t.cell;t.startRow===o&&(i=n),n.__colSpan>1&&(e+=n.__colSpan-1);}if(null===i)for(let n=r-1;n>=0;n--)mt(e,$e$1(h[n]|f[t]).append(eo()));else for(let e=r-1;e>=0;e--)i.insertAfter($e$1(h[e]|f[t]).append(eo()));}t.setRowSpan(1);}}function wt(e,t,n){const[o,r,l]=bt(e,t,n);return null===r&&Le$1(207),null===l&&Le$1(208),[o,r,l]}function bt(e,t,n){const o=[];let r=null,l=null;function s(e){let t=o[e];return void 0===t&&(o[e]=t=[]),t}const i=e.getChildren();for(let e=0;e<i.length;e++){const o=i[e];De$1(o)||Le$1(209);const c=s(e);for(let a=o.getFirstChild(),u=0;null!=a;a=a.getNextSibling()){for(We$1(a)||Le$1(147);void 0!==c[u];)u++;const o={cell:a,startColumn:u,startRow:e},{__rowSpan:h,__colSpan:d}=a;for(let t=0;t<h&&!(e+t>=i.length);t++){const n=s(e+t);for(let e=0;e<d;e++)n[u+e]=o;}null!==t&&null===r&&t.is(a)&&(r=o),null!==n&&null===l&&n.is(a)&&(l=o);}}return [o,r,l]}function yt(e){let t;if(e instanceof Ee$1)t=e;else if("__type"in e){const o=dl(e,We$1);We$1(o)||Le$1(148),t=o;}else {const o=dl(e.getNode(),We$1);We$1(o)||Le$1(148),t=o;}const o=t.getParent();De$1(o)||Le$1(149);const r=o.getParent();return Rn(r)||Le$1(210),[t,o,r]}function Nt(e,t,n){let o,r=Math.min(t.startColumn,n.startColumn),l=Math.min(t.startRow,n.startRow),s=Math.max(t.startColumn+t.cell.__colSpan-1,n.startColumn+n.cell.__colSpan-1),i=Math.max(t.startRow+t.cell.__rowSpan-1,n.startRow+n.cell.__rowSpan-1);do{o=false;for(let t=0;t<e.length;t++)for(let n=0;n<e[0].length;n++){const c=e[t][n];if(!c)continue;const a=c.startColumn+c.cell.__colSpan-1,u=c.startRow+c.cell.__rowSpan-1,h=c.startColumn<=s&&a>=r,d=c.startRow<=i&&u>=l;if(h&&d){const e=Math.min(r,c.startColumn),t=Math.max(s,a),n=Math.min(l,c.startRow),h=Math.max(i,u);e===r&&t===s&&n===l&&h===i||(r=e,s=t,l=n,i=h,o=true);}}}while(o);return {maxColumn:s,maxRow:i,minColumn:r,minRow:l}}function Tt(e){const[t,,n]=yt(e),o=n.getChildren(),r=o.length,l=o[0].getChildren().length,s=new Array(r);for(let e=0;e<r;e++)s[e]=new Array(l);for(let e=0;e<r;e++){const n=o[e].getChildren();let r=0;for(let o=0;o<n.length;o++){for(;s[e][r];)r++;const l=n[o],i=l.__rowSpan||1,c=l.__colSpan||1;for(let t=0;t<i;t++)for(let n=0;n<c;n++)s[e+t][r+n]=l;if(t===l)return {colSpan:c,columnIndex:r,rowIndex:e,rowSpan:i};r+=c;}}return null}function Ft(e){const[[t,o,r,l],[s,i,c,a]]=["anchor","focus"].map(t=>{const o=e[t].getNode(),r=dl(o,We$1);We$1(r)||Le$1(238,t,o.getKey(),o.getType());const l=r.getParent();De$1(l)||Le$1(239,t);const s=l.getParent();return Rn(s)||Le$1(240,t),[o,r,l,s]});return l.is(a)||Le$1(241),{anchorCell:o,anchorNode:t,anchorRow:r,anchorTable:l,focusCell:i,focusNode:s,focusRow:c,focusTable:a}}class Rt{tableKey;anchor;focus;_cachedNodes;dirty;constructor(e,t,n){this.anchor=t,this.focus=n,t._selection=this,n._selection=this,this._cachedNodes=null,this.dirty=false,this.tableKey=e;}getStartEndPoints(){return [this.anchor,this.focus]}isValid(){if("root"===this.tableKey||"root"===this.anchor.key||"element"!==this.anchor.type||"root"===this.focus.key||"element"!==this.focus.type)return false;const e=Yo(this.tableKey),t=Yo(this.anchor.key),n=Yo(this.focus.key);return null!==e&&null!==t&&null!==n}isBackward(){return this.focus.isBefore(this.anchor)}getCachedNodes(){return this._cachedNodes}setCachedNodes(e){this._cachedNodes=e;}is(e){return Ot(e)&&this.tableKey===e.tableKey&&this.anchor.is(e.anchor)&&this.focus.is(e.focus)}set(e,t,n){this.dirty=this.dirty||e!==this.tableKey||t!==this.anchor.key||n!==this.focus.key,this.tableKey=e,this.anchor.key=t,this.focus.key=n,this._cachedNodes=null;}clone(){return new Rt(this.tableKey,Mr(this.anchor.key,this.anchor.offset,this.anchor.type),Mr(this.focus.key,this.focus.offset,this.focus.type))}isCollapsed(){return false}extract(){return this.getNodes()}insertRawText(e){}insertText(){}hasFormat(e){let t=0;this.getNodes().filter(We$1).forEach(e=>{const n=e.getFirstChild();no(n)&&(t|=n.getTextFormat());});const n=z$7[e];return 0!==(t&n)}insertNodes(e){const t=this.focus.getNode();Wi(t)||Le$1(151);St$3(t.select(0,t.getChildrenSize())).insertNodes(e);}getShape(){const{anchorCell:e,focusCell:t}=Ft(this),n=Tt(e);null===n&&Le$1(153);const o=Tt(t);null===o&&Le$1(155);const r=Math.min(n.columnIndex,o.columnIndex),l=Math.max(n.columnIndex+n.colSpan-1,o.columnIndex+o.colSpan-1),s=Math.min(n.rowIndex,o.rowIndex),i=Math.max(n.rowIndex+n.rowSpan-1,o.rowIndex+o.rowSpan-1);return {fromX:Math.min(r,l),fromY:Math.min(s,i),toX:Math.max(r,l),toY:Math.max(s,i)}}getNodes(){if(!this.isValid())return [];const e=this._cachedNodes;if(null!==e)return e;const{anchorTable:t,anchorCell:n,focusCell:o}=Ft(this),r=o.getParents()[1];if(r!==t){if(t.isParentOf(o)){const e=r.getParent();null==e&&Le$1(159),this.set(this.tableKey,o.getKey(),e.getKey());}else {const e=t.getParent();null==e&&Le$1(158),this.set(this.tableKey,e.getKey(),o.getKey());}return this.getNodes()}const[l,s,i]=wt(t,n,o),{minColumn:c,maxColumn:a,minRow:u,maxRow:h}=Nt(l,s,i),d=new Map([[t.getKey(),t]]);let f=null;for(let e=u;e<=h;e++)for(let t=c;t<=a;t++){const{cell:n}=l[e][t],o=n.getParent();De$1(o)||Le$1(160),o!==f&&(d.set(o.getKey(),o),f=o),d.has(n.getKey())||Et(n,e=>{d.set(e.getKey(),e);});}const g=Array.from(d.values());return mi()||(this._cachedNodes=g),g}getTextContent(){const e=this.getNodes().filter(e=>We$1(e));let t="";for(let n=0;n<e.length;n++){const o=e[n],r=o.__parent,l=(e[n+1]||{}).__parent;t+=o.getTextContent()+(l!==r?"\n":"\t");}return t}}function Ot(e){return e instanceof Rt}function Kt(){const e=Mr("root",0,"element"),t=Mr("root",0,"element");return new Rt("root",e,t)}function At(e,t,n){e.getKey(),t.getKey(),n.getKey();const o=Qr(),r=Ot(o)?o.clone():Kt();return r.set(e.getKey(),t.getKey(),n.getKey()),r}function Et(e,t){const n=[[e]];for(let e=n.at(-1);void 0!==e&&n.length>0;e=n.at(-1)){const o=e.pop();void 0===o?n.pop():false!==t(o)&&Wi(o)&&n.push(o.getChildren());}}function kt(e,t=Zs()){const n=Yo(e);Rn(n)||Le$1(231,e);const o=Lt(n,t.getElementByKey(e));return null===o&&Le$1(232,e),{tableElement:o,tableNode:n}}class Mt{observers;nextFocus;shouldCheckSelectionForTable;constructor(){this.observers=new Map,this.nextFocus=null,this.shouldCheckSelectionForTable=null;}setNextFocus(e){this.nextFocus=e;}getAndClearNextFocus(){const{nextFocus:e}=this;return null!==e&&(this.nextFocus=null),e}setShouldCheckSelectionForTable(e){this.shouldCheckSelectionForTable=e;}getAndClearShouldCheckSelectionForTable(){const{shouldCheckSelectionForTable:e}=this;return e?(this.shouldCheckSelectionForTable=null,e):null}}class $t{focusX;focusY;listenersToRemove;table;isHighlightingCells;anchorX;anchorY;tableNodeKey;anchorCell;focusCell;anchorCellNodeKey;focusCellNodeKey;editor;tableSelection;hasHijackedSelectionStyles;isSelecting;pointerType;abortController;listenerOptions;constructor(e,t){this.isHighlightingCells=false,this.anchorX=-1,this.anchorY=-1,this.focusX=-1,this.focusY=-1,this.listenersToRemove=new Set,this.tableNodeKey=t,this.editor=e,this.table={columns:0,domRows:[],rows:0},this.tableSelection=null,this.anchorCellNodeKey=null,this.focusCellNodeKey=null,this.anchorCell=null,this.focusCell=null,this.hasHijackedSelectionStyles=false,this.isSelecting=false,this.pointerType=null,this.abortController=new AbortController,this.listenerOptions={signal:this.abortController.signal},this.trackTable();}getTable(){return this.table}removeListeners(){this.abortController.abort("removeListeners"),Array.from(this.listenersToRemove).forEach(e=>e()),this.listenersToRemove.clear();}$lookup(){return kt(this.tableNodeKey,this.editor)}trackTable(){const e=new MutationObserver(e=>{this.editor.getEditorState().read(()=>{let t=false;for(let n=0;n<e.length;n++){const o=e[n].target.nodeName;if("TABLE"===o||"TBODY"===o||"THEAD"===o||"TR"===o){t=true;break}}if(!t)return;const{tableNode:n,tableElement:o}=this.$lookup();this.table=Gt(n,o);},{editor:this.editor});});this.editor.getEditorState().read(()=>{const{tableNode:t,tableElement:n}=this.$lookup();this.table=Gt(t,n),e.observe(n,{attributes:true,childList:true,subtree:true});},{editor:this.editor});}$clearHighlight(e=true){const t=this.editor;this.isHighlightingCells=false,this.anchorX=-1,this.anchorY=-1,this.focusX=-1,this.focusY=-1,this.tableSelection=null,this.anchorCellNodeKey=null,this.focusCellNodeKey=null,this.anchorCell=null,this.focusCell=null,this.hasHijackedSelectionStyles=false,this.$enableHighlightStyle();const{tableNode:n,tableElement:o}=this.$lookup();Qt(t,Gt(n,o),null),e&&null!==Qr()&&(es(null),t.dispatchCommand(ie$4,void 0));}$enableHighlightStyle(){const e=this.editor,{tableElement:t}=this.$lookup();xc(t,e._config.theme.tableSelection),t.classList.remove("disable-selection"),this.hasHijackedSelectionStyles=false;}$disableHighlightStyle(){const{tableElement:t}=this.$lookup();mc(t,this.editor._config.theme.tableSelection),this.hasHijackedSelectionStyles=true;}$updateTableTableSelection(e){if(null!==e){e.tableKey!==this.tableNodeKey&&Le$1(233,e.tableKey,this.tableNodeKey);const t=this.editor;this.tableSelection=e,this.isHighlightingCells=true,this.$disableHighlightStyle(),this.updateDOMSelection(),Qt(t,this.table,this.tableSelection);}else this.$clearHighlight();}updateDOMSelection(){if(null!==this.anchorCell&&null!==this.focusCell){const e=Js(this.editor._window);e&&e.rangeCount>0&&e.removeAllRanges();}}$setFocusCellForSelection(e,t=false){const n=this.editor,{tableNode:o}=this.$lookup(),r=e.x,l=e.y;if(this.focusCell=e,!this.isHighlightingCells){(t||this.anchorX!==r||this.anchorY!==l||null!=this.tableSelection&&null!=this.anchorCellNodeKey)&&(this.isHighlightingCells=true,this.$disableHighlightStyle());}if(-1!==this.focusX&&-1!==this.focusY&&r===this.focusX&&l===this.focusY)return false;if(this.focusX=r,this.focusY=l,this.isHighlightingCells){const s=_n(o,e.elem);if(null!=this.tableSelection&&null!=this.anchorCellNodeKey){let e=s;if(null===e&&t&&(e=o.getCellNodeFromCords(r,l,this.table)),null!==e){const t=this.$getAnchorTableCellOrThrow();return this.focusCellNodeKey=e.getKey(),this.tableSelection=At(o,t,e),es(this.tableSelection),n.dispatchCommand(ie$4,void 0),Qt(n,this.table,this.tableSelection),true}}}return false}$getAnchorTableCell(){return this.anchorCellNodeKey?Yo(this.anchorCellNodeKey):null}$getAnchorTableCellOrThrow(){const e=this.$getAnchorTableCell();return null===e&&Le$1(234),e}$getFocusTableCell(){return this.focusCellNodeKey?Yo(this.focusCellNodeKey):null}$getFocusTableCellOrThrow(){const e=this.$getFocusTableCell();return null===e&&Le$1(235),e}$setAnchorCellForSelection(e){this.isHighlightingCells=false,this.anchorCell=e,this.anchorX=e.x,this.anchorY=e.y,this.focusX=-1,this.focusY=-1,this.focusCell=null,this.focusCellNodeKey=null;const{tableNode:t}=this.$lookup(),n=_n(t,e.elem);if(null!==n){const e=n.getKey();null!=this.tableSelection?(this.tableSelection=this.tableSelection.clone(),this.tableSelection.set(t.getKey(),e,e)):this.tableSelection=At(t,n,n),this.anchorCellNodeKey=e;}}$formatCells(e){const t=Qr();Ot(t)||Le$1(236);const n=qr(),o=n.anchor,r=n.focus,l=t.getNodes().filter(We$1);l.length>0||Le$1(237);const s=l[0].getFirstChild(),i=no(s)?s.getFormatFlags(e,null):null;l.forEach(t=>{o.set(t.getKey(),0,"element"),r.set(t.getKey(),t.getChildrenSize(),"element"),n.formatText(e,i);}),es(t),this.editor.dispatchCommand(ie$4,void 0);}$clearText(){const{editor:e}=this,t=Yo(this.tableNodeKey);if(!Rn(t))throw new Error("Expected TableNode.");const n=Qr();Ot(n)||Le$1(253);const o=n.getNodes().filter(We$1),r=t.getFirstChild(),l=t.getLastChild();if(o.length>0&&null!==r&&null!==l&&De$1(r)&&De$1(l)&&o[0]===r.getFirstChild()&&o[o.length-1]===l.getLastChild()){t.selectPrevious();const n=t.getParent();return t.remove(),void(Vi(n)&&n.isEmpty()&&e.dispatchCommand(he$3,void 0))}o.forEach(e=>{if(Wi(e)){const t=eo(),n=kr();t.append(n),e.append(t),e.getChildren().forEach(e=>{e!==t&&e.remove();});}}),Qt(e,this.table,null),es(null),e.dispatchCommand(ie$4,void 0);}}const Wt="__lexicalTableSelection";function zt(e){return Ys(e)&&"TABLE"===e.nodeName}function Lt(e,t){if(!t)return t;const n=zt(t)?t:t.querySelector("table");return zt(n)||Le$1(341,e.constructor.name,e.getType(),e.getKey(),t.nodeName),n}function Ht(e){return e._window}function Bt(e,t){for(let n=t,o=null;null!==n;n=n.getParent()){if(e.is(n))return o;We$1(n)&&(o=n);}return null}const Pt=[[Ee$3,"down"],[we$1,"up"],[Ne$1,"backward"],[ke$2,"forward"]],Dt=[ye$2,me$3,fe$4],It=[Ae$3,Pe$2];function Ut(e,t){const n=e.getRootElement(),o=e._window;if(!n||!o)return ()=>{};const r=o=>{const r=o.target;if(0!==o.button||!qs(r)||!n.contains(r))return;const l=function(e){const t=jt(e);if(null===t)return null;let n=t.elem;for(;null!=n;){if("TABLE"===n.nodeName&&Wt in n&&n[Wt])return {cellElement:t,tableElement:n,tableObserver:n[Wt]};n=n.parentNode;}return null}(r);e.update(()=>{if(Ot(Qr())){for(const[e]of t.observers.values())e.$clearHighlight(false);es(null),e.dispatchCommand(ie$4,void 0);}if(!l)return;const{tableObserver:n,tableElement:r,cellElement:s}=l;!function(e,t,n,o,r,l){const s=e._window;if(!s)return;const i=t=>{if(r.isSelecting)return;r.isSelecting=true,null!==t&&null===r.anchorCell&&e.update(()=>{r.$setAnchorCellForSelection(t);});const n=()=>{r.isSelecting=false,s.removeEventListener("pointerup",n),s.removeEventListener("pointermove",i);},i=t=>{if(!(e=>!(1&~e.buttons))(t)&&r.isSelecting)return r.isSelecting=false,s.removeEventListener("pointerup",n),void s.removeEventListener("pointermove",i);if(!qs(t.target))return;let c=null;const a=!(Je$1||o.contains(t.target));if(a)c=Vt(o,t.target);else for(const e of document.elementsFromPoint(t.clientX,t.clientY))if(c=Vt(o,e),c)break;if(c){const t=c;null===r.anchorCell&&e.update(()=>{r.$setAnchorCellForSelection(t);}),null!==r.focusCell&&c.elem===r.focusCell.elem||(l.setNextFocus({focusCell:c,override:a,tableKey:r.tableNodeKey}),e.dispatchCommand(ie$4,void 0));}};s.addEventListener("pointerup",n,r.listenerOptions),s.addEventListener("pointermove",i,r.listenerOptions);};r.pointerType=t.pointerType;const c=Bs(r.tableNodeKey),a=Zr();if(Je$1&&t.shiftKey&&ln(a,c)&&(Fr(a)||Ot(a))){const e=a.anchor.getNode(),o=Bt(c,a.anchor.getNode());if(o)r.$setAnchorCellForSelection(Cn(r,o)),r.$setFocusCellForSelection(n),gn(t);else {(c.isBefore(e)?c.selectStart():c.selectEnd()).anchor.set(a.anchor.key,a.anchor.offset,a.anchor.type);}}else "touch"!==t.pointerType&&r.$setAnchorCellForSelection(n);i(n);}(e,o,s,r,n,t);});};return o.addEventListener("pointerdown",r),()=>{o.removeEventListener("pointerdown",r);}}function Jt(e,t,o,l,s){const i=o.getRootElement(),c=Ht(o);null!==i&&null!==c||Le$1(246);const a=new $t(o,e.getKey()),u=Lt(e,t);!function(e,t){null!==qt(e)&&Le$1(205);e[Wt]=t;}(u,a),a.listenersToRemove.add(()=>function(e,t){qt(e)===t&&delete e[Wt];}(u,a));const h=e=>{if(e.detail>=3&&qs(e.target)){null!==jt(e.target)&&e.preventDefault();}};u.addEventListener("mousedown",h,a.listenerOptions),a.listenersToRemove.add(()=>{u.removeEventListener("mousedown",h);});for(const[t,n]of Pt)a.listenersToRemove.add(o.registerCommand(t,t=>fn(o,t,n,e,a,s),so));a.listenersToRemove.add(o.registerCommand(De$2,t=>{const n=Qr();if(Ot(n)){const o=Bt(e,n.focus.getNode());if(null!==o)return gn(t),o.selectEnd(),true}return false},so));const d=t=>()=>{const o=Qr();if(!ln(o,e))return false;if(Ot(o))return a.$clearText(),true;if(Fr(o)){if(!We$1(Bt(e,o.anchor.getNode())))return false;const r=o.anchor.getNode(),l=o.focus.getNode(),s=e.isParentOf(r),i=e.isParentOf(l);if(s&&!i||i&&!s)return a.$clearText(),true;const c=dl(o.anchor.getNode(),e=>Wi(e)),u=c&&dl(c,e=>Wi(e)&&We$1(e.getParent()));if(!Wi(u)||!Wi(c))return false;if(t===me$3&&null===u.getPreviousSibling())return true}return false};for(const e of Dt)a.listenersToRemove.add(o.registerCommand(e,d(e),so));const f=t=>{const n=Qr();if(!Ot(n)&&!Fr(n))return false;const o=e.isParentOf(n.anchor.getNode());if(o!==e.isParentOf(n.focus.getNode())){const t=o?"anchor":"focus",r=o?"focus":"anchor",{key:l,offset:s,type:i}=n[r];return e[n[t].isBefore(n[r])?"selectPrevious":"selectNext"]()[r].set(l,s,i),false}return !!ln(n,e)&&(!!Ot(n)&&(t&&(t.preventDefault(),t.stopPropagation()),a.$clearText(),true))};for(const e of It)a.listenersToRemove.add(o.registerCommand(e,f,so));return a.listenersToRemove.add(o.registerCommand(je$2,e=>{const t=Qr();if(t){if(!Ot(t)&&!Fr(t))return false;V$4(o,Bt$3(e,ClipboardEvent)?e:null,et(t));const n=f(e);return Fr(t)?(t.removeText(),true):n}return false},so)),a.listenersToRemove.add(o.registerCommand(xe,t=>{const o=Qr();if(!ln(o,e))return false;if(Ot(o))return a.$formatCells(t),true;if(Fr(o)){const e=dl(o.anchor.getNode(),e=>We$1(e));if(!We$1(e))return false}return false},so)),a.listenersToRemove.add(o.registerCommand(Re$1,t=>{const n=Qr();if(!Ot(n)||!ln(n,e))return false;const o=n.anchor.getNode(),r=n.focus.getNode();if(!We$1(o)||!We$1(r))return false;if(function(e,t){if(Ot(e)){const n=e.anchor.getNode(),o=e.focus.getNode();if(t&&n&&o){const[e]=wt(t,n,o);return n.getKey()===e[0][0].cell.getKey()&&o.getKey()===e[e.length-1].at(-1).cell.getKey()}}return false}(n,e))return e.setFormat(t),true;const[l,s,i]=wt(e,o,r),c=Math.max(s.startRow+s.cell.__rowSpan-1,i.startRow+i.cell.__rowSpan-1),a=Math.max(s.startColumn+s.cell.__colSpan-1,i.startColumn+i.cell.__colSpan-1),u=Math.min(s.startRow,i.startRow),h=Math.min(s.startColumn,i.startColumn),d=new Set;for(let e=u;e<=c;e++)for(let n=h;n<=a;n++){const o=l[e][n].cell;if(d.has(o))continue;d.add(o),o.setFormat(t);const r=o.getChildren();for(let e=0;e<r.length;e++){const n=r[e];Wi(n)&&!n.isInline()&&n.setFormat(t);}}return true},so)),a.listenersToRemove.add(o.registerCommand(ge$3,t=>{const r=Qr();if(!ln(r,e))return false;if(Ot(r))return a.$clearHighlight(),false;if(Fr(r)){const l=dl(r.anchor.getNode(),e=>We$1(e));if(!We$1(l))return false;if("string"==typeof t){const n=pn(o,r,e);if(n)return mn(n,e,[kr(t)]),true}}return false},so)),l&&a.listenersToRemove.add(o.registerCommand(Fe$2,t=>{const o=Qr();if(!Fr(o)||!o.isCollapsed()||!ln(o,e))return false;const r=un(o.anchor.getNode());return !(null===r||!e.is(hn(r)))&&(gn(t),function(e,t){const o="next"===t?"getNextSibling":"getPreviousSibling",r="next"===t?"getFirstChild":"getLastChild",l=e[o]();if(Wi(l))return l.selectEnd();const s=dl(e,De$1);null===s&&Le$1(247);for(let e=s[o]();De$1(e);e=e[o]()){const t=e[r]();if(Wi(t))return t.selectEnd()}const i=dl(s,Rn);null===i&&Le$1(248);"next"===t?i.selectNext():i.selectPrevious();}(r,t.shiftKey?"previous":"next"),true)},so)),a.listenersToRemove.add(o.registerCommand(Ge$2,t=>e.isSelected(),so)),a.listenersToRemove.add(o.registerCommand(he$3,()=>{const t=Qr();if(!Fr(t)||!t.isCollapsed()||!ln(t,e))return false;const n=pn(o,t,e);return !!n&&(mn(n,e),true)},so)),a}function Xt(e,t){const o=Qr(),r=Zr(),l=e.getAndClearNextFocus();if(null!==l){const{tableKey:t,focusCell:n}=l,r=e.observers.get(t);r||Le$1(335,t);const[s]=r;if(Ot(o)&&o.tableKey===s.tableNodeKey)return (n.x!==s.focusX||n.y!==s.focusY)&&(s.$setFocusCellForSelection(n),true);if(null!==s.anchorCell&&null!==s.anchorCellNodeKey&&n.elem!==s.anchorCell.elem&&null!==s.tableSelection)return s.$setFocusCellForSelection(n,true),true}const s=e.getAndClearShouldCheckSelectionForTable();if(s&&Fr(r)&&Fr(o)&&o.isCollapsed()){const e=Bs(s),t=o.anchor.getNode(),r=e.getFirstChild(),l=un(t);if(null!==l&&De$1(r)){const t=r.getFirstChild();if(We$1(t)&&e.is(dl(l,n=>n.is(e)||n.is(t))))return t.selectStart(),true}}Ot(o)&&function(e,t){const n=Ht(e),o=Zr();if(!t.is(o))return;const r=Bs(t.tableKey),l=Js(n);if(l&&l.anchorNode&&l.focusNode){const n=Go(l.focusNode),o=n&&!r.isParentOf(n),s=Go(l.anchorNode),i=s&&r.isParentOf(s);if(o&&i&&l.rangeCount>0){const n=Gr(l,e);n&&(n.anchor.set(r.getKey(),t.isBackward()?r.getChildrenSize():0,"element"),l.removeAllRanges(),es(n));}}}(t,o),Fr(o)&&function(e,t){const n=Zr(),{anchor:o,focus:r}=e,l=o.getNode(),s=r.getNode(),i=un(l),c=un(s),a=i?hn(i):null,u=c?hn(c):null,h=e.isBackward(),d=i&&c&&a&&u&&a.is(u),f=u&&(!a||a.isParentOf(u)),g=a&&(!u||u.isParentOf(a));if(f){const t=e.clone(),[n]=wt(u,c,c),o=n[0][0].cell,r=n[n.length-1].at(-1).cell;t.focus.set(h?o.getKey():r.getKey(),h?0:r.getChildrenSize(),"element"),es(t);}else if(g){const t=e.clone(),[n]=wt(a,i,i),o=n[0][0].cell,r=n[n.length-1].at(-1).cell;t.anchor.set(h?r.getKey():o.getKey(),h?r.getChildrenSize():0,"element"),es(t);}else if(d){const o=t.observers.get(a.getKey());o||Le$1(335,a.getKey());const[r]=o;if(i.is(c)||(r.$setAnchorCellForSelection(Cn(r,i)),r.$setFocusCellForSelection(Cn(r,c),true)),"touch"===r.pointerType&&r.isSelecting&&e.isCollapsed()&&Fr(n)&&n.isCollapsed()){const e=un(n.anchor.getNode());e&&!e.is(c)&&(r.$setAnchorCellForSelection(Cn(r,e)),r.$setFocusCellForSelection(Cn(r,c),true),r.pointerType=null);}}}(o,e);const i=Array.from(e.observers.entries()).map(([e,[t]])=>({tableNode:Bs(e),tableObserver:t}));for(const{tableNode:e,tableObserver:n}of i)Yt(t,e,n);return false}function Yt(e,t,n){const o=Qr(),r=Zr();o&&!o.is(r)&&(Ot(o)||Ot(r))&&n.tableSelection&&!n.tableSelection.is(r)&&(Ot(o)&&o.tableKey===n.tableNodeKey?n.$updateTableTableSelection(o):!Ot(o)&&Ot(r)&&r.tableKey===n.tableNodeKey&&n.$updateTableTableSelection(null)),n.hasHijackedSelectionStyles&&!t.isSelected()?function(e,t){t.$enableHighlightStyle(),Zt(t.table,t=>{const n=t.elem;t.highlighted=false,an(e,t),n.getAttribute("style")||n.removeAttribute("style");});}(e,n):!n.hasHijackedSelectionStyles&&t.isSelected()&&function(e,t){t.$disableHighlightStyle(),Zt(t.table,t=>{t.highlighted=true,cn(e,t);});}(e,n);}function qt(e){return e[Wt]||null}function jt(e){let t=e;for(;null!=t;){const e=t.nodeName;if("TD"===e||"TH"===e){const e=t._cell;return void 0===e?null:e}t=t.parentNode;}return null}function Vt(e,t){if(!e.contains(t))return null;let n=null;for(let o=t;null!=o;o=o.parentNode){if(o===e)return n;const t=o.nodeName;"TD"!==t&&"TH"!==t||(n=o._cell||null);}return null}function Gt(e,t){const n=[],o={columns:0,domRows:n,rows:0};let r=Lt(e,t).querySelector("tr"),l=0,s=0;for(n.length=0;null!=r;){const e=r.nodeName;if("TD"===e||"TH"===e){const e={elem:r,hasBackgroundColor:""!==r.style.backgroundColor,highlighted:false,x:l,y:s};r._cell=e;let t=n[s];void 0===t&&(t=n[s]=[]),t[l]=e;}else {const e=r.firstChild;if(null!=e){r=e;continue}}const t=r.nextSibling;if(null!=t){l++,r=t;continue}const o=r.parentNode;if(null!=o){const e=o.nextSibling;if(null==e)break;s++,l=0,r=e;}}return o.columns=l+1,o.rows=s+1,o}function Qt(e,t,n){const o=new Set(n?n.getNodes():[]);Zt(t,(t,n)=>{const r=t.elem;o.has(n)?(t.highlighted=true,cn(e,t)):(t.highlighted=false,an(e,t),r.getAttribute("style")||r.removeAttribute("style"));});}function Zt(e,t){const{domRows:n}=e;for(let e=0;e<n.length;e++){const o=n[e];if(o)for(let n=0;n<o.length;n++){const r=o[n];if(!r)continue;const l=Go(r.elem);null!==l&&t(r,l,{x:n,y:e});}}}const en=(e,t,n,o,r)=>{const l="forward"===r;switch(r){case "backward":case "forward":return n!==(l?e.table.columns-1:0)?sn(t.getCellNodeFromCordsOrThrow(n+(l?1:-1),o,e.table),l):o!==(l?e.table.rows-1:0)?sn(t.getCellNodeFromCordsOrThrow(l?0:e.table.columns-1,o+(l?1:-1),e.table),l):l?t.selectNext():t.selectPrevious(),true;case "up":return 0!==o?sn(t.getCellNodeFromCordsOrThrow(n,o-1,e.table),false):t.selectPrevious(),true;case "down":return o!==e.table.rows-1?sn(t.getCellNodeFromCordsOrThrow(n,o+1,e.table),true):t.selectNext(),true;default:return false}};function tn(e,t){let n,o;if(t.startColumn===e.minColumn)n="minColumn";else {if(t.startColumn+t.cell.__colSpan-1!==e.maxColumn)return null;n="maxColumn";}if(t.startRow===e.minRow)o="minRow";else {if(t.startRow+t.cell.__rowSpan-1!==e.maxRow)return null;o="maxRow";}return [n,o]}function nn([e,t]){return ["minColumn"===e?"maxColumn":"minColumn","minRow"===t?"maxRow":"minRow"]}function on(e,t,[n,o]){const r=t[o],l=e[r];void 0===l&&Le$1(250,o,String(r));const s=t[n],i=l[s];return void 0===i&&Le$1(250,n,String(s)),i}function rn(e,t,n,o,r){const l=Nt(t,n,o),s=function(e,t){const{minColumn:n,maxColumn:o,minRow:r,maxRow:l}=t;let s=1,i=1,c=1,a=1;const u=e[r],h=e[l];for(let e=n;e<=o;e++)s=Math.max(s,u[e].cell.__rowSpan),a=Math.max(a,h[e].cell.__rowSpan);for(let t=r;t<=l;t++)i=Math.max(i,e[t][n].cell.__colSpan),c=Math.max(c,e[t][o].cell.__colSpan);return {bottomSpan:a,leftSpan:i,rightSpan:c,topSpan:s}}(t,l),{topSpan:i,leftSpan:c,bottomSpan:a,rightSpan:u}=s,h=function(e,t){const n=tn(e,t);return null===n&&Le$1(249,t.cell.getKey()),n}(l,n),[d,f]=nn(h);let g=l[d],m=l[f];"forward"===r?g+="maxColumn"===d?1:c:"backward"===r?g-="minColumn"===d?1:u:"down"===r?m+="maxRow"===f?1:i:"up"===r&&(m-="minRow"===f?1:a);const p=t[m];if(void 0===p)return false;const C=p[g];if(void 0===C)return false;const[_,S]=function(e,t,n){const o=Nt(e,t,n),r=tn(o,t);if(r)return [on(e,o,r),on(e,o,nn(r))];const l=tn(o,n);if(l)return [on(e,o,nn(l)),on(e,o,l)];const s=["minColumn","minRow"];return [on(e,o,s),on(e,o,nn(s))]}(t,n,C),w=Cn(e,_.cell),b=Cn(e,S.cell);return e.$setAnchorCellForSelection(w),e.$setFocusCellForSelection(b,true),true}function ln(e,t){if(Fr(e)||Ot(e)){const n=t.isParentOf(e.anchor.getNode()),o=t.isParentOf(e.focus.getNode());return n&&o}return false}function sn(e,t){t?e.selectStart():e.selectEnd();}function cn(t,n){const o=n.elem,r=t._config.theme;We$1(Go(o))||Le$1(131),mc(o,r.tableCellSelected);}function an(e,t){const n=t.elem;We$1(Go(n))||Le$1(131);const r=e._config.theme;xc(n,r.tableCellSelected);}function un(e){const t=dl(e,We$1);return We$1(t)?t:null}function hn(e){const t=dl(e,Rn);return Rn(t)?t:null}function dn(e,t,o,r,l,s,i){const c=ql(o.focus,l?"previous":"next");if(ic(c))return false;let a=c;for(const e of Rl(c).iterNodeCarets("shadowRoot")){if(!Tl(e)||!Wi(e.origin))return false;a=e;}const u=a.getParentAtCaret();if(!We$1(u))return false;const h=u,d=function(e){for(const t of Rl(e).iterNodeCarets("root")){const{origin:n}=t;if(We$1(n)){if(Nl(t))return Pl(n,e.direction)}else if(!De$1(n))break}return null}(Ol(h,a.direction)),f=dl(h,Rn);if(!f||!f.is(s))return false;const g=e.getElementByKey(h.getKey()),m=jt(g);if(!g||!m)return false;const p=xn(e,f);if(i.table=p,d)if("extend"===r){const t=jt(e.getElementByKey(d.origin.getKey()));if(!t)return false;i.$setAnchorCellForSelection(m),i.$setFocusCellForSelection(t,true);}else {const e=rc(d);Hl(o.anchor,e),Hl(o.focus,e);}else if("extend"===r)i.$setAnchorCellForSelection(m),i.$setFocusCellForSelection(m,true);else {const e=function(e){const t=Ll(e);return Nl(t)?rc(t):e}(Ol(f,c.direction));Hl(o.anchor,e),Hl(o.focus,e);}return gn(t),true}function fn(e,t,o,r,l,s){if(("up"===o||"down"===o)&&function(e){const t=e.getRootElement();if(!t)return false;return t.hasAttribute("aria-controls")&&"typeahead-menu"===t.getAttribute("aria-controls")}(e))return false;const i=Qr();if(!ln(i,r)){if(Fr(i)){if("backward"===o){if(i.focus.offset>0)return false;const e=function(e){for(let t=e,n=e;null!==n;t=n,n=n.getParent())if(Wi(n)){if(n!==t&&n.getFirstChild()!==t)return null;if(!n.isInline())return n}return null}(i.focus.getNode());if(!e)return false;const n=e.getPreviousSibling();return !!Rn(n)&&(gn(t),t.shiftKey?i.focus.set(n.getParentOrThrow().getKey(),n.getIndexWithinParent(),"element"):n.selectEnd(),true)}if(t.shiftKey&&("up"===o||"down"===o)){const e=i.focus.getNode();if(!i.isCollapsed()&&("up"===o&&!i.isBackward()||"down"===o&&i.isBackward())){let l=dl(e,e=>Rn(e));if(We$1(l)&&(l=dl(l,Rn)),l!==r)return false;if(!l)return false;const s="down"===o?l.getNextSibling():l.getPreviousSibling();if(!s)return false;let c=0;"up"===o&&Wi(s)&&(c=s.getChildrenSize());let a=s;if("up"===o&&Wi(s)){const e=s.getLastChild();a=e||s,c=Tr(a)?a.getTextContentSize():0;}const u=i.clone();return u.focus.set(a.getKey(),c,Tr(a)?"text":"element"),es(u),gn(t),true}if(Is(e)){const e="up"===o?i.getNodes()[i.getNodes().length-1]:i.getNodes()[0];if(e){if(null!==Bt(r,e)){const e=r.getFirstDescendant(),t=r.getLastDescendant();if(!e||!t)return false;const[n]=yt(e),[o]=yt(t),s=r.getCordsFromCellNode(n,l.table),i=r.getCordsFromCellNode(o,l.table),c=r.getDOMCellFromCordsOrThrow(s.x,s.y,l.table),a=r.getDOMCellFromCordsOrThrow(i.x,i.y,l.table);return l.$setAnchorCellForSelection(c),l.$setFocusCellForSelection(a,true),true}}return false}{let r=dl(e,e=>Wi(e)&&!e.isInline());if(We$1(r)&&(r=dl(r,Rn)),!r)return false;const s="down"===o?r.getNextSibling():r.getPreviousSibling();if(Rn(s)&&l.tableNodeKey===s.getKey()){const e=s.getFirstDescendant(),n=s.getLastDescendant();if(!e||!n)return false;const[r]=yt(e),[l]=yt(n),c=i.clone();return c.focus.set(("up"===o?r:l).getKey(),"up"===o?0:l.getChildrenSize(),"element"),gn(t),es(c),true}}}}return "down"===o&&yn(e)&&s.setShouldCheckSelectionForTable(r.getKey()),false}if(Fr(i)){if("backward"===o||"forward"===o){return dn(e,t,i,t.shiftKey?"extend":"move","backward"===o,r,l)}if(i.isCollapsed()){const{anchor:c,focus:a}=i,u=dl(c.getNode(),We$1),h=dl(a.getNode(),We$1);if(!We$1(u)||!u.is(h))return false;const d=hn(u);if(d!==r&&null!=d){const n=Lt(d,e.getElementByKey(d.getKey()));if(null!=n)return l.table=Gt(d,n),fn(e,t,o,d,l,s)}const f=e.getElementByKey(u.__key),g=e.getElementByKey(c.key);if(null==g||null==f)return false;let m;if("element"===c.type)m=g.getBoundingClientRect();else {const t=Js(Ht(e));if(null===t||0===t.rangeCount)return false;m=t.getRangeAt(0).getBoundingClientRect();}const p="up"===o?u.getFirstChild():u.getLastChild();if(null==p)return false;const C=e.getElementByKey(p.__key);if(null==C)return false;const _=C.getBoundingClientRect();if("up"===o?_.top>m.top-m.height:m.bottom+m.height>_.bottom){gn(t);const e=r.getCordsFromCellNode(u,l.table);if(!t.shiftKey)return en(l,r,e.x,e.y,o);{const t=r.getDOMCellFromCordsOrThrow(e.x,e.y,l.table);l.$setAnchorCellForSelection(t),l.$setFocusCellForSelection(t,true);}return true}}}else if(Ot(i)){const{anchor:s,focus:c}=i,a=dl(s.getNode(),We$1),u=dl(c.getNode(),We$1),[h]=i.getNodes();Rn(h)||Le$1(251);const d=Lt(h,e.getElementByKey(h.getKey()));if(!We$1(a)||!We$1(u)||!Rn(h)||null==d)return false;l.$updateTableTableSelection(i);const f=Gt(h,d),g=r.getCordsFromCellNode(a,f),m=r.getDOMCellFromCordsOrThrow(g.x,g.y,f);if(l.$setAnchorCellForSelection(m),gn(t),t.shiftKey){const[e,t,n]=wt(r,a,u);return rn(l,e,t,n,o)}return u.selectEnd(),true}return false}function gn(e){e.preventDefault(),e.stopImmediatePropagation(),e.stopPropagation();}function mn(e,t,n){const o=eo();"first"===e?t.insertBefore(o):t.insertAfter(o),o.append(...n||[]),o.selectEnd();}function pn(e,t,o){const r=o.getParent();if(!r)return;const l=Js(Ht(e));if(!l)return;const s=l.anchorNode,i=e.getElementByKey(r.getKey()),c=Lt(o,e.getElementByKey(o.getKey()));if(!s||!i||!c||!i.contains(s)||c.contains(s))return;const a=dl(t.anchor.getNode(),e=>We$1(e));if(!a)return;const u=dl(a,e=>Rn(e));if(!Rn(u)||!u.is(o))return;const[h,d]=wt(o,a,a),f=h[0][0],g=h[h.length-1][h[0].length-1],{startRow:m,startColumn:p}=d,C=m===f.startRow&&p===f.startColumn,_=m===g.startRow&&p===g.startColumn;return C?"first":_?"last":void 0}function Cn(e,t){const{tableNode:n}=e.$lookup(),o=n.getCordsFromCellNode(t,e.table);return n.getDOMCellFromCordsOrThrow(o.x,o.y,e.table)}function _n(e,t,n){return Bt(e,Go(t,n))}function Sn(e,t,n){const o=e.querySelector("colgroup");if(!o)return;const r=[];for(let e=0;e<t;e++){const t=document.createElement("col"),o=n&&n[e];o&&(t.style.width=`${o}px`),r.push(t);}o.replaceChildren(...r);}function wn(t,n,r){if(!n.theme.tableAlignment)return;const l=[],s=[];for(const e of ["center","right"]){const t=n.theme.tableAlignment[e];t&&(e===r?s:l).push(t);}xc(t,...l),mc(t,...s);}const bn=new WeakSet;function yn(e=Zs()){return bn.has(e)}function Nn(e,t){bn.add(e);}class vn extends Bi{__rowStriping;__frozenColumnCount;__frozenRowCount;__colWidths;static getType(){return "table"}getColWidths(){return this.getLatest().__colWidths}setColWidths(e){const t=this.getWritable();return t.__colWidths=e,t}static clone(e){return new vn(e.__key)}afterCloneFrom(e){super.afterCloneFrom(e),this.__colWidths=e.__colWidths,this.__rowStriping=e.__rowStriping,this.__frozenColumnCount=e.__frozenColumnCount,this.__frozenRowCount=e.__frozenRowCount;}static importDOM(){return {table:e=>({conversion:Tn,priority:1})}}static importJSON(e){return Fn().updateFromJSON(e)}updateFromJSON(e){return super.updateFromJSON(e).setRowStriping(e.rowStriping||false).setFrozenColumns(e.frozenColumnCount||0).setFrozenRows(e.frozenRowCount||0).setColWidths(e.colWidths)}constructor(e){super(e),this.__rowStriping=false,this.__frozenColumnCount=0,this.__frozenRowCount=0,this.__colWidths=void 0;}exportJSON(){return {...super.exportJSON(),colWidths:this.getColWidths(),frozenColumnCount:this.__frozenColumnCount?this.__frozenColumnCount:void 0,frozenRowCount:this.__frozenRowCount?this.__frozenRowCount:void 0,rowStriping:this.__rowStriping?this.__rowStriping:void 0}}extractWithChild(e,t,n){return "html"===n}getDOMSlot(e){const t=zt(e)?e:e.querySelector("table");return zt(t)||Le$1(229),super.getDOMSlot(e).withElement(t).withAfter(t.querySelector("colgroup"))}createDOM(t,n){const o=document.createElement("table");this.__style&&nr(o.style,this.__style);const r=document.createElement("colgroup");if(o.appendChild(r),ll(r),mc(o,t.theme.table),this.updateTableElement(null,o,t),yn(n)){const n=document.createElement("div"),r=t.theme.tableScrollableWrapper;return r?mc(n,r):n.style.overflowX="auto",n.appendChild(o),this.updateTableWrapper(null,n,o,t),n}return o}updateTableWrapper(t,n,r,l){this.__frozenColumnCount!==(t?t.__frozenColumnCount:0)&&function(t,n,r,l){l>0?(mc(t,r.theme.tableFrozenColumn),n.setAttribute("data-lexical-frozen-column","true")):(xc(t,r.theme.tableFrozenColumn),n.removeAttribute("data-lexical-frozen-column"));}(n,r,l,this.__frozenColumnCount),this.__frozenRowCount!==(t?t.__frozenRowCount:0)&&function(t,n,r,l){l>0?(mc(t,r.theme.tableFrozenRow),n.setAttribute("data-lexical-frozen-row","true")):(xc(t,r.theme.tableFrozenRow),n.removeAttribute("data-lexical-frozen-row"));}(n,r,l,this.__frozenRowCount);}updateTableElement(t,n,r){this.__style!==(t?t.__style:"")&&nr(n.style,this.__style,t?t.__style:""),this.__rowStriping!==(!!t&&t.__rowStriping)&&function(t,n,r){r?(mc(t,n.theme.tableRowStriping),t.setAttribute("data-lexical-row-striping","true")):(xc(t,n.theme.tableRowStriping),t.removeAttribute("data-lexical-row-striping"));}(n,r,this.__rowStriping);const l=t?t.getColumnCount():0,s=t?t.__colWidths:void 0;this.getColumnCount()===l&&this.getColWidths()===s||Sn(n,this.getColumnCount(),this.getColWidths()),wn(n,r,this.getFormatType());}updateDOM(e,t,n){const o=Lt(this,t);return t===o===yn()||(Ys(r=t)&&"DIV"===r.nodeName&&this.updateTableWrapper(e,t,o,n),this.updateTableElement(e,o,n),false);var r;}scaleDOMColWidths(e,t){const n=this.getColWidths();if(!n)return;Sn(Lt(this,e),this.getColumnCount(),n.map(e=>e*t));}exportDOM(e){const t=super.exportDOM(e),{element:n}=t;return {after:n=>{if(t.after&&(n=t.after(n)),!zt(n)&&Ys(n)&&(n=n.querySelector("table")),!zt(n))return null;wn(n,e._config,this.getFormatType());const[o]=bt(this,null,null),r=new Map;for(const e of o)for(const t of e){const e=t.cell.getKey();r.has(e)||r.set(e,{colSpan:t.cell.getColSpan(),startColumn:t.startColumn});}const s=new Set;for(const e of n.querySelectorAll(":scope > tr > [data-temporary-table-cell-lexical-key]")){const t=e.getAttribute("data-temporary-table-cell-lexical-key");if(t){const n=r.get(t);if(e.removeAttribute("data-temporary-table-cell-lexical-key"),n){r.delete(t);for(let e=0;e<n.colSpan;e++)s.add(e+n.startColumn);}}}const i=n.querySelector(":scope > colgroup");if(i){const e=Array.from(n.querySelectorAll(":scope > colgroup > col")).filter((e,t)=>s.has(t));i.replaceChildren(...e);}const c=n.querySelectorAll(":scope > tr");if(c.length>0){const e=document.createElement("tbody");for(const t of c)e.appendChild(t);n.append(e);}return n},element:!zt(n)&&Ys(n)?n.querySelector("table"):n}}canBeEmpty(){return false}isShadowRoot(){return true}getCordsFromCellNode(e,t){const{rows:n,domRows:o}=t;for(let t=0;t<n;t++){const n=o[t];if(null!=n)for(let o=0;o<n.length;o++){const r=n[o];if(null==r)continue;const{elem:l}=r,s=_n(this,l);if(null!==s&&e.is(s))return {x:o,y:t}}}throw new Error("Cell not found in table.")}getDOMCellFromCords(e,t,n){const{domRows:o}=n,r=o[t];if(null==r)return null;const l=r[e<r.length?e:r.length-1];return null==l?null:l}getDOMCellFromCordsOrThrow(e,t,n){const o=this.getDOMCellFromCords(e,t,n);if(!o)throw new Error("Cell not found at cords.");return o}getCellNodeFromCords(e,t,n){const o=this.getDOMCellFromCords(e,t,n);if(null==o)return null;const r=Go(o.elem);return We$1(r)?r:null}getCellNodeFromCordsOrThrow(e,t,n){const o=this.getCellNodeFromCords(e,t,n);if(!o)throw new Error("Node at cords not TableCellNode.");return o}getRowStriping(){return Boolean(this.getLatest().__rowStriping)}setRowStriping(e){const t=this.getWritable();return t.__rowStriping=e,t}setFrozenColumns(e){const t=this.getWritable();return t.__frozenColumnCount=e,t}getFrozenColumns(){return this.getLatest().__frozenColumnCount}setFrozenRows(e){const t=this.getWritable();return t.__frozenRowCount=e,t}getFrozenRows(){return this.getLatest().__frozenRowCount}canSelectBefore(){return true}canIndent(){return false}getColumnCount(){const e=this.getFirstChild();if(!e)return 0;let t=0;return e.getChildren().forEach(e=>{We$1(e)&&(t+=e.getColSpan());}),t}}function xn(e,t){const n=e.getElementByKey(t.getKey());return null===n&&Le$1(230),Gt(t,n)}function Tn(e){const n=Fn();e.hasAttribute("data-lexical-row-striping")&&n.setRowStriping(true),e.hasAttribute("data-lexical-frozen-column")&&n.setFrozenColumns(1),e.hasAttribute("data-lexical-frozen-row")&&n.setFrozenRows(1);const o=e.querySelector(":scope > colgroup");if(o){let e=[];for(const t of o.querySelectorAll(":scope > col")){let n=t.style.width||"";if(!Ke$1.test(n)&&(n=t.getAttribute("width")||"",!/^\d+$/.test(n))){e=void 0;break}e.push(parseFloat(n));}e&&n.setColWidths(e);}return {after:e=>Ht$3(e,De$1),node:n}}function Fn(){return zs(new vn)}function Rn(e){return e instanceof vn}function On(e){De$1(e.getParent())?e.isEmpty()&&e.append(eo()):e.remove();}function Kn(e){Rn(e.getParent())?Ot$3(e,We$1):e.remove();}function An(e){Ot$3(e,De$1);const[t]=bt(e,null,null),n=t.reduce((e,t)=>Math.max(e,t.length),0),o=e.getChildren();for(let e=0;e<t.length;++e){const r=o[e];if(!r)continue;De$1(r)||Le$1(254,r.constructor.name,r.getType());const l=t[e].reduce((e,t)=>t?1+e:e,0);if(l!==n)for(let e=l;e<n;++e){const e=$e$1();e.append(eo()),r.append(e);}}const r=e.getColWidths(),l=e.getColumnCount();if(r&&r.length!==l){let t;if(l<r.length)t=r.slice(0,l);else if(r.length>0){const e=r[r.length-1];t=[...r,...Array(l-r.length).fill(e)];}e.setColWidths(t);}}function En(e){if(e.detail<3||!qs(e.target))return false;const t=Go(e.target);if(null===t)return false;const o=dl(t,e=>Wi(e)&&!e.isInline());if(null===o)return false;return !!We$1(o.getParent())&&(o.select(0),true)}function kn(){const e=Qr();if(!Fr(e))return false;const t=hn(e.anchor.getNode());if(null===t)return false;const n=Zo();if(!n.is(t.getParent())||1!==n.getChildrenSize())return false;const[o]=bt(t,null,null);if(0===o.length||0===o[0].length)return false;const r=o[0][0];if(!r||!r.cell)return false;const l=o[o.length-1],s=l[l.length-1];if(!s||!s.cell)return false;const i=At(t,r.cell,s.cell);return es(i),true}function $n(e,t=true){const n=new Mt,o=(o,r,l)=>{const s=Lt(o,l),i=Jt(o,s,e,t,n);n.observers.set(r,[i,s]);};return Cc(Ut(e,n),e.registerCommand(ie$4,()=>Xt(n,e),so),e.registerMutationListener(vn,t=>{e.getEditorState().read(()=>{for(const[e,r]of t){const t=n.observers.get(e);if("created"===r||"updated"===r){const{tableNode:r,tableElement:l}=kt(e);void 0===t?o(r,e,l):l!==t[1]&&(t[0].removeListeners(),n.observers.delete(e),o(r,e,l));}else "destroyed"===r&&void 0!==t&&(t[0].removeListeners(),n.observers.delete(e));}},{editor:e});},{skipInitialization:false}),()=>{for(const[,[e]]of n.observers)e.removeListeners();})}function Wn(e,t){e.hasNodes([vn])||Le$1(255);const{hasNestedTables:o=ft$1(false)}={};return Cc(e.registerCommand(ze$1,e=>function({rows:e,columns:t,includeHeaders:n},o){const r=Qr()||Zr();if(!r||!Fr(r))return false;if(!o&&hn(r.anchor.getNode()))return false;const l=Xe$1(Number(e),Number(t),n);Pt$3(l);const s=l.getFirstDescendant();return Tr(s)&&s.select(),true}(e,o.peek()),ro),e.registerCommand(oe$6,(t,r)=>e===r&&function(e,t){const{nodes:o,selection:r}=e;if(!o.some(e=>Rn(e)||pt$2(e).some(e=>Rn(e.node))))return false;const l=Ot(r),s=Fr(r);if(!(s&&null!==dl(r.anchor.getNode(),e=>We$1(e))&&null!==dl(r.focus.getNode(),e=>We$1(e))||l))return false;if(1===o.length&&Rn(o[0]))return function(e,t){const o=t.getStartEndPoints(),r=Ot(t);if(null===o)return false;const[l,s]=o,[i,c,a]=yt(l),u=dl(s.getNode(),e=>We$1(e));if(!(We$1(i)&&We$1(u)&&De$1(c)&&Rn(a)))return false;const[h,d,f]=wt(a,i,u),[m]=bt(e,null,null),C=h.length,_=C>0?h[0].length:0;let S=d.startRow,w=d.startColumn,b=m.length,y=b>0?m[0].length:0;if(r){const e=Nt(h,d,f),t=e.maxRow-e.minRow+1,n=e.maxColumn-e.minColumn+1;S=e.minRow,w=e.minColumn,b=Math.min(b,t),y=Math.min(y,n);}let N=false;const v=Math.min(C,S+b)-1,x=Math.min(_,w+y)-1,T=new Set;for(let e=S;e<=v;e++)for(let t=w;t<=x;t++){const n=h[e][t];T.has(n.cell.getKey())||(1===n.cell.__rowSpan&&1===n.cell.__colSpan||(St(n.cell),T.add(n.cell.getKey()),N=true));}let[F]=bt(a.getWritable(),null,null);const R=b-C+S;for(let e=0;e<R;e++){rt(F[C-1][0].cell);}const O=y-_+w;for(let e=0;e<O;e++){ct(F[0][_-1].cell,true,false);}[F]=bt(a.getWritable(),null,null);for(let e=S;e<S+b;e++)for(let t=w;t<w+y;t++){const n=e-S,o=t-w,r=m[n][o];if(r.startRow!==n||r.startColumn!==o)continue;const l=r.cell;if(1!==l.__rowSpan||1!==l.__colSpan){const n=[],o=Math.min(e+l.__rowSpan,S+b)-1,r=Math.min(t+l.__colSpan,w+y)-1;for(let l=e;l<=o;l++)for(let e=t;e<=r;e++){const t=F[l][e];n.push(t.cell);}pt(n),N=true;}const{cell:s}=F[e][t],i=l.getBackgroundColor();null!=i&&s.setBackgroundColor(i);const c=s.getChildren();l.getChildren().forEach(e=>{if(Tr(e)){eo().append(e),s.append(e);}else s.append(e);}),c.forEach(e=>e.remove());}if(r&&N){const[e]=bt(a.getWritable(),null,null);e[d.startRow][d.startColumn].cell.selectEnd();}return true}(o[0],r);if(s&&t.peek()&&!function(e){if(Ot(e)&&!e.focus.getNode().is(e.anchor.getNode()))return true;if(Fr(e)&&We$1(e.anchor.getNode())&&!e.anchor.getNode().is(e.focus.getNode()))return true;return false}(r))return false;return true}(t,o),ro),e.registerCommand(Ue$2,kn,io),e.registerCommand(se$5,En,ro),e.registerNodeTransform(vn,An),e.registerNodeTransform(He$1,Kn),e.registerNodeTransform(Ee$1,On))}
11154
11204
 
11205
+ // Partition a stretch of text into consecutive { start, end, range } segments,
11206
+ // where offsets are relative to the text and range is the covering source
11207
+ // range — expressed in outer coordinates as { start, end, ... } — or null for
11208
+ // the stretches no range covers. Ranges must be sorted and non-overlapping.
11209
+ function segmentTextByRanges(text, textStart, ranges) {
11210
+ const segments = [];
11211
+ let cursor = 0;
11212
+
11213
+ for (const range of ranges) {
11214
+ const from = Math.max(range.start - textStart, cursor);
11215
+ const to = Math.min(range.end - textStart, text.length);
11216
+
11217
+ if (from < to) {
11218
+ if (from > cursor) {
11219
+ segments.push({ start: cursor, end: from, range: null });
11220
+ }
11221
+ segments.push({ start: from, end: to, range });
11222
+ cursor = to;
11223
+ }
11224
+ }
11225
+
11226
+ if (cursor < text.length) {
11227
+ segments.push({ start: cursor, end: text.length, range: null });
11228
+ }
11229
+
11230
+ return segments
11231
+ }
11232
+
11155
11233
  // Shared, strictly-contained element used to attach ephemeral nodes when we
11156
11234
  // need to read computed styles (e.g. canonicalizing style values, resolving
11157
11235
  // CSS custom properties). The container is created once and attached to
@@ -11455,26 +11533,9 @@ function extractHighlightStyleFromElement(element) {
11455
11533
  return css.length > 0 ? css : null
11456
11534
  }
11457
11535
 
11458
- // The code retokenizer replaces a code block's children with freshly created
11459
- // tokens that carry no styles, which would drop color highlights on every
11460
- // edit. This tokenizer wraps the stock Prism tokenizer to restore them: it
11461
- // recovers the block's highlight ranges — staged during HTML import, or read
11462
- // from the children the fresh tokens are about to replace — and reapplies
11463
- // them to the fresh tokens before the retokenizer splices them in.
11464
- function buildHighlightPreservingTokenizer(editor) {
11465
- return {
11466
- defaultLanguage: r.defaultLanguage,
11467
- tokenize(code, language) {
11468
- return r.tokenize(code, language)
11469
- },
11470
- $tokenize(codeNode, language) {
11471
- const tokens = r.$tokenize(codeNode, language);
11472
- const highlights = $takeHighlightRanges(editor, codeNode);
11473
- return $applyHighlightRangesToTokens(tokens, highlights)
11474
- }
11475
- }
11476
- }
11477
-
11536
+ // Recover the highlight ranges to reapply after a retokenization: the ranges
11537
+ // staged during HTML import, or the ones read from the children the fresh
11538
+ // tokens are about to replace.
11478
11539
  function $takeHighlightRanges(editor, codeNode) {
11479
11540
  const pending = $getPendingHighlights(editor);
11480
11541
  const key = codeNode.getKey();
@@ -11516,52 +11577,25 @@ function $applyHighlightRangesToTokens(tokens, highlights) {
11516
11577
  // attached to the tree yet, so we create CodeHighlightNode replacements.
11517
11578
  function $splitTokenAtHighlightBoundaries(token, tokenStart, highlights) {
11518
11579
  const text = token.getTextContent();
11519
- const segments = segmentTextByHighlights(text, tokenStart, highlights);
11580
+ const segments = segmentTextByRanges(text, tokenStart, highlights);
11520
11581
 
11521
11582
  if (segments.length === 1) {
11522
11583
  const [ segment ] = segments;
11523
- if (segment.style) {
11524
- $applyHighlightStyleToToken(token, segment.style);
11584
+ if (segment.range) {
11585
+ $applyHighlightStyleToToken(token, segment.range.style);
11525
11586
  }
11526
11587
  return [ token ]
11527
11588
  } else {
11528
11589
  return segments.map((segment) => {
11529
11590
  const segmentToken = V$2(text.slice(segment.start, segment.end), token.getHighlightType());
11530
- if (segment.style) {
11531
- $applyHighlightStyleToToken(segmentToken, segment.style);
11591
+ if (segment.range) {
11592
+ $applyHighlightStyleToToken(segmentToken, segment.range.style);
11532
11593
  }
11533
11594
  return segmentToken
11534
11595
  })
11535
11596
  }
11536
11597
  }
11537
11598
 
11538
- // Partition a token's text into consecutive { start, end, style } segments,
11539
- // where offsets are relative to the token and style is null for the stretches
11540
- // no highlight covers.
11541
- function segmentTextByHighlights(text, tokenStart, highlights) {
11542
- const segments = [];
11543
- let cursor = 0;
11544
-
11545
- for (const { start, end, style } of highlights) {
11546
- const from = Math.max(start - tokenStart, cursor);
11547
- const to = Math.min(end - tokenStart, text.length);
11548
-
11549
- if (from < to) {
11550
- if (from > cursor) {
11551
- segments.push({ start: cursor, end: from, style: null });
11552
- }
11553
- segments.push({ start: from, end: to, style });
11554
- cursor = to;
11555
- }
11556
- }
11557
-
11558
- if (cursor < text.length) {
11559
- segments.push({ start: cursor, end: text.length, style: null });
11560
- }
11561
-
11562
- return segments
11563
- }
11564
-
11565
11599
  function $applyHighlightStyleToToken(token, style) {
11566
11600
  token.setStyle(style);
11567
11601
  $setCodeHighlightFormat(token, true);
@@ -11571,17 +11605,24 @@ function $buildChildRanges(codeNode) {
11571
11605
  const childRanges = [];
11572
11606
  let charOffset = 0;
11573
11607
 
11574
- for (const child of codeNode.getChildren()) {
11575
- if (X$1(child) || Tr(child)) {
11576
- const text = child.getTextContent();
11577
- childRanges.push({ node: child, start: charOffset, end: charOffset + text.length });
11578
- charOffset += text.length;
11579
- } else {
11580
- // LineBreakNode, TabNode - count as 1 character each (\n, \t)
11581
- charOffset += 1;
11608
+ function walk(node) {
11609
+ for (const child of node.getChildren()) {
11610
+ if (Wi(child)) {
11611
+ // e.g. a LinkNode awaiting its first retokenization
11612
+ walk(child);
11613
+ } else if (X$1(child) || Tr(child)) {
11614
+ const text = child.getTextContent();
11615
+ childRanges.push({ node: child, start: charOffset, end: charOffset + text.length });
11616
+ charOffset += text.length;
11617
+ } else {
11618
+ // LineBreakNode - counts as 1 character (\n)
11619
+ charOffset += 1;
11620
+ }
11582
11621
  }
11583
11622
  }
11584
11623
 
11624
+ walk(codeNode);
11625
+
11585
11626
  return childRanges
11586
11627
  }
11587
11628
 
@@ -12701,10 +12742,17 @@ class Selection {
12701
12742
  || this.#selectInLexical(this.topLevelNodeAfterCursor)
12702
12743
  }
12703
12744
 
12745
+ // hasNodeSelection reads the committed state, while $getSelection() resolves
12746
+ // against the pending one — so the selection here can be missing, no longer a
12747
+ // NodeSelection, or reference a node that no longer exists (empty editor,
12748
+ // just-deleted node, decorator boundary). Only invoke the callback when a
12749
+ // node actually resolves; returning false lets the callers fall back —
12750
+ // #selectInLexical for plain arrows, native pass-through for shift-arrows.
12704
12751
  #withCurrentNodeSelectionNode(fn) {
12705
- if (this.hasNodeSelection) {
12706
- return fn(Qr().getNodes()[0])
12707
- }
12752
+ const selection = this.hasNodeSelection ? Qr() : null;
12753
+ const currentNode = Ir(selection) ? selection.getNodes()[0] : undefined;
12754
+
12755
+ return currentNode ? fn(currentNode) : false
12708
12756
  }
12709
12757
 
12710
12758
  #rangeSelectDecorator(node, direction = "forward") {
@@ -13891,15 +13939,18 @@ class ListItemNodeInserter extends BaseNodeInserter {
13891
13939
  // very corruption we are avoiding. The block must land at the list's level.
13892
13940
  const anchorNode = this.selection.anchor.getNode();
13893
13941
  const outerList = this.#outermostList(anchorNode);
13894
- const topItem = this.#topLevelItemFor(anchorNode, outerList);
13895
13942
 
13896
- // A blank top-level bullet is just the insertion point (e.g. the user pressed
13897
- // Enter to leave the list); break out of it entirely. A bullet with content —
13898
- // including one wrapping a nested list — splits so its content stays in the list.
13899
- const splitAfterItem = $isBlankNode(topItem) ? topItem.getPreviousSibling() : topItem;
13900
- const splitIndex = splitAfterItem ? splitAfterItem.getIndexWithinParent() + 1 : 0;
13901
- const [ listBefore, listAfter ] = Us(outerList, splitIndex);
13902
- if ($isBlankNode(topItem)) { topItem.remove(); }
13943
+ // removeText() can relocate the anchor before we read it back — clean out
13944
+ // of the list when the removed range spanned it. With no list left to
13945
+ // split, default insertion applies.
13946
+ if (!outerList) {
13947
+ this.selection.insertNodes(nodes);
13948
+ return
13949
+ }
13950
+
13951
+ const topItem = this.#topLevelItemFor(anchorNode, outerList);
13952
+ const [ listBefore, listAfter ] = Us(outerList, this.#splitIndexFor(topItem));
13953
+ if (topItem && $isBlankNode(topItem)) { topItem.remove(); }
13903
13954
 
13904
13955
  let anchor = listBefore ?? listAfter;
13905
13956
  for (const node of nodes) {
@@ -13912,6 +13963,18 @@ class ListItemNodeInserter extends BaseNodeInserter {
13912
13963
  nodes.at(-1).selectNext();
13913
13964
  }
13914
13965
 
13966
+ // A blank top-level bullet is just the insertion point (e.g. the user pressed
13967
+ // Enter to leave the list); break out of it entirely. A bullet with content —
13968
+ // including one wrapping a nested list — splits so its content stays in the
13969
+ // list. With no top-level bullet at all — removeText() relocated the anchor
13970
+ // onto the list node itself — the anchor offset is the boundary between items.
13971
+ #splitIndexFor(topItem) {
13972
+ if (!topItem) return this.selection.anchor.offset
13973
+
13974
+ const splitAfterItem = $isBlankNode(topItem) ? topItem.getPreviousSibling() : topItem;
13975
+ return splitAfterItem ? splitAfterItem.getIndexWithinParent() + 1 : 0
13976
+ }
13977
+
13915
13978
  #outermostList(node) {
13916
13979
  return [ node, ...node.getParents() ].reverse().find(Se$1)
13917
13980
  }
@@ -15083,11 +15146,93 @@ ${e}</tr>
15083
15146
  `+this.renderer.text(o);t?n+=this.renderer.paragraph({type:"paragraph",raw:a,text:a,tokens:[{type:"text",raw:a,text:a,escaped:true}]}):n+=a;continue}default:{let o='Token with "'+s.type+'" type was not found.';if(this.options.silent)return console.error(o),"";throw new Error(o)}}}return n}parseInline(e,t=this.renderer){let n="";for(let r=0;r<e.length;r++){let i=e[r];if(this.options.extensions?.renderers?.[i.type]){let o=this.options.extensions.renderers[i.type].call({parser:this},i);if(o!==false||!["escape","html","link","image","strong","em","codespan","br","del","text"].includes(i.type)){n+=o||"";continue}}let s=i;switch(s.type){case "escape":{n+=t.text(s);break}case "html":{n+=t.html(s);break}case "link":{n+=t.link(s);break}case "image":{n+=t.image(s);break}case "strong":{n+=t.strong(s);break}case "em":{n+=t.em(s);break}case "codespan":{n+=t.codespan(s);break}case "br":{n+=t.br(s);break}case "del":{n+=t.del(s);break}case "text":{n+=t.text(s);break}default:{let o='Token with "'+s.type+'" type was not found.';if(this.options.silent)return console.error(o),"";throw new Error(o)}}}return n}};var S=class{options;block;constructor(e){this.options=e||T;}static passThroughHooks=new Set(["preprocess","postprocess","processAllTokens","emStrongMask"]);static passThroughHooksRespectAsync=new Set(["preprocess","postprocess","processAllTokens"]);preprocess(e){return e}postprocess(e){return e}processAllTokens(e){return e}emStrongMask(e){return e}provideLexer(){return this.block?x.lex:x.lexInline}provideParser(){return this.block?b.parse:b.parseInline}};var B=class{defaults=L();options=this.setOptions;parse=this.parseMarkdown(true);parseInline=this.parseMarkdown(false);Parser=b;Renderer=P;TextRenderer=$;Lexer=x;Tokenizer=y;Hooks=S;constructor(...e){this.use(...e);}walkTokens(e,t){let n=[];for(let r of e)switch(n=n.concat(t.call(this,r)),r.type){case "table":{let i=r;for(let s of i.header)n=n.concat(this.walkTokens(s.tokens,t));for(let s of i.rows)for(let o of s)n=n.concat(this.walkTokens(o.tokens,t));break}case "list":{let i=r;n=n.concat(this.walkTokens(i.items,t));break}default:{let i=r;this.defaults.extensions?.childTokens?.[i.type]?this.defaults.extensions.childTokens[i.type].forEach(s=>{let o=i[s].flat(1/0);n=n.concat(this.walkTokens(o,t));}):i.tokens&&(n=n.concat(this.walkTokens(i.tokens,t)));}}return n}use(...e){let t=this.defaults.extensions||{renderers:{},childTokens:{}};return e.forEach(n=>{let r={...n};if(r.async=this.defaults.async||r.async||false,n.extensions&&(n.extensions.forEach(i=>{if(!i.name)throw new Error("extension name required");if("renderer"in i){let s=t.renderers[i.name];s?t.renderers[i.name]=function(...o){let a=i.renderer.apply(this,o);return a===false&&(a=s.apply(this,o)),a}:t.renderers[i.name]=i.renderer;}if("tokenizer"in i){if(!i.level||i.level!=="block"&&i.level!=="inline")throw new Error("extension level must be 'block' or 'inline'");let s=t[i.level];s?s.unshift(i.tokenizer):t[i.level]=[i.tokenizer],i.start&&(i.level==="block"?t.startBlock?t.startBlock.push(i.start):t.startBlock=[i.start]:i.level==="inline"&&(t.startInline?t.startInline.push(i.start):t.startInline=[i.start]));}"childTokens"in i&&i.childTokens&&(t.childTokens[i.name]=i.childTokens);}),r.extensions=t),n.renderer){let i=this.defaults.renderer||new P(this.defaults);for(let s in n.renderer){if(!(s in i))throw new Error(`renderer '${s}' does not exist`);if(["options","parser"].includes(s))continue;let o=s,a=n.renderer[o],l=i[o];i[o]=(...c)=>{let p=a.apply(i,c);return p===false&&(p=l.apply(i,c)),p||""};}r.renderer=i;}if(n.tokenizer){let i=this.defaults.tokenizer||new y(this.defaults);for(let s in n.tokenizer){if(!(s in i))throw new Error(`tokenizer '${s}' does not exist`);if(["options","rules","lexer"].includes(s))continue;let o=s,a=n.tokenizer[o],l=i[o];i[o]=(...c)=>{let p=a.apply(i,c);return p===false&&(p=l.apply(i,c)),p};}r.tokenizer=i;}if(n.hooks){let i=this.defaults.hooks||new S;for(let s in n.hooks){if(!(s in i))throw new Error(`hook '${s}' does not exist`);if(["options","block"].includes(s))continue;let o=s,a=n.hooks[o],l=i[o];S.passThroughHooks.has(s)?i[o]=c=>{if(this.defaults.async&&S.passThroughHooksRespectAsync.has(s))return (async()=>{let g=await a.call(i,c);return l.call(i,g)})();let p=a.call(i,c);return l.call(i,p)}:i[o]=(...c)=>{if(this.defaults.async)return (async()=>{let g=await a.apply(i,c);return g===false&&(g=await l.apply(i,c)),g})();let p=a.apply(i,c);return p===false&&(p=l.apply(i,c)),p};}r.hooks=i;}if(n.walkTokens){let i=this.defaults.walkTokens,s=n.walkTokens;r.walkTokens=function(o){let a=[];return a.push(s.call(this,o)),i&&(a=a.concat(i.call(this,o))),a};}this.defaults={...this.defaults,...r};}),this}setOptions(e){return this.defaults={...this.defaults,...e},this}lexer(e,t){return x.lex(e,t??this.defaults)}parser(e,t){return b.parse(e,t??this.defaults)}parseMarkdown(e){return (n,r)=>{let i={...r},s={...this.defaults,...i},o=this.onError(!!s.silent,!!s.async);if(this.defaults.async===true&&i.async===false)return o(new Error("marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise."));if(typeof n>"u"||n===null)return o(new Error("marked(): input parameter is undefined or null"));if(typeof n!="string")return o(new Error("marked(): input parameter is of type "+Object.prototype.toString.call(n)+", string expected"));if(s.hooks&&(s.hooks.options=s,s.hooks.block=e),s.async)return (async()=>{let a=s.hooks?await s.hooks.preprocess(n):n,c=await(s.hooks?await s.hooks.provideLexer():e?x.lex:x.lexInline)(a,s),p=s.hooks?await s.hooks.processAllTokens(c):c;s.walkTokens&&await Promise.all(this.walkTokens(p,s.walkTokens));let d=await(s.hooks?await s.hooks.provideParser():e?b.parse:b.parseInline)(p,s);return s.hooks?await s.hooks.postprocess(d):d})().catch(o);try{s.hooks&&(n=s.hooks.preprocess(n));let l=(s.hooks?s.hooks.provideLexer():e?x.lex:x.lexInline)(n,s);s.hooks&&(l=s.hooks.processAllTokens(l)),s.walkTokens&&this.walkTokens(l,s.walkTokens);let p=(s.hooks?s.hooks.provideParser():e?b.parse:b.parseInline)(l,s);return s.hooks&&(p=s.hooks.postprocess(p)),p}catch(a){return o(a)}}}onError(e,t){return n=>{if(n.message+=`
15084
15147
  Please report this to https://github.com/markedjs/marked.`,e){let r="<p>An error occurred:</p><pre>"+w(n.message+"",true)+"</pre>";return t?Promise.resolve(r):r}if(t)return Promise.reject(n);throw n}}};var _=new B;function k(u,e){return _.parse(u,e)}k.options=k.setOptions=function(u){return _.setOptions(u),k.defaults=_.defaults,G(k.defaults),k};k.getDefaults=L;k.defaults=T;k.use=function(...u){return _.use(...u),k.defaults=_.defaults,G(k.defaults),k};k.walkTokens=function(u,e){return _.walkTokens(u,e)};k.parseInline=_.parseInline;k.Parser=b;k.parser=b.parse;k.Renderer=P;k.TextRenderer=$;k.Lexer=x;k.lexer=x.lex;k.Tokenizer=y;k.Hooks=S;k.parse=k;k.options;k.setOptions;k.use;k.walkTokens;k.parseInline;b.parse;x.lex;
15085
15148
 
15149
+ function parsePastedMarkdown(text) {
15150
+ return pasteMarked.parse(text)
15151
+ }
15152
+
15153
+ // A marked instance scoped to the paste flow. A fresh Marked starts from
15154
+ // marked's stock defaults — gfm stays on and tables still parse — and is
15155
+ // isolated from the global `marked` singleton, so a host bundle sharing the
15156
+ // deduped module can't leak `marked.use(...)` customizations into pasting.
15157
+ // The additions are breaks: true, matching the render pass Clipboard always
15158
+ // used, the `html` renderer, and the dropped `code` tokenizer.
15159
+ //
15086
15160
  // Markdown reads any line indented by a tab or four spaces as a code block. Pasted
15087
15161
  // plain text is full of incidental indentation — outlines, notes, logs — and nobody
15088
15162
  // indents a note meaning "this is code"; they fence it. Keep fences, drop the
15089
15163
  // indentation rule.
15090
- const pastedMarkdown = new B({ breaks: true }).use({ tokenizer: { code: () => undefined } });
15164
+ //
15165
+ // Following CommonMark, marked tokenizes a bare "<tag>" in prose as raw inline
15166
+ // (or block) HTML. That is intentional for recognized tags — pasted plain text
15167
+ // carrying <span style>, <mark>, <b>… is styled on import — but for an
15168
+ // *unrecognized* element the Lexical importer has no converter and silently
15169
+ // unwraps it, dropping the tag. WEBVTT speaker cues such as
15170
+ // "<v Nabila Abdel Nabi>", where the name lives in what the HTML parser reads
15171
+ // as attributes, thus vanish entirely.
15172
+ //
15173
+ // Classifying at marked's html renderer rides its public token grammar instead
15174
+ // of shadowing it: marked routes code (`code`/`codespan`), autolinks and
15175
+ // [text](<dest>) links to *other* token types that never reach this renderer,
15176
+ // so their literal "<...>" content is preserved for free — no pre-escaping,
15177
+ // code-region collection, or lexer-option syncing required. This renderer fires
15178
+ // only for genuine raw-HTML tokens, and marked inserts its return value verbatim
15179
+ // (it does not re-encode), so we escape unsupported tags to literal text here.
15180
+ const pasteMarked = new B({
15181
+ breaks: true,
15182
+ renderer: { html: renderPastedHtmlToken }
15183
+ }).use({ tokenizer: { code: () => undefined } });
15184
+
15185
+ // Matches a single HTML tag lexeme: an optional "/", a tag name, then attribute
15186
+ // characters up to the closing ">". Quoted attribute values may contain ">" —
15187
+ // the HTML tokenizer consumes them as part of the value, and marked's tag
15188
+ // grammar matches them into the same raw token — so the attribute run matches
15189
+ // quoted strings whole. Otherwise a lexeme like <v title="a > b"> would end at
15190
+ // the inner ">", escaping only the prefix and leaving the tail for DOMParser
15191
+ // to decode.
15192
+ const HTML_TAG_LEXEME = /<(\/?)([a-zA-Z][a-zA-Z0-9-]*)((?:"[^"]*"|'[^']*'|[^'">])*)>/g;
15193
+
15194
+ // Escape unknown tags *within* the raw-HTML token, keeping known tags intact.
15195
+ // Lexeme-level (not whole-token) escaping matters because marked can emit a
15196
+ // single coarse block-HTML token whose first tag is known but which nests an
15197
+ // unknown one — e.g. "<div><v Name> Hello</div>" arrives as one token. We keep
15198
+ // the <div> so it still renders, and escape the nested <v Name> so it survives
15199
+ // as literal text rather than being unwrapped and dropped by the importer.
15200
+ function renderPastedHtmlToken(token) {
15201
+ return token.text.replace(HTML_TAG_LEXEME, (lexeme, _slash, name) => {
15202
+ return isSupportedHtmlElement(name) ? lexeme : escapeHtml(lexeme)
15203
+ })
15204
+ }
15205
+
15206
+ // The renderer's output is final, so escape the full lexeme — "&", "<" and ">" —
15207
+ // for an exact round-trip (e.g. "<v A&nbsp;B>" → "&lt;v A&amp;nbsp;B&gt;").
15208
+ function escapeHtml(text) {
15209
+ return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;")
15210
+ }
15211
+
15212
+ // "Supported" — safe to pass through for the importer to handle — is decided from
15213
+ // the element taxonomy, not the importer's converter registry. The importer both
15214
+ // converts tags it has a converter for (span→mark, b→bold, tr/td→table cells) and
15215
+ // transparently traverses standard structural wrappers it has *no* converter for
15216
+ // (thead, tbody, tfoot, colgroup, caption), keeping their children. A converter
15217
+ // registry (editor._htmlConversions) lists only the former, so classifying by it
15218
+ // escaped those wrappers to literal text and corrupted pasted tables — foster
15219
+ // parenting hoisted "&lt;thead&gt;…" out as a stray paragraph. The taxonomy covers
15220
+ // both: a standard HTML element is either converted or losslessly unwrapped.
15221
+ //
15222
+ // Two exclusions escape the tag to literal text instead:
15223
+ // - Invented tags (WEBVTT's "<v Nabila Abdel Nabi>", "<foo>"): document
15224
+ // .createElement returns HTMLUnknownElement. The importer would unwrap them,
15225
+ // dropping the tag — and for <v Name> the name lives in what parses as
15226
+ // attributes, so it vanishes entirely.
15227
+ // - Custom elements (turbo-frame, bc-attachment, action-text-attachment): a
15228
+ // hyphenated name is a custom element (HTML spec; no standard element has a
15229
+ // hyphen). They're excluded even when the importer registers a converter, so
15230
+ // a plain-text paste can never materialize an attachment/widget. Legitimate
15231
+ // attachments arrive through the rich-HTML paste path, not here.
15232
+ function isSupportedHtmlElement(name) {
15233
+ const tag = name.toLowerCase();
15234
+ return !(document.createElement(tag) instanceof HTMLUnknownElement) && !tag.includes("-")
15235
+ }
15091
15236
 
15092
15237
  class Clipboard {
15093
15238
  #listeners = new ListenerBin()
@@ -15275,7 +15420,7 @@ class Clipboard {
15275
15420
  }
15276
15421
 
15277
15422
  #pasteMarkdown(text) {
15278
- const html = pastedMarkdown.parse(text);
15423
+ const html = parsePastedMarkdown(text);
15279
15424
  const doc = parseHtml(html);
15280
15425
 
15281
15426
  if (this.#isPlainTextWithoutMarkdown(doc)) {
@@ -15474,6 +15619,134 @@ class BrowserAdapter {
15474
15619
  }
15475
15620
  }
15476
15621
 
15622
+ // The code retokenizer only knows CodeHighlightNode, LineBreakNode and
15623
+ // TabNode, so a LinkNode inside a code block — Trix-authored documents allow
15624
+ // links in code — is destroyed on the first retokenization. Links survive as
15625
+ // state on the tokens instead: this state records the link attributes on each
15626
+ // CodeHighlightNode the link covers, the extraction below reads it (or a
15627
+ // still-untokenized LinkNode) back into ranges before every retokenization,
15628
+ // and the tokenizer reapplies it to the fresh tokens.
15629
+ const codeLinkState = ot$3("codeLink", {
15630
+ parse: (value) => (value && typeof value.url === "string" ? value : null)
15631
+ });
15632
+
15633
+ function $getCodeLink(node) {
15634
+ return st$2(node, codeLinkState)
15635
+ }
15636
+
15637
+ function $setCodeLink(node, link) {
15638
+ ct$2(node, codeLinkState, link);
15639
+ }
15640
+
15641
+ // Build the list of { start, end, link } ranges covering every link in a code
15642
+ // block, with offsets into the block's text content. Links appear either as
15643
+ // LinkNode descendants (imported or just created, before their first
15644
+ // retokenization) or as link state on tokens (after it). The walk recurses
15645
+ // through nested elements because `<pre><code>` imports of multi-line content
15646
+ // briefly produce a CodeNode nested inside another before the outer one's
15647
+ // retokenization flattens them.
15648
+ function $extractLinkRangesFromCodeNode(codeNode) {
15649
+ const ranges = [];
15650
+ let offset = 0;
15651
+
15652
+ function walk(node) {
15653
+ for (const child of node.getChildren()) {
15654
+ if (z$5(child)) {
15655
+ const size = child.getTextContent().length;
15656
+ appendRange(ranges, { start: offset, end: offset + size, link: linkAttributesFrom(child) });
15657
+ offset += size;
15658
+ } else if (Wi(child)) {
15659
+ walk(child);
15660
+ } else {
15661
+ const size = child.getTextContent().length;
15662
+ if (Tr(child)) {
15663
+ const link = $getCodeLink(child);
15664
+ if (link) {
15665
+ appendRange(ranges, { start: offset, end: offset + size, link });
15666
+ }
15667
+ }
15668
+ offset += size;
15669
+ }
15670
+ }
15671
+ }
15672
+
15673
+ walk(codeNode);
15674
+
15675
+ return ranges
15676
+ }
15677
+
15678
+ function $applyLinkRangesToTokens(tokens, ranges) {
15679
+ if (ranges.length === 0) return tokens
15680
+
15681
+ const linkedTokens = [];
15682
+ let offset = 0;
15683
+
15684
+ for (const token of tokens) {
15685
+ if (X$1(token)) {
15686
+ linkedTokens.push(...$splitTokenAtLinkBoundaries(token, offset, ranges));
15687
+ } else {
15688
+ linkedTokens.push(token);
15689
+ }
15690
+ offset += token.getTextContentSize();
15691
+ }
15692
+
15693
+ return linkedTokens
15694
+ }
15695
+
15696
+ function $splitTokenAtLinkBoundaries(token, tokenStart, ranges) {
15697
+ const text = token.getTextContent();
15698
+ const segments = segmentTextByRanges(text, tokenStart, ranges);
15699
+
15700
+ if (segments.length === 1) {
15701
+ const [ segment ] = segments;
15702
+ if (segment.range) {
15703
+ $setCodeLink(token, segment.range.link);
15704
+ }
15705
+ return [ token ]
15706
+ } else {
15707
+ return segments.map((segment) => {
15708
+ const segmentToken = $cloneTokenSlice(token, text.slice(segment.start, segment.end));
15709
+ if (segment.range) {
15710
+ $setCodeLink(segmentToken, segment.range.link);
15711
+ }
15712
+ return segmentToken
15713
+ })
15714
+ }
15715
+ }
15716
+
15717
+ function $cloneTokenSlice(token, text) {
15718
+ const segmentToken = V$2(text, token.getHighlightType());
15719
+ segmentToken.setStyle(token.getStyle());
15720
+ // CodeHighlightNode.setFormat is a no-op, so carry the format over directly
15721
+ segmentToken.getWritable().__format = token.getFormat();
15722
+ return segmentToken
15723
+ }
15724
+
15725
+ // Consecutive children carrying the same link merge into a single range, so a
15726
+ // link split across tokens by an earlier retokenization keeps covering fresh
15727
+ // tokens as one contiguous stretch however they retokenize.
15728
+ function appendRange(ranges, range) {
15729
+ const previous = ranges[ranges.length - 1];
15730
+
15731
+ if (previous && previous.end === range.start && sameLink(previous.link, range.link)) {
15732
+ previous.end = range.end;
15733
+ } else {
15734
+ ranges.push(range);
15735
+ }
15736
+ }
15737
+
15738
+ function sameLink(a, b) {
15739
+ return a.url === b.url && a.target === b.target && a.rel === b.rel && a.title === b.title
15740
+ }
15741
+
15742
+ function linkAttributesFrom(linkNode) {
15743
+ const link = { url: linkNode.getURL() };
15744
+ if (linkNode.getTarget()) link.target = linkNode.getTarget();
15745
+ if (linkNode.getRel()) link.rel = linkNode.getRel();
15746
+ if (linkNode.getTitle()) link.title = linkNode.getTitle();
15747
+ return link
15748
+ }
15749
+
15477
15750
  // Custom TextNode exportDOM that avoids redundant wrapping.
15478
15751
  //
15479
15752
  // Lexical's built-in TextNode.exportDOM() calls createDOM() which produces semantic tags
@@ -15488,6 +15761,30 @@ class BrowserAdapter {
15488
15761
  // Any <span> elements produced by createDOM() are unwrapped, since they only carry
15489
15762
  // editor classes that aren't meaningful in exported HTML.
15490
15763
 
15764
+ // A CodeHighlightNode exports like any other text node, plus an <a> wrapper
15765
+ // when it carries link state — that's how a link survives inside a code
15766
+ // block, whose retokenizer would destroy an actual LinkNode child.
15767
+ function exportCodeHighlightNodeDOM(editor, codeHighlightNode) {
15768
+ const output = exportTextNodeDOM(editor, codeHighlightNode);
15769
+ const link = $getCodeLink(codeHighlightNode);
15770
+
15771
+ if (link) {
15772
+ return { element: wrapWithAnchor(output.element, link) }
15773
+ } else {
15774
+ return output
15775
+ }
15776
+ }
15777
+
15778
+ function wrapWithAnchor(element, link) {
15779
+ const anchor = document.createElement("a");
15780
+ anchor.setAttribute("href", link.url);
15781
+ if (link.target) anchor.setAttribute("target", link.target);
15782
+ if (link.rel) anchor.setAttribute("rel", link.rel);
15783
+ if (link.title) anchor.setAttribute("title", link.title);
15784
+ anchor.appendChild(element);
15785
+ return anchor
15786
+ }
15787
+
15491
15788
  function exportTextNodeDOM(editor, textNode) {
15492
15789
  const element = textNode.createDOM(editor._config, editor);
15493
15790
  element.style.whiteSpace = "pre-wrap";
@@ -15719,12 +16016,34 @@ class CodeHighlightingExtension extends LexxyExtension {
15719
16016
  return dc({
15720
16017
  name: "lexxy/code-highlighting",
15721
16018
  register(editor) {
15722
- return L$1(editor, buildHighlightPreservingTokenizer(editor))
16019
+ return L$1(editor, buildMarkupPreservingTokenizer(editor))
15723
16020
  }
15724
16021
  })
15725
16022
  }
15726
16023
  }
15727
16024
 
16025
+ // The code retokenizer replaces a code block's children with freshly created
16026
+ // tokens that carry no styles or links, which would drop color highlights and
16027
+ // hyperlinks on every edit. This tokenizer wraps the stock Prism tokenizer to
16028
+ // restore both: it recovers the block's highlight and link ranges — staged
16029
+ // during HTML import, or read from the children the fresh tokens are about to
16030
+ // replace — and reapplies them to the fresh tokens before the retokenizer
16031
+ // splices them in.
16032
+ function buildMarkupPreservingTokenizer(editor) {
16033
+ return {
16034
+ defaultLanguage: r.defaultLanguage,
16035
+ tokenize(code, language) {
16036
+ return r.tokenize(code, language)
16037
+ },
16038
+ $tokenize(codeNode, language) {
16039
+ const linkRanges = $extractLinkRangesFromCodeNode(codeNode);
16040
+ const highlightRanges = $takeHighlightRanges(editor, codeNode);
16041
+ const tokens = r.$tokenize(codeNode, language);
16042
+ return $applyLinkRangesToTokens($applyHighlightRangesToTokens(tokens, highlightRanges), linkRanges)
16043
+ }
16044
+ }
16045
+ }
16046
+
15728
16047
  const TRIX_LANGUAGE_ATTR = "language";
15729
16048
 
15730
16049
  class TrixContentExtension extends LexxyExtension {
@@ -17511,7 +17830,7 @@ class LexicalEditorElement extends HTMLElement {
17511
17830
  theme: theme,
17512
17831
  nodes: this.#lexicalNodes,
17513
17832
  html: {
17514
- export: new Map([ [ gr, exportTextNodeDOM ], [ K$1, exportTextNodeDOM ] ])
17833
+ export: new Map([ [ gr, exportTextNodeDOM ], [ K$1, exportCodeHighlightNodeDOM ] ])
17515
17834
  },
17516
17835
  $initialEditorState: (editor) => {
17517
17836
  this.#configureSanitizer(editor);
@@ -19690,12 +20009,13 @@ function highlightElement(preElement) {
19690
20009
  const grammar = Prism$1.languages?.[language];
19691
20010
  if (!grammar) return
19692
20011
 
19693
- // Read the source text and <mark> ranges in a single walk, before Prism
19694
- // rewrites the element. Sharing one traversal keeps the highlight offsets
19695
- // aligned with the code string and preserves leading whitespace — deriving
19696
- // either of them separately (e.g. textContent through DOMParser) collapses
19697
- // leading whitespace and shifts every range, re-indenting the rendered block.
19698
- const { code, highlights } = extractCodeAndHighlights(preElement);
20012
+ // Read the source text and the <mark> and <a> ranges in a single walk,
20013
+ // before Prism rewrites the element. Sharing one traversal keeps the range
20014
+ // offsets aligned with the code string and preserves leading whitespace —
20015
+ // deriving either of them separately (e.g. textContent through DOMParser)
20016
+ // collapses leading whitespace and shifts every range, re-indenting the
20017
+ // rendered block.
20018
+ const { code, highlights, links } = extractCodeAndMarkup(preElement);
19699
20019
 
19700
20020
  const highlightedHtml = Prism$1.highlight(code, grammar, language);
19701
20021
  preElement.innerHTML = highlightedHtml;
@@ -19704,18 +20024,24 @@ function highlightElement(preElement) {
19704
20024
  applyHighlightRanges(preElement, highlights);
19705
20025
  }
19706
20026
 
20027
+ if (links.length > 0) {
20028
+ applyLinkRanges(preElement, links);
20029
+ }
20030
+
19707
20031
  preElement.dataset.highlighted = "true";
19708
20032
  }
19709
20033
 
19710
- // Walk the <pre> once, building Prism's source text and the <mark> ranges
19711
- // together: a text node contributes its text verbatim, a <br> contributes a
19712
- // newline, and a <mark> records the slice of code it covers. Because both
19713
- // outputs come from the same walk, every range offset is just a position in
19714
- // `code` — so the highlights can't drift out of sync with the source, and the
19715
- // block's leading whitespace survives (HTML parsing would collapse it).
19716
- function extractCodeAndHighlights(preElement) {
20034
+ // Walk the <pre> once, building Prism's source text and the <mark> and <a>
20035
+ // ranges together: a text node contributes its text verbatim, a <br>
20036
+ // contributes a newline, and a <mark> or <a> records the slice of code it
20037
+ // covers. Because all outputs come from the same walk, every range offset is
20038
+ // just a position in `code` — so the markup can't drift out of sync with the
20039
+ // source, and the block's leading whitespace survives (HTML parsing would
20040
+ // collapse it).
20041
+ function extractCodeAndMarkup(preElement) {
19717
20042
  const root = preElement.querySelector("code") || preElement;
19718
20043
  const highlights = [];
20044
+ const links = [];
19719
20045
  let code = "";
19720
20046
 
19721
20047
  function walk(node) {
@@ -19733,6 +20059,12 @@ function extractCodeAndHighlights(preElement) {
19733
20059
  if (style) {
19734
20060
  highlights.push({ start, end: code.length, style });
19735
20061
  }
20062
+ } else if (node.tagName === "A" && node.getAttribute("href")) {
20063
+ const start = code.length;
20064
+ for (const child of node.childNodes) {
20065
+ walk(child);
20066
+ }
20067
+ links.push({ start, end: code.length, attributes: linkAttributes(node) });
19736
20068
  } else {
19737
20069
  for (const child of node.childNodes) {
19738
20070
  walk(child);
@@ -19745,7 +20077,17 @@ function extractCodeAndHighlights(preElement) {
19745
20077
  walk(child);
19746
20078
  }
19747
20079
 
19748
- return { code, highlights }
20080
+ return { code, highlights, links }
20081
+ }
20082
+
20083
+ function linkAttributes(element) {
20084
+ const attributes = { href: element.getAttribute("href") };
20085
+ for (const name of [ "target", "rel", "title" ]) {
20086
+ if (element.getAttribute(name)) {
20087
+ attributes[name] = element.getAttribute(name);
20088
+ }
20089
+ }
20090
+ return attributes
19749
20091
  }
19750
20092
 
19751
20093
  function extractStyle(element) {
@@ -19755,16 +20097,32 @@ function extractStyle(element) {
19755
20097
  return parts.length > 0 ? parts.join(" ") : null
19756
20098
  }
19757
20099
 
19758
- // Wrap character ranges in <mark> elements within a Prism-highlighted DOM tree.
19759
- // Each range is applied independently, re-collecting text nodes each time to
19760
- // account for splits from previous ranges.
20100
+ // Wrap character ranges in <mark> or <a> elements within a Prism-highlighted
20101
+ // DOM tree. Each range is applied independently, re-collecting text nodes
20102
+ // each time to account for splits from previous ranges.
19761
20103
  function applyHighlightRanges(element, highlights) {
19762
20104
  for (const { start, end, style } of highlights) {
19763
- wrapRange(element, start, end, style);
20105
+ wrapRange(element, start, end, () => {
20106
+ const mark = document.createElement("mark");
20107
+ mark.setAttribute("style", style);
20108
+ return mark
20109
+ });
20110
+ }
20111
+ }
20112
+
20113
+ function applyLinkRanges(element, links) {
20114
+ for (const { start, end, attributes } of links) {
20115
+ wrapRange(element, start, end, () => {
20116
+ const anchor = document.createElement("a");
20117
+ for (const [ name, value ] of Object.entries(attributes)) {
20118
+ anchor.setAttribute(name, value);
20119
+ }
20120
+ return anchor
20121
+ });
19764
20122
  }
19765
20123
  }
19766
20124
 
19767
- function wrapRange(container, rangeStart, rangeEnd, style) {
20125
+ function wrapRange(container, rangeStart, rangeEnd, createWrapper) {
19768
20126
  const textNodes = collectTextNodes(container);
19769
20127
 
19770
20128
  // Process in reverse so DOM mutations don't shift earlier text node offsets
@@ -19779,14 +20137,13 @@ function wrapRange(container, rangeStart, rangeEnd, style) {
19779
20137
  const text = node.textContent;
19780
20138
  const parent = node.parentNode;
19781
20139
 
19782
- const mark = document.createElement("mark");
19783
- mark.setAttribute("style", style);
19784
- mark.textContent = text.slice(relStart, relEnd);
20140
+ const wrapper = createWrapper();
20141
+ wrapper.textContent = text.slice(relStart, relEnd);
19785
20142
 
19786
20143
  if (relEnd < text.length) {
19787
20144
  parent.insertBefore(document.createTextNode(text.slice(relEnd)), node.nextSibling);
19788
20145
  }
19789
- parent.insertBefore(mark, node.nextSibling);
20146
+ parent.insertBefore(wrapper, node.nextSibling);
19790
20147
 
19791
20148
  if (relStart > 0) {
19792
20149
  node.textContent = text.slice(0, relStart);