@bendyline/squisq 2.3.2 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/dist/{Doc-BrgZC7SE.d.ts → Doc-DLpyOAXJ.d.ts} +87 -2
  2. package/dist/{ImageEditDoc-rum0Xb9P.d.ts → ImageEditDoc-Cu30xb9b.d.ts} +1 -1
  3. package/dist/{chunk-2ZWIXGAC.js → chunk-2S74DPJH.js} +4 -0
  4. package/dist/{chunk-ZQKZSJAX.js → chunk-2VCNTDNZ.js} +245 -0
  5. package/dist/{chunk-RS5AP3J4.js → chunk-AE3IUKMM.js} +1 -1
  6. package/dist/{chunk-QWCFK5FN.js → chunk-CUYHFOFL.js} +5 -1
  7. package/dist/{chunk-ACZOVWX3.js → chunk-D4LPP3P5.js} +44 -15
  8. package/dist/{chunk-CKZY6K5R.js → chunk-F2IEPSMA.js} +2565 -1143
  9. package/dist/{chunk-ZAFLMJPD.js → chunk-KPBZZVGY.js} +37 -7
  10. package/dist/{chunk-BCCXTMN5.js → chunk-O7JILDEF.js} +7 -0
  11. package/dist/{chunk-SPTY4C6F.js → chunk-REDUXXDJ.js} +1 -1
  12. package/dist/{chunk-BCHAXKKI.js → chunk-ZHLNKB2I.js} +1 -1
  13. package/dist/chunk-ZYO3DBTA.js +983 -0
  14. package/dist/doc/index.d.ts +111 -6
  15. package/dist/doc/index.js +11 -7
  16. package/dist/generate/index.d.ts +1 -1
  17. package/dist/imageEdit/index.d.ts +3 -3
  18. package/dist/index.d.ts +6 -6
  19. package/dist/index.js +34 -14
  20. package/dist/jsonForm/index.d.ts +1 -1
  21. package/dist/jsonForm/index.js +2 -2
  22. package/dist/markdown/index.d.ts +118 -1
  23. package/dist/markdown/index.js +24 -8
  24. package/dist/{materializePageSection-DAbyLi-k.d.ts → materializePageSection-CgNs5Qmw.d.ts} +4 -2
  25. package/dist/narration/index.d.ts +1 -1
  26. package/dist/narration/index.js +5 -5
  27. package/dist/recommend/index.js +2 -2
  28. package/dist/schemas/index.d.ts +4 -4
  29. package/dist/schemas/index.js +2 -2
  30. package/dist/{themeLibrary-DJt89gyP.d.ts → themeLibrary-RWsNtlOu.d.ts} +1 -1
  31. package/dist/transform/index.d.ts +2 -2
  32. package/dist/transform/index.js +2 -2
  33. package/package.json +1 -1
  34. package/dist/chunk-3IGPAPQ7.js +0 -645
@@ -17,6 +17,14 @@ import { a0 as Transition, a2 as TransitionType, M as MarkdownBlockNode, r as Ma
17
17
  * `doc.documentMedia` clip that spans the whole timeline.
18
18
  */
19
19
 
20
+ /**
21
+ * How an authored video participates in the composed document frame.
22
+ *
23
+ * `content` videos remain in the block body and are laid out by the block
24
+ * template. The other placements are scheduled player-level video and sit
25
+ * above the composed slide.
26
+ */
27
+ type VideoPlacement = 'content' | 'picture-in-picture' | 'overlay';
20
28
  /**
21
29
  * A timed piece of media attached to a block (or the document).
22
30
  */
@@ -26,6 +34,14 @@ interface MediaClip {
26
34
  /** Source path (mp3/mp4/…), relative to the article media dir. */
27
35
  src: string;
28
36
  kind: 'audio' | 'video';
37
+ /** Per-video placement. Omitted audio and legacy video use player defaults. */
38
+ placement?: Exclude<VideoPlacement, 'content'>;
39
+ /**
40
+ * Whether a placed video is locked to its owning block's timeline span.
41
+ * `true` clips start with and are capped by the block. `false` clips are
42
+ * document-timed and may cross block boundaries. Omitted for legacy media.
43
+ */
44
+ lockToBlock?: boolean;
29
45
  /**
30
46
  * Seconds from the parent block's start when this clip begins. For an
31
47
  * `anchor='document'` clip, seconds from the document start. Default 0.
@@ -64,6 +80,8 @@ interface MediaClip {
64
80
  blockId: string;
65
81
  index: number;
66
82
  raw?: string;
83
+ /** Raw authoring form; omitted means a squiggly media annotation. */
84
+ format?: 'html';
67
85
  };
68
86
  }
69
87
  /**
@@ -75,6 +93,10 @@ interface ScheduledClip {
75
93
  id: string;
76
94
  src: string;
77
95
  kind: 'audio' | 'video';
96
+ /** Per-video placement carried through to the player-level compositor. */
97
+ placement?: Exclude<VideoPlacement, 'content'>;
98
+ /** Authored placed-video lock state, when applicable. */
99
+ lockToBlock?: boolean;
78
100
  /** Absolute doc-timeline second the clip starts. */
79
101
  absoluteStart: number;
80
102
  /** Absolute doc-timeline second the clip ends (exclusive). */
@@ -939,10 +961,73 @@ interface DataTableInput extends BaseTemplateBlock {
939
961
  /** Color scheme for the table header */
940
962
  colorScheme?: ColorScheme;
941
963
  }
964
+ /**
965
+ * Fields shared by every chart template. Chart data normally arrives from
966
+ * the first markdown table in the block body (derived at materialize time);
967
+ * `headers`/`rows` may also be supplied via a ```json data fence. Column
968
+ * roles reference headers by name (case-insensitive) or 0-based index.
969
+ * A chart block with no chartable table renders as ordinary content.
970
+ */
971
+ interface ChartBaseFields {
972
+ /** Optional title displayed above the chart */
973
+ title?: string;
974
+ /** Header cells (normally derived from the block's markdown table) */
975
+ headers?: string[];
976
+ /** Data rows (normally derived from the block's markdown table) */
977
+ rows?: string[][];
978
+ /** Category/label column — header name or 0-based index. Default: first column. */
979
+ labelColumn?: string;
980
+ /** Value columns — header names or 0-based indexes. Default: all numeric columns. */
981
+ valueColumns?: string[];
982
+ /** Render the source table beneath the chart */
983
+ showTable?: boolean;
984
+ /** Show a series legend (default: on whenever it adds information) */
985
+ showLegend?: boolean;
986
+ /** Print numeric value labels on marks */
987
+ showValues?: boolean;
988
+ /** Unit suffix for tick/value labels (e.g. "km") */
989
+ unit?: string;
990
+ /** Color scheme seeding the series color rotation */
991
+ colorScheme?: ColorScheme;
992
+ }
993
+ /** Horizontal bars — one bar (or bar group) per table row. */
994
+ interface BarChartInput extends BaseTemplateBlock, ChartBaseFields {
995
+ template: 'barChart';
996
+ /** Stack series instead of grouping them side by side */
997
+ stacked?: boolean;
998
+ }
999
+ /** Vertical columns — one column (or column group) per table row. */
1000
+ interface ColumnChartInput extends BaseTemplateBlock, ChartBaseFields {
1001
+ template: 'columnChart';
1002
+ /** Stack series instead of grouping them side by side */
1003
+ stacked?: boolean;
1004
+ }
1005
+ /** Pie chart of the first value column (positive values only). */
1006
+ interface PieChartInput extends BaseTemplateBlock, ChartBaseFields {
1007
+ template: 'pieChart';
1008
+ }
1009
+ /** Donut chart of the first value column (positive values only). */
1010
+ interface DonutChartInput extends BaseTemplateBlock, ChartBaseFields {
1011
+ template: 'donutChart';
1012
+ }
1013
+ /** Line chart — one line per value column; unparseable cells become gaps. */
1014
+ interface LineChartInput extends BaseTemplateBlock, ChartBaseFields {
1015
+ template: 'lineChart';
1016
+ }
1017
+ /** Area chart — filled lines, zero-based value axis. */
1018
+ interface AreaChartInput extends BaseTemplateBlock, ChartBaseFields {
1019
+ template: 'areaChart';
1020
+ }
1021
+ /** Scatter plot — numeric label column as x-axis (row index fallback). */
1022
+ interface ScatterChartInput extends BaseTemplateBlock, ChartBaseFields {
1023
+ template: 'scatterChart';
1024
+ }
1025
+ /** Union of the chart template inputs (all render through one shared engine). */
1026
+ type ChartTemplateInput = BarChartInput | ColumnChartInput | PieChartInput | DonutChartInput | LineChartInput | AreaChartInput | ScatterChartInput;
942
1027
  /**
943
1028
  * Union of all template block types.
944
1029
  */
945
- type TemplateBlock = TitleBlockInput | SectionHeaderInput | ContentBlockInput | StatHighlightInput | QuoteBlockInput | FactCardInput | TwoColumnInput | DateEventInput | ImageWithCaptionInput | LeftFeatureInput | RightFeatureInput | MapBlockInput | FullBleedQuoteInput | ListBlockInput | PhotoGridInput | DefinitionCardInput | ComparisonBarInput | PullQuoteInput | VideoWithCaptionInput | VideoPullQuoteInput | DataTableInput | DiagramBlockInput | TreeBlockInput | TimelineBlockInput | DrawingBlockInput | RawLayersInput;
1030
+ type TemplateBlock = TitleBlockInput | SectionHeaderInput | ContentBlockInput | StatHighlightInput | QuoteBlockInput | FactCardInput | TwoColumnInput | DateEventInput | ImageWithCaptionInput | LeftFeatureInput | RightFeatureInput | MapBlockInput | FullBleedQuoteInput | ListBlockInput | PhotoGridInput | DefinitionCardInput | ComparisonBarInput | PullQuoteInput | VideoWithCaptionInput | VideoPullQuoteInput | DataTableInput | BarChartInput | ColumnChartInput | PieChartInput | DonutChartInput | LineChartInput | AreaChartInput | ScatterChartInput | DiagramBlockInput | TreeBlockInput | TimelineBlockInput | DrawingBlockInput | RawLayersInput;
946
1031
  /**
947
1032
  * A block can be either a raw Block or a TemplateBlock.
948
1033
  */
@@ -2557,4 +2642,4 @@ declare function getBlockAtTime(blocks: Block[], time: number): Block | null;
2557
2642
  */
2558
2643
  declare function getCaptionAtTime(captions: CaptionTrack | undefined, time: number): CaptionPhrase | null;
2559
2644
 
2560
- export { type ListBlockInput as $, type AccentImage as A, type Block as B, type CaptionPhrase as C, DARK_SURFACE as D, type DiagramTemplateEdge as E, type DiagramTemplateNode as F, type Doc as G, type DocBlock as H, type DocDiagnostic as I, type DrawingBlockInput as J, FRONTMATTER_CUSTOM_TEMPLATES_KEY as K, FRONTMATTER_CUSTOM_THEMES_KEY as L, type FactCardInput as M, type FontFamily as N, type FontFamilyKind as O, type FullBleedQuoteInput as P, type GradientBackgroundConfig as Q, type ImageBackgroundConfig as R, type ImageLayer as S, type ImageTreatment as T, type ImageWithCaptionInput as U, LIGHT_SURFACE as V, type Layer as W, type LayerRepeat as X, type LayoutHints as Y, type LeftFeatureInput as Z, type LinearGradient as _, type AccentPosition as a, type TemplateRegistry as a$, type MapBlockInput as a0, type MapLayer as a1, type MapMarker as a2, type MapTileStyle as a3, type MarkerStyle as a4, type MediaClip as a5, type MermaidLayer as a6, PAGE_ACCENT_STRATEGIES as a7, PAGE_BACKGROUNDS as a8, PAGE_BACKGROUND_RHYTHMS as a9, type PersistentLayerConfig as aA, type PersistentLayerTemplate as aB, type PersistentLayerTemplateConfig as aC, type PersistentLayerTemplateType as aD, type PhotoGridInput as aE, type Position as aF, type ProgressIndicatorConfig as aG, type PullQuoteInput as aH, type QuoteBlockInput as aI, type RawLayersInput as aJ, type RenderStyle as aK, type RightFeatureInput as aL, type ScheduledClip as aM, type SectionHeaderInput as aN, type ShapeFilter as aO, type ShapeLayer as aP, type ShapePattern as aQ, type SolidBackgroundConfig as aR, type StartBlockConfig as aS, type StatHighlightInput as aT, type SurfaceScheme as aU, THEME_SCHEMA_VERSION as aV, type TableLayer as aW, type TableLayerStyle as aX, type TemplateBlock as aY, type TemplateContext as aZ, type TemplateFunction as a_, PAGE_DESIGN_FAMILIES as aa, PAGE_DIVIDERS as ab, PAGE_EMPHASES as ac, PAGE_EYEBROWS as ad, PAGE_HEADING_CASES as ae, PAGE_HEADING_SCALES as af, PAGE_HEADING_UNDERLINES as ag, PAGE_HERO_STYLES as ah, PAGE_IMAGE_FRAMINGS as ai, PAGE_NUMERAL_STYLES as aj, PAGE_PATTERNS as ak, PAGE_QUOTE_MARKS as al, PAGE_SECTION_KINDS as am, PAGE_SECTION_SPACINGS as an, PAGE_SHADOWS as ao, type PageAccentRotation as ap, type PageBackground as aq, type PageDesignFamily as ar, type PageEmphasis as as, type PageHeadingTreatment as at, type PageSectionKind as au, type PageSectionOverride as av, type PageTokens as aw, type PathLayer as ax, type PatternBackgroundConfig as ay, type PersistentLayer as az, type AmbientGradientConfig as b, type TextLayer as b0, type TextStyle as b1, type Theme as b2, type ThemeColorPalette as b3, type ThemeColorScheme as b4, type ThemePageStyle as b5, type ThemeRegistry as b6, type ThemeSchemaVersion as b7, type ThemeSeedColors as b8, type ThemeStyle as b9, createThemeRegistry as bA, getAspectRatioString as bB, getBlockAtTime as bC, getCaptionAtTime as bD, getDocPlaybackDuration as bE, getLayoutHints as bF, getSafeTextBounds as bG, getSegmentAtTime as bH, getTwoColumnPositions as bI, getViewport as bJ, getViewportOrientation as bK, isPersistentLayerTemplate as bL, isTemplateBlock as bM, scaledFontSize$1 as bN, resolveMediaSchedule as bO, scaledFontSize as bP, type ThemeTypography as ba, type TimelineBlockInput as bb, type TimelineTemplateEvent as bc, type TimelineTemplateLink as bd, type TimelineTemplateTrack as be, type TitleBlockInput as bf, type TitleCaptionConfig as bg, type TreeBlockInput as bh, type TreeLayer as bi, type TreeLayerItem as bj, type TreeLayerStyle as bk, type TreeTemplateItem as bl, type TwoColumnInput as bm, VIEWPORT_PRESETS as bn, type VideoLayer as bo, type VideoPullQuoteInput as bp, type VideoWithCaptionInput as bq, type ViewportConfig as br, type ViewportOrientation as bs, type ViewportPreset as bt, type VignetteConfig as bu, applySurface as bv, calculateDuration as bw, calculateFontScale as bx, createTemplateContext as by, createTheme as bz, type Animation as c, type AnimationType as d, type AudioBookmark as e, type AudioSegment as f, type AudioTimingData as g, type AudioTrack as h, type BlockConnection as i, type BorderStyle as j, type CaptionTrack as k, type CaptionWord as l, type ColorScheme as m, type ComparisonBarInput as n, type ContentBlockInput as o, type CornerBrandingConfig as p, type CustomTemplateDefinition as q, type CustomTemplateLayer as r, DEFAULT_DOC_FONT as s, DEFAULT_TITLE_FONT as t, type DataTableInput as u, type DateEventInput as v, type DeepPartial as w, type DefinitionCardInput as x, type DiagramBlockInput as y, type DiagramEdgeAnchor as z };
2645
+ export { LIGHT_SURFACE as $, type AccentImage as A, type BarChartInput as B, type CaptionPhrase as C, DARK_SURFACE as D, type DateEventInput as E, type DeepPartial as F, type DefinitionCardInput as G, type DiagramBlockInput as H, type DiagramEdgeAnchor as I, type DiagramTemplateEdge as J, type DiagramTemplateNode as K, type Doc as L, type DocBlock as M, type DocDiagnostic as N, type DonutChartInput as O, type DrawingBlockInput as P, FRONTMATTER_CUSTOM_TEMPLATES_KEY as Q, FRONTMATTER_CUSTOM_THEMES_KEY as R, type FactCardInput as S, type FontFamily as T, type FontFamilyKind as U, type FullBleedQuoteInput as V, type GradientBackgroundConfig as W, type ImageBackgroundConfig as X, type ImageLayer as Y, type ImageTreatment as Z, type ImageWithCaptionInput as _, type AccentPosition as a, type StartBlockConfig as a$, type Layer as a0, type LayerRepeat as a1, type LayoutHints as a2, type LeftFeatureInput as a3, type LineChartInput as a4, type LinearGradient as a5, type ListBlockInput as a6, type MapBlockInput as a7, type MapLayer as a8, type MapMarker as a9, type PageHeadingTreatment as aA, type PageSectionKind as aB, type PageSectionOverride as aC, type PageTokens as aD, type PathLayer as aE, type PatternBackgroundConfig as aF, type PersistentLayer as aG, type PersistentLayerConfig as aH, type PersistentLayerTemplate as aI, type PersistentLayerTemplateConfig as aJ, type PersistentLayerTemplateType as aK, type PhotoGridInput as aL, type PieChartInput as aM, type Position as aN, type ProgressIndicatorConfig as aO, type PullQuoteInput as aP, type QuoteBlockInput as aQ, type RawLayersInput as aR, type RenderStyle as aS, type RightFeatureInput as aT, type ScatterChartInput as aU, type ScheduledClip as aV, type SectionHeaderInput as aW, type ShapeFilter as aX, type ShapeLayer as aY, type ShapePattern as aZ, type SolidBackgroundConfig as a_, type MapTileStyle as aa, type MarkerStyle as ab, type MediaClip as ac, type MermaidLayer as ad, PAGE_ACCENT_STRATEGIES as ae, PAGE_BACKGROUNDS as af, PAGE_BACKGROUND_RHYTHMS as ag, PAGE_DESIGN_FAMILIES as ah, PAGE_DIVIDERS as ai, PAGE_EMPHASES as aj, PAGE_EYEBROWS as ak, PAGE_HEADING_CASES as al, PAGE_HEADING_SCALES as am, PAGE_HEADING_UNDERLINES as an, PAGE_HERO_STYLES as ao, PAGE_IMAGE_FRAMINGS as ap, PAGE_NUMERAL_STYLES as aq, PAGE_PATTERNS as ar, PAGE_QUOTE_MARKS as as, PAGE_SECTION_KINDS as at, PAGE_SECTION_SPACINGS as au, PAGE_SHADOWS as av, type PageAccentRotation as aw, type PageBackground as ax, type PageDesignFamily as ay, type PageEmphasis as az, type AmbientGradientConfig as b, type StatHighlightInput as b0, type SurfaceScheme as b1, THEME_SCHEMA_VERSION as b2, type TableLayer as b3, type TableLayerStyle as b4, type TemplateBlock as b5, type TemplateContext as b6, type TemplateFunction as b7, type TemplateRegistry as b8, type TextLayer as b9, type VideoWithCaptionInput as bA, type ViewportConfig as bB, type ViewportOrientation as bC, type ViewportPreset as bD, type VignetteConfig as bE, applySurface as bF, calculateDuration as bG, calculateFontScale as bH, createTemplateContext as bI, createTheme as bJ, createThemeRegistry as bK, getAspectRatioString as bL, getBlockAtTime as bM, getCaptionAtTime as bN, getDocPlaybackDuration as bO, getLayoutHints as bP, getSafeTextBounds as bQ, getSegmentAtTime as bR, getTwoColumnPositions as bS, getViewport as bT, getViewportOrientation as bU, isPersistentLayerTemplate as bV, isTemplateBlock as bW, scaledFontSize$1 as bX, resolveMediaSchedule as bY, scaledFontSize as bZ, type TextStyle as ba, type Theme as bb, type ThemeColorPalette as bc, type ThemeColorScheme as bd, type ThemePageStyle as be, type ThemeRegistry as bf, type ThemeSchemaVersion as bg, type ThemeSeedColors as bh, type ThemeStyle as bi, type ThemeTypography as bj, type TimelineBlockInput as bk, type TimelineTemplateEvent as bl, type TimelineTemplateLink as bm, type TimelineTemplateTrack as bn, type TitleBlockInput as bo, type TitleCaptionConfig as bp, type TreeBlockInput as bq, type TreeLayer as br, type TreeLayerItem as bs, type TreeLayerStyle as bt, type TreeTemplateItem as bu, type TwoColumnInput as bv, VIEWPORT_PRESETS as bw, type VideoLayer as bx, type VideoPlacement as by, type VideoPullQuoteInput as bz, type Animation as c, type AnimationType as d, type AreaChartInput as e, type AudioBookmark as f, type AudioSegment as g, type AudioTimingData as h, type AudioTrack as i, type Block as j, type BlockConnection as k, type BorderStyle as l, type CaptionTrack as m, type CaptionWord as n, type ChartBaseFields as o, type ChartTemplateInput as p, type ColorScheme as q, type ColumnChartInput as r, type ComparisonBarInput as s, type ContentBlockInput as t, type CornerBrandingConfig as u, type CustomTemplateDefinition as v, type CustomTemplateLayer as w, DEFAULT_DOC_FONT as x, DEFAULT_TITLE_FONT as y, type DataTableInput as z };
@@ -1,4 +1,4 @@
1
- import { S as ImageLayer, b0 as TextLayer, aP as ShapeLayer, ax as PathLayer } from './Doc-BrgZC7SE.js';
1
+ import { Y as ImageLayer, b9 as TextLayer, aY as ShapeLayer, aE as PathLayer } from './Doc-DLpyOAXJ.js';
2
2
 
3
3
  /**
4
4
  * ImageEditDoc — JSON document describing a layered, editable image.
@@ -35,6 +35,8 @@ function resolveMediaSchedule(doc) {
35
35
  id: clip.id,
36
36
  src: clip.src,
37
37
  kind: clip.kind,
38
+ ...clip.placement ? { placement: clip.placement } : {},
39
+ ...clip.lockToBlock != null ? { lockToBlock: clip.lockToBlock } : {},
38
40
  absoluteStart: start,
39
41
  absoluteEnd: Math.max(start, end),
40
42
  sourceIn: clip.clipStart ?? 0,
@@ -52,6 +54,8 @@ function resolveMediaSchedule(doc) {
52
54
  id: clip.id,
53
55
  src: clip.src,
54
56
  kind: clip.kind,
57
+ ...clip.placement ? { placement: clip.placement } : {},
58
+ ...clip.lockToBlock != null ? { lockToBlock: clip.lockToBlock } : {},
55
59
  absoluteStart: start,
56
60
  absoluteEnd: Math.max(start, end),
57
61
  sourceIn: clip.clipStart ?? 0,
@@ -5,6 +5,249 @@ import {
5
5
  normalizeTransitionType
6
6
  } from "./chunk-4VOD55SX.js";
7
7
 
8
+ // src/markdown/sanitize.ts
9
+ var SAFE_LINK_SCHEMES = /* @__PURE__ */ new Set(["http", "https", "mailto", "tel"]);
10
+ var SAFE_MEDIA_SCHEMES = /* @__PURE__ */ new Set(["http", "https", "blob"]);
11
+ var NEVER_ALLOWED_SCHEMES = /* @__PURE__ */ new Set(["javascript", "vbscript", "data"]);
12
+ var SAFE_DATA_MEDIA_RE = /^data:(?:image\/(?!svg\+xml)[a-z0-9.+-]+|audio\/[a-z0-9.+-]+|video\/[a-z0-9.+-]+);/i;
13
+ var SAFE_TAGS = /* @__PURE__ */ new Set([
14
+ "a",
15
+ "abbr",
16
+ "b",
17
+ "blockquote",
18
+ "br",
19
+ "caption",
20
+ "cite",
21
+ "code",
22
+ "col",
23
+ "colgroup",
24
+ "data",
25
+ "dd",
26
+ "del",
27
+ "details",
28
+ "dfn",
29
+ "div",
30
+ "dl",
31
+ "dt",
32
+ "em",
33
+ "figcaption",
34
+ "figure",
35
+ "h1",
36
+ "h2",
37
+ "h3",
38
+ "h4",
39
+ "h5",
40
+ "h6",
41
+ "hr",
42
+ "i",
43
+ "img",
44
+ "kbd",
45
+ "li",
46
+ "mark",
47
+ "ol",
48
+ "p",
49
+ "pre",
50
+ "q",
51
+ "s",
52
+ "samp",
53
+ "small",
54
+ "source",
55
+ "span",
56
+ "strong",
57
+ "sub",
58
+ "summary",
59
+ "sup",
60
+ "table",
61
+ "tbody",
62
+ "td",
63
+ "tfoot",
64
+ "th",
65
+ "thead",
66
+ "time",
67
+ "tr",
68
+ "track",
69
+ "u",
70
+ "ul",
71
+ "var",
72
+ "video",
73
+ "audio"
74
+ ]);
75
+ var DROP_WITH_CONTENT_TAGS = /* @__PURE__ */ new Set([
76
+ "base",
77
+ "button",
78
+ "embed",
79
+ "form",
80
+ "iframe",
81
+ "input",
82
+ "link",
83
+ "meta",
84
+ "object",
85
+ "option",
86
+ "script",
87
+ "select",
88
+ "style",
89
+ "svg",
90
+ "template",
91
+ "textarea"
92
+ ]);
93
+ var GLOBAL_ATTRS = /* @__PURE__ */ new Set(["class", "id", "title", "role"]);
94
+ var TAG_ATTRS = {
95
+ a: /* @__PURE__ */ new Set(["href", "target", "rel"]),
96
+ audio: /* @__PURE__ */ new Set(["src", "controls", "preload", "muted", "loop"]),
97
+ col: /* @__PURE__ */ new Set(["span", "width"]),
98
+ colgroup: /* @__PURE__ */ new Set(["span"]),
99
+ data: /* @__PURE__ */ new Set(["value"]),
100
+ img: /* @__PURE__ */ new Set(["src", "alt", "width", "height", "loading", "decoding"]),
101
+ li: /* @__PURE__ */ new Set(["value"]),
102
+ ol: /* @__PURE__ */ new Set(["start", "type"]),
103
+ q: /* @__PURE__ */ new Set(["cite"]),
104
+ source: /* @__PURE__ */ new Set(["src", "type", "media"]),
105
+ td: /* @__PURE__ */ new Set(["colspan", "rowspan", "align"]),
106
+ th: /* @__PURE__ */ new Set(["colspan", "rowspan", "align", "scope"]),
107
+ time: /* @__PURE__ */ new Set(["datetime"]),
108
+ track: /* @__PURE__ */ new Set(["src", "kind", "label", "srclang", "default"]),
109
+ video: /* @__PURE__ */ new Set([
110
+ "src",
111
+ "poster",
112
+ "width",
113
+ "height",
114
+ "controls",
115
+ "preload",
116
+ "muted",
117
+ "loop",
118
+ "playsinline"
119
+ ])
120
+ };
121
+ var SAFE_ATTR_NAME_RE = /^[a-z][a-z0-9:_.-]*$/;
122
+ var SAFE_OL_TYPES = /* @__PURE__ */ new Set(["1", "a", "A", "i", "I"]);
123
+ var SAFE_PRELOAD_VALUES = /* @__PURE__ */ new Set(["none", "metadata", "auto"]);
124
+ var SAFE_TRACK_KINDS = /* @__PURE__ */ new Set(["subtitles", "captions", "descriptions", "chapters", "metadata"]);
125
+ function sanitizeUrl(url, kind = "link", options) {
126
+ if (typeof url !== "string") return null;
127
+ const trimmed = url.trim();
128
+ if (!trimmed) return null;
129
+ const compact = stripUrlSchemeNoise(trimmed);
130
+ const colon = compact.indexOf(":");
131
+ const firstPathChar = firstIndexOfAny(compact, ["/", "?", "#"]);
132
+ const hasScheme = colon >= 0 && (firstPathChar < 0 || colon < firstPathChar);
133
+ if (!hasScheme) return trimmed;
134
+ const scheme = compact.slice(0, colon).toLowerCase();
135
+ if (kind === "media") {
136
+ if (scheme === "data") return SAFE_DATA_MEDIA_RE.test(compact) ? trimmed : null;
137
+ return SAFE_MEDIA_SCHEMES.has(scheme) ? trimmed : null;
138
+ }
139
+ if (SAFE_LINK_SCHEMES.has(scheme)) return trimmed;
140
+ if (options?.extraLinkSchemes?.includes(scheme) && !NEVER_ALLOWED_SCHEMES.has(scheme)) {
141
+ return trimmed;
142
+ }
143
+ return null;
144
+ }
145
+ function sanitizeHtmlNodes(nodes) {
146
+ const out = [];
147
+ for (const node of nodes) {
148
+ out.push(...sanitizeHtmlNode(node));
149
+ }
150
+ return out;
151
+ }
152
+ function sanitizeHtmlNode(node) {
153
+ switch (node.type) {
154
+ case "htmlText":
155
+ return [node];
156
+ case "htmlComment":
157
+ return [];
158
+ case "htmlElement":
159
+ return sanitizeHtmlElement(node);
160
+ }
161
+ }
162
+ function sanitizeHtmlElement(node) {
163
+ const tag = node.tagName.toLowerCase();
164
+ if (DROP_WITH_CONTENT_TAGS.has(tag)) return [];
165
+ const children = sanitizeHtmlNodes(node.children);
166
+ if (!SAFE_TAGS.has(tag)) return children;
167
+ return [
168
+ {
169
+ type: "htmlElement",
170
+ tagName: tag,
171
+ attributes: sanitizeAttrs(tag, node.attributes),
172
+ children,
173
+ selfClosing: node.selfClosing
174
+ }
175
+ ];
176
+ }
177
+ function sanitizeAttrs(tag, attrs) {
178
+ const out = {};
179
+ for (const [rawName, rawValue] of Object.entries(attrs)) {
180
+ const name = rawName.toLowerCase();
181
+ if (!isAllowedAttr(tag, name)) continue;
182
+ const value = String(rawValue);
183
+ const safeValue = sanitizeAttrValue(tag, name, value);
184
+ if (safeValue === null) continue;
185
+ out[name] = safeValue;
186
+ }
187
+ if (tag === "a" && out.target === "_blank") {
188
+ out.rel = ensureRelTokens(out.rel, ["noopener", "noreferrer"]);
189
+ }
190
+ return out;
191
+ }
192
+ function isAllowedAttr(tag, name) {
193
+ if (!SAFE_ATTR_NAME_RE.test(name)) return false;
194
+ if (name.startsWith("on")) return false;
195
+ if (name.startsWith("aria-") || name.startsWith("data-")) return true;
196
+ if (GLOBAL_ATTRS.has(name)) return true;
197
+ return TAG_ATTRS[tag]?.has(name) ?? false;
198
+ }
199
+ function sanitizeAttrValue(tag, name, value) {
200
+ if (name === "href") return sanitizeUrl(value, "link");
201
+ if (name === "src" || name === "poster") return sanitizeUrl(value, "media");
202
+ if ((name === "width" || name === "height" || name === "span" || name === "colspan" || name === "rowspan" || name === "value") && !isNonNegativeInteger(value)) {
203
+ return null;
204
+ }
205
+ if (name === "start" && !isInteger(value)) return null;
206
+ if (name === "type" && tag === "ol" && !SAFE_OL_TYPES.has(value)) return null;
207
+ if (name === "preload" && !SAFE_PRELOAD_VALUES.has(value)) return null;
208
+ if (name === "kind" && tag === "track" && !SAFE_TRACK_KINDS.has(value)) return null;
209
+ if (name === "align" && value !== "left" && value !== "right" && value !== "center") return null;
210
+ if (name === "target")
211
+ return value === "_blank" || value === "_self" || value === "_parent" || value === "_top" ? value : null;
212
+ if (name === "rel") return sanitizeRel(value);
213
+ return value;
214
+ }
215
+ function sanitizeRel(value) {
216
+ return relTokens(value).join(" ");
217
+ }
218
+ function ensureRelTokens(value, required) {
219
+ const tokens = new Set(value ? relTokens(value) : []);
220
+ for (const token of required) tokens.add(token);
221
+ return Array.from(tokens).join(" ");
222
+ }
223
+ function relTokens(value) {
224
+ const tokens = value.split(/\s+/).map((token) => token.trim().toLowerCase()).filter(Boolean).filter((token) => /^[a-z0-9_-]+$/.test(token));
225
+ return Array.from(new Set(tokens));
226
+ }
227
+ function isInteger(value) {
228
+ return /^-?\d+$/.test(value.trim());
229
+ }
230
+ function isNonNegativeInteger(value) {
231
+ return /^\d+$/.test(value.trim());
232
+ }
233
+ function firstIndexOfAny(value, needles) {
234
+ let result = -1;
235
+ for (const needle of needles) {
236
+ const index = value.indexOf(needle);
237
+ if (index >= 0 && (result < 0 || index < result)) result = index;
238
+ }
239
+ return result;
240
+ }
241
+ function stripUrlSchemeNoise(value) {
242
+ let out = "";
243
+ for (const char of value) {
244
+ const code = char.charCodeAt(0);
245
+ if (code <= 32 || code === 127 || char.trim() === "") continue;
246
+ out += char;
247
+ }
248
+ return out;
249
+ }
250
+
8
251
  // src/markdown/annotationCoercion.ts
9
252
  var KNOWN_BLOCK_META_KEYS = {
10
253
  x: "number",
@@ -275,6 +518,8 @@ function serializeAnnotation(template, params) {
275
518
  }
276
519
 
277
520
  export {
521
+ sanitizeUrl,
522
+ sanitizeHtmlNodes,
278
523
  KNOWN_BLOCK_META_KEYS,
279
524
  BLOCK_META_KEY_DESCRIPTORS,
280
525
  coerceAnnotationValues,
@@ -10,7 +10,7 @@ import {
10
10
  import {
11
11
  extractPlainText,
12
12
  getChildren
13
- } from "./chunk-BCCXTMN5.js";
13
+ } from "./chunk-O7JILDEF.js";
14
14
  import {
15
15
  estimateTimeFromText
16
16
  } from "./chunk-67L6WRJN.js";
@@ -2,7 +2,7 @@ import {
2
2
  extractPlainText,
3
3
  findNodesByType,
4
4
  walkMarkdownTree
5
- } from "./chunk-BCCXTMN5.js";
5
+ } from "./chunk-O7JILDEF.js";
6
6
 
7
7
  // src/doc/asciiDiagram/chars.ts
8
8
  function toCells(s) {
@@ -2435,6 +2435,10 @@ function recommendedNamesForProfile(profile) {
2435
2435
  anyContentSignal = true;
2436
2436
  names.add("dataTable");
2437
2437
  names.add("comparisonBar");
2438
+ names.add("columnChart");
2439
+ names.add("barChart");
2440
+ names.add("lineChart");
2441
+ names.add("pieChart");
2438
2442
  }
2439
2443
  if (profile.hasDate) {
2440
2444
  anyContentSignal = true;
@@ -5,14 +5,14 @@ import {
5
5
  quoteAttrValue,
6
6
  splitKeyValueToken,
7
7
  tokenizeAttrTokens
8
- } from "./chunk-ZQKZSJAX.js";
8
+ } from "./chunk-2VCNTDNZ.js";
9
9
  import {
10
10
  resolveIcon
11
11
  } from "./chunk-7N4G32LG.js";
12
12
  import {
13
13
  parseFrontmatter,
14
14
  parseHtmlToNodes
15
- } from "./chunk-BCCXTMN5.js";
15
+ } from "./chunk-O7JILDEF.js";
16
16
 
17
17
  // src/markdown/convert.ts
18
18
  function convertPosition(pos) {
@@ -58,25 +58,54 @@ function extractText(node) {
58
58
  return "";
59
59
  }
60
60
  function extractTemplateAnnotation(children) {
61
+ const trail = [];
61
62
  for (let i = children.length - 1; i >= 0; i--) {
62
63
  const child = children[i];
63
64
  if (child.type === "text") {
64
- const match = matchTrailingTemplateAnnotation(child.value);
65
- if (match) {
66
- const inner = match.inner.trim();
67
- const annotation = parseAnnotationTokens(inner);
68
- const stripped = child.value.slice(0, match.index).replace(/\s+$/, "");
69
- if (stripped) {
70
- child.value = stripped;
71
- } else {
72
- children.splice(i, 1);
73
- }
74
- return annotation;
75
- }
76
- break;
65
+ trail.unshift({ value: child.value, index: i });
66
+ continue;
67
+ }
68
+ const autolink = literalAutolinkText(child);
69
+ if (autolink != null) {
70
+ trail.unshift({ value: autolink, index: i });
71
+ continue;
77
72
  }
78
73
  break;
79
74
  }
75
+ if (trail.length === 0) return null;
76
+ const joined = trail.map((part) => part.value).join("");
77
+ const match = matchTrailingTemplateAnnotation(joined);
78
+ if (!match) return null;
79
+ const annotation = parseAnnotationTokens(match.inner.trim());
80
+ let scannedLength = 0;
81
+ for (const part of trail) {
82
+ if (scannedLength + part.value.length <= match.index) {
83
+ scannedLength += part.value.length;
84
+ continue;
85
+ }
86
+ const boundaryNode = children[part.index];
87
+ const keepLength = match.index - scannedLength;
88
+ if (boundaryNode.type === "text" && keepLength > 0) {
89
+ const stripped = boundaryNode.value.slice(0, keepLength).replace(/\s+$/, "");
90
+ if (stripped) {
91
+ boundaryNode.value = stripped;
92
+ children.splice(part.index + 1);
93
+ } else {
94
+ children.splice(part.index);
95
+ }
96
+ } else {
97
+ children.splice(part.index);
98
+ }
99
+ return annotation;
100
+ }
101
+ children.splice(trail[0].index);
102
+ return annotation;
103
+ }
104
+ function literalAutolinkText(node) {
105
+ if (node.type !== "link" || node.title != null) return null;
106
+ const label = extractInlineText(node.children);
107
+ if (label === node.url) return label;
108
+ if (/^www\./i.test(label) && node.url === `http://${label}`) return label;
80
109
  return null;
81
110
  }
82
111
  function parseAnnotationTokens(inner) {