@bitcobblers/wod-wiki-ui 0.35.2115 → 0.35.2117

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.
@@ -7,6 +7,7 @@ var state = require('@codemirror/state');
7
7
  var lint = require('@codemirror/lint');
8
8
  var wodWikiLang = require('@bitcobblers/wod-wiki-lang');
9
9
  var wodWikiCore = require('@bitcobblers/wod-wiki-core');
10
+ var commands = require('@codemirror/commands');
10
11
  var wodWikiWql = require('@bitcobblers/wod-wiki-wql');
11
12
  var autocomplete = require('@codemirror/autocomplete');
12
13
  var client = require('react-dom/client');
@@ -18,7 +19,6 @@ var tailwindMerge = require('tailwind-merge');
18
19
  var recharts = require('recharts');
19
20
  var reactDom = require('react-dom');
20
21
  var server = require('react-dom/server');
21
- var commands = require('@codemirror/commands');
22
22
  var solid = require('@heroicons/react/20/solid');
23
23
  var common = require('@lezer/common');
24
24
  var lr = require('@lezer/lr');
@@ -386,255 +386,202 @@ var linkOpen = [
386
386
  ctrlClickPlugin,
387
387
  linkCursorTheme
388
388
  ];
389
- var VALID_DIALECTS = ["time", "log"];
389
+ var sectionIdentity = state.Facet.define({ combine: (values2) => values2[0] });
390
+ var registeredSectionWidgets = state.Facet.define({ combine: (values2) => values2.length ? values2.flat() : void 0 });
390
391
  var forceSectionParse = state.StateEffect.define();
391
- function generateSectionId(type, cmStartLine, content) {
392
- return wodWikiCore.generateSectionId(type, cmStartLine - 1, content);
393
- }
394
- function mapIdentities(oldSections, newSections) {
395
- return newSections.map((nSec) => {
396
- const match = oldSections.find(
397
- (oSec) => oSec.type === nSec.type && Math.abs(oSec.startLine - nSec.startLine) <= 2
398
- );
399
- return match ? { ...nSec, id: match.id } : nSec;
400
- });
401
- }
402
- function matchDialectFence(trimmed) {
403
- const match = wodWikiCore.matchDialectFence(trimmed);
404
- if (!match) return null;
405
- return { dialect: match.dialect, sport: match.sport };
406
- }
407
- function matchWidgetFence(trimmed) {
408
- const match = trimmed.match(/^```\s*widget:([\w-]+)\s*$/);
409
- return match ? match[1] : null;
410
- }
411
- function matchContentFence(trimmed) {
412
- const match = trimmed.match(/^```\s*query(?:[:\s](.*))?$/i);
413
- if (!match) return null;
414
- const rawSuffix = (match[1] ?? "").trim();
415
- if (rawSuffix === "") return { kind: "query" };
416
- const parsed = wodWikiWql.parseQueryWidgetSuffix(rawSuffix.replace(/^:/, ""));
417
- return {
418
- kind: "query",
419
- widgetType: parsed.type,
420
- widgetError: parsed.error
421
- };
422
- }
423
- function matchGenericFence(trimmed) {
424
- const match = trimmed.match(/^```\s*(\S+)\s*$/);
425
- if (!match) return null;
426
- const tag = match[1].toLowerCase();
427
- if (VALID_DIALECTS.includes(tag)) return null;
428
- if (tag.startsWith("widget:")) return null;
429
- if (tag.startsWith("query")) return null;
430
- return match[1];
431
- }
432
- function matchMarkdownEmbed(trimmed) {
433
- const imgMatch = trimmed.match(/^!\[([^\]]*)\]\(([^)]+)\)$/);
434
- if (imgMatch) {
435
- const label = imgMatch[1];
436
- const url = imgMatch[2];
437
- return { type: "image", url, label };
438
- }
439
- const linkMatch = trimmed.match(/^\[([^\]]+)\]\(([^)]+)\)$/);
440
- if (linkMatch) {
441
- const label = linkMatch[1];
442
- const url = linkMatch[2];
443
- return { type: "link", url, label };
392
+ var sectionSaved = state.StateEffect.define();
393
+ var sectionRestore = state.StateEffect.define();
394
+ var sectionMove = state.StateEffect.define();
395
+ var restoreHistoryIdentity = state.StateEffect.define({
396
+ map(value, changes) {
397
+ const blocks = {};
398
+ for (const block of Object.values(value.blocks)) {
399
+ const from = changes.mapPos(block.from, 1);
400
+ const to = changes.mapPos(block.to, -1);
401
+ if (from < to) blocks[block.id] = { ...block, from, to };
402
+ }
403
+ return { rawContent: value.rawContent, blocks };
444
404
  }
445
- return null;
405
+ });
406
+ function sourceCoordinates(rawContent) {
407
+ const rawStarts = [0];
408
+ const editorStarts = [0];
409
+ let removed = 0;
410
+ for (const match of rawContent.matchAll(/\r\n|\r|\n/g)) {
411
+ removed += match[0].length - 1;
412
+ rawStarts.push(match.index + match[0].length);
413
+ editorStarts.push(match.index + match[0].length - removed);
414
+ }
415
+ return { rawStarts, editorStarts };
416
+ }
417
+ function toSourcePosition(state, rawStarts, position) {
418
+ const line = state.doc.lineAt(position);
419
+ return rawStarts[line.number - 1] + position - line.from;
420
+ }
421
+ function toEditorBlocks(state) {
422
+ const blocks = {};
423
+ for (const block of Object.values(state.noteBlocks)) {
424
+ const section = state.sections.find((section2) => section2.id === block.id);
425
+ if (section) blocks[block.id] = { ...block, from: section.from, to: section.to };
426
+ }
427
+ return blocks;
428
+ }
429
+ function deriveState(state, rawContent, sourceRevision, lineage, savedVersions, previousSections = []) {
430
+ const registeredWidgets = state.facet(registeredSectionWidgets);
431
+ const noteBlocks = wodWikiCore.reconcileNoteBlocks(rawContent, { sourceRevision, blocks: lineage, registeredWidgets });
432
+ const coordinates = sourceCoordinates(rawContent);
433
+ const sections = wodWikiCore.parseDocumentSections(rawContent, { registeredWidgets }).map((section) => {
434
+ const start = coordinates.editorStarts[section.startLine];
435
+ const end = coordinates.editorStarts[section.endLine] + section.to - coordinates.rawStarts[section.endLine];
436
+ const block = wodWikiCore.actionableSectionKind(section) ? Object.values(noteBlocks).find((block2) => block2.from === section.from && block2.to === section.to) : void 0;
437
+ const prior = previousSections.find((prior2) => prior2.from === start && prior2.to === end && prior2.type === (section.type === "title" ? "markdown" : section.type));
438
+ const query = section.querySuffix ? wodWikiWql.parseQueryWidgetSuffix(section.querySuffix) : void 0;
439
+ const subtype = section.subtype;
440
+ return {
441
+ id: block?.id ?? prior?.id ?? section.id,
442
+ type: section.type === "title" ? "markdown" : section.type,
443
+ ...subtype === "heading" || subtype === "paragraph" || subtype === "list" || subtype === "blockquote" || subtype === "table" ? { subtype } : {},
444
+ from: start,
445
+ to: end,
446
+ startLine: section.startLine + 1,
447
+ endLine: section.endLine + 1,
448
+ ...section.contentFrom !== void 0 ? { contentFrom: coordinates.editorStarts[section.startLine + 1] ?? end } : {},
449
+ ...section.contentTo !== void 0 ? { contentTo: coordinates.editorStarts[section.endLine] - (section.type === "frontmatter" ? 1 : 0) } : {},
450
+ sport: section.sport,
451
+ widgetName: section.widgetName,
452
+ contentId: section.contentId,
453
+ queryType: query?.type,
454
+ queryError: query?.error,
455
+ embed: section.embed
456
+ };
457
+ });
458
+ for (const block of Object.values(noteBlocks)) block.version = savedVersions[block.id] ?? block.version;
459
+ return { sections, rawContent, sourceRevision, noteBlocks, savedVersions };
446
460
  }
447
- function detectMarkdownSubtype(lines) {
448
- const first = lines.find((l) => l.trim().length > 0)?.trim() ?? "";
449
- if (/^#{1,6}\s/.test(first)) return "heading";
450
- if (/^[-*+]\s|^\d+\.\s/.test(first)) return "list";
451
- if (/^>\s?/.test(first)) return "blockquote";
452
- if (first.startsWith("|") && lines.some((l) => /^\|[\s:]*-+/.test(l.trim()))) return "table";
453
- return "paragraph";
454
- }
455
- function scanFenced(state, openLineNum) {
456
- const openLine = state.doc.line(openLineNum);
457
- const contentFrom = openLine.to + 1;
458
- for (let i = openLineNum + 1; i <= state.doc.lines; i++) {
459
- const l = state.doc.line(i);
460
- if (l.text.trim().startsWith("```")) {
461
- return { closeLine: i, contentFrom, contentTo: l.from };
462
- }
463
- }
464
- const last = state.doc.line(state.doc.lines);
465
- return { closeLine: state.doc.lines, contentFrom, contentTo: last.to };
466
- }
467
- function parseSections(state) {
468
- const sections = [];
469
- let currentMdLines = [];
470
- let mdStartLine = 1;
471
- let mdStartPos = 0;
472
- function flushMarkdown(endLine, endPos) {
473
- if (currentMdLines.length === 0) return;
474
- const content = currentMdLines.join("\n");
475
- if (content.trim().length > 0) {
476
- const embed = currentMdLines.length === 1 ? matchMarkdownEmbed(content.trim()) : null;
477
- if (embed) {
478
- sections.push({
479
- id: generateSectionId("embed", mdStartLine, content),
480
- type: "embed",
481
- from: mdStartPos,
482
- to: endPos,
483
- startLine: mdStartLine,
484
- endLine,
485
- embed
486
- });
487
- } else {
488
- sections.push({
489
- id: generateSectionId("markdown", mdStartLine, content),
490
- type: "markdown",
491
- subtype: detectMarkdownSubtype(currentMdLines),
492
- from: mdStartPos,
493
- to: endPos,
494
- startLine: mdStartLine,
495
- endLine
496
- });
497
- }
498
- }
499
- currentMdLines = [];
500
- }
501
- let lineNum = 1;
502
- while (lineNum <= state.doc.lines) {
503
- const line = state.doc.line(lineNum);
504
- const trimmed = line.text.trim();
505
- const dialectMatch = matchDialectFence(trimmed);
506
- const widgetMatch = matchWidgetFence(trimmed);
507
- const contentMatch = matchContentFence(trimmed);
508
- const genericFence = matchGenericFence(trimmed);
509
- if (dialectMatch || widgetMatch || contentMatch || genericFence) {
510
- flushMarkdown(lineNum - 1, line.from);
511
- const { closeLine, contentFrom, contentTo } = scanFenced(state, lineNum);
512
- const closeLineObj = state.doc.line(closeLine);
513
- const innerContent = state.doc.sliceString(contentFrom, contentTo);
514
- if (dialectMatch) {
515
- sections.push({
516
- id: generateSectionId(dialectMatch.dialect, lineNum, innerContent),
517
- type: dialectMatch.dialect,
518
- from: line.from,
519
- to: closeLineObj.to,
520
- startLine: lineNum,
521
- endLine: closeLine,
522
- contentFrom,
523
- contentTo,
524
- sport: dialectMatch.sport,
525
- contentId: wodWikiCore.blockContentId(innerContent)
526
- });
527
- } else if (widgetMatch) {
528
- sections.push({
529
- id: generateSectionId("widget", lineNum, innerContent),
530
- type: "widget",
531
- widgetName: widgetMatch,
532
- from: line.from,
533
- to: closeLineObj.to,
534
- startLine: lineNum,
535
- endLine: closeLine,
536
- contentFrom,
537
- contentTo
538
- });
539
- } else if (contentMatch) {
540
- sections.push({
541
- id: generateSectionId("query", lineNum, innerContent),
542
- type: "query",
543
- from: line.from,
544
- to: closeLineObj.to,
545
- startLine: lineNum,
546
- endLine: closeLine,
547
- contentFrom,
548
- contentTo,
549
- queryType: contentMatch.widgetType,
550
- queryError: contentMatch.widgetError
551
- });
552
- } else if (genericFence) {
553
- sections.push({
554
- id: generateSectionId("code", lineNum, innerContent),
555
- type: "code",
556
- from: line.from,
557
- to: closeLineObj.to,
558
- startLine: lineNum,
559
- endLine: closeLine,
560
- contentFrom,
561
- contentTo
562
- });
563
- }
564
- lineNum = closeLine + 1;
565
- mdStartLine = lineNum;
566
- mdStartPos = lineNum <= state.doc.lines ? state.doc.line(lineNum).from : state.doc.length;
567
- continue;
568
- }
569
- if (trimmed === "---") {
570
- const lineCount = state.doc.lines;
571
- const nextLineText = lineNum < lineCount ? state.doc.line(lineNum + 1).text.trim() : "";
572
- if (nextLineText !== "") {
573
- let foundClose = false;
574
- let closeLine = lineNum;
575
- let hasKeyValueLine = false;
576
- for (let j = lineNum + 1; j <= lineCount; j++) {
577
- const jTrimmed = state.doc.line(j).text.trim();
578
- if (matchDialectFence(jTrimmed) || matchGenericFence(jTrimmed)) break;
579
- if (jTrimmed === "---") {
580
- closeLine = j;
581
- foundClose = true;
582
- break;
583
- }
584
- if (/^[A-Za-z_][\w-]*\s*:/.test(jTrimmed)) {
585
- hasKeyValueLine = true;
461
+ var sectionField = state.StateField.define({
462
+ create(state) {
463
+ const initial = state.facet(sectionIdentity);
464
+ const rawContent = initial?.rawContent ?? state.doc.toString();
465
+ if (rawContent.replace(/\r\n|\r/g, "\n") !== state.doc.toString()) throw new Error("Editor source and identity map disagree");
466
+ if (initial) wodWikiCore.validateNoteBlocks(rawContent, initial.blocks, initial.sourceRevision, { registeredWidgets: state.facet(registeredSectionWidgets) });
467
+ const savedVersions = Object.fromEntries(Object.values(initial?.blocks ?? {}).map((block) => [block.id, block.version]));
468
+ return deriveState(state, rawContent, initial?.sourceRevision ?? 1, initial?.blocks ?? {}, savedVersions);
469
+ },
470
+ update(value, tr) {
471
+ let rawContent = value.rawContent;
472
+ let lineage = value.noteBlocks;
473
+ let sourceRevision = value.sourceRevision;
474
+ let savedVersions = value.savedVersions;
475
+ if (tr.docChanged) {
476
+ const { rawStarts } = sourceCoordinates(rawContent);
477
+ const changes = [];
478
+ const lineBreak = rawContent.includes("\r\n") ? "\r\n" : rawContent.includes("\r") ? "\r" : "\n";
479
+ tr.changes.iterChanges((fromA, toA, fromB, toB) => changes.push({
480
+ from: toSourcePosition(tr.startState, rawStarts, fromA),
481
+ to: toSourcePosition(tr.startState, rawStarts, toA),
482
+ insert: tr.newDoc.sliceString(fromB, toB, lineBreak)
483
+ }));
484
+ lineage = wodWikiCore.mapNoteBlockChanges(lineage, changes);
485
+ for (let i = changes.length - 1; i >= 0; i--) {
486
+ const change = changes[i];
487
+ rawContent = rawContent.slice(0, change.from) + change.insert + rawContent.slice(change.to);
488
+ }
489
+ if (tr.isUserEvent("move.drop")) {
490
+ const moves = [];
491
+ tr.changes.iterChanges((fromA, toA, fromB, toB) => moves.push({ fromA, toA, fromB, toB }));
492
+ const deletion = moves.filter((change) => change.toA > change.fromA && change.fromB === change.toB);
493
+ const insertion = moves.filter((change) => change.fromA === change.toA && change.toB > change.fromB);
494
+ if (deletion.length === 1 && insertion.length === 1) {
495
+ const removed = deletion[0];
496
+ const added = insertion[0];
497
+ if (tr.startState.doc.sliceString(removed.fromA, removed.toA) === tr.newDoc.sliceString(added.fromB, added.toB)) {
498
+ const currentStarts = sourceCoordinates(rawContent).rawStarts;
499
+ for (const section of value.sections) {
500
+ const block = value.noteBlocks[section.id];
501
+ if (block && section.from >= removed.fromA && section.to <= removed.toA) {
502
+ lineage[block.id] = {
503
+ ...block,
504
+ from: toSourcePosition(tr.state, currentStarts, added.fromB + section.from - removed.fromA),
505
+ to: toSourcePosition(tr.state, currentStarts, added.fromB + section.to - removed.fromA)
506
+ };
507
+ }
508
+ }
586
509
  }
587
510
  }
588
- if (foundClose && hasKeyValueLine) {
589
- flushMarkdown(lineNum - 1, line.from);
590
- const closeLineObj = state.doc.line(closeLine);
591
- const content = state.doc.sliceString(line.from, closeLineObj.to);
592
- sections.push({
593
- id: generateSectionId("frontmatter", lineNum, content),
594
- type: "frontmatter",
595
- from: line.from,
596
- to: closeLineObj.to,
597
- startLine: lineNum,
598
- endLine: closeLine,
599
- contentFrom: line.to + 1,
600
- contentTo: closeLineObj.from - 1
601
- });
602
- lineNum = closeLine + 1;
603
- mdStartLine = lineNum;
604
- mdStartPos = lineNum <= lineCount ? state.doc.line(lineNum).from : state.doc.length;
605
- continue;
511
+ }
512
+ if (tr.isUserEvent("move.line")) {
513
+ const currentStarts = sourceCoordinates(rawContent).rawStarts;
514
+ for (let i = 0; i < tr.startState.selection.ranges.length; i++) {
515
+ const before = tr.startState.selection.ranges[i];
516
+ const after = tr.newSelection.ranges[i];
517
+ if (!after) continue;
518
+ const firstLine = tr.startState.doc.lineAt(before.from);
519
+ const lastLine = tr.startState.doc.lineAt(before.to > before.from && tr.startState.doc.lineAt(before.to).from === before.to ? before.to - 1 : before.to);
520
+ const delta = after.anchor - before.anchor;
521
+ for (const section of value.sections) {
522
+ const block = value.noteBlocks[section.id];
523
+ if (block && section.from >= firstLine.from && section.to <= lastLine.to) {
524
+ lineage[block.id] = {
525
+ ...block,
526
+ from: toSourcePosition(tr.state, currentStarts, section.from + delta),
527
+ to: toSourcePosition(tr.state, currentStarts, section.to + delta)
528
+ };
529
+ }
530
+ }
606
531
  }
607
532
  }
608
533
  }
609
- if (currentMdLines.length === 0) {
610
- mdStartLine = lineNum;
611
- mdStartPos = line.from;
612
- }
613
- currentMdLines.push(line.text);
614
- lineNum++;
615
- }
616
- flushMarkdown(state.doc.lines, state.doc.length);
617
- return sections;
618
- }
619
- var sectionField = state.StateField.define({
620
- create(state) {
621
- return { sections: parseSections(state) };
622
- },
623
- update(value, tr) {
624
- if (tr.docChanged || tr.effects.some((e) => e.is(forceSectionParse))) {
625
- const newSections = parseSections(tr.state);
626
- return { sections: mapIdentities(value.sections, newSections) };
534
+ for (const effect of tr.effects) {
535
+ if (effect.is(sectionSaved)) {
536
+ sourceRevision = Math.max(sourceRevision, effect.value.sourceRevision);
537
+ savedVersions = { ...savedVersions };
538
+ for (const block of Object.values(effect.value.blocks)) savedVersions[block.id] = Math.max(savedVersions[block.id] ?? 1, block.version);
539
+ }
540
+ if (effect.is(sectionRestore)) {
541
+ if (effect.value.rawContent.replace(/\r\n|\r/g, "\n") !== tr.newDoc.toString()) throw new Error("Restored source does not match editor");
542
+ wodWikiCore.validateNoteBlocks(effect.value.rawContent, effect.value.blocks, effect.value.sourceRevision, { registeredWidgets: tr.state.facet(registeredSectionWidgets) });
543
+ rawContent = effect.value.rawContent;
544
+ lineage = effect.value.blocks;
545
+ sourceRevision = effect.value.sourceRevision;
546
+ savedVersions = { ...savedVersions, ...Object.fromEntries(Object.values(lineage).map((block) => [block.id, block.version])) };
547
+ }
548
+ if (effect.is(restoreHistoryIdentity)) {
549
+ const exactHistory = tr.effects.some((candidate) => candidate.is(restoreHistoryIdentity) && candidate.value.rawContent.replace(/\r\n|\r/g, "\n") === tr.newDoc.toString());
550
+ if (exactHistory && effect.value.rawContent.replace(/\r\n|\r/g, "\n") !== tr.newDoc.toString()) continue;
551
+ if (effect.value.rawContent.replace(/\r\n|\r/g, "\n") === tr.newDoc.toString()) rawContent = effect.value.rawContent;
552
+ const { rawStarts } = sourceCoordinates(rawContent);
553
+ lineage = Object.fromEntries(Object.values(effect.value.blocks).map((block) => [block.id, {
554
+ ...block,
555
+ from: toSourcePosition(tr.state, rawStarts, block.from),
556
+ to: toSourcePosition(tr.state, rawStarts, block.to)
557
+ }]));
558
+ }
559
+ if (effect.is(sectionMove)) {
560
+ const prior = value.noteBlocks[effect.value.id];
561
+ if (!prior || lineage[prior.id]) throw new Error("Explicit move must remove the original occurrence");
562
+ const { rawStarts } = sourceCoordinates(rawContent);
563
+ const from = toSourcePosition(tr.state, rawStarts, effect.value.from);
564
+ const to = toSourcePosition(tr.state, rawStarts, effect.value.to);
565
+ if (rawContent.slice(from, to) !== value.rawContent.slice(prior.from, prior.to)) throw new Error("Explicit move changed source");
566
+ lineage = { ...lineage, [prior.id]: { ...prior, from, to } };
567
+ }
568
+ }
569
+ if (tr.docChanged || tr.effects.some((effect) => effect.is(forceSectionParse) || effect.is(sectionRestore) || effect.is(sectionSaved) || effect.is(restoreHistoryIdentity))) {
570
+ const previous = value.sections.map((section) => ({ ...section, from: tr.changes.mapPos(section.from, 1), to: tr.changes.mapPos(section.to, -1) }));
571
+ return deriveState(tr.state, rawContent, sourceRevision, lineage, savedVersions, previous);
627
572
  }
628
573
  return value;
629
574
  }
630
575
  });
576
+ var sectionIdentityHistory = commands.invertedEffects.of((tr) => {
577
+ const value = tr.startState.field(sectionField, false);
578
+ return value && tr.docChanged ? [restoreHistoryIdentity.of({ rawContent: value.rawContent, blocks: toEditorBlocks(value) })] : [];
579
+ });
631
580
  function sectionAtPos(state, pos) {
632
- const { sections } = state.field(sectionField);
633
- return sections.find((s) => pos >= s.from && pos <= s.to) ?? null;
581
+ return state.field(sectionField).sections.find((section) => pos >= section.from && pos <= section.to) ?? null;
634
582
  }
635
583
  function activeCursorSection(state) {
636
- const pos = state.selection.main.head;
637
- return sectionAtPos(state, pos);
584
+ return sectionAtPos(state, state.selection.main.head);
638
585
  }
639
586
 
640
587
  // src/extensions/whiteboard-linter.ts
@@ -2508,18 +2455,9 @@ function dispatchExpandRuntimePanel(view, sectionId, expanded) {
2508
2455
  function sessionQueryWql(resultId) {
2509
2456
  return `:session{result:${resultId}}`;
2510
2457
  }
2511
- function sessionQueryInsert(state, blockId, resultId, runBlock) {
2458
+ function sessionQueryInsert(state, blockId, resultId) {
2512
2459
  const sections = state.field(sectionField).sections;
2513
- let section = sections.find((s) => s.id === blockId);
2514
- if (!section && runBlock?.contentId) {
2515
- section = sections.find((s) => s.contentId === runBlock.contentId);
2516
- }
2517
- if (!section && runBlock?.id) {
2518
- section = sections.find((s) => s.id === runBlock.id);
2519
- }
2520
- if (!section && runBlock) {
2521
- section = sections.find((s) => s.type === "time" || s.type === "log");
2522
- }
2460
+ const section = sections.find((s) => s.id === blockId);
2523
2461
  if (!section || section.type !== "time" && section.type !== "log") {
2524
2462
  return null;
2525
2463
  }
@@ -4689,7 +4627,7 @@ var STATIC_OPTIONS = {
4689
4627
  unit: UNIT_OPTIONS,
4690
4628
  intensity: wodWikiWql.WQL_INTENSITY_TIERS.map((v) => ({ value: v, label: v }))
4691
4629
  };
4692
- var CANONICAL_BLOCK_TYPES = ["wod", "movement", "workout"];
4630
+ var CANONICAL_BLOCK_TYPES = ["wod", "query", "widget", "embed"];
4693
4631
  function canonicalSuggestionItems(values2) {
4694
4632
  return values2.map((value) => ({ value, label: value.charAt(0).toUpperCase() + value.slice(1) }));
4695
4633
  }
@@ -12204,6 +12142,7 @@ function editorPreset(optionsOrDialect = "markdown") {
12204
12142
  extensions.push(
12205
12143
  markdown({ codeLanguages: resolveCodeLanguage }),
12206
12144
  sectionField,
12145
+ sectionIdentityHistory,
12207
12146
  previewDecorations,
12208
12147
  wodLinter,
12209
12148
  wodAutocompletion,
@@ -12263,12 +12202,18 @@ exports.navigationFacet = navigationFacet;
12263
12202
  exports.previewDecorations = previewDecorations;
12264
12203
  exports.queryBlockPreview = queryBlockPreview;
12265
12204
  exports.registerCustomCompletionSource = registerCustomCompletionSource;
12205
+ exports.registeredSectionWidgets = registeredSectionWidgets;
12266
12206
  exports.removeRuntimePanel = removeRuntimePanel;
12267
12207
  exports.runtimePanelField = runtimePanelField;
12268
12208
  exports.saveBlockQuerySource = saveBlockQuerySource;
12269
12209
  exports.sectionAtPos = sectionAtPos;
12270
12210
  exports.sectionField = sectionField;
12271
12211
  exports.sectionGeometry = sectionGeometry;
12212
+ exports.sectionIdentity = sectionIdentity;
12213
+ exports.sectionIdentityHistory = sectionIdentityHistory;
12214
+ exports.sectionMove = sectionMove;
12215
+ exports.sectionRestore = sectionRestore;
12216
+ exports.sectionSaved = sectionSaved;
12272
12217
  exports.sessionQueryInsert = sessionQueryInsert;
12273
12218
  exports.sessionQueryWql = sessionQueryWql;
12274
12219
  exports.setGutterHighlights = setGutterHighlights;