@velo-sci/notebook-react 0.6.1 → 0.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/index.cjs +826 -741
  2. package/dist/index.js +825 -740
  3. package/package.json +3 -3
package/dist/index.cjs CHANGED
@@ -123,12 +123,12 @@ function useNotebookEvent(type, handler) {
123
123
  }
124
124
 
125
125
  // src/components/SciNotebook.tsx
126
- var import_react13 = __toESM(require("react"), 1);
126
+ var import_react14 = __toESM(require("react"), 1);
127
127
  var import_notebook_core = require("@velo-sci/notebook-core");
128
- var import_notebook_renderer = require("@velo-sci/notebook-renderer");
128
+ var import_notebook_renderer2 = require("@velo-sci/notebook-renderer");
129
129
 
130
130
  // src/components/Cell.tsx
131
- var import_react9 = require("react");
131
+ var import_react10 = require("react");
132
132
 
133
133
  // src/components/FloatingToolbar.tsx
134
134
  var import_react2 = require("react");
@@ -259,10 +259,11 @@ function parseInlineStyle(css) {
259
259
 
260
260
  // src/components/MathEditor.tsx
261
261
  var import_react3 = require("react");
262
- var import_jsx_runtime2 = require("react/jsx-runtime");
262
+
263
+ // src/components/math-categories.ts
263
264
  var MATH_CATEGORIES = [
264
265
  {
265
- name: "Estructuras",
266
+ name: "Structures",
266
267
  icon: "\u2B1A",
267
268
  blocks: [
268
269
  { label: "a/b", latex: "\\frac{\u25A2}{\u25A2}", cursor: 6 },
@@ -279,7 +280,7 @@ var MATH_CATEGORIES = [
279
280
  ]
280
281
  },
281
282
  {
282
- name: "Integrales",
283
+ name: "Integrals",
283
284
  icon: "\u222B",
284
285
  blocks: [
285
286
  { label: "\u222B", latex: "\\int{\u25A2}\\,d{\u25A2}", cursor: 5 },
@@ -290,7 +291,7 @@ var MATH_CATEGORIES = [
290
291
  ]
291
292
  },
292
293
  {
293
- name: "Sumatorias",
294
+ name: "Summations",
294
295
  icon: "\u2211",
295
296
  blocks: [
296
297
  { label: "\u2211", latex: "\\sum_{\u25A2}^{\u25A2}{\u25A2}", cursor: 5 },
@@ -307,11 +308,11 @@ var MATH_CATEGORIES = [
307
308
  { label: "3\xD73", latex: "\\begin{pmatrix} \u25A2 & \u25A2 & \u25A2 \\\\ \u25A2 & \u25A2 & \u25A2 \\\\ \u25A2 & \u25A2 & \u25A2 \\end{pmatrix}", cursor: 16 },
308
309
  { label: "[2\xD72]", latex: "\\begin{bmatrix} \u25A2 & \u25A2 \\\\ \u25A2 & \u25A2 \\end{bmatrix}", cursor: 16 },
309
310
  { label: "|2\xD72|", latex: "\\begin{vmatrix} \u25A2 & \u25A2 \\\\ \u25A2 & \u25A2 \\end{vmatrix}", cursor: 16 },
310
- { label: "cases", latex: "\\begin{cases} \u25A2 & \\text{si } \u25A2 \\\\ \u25A2 & \\text{si } \u25A2 \\end{cases}", cursor: 14 }
311
+ { label: "cases", latex: "\\begin{cases} \u25A2 & \\text{if } \u25A2 \\\\ \u25A2 & \\text{if } \u25A2 \\end{cases}", cursor: 14 }
311
312
  ]
312
313
  },
313
314
  {
314
- name: "Griegos",
315
+ name: "Greek",
315
316
  icon: "\u03B1",
316
317
  blocks: [
317
318
  { label: "\u03B1", latex: "\\alpha" },
@@ -342,7 +343,7 @@ var MATH_CATEGORIES = [
342
343
  ]
343
344
  },
344
345
  {
345
- name: "Operadores",
346
+ name: "Operators",
346
347
  icon: "\xB1",
347
348
  blocks: [
348
349
  { label: "\xB1", latex: "\\pm" },
@@ -374,7 +375,7 @@ var MATH_CATEGORIES = [
374
375
  ]
375
376
  },
376
377
  {
377
- name: "Flechas",
378
+ name: "Arrows",
378
379
  icon: "\u2192",
379
380
  blocks: [
380
381
  { label: "\u2192", latex: "\\rightarrow" },
@@ -389,7 +390,7 @@ var MATH_CATEGORIES = [
389
390
  ]
390
391
  },
391
392
  {
392
- name: "Funciones",
393
+ name: "Functions",
393
394
  icon: "f(x)",
394
395
  blocks: [
395
396
  { label: "sin", latex: "\\sin{\u25A2}", cursor: 5 },
@@ -405,7 +406,7 @@ var MATH_CATEGORIES = [
405
406
  ]
406
407
  },
407
408
  {
408
- name: "Delimitadores",
409
+ name: "Delimiters",
409
410
  icon: "()",
410
411
  blocks: [
411
412
  { label: "(\u2026)", latex: "\\left( \u25A2 \\right)", cursor: 7 },
@@ -418,9 +419,12 @@ var MATH_CATEGORIES = [
418
419
  ]
419
420
  }
420
421
  ];
422
+
423
+ // src/components/MathEditor.tsx
424
+ var import_jsx_runtime2 = require("react/jsx-runtime");
421
425
  function renderLatexPreview(latex) {
422
426
  const clean = latex.replace(/^\$\$\s*/, "").replace(/\s*\$\$$/, "").trim();
423
- if (!clean) return '<span class="sci-nb-math-preview-empty">Formula vacia</span>';
427
+ if (!clean) return '<span class="sci-nb-math-preview-empty">Empty formula</span>';
424
428
  if (typeof globalThis !== "undefined" && globalThis.katex) {
425
429
  try {
426
430
  return globalThis.katex.renderToString(clean, {
@@ -430,14 +434,13 @@ function renderLatexPreview(latex) {
430
434
  } catch {
431
435
  }
432
436
  }
433
- return `<code class="sci-nb-math-preview-code">${escapeHtml(clean)}</code>`;
434
- }
435
- function escapeHtml(s) {
436
- return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
437
+ const escaped = clean.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
438
+ return `<code class="sci-nb-math-preview-code">${escaped}</code>`;
437
439
  }
438
440
  var MathEditor = ({ cellId, source, onExit }) => {
439
441
  const engine = useSciNotebook();
440
442
  const textareaRef = (0, import_react3.useRef)(null);
443
+ const containerRef = (0, import_react3.useRef)(null);
441
444
  const [activeCategory, setActiveCategory] = (0, import_react3.useState)(0);
442
445
  const [showRaw, setShowRaw] = (0, import_react3.useState)(false);
443
446
  const innerLatex = source.replace(/^\$\$\s*/, "").replace(/\s*\$\$$/, "").trim();
@@ -474,15 +477,42 @@ $$`);
474
477
  }
475
478
  });
476
479
  }, [innerLatex, updateSource]);
480
+ const exitAndNext = (0, import_react3.useCallback)(() => {
481
+ onExit();
482
+ const cells = engine.getCells();
483
+ const idx = cells.findIndex((c) => c.id === cellId);
484
+ if (idx < cells.length - 1) {
485
+ engine.focusCell(cells[idx + 1].id);
486
+ engine.setEditMode(cells[idx + 1].id);
487
+ }
488
+ }, [engine, cellId, onExit]);
477
489
  const handleKeyDown = (0, import_react3.useCallback)((e) => {
478
490
  if (e.key === "Escape") {
479
491
  e.preventDefault();
492
+ e.stopPropagation();
480
493
  onExit();
481
494
  } else if (e.key === "Enter" && e.shiftKey) {
482
495
  e.preventDefault();
496
+ e.stopPropagation();
497
+ exitAndNext();
498
+ } else if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
499
+ e.preventDefault();
500
+ e.stopPropagation();
483
501
  onExit();
484
502
  }
485
- }, [onExit]);
503
+ }, [onExit, exitAndNext]);
504
+ (0, import_react3.useEffect)(() => {
505
+ if (showRaw && textareaRef.current) {
506
+ textareaRef.current.focus();
507
+ } else if (containerRef.current) {
508
+ containerRef.current.focus();
509
+ }
510
+ }, [showRaw]);
511
+ (0, import_react3.useEffect)(() => {
512
+ if (containerRef.current) {
513
+ containerRef.current.focus();
514
+ }
515
+ }, []);
486
516
  (0, import_react3.useEffect)(() => {
487
517
  if (showRaw && textareaRef.current) {
488
518
  const ta = textareaRef.current;
@@ -491,82 +521,97 @@ $$`);
491
521
  }
492
522
  }, [innerLatex, showRaw]);
493
523
  const category = MATH_CATEGORIES[activeCategory];
494
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "sci-nb-math-editor", onKeyDown: handleKeyDown, children: [
495
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "sci-nb-math-tabs", children: MATH_CATEGORIES.map((cat, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
496
- "button",
497
- {
498
- className: `sci-nb-math-tab ${i === activeCategory ? "sci-nb-math-tab--active" : ""}`,
499
- onClick: () => setActiveCategory(i),
500
- title: cat.name,
501
- children: [
502
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "sci-nb-math-tab-icon", children: cat.icon }),
503
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "sci-nb-math-tab-label", children: cat.name })
504
- ]
505
- },
506
- cat.name
507
- )) }),
508
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "sci-nb-math-palette", children: category.blocks.map((block, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
509
- "button",
510
- {
511
- className: "sci-nb-math-block",
512
- onClick: () => insertBlock(block),
513
- title: block.latex,
514
- children: block.label
515
- },
516
- i
517
- )) }),
518
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "sci-nb-math-editor-area", children: [
519
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "sci-nb-math-mode-toggle", children: [
520
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
524
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
525
+ "div",
526
+ {
527
+ ref: containerRef,
528
+ className: "sci-nb-math-editor",
529
+ onKeyDown: handleKeyDown,
530
+ tabIndex: -1,
531
+ children: [
532
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "sci-nb-math-tabs", children: MATH_CATEGORIES.map((cat, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
521
533
  "button",
522
534
  {
523
- className: `sci-nb-math-mode-btn ${!showRaw ? "sci-nb-math-mode-btn--active" : ""}`,
524
- onClick: () => setShowRaw(false),
525
- children: "Preview"
526
- }
527
- ),
528
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
535
+ className: `sci-nb-math-tab ${i === activeCategory ? "sci-nb-math-tab--active" : ""}`,
536
+ onClick: () => setActiveCategory(i),
537
+ title: cat.name,
538
+ tabIndex: -1,
539
+ children: [
540
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "sci-nb-math-tab-icon", children: cat.icon }),
541
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "sci-nb-math-tab-label", children: cat.name })
542
+ ]
543
+ },
544
+ cat.name
545
+ )) }),
546
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "sci-nb-math-palette", children: category.blocks.map((block, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
529
547
  "button",
530
548
  {
531
- className: `sci-nb-math-mode-btn ${showRaw ? "sci-nb-math-mode-btn--active" : ""}`,
532
- onClick: () => setShowRaw(true),
533
- children: "LaTeX"
534
- }
535
- )
536
- ] }),
537
- showRaw ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
538
- "textarea",
539
- {
540
- ref: textareaRef,
541
- className: "sci-nb-math-raw",
542
- value: innerLatex,
543
- onChange: handleRawChange,
544
- placeholder: "Escribe LaTeX aqui...",
545
- spellCheck: false,
546
- autoFocus: true
547
- }
548
- ) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "sci-nb-math-visual", children: [
549
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
550
- "div",
551
- {
552
- className: "sci-nb-math-preview",
553
- dangerouslySetInnerHTML: { __html: renderLatexPreview(source) }
554
- }
555
- ),
556
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("p", { className: "sci-nb-math-visual-hint", children: [
557
- "Haz click en los bloques de arriba para construir tu formula. Cambia a modo ",
558
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("strong", { children: "LaTeX" }),
559
- " para editar directamente."
549
+ className: "sci-nb-math-block",
550
+ onClick: () => insertBlock(block),
551
+ title: block.latex,
552
+ tabIndex: -1,
553
+ children: block.label
554
+ },
555
+ i
556
+ )) }),
557
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "sci-nb-math-editor-area", children: [
558
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "sci-nb-math-mode-toggle", children: [
559
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
560
+ "button",
561
+ {
562
+ className: `sci-nb-math-mode-btn ${!showRaw ? "sci-nb-math-mode-btn--active" : ""}`,
563
+ onClick: () => setShowRaw(false),
564
+ tabIndex: -1,
565
+ children: "Preview"
566
+ }
567
+ ),
568
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
569
+ "button",
570
+ {
571
+ className: `sci-nb-math-mode-btn ${showRaw ? "sci-nb-math-mode-btn--active" : ""}`,
572
+ onClick: () => setShowRaw(true),
573
+ tabIndex: -1,
574
+ children: "LaTeX"
575
+ }
576
+ )
577
+ ] }),
578
+ showRaw ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
579
+ "textarea",
580
+ {
581
+ ref: textareaRef,
582
+ className: "sci-nb-math-raw",
583
+ value: innerLatex,
584
+ onChange: handleRawChange,
585
+ placeholder: "Type LaTeX here...",
586
+ spellCheck: false,
587
+ autoFocus: true
588
+ }
589
+ ) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "sci-nb-math-visual", children: [
590
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
591
+ "div",
592
+ {
593
+ className: "sci-nb-math-preview",
594
+ dangerouslySetInnerHTML: { __html: renderLatexPreview(source) }
595
+ }
596
+ ),
597
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("p", { className: "sci-nb-math-visual-hint", children: [
598
+ "Click the blocks above to build your formula. Switch to ",
599
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("strong", { children: "LaTeX" }),
600
+ " mode to edit directly."
601
+ ] })
602
+ ] })
603
+ ] }),
604
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "sci-nb-cell-hint", children: [
605
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("kbd", { children: "Esc" }),
606
+ " exit \xB7 ",
607
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("kbd", { children: "Shift+Enter" }),
608
+ " next \xB7 ",
609
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("kbd", { children: "Ctrl+Enter" }),
610
+ " render"
560
611
  ] })
561
- ] })
562
- ] }),
563
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "sci-nb-cell-hint", children: [
564
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("kbd", { children: "Esc" }),
565
- " salir \xB7 ",
566
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("kbd", { children: "Shift+Enter" }),
567
- " siguiente"
568
- ] })
569
- ] });
612
+ ]
613
+ }
614
+ );
570
615
  };
571
616
 
572
617
  // src/components/ImageCell.tsx
@@ -664,7 +709,7 @@ var ImageCell = ({ cellId, source, metadata, onExit }) => {
664
709
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("circle", { cx: "12", cy: "12", r: "2.5" }),
665
710
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M4 22l6-6 4 4 4-4 10 10", strokeLinejoin: "round" })
666
711
  ] }),
667
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { children: "Arrastra, pega (Ctrl+V) o haz click para seleccionar" }),
712
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { children: "Drag, paste (Ctrl+V) or click to select" }),
668
713
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
669
714
  "input",
670
715
  {
@@ -703,7 +748,7 @@ var ImageCell = ({ cellId, source, metadata, onExit }) => {
703
748
  type: "text",
704
749
  value: data.alt,
705
750
  onChange: (e) => save({ alt: e.target.value }),
706
- placeholder: "Descripcion de la imagen"
751
+ placeholder: "Image description"
707
752
  }
708
753
  )
709
754
  ] }),
@@ -715,13 +760,13 @@ var ImageCell = ({ cellId, source, metadata, onExit }) => {
715
760
  type: "text",
716
761
  value: data.caption,
717
762
  onChange: (e) => save({ caption: e.target.value }),
718
- placeholder: "Pie de imagen (opcional)"
763
+ placeholder: "Caption (optional)"
719
764
  }
720
765
  )
721
766
  ] }),
722
767
  /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "sci-nb-image-row", children: [
723
768
  /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "sci-nb-image-field sci-nb-image-field--small", children: [
724
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("label", { children: "Ancho" }),
769
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("label", { children: "Width" }),
725
770
  /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("select", { value: data.width, onChange: (e) => save({ width: e.target.value }), children: [
726
771
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: "25%", children: "25%" }),
727
772
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: "50%", children: "50%" }),
@@ -731,38 +776,38 @@ var ImageCell = ({ cellId, source, metadata, onExit }) => {
731
776
  ] })
732
777
  ] }),
733
778
  /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "sci-nb-image-field sci-nb-image-field--small", children: [
734
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("label", { children: "Alinear" }),
779
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("label", { children: "Align" }),
735
780
  /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("select", { value: data.align, onChange: (e) => save({ align: e.target.value }), children: [
736
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: "left", children: "Izquierda" }),
737
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: "center", children: "Centro" }),
738
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: "right", children: "Derecha" })
781
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: "left", children: "Left" }),
782
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: "center", children: "Center" }),
783
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: "right", children: "Right" })
739
784
  ] })
740
785
  ] }),
741
- hasSrc && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { className: "sci-nb-image-clear", onClick: () => save({ src: "" }), children: "Quitar imagen" })
786
+ hasSrc && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { className: "sci-nb-image-clear", onClick: () => save({ src: "" }), children: "Remove image" })
742
787
  ] })
743
788
  ] }),
744
789
  /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "sci-nb-cell-hint", children: [
745
790
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("kbd", { children: "Esc" }),
746
- " salir"
791
+ " exit"
747
792
  ] })
748
793
  ] });
749
794
  };
750
795
  function renderImagePreview(source, metadata) {
751
796
  const data = parseImageSource(source, metadata);
752
797
  if (!data.src) {
753
- return '<div class="sci-nb-image-empty"><span class="sci-nb-placeholder">Click para agregar imagen</span></div>';
798
+ return '<div class="sci-nb-image-empty"><span class="sci-nb-placeholder">Click to add image</span></div>';
754
799
  }
755
800
  const alignStyle = `text-align:${data.align}`;
756
801
  const widthStyle = `max-width:${data.width};width:auto;max-height:400px`;
757
802
  let html = `<div class="sci-nb-image-view" style="${alignStyle}">`;
758
803
  html += `<img src="${escapeAttr(data.src)}" alt="${escapeAttr(data.alt)}" style="${widthStyle}" />`;
759
804
  if (data.caption) {
760
- html += `<p class="sci-nb-image-caption">${escapeHtml2(data.caption)}</p>`;
805
+ html += `<p class="sci-nb-image-caption">${escapeHtml(data.caption)}</p>`;
761
806
  }
762
807
  html += `</div>`;
763
808
  return html;
764
809
  }
765
- function escapeHtml2(s) {
810
+ function escapeHtml(s) {
766
811
  return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
767
812
  }
768
813
  function escapeAttr(s) {
@@ -888,22 +933,22 @@ var EmbedCell = ({ cellId, source, metadata, onExit }) => {
888
933
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("label", { children: "Sandbox" }),
889
934
  /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("select", { value: data.sandbox, onChange: (e) => save({ sandbox: e.target.value }), children: [
890
935
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("option", { value: "allow-scripts allow-same-origin allow-popups", children: "Standard" }),
891
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("option", { value: "allow-scripts", children: "Solo scripts" }),
892
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("option", { value: "", children: "Restringido" })
936
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("option", { value: "allow-scripts", children: "Scripts only" }),
937
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("option", { value: "", children: "Restricted" })
893
938
  ] })
894
939
  ] })
895
940
  ] })
896
941
  ] }),
897
942
  /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "sci-nb-cell-hint", children: [
898
943
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("kbd", { children: "Esc" }),
899
- " salir"
944
+ " exit"
900
945
  ] })
901
946
  ] });
902
947
  };
903
948
  function renderEmbedPreview(source, metadata) {
904
949
  const data = parseEmbedSource(source, metadata);
905
950
  if (!data.url) {
906
- return '<div class="sci-nb-embed-empty"><span class="sci-nb-placeholder">Click para agregar contenido embebido</span></div>';
951
+ return '<div class="sci-nb-embed-empty"><span class="sci-nb-placeholder">Click to add embedded content</span></div>';
907
952
  }
908
953
  const titleAttr = data.title ? ` title="${escapeAttr2(data.title)}"` : "";
909
954
  return `<div class="sci-nb-embed-view" style="height:${data.height}">
@@ -918,14 +963,14 @@ function escapeAttr2(s) {
918
963
  var import_react6 = require("react");
919
964
  var import_jsx_runtime5 = require("react/jsx-runtime");
920
965
  var DEFAULT_COMMANDS = [
921
- { type: "markdown", label: "Texto", description: "Bloque de texto con formato Markdown", icon: "M", keywords: ["text", "markdown", "paragraph", "texto"] },
922
- { type: "code", label: "C\xF3digo", description: "Bloque de c\xF3digo con syntax highlighting", icon: "</>", keywords: ["code", "codigo", "script", "program"] },
923
- { type: "latex", label: "F\xF3rmula", description: "Editor visual de f\xF3rmulas LaTeX", icon: "\u2211", keywords: ["latex", "math", "formula", "ecuacion", "equation"] },
924
- { type: "image", label: "Imagen", description: "Imagen con drag & drop, URL, caption", icon: "\u{1F5BC}", keywords: ["image", "imagen", "foto", "picture", "img"] },
966
+ { type: "markdown", label: "Text", description: "Markdown formatted text block", icon: "M", keywords: ["text", "markdown", "paragraph"] },
967
+ { type: "code", label: "Code", description: "Code block with syntax highlighting", icon: "</>", keywords: ["code", "script", "program"] },
968
+ { type: "latex", label: "Formula", description: "Visual LaTeX formula editor", icon: "\u2211", keywords: ["latex", "math", "formula", "equation"] },
969
+ { type: "image", label: "Image", description: "Image with drag & drop, URL, caption", icon: "\u{1F5BC}", keywords: ["image", "picture", "photo", "img"] },
925
970
  { type: "embed", label: "Embed", description: "YouTube, CodePen, Desmos, iframe", icon: "\u29C9", keywords: ["embed", "iframe", "youtube", "video", "codepen"] },
926
- { type: "table", label: "Tabla", description: "Tabla editable con filas y columnas", icon: "\u25A6", keywords: ["table", "tabla", "grid", "spreadsheet"] },
927
- { type: "mermaid", label: "Diagrama", description: "Diagrama Mermaid (flowchart, sequence, etc.)", icon: "\u25C7", keywords: ["mermaid", "diagram", "diagrama", "flowchart", "chart"] },
928
- { type: "raw", label: "Raw", description: "Texto sin formato", icon: "T", keywords: ["raw", "plain", "text", "crudo"] }
971
+ { type: "table", label: "Table", description: "Editable table with rows and columns", icon: "\u25A6", keywords: ["table", "grid", "spreadsheet"] },
972
+ { type: "mermaid", label: "Diagram", description: "Mermaid diagram (flowchart, sequence, etc.)", icon: "\u25C7", keywords: ["mermaid", "diagram", "flowchart", "chart"] },
973
+ { type: "raw", label: "Raw", description: "Plain unformatted text", icon: "T", keywords: ["raw", "plain", "text"] }
929
974
  ];
930
975
  var SlashCommand = ({
931
976
  position,
@@ -980,7 +1025,7 @@ var SlashCommand = ({
980
1025
  className: "sci-nb-slash-menu",
981
1026
  style: { top: position.top, left: position.left },
982
1027
  children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "sci-nb-slash-empty", children: [
983
- 'Sin resultados para "/',
1028
+ 'No results for "/',
984
1029
  query,
985
1030
  '"'
986
1031
  ] })
@@ -994,7 +1039,7 @@ var SlashCommand = ({
994
1039
  className: "sci-nb-slash-menu",
995
1040
  style: { top: position.top, left: position.left },
996
1041
  children: [
997
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "sci-nb-slash-header", children: "Insertar bloque" }),
1042
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "sci-nb-slash-header", children: "Insert block" }),
998
1043
  filtered.map((cmd, i) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
999
1044
  "button",
1000
1045
  {
@@ -1047,6 +1092,8 @@ function toMarkdownTable(data) {
1047
1092
  var TableCell = ({ cellId, source, onExit }) => {
1048
1093
  const engine = useSciNotebook();
1049
1094
  const [data, setData] = (0, import_react7.useState)(() => parseMarkdownTable(source));
1095
+ const [hoverCol, setHoverCol] = (0, import_react7.useState)(null);
1096
+ const [hoverRow, setHoverRow] = (0, import_react7.useState)(null);
1050
1097
  const syncToEngine = (0, import_react7.useCallback)((newData) => {
1051
1098
  setData(newData);
1052
1099
  engine.updateCellSource(cellId, toMarkdownTable(newData));
@@ -1085,142 +1132,104 @@ var TableCell = ({ cellId, source, onExit }) => {
1085
1132
  if (e.key === "Escape") {
1086
1133
  e.preventDefault();
1087
1134
  onExit();
1088
- } else if (e.key === "Tab" && !e.shiftKey) {
1089
1135
  }
1090
1136
  }, [onExit]);
1091
1137
  return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "sci-nb-table-editor", onKeyDown: handleKeyDown, children: [
1092
1138
  /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "sci-nb-table-toolbar", children: [
1093
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { onClick: addRow, children: "+ Fila" }),
1094
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { onClick: addColumn, children: "+ Columna" })
1139
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { onClick: addRow, children: "+ Row" }),
1140
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { onClick: addColumn, children: "+ Column" })
1095
1141
  ] }),
1096
1142
  /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("table", { children: [
1097
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("tr", { children: [
1098
- data.headers.map((h, ci) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("th", { children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1099
- "input",
1100
- {
1101
- value: h,
1102
- onChange: (e) => updateHeader(ci, e.target.value),
1103
- placeholder: `Col ${ci + 1}`
1104
- }
1105
- ) }, ci)),
1106
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("th", { style: { width: 30, padding: 0 } })
1107
- ] }) }),
1108
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("tbody", { children: data.rows.map((row, ri) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("tr", { children: [
1109
- row.map((cell, ci) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("td", { children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1110
- "input",
1111
- {
1112
- value: cell,
1113
- onChange: (e) => updateCell(ri, ci, e.target.value),
1114
- placeholder: "..."
1115
- }
1116
- ) }, ci)),
1117
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("td", { style: { width: 30, padding: 0, textAlign: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1118
- "button",
1119
- {
1120
- className: "sci-nb-btn sci-nb-btn--danger",
1121
- onClick: () => removeRow(ri),
1122
- title: "Eliminar fila",
1123
- style: { padding: "2px 4px", fontSize: 10, border: "none", background: "transparent" },
1124
- children: "\u2715"
1125
- }
1126
- ) })
1127
- ] }, ri)) })
1143
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("tr", { children: data.headers.map((h, ci) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1144
+ "th",
1145
+ {
1146
+ className: "sci-nb-table-header-cell",
1147
+ onMouseEnter: () => setHoverCol(ci),
1148
+ onMouseLeave: () => setHoverCol(null),
1149
+ children: [
1150
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1151
+ "input",
1152
+ {
1153
+ value: h,
1154
+ onChange: (e) => updateHeader(ci, e.target.value),
1155
+ placeholder: `Col ${ci + 1}`
1156
+ }
1157
+ ),
1158
+ data.headers.length > 1 && hoverCol === ci && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1159
+ "button",
1160
+ {
1161
+ className: "sci-nb-table-delete-btn",
1162
+ onClick: () => removeColumn(ci),
1163
+ title: "Delete column",
1164
+ children: "\u2715"
1165
+ }
1166
+ )
1167
+ ]
1168
+ },
1169
+ ci
1170
+ )) }) }),
1171
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("tbody", { children: data.rows.map((row, ri) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1172
+ "tr",
1173
+ {
1174
+ onMouseEnter: () => setHoverRow(ri),
1175
+ onMouseLeave: () => setHoverRow(null),
1176
+ children: row.map((cell, ci) => {
1177
+ const isLastCol = ci === row.length - 1;
1178
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1179
+ "td",
1180
+ {
1181
+ className: isLastCol ? "sci-nb-table-row-end" : "",
1182
+ children: [
1183
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1184
+ "input",
1185
+ {
1186
+ value: cell,
1187
+ onChange: (e) => updateCell(ri, ci, e.target.value),
1188
+ placeholder: "..."
1189
+ }
1190
+ ),
1191
+ isLastCol && data.rows.length > 1 && hoverRow === ri && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1192
+ "button",
1193
+ {
1194
+ className: "sci-nb-table-delete-btn",
1195
+ onClick: () => removeRow(ri),
1196
+ title: "Delete row",
1197
+ children: "\u2715"
1198
+ }
1199
+ )
1200
+ ]
1201
+ },
1202
+ ci
1203
+ );
1204
+ })
1205
+ },
1206
+ ri
1207
+ )) })
1128
1208
  ] }),
1129
1209
  /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "sci-nb-cell-hint", children: [
1130
1210
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("kbd", { children: "Tab" }),
1131
- " siguiente celda \xB7 ",
1211
+ " next cell \xB7 ",
1132
1212
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("kbd", { children: "Esc" }),
1133
- " salir"
1213
+ " exit"
1134
1214
  ] })
1135
1215
  ] });
1136
1216
  };
1137
1217
  function renderTablePreview(source) {
1138
1218
  const data = parseMarkdownTable(source);
1139
- if (data.headers.length === 0) return "<p>Tabla vac\xEDa</p>";
1140
- const ths = data.headers.map((h) => `<th>${escapeHtml3(h)}</th>`).join("");
1219
+ if (data.headers.length === 0) return "<p>Empty table</p>";
1220
+ const ths = data.headers.map((h) => `<th>${escapeHtml2(h)}</th>`).join("");
1141
1221
  const trs = data.rows.map(
1142
- (row) => `<tr>${row.map((c) => `<td>${escapeHtml3(c)}</td>`).join("")}</tr>`
1222
+ (row) => `<tr>${row.map((c) => `<td>${escapeHtml2(c)}</td>`).join("")}</tr>`
1143
1223
  ).join("");
1144
1224
  return `<table class="sci-nb-rendered-table"><thead><tr>${ths}</tr></thead><tbody>${trs}</tbody></table>`;
1145
1225
  }
1146
- function escapeHtml3(s) {
1226
+ function escapeHtml2(s) {
1147
1227
  return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
1148
1228
  }
1149
1229
 
1150
- // src/components/CellOutput.tsx
1151
- var import_jsx_runtime7 = require("react/jsx-runtime");
1152
- var CellOutputDisplay = ({ outputs }) => {
1153
- if (!outputs || outputs.length === 0) return null;
1154
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "sci-nb-cell-outputs", children: outputs.map((output, i) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: `sci-nb-output sci-nb-output--${output.outputType}`, children: renderOutput(output) }, i)) });
1155
- };
1156
- function renderOutput(output) {
1157
- switch (output.outputType) {
1158
- case "stream":
1159
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("pre", { className: `sci-nb-output-stream sci-nb-output-stream--${output.name}`, children: output.text });
1160
- case "display": {
1161
- if (output.data["text/html"]) {
1162
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1163
- "div",
1164
- {
1165
- className: "sci-nb-output-html",
1166
- dangerouslySetInnerHTML: { __html: output.data["text/html"] }
1167
- }
1168
- );
1169
- }
1170
- if (output.data["image/svg+xml"]) {
1171
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1172
- "div",
1173
- {
1174
- className: "sci-nb-output-svg",
1175
- dangerouslySetInnerHTML: { __html: output.data["image/svg+xml"] }
1176
- }
1177
- );
1178
- }
1179
- if (output.data["image/png"]) {
1180
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1181
- "img",
1182
- {
1183
- className: "sci-nb-output-image",
1184
- src: `data:image/png;base64,${output.data["image/png"]}`,
1185
- alt: "Output"
1186
- }
1187
- );
1188
- }
1189
- if (output.data["image/jpeg"]) {
1190
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1191
- "img",
1192
- {
1193
- className: "sci-nb-output-image",
1194
- src: `data:image/jpeg;base64,${output.data["image/jpeg"]}`,
1195
- alt: "Output"
1196
- }
1197
- );
1198
- }
1199
- if (output.data["application/json"]) {
1200
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("pre", { className: "sci-nb-output-json", children: JSON.stringify(JSON.parse(output.data["application/json"]), null, 2) });
1201
- }
1202
- if (output.data["text/plain"]) {
1203
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("pre", { className: "sci-nb-output-text", children: output.data["text/plain"] });
1204
- }
1205
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("pre", { className: "sci-nb-output-text", children: "[Display output]" });
1206
- }
1207
- case "error":
1208
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "sci-nb-output-error", children: [
1209
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("strong", { className: "sci-nb-output-error-name", children: [
1210
- output.name,
1211
- ": "
1212
- ] }),
1213
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "sci-nb-output-error-msg", children: output.message }),
1214
- output.traceback && output.traceback.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("pre", { className: "sci-nb-output-traceback", children: output.traceback.join("\n") })
1215
- ] });
1216
- default:
1217
- return null;
1218
- }
1219
- }
1220
-
1221
1230
  // src/components/MermaidCell.tsx
1222
1231
  var import_react8 = require("react");
1223
- var import_jsx_runtime8 = require("react/jsx-runtime");
1232
+ var import_jsx_runtime7 = require("react/jsx-runtime");
1224
1233
  var mermaidIdCounter = 0;
1225
1234
  var MermaidPreview = ({ source, onClick }) => {
1226
1235
  const [svg, setSvg] = (0, import_react8.useState)(null);
@@ -1263,29 +1272,29 @@ var MermaidPreview = ({ source, onClick }) => {
1263
1272
  }, [source]);
1264
1273
  const mermaid = globalThis.mermaid;
1265
1274
  if (!source.trim()) {
1266
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "sci-nb-mermaid-preview", onClick, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "sci-nb-placeholder", children: "Diagrama vacio \u2014 escribe sintaxis Mermaid" }) });
1275
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "sci-nb-mermaid-preview", onClick, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "sci-nb-placeholder", children: "Empty diagram \u2014 write Mermaid syntax" }) });
1267
1276
  }
1268
1277
  if (!mermaid) {
1269
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "sci-nb-mermaid-preview", onClick, children: [
1270
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("pre", { className: "sci-nb-code", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("code", { className: "language-mermaid", children: source }) }),
1271
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: { fontSize: 11, color: "#94a3b8", textAlign: "center", padding: 4 }, children: [
1272
- "Mermaid no disponible. Importa ",
1273
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("code", { children: "mermaid" }),
1274
- " y exponlo como ",
1275
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("code", { children: "globalThis.mermaid" }),
1278
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "sci-nb-mermaid-preview", onClick, children: [
1279
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("pre", { className: "sci-nb-code", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("code", { className: "language-mermaid", children: source }) }),
1280
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { fontSize: 11, color: "#94a3b8", textAlign: "center", padding: 4 }, children: [
1281
+ "Mermaid not available. Import ",
1282
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("code", { children: "mermaid" }),
1283
+ " and expose it as ",
1284
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("code", { children: "globalThis.mermaid" }),
1276
1285
  "."
1277
1286
  ] })
1278
1287
  ] });
1279
1288
  }
1280
1289
  if (error) {
1281
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "sci-nb-mermaid-error", onClick, children: [
1282
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("strong", { children: "Mermaid error:" }),
1290
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "sci-nb-mermaid-error", onClick, children: [
1291
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("strong", { children: "Mermaid error:" }),
1283
1292
  " ",
1284
1293
  error
1285
1294
  ] });
1286
1295
  }
1287
1296
  if (svg) {
1288
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1297
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1289
1298
  "div",
1290
1299
  {
1291
1300
  ref: containerRef,
@@ -1293,125 +1302,361 @@ var MermaidPreview = ({ source, onClick }) => {
1293
1302
  onClick,
1294
1303
  dangerouslySetInnerHTML: { __html: svg }
1295
1304
  }
1296
- );
1305
+ );
1306
+ }
1307
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "sci-nb-mermaid-preview", onClick, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "sci-nb-placeholder", children: "Rendering diagram..." }) });
1308
+ };
1309
+ function initMermaid(mermaidLib, config) {
1310
+ globalThis.mermaid = mermaidLib;
1311
+ mermaidLib.initialize({
1312
+ startOnLoad: false,
1313
+ theme: "default",
1314
+ securityLevel: "loose",
1315
+ ...config
1316
+ });
1317
+ }
1318
+
1319
+ // src/components/CodeEditor.tsx
1320
+ var import_react9 = require("react");
1321
+ var import_notebook_renderer = require("@velo-sci/notebook-renderer");
1322
+ var import_jsx_runtime8 = require("react/jsx-runtime");
1323
+ var CodeEditor = ({
1324
+ source,
1325
+ language,
1326
+ onChange,
1327
+ onKeyDown,
1328
+ placeholder
1329
+ }) => {
1330
+ const textareaRef = (0, import_react9.useRef)(null);
1331
+ const preRef = (0, import_react9.useRef)(null);
1332
+ const [highlighted, setHighlighted] = (0, import_react9.useState)("");
1333
+ (0, import_react9.useEffect)(() => {
1334
+ const html = (0, import_notebook_renderer.highlightCodeTokens)(source, language || "text");
1335
+ const match = html.match(/<code[^>]*>([\s\S]*)<\/code>/);
1336
+ setHighlighted(match ? match[1] : html);
1337
+ }, [source, language]);
1338
+ const syncScroll = (0, import_react9.useCallback)(() => {
1339
+ if (textareaRef.current && preRef.current) {
1340
+ preRef.current.scrollTop = textareaRef.current.scrollTop;
1341
+ preRef.current.scrollLeft = textareaRef.current.scrollLeft;
1342
+ }
1343
+ }, []);
1344
+ (0, import_react9.useEffect)(() => {
1345
+ if (textareaRef.current) {
1346
+ const ta = textareaRef.current;
1347
+ ta.style.height = "auto";
1348
+ ta.style.height = `${Math.max(40, ta.scrollHeight)}px`;
1349
+ }
1350
+ }, [source]);
1351
+ (0, import_react9.useEffect)(() => {
1352
+ textareaRef.current?.focus();
1353
+ }, []);
1354
+ const handleChange = (0, import_react9.useCallback)((e) => {
1355
+ onChange(e.target.value);
1356
+ }, [onChange]);
1357
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "sci-nb-code-editor-wrap", children: [
1358
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1359
+ "pre",
1360
+ {
1361
+ ref: preRef,
1362
+ className: "sci-nb-code-editor-highlight sci-nb-code--highlighted",
1363
+ "aria-hidden": "true",
1364
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("code", { className: `language-${language || "text"}`, children: [
1365
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { dangerouslySetInnerHTML: { __html: highlighted || "&nbsp;" } }),
1366
+ "\n"
1367
+ ] })
1368
+ }
1369
+ ),
1370
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1371
+ "textarea",
1372
+ {
1373
+ ref: textareaRef,
1374
+ className: "sci-nb-code-editor-input",
1375
+ value: source,
1376
+ onChange: handleChange,
1377
+ onKeyDown,
1378
+ onScroll: syncScroll,
1379
+ placeholder,
1380
+ spellCheck: false,
1381
+ autoComplete: "off",
1382
+ autoCapitalize: "off",
1383
+ rows: 1
1384
+ }
1385
+ )
1386
+ ] });
1387
+ };
1388
+
1389
+ // src/components/CellRenderers.tsx
1390
+ var import_jsx_runtime9 = require("react/jsx-runtime");
1391
+ function renderEditMode(cell, cellId, engine, textareaRef, handleSourceChange, handleKeyDown, placeholder, exitEdit, slashState, onSlashSelect, onSlashClose) {
1392
+ if (cell.type === "latex") {
1393
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(MathEditor, { cellId, source: cell.source, onExit: exitEdit });
1394
+ }
1395
+ if (cell.type === "image") {
1396
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ImageCell, { cellId, source: cell.source, metadata: cell.metadata, onExit: exitEdit });
1397
+ }
1398
+ if (cell.type === "embed") {
1399
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(EmbedCell, { cellId, source: cell.source, metadata: cell.metadata, onExit: exitEdit });
1400
+ }
1401
+ if (cell.type === "table") {
1402
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(TableCell, { cellId, source: cell.source, metadata: cell.metadata, onExit: exitEdit });
1403
+ }
1404
+ if (cell.type === "code") {
1405
+ const lang = cell.metadata.language || "javascript";
1406
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
1407
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1408
+ CodeEditor,
1409
+ {
1410
+ cellId,
1411
+ source: cell.source,
1412
+ language: lang,
1413
+ onChange: (val) => engine.updateCellSource(cellId, val),
1414
+ onKeyDown: handleKeyDown,
1415
+ placeholder
1416
+ }
1417
+ ),
1418
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "sci-nb-cell-hint", children: [
1419
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("kbd", { children: "Shift+Enter" }),
1420
+ " next \xB7 ",
1421
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("kbd", { children: "Esc" }),
1422
+ " exit"
1423
+ ] })
1424
+ ] });
1425
+ }
1426
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
1427
+ cell.type === "markdown" && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(FloatingToolbar, { cellId, textareaRef }),
1428
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1429
+ "textarea",
1430
+ {
1431
+ ref: textareaRef,
1432
+ className: "sci-nb-editor",
1433
+ value: cell.source,
1434
+ onChange: handleSourceChange,
1435
+ onKeyDown: handleKeyDown,
1436
+ placeholder,
1437
+ spellCheck: cell.type === "markdown",
1438
+ rows: 1
1439
+ }
1440
+ ),
1441
+ slashState && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1442
+ SlashCommand,
1443
+ {
1444
+ position: slashState.pos,
1445
+ query: slashState.query,
1446
+ onSelect: onSlashSelect,
1447
+ onClose: onSlashClose
1448
+ }
1449
+ ),
1450
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "sci-nb-cell-hint", children: [
1451
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("kbd", { children: "/" }),
1452
+ " commands \xB7 ",
1453
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("kbd", { children: "Shift+Enter" }),
1454
+ " next \xB7 ",
1455
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("kbd", { children: "Esc" }),
1456
+ " exit"
1457
+ ] })
1458
+ ] });
1459
+ }
1460
+ function renderViewMode(cell, renderedHtml, isEmpty, placeholder, enterEdit) {
1461
+ if (cell.type === "image") {
1462
+ const html = renderImagePreview(cell.source, cell.metadata);
1463
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "sci-nb-preview", onClick: enterEdit, dangerouslySetInnerHTML: { __html: html } });
1464
+ }
1465
+ if (cell.type === "embed") {
1466
+ const html = renderEmbedPreview(cell.source, cell.metadata);
1467
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "sci-nb-preview sci-nb-preview--embed", onClick: enterEdit, dangerouslySetInnerHTML: { __html: html } });
1468
+ }
1469
+ if (cell.type === "table") {
1470
+ const html = renderTablePreview(cell.source);
1471
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "sci-nb-preview", onClick: enterEdit, dangerouslySetInnerHTML: { __html: html } });
1472
+ }
1473
+ if (cell.type === "mermaid") {
1474
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(MermaidPreview, { source: cell.source, onClick: enterEdit });
1475
+ }
1476
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1477
+ "div",
1478
+ {
1479
+ className: `sci-nb-preview ${isEmpty ? "sci-nb-preview--empty" : ""}`,
1480
+ onClick: enterEdit,
1481
+ dangerouslySetInnerHTML: isEmpty ? { __html: `<span class="sci-nb-placeholder">${placeholder}</span>` } : { __html: renderedHtml }
1482
+ }
1483
+ );
1484
+ }
1485
+
1486
+ // src/components/CellOutput.tsx
1487
+ var import_jsx_runtime10 = require("react/jsx-runtime");
1488
+ var CellOutputDisplay = ({ outputs }) => {
1489
+ if (!outputs || outputs.length === 0) return null;
1490
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "sci-nb-cell-outputs", children: outputs.map((output, i) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: `sci-nb-output sci-nb-output--${output.outputType}`, children: renderOutput(output) }, i)) });
1491
+ };
1492
+ function renderOutput(output) {
1493
+ switch (output.outputType) {
1494
+ case "stream":
1495
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("pre", { className: `sci-nb-output-stream sci-nb-output-stream--${output.name}`, children: output.text });
1496
+ case "display": {
1497
+ if (output.data["text/html"]) {
1498
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1499
+ "div",
1500
+ {
1501
+ className: "sci-nb-output-html",
1502
+ dangerouslySetInnerHTML: { __html: output.data["text/html"] }
1503
+ }
1504
+ );
1505
+ }
1506
+ if (output.data["image/svg+xml"]) {
1507
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1508
+ "div",
1509
+ {
1510
+ className: "sci-nb-output-svg",
1511
+ dangerouslySetInnerHTML: { __html: output.data["image/svg+xml"] }
1512
+ }
1513
+ );
1514
+ }
1515
+ if (output.data["image/png"]) {
1516
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1517
+ "img",
1518
+ {
1519
+ className: "sci-nb-output-image",
1520
+ src: `data:image/png;base64,${output.data["image/png"]}`,
1521
+ alt: "Output"
1522
+ }
1523
+ );
1524
+ }
1525
+ if (output.data["image/jpeg"]) {
1526
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1527
+ "img",
1528
+ {
1529
+ className: "sci-nb-output-image",
1530
+ src: `data:image/jpeg;base64,${output.data["image/jpeg"]}`,
1531
+ alt: "Output"
1532
+ }
1533
+ );
1534
+ }
1535
+ if (output.data["application/json"]) {
1536
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("pre", { className: "sci-nb-output-json", children: JSON.stringify(JSON.parse(output.data["application/json"]), null, 2) });
1537
+ }
1538
+ if (output.data["text/plain"]) {
1539
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("pre", { className: "sci-nb-output-text", children: output.data["text/plain"] });
1540
+ }
1541
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("pre", { className: "sci-nb-output-text", children: "[Display output]" });
1542
+ }
1543
+ case "error":
1544
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "sci-nb-output-error", children: [
1545
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("strong", { className: "sci-nb-output-error-name", children: [
1546
+ output.name,
1547
+ ": "
1548
+ ] }),
1549
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "sci-nb-output-error-msg", children: output.message }),
1550
+ output.traceback && output.traceback.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("pre", { className: "sci-nb-output-traceback", children: output.traceback.join("\n") })
1551
+ ] });
1552
+ default:
1553
+ return null;
1297
1554
  }
1298
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "sci-nb-mermaid-preview", onClick, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "sci-nb-placeholder", children: "Renderizando diagrama..." }) });
1299
- };
1300
- function initMermaid(mermaidLib, config) {
1301
- globalThis.mermaid = mermaidLib;
1302
- mermaidLib.initialize({
1303
- startOnLoad: false,
1304
- theme: "default",
1305
- securityLevel: "loose",
1306
- ...config
1307
- });
1308
1555
  }
1309
1556
 
1310
1557
  // src/components/Cell.tsx
1311
- var import_jsx_runtime9 = require("react/jsx-runtime");
1558
+ var import_jsx_runtime11 = require("react/jsx-runtime");
1312
1559
  var CELL_TYPES = [
1313
1560
  { value: "markdown", label: "Markdown", icon: "M" },
1314
1561
  { value: "code", label: "Code", icon: "</>" },
1315
1562
  { value: "raw", label: "Raw", icon: "T" },
1316
1563
  { value: "latex", label: "LaTeX", icon: "\u2211" },
1317
- { value: "image", label: "Imagen", icon: "\u{1F5BC}" },
1564
+ { value: "image", label: "Image", icon: "\u{1F5BC}" },
1318
1565
  { value: "embed", label: "Embed", icon: "\u29C9" }
1319
1566
  ];
1320
1567
  var PLACEHOLDERS = {
1321
- markdown: "Escribe markdown aqui... (click para editar)",
1322
- code: "Escribe codigo aqui...",
1323
- raw: "Texto raw...",
1324
- latex: "Escribe LaTeX aqui... e.g. \\int_0^1 x^2 dx",
1325
- image: "Click para agregar imagen",
1326
- embed: "Click para agregar contenido embebido"
1568
+ markdown: "Write markdown here... (click to edit)",
1569
+ code: "Write code here...",
1570
+ raw: "Raw text...",
1571
+ latex: "Write LaTeX here... e.g. \\int_0^1 x^2 dx",
1572
+ image: "Click to add image",
1573
+ embed: "Click to add embedded content"
1327
1574
  };
1328
1575
  var Cell = ({ cellId, pipeline, index, totalCells }) => {
1329
1576
  const cell = useCell(cellId);
1330
1577
  const engine = useSciNotebook();
1331
- const textareaRef = (0, import_react9.useRef)(null);
1332
- const cellRef = (0, import_react9.useRef)(null);
1333
- const [showTypeMenu, setShowTypeMenu] = (0, import_react9.useState)(false);
1334
- const [hovered, setHovered] = (0, import_react9.useState)(false);
1335
- const [slashState, setSlashState] = (0, import_react9.useState)(null);
1336
- const [dragOver, setDragOver] = (0, import_react9.useState)(null);
1337
- const [isDragging, setIsDragging] = (0, import_react9.useState)(false);
1338
- const rendered = (0, import_react9.useMemo)(() => {
1578
+ const textareaRef = (0, import_react10.useRef)(null);
1579
+ const cellRef = (0, import_react10.useRef)(null);
1580
+ const [showTypeMenu, setShowTypeMenu] = (0, import_react10.useState)(false);
1581
+ const [hovered, setHovered] = (0, import_react10.useState)(false);
1582
+ const [slashState, setSlashState] = (0, import_react10.useState)(null);
1583
+ const [dragOver, setDragOver] = (0, import_react10.useState)(null);
1584
+ const [isDragging, setIsDragging] = (0, import_react10.useState)(false);
1585
+ const rendered = (0, import_react10.useMemo)(() => {
1339
1586
  if (!cell) return { html: "", cellId: "", renderTime: 0, cached: false };
1340
1587
  return pipeline.render(cell);
1341
1588
  }, [cell?.source, cell?.type, cell?.metadata, pipeline]);
1342
- (0, import_react9.useEffect)(() => {
1589
+ (0, import_react10.useEffect)(() => {
1343
1590
  if (cell?.editing && textareaRef.current) {
1344
1591
  const ta = textareaRef.current;
1345
1592
  ta.style.height = "auto";
1346
1593
  ta.style.height = `${Math.max(40, ta.scrollHeight)}px`;
1347
1594
  }
1348
1595
  }, [cell?.source, cell?.editing]);
1349
- (0, import_react9.useEffect)(() => {
1350
- if (cell?.editing && textareaRef.current) {
1351
- textareaRef.current.focus();
1352
- }
1596
+ (0, import_react10.useEffect)(() => {
1597
+ if (cell?.editing && textareaRef.current) textareaRef.current.focus();
1353
1598
  }, [cell?.editing]);
1354
- (0, import_react9.useEffect)(() => {
1599
+ (0, import_react10.useEffect)(() => {
1355
1600
  if (!showTypeMenu) return;
1356
1601
  const handler = (e) => {
1357
- if (cellRef.current && !cellRef.current.contains(e.target)) {
1358
- setShowTypeMenu(false);
1359
- }
1602
+ if (cellRef.current && !cellRef.current.contains(e.target)) setShowTypeMenu(false);
1360
1603
  };
1361
1604
  document.addEventListener("mousedown", handler);
1362
1605
  return () => document.removeEventListener("mousedown", handler);
1363
1606
  }, [showTypeMenu]);
1364
- const handleSourceChange = (0, import_react9.useCallback)((e) => {
1607
+ const handleSourceChange = (0, import_react10.useCallback)((e) => {
1365
1608
  const val = e.target.value;
1366
1609
  engine.updateCellSource(cellId, val);
1367
1610
  const ta = e.target;
1368
1611
  const cursor = ta.selectionStart;
1369
1612
  const textBefore = val.slice(0, cursor);
1370
1613
  const lastNewline = textBefore.lastIndexOf("\n");
1371
- const lineStart = lastNewline + 1;
1372
- const currentLine = textBefore.slice(lineStart);
1614
+ const currentLine = textBefore.slice(lastNewline + 1);
1373
1615
  if (currentLine.startsWith("/")) {
1374
- const query = currentLine.slice(1);
1375
1616
  const rect = ta.getBoundingClientRect();
1376
- const lineHeight = 22;
1377
1617
  const lines = textBefore.split("\n").length;
1378
- setSlashState({
1379
- query,
1380
- pos: { top: rect.top + lines * lineHeight + 4 - ta.scrollTop, left: rect.left + 8 }
1381
- });
1618
+ setSlashState({ query: currentLine.slice(1), pos: { top: rect.top + lines * 22 + 4 - ta.scrollTop, left: rect.left + 8 } });
1382
1619
  } else {
1383
1620
  setSlashState(null);
1384
1621
  }
1385
1622
  }, [engine, cellId]);
1386
- const enterEdit = (0, import_react9.useCallback)(() => {
1623
+ const enterEdit = (0, import_react10.useCallback)(() => {
1387
1624
  engine.setEditMode(cellId);
1388
1625
  engine.focusCell(cellId);
1389
1626
  }, [engine, cellId]);
1390
- const exitEdit = (0, import_react9.useCallback)(() => {
1627
+ const exitEdit = (0, import_react10.useCallback)(() => {
1391
1628
  engine.setViewMode(cellId);
1392
1629
  }, [engine, cellId]);
1393
- const handleSlashSelect = (0, import_react9.useCallback)((type) => {
1630
+ const handleSlashSelect = (0, import_react10.useCallback)((type) => {
1394
1631
  const val = cell?.source || "";
1395
1632
  const ta = textareaRef.current;
1396
1633
  if (ta) {
1397
1634
  const cursor = ta.selectionStart;
1398
1635
  const textBefore = val.slice(0, cursor);
1399
- const lastNewline = textBefore.lastIndexOf("\n");
1400
- const lineStart = lastNewline + 1;
1401
- const cleaned = val.slice(0, lineStart) + val.slice(cursor);
1402
- engine.updateCellSource(cellId, cleaned.trim());
1636
+ const lineStart = textBefore.lastIndexOf("\n") + 1;
1637
+ engine.updateCellSource(cellId, (val.slice(0, lineStart) + val.slice(cursor)).trim());
1403
1638
  }
1404
1639
  engine.setCellType(cellId, type);
1405
1640
  setSlashState(null);
1406
1641
  }, [engine, cellId, cell?.source]);
1407
- const handleKeyDown = (0, import_react9.useCallback)((e) => {
1408
- if (slashState) {
1409
- if (["ArrowDown", "ArrowUp", "Enter"].includes(e.key)) return;
1410
- if (e.key === "Escape") {
1411
- e.preventDefault();
1412
- setSlashState(null);
1413
- return;
1642
+ const wrapSelection = (0, import_react10.useCallback)((before, after) => {
1643
+ const ta = textareaRef.current;
1644
+ if (!ta) return;
1645
+ const { selectionStart: start, selectionEnd: end, value: val } = ta;
1646
+ engine.updateCellSource(cellId, val.substring(0, start) + before + val.substring(start, end) + after + val.substring(end));
1647
+ requestAnimationFrame(() => {
1648
+ if (textareaRef.current) {
1649
+ textareaRef.current.selectionStart = start + before.length;
1650
+ textareaRef.current.selectionEnd = end + before.length;
1414
1651
  }
1652
+ });
1653
+ }, [engine, cellId]);
1654
+ const handleKeyDown = (0, import_react10.useCallback)((e) => {
1655
+ if (slashState && ["ArrowDown", "ArrowUp", "Enter"].includes(e.key)) return;
1656
+ if (slashState && e.key === "Escape") {
1657
+ e.preventDefault();
1658
+ setSlashState(null);
1659
+ return;
1415
1660
  }
1416
1661
  if (e.key === "Escape") {
1417
1662
  e.preventDefault();
@@ -1432,30 +1677,24 @@ var Cell = ({ cellId, pipeline, index, totalCells }) => {
1432
1677
  e.preventDefault();
1433
1678
  const ta = e.currentTarget;
1434
1679
  const start = ta.selectionStart;
1435
- const end = ta.selectionEnd;
1436
- const val = ta.value;
1437
- const newVal = val.substring(0, start) + " " + val.substring(end);
1438
- engine.updateCellSource(cellId, newVal);
1680
+ engine.updateCellSource(cellId, ta.value.substring(0, start) + " " + ta.value.substring(ta.selectionEnd));
1439
1681
  requestAnimationFrame(() => {
1440
1682
  if (textareaRef.current) {
1441
- textareaRef.current.selectionStart = start + 2;
1442
- textareaRef.current.selectionEnd = start + 2;
1683
+ textareaRef.current.selectionStart = textareaRef.current.selectionEnd = start + 2;
1443
1684
  }
1444
1685
  });
1445
1686
  } else if (e.key === "Tab" && e.shiftKey) {
1446
1687
  e.preventDefault();
1447
1688
  const ta = e.currentTarget;
1448
1689
  const start = ta.selectionStart;
1449
- const val = ta.value;
1450
- const before = val.substring(0, start);
1690
+ const before = ta.value.substring(0, start);
1451
1691
  const trimmed = before.replace(/ $/, "");
1452
1692
  if (trimmed !== before) {
1453
- engine.updateCellSource(cellId, trimmed + val.substring(start));
1454
1693
  const diff = before.length - trimmed.length;
1694
+ engine.updateCellSource(cellId, trimmed + ta.value.substring(start));
1455
1695
  requestAnimationFrame(() => {
1456
1696
  if (textareaRef.current) {
1457
- textareaRef.current.selectionStart = start - diff;
1458
- textareaRef.current.selectionEnd = start - diff;
1697
+ textareaRef.current.selectionStart = textareaRef.current.selectionEnd = start - diff;
1459
1698
  }
1460
1699
  });
1461
1700
  }
@@ -1466,27 +1705,12 @@ var Cell = ({ cellId, pipeline, index, totalCells }) => {
1466
1705
  e.preventDefault();
1467
1706
  wrapSelection("*", "*");
1468
1707
  }
1469
- }, [engine, cellId, exitEdit]);
1470
- const wrapSelection = (0, import_react9.useCallback)((before, after) => {
1471
- const ta = textareaRef.current;
1472
- if (!ta) return;
1473
- const start = ta.selectionStart;
1474
- const end = ta.selectionEnd;
1475
- const val = ta.value;
1476
- const newVal = val.substring(0, start) + before + val.substring(start, end) + after + val.substring(end);
1477
- engine.updateCellSource(cellId, newVal);
1478
- requestAnimationFrame(() => {
1479
- if (textareaRef.current) {
1480
- textareaRef.current.selectionStart = start + before.length;
1481
- textareaRef.current.selectionEnd = end + before.length;
1482
- }
1483
- });
1484
- }, [engine, cellId]);
1708
+ }, [engine, cellId, exitEdit, slashState, wrapSelection]);
1485
1709
  if (!cell) return null;
1486
1710
  const isEditing = !!cell.editing;
1487
1711
  const isEmpty = !cell.source.trim();
1488
1712
  const placeholder = PLACEHOLDERS[cell.type] || "Click to edit...";
1489
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1713
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
1490
1714
  "div",
1491
1715
  {
1492
1716
  ref: cellRef,
@@ -1513,18 +1737,14 @@ var Cell = ({ cellId, pipeline, index, totalCells }) => {
1513
1737
  e.preventDefault();
1514
1738
  e.dataTransfer.dropEffect = "move";
1515
1739
  const rect = e.currentTarget.getBoundingClientRect();
1516
- const midY = rect.top + rect.height / 2;
1517
- setDragOver(e.clientY < midY ? "top" : "bottom");
1740
+ setDragOver(e.clientY < rect.top + rect.height / 2 ? "top" : "bottom");
1518
1741
  },
1519
1742
  onDragLeave: () => setDragOver(null),
1520
1743
  onDrop: (e) => {
1521
1744
  e.preventDefault();
1522
- const draggedId = e.dataTransfer.getData("text/plain");
1745
+ const did = e.dataTransfer.getData("text/plain");
1523
1746
  setDragOver(null);
1524
- if (draggedId && draggedId !== cellId) {
1525
- const targetIdx = dragOver === "top" ? index : index + 1;
1526
- engine.moveCell(draggedId, targetIdx);
1527
- }
1747
+ if (did && did !== cellId) engine.moveCell(did, dragOver === "top" ? index : index + 1);
1528
1748
  },
1529
1749
  "data-testid": `cell-${cell.id}`,
1530
1750
  "data-editing": String(isEditing),
@@ -1537,35 +1757,27 @@ var Cell = ({ cellId, pipeline, index, totalCells }) => {
1537
1757
  onMouseLeave: () => setHovered(false),
1538
1758
  onClick: () => engine.focusCell(cellId),
1539
1759
  children: [
1540
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "sci-nb-cell-gutter", children: [
1541
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "sci-nb-cell-handle", title: "Drag to reorder", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("svg", { width: "12", height: "20", viewBox: "0 0 12 20", fill: "currentColor", children: [
1542
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("circle", { cx: "3", cy: "4", r: "1.5" }),
1543
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("circle", { cx: "9", cy: "4", r: "1.5" }),
1544
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("circle", { cx: "3", cy: "10", r: "1.5" }),
1545
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("circle", { cx: "9", cy: "10", r: "1.5" }),
1546
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("circle", { cx: "3", cy: "16", r: "1.5" }),
1547
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("circle", { cx: "9", cy: "16", r: "1.5" })
1760
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "sci-nb-cell-gutter", children: [
1761
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "sci-nb-cell-handle", title: "Drag to reorder", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("svg", { width: "12", height: "20", viewBox: "0 0 12 20", fill: "currentColor", children: [
1762
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("circle", { cx: "3", cy: "4", r: "1.5" }),
1763
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("circle", { cx: "9", cy: "4", r: "1.5" }),
1764
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("circle", { cx: "3", cy: "10", r: "1.5" }),
1765
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("circle", { cx: "9", cy: "10", r: "1.5" }),
1766
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("circle", { cx: "3", cy: "16", r: "1.5" }),
1767
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("circle", { cx: "9", cy: "16", r: "1.5" })
1548
1768
  ] }) }),
1549
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "sci-nb-cell-index", children: [
1769
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "sci-nb-cell-index", children: [
1550
1770
  "[",
1551
1771
  index + 1,
1552
1772
  "]"
1553
1773
  ] })
1554
1774
  ] }),
1555
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "sci-nb-cell-badge-wrap", children: [
1556
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1557
- "button",
1558
- {
1559
- className: "sci-nb-cell-badge",
1560
- onClick: (e) => {
1561
- e.stopPropagation();
1562
- setShowTypeMenu(!showTypeMenu);
1563
- },
1564
- title: "Change cell type",
1565
- children: CELL_TYPES.find((ct) => ct.value === cell.type)?.icon || cell.type.slice(0, 2).toUpperCase()
1566
- }
1567
- ),
1568
- showTypeMenu && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "sci-nb-type-menu", children: CELL_TYPES.map((ct) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1775
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "sci-nb-cell-badge-wrap", children: [
1776
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { className: "sci-nb-cell-badge", onClick: (e) => {
1777
+ e.stopPropagation();
1778
+ setShowTypeMenu(!showTypeMenu);
1779
+ }, title: "Change cell type", children: CELL_TYPES.find((ct) => ct.value === cell.type)?.icon || cell.type.slice(0, 2).toUpperCase() }),
1780
+ showTypeMenu && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "sci-nb-type-menu", children: CELL_TYPES.map((ct) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
1569
1781
  "button",
1570
1782
  {
1571
1783
  className: `sci-nb-type-option ${cell.type === ct.value ? "sci-nb-type-option--active" : ""}`,
@@ -1575,173 +1787,46 @@ var Cell = ({ cellId, pipeline, index, totalCells }) => {
1575
1787
  setShowTypeMenu(false);
1576
1788
  },
1577
1789
  children: [
1578
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "sci-nb-type-option-icon", children: ct.icon }),
1790
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "sci-nb-type-option-icon", children: ct.icon }),
1579
1791
  ct.label
1580
1792
  ]
1581
1793
  },
1582
1794
  ct.value
1583
1795
  )) })
1584
1796
  ] }),
1585
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "sci-nb-cell-content", children: [
1586
- isEditing ? renderEditMode(cell, cellId, textareaRef, handleSourceChange, handleKeyDown, placeholder, exitEdit, slashState, handleSlashSelect, () => setSlashState(null)) : renderViewMode(cell, rendered.html, isEmpty, placeholder, enterEdit),
1587
- cell.outputs && cell.outputs.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(CellOutputDisplay, { outputs: cell.outputs })
1797
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "sci-nb-cell-content", children: [
1798
+ isEditing ? renderEditMode(cell, cellId, engine, textareaRef, handleSourceChange, handleKeyDown, placeholder, exitEdit, slashState, handleSlashSelect, () => setSlashState(null)) : renderViewMode(cell, rendered.html, isEmpty, placeholder, enterEdit),
1799
+ cell.outputs && cell.outputs.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(CellOutputDisplay, { outputs: cell.outputs })
1588
1800
  ] }),
1589
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "sci-nb-cell-actions", children: [
1590
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1591
- "button",
1592
- {
1593
- className: "sci-nb-btn",
1594
- onClick: (e) => {
1595
- e.stopPropagation();
1596
- engine.moveCell(cellId, index - 1);
1597
- },
1598
- disabled: index === 0,
1599
- title: "Move up",
1600
- children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { d: "M7 11V3M7 3L3 7M7 3l4 4", strokeLinecap: "round", strokeLinejoin: "round" }) })
1601
- }
1602
- ),
1603
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1604
- "button",
1605
- {
1606
- className: "sci-nb-btn",
1607
- onClick: (e) => {
1608
- e.stopPropagation();
1609
- engine.moveCell(cellId, index + 1);
1610
- },
1611
- disabled: index >= totalCells - 1,
1612
- title: "Move down",
1613
- children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { d: "M7 3v8M7 11l-4-4M7 11l4-4", strokeLinecap: "round", strokeLinejoin: "round" }) })
1614
- }
1615
- ),
1616
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1617
- "button",
1618
- {
1619
- className: "sci-nb-btn",
1620
- onClick: (e) => {
1621
- e.stopPropagation();
1622
- engine.duplicateCell(cellId);
1623
- },
1624
- title: "Duplicate cell",
1625
- children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: [
1626
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("rect", { x: "4", y: "4", width: "8", height: "8", rx: "1.5" }),
1627
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { d: "M10 2H3.5A1.5 1.5 0 002 3.5V10" })
1628
- ] })
1629
- }
1630
- ),
1631
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1632
- "button",
1633
- {
1634
- className: "sci-nb-btn sci-nb-btn--danger",
1635
- onClick: (e) => {
1636
- e.stopPropagation();
1637
- engine.deleteCell(cellId);
1638
- },
1639
- title: "Delete cell",
1640
- children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { d: "M3 4h8M5.5 4V3a1 1 0 011-1h1a1 1 0 011 1v1M6 6.5v3M8 6.5v3M4 4l.5 7a1.5 1.5 0 001.5 1.5h2A1.5 1.5 0 0010 11l.5-7", strokeLinecap: "round", strokeLinejoin: "round" }) })
1641
- }
1642
- )
1801
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "sci-nb-cell-actions", children: [
1802
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { className: "sci-nb-btn", onClick: (e) => {
1803
+ e.stopPropagation();
1804
+ engine.moveCell(cellId, index - 1);
1805
+ }, disabled: index === 0, title: "Move up", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M7 11V3M7 3L3 7M7 3l4 4", strokeLinecap: "round", strokeLinejoin: "round" }) }) }),
1806
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { className: "sci-nb-btn", onClick: (e) => {
1807
+ e.stopPropagation();
1808
+ engine.moveCell(cellId, index + 1);
1809
+ }, disabled: index >= totalCells - 1, title: "Move down", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M7 3v8M7 11l-4-4M7 11l4-4", strokeLinecap: "round", strokeLinejoin: "round" }) }) }),
1810
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { className: "sci-nb-btn", onClick: (e) => {
1811
+ e.stopPropagation();
1812
+ engine.duplicateCell(cellId);
1813
+ }, title: "Duplicate cell", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: [
1814
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("rect", { x: "4", y: "4", width: "8", height: "8", rx: "1.5" }),
1815
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M10 2H3.5A1.5 1.5 0 002 3.5V10" })
1816
+ ] }) }),
1817
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { className: "sci-nb-btn sci-nb-btn--danger", onClick: (e) => {
1818
+ e.stopPropagation();
1819
+ engine.deleteCell(cellId);
1820
+ }, title: "Delete cell", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M3 4h8M5.5 4V3a1 1 0 011-1h1a1 1 0 011 1v1M6 6.5v3M8 6.5v3M4 4l.5 7a1.5 1.5 0 001.5 1.5h2A1.5 1.5 0 0010 11l.5-7", strokeLinecap: "round", strokeLinejoin: "round" }) }) })
1643
1821
  ] })
1644
1822
  ]
1645
1823
  }
1646
1824
  );
1647
1825
  };
1648
- function renderEditMode(cell, cellId, textareaRef, handleSourceChange, handleKeyDown, placeholder, exitEdit, slashState, onSlashSelect, onSlashClose) {
1649
- if (cell.type === "latex") {
1650
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(MathEditor, { cellId, source: cell.source, onExit: exitEdit });
1651
- }
1652
- if (cell.type === "image") {
1653
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ImageCell, { cellId, source: cell.source, metadata: cell.metadata, onExit: exitEdit });
1654
- }
1655
- if (cell.type === "embed") {
1656
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(EmbedCell, { cellId, source: cell.source, metadata: cell.metadata, onExit: exitEdit });
1657
- }
1658
- if (cell.type === "table") {
1659
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(TableCell, { cellId, source: cell.source, metadata: cell.metadata, onExit: exitEdit });
1660
- }
1661
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
1662
- cell.type === "markdown" && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(FloatingToolbar, { cellId, textareaRef }),
1663
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1664
- "textarea",
1665
- {
1666
- ref: textareaRef,
1667
- className: "sci-nb-editor",
1668
- value: cell.source,
1669
- onChange: handleSourceChange,
1670
- onKeyDown: handleKeyDown,
1671
- placeholder,
1672
- spellCheck: cell.type === "markdown",
1673
- rows: 1
1674
- }
1675
- ),
1676
- slashState && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1677
- SlashCommand,
1678
- {
1679
- position: slashState.pos,
1680
- query: slashState.query,
1681
- onSelect: onSlashSelect,
1682
- onClose: onSlashClose
1683
- }
1684
- ),
1685
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "sci-nb-cell-hint", children: [
1686
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("kbd", { children: "/" }),
1687
- " comandos \xB7 ",
1688
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("kbd", { children: "Shift+Enter" }),
1689
- " siguiente \xB7 ",
1690
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("kbd", { children: "Esc" }),
1691
- " salir"
1692
- ] })
1693
- ] });
1694
- }
1695
- function renderViewMode(cell, renderedHtml, isEmpty, placeholder, enterEdit) {
1696
- if (cell.type === "image") {
1697
- const html = renderImagePreview(cell.source, cell.metadata);
1698
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1699
- "div",
1700
- {
1701
- className: "sci-nb-preview",
1702
- onClick: enterEdit,
1703
- dangerouslySetInnerHTML: { __html: html }
1704
- }
1705
- );
1706
- }
1707
- if (cell.type === "embed") {
1708
- const html = renderEmbedPreview(cell.source, cell.metadata);
1709
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1710
- "div",
1711
- {
1712
- className: "sci-nb-preview sci-nb-preview--embed",
1713
- onClick: enterEdit,
1714
- dangerouslySetInnerHTML: { __html: html }
1715
- }
1716
- );
1717
- }
1718
- if (cell.type === "table") {
1719
- const html = renderTablePreview(cell.source);
1720
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1721
- "div",
1722
- {
1723
- className: "sci-nb-preview",
1724
- onClick: enterEdit,
1725
- dangerouslySetInnerHTML: { __html: html }
1726
- }
1727
- );
1728
- }
1729
- if (cell.type === "mermaid") {
1730
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(MermaidPreview, { source: cell.source, onClick: enterEdit });
1731
- }
1732
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1733
- "div",
1734
- {
1735
- className: `sci-nb-preview ${isEmpty ? "sci-nb-preview--empty" : ""}`,
1736
- onClick: enterEdit,
1737
- dangerouslySetInnerHTML: isEmpty ? { __html: `<span class="sci-nb-placeholder">${placeholder}</span>` } : { __html: renderedHtml }
1738
- }
1739
- );
1740
- }
1741
1826
 
1742
1827
  // src/components/InsertHandle.tsx
1743
- var import_react10 = require("react");
1744
- var import_jsx_runtime10 = require("react/jsx-runtime");
1828
+ var import_react11 = require("react");
1829
+ var import_jsx_runtime12 = require("react/jsx-runtime");
1745
1830
  var INSERT_TYPES = [
1746
1831
  { type: "markdown", label: "Markdown", icon: "M" },
1747
1832
  { type: "code", label: "Code", icon: "</>" },
@@ -1752,9 +1837,9 @@ var INSERT_TYPES = [
1752
1837
  ];
1753
1838
  var InsertHandle = ({ index }) => {
1754
1839
  const engine = useSciNotebook();
1755
- const [open, setOpen] = (0, import_react10.useState)(false);
1756
- const menuRef = (0, import_react10.useRef)(null);
1757
- (0, import_react10.useEffect)(() => {
1840
+ const [open, setOpen] = (0, import_react11.useState)(false);
1841
+ const menuRef = (0, import_react11.useRef)(null);
1842
+ (0, import_react11.useEffect)(() => {
1758
1843
  if (!open) return;
1759
1844
  const onClickOutside = (e) => {
1760
1845
  if (menuRef.current && !menuRef.current.contains(e.target)) {
@@ -1775,27 +1860,27 @@ var InsertHandle = ({ index }) => {
1775
1860
  }
1776
1861
  });
1777
1862
  };
1778
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "sci-nb-insert-handle", ref: menuRef, children: [
1779
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "sci-nb-insert-line", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1863
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "sci-nb-insert-handle", ref: menuRef, children: [
1864
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "sci-nb-insert-line", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1780
1865
  "button",
1781
1866
  {
1782
1867
  className: "sci-nb-insert-btn",
1783
1868
  onClick: () => setOpen(!open),
1784
1869
  title: "Insert cell",
1785
- children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", children: [
1786
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("line", { x1: "8", y1: "3", x2: "8", y2: "13", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }),
1787
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("line", { x1: "3", y1: "8", x2: "13", y2: "8", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" })
1870
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", children: [
1871
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("line", { x1: "8", y1: "3", x2: "8", y2: "13", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }),
1872
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("line", { x1: "3", y1: "8", x2: "13", y2: "8", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" })
1788
1873
  ] })
1789
1874
  }
1790
1875
  ) }),
1791
- open && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "sci-nb-insert-menu", children: INSERT_TYPES.map((ct) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
1876
+ open && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "sci-nb-insert-menu", children: INSERT_TYPES.map((ct) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
1792
1877
  "button",
1793
1878
  {
1794
1879
  className: "sci-nb-insert-option",
1795
1880
  onClick: () => handleInsert(ct.type),
1796
1881
  children: [
1797
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "sci-nb-insert-option-icon", children: ct.icon }),
1798
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: ct.label })
1882
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "sci-nb-insert-option-icon", children: ct.icon }),
1883
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: ct.label })
1799
1884
  ]
1800
1885
  },
1801
1886
  ct.type
@@ -1804,12 +1889,12 @@ var InsertHandle = ({ index }) => {
1804
1889
  };
1805
1890
 
1806
1891
  // src/components/TOCSidebar.tsx
1807
- var import_react11 = require("react");
1808
- var import_jsx_runtime11 = require("react/jsx-runtime");
1892
+ var import_react12 = require("react");
1893
+ var import_jsx_runtime13 = require("react/jsx-runtime");
1809
1894
  var TOCSidebar = ({ focusedCellId }) => {
1810
1895
  const notebook = useNotebook();
1811
1896
  const engine = useSciNotebook();
1812
- const items = (0, import_react11.useMemo)(() => {
1897
+ const items = (0, import_react12.useMemo)(() => {
1813
1898
  if (!notebook) return [];
1814
1899
  const result = [];
1815
1900
  for (const cell of notebook.cells) {
@@ -1828,16 +1913,16 @@ var TOCSidebar = ({ focusedCellId }) => {
1828
1913
  }
1829
1914
  return result;
1830
1915
  }, [notebook]);
1831
- const handleClick = (0, import_react11.useCallback)((cellId) => {
1916
+ const handleClick = (0, import_react12.useCallback)((cellId) => {
1832
1917
  engine.focusCell(cellId);
1833
1918
  engine.setEditMode(cellId);
1834
1919
  const el = document.querySelector(`[data-testid="cell-${cellId}"]`);
1835
1920
  if (el) el.scrollIntoView({ behavior: "smooth", block: "center" });
1836
1921
  }, [engine]);
1837
1922
  if (items.length === 0) return null;
1838
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("nav", { className: "sci-nb-toc", children: [
1839
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "sci-nb-toc-title", children: "Contenido" }),
1840
- items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1923
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("nav", { className: "sci-nb-toc", children: [
1924
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "sci-nb-toc-title", children: "Contenido" }),
1925
+ items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1841
1926
  "button",
1842
1927
  {
1843
1928
  className: [
@@ -1855,21 +1940,21 @@ var TOCSidebar = ({ focusedCellId }) => {
1855
1940
  };
1856
1941
 
1857
1942
  // src/components/FindReplace.tsx
1858
- var import_react12 = require("react");
1859
- var import_jsx_runtime12 = require("react/jsx-runtime");
1943
+ var import_react13 = require("react");
1944
+ var import_jsx_runtime14 = require("react/jsx-runtime");
1860
1945
  var FindReplace = ({ onClose }) => {
1861
1946
  const notebook = useNotebook();
1862
1947
  const engine = useSciNotebook();
1863
- const [query, setQuery] = (0, import_react12.useState)("");
1864
- const [replacement, setReplacement] = (0, import_react12.useState)("");
1865
- const [showReplace, setShowReplace] = (0, import_react12.useState)(false);
1866
- const [caseSensitive, setCaseSensitive] = (0, import_react12.useState)(false);
1867
- const [currentIdx, setCurrentIdx] = (0, import_react12.useState)(0);
1868
- const inputRef = (0, import_react12.useRef)(null);
1869
- (0, import_react12.useEffect)(() => {
1948
+ const [query, setQuery] = (0, import_react13.useState)("");
1949
+ const [replacement, setReplacement] = (0, import_react13.useState)("");
1950
+ const [showReplace, setShowReplace] = (0, import_react13.useState)(false);
1951
+ const [caseSensitive, setCaseSensitive] = (0, import_react13.useState)(false);
1952
+ const [currentIdx, setCurrentIdx] = (0, import_react13.useState)(0);
1953
+ const inputRef = (0, import_react13.useRef)(null);
1954
+ (0, import_react13.useEffect)(() => {
1870
1955
  inputRef.current?.focus();
1871
1956
  }, []);
1872
- const matches = (0, import_react12.useMemo)(() => {
1957
+ const matches = (0, import_react13.useMemo)(() => {
1873
1958
  if (!query || !notebook) return [];
1874
1959
  const result = [];
1875
1960
  const q = caseSensitive ? query : query.toLowerCase();
@@ -1885,27 +1970,27 @@ var FindReplace = ({ onClose }) => {
1885
1970
  }
1886
1971
  return result;
1887
1972
  }, [query, notebook, caseSensitive]);
1888
- (0, import_react12.useEffect)(() => {
1973
+ (0, import_react13.useEffect)(() => {
1889
1974
  setCurrentIdx(0);
1890
1975
  }, [query, caseSensitive]);
1891
- const navigateToMatch = (0, import_react12.useCallback)((match) => {
1976
+ const navigateToMatch = (0, import_react13.useCallback)((match) => {
1892
1977
  engine.focusCell(match.cellId);
1893
1978
  const el = document.querySelector(`[data-testid="cell-${match.cellId}"]`);
1894
1979
  if (el) el.scrollIntoView({ behavior: "smooth", block: "center" });
1895
1980
  }, [engine]);
1896
- const goNext = (0, import_react12.useCallback)(() => {
1981
+ const goNext = (0, import_react13.useCallback)(() => {
1897
1982
  if (matches.length === 0) return;
1898
1983
  const next = (currentIdx + 1) % matches.length;
1899
1984
  setCurrentIdx(next);
1900
1985
  navigateToMatch(matches[next]);
1901
1986
  }, [matches, currentIdx, navigateToMatch]);
1902
- const goPrev = (0, import_react12.useCallback)(() => {
1987
+ const goPrev = (0, import_react13.useCallback)(() => {
1903
1988
  if (matches.length === 0) return;
1904
1989
  const prev = (currentIdx - 1 + matches.length) % matches.length;
1905
1990
  setCurrentIdx(prev);
1906
1991
  navigateToMatch(matches[prev]);
1907
1992
  }, [matches, currentIdx, navigateToMatch]);
1908
- const replaceCurrent = (0, import_react12.useCallback)(() => {
1993
+ const replaceCurrent = (0, import_react13.useCallback)(() => {
1909
1994
  if (matches.length === 0) return;
1910
1995
  const match = matches[currentIdx];
1911
1996
  if (!match) return;
@@ -1914,7 +1999,7 @@ var FindReplace = ({ onClose }) => {
1914
1999
  const newSource = cell.source.slice(0, match.index) + replacement + cell.source.slice(match.index + match.length);
1915
2000
  engine.updateCellSource(match.cellId, newSource);
1916
2001
  }, [matches, currentIdx, replacement, notebook, engine]);
1917
- const replaceAll = (0, import_react12.useCallback)(() => {
2002
+ const replaceAll = (0, import_react13.useCallback)(() => {
1918
2003
  if (matches.length === 0 || !notebook) return;
1919
2004
  const byCellId = /* @__PURE__ */ new Map();
1920
2005
  for (const m of matches) {
@@ -1933,7 +2018,7 @@ var FindReplace = ({ onClose }) => {
1933
2018
  engine.updateCellSource(cellId, src);
1934
2019
  }
1935
2020
  }, [matches, replacement, notebook, engine]);
1936
- const handleKeyDown = (0, import_react12.useCallback)((e) => {
2021
+ const handleKeyDown = (0, import_react13.useCallback)((e) => {
1937
2022
  if (e.key === "Escape") {
1938
2023
  e.preventDefault();
1939
2024
  onClose();
@@ -1946,21 +2031,21 @@ var FindReplace = ({ onClose }) => {
1946
2031
  setShowReplace((v) => !v);
1947
2032
  }
1948
2033
  }, [onClose, goNext, goPrev]);
1949
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "sci-nb-find-bar", onKeyDown: handleKeyDown, children: [
1950
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2034
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "sci-nb-find-bar", onKeyDown: handleKeyDown, children: [
2035
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1951
2036
  "input",
1952
2037
  {
1953
2038
  ref: inputRef,
1954
2039
  type: "text",
1955
2040
  value: query,
1956
2041
  onChange: (e) => setQuery(e.target.value),
1957
- placeholder: "Buscar..."
2042
+ placeholder: "Search..."
1958
2043
  }
1959
2044
  ),
1960
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "sci-nb-find-count", children: matches.length > 0 ? `${currentIdx + 1}/${matches.length}` : query ? "0" : "" }),
1961
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { onClick: goPrev, title: "Anterior (Shift+Enter)", children: "\u25B2" }),
1962
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { onClick: goNext, title: "Siguiente (Enter)", children: "\u25BC" }),
1963
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2045
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "sci-nb-find-count", children: matches.length > 0 ? `${currentIdx + 1}/${matches.length}` : query ? "0" : "" }),
2046
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { onClick: goPrev, title: "Previous (Shift+Enter)", children: "\u25B2" }),
2047
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { onClick: goNext, title: "Next (Enter)", children: "\u25BC" }),
2048
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1964
2049
  "button",
1965
2050
  {
1966
2051
  onClick: () => setCaseSensitive((v) => !v),
@@ -1969,29 +2054,29 @@ var FindReplace = ({ onClose }) => {
1969
2054
  children: "Aa"
1970
2055
  }
1971
2056
  ),
1972
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("button", { onClick: () => setShowReplace((v) => !v), title: "Reemplazar (Ctrl+H)", children: [
2057
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("button", { onClick: () => setShowReplace((v) => !v), title: "Replace (Ctrl+H)", children: [
1973
2058
  showReplace ? "\u25BE" : "\u25B8",
1974
- " Reemplazar"
2059
+ " Replace"
1975
2060
  ] }),
1976
- showReplace && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
1977
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2061
+ showReplace && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
2062
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1978
2063
  "input",
1979
2064
  {
1980
2065
  type: "text",
1981
2066
  value: replacement,
1982
2067
  onChange: (e) => setReplacement(e.target.value),
1983
- placeholder: "Reemplazar con..."
2068
+ placeholder: "Replace with..."
1984
2069
  }
1985
2070
  ),
1986
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { onClick: replaceCurrent, title: "Reemplazar actual", children: "1" }),
1987
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { onClick: replaceAll, title: "Reemplazar todos", children: "\u2200" })
2071
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { onClick: replaceCurrent, title: "Replace current", children: "1" }),
2072
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { onClick: replaceAll, title: "Replace all", children: "\u2200" })
1988
2073
  ] }),
1989
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { onClick: onClose, title: "Cerrar (Esc)", children: "\u2715" })
2074
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { onClick: onClose, title: "Close (Esc)", children: "\u2715" })
1990
2075
  ] });
1991
2076
  };
1992
2077
 
1993
2078
  // src/components/SciNotebook.tsx
1994
- var import_jsx_runtime13 = require("react/jsx-runtime");
2079
+ var import_jsx_runtime15 = require("react/jsx-runtime");
1995
2080
  var SciNotebook = ({
1996
2081
  notebook: initialNotebook,
1997
2082
  engine: providedEngine,
@@ -2007,7 +2092,7 @@ var SciNotebook = ({
2007
2092
  engineRef,
2008
2093
  showTOC: showTOCProp = false
2009
2094
  }) => {
2010
- const engine = (0, import_react13.useMemo)(() => {
2095
+ const engine = (0, import_react14.useMemo)(() => {
2011
2096
  if (providedEngine) return providedEngine;
2012
2097
  if (initialContent && !initialNotebook) {
2013
2098
  const cells2 = parseInitialContent(initialContent);
@@ -2026,37 +2111,37 @@ var SciNotebook = ({
2026
2111
  }
2027
2112
  return (0, import_notebook_core.createNotebook)({ notebook: initialNotebook, config: { plugins } });
2028
2113
  }, [providedEngine]);
2029
- (0, import_react13.useEffect)(() => {
2114
+ (0, import_react14.useEffect)(() => {
2030
2115
  if (engineRef) engineRef.current = engine;
2031
2116
  return () => {
2032
2117
  if (engineRef) engineRef.current = null;
2033
2118
  };
2034
2119
  }, [engine, engineRef]);
2035
- const [notebook, setNotebook] = (0, import_react13.useState)(initialNotebook || engine.getNotebook());
2036
- (0, import_react13.useEffect)(() => {
2120
+ const [notebook, setNotebook] = (0, import_react14.useState)(initialNotebook || engine.getNotebook());
2121
+ (0, import_react14.useEffect)(() => {
2037
2122
  const unsub = engine.on("notebook:updated", (payload) => {
2038
2123
  setNotebook(payload.data.notebook);
2039
2124
  if (onChange) onChange(payload.data.notebook);
2040
2125
  });
2041
2126
  return unsub;
2042
2127
  }, [engine, onChange]);
2043
- (0, import_react13.useEffect)(() => {
2128
+ (0, import_react14.useEffect)(() => {
2044
2129
  if (!onCellFocus) return;
2045
2130
  return engine.on("cell:focused", (payload) => {
2046
2131
  onCellFocus(payload.data.cellId);
2047
2132
  });
2048
2133
  }, [engine, onCellFocus]);
2049
- const pipeline = (0, import_react13.useMemo)(() => new import_notebook_renderer.RenderPipeline(), []);
2134
+ const pipeline = (0, import_react14.useMemo)(() => new import_notebook_renderer2.RenderPipeline(), []);
2050
2135
  const cells = notebook.cells;
2051
- const [showFind, setShowFind] = (0, import_react13.useState)(false);
2052
- const [showTOC, setShowTOC] = (0, import_react13.useState)(showTOCProp);
2053
- const [focusedCellId, setFocusedCellId] = (0, import_react13.useState)(null);
2054
- (0, import_react13.useEffect)(() => {
2136
+ const [showFind, setShowFind] = (0, import_react14.useState)(false);
2137
+ const [showTOC, setShowTOC] = (0, import_react14.useState)(showTOCProp);
2138
+ const [focusedCellId, setFocusedCellId] = (0, import_react14.useState)(null);
2139
+ (0, import_react14.useEffect)(() => {
2055
2140
  return engine.on("cell:focused", (payload) => {
2056
2141
  setFocusedCellId(payload.data.cellId);
2057
2142
  });
2058
2143
  }, [engine]);
2059
- const handleGlobalKeyDown = (0, import_react13.useCallback)((e) => {
2144
+ const handleGlobalKeyDown = (0, import_react14.useCallback)((e) => {
2060
2145
  if (readOnly) return;
2061
2146
  if ((e.ctrlKey || e.metaKey) && e.key === "f") {
2062
2147
  e.preventDefault();
@@ -2065,7 +2150,7 @@ var SciNotebook = ({
2065
2150
  }
2066
2151
  engine.handleKeyDown(e.nativeEvent);
2067
2152
  }, [engine, readOnly]);
2068
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(NotebookContext.Provider, { value: engine, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
2153
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(NotebookContext.Provider, { value: engine, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
2069
2154
  "div",
2070
2155
  {
2071
2156
  className: `sci-nb ${className || ""}`,
@@ -2074,10 +2159,10 @@ var SciNotebook = ({
2074
2159
  onKeyDown: handleGlobalKeyDown,
2075
2160
  tabIndex: 0,
2076
2161
  children: [
2077
- showToolbar && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "sci-nb-toolbar", children: [
2078
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "sci-nb-toolbar-group", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "sci-nb-toolbar-title", children: notebook.title }) }),
2079
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "sci-nb-toolbar-group", children: [
2080
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
2162
+ showToolbar && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "sci-nb-toolbar", children: [
2163
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "sci-nb-toolbar-group", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "sci-nb-toolbar-title", children: notebook.title }) }),
2164
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "sci-nb-toolbar-group", children: [
2165
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
2081
2166
  "button",
2082
2167
  {
2083
2168
  className: "sci-nb-toolbar-btn",
@@ -2085,12 +2170,12 @@ var SciNotebook = ({
2085
2170
  disabled: !engine.canUndo(),
2086
2171
  title: "Undo (Ctrl+Z)",
2087
2172
  children: [
2088
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M3 7h6a3 3 0 010 6H7M3 7l3-3M3 7l3 3", strokeLinecap: "round", strokeLinejoin: "round" }) }),
2173
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("path", { d: "M3 7h6a3 3 0 010 6H7M3 7l3-3M3 7l3 3", strokeLinecap: "round", strokeLinejoin: "round" }) }),
2089
2174
  "Undo"
2090
2175
  ]
2091
2176
  }
2092
2177
  ),
2093
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
2178
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
2094
2179
  "button",
2095
2180
  {
2096
2181
  className: "sci-nb-toolbar-btn",
@@ -2099,12 +2184,12 @@ var SciNotebook = ({
2099
2184
  title: "Redo (Ctrl+Shift+Z)",
2100
2185
  children: [
2101
2186
  "Redo",
2102
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M11 7H5a3 3 0 000 6h2M11 7l-3-3M11 7l-3 3", strokeLinecap: "round", strokeLinejoin: "round" }) })
2187
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("path", { d: "M11 7H5a3 3 0 000 6h2M11 7l-3-3M11 7l-3 3", strokeLinecap: "round", strokeLinejoin: "round" }) })
2103
2188
  ]
2104
2189
  }
2105
2190
  ),
2106
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "sci-nb-toolbar-sep" }),
2107
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2191
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "sci-nb-toolbar-sep" }),
2192
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2108
2193
  "button",
2109
2194
  {
2110
2195
  className: "sci-nb-toolbar-btn",
@@ -2113,7 +2198,7 @@ var SciNotebook = ({
2113
2198
  children: "Edit All"
2114
2199
  }
2115
2200
  ),
2116
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2201
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2117
2202
  "button",
2118
2203
  {
2119
2204
  className: "sci-nb-toolbar-btn",
@@ -2122,17 +2207,17 @@ var SciNotebook = ({
2122
2207
  children: "View All"
2123
2208
  }
2124
2209
  ),
2125
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "sci-nb-toolbar-sep" }),
2126
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2210
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "sci-nb-toolbar-sep" }),
2211
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2127
2212
  "button",
2128
2213
  {
2129
2214
  className: "sci-nb-toolbar-btn",
2130
2215
  onClick: () => setShowFind((v) => !v),
2131
2216
  title: "Find & Replace (Ctrl+F)",
2132
- children: "Buscar"
2217
+ children: "Find"
2133
2218
  }
2134
2219
  ),
2135
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2220
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2136
2221
  "button",
2137
2222
  {
2138
2223
  className: `sci-nb-toolbar-btn ${showTOC ? "sci-nb-toolbar-btn--active" : ""}`,
@@ -2143,23 +2228,23 @@ var SciNotebook = ({
2143
2228
  )
2144
2229
  ] })
2145
2230
  ] }),
2146
- showFind && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(FindReplace, { onClose: () => setShowFind(false) }),
2147
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "sci-nb-layout", style: { display: "flex", gap: 16 }, children: [
2148
- showTOC && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(TOCSidebar, { focusedCellId }),
2149
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "sci-nb-cells", style: { flex: 1 }, children: [
2150
- cells.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "sci-nb-empty", children: [
2151
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "sci-nb-empty-icon", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("svg", { width: "48", height: "48", viewBox: "0 0 48 48", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: [
2152
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("rect", { x: "8", y: "6", width: "32", height: "36", rx: "4" }),
2153
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("line", { x1: "14", y1: "14", x2: "34", y2: "14" }),
2154
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("line", { x1: "14", y1: "22", x2: "28", y2: "22" }),
2155
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("line", { x1: "14", y1: "30", x2: "22", y2: "30" })
2231
+ showFind && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(FindReplace, { onClose: () => setShowFind(false) }),
2232
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "sci-nb-layout", style: { display: "flex", gap: 16 }, children: [
2233
+ showTOC && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TOCSidebar, { focusedCellId }),
2234
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "sci-nb-cells", style: { flex: 1 }, children: [
2235
+ cells.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "sci-nb-empty", children: [
2236
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "sci-nb-empty-icon", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("svg", { width: "48", height: "48", viewBox: "0 0 48 48", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: [
2237
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("rect", { x: "8", y: "6", width: "32", height: "36", rx: "4" }),
2238
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("line", { x1: "14", y1: "14", x2: "34", y2: "14" }),
2239
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("line", { x1: "14", y1: "22", x2: "28", y2: "22" }),
2240
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("line", { x1: "14", y1: "30", x2: "22", y2: "30" })
2156
2241
  ] }) }),
2157
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { children: "Notebook vacio. Agrega una celda para comenzar." }),
2158
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(InsertHandle, { index: 0 })
2242
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { children: "Empty notebook. Add a cell to get started." }),
2243
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(InsertHandle, { index: 0 })
2159
2244
  ] }),
2160
- cells.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(InsertHandle, { index: 0 }),
2161
- cells.map((cell, idx) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_react13.default.Fragment, { children: [
2162
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2245
+ cells.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(InsertHandle, { index: 0 }),
2246
+ cells.map((cell, idx) => /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_react14.default.Fragment, { children: [
2247
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2163
2248
  Cell,
2164
2249
  {
2165
2250
  cellId: cell.id,
@@ -2168,7 +2253,7 @@ var SciNotebook = ({
2168
2253
  totalCells: cells.length
2169
2254
  }
2170
2255
  ),
2171
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(InsertHandle, { index: idx + 1 })
2256
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(InsertHandle, { index: idx + 1 })
2172
2257
  ] }, cell.id))
2173
2258
  ] })
2174
2259
  ] })
@@ -2190,8 +2275,8 @@ function parseInitialContent(content) {
2190
2275
  }
2191
2276
 
2192
2277
  // src/components/LatexAutocomplete.tsx
2193
- var import_react14 = require("react");
2194
- var import_jsx_runtime14 = require("react/jsx-runtime");
2278
+ var import_react15 = require("react");
2279
+ var import_jsx_runtime16 = require("react/jsx-runtime");
2195
2280
  var LATEX_COMMANDS = [
2196
2281
  // Structures
2197
2282
  { cmd: "\\frac{}{}", desc: "Fracci\xF3n", category: "struct" },
@@ -2323,19 +2408,19 @@ var LatexAutocomplete = ({
2323
2408
  onSelect,
2324
2409
  onClose
2325
2410
  }) => {
2326
- const [selectedIndex, setSelectedIndex] = (0, import_react14.useState)(0);
2327
- const menuRef = (0, import_react14.useRef)(null);
2328
- const filtered = (0, import_react14.useMemo)(() => {
2411
+ const [selectedIndex, setSelectedIndex] = (0, import_react15.useState)(0);
2412
+ const menuRef = (0, import_react15.useRef)(null);
2413
+ const filtered = (0, import_react15.useMemo)(() => {
2329
2414
  if (!query) return LATEX_COMMANDS.slice(0, 12);
2330
2415
  const q = query.toLowerCase();
2331
2416
  return LATEX_COMMANDS.filter(
2332
2417
  (c) => c.cmd.toLowerCase().includes(q) || c.desc.toLowerCase().includes(q)
2333
2418
  ).slice(0, 10);
2334
2419
  }, [query]);
2335
- (0, import_react14.useEffect)(() => {
2420
+ (0, import_react15.useEffect)(() => {
2336
2421
  setSelectedIndex(0);
2337
2422
  }, [query]);
2338
- (0, import_react14.useEffect)(() => {
2423
+ (0, import_react15.useEffect)(() => {
2339
2424
  const handleKey = (e) => {
2340
2425
  if (e.key === "ArrowDown") {
2341
2426
  e.preventDefault();
@@ -2360,23 +2445,23 @@ var LatexAutocomplete = ({
2360
2445
  return () => document.removeEventListener("keydown", handleKey, true);
2361
2446
  }, [filtered, selectedIndex, onSelect, onClose]);
2362
2447
  if (filtered.length === 0) return null;
2363
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2448
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2364
2449
  "div",
2365
2450
  {
2366
2451
  ref: menuRef,
2367
2452
  className: "sci-nb-slash-menu",
2368
2453
  style: { top: position.top, left: position.left, minWidth: 220 },
2369
- children: filtered.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
2454
+ children: filtered.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
2370
2455
  "button",
2371
2456
  {
2372
2457
  className: `sci-nb-slash-item ${i === selectedIndex ? "sci-nb-slash-item--active" : ""}`,
2373
2458
  onMouseEnter: () => setSelectedIndex(i),
2374
2459
  onClick: () => onSelect(item.cmd),
2375
2460
  children: [
2376
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "sci-nb-slash-icon", style: { fontFamily: "monospace", fontSize: 11 }, children: item.desc.length <= 2 ? item.desc : item.cmd.slice(0, 4) }),
2377
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "sci-nb-slash-text", children: [
2378
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "sci-nb-slash-label", style: { fontFamily: "monospace", fontSize: 12 }, children: item.cmd }),
2379
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "sci-nb-slash-desc", children: item.desc })
2461
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "sci-nb-slash-icon", style: { fontFamily: "monospace", fontSize: 11 }, children: item.desc.length <= 2 ? item.desc : item.cmd.slice(0, 4) }),
2462
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "sci-nb-slash-text", children: [
2463
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "sci-nb-slash-label", style: { fontFamily: "monospace", fontSize: 12 }, children: item.cmd }),
2464
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "sci-nb-slash-desc", children: item.desc })
2380
2465
  ] })
2381
2466
  ]
2382
2467
  },
@@ -2387,15 +2472,15 @@ var LatexAutocomplete = ({
2387
2472
  };
2388
2473
 
2389
2474
  // src/components/GhostText.tsx
2390
- var import_react15 = require("react");
2391
- var import_jsx_runtime15 = require("react/jsx-runtime");
2475
+ var import_react16 = require("react");
2476
+ var import_jsx_runtime17 = require("react/jsx-runtime");
2392
2477
  var GhostText = ({
2393
2478
  text,
2394
2479
  textareaRef,
2395
2480
  onAccept,
2396
2481
  onDismiss
2397
2482
  }) => {
2398
- const handleKeyDown = (0, import_react15.useCallback)((e) => {
2483
+ const handleKeyDown = (0, import_react16.useCallback)((e) => {
2399
2484
  if (e.key === "Tab" && !e.shiftKey) {
2400
2485
  e.preventDefault();
2401
2486
  e.stopPropagation();
@@ -2405,7 +2490,7 @@ var GhostText = ({
2405
2490
  onDismiss();
2406
2491
  }
2407
2492
  }, [onAccept, onDismiss]);
2408
- (0, import_react15.useEffect)(() => {
2493
+ (0, import_react16.useEffect)(() => {
2409
2494
  const ta2 = textareaRef.current;
2410
2495
  if (!ta2) return;
2411
2496
  ta2.addEventListener("keydown", handleKeyDown, true);
@@ -2423,7 +2508,7 @@ var GhostText = ({
2423
2508
  const left = lines[lines.length - 1].length * charWidth;
2424
2509
  const firstLine = text.split("\n")[0];
2425
2510
  const hasMore = text.includes("\n");
2426
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
2511
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
2427
2512
  "div",
2428
2513
  {
2429
2514
  className: "sci-nb-ghost-text",
@@ -2441,15 +2526,15 @@ var GhostText = ({
2441
2526
  children: [
2442
2527
  firstLine,
2443
2528
  hasMore ? "..." : "",
2444
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { style: { fontSize: 10, opacity: 0.5, marginLeft: 8 }, children: "Tab \u21B9" })
2529
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { style: { fontSize: 10, opacity: 0.5, marginLeft: 8 }, children: "Tab \u21B9" })
2445
2530
  ]
2446
2531
  }
2447
2532
  );
2448
2533
  };
2449
2534
 
2450
2535
  // src/components/ChatSidebar.tsx
2451
- var import_react16 = require("react");
2452
- var import_jsx_runtime16 = require("react/jsx-runtime");
2536
+ var import_react17 = require("react");
2537
+ var import_jsx_runtime18 = require("react/jsx-runtime");
2453
2538
  var ChatSidebar = ({
2454
2539
  onSend,
2455
2540
  systemPrompt,
@@ -2457,23 +2542,23 @@ var ChatSidebar = ({
2457
2542
  onClose
2458
2543
  }) => {
2459
2544
  const engine = useSciNotebook();
2460
- const [messages, setMessages] = (0, import_react16.useState)(() => {
2545
+ const [messages, setMessages] = (0, import_react17.useState)(() => {
2461
2546
  if (systemPrompt) {
2462
2547
  return [{ role: "system", content: systemPrompt, timestamp: Date.now() }];
2463
2548
  }
2464
2549
  return [];
2465
2550
  });
2466
- const [input, setInput] = (0, import_react16.useState)("");
2467
- const [loading, setLoading] = (0, import_react16.useState)(false);
2468
- const messagesEndRef = (0, import_react16.useRef)(null);
2469
- const inputRef = (0, import_react16.useRef)(null);
2470
- (0, import_react16.useEffect)(() => {
2551
+ const [input, setInput] = (0, import_react17.useState)("");
2552
+ const [loading, setLoading] = (0, import_react17.useState)(false);
2553
+ const messagesEndRef = (0, import_react17.useRef)(null);
2554
+ const inputRef = (0, import_react17.useRef)(null);
2555
+ (0, import_react17.useEffect)(() => {
2471
2556
  messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
2472
2557
  }, [messages]);
2473
- (0, import_react16.useEffect)(() => {
2558
+ (0, import_react17.useEffect)(() => {
2474
2559
  inputRef.current?.focus();
2475
2560
  }, []);
2476
- const handleSend = (0, import_react16.useCallback)(async () => {
2561
+ const handleSend = (0, import_react17.useCallback)(async () => {
2477
2562
  const text = input.trim();
2478
2563
  if (!text || loading) return;
2479
2564
  const userMsg = { role: "user", content: text, timestamp: Date.now() };
@@ -2511,17 +2596,17 @@ var ChatSidebar = ({
2511
2596
  setLoading(false);
2512
2597
  }
2513
2598
  }, [input, messages, loading, onSend]);
2514
- const handleKeyDown = (0, import_react16.useCallback)((e) => {
2599
+ const handleKeyDown = (0, import_react17.useCallback)((e) => {
2515
2600
  if (e.key === "Enter" && !e.shiftKey) {
2516
2601
  e.preventDefault();
2517
2602
  handleSend();
2518
2603
  }
2519
2604
  }, [handleSend]);
2520
2605
  const visibleMessages = messages.filter((m) => m.role !== "system");
2521
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "sci-nb-chat-sidebar", children: [
2522
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "sci-nb-chat-header", children: [
2523
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { children: "AI Assistant" }),
2524
- onClose && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2606
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "sci-nb-chat-sidebar", children: [
2607
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "sci-nb-chat-header", children: [
2608
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { children: "AI Assistant" }),
2609
+ onClose && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2525
2610
  "button",
2526
2611
  {
2527
2612
  onClick: onClose,
@@ -2530,11 +2615,11 @@ var ChatSidebar = ({
2530
2615
  }
2531
2616
  )
2532
2617
  ] }),
2533
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "sci-nb-chat-messages", children: [
2534
- visibleMessages.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: { textAlign: "center", color: "#94a3b8", padding: 24 }, children: "Ask me anything about your notebook..." }),
2535
- visibleMessages.map((msg, i) => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: `sci-nb-chat-msg sci-nb-chat-msg--${msg.role}`, children: [
2536
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { children: msg.content }),
2537
- msg.role === "assistant" && onApply && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2618
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "sci-nb-chat-messages", children: [
2619
+ visibleMessages.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { textAlign: "center", color: "#94a3b8", padding: 24 }, children: "Ask me anything about your notebook..." }),
2620
+ visibleMessages.map((msg, i) => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: `sci-nb-chat-msg sci-nb-chat-msg--${msg.role}`, children: [
2621
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { children: msg.content }),
2622
+ msg.role === "assistant" && onApply && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2538
2623
  "button",
2539
2624
  {
2540
2625
  onClick: () => onApply(msg.content),
@@ -2551,11 +2636,11 @@ var ChatSidebar = ({
2551
2636
  }
2552
2637
  )
2553
2638
  ] }, i)),
2554
- loading && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "sci-nb-chat-msg sci-nb-chat-msg--assistant", style: { opacity: 0.6 }, children: "Thinking..." }),
2555
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { ref: messagesEndRef })
2639
+ loading && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "sci-nb-chat-msg sci-nb-chat-msg--assistant", style: { opacity: 0.6 }, children: "Thinking..." }),
2640
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { ref: messagesEndRef })
2556
2641
  ] }),
2557
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "sci-nb-chat-input", children: [
2558
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2642
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "sci-nb-chat-input", children: [
2643
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2559
2644
  "input",
2560
2645
  {
2561
2646
  ref: inputRef,
@@ -2567,14 +2652,14 @@ var ChatSidebar = ({
2567
2652
  disabled: loading
2568
2653
  }
2569
2654
  ),
2570
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { onClick: handleSend, disabled: loading || !input.trim(), children: "Send" })
2655
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("button", { onClick: handleSend, disabled: loading || !input.trim(), children: "Send" })
2571
2656
  ] })
2572
2657
  ] });
2573
2658
  };
2574
2659
 
2575
2660
  // src/components/ImageResize.tsx
2576
- var import_react17 = require("react");
2577
- var import_jsx_runtime17 = require("react/jsx-runtime");
2661
+ var import_react18 = require("react");
2662
+ var import_jsx_runtime19 = require("react/jsx-runtime");
2578
2663
  var ImageResize = ({
2579
2664
  src,
2580
2665
  alt = "",
@@ -2583,12 +2668,12 @@ var ImageResize = ({
2583
2668
  onResize,
2584
2669
  children
2585
2670
  }) => {
2586
- const containerRef = (0, import_react17.useRef)(null);
2587
- const imgRef = (0, import_react17.useRef)(null);
2588
- const [dragging, setDragging] = (0, import_react17.useState)(false);
2589
- const [width, setWidth] = (0, import_react17.useState)(null);
2590
- const startRef = (0, import_react17.useRef)({ x: 0, w: 0 });
2591
- const handleMouseDown = (0, import_react17.useCallback)((e) => {
2671
+ const containerRef = (0, import_react18.useRef)(null);
2672
+ const imgRef = (0, import_react18.useRef)(null);
2673
+ const [dragging, setDragging] = (0, import_react18.useState)(false);
2674
+ const [width, setWidth] = (0, import_react18.useState)(null);
2675
+ const startRef = (0, import_react18.useRef)({ x: 0, w: 0 });
2676
+ const handleMouseDown = (0, import_react18.useCallback)((e) => {
2592
2677
  e.preventDefault();
2593
2678
  e.stopPropagation();
2594
2679
  const img = imgRef.current;
@@ -2596,7 +2681,7 @@ var ImageResize = ({
2596
2681
  startRef.current = { x: e.clientX, w: img.offsetWidth };
2597
2682
  setDragging(true);
2598
2683
  }, []);
2599
- (0, import_react17.useEffect)(() => {
2684
+ (0, import_react18.useEffect)(() => {
2600
2685
  if (!dragging) return;
2601
2686
  const handleMouseMove = (e) => {
2602
2687
  const dx = e.clientX - startRef.current.x;
@@ -2624,8 +2709,8 @@ var ImageResize = ({
2624
2709
  position: "relative",
2625
2710
  display: "inline-block"
2626
2711
  };
2627
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { ref: containerRef, className: "sci-nb-image-resizable", style, children: [
2628
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2712
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { ref: containerRef, className: "sci-nb-image-resizable", style, children: [
2713
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2629
2714
  "img",
2630
2715
  {
2631
2716
  ref: imgRef,
@@ -2636,7 +2721,7 @@ var ImageResize = ({
2636
2721
  }
2637
2722
  ),
2638
2723
  children,
2639
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2724
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2640
2725
  "div",
2641
2726
  {
2642
2727
  className: "sci-nb-image-resize-handle sci-nb-image-resize-handle--se",
@@ -2647,28 +2732,28 @@ var ImageResize = ({
2647
2732
  };
2648
2733
 
2649
2734
  // src/components/VirtualRenderer.tsx
2650
- var import_react18 = require("react");
2651
- var import_jsx_runtime18 = require("react/jsx-runtime");
2735
+ var import_react19 = require("react");
2736
+ var import_jsx_runtime20 = require("react/jsx-runtime");
2652
2737
  var VirtualRenderer = ({
2653
2738
  cells,
2654
2739
  pipeline,
2655
2740
  estimatedHeight = 120,
2656
2741
  overscan = 5
2657
2742
  }) => {
2658
- const containerRef = (0, import_react18.useRef)(null);
2659
- const [visibleRange, setVisibleRange] = (0, import_react18.useState)({ start: 0, end: 20 });
2660
- const cellHeights = (0, import_react18.useRef)(/* @__PURE__ */ new Map());
2661
- const getHeight = (0, import_react18.useCallback)((index) => {
2743
+ const containerRef = (0, import_react19.useRef)(null);
2744
+ const [visibleRange, setVisibleRange] = (0, import_react19.useState)({ start: 0, end: 20 });
2745
+ const cellHeights = (0, import_react19.useRef)(/* @__PURE__ */ new Map());
2746
+ const getHeight = (0, import_react19.useCallback)((index) => {
2662
2747
  return cellHeights.current.get(index) ?? estimatedHeight;
2663
2748
  }, [estimatedHeight]);
2664
- const totalHeight = (0, import_react18.useMemo)(() => {
2749
+ const totalHeight = (0, import_react19.useMemo)(() => {
2665
2750
  let h = 0;
2666
2751
  for (let i = 0; i < cells.length; i++) {
2667
2752
  h += getHeight(i) + 32;
2668
2753
  }
2669
2754
  return h;
2670
2755
  }, [cells.length, getHeight]);
2671
- (0, import_react18.useEffect)(() => {
2756
+ (0, import_react19.useEffect)(() => {
2672
2757
  const container = containerRef.current;
2673
2758
  if (!container) return;
2674
2759
  const handleScroll = () => {
@@ -2697,7 +2782,7 @@ var VirtualRenderer = ({
2697
2782
  container.addEventListener("scroll", handleScroll, { passive: true });
2698
2783
  return () => container.removeEventListener("scroll", handleScroll);
2699
2784
  }, [cells.length, getHeight, overscan]);
2700
- const measureRef = (0, import_react18.useCallback)((index) => {
2785
+ const measureRef = (0, import_react19.useCallback)((index) => {
2701
2786
  return (el) => {
2702
2787
  if (!el) return;
2703
2788
  const observer = new ResizeObserver((entries) => {
@@ -2711,7 +2796,7 @@ var VirtualRenderer = ({
2711
2796
  observer.observe(el);
2712
2797
  };
2713
2798
  }, []);
2714
- const topOffset = (0, import_react18.useMemo)(() => {
2799
+ const topOffset = (0, import_react19.useMemo)(() => {
2715
2800
  let h = 0;
2716
2801
  for (let i = 0; i < visibleRange.start; i++) {
2717
2802
  h += getHeight(i) + 32;
@@ -2719,18 +2804,18 @@ var VirtualRenderer = ({
2719
2804
  return h;
2720
2805
  }, [visibleRange.start, getHeight]);
2721
2806
  const visibleCells = cells.slice(visibleRange.start, visibleRange.end);
2722
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2807
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
2723
2808
  "div",
2724
2809
  {
2725
2810
  ref: containerRef,
2726
2811
  className: "sci-nb-virtual-container",
2727
2812
  style: { height: "100%", overflow: "auto", position: "relative" },
2728
- children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { height: totalHeight, position: "relative" }, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { position: "absolute", top: topOffset, left: 0, right: 0 }, children: [
2729
- visibleRange.start === 0 && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(InsertHandle, { index: 0 }),
2813
+ children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { height: totalHeight, position: "relative" }, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { position: "absolute", top: topOffset, left: 0, right: 0 }, children: [
2814
+ visibleRange.start === 0 && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(InsertHandle, { index: 0 }),
2730
2815
  visibleCells.map((cell, i) => {
2731
2816
  const realIndex = visibleRange.start + i;
2732
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { ref: measureRef(realIndex), children: [
2733
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2817
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { ref: measureRef(realIndex), children: [
2818
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
2734
2819
  Cell,
2735
2820
  {
2736
2821
  cellId: cell.id,
@@ -2739,7 +2824,7 @@ var VirtualRenderer = ({
2739
2824
  totalCells: cells.length
2740
2825
  }
2741
2826
  ),
2742
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(InsertHandle, { index: realIndex + 1 })
2827
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(InsertHandle, { index: realIndex + 1 })
2743
2828
  ] }, cell.id);
2744
2829
  })
2745
2830
  ] }) })
@@ -2748,8 +2833,8 @@ var VirtualRenderer = ({
2748
2833
  };
2749
2834
 
2750
2835
  // src/components/AIRewrite.tsx
2751
- var import_react19 = require("react");
2752
- var import_jsx_runtime19 = require("react/jsx-runtime");
2836
+ var import_react20 = require("react");
2837
+ var import_jsx_runtime21 = require("react/jsx-runtime");
2753
2838
  var AIRewrite = ({
2754
2839
  selectedText,
2755
2840
  position,
@@ -2757,15 +2842,15 @@ var AIRewrite = ({
2757
2842
  onAccept,
2758
2843
  onReject
2759
2844
  }) => {
2760
- const [state, setState] = (0, import_react19.useState)("prompt");
2761
- const [instruction, setInstruction] = (0, import_react19.useState)("");
2762
- const [result, setResult] = (0, import_react19.useState)("");
2763
- const [error, setError] = (0, import_react19.useState)(null);
2764
- const inputRef = (0, import_react19.useRef)(null);
2765
- (0, import_react19.useEffect)(() => {
2845
+ const [state, setState] = (0, import_react20.useState)("prompt");
2846
+ const [instruction, setInstruction] = (0, import_react20.useState)("");
2847
+ const [result, setResult] = (0, import_react20.useState)("");
2848
+ const [error, setError] = (0, import_react20.useState)(null);
2849
+ const inputRef = (0, import_react20.useRef)(null);
2850
+ (0, import_react20.useEffect)(() => {
2766
2851
  inputRef.current?.focus();
2767
2852
  }, []);
2768
- const handleSubmit = (0, import_react19.useCallback)(async () => {
2853
+ const handleSubmit = (0, import_react20.useCallback)(async () => {
2769
2854
  if (!instruction.trim()) return;
2770
2855
  setState("loading");
2771
2856
  setError(null);
@@ -2778,7 +2863,7 @@ var AIRewrite = ({
2778
2863
  setState("prompt");
2779
2864
  }
2780
2865
  }, [instruction, selectedText, onRewrite]);
2781
- const handleKeyDown = (0, import_react19.useCallback)((e) => {
2866
+ const handleKeyDown = (0, import_react20.useCallback)((e) => {
2782
2867
  if (e.key === "Enter" && !e.shiftKey) {
2783
2868
  e.preventDefault();
2784
2869
  handleSubmit();
@@ -2787,15 +2872,15 @@ var AIRewrite = ({
2787
2872
  onReject();
2788
2873
  }
2789
2874
  }, [handleSubmit, onReject]);
2790
- const handleAccept = (0, import_react19.useCallback)(() => {
2875
+ const handleAccept = (0, import_react20.useCallback)(() => {
2791
2876
  onAccept(result);
2792
2877
  }, [result, onAccept]);
2793
- const handleRetry = (0, import_react19.useCallback)(() => {
2878
+ const handleRetry = (0, import_react20.useCallback)(() => {
2794
2879
  setState("prompt");
2795
2880
  setResult("");
2796
2881
  inputRef.current?.focus();
2797
2882
  }, []);
2798
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
2883
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
2799
2884
  "div",
2800
2885
  {
2801
2886
  className: "sci-nb-ai-rewrite",
@@ -2806,13 +2891,13 @@ var AIRewrite = ({
2806
2891
  zIndex: 100
2807
2892
  },
2808
2893
  children: [
2809
- state === "prompt" && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "sci-nb-ai-rewrite-prompt", children: [
2810
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "sci-nb-ai-rewrite-selected", children: [
2811
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "sci-nb-ai-rewrite-label", children: "Selected:" }),
2812
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "sci-nb-ai-rewrite-text", children: selectedText.length > 80 ? selectedText.slice(0, 80) + "..." : selectedText })
2894
+ state === "prompt" && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "sci-nb-ai-rewrite-prompt", children: [
2895
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "sci-nb-ai-rewrite-selected", children: [
2896
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "sci-nb-ai-rewrite-label", children: "Selected:" }),
2897
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "sci-nb-ai-rewrite-text", children: selectedText.length > 80 ? selectedText.slice(0, 80) + "..." : selectedText })
2813
2898
  ] }),
2814
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "sci-nb-ai-rewrite-input-row", children: [
2815
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2899
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "sci-nb-ai-rewrite-input-row", children: [
2900
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2816
2901
  "input",
2817
2902
  {
2818
2903
  ref: inputRef,
@@ -2824,7 +2909,7 @@ var AIRewrite = ({
2824
2909
  className: "sci-nb-ai-rewrite-input"
2825
2910
  }
2826
2911
  ),
2827
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2912
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2828
2913
  "button",
2829
2914
  {
2830
2915
  onClick: handleSubmit,
@@ -2833,24 +2918,24 @@ var AIRewrite = ({
2833
2918
  children: "Rewrite"
2834
2919
  }
2835
2920
  ),
2836
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { onClick: onReject, className: "sci-nb-ai-rewrite-btn", children: "Cancel" })
2921
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: onReject, className: "sci-nb-ai-rewrite-btn", children: "Cancel" })
2837
2922
  ] }),
2838
- error && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "sci-nb-ai-rewrite-error", children: error })
2923
+ error && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "sci-nb-ai-rewrite-error", children: error })
2839
2924
  ] }),
2840
- state === "loading" && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "sci-nb-ai-rewrite-loading", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { children: "Rewriting..." }) }),
2841
- state === "preview" && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "sci-nb-ai-rewrite-preview", children: [
2842
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "sci-nb-ai-rewrite-diff", children: [
2843
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "sci-nb-ai-rewrite-diff-old", children: [
2844
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "sci-nb-ai-rewrite-diff-label", children: "Original:" }),
2845
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("pre", { children: selectedText })
2925
+ state === "loading" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "sci-nb-ai-rewrite-loading", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { children: "Rewriting..." }) }),
2926
+ state === "preview" && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "sci-nb-ai-rewrite-preview", children: [
2927
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "sci-nb-ai-rewrite-diff", children: [
2928
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "sci-nb-ai-rewrite-diff-old", children: [
2929
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "sci-nb-ai-rewrite-diff-label", children: "Original:" }),
2930
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("pre", { children: selectedText })
2846
2931
  ] }),
2847
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "sci-nb-ai-rewrite-diff-new", children: [
2848
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "sci-nb-ai-rewrite-diff-label", children: "Rewritten:" }),
2849
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("pre", { children: result })
2932
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "sci-nb-ai-rewrite-diff-new", children: [
2933
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "sci-nb-ai-rewrite-diff-label", children: "Rewritten:" }),
2934
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("pre", { children: result })
2850
2935
  ] })
2851
2936
  ] }),
2852
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "sci-nb-ai-rewrite-actions", children: [
2853
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2937
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "sci-nb-ai-rewrite-actions", children: [
2938
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2854
2939
  "button",
2855
2940
  {
2856
2941
  onClick: handleAccept,
@@ -2858,8 +2943,8 @@ var AIRewrite = ({
2858
2943
  children: "Accept"
2859
2944
  }
2860
2945
  ),
2861
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { onClick: handleRetry, className: "sci-nb-ai-rewrite-btn", children: "Retry" }),
2862
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { onClick: onReject, className: "sci-nb-ai-rewrite-btn", children: "Reject" })
2946
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: handleRetry, className: "sci-nb-ai-rewrite-btn", children: "Retry" }),
2947
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: onReject, className: "sci-nb-ai-rewrite-btn", children: "Reject" })
2863
2948
  ] })
2864
2949
  ] })
2865
2950
  ]
@@ -2868,22 +2953,22 @@ var AIRewrite = ({
2868
2953
  };
2869
2954
 
2870
2955
  // src/components/AICellGenerate.tsx
2871
- var import_react20 = require("react");
2872
- var import_jsx_runtime20 = require("react/jsx-runtime");
2956
+ var import_react21 = require("react");
2957
+ var import_jsx_runtime22 = require("react/jsx-runtime");
2873
2958
  var AICellGenerate = ({
2874
2959
  onGenerate,
2875
2960
  onAccept,
2876
2961
  onCancel
2877
2962
  }) => {
2878
- const [state, setState] = (0, import_react20.useState)("prompt");
2879
- const [prompt, setPrompt] = (0, import_react20.useState)("");
2880
- const [cells, setCells] = (0, import_react20.useState)([]);
2881
- const [error, setError] = (0, import_react20.useState)(null);
2882
- const inputRef = (0, import_react20.useRef)(null);
2883
- (0, import_react20.useEffect)(() => {
2963
+ const [state, setState] = (0, import_react21.useState)("prompt");
2964
+ const [prompt, setPrompt] = (0, import_react21.useState)("");
2965
+ const [cells, setCells] = (0, import_react21.useState)([]);
2966
+ const [error, setError] = (0, import_react21.useState)(null);
2967
+ const inputRef = (0, import_react21.useRef)(null);
2968
+ (0, import_react21.useEffect)(() => {
2884
2969
  inputRef.current?.focus();
2885
2970
  }, []);
2886
- const handleGenerate = (0, import_react20.useCallback)(async () => {
2971
+ const handleGenerate = (0, import_react21.useCallback)(async () => {
2887
2972
  if (!prompt.trim()) return;
2888
2973
  setState("loading");
2889
2974
  setError(null);
@@ -2896,7 +2981,7 @@ var AICellGenerate = ({
2896
2981
  setState("prompt");
2897
2982
  }
2898
2983
  }, [prompt, onGenerate]);
2899
- const handleKeyDown = (0, import_react20.useCallback)((e) => {
2984
+ const handleKeyDown = (0, import_react21.useCallback)((e) => {
2900
2985
  if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
2901
2986
  e.preventDefault();
2902
2987
  handleGenerate();
@@ -2905,10 +2990,10 @@ var AICellGenerate = ({
2905
2990
  onCancel();
2906
2991
  }
2907
2992
  }, [handleGenerate, onCancel]);
2908
- const handleAccept = (0, import_react20.useCallback)(() => {
2993
+ const handleAccept = (0, import_react21.useCallback)(() => {
2909
2994
  onAccept(cells);
2910
2995
  }, [cells, onAccept]);
2911
- const handleRegenerate = (0, import_react20.useCallback)(() => {
2996
+ const handleRegenerate = (0, import_react21.useCallback)(() => {
2912
2997
  setState("prompt");
2913
2998
  setCells([]);
2914
2999
  inputRef.current?.focus();
@@ -2921,13 +3006,13 @@ var AICellGenerate = ({
2921
3006
  mermaid: "Mermaid",
2922
3007
  raw: "Raw"
2923
3008
  };
2924
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "sci-nb-ai-generate", children: [
2925
- state === "prompt" && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "sci-nb-ai-generate-prompt", children: [
2926
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "sci-nb-ai-generate-header", children: [
2927
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("path", { d: "M8 1v14M1 8h14", strokeLinecap: "round" }) }),
2928
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { children: "Generate cells with AI" })
3009
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "sci-nb-ai-generate", children: [
3010
+ state === "prompt" && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "sci-nb-ai-generate-prompt", children: [
3011
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "sci-nb-ai-generate-header", children: [
3012
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("path", { d: "M8 1v14M1 8h14", strokeLinecap: "round" }) }),
3013
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { children: "Generate cells with AI" })
2929
3014
  ] }),
2930
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3015
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2931
3016
  "textarea",
2932
3017
  {
2933
3018
  ref: inputRef,
@@ -2939,8 +3024,8 @@ var AICellGenerate = ({
2939
3024
  rows: 3
2940
3025
  }
2941
3026
  ),
2942
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "sci-nb-ai-generate-actions", children: [
2943
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3027
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "sci-nb-ai-generate-actions", children: [
3028
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2944
3029
  "button",
2945
3030
  {
2946
3031
  onClick: handleGenerate,
@@ -2949,24 +3034,24 @@ var AICellGenerate = ({
2949
3034
  children: "Generate (Ctrl+Enter)"
2950
3035
  }
2951
3036
  ),
2952
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { onClick: onCancel, className: "sci-nb-ai-rewrite-btn", children: "Cancel" })
3037
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("button", { onClick: onCancel, className: "sci-nb-ai-rewrite-btn", children: "Cancel" })
2953
3038
  ] }),
2954
- error && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "sci-nb-ai-rewrite-error", children: error })
3039
+ error && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "sci-nb-ai-rewrite-error", children: error })
2955
3040
  ] }),
2956
- state === "loading" && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "sci-nb-ai-generate-loading", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { children: "Generating cells..." }) }),
2957
- state === "preview" && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "sci-nb-ai-generate-preview", children: [
2958
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "sci-nb-ai-generate-header", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { children: [
3041
+ state === "loading" && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "sci-nb-ai-generate-loading", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { children: "Generating cells..." }) }),
3042
+ state === "preview" && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "sci-nb-ai-generate-preview", children: [
3043
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "sci-nb-ai-generate-header", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("span", { children: [
2959
3044
  "Generated ",
2960
3045
  cells.length,
2961
3046
  " cell",
2962
3047
  cells.length !== 1 ? "s" : ""
2963
3048
  ] }) }),
2964
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "sci-nb-ai-generate-cells", children: cells.map((cell, i) => /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "sci-nb-ai-generate-cell", children: [
2965
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "sci-nb-ai-generate-cell-badge", children: CELL_TYPE_LABELS[cell.type] || cell.type }),
2966
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("pre", { className: "sci-nb-ai-generate-cell-source", children: cell.source.length > 200 ? cell.source.slice(0, 200) + "..." : cell.source })
3049
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "sci-nb-ai-generate-cells", children: cells.map((cell, i) => /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "sci-nb-ai-generate-cell", children: [
3050
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "sci-nb-ai-generate-cell-badge", children: CELL_TYPE_LABELS[cell.type] || cell.type }),
3051
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("pre", { className: "sci-nb-ai-generate-cell-source", children: cell.source.length > 200 ? cell.source.slice(0, 200) + "..." : cell.source })
2967
3052
  ] }, i)) }),
2968
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "sci-nb-ai-generate-actions", children: [
2969
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
3053
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "sci-nb-ai-generate-actions", children: [
3054
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
2970
3055
  "button",
2971
3056
  {
2972
3057
  onClick: handleAccept,
@@ -2979,8 +3064,8 @@ var AICellGenerate = ({
2979
3064
  ]
2980
3065
  }
2981
3066
  ),
2982
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { onClick: handleRegenerate, className: "sci-nb-ai-rewrite-btn", children: "Regenerate" }),
2983
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { onClick: onCancel, className: "sci-nb-ai-rewrite-btn", children: "Cancel" })
3067
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("button", { onClick: handleRegenerate, className: "sci-nb-ai-rewrite-btn", children: "Regenerate" }),
3068
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("button", { onClick: onCancel, className: "sci-nb-ai-rewrite-btn", children: "Cancel" })
2984
3069
  ] })
2985
3070
  ] })
2986
3071
  ] });