@k2b/ui 0.24.0 → 0.25.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.
- package/README.md +2 -2
- package/dist/browser/actions/Dropdown.js +67 -52
- package/dist/browser/actions/Dropdown.js.map +1 -1
- package/dist/browser/actions/GestureMenu.js +3 -3
- package/dist/browser/actions/GestureMenu.js.map +1 -1
- package/dist/browser/actions/SpotlightSearch.js +13 -6
- package/dist/browser/actions/SpotlightSearch.js.map +1 -1
- package/dist/browser/actions/Toolbar.js +75 -1
- package/dist/browser/actions/Toolbar.js.map +1 -1
- package/dist/browser/content/Calendar.js +1538 -911
- package/dist/browser/content/Calendar.js.map +1 -1
- package/dist/browser/content/CalendarDayView.js +1 -1
- package/dist/browser/content/CalendarDayView.js.map +1 -1
- package/dist/browser/content/CalendarWeekView.js +1 -1
- package/dist/browser/content/CalendarWeekView.js.map +1 -1
- package/dist/browser/content/Kbd.js +51 -0
- package/dist/browser/content/Kbd.js.map +1 -0
- package/dist/browser/content/LabelChip.js +38 -0
- package/dist/browser/content/LabelChip.js.map +1 -0
- package/dist/browser/content/MarkdownView.js +2 -1
- package/dist/browser/content/MarkdownView.js.map +1 -1
- package/dist/browser/content/Steps.js +34 -0
- package/dist/browser/content/Steps.js.map +1 -0
- package/dist/browser/content/VirtualFeed.js +33 -1
- package/dist/browser/content/VirtualFeed.js.map +1 -1
- package/dist/browser/content/calendar-dialogs.js +32 -60
- package/dist/browser/content/calendar-dialogs.js.map +1 -1
- package/dist/browser/content/calendar-month-scroll.js +80 -0
- package/dist/browser/content/calendar-month-scroll.js.map +1 -0
- package/dist/browser/content/index.js +4 -1
- package/dist/browser/content/index.js.map +1 -1
- package/dist/browser/content/markdown-info-blocks.js +33 -5
- package/dist/browser/content/markdown-info-blocks.js.map +1 -1
- package/dist/browser/feedback/prompts.js +17 -3
- package/dist/browser/feedback/prompts.js.map +1 -1
- package/dist/browser/intl/index.js +1 -0
- package/dist/browser/intl/index.js.map +1 -1
- package/dist/browser/intl/shortcut-messages.js +77 -0
- package/dist/browser/intl/shortcut-messages.js.map +1 -0
- package/dist/browser/intl/shortcut.js +123 -0
- package/dist/browser/intl/shortcut.js.map +1 -0
- package/dist/browser/layout/AppWorkspace.js +343 -325
- package/dist/browser/layout/AppWorkspace.js.map +1 -1
- package/dist/browser/layout/TableOfContents.js +115 -0
- package/dist/browser/layout/TableOfContents.js.map +1 -0
- package/dist/browser/layout/app-workspace-controller.js +3 -46
- package/dist/browser/layout/app-workspace-controller.js.map +1 -1
- package/dist/browser/layout/index.js +1 -0
- package/dist/browser/layout/index.js.map +1 -1
- package/dist/browser/layout/table-of-contents-messages.js +19 -0
- package/dist/browser/layout/table-of-contents-messages.js.map +1 -0
- package/dist/browser/surfaces/LinkCard.js +40 -24
- package/dist/browser/surfaces/LinkCard.js.map +1 -1
- package/dist/ssr/actions/Dropdown.js +11 -5
- package/dist/ssr/actions/Dropdown.js.map +1 -1
- package/dist/ssr/actions/GestureMenu.js +3 -3
- package/dist/ssr/actions/GestureMenu.js.map +1 -1
- package/dist/ssr/actions/SpotlightSearch.js +9 -3
- package/dist/ssr/actions/SpotlightSearch.js.map +1 -1
- package/dist/ssr/actions/Toolbar.js +67 -1
- package/dist/ssr/actions/Toolbar.js.map +1 -1
- package/dist/ssr/content/Calendar.js +863 -312
- package/dist/ssr/content/Calendar.js.map +1 -1
- package/dist/ssr/content/CalendarDayView.js +1 -1
- package/dist/ssr/content/CalendarDayView.js.map +1 -1
- package/dist/ssr/content/CalendarWeekView.js +1 -1
- package/dist/ssr/content/CalendarWeekView.js.map +1 -1
- package/dist/ssr/content/Kbd.js +38 -0
- package/dist/ssr/content/Kbd.js.map +1 -0
- package/dist/ssr/content/LabelChip.js +21 -0
- package/dist/ssr/content/LabelChip.js.map +1 -0
- package/dist/ssr/content/MarkdownView.js +2 -1
- package/dist/ssr/content/MarkdownView.js.map +1 -1
- package/dist/ssr/content/Steps.js +14 -0
- package/dist/ssr/content/Steps.js.map +1 -0
- package/dist/ssr/content/VirtualFeed.js +33 -1
- package/dist/ssr/content/VirtualFeed.js.map +1 -1
- package/dist/ssr/content/calendar-dialogs.js +12 -32
- package/dist/ssr/content/calendar-dialogs.js.map +1 -1
- package/dist/ssr/content/calendar-month-scroll.js +80 -0
- package/dist/ssr/content/calendar-month-scroll.js.map +1 -0
- package/dist/ssr/content/index.js +4 -1
- package/dist/ssr/content/index.js.map +1 -1
- package/dist/ssr/content/markdown-info-blocks.js +33 -5
- package/dist/ssr/content/markdown-info-blocks.js.map +1 -1
- package/dist/ssr/feedback/prompts.js +17 -3
- package/dist/ssr/feedback/prompts.js.map +1 -1
- package/dist/ssr/intl/index.js +1 -0
- package/dist/ssr/intl/index.js.map +1 -1
- package/dist/ssr/intl/shortcut-messages.js +77 -0
- package/dist/ssr/intl/shortcut-messages.js.map +1 -0
- package/dist/ssr/intl/shortcut.js +123 -0
- package/dist/ssr/intl/shortcut.js.map +1 -0
- package/dist/ssr/layout/AppWorkspace.js +65 -59
- package/dist/ssr/layout/AppWorkspace.js.map +1 -1
- package/dist/ssr/layout/TableOfContents.js +79 -0
- package/dist/ssr/layout/TableOfContents.js.map +1 -0
- package/dist/ssr/layout/app-workspace-controller.js +3 -46
- package/dist/ssr/layout/app-workspace-controller.js.map +1 -1
- package/dist/ssr/layout/index.js +1 -0
- package/dist/ssr/layout/index.js.map +1 -1
- package/dist/ssr/layout/table-of-contents-messages.js +19 -0
- package/dist/ssr/layout/table-of-contents-messages.js.map +1 -0
- package/dist/ssr/surfaces/LinkCard.js +26 -10
- package/dist/ssr/surfaces/LinkCard.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/types/actions/Dropdown.d.ts +12 -0
- package/dist/types/actions/SpotlightSearch.d.ts +2 -0
- package/dist/types/content/Calendar.d.ts +16 -6
- package/dist/types/content/Kbd.d.ts +16 -0
- package/dist/types/content/LabelChip.d.ts +12 -0
- package/dist/types/content/MarkdownView.d.ts +2 -1
- package/dist/types/content/Steps.d.ts +12 -0
- package/dist/types/content/VirtualFeed.d.ts +8 -0
- package/dist/types/content/calendar-dialogs.d.ts +0 -2
- package/dist/types/content/calendar-month-scroll.d.ts +25 -0
- package/dist/types/content/index.d.ts +7 -1
- package/dist/types/content/markdown-info-blocks.d.ts +21 -4
- package/dist/types/feedback/prompts.d.ts +8 -2
- package/dist/types/intl/index.d.ts +2 -0
- package/dist/types/intl/shortcut-messages.d.ts +35 -0
- package/dist/types/intl/shortcut.d.ts +29 -0
- package/dist/types/layout/AppWorkspace.d.ts +3 -1
- package/dist/types/layout/TableOfContents.d.ts +24 -0
- package/dist/types/layout/index.d.ts +2 -0
- package/dist/types/layout/table-of-contents-messages.d.ts +4 -0
- package/dist/types/surfaces/LinkCard.d.ts +3 -0
- package/package.json +3 -3
|
@@ -12,31 +12,13 @@ import { createComponent as _$createComponent } from "solid-js/web";
|
|
|
12
12
|
var _tmpl$ = /*#__PURE__*/_$template(`<div class=k2b-dialog__panel><!$><!/><div class=k2b-dialog__body><dl class=k2b-calendar-shortcuts></dl><p class=k2b-calendar-shortcuts__note>`),
|
|
13
13
|
_tmpl$2 = /*#__PURE__*/_$template(`<dt><!$><!/><!$><!/>`),
|
|
14
14
|
_tmpl$3 = /*#__PURE__*/_$template(`<dd>`),
|
|
15
|
-
_tmpl$4 = /*#__PURE__*/_$template(`<
|
|
16
|
-
_tmpl$5 = /*#__PURE__*/_$template(`<
|
|
17
|
-
_tmpl$6 = /*#__PURE__*/_$template(`<form class=k2b-dialog__panel><!$><!/><div class="k2b-dialog__body k2b-calendar-goto"><input class=k2b-calendar-goto__input type=text autocomplete=off aria-describedby=k2b-calendar-goto-hint><p class=k2b-calendar-goto__preview id=k2b-calendar-goto-hint aria-live=polite></p></div><footer class=k2b-dialog__actions><button type=submit class=k2b-button data-variant=primary data-size=sm>`);
|
|
15
|
+
_tmpl$4 = /*#__PURE__*/_$template(`<span class=k2b-calendar-shortcuts__or>/`),
|
|
16
|
+
_tmpl$5 = /*#__PURE__*/_$template(`<form class=k2b-dialog__panel><!$><!/><div class="k2b-dialog__body k2b-calendar-goto"><input class=k2b-calendar-goto__input type=text autocomplete=off aria-describedby=k2b-calendar-goto-hint><p class=k2b-calendar-goto__preview id=k2b-calendar-goto-hint aria-live=polite></p></div><footer class=k2b-dialog__actions><button type=submit class=k2b-button data-variant=primary data-size=sm>`);
|
|
18
17
|
import { createSignal, For, Show } from "solid-js";
|
|
19
18
|
import { dialogCore } from "../feedback/dialog-core";
|
|
20
19
|
import { DialogHeader } from "../feedback/prompts";
|
|
21
20
|
import { addDayKeys } from "./calendar-days";
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
/** The keys of a shortcut as the reader presses them, such as ["⇧", "N"] or ["Shift", "N"]. */
|
|
25
|
-
export const shortcutKeys = shortcut => {
|
|
26
|
-
const mac = isMac();
|
|
27
|
-
const names = {
|
|
28
|
-
shift: mac ? "⇧" : "Shift",
|
|
29
|
-
alt: mac ? "⌥" : "Alt",
|
|
30
|
-
ctrl: mac ? "⌃" : "Ctrl",
|
|
31
|
-
meta: mac ? "⌘" : "Meta",
|
|
32
|
-
mod: mac ? "⌘" : "Ctrl",
|
|
33
|
-
arrowup: "↑",
|
|
34
|
-
arrowdown: "↓",
|
|
35
|
-
arrowleft: "←",
|
|
36
|
-
arrowright: "→"
|
|
37
|
-
};
|
|
38
|
-
return shortcut.split("+").map(part => names[part.toLowerCase()] ?? (part.length === 1 ? part.toUpperCase() : part));
|
|
39
|
-
};
|
|
21
|
+
import { Kbd } from "./Kbd";
|
|
40
22
|
|
|
41
23
|
/**
|
|
42
24
|
* The calendar's shortcuts: the same list the host registers for its dispatcher and its help. `alternatives` names
|
|
@@ -66,29 +48,19 @@ export const openCalendarShortcuts = (commands, messages, alternatives = {}) =>
|
|
|
66
48
|
[_el$9, _co$2] = _$getNextMarker(_el$8.nextSibling),
|
|
67
49
|
_el$0 = _el$9.nextSibling,
|
|
68
50
|
[_el$1, _co$3] = _$getNextMarker(_el$0.nextSibling);
|
|
69
|
-
_$insert(_el$7, _$createComponent(
|
|
70
|
-
get
|
|
71
|
-
return
|
|
72
|
-
}
|
|
73
|
-
children: key => (() => {
|
|
74
|
-
var _el$11 = _$getNextElement(_tmpl$4);
|
|
75
|
-
_$insert(_el$11, key);
|
|
76
|
-
return _el$11;
|
|
77
|
-
})()
|
|
51
|
+
_$insert(_el$7, _$createComponent(Kbd, {
|
|
52
|
+
get keys() {
|
|
53
|
+
return command.shortcut;
|
|
54
|
+
}
|
|
78
55
|
}), _el$9, _co$2);
|
|
79
56
|
_$insert(_el$7, _$createComponent(Show, {
|
|
80
57
|
get when() {
|
|
81
58
|
return alternatives[command.id];
|
|
82
59
|
},
|
|
83
|
-
children: other => [_$getNextElement(_tmpl$
|
|
84
|
-
get
|
|
85
|
-
return
|
|
86
|
-
}
|
|
87
|
-
children: key => (() => {
|
|
88
|
-
var _el$13 = _$getNextElement(_tmpl$4);
|
|
89
|
-
_$insert(_el$13, key);
|
|
90
|
-
return _el$13;
|
|
91
|
-
})()
|
|
60
|
+
children: other => [_$getNextElement(_tmpl$4), _$createComponent(Kbd, {
|
|
61
|
+
get keys() {
|
|
62
|
+
return other();
|
|
63
|
+
}
|
|
92
64
|
})]
|
|
93
65
|
}), _el$1, _co$3);
|
|
94
66
|
return _el$7;
|
|
@@ -173,29 +145,29 @@ export const openCalendarGoTo = props => dialogCore.open(close => {
|
|
|
173
145
|
const [text, setText] = createSignal("");
|
|
174
146
|
const result = () => parseGoTo(text(), props.today);
|
|
175
147
|
return (() => {
|
|
176
|
-
var _el$
|
|
177
|
-
_el$
|
|
178
|
-
[_el$
|
|
179
|
-
_el$
|
|
180
|
-
_el$
|
|
181
|
-
_el$
|
|
182
|
-
_el$
|
|
183
|
-
_el$
|
|
184
|
-
_el$
|
|
148
|
+
var _el$12 = _$getNextElement(_tmpl$5),
|
|
149
|
+
_el$18 = _el$12.firstChild,
|
|
150
|
+
[_el$19, _co$4] = _$getNextMarker(_el$18.nextSibling),
|
|
151
|
+
_el$13 = _el$19.nextSibling,
|
|
152
|
+
_el$14 = _el$13.firstChild,
|
|
153
|
+
_el$15 = _el$14.nextSibling,
|
|
154
|
+
_el$16 = _el$13.nextSibling,
|
|
155
|
+
_el$17 = _el$16.firstChild;
|
|
156
|
+
_el$12.addEventListener("submit", event => {
|
|
185
157
|
event.preventDefault();
|
|
186
158
|
const key = result();
|
|
187
159
|
if (key) close(key);
|
|
188
160
|
});
|
|
189
|
-
_$insert(_el$
|
|
161
|
+
_$insert(_el$12, _$createComponent(DialogHeader, {
|
|
190
162
|
get title() {
|
|
191
163
|
return props.messages.calendarCommandGoTo;
|
|
192
164
|
},
|
|
193
165
|
icon: "ti ti-calendar-search",
|
|
194
166
|
close: () => close()
|
|
195
|
-
}), _el$
|
|
196
|
-
_el$
|
|
197
|
-
_$setAttribute(_el$
|
|
198
|
-
_$insert(_el$
|
|
167
|
+
}), _el$19, _co$4);
|
|
168
|
+
_el$14.$$input = event => setText(event.currentTarget.value);
|
|
169
|
+
_$setAttribute(_el$14, "spellcheck", false);
|
|
170
|
+
_$insert(_el$15, _$createComponent(Show, {
|
|
199
171
|
get when() {
|
|
200
172
|
return result();
|
|
201
173
|
},
|
|
@@ -204,16 +176,16 @@ export const openCalendarGoTo = props => dialogCore.open(close => {
|
|
|
204
176
|
},
|
|
205
177
|
children: key => `→ ${props.describe(key())}`
|
|
206
178
|
}));
|
|
207
|
-
_$insert(_el$
|
|
179
|
+
_$insert(_el$17, () => props.messages.calendarGoToGo);
|
|
208
180
|
_$effect(_p$ => {
|
|
209
181
|
var _v$ = props.messages.calendarCommandGoTo,
|
|
210
182
|
_v$2 = props.messages.calendarGoToPlaceholder,
|
|
211
183
|
_v$3 = result() ? "true" : undefined,
|
|
212
184
|
_v$4 = !result();
|
|
213
|
-
_v$ !== _p$.e && _$setAttribute(_el$
|
|
214
|
-
_v$2 !== _p$.t && _$setAttribute(_el$
|
|
215
|
-
_v$3 !== _p$.a && _$setAttribute(_el$
|
|
216
|
-
_v$4 !== _p$.o && _$setProperty(_el$
|
|
185
|
+
_v$ !== _p$.e && _$setAttribute(_el$14, "aria-label", _p$.e = _v$);
|
|
186
|
+
_v$2 !== _p$.t && _$setAttribute(_el$14, "placeholder", _p$.t = _v$2);
|
|
187
|
+
_v$3 !== _p$.a && _$setAttribute(_el$15, "data-ok", _p$.a = _v$3);
|
|
188
|
+
_v$4 !== _p$.o && _$setProperty(_el$17, "disabled", _p$.o = _v$4);
|
|
217
189
|
return _p$;
|
|
218
190
|
}, {
|
|
219
191
|
e: undefined,
|
|
@@ -221,9 +193,9 @@ export const openCalendarGoTo = props => dialogCore.open(close => {
|
|
|
221
193
|
a: undefined,
|
|
222
194
|
o: undefined
|
|
223
195
|
});
|
|
224
|
-
_$effect(() => _$setProperty(_el$
|
|
196
|
+
_$effect(() => _$setProperty(_el$14, "value", text()));
|
|
225
197
|
_$runHydrationEvents();
|
|
226
|
-
return _el$
|
|
198
|
+
return _el$12;
|
|
227
199
|
})();
|
|
228
200
|
}, {
|
|
229
201
|
panelClassName: "k2b-dialog k2b-dialog--small",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["content/calendar-dialogs.tsx"],"sourcesContent":["import { createSignal, For, Show } from \"solid-js\";\nimport { dialogCore } from \"../feedback/dialog-core\";\nimport { DialogHeader } from \"../feedback/prompts\";\nimport type { CalendarCommand } from \"./Calendar\";\nimport { addDayKeys } from \"./calendar-days\";\nimport type { CalendarMessages } from \"./calendar-messages\";\n\nconst isMac = () => typeof navigator !== \"undefined\" && /Mac|iPhone|iPad/.test(navigator.platform);\n\n/** The keys of a shortcut as the reader presses them, such as [\"⇧\", \"N\"] or [\"Shift\", \"N\"]. */\nexport const shortcutKeys = (shortcut: string): string[] => {\n const mac = isMac();\n const names: Record<string, string> = {\n shift: mac ? \"⇧\" : \"Shift\",\n alt: mac ? \"⌥\" : \"Alt\",\n ctrl: mac ? \"⌃\" : \"Ctrl\",\n meta: mac ? \"⌘\" : \"Meta\",\n mod: mac ? \"⌘\" : \"Ctrl\",\n arrowup: \"↑\",\n arrowdown: \"↓\",\n arrowleft: \"←\",\n arrowright: \"→\",\n };\n return shortcut.split(\"+\").map((part) => names[part.toLowerCase()] ?? (part.length === 1 ? part.toUpperCase() : part));\n};\n\n/**\n * The calendar's shortcuts: the same list the host registers for its dispatcher and its help. `alternatives` names\n * other keys the calendar itself handles for a command, such as the arrow keys that page like J and K.\n */\nexport const openCalendarShortcuts = (\n commands: readonly CalendarCommand[],\n messages: CalendarMessages,\n alternatives: Readonly<Record<string, string>> = {},\n) =>\n dialogCore.open<void>(\n (close) => (\n <div class=\"k2b-dialog__panel\">\n <DialogHeader title={messages.calendarShortcuts} icon=\"ti ti-keyboard\" close={() => close()} />\n <div class=\"k2b-dialog__body\">\n <dl class=\"k2b-calendar-shortcuts\">\n <For each={commands.filter((command) => command.shortcut)}>\n {(command) => (\n <>\n <dt>\n <For each={shortcutKeys(command.shortcut!)}>{(key) => <kbd class=\"k2b-calendar-shortcuts__key\">{key}</kbd>}</For>\n <Show when={alternatives[command.id]}>\n {(other) => (\n <>\n <span class=\"k2b-calendar-shortcuts__or\">/</span>\n <For each={shortcutKeys(other())}>{(key) => <kbd class=\"k2b-calendar-shortcuts__key\">{key}</kbd>}</For>\n </>\n )}\n </Show>\n </dt>\n <dd>{command.label}</dd>\n </>\n )}\n </For>\n </dl>\n <p class=\"k2b-calendar-shortcuts__note\">{messages.calendarShortcutsNote}</p>\n </div>\n </div>\n ),\n { panelClassName: \"k2b-dialog k2b-dialog--small\", ariaLabel: messages.calendarShortcuts },\n );\n\nconst pad = (value: number) => String(value).padStart(2, \"0\");\nconst validKey = (year: number, month: number, day: number) => {\n const date = new Date(Date.UTC(year, month - 1, day));\n return date.getUTCFullYear() === year && date.getUTCMonth() === month - 1 && date.getUTCDate() === day\n ? `${year}-${pad(month)}-${pad(day)}`\n : null;\n};\n/** The Monday of an ISO week of a year. */\nconst isoWeekStart = (year: number, week: number) => {\n const january4 = new Date(Date.UTC(year, 0, 4));\n const monday = new Date(january4.getTime() - ((january4.getUTCDay() || 7) - 1) * 86_400_000);\n return addDayKeys(monday.toISOString().slice(0, 10), (week - 1) * 7);\n};\n\n/**\n * Reads German and English dates, weekdays, months, week numbers, today, and tomorrow for Go to. Weekdays include\n * today unless preceded by next; a month alone uses the next year if it has passed. A date without a year is this\n * year's. Names ignore case and accents and allow a trailing dot. Returns a `YYYY-MM-DD` key or `null`.\n */\nexport const parseGoTo = (text: string, today: string): string | null => {\n const value = text.trim().toLowerCase();\n if (!value) return null;\n const year = Number(today.slice(0, 4));\n if (/^(heute|today)$/.test(value)) return today;\n if (/^(morgen|tomorrow)$/.test(value)) return addDayKeys(today, 1);\n const fullYear = (raw: string | undefined) => (raw ? (raw.length === 2 ? 2000 + Number(raw) : Number(raw)) : year);\n let match = /^(\\d{4})-(\\d{1,2})-(\\d{1,2})$/.exec(value);\n if (match) return validKey(Number(match[1]), Number(match[2]), Number(match[3]));\n match = /^(\\d{1,2})\\.(\\d{1,2})\\.?(\\d{2}|\\d{4})?$/.exec(value);\n if (match) return validKey(fullYear(match[3]), Number(match[2]), Number(match[1]));\n match = /^(\\d{1,2})\\/(\\d{1,2})(?:\\/(\\d{2}|\\d{4}))?$/.exec(value);\n if (match) return validKey(fullYear(match[3]), Number(match[1]), Number(match[2]));\n match = /^(?:kw|w|week|woche)\\s*(\\d{1,2})(?:\\s*\\/?\\s*(\\d{4}))?$/.exec(value);\n if (match) {\n const week = Number(match[1]);\n return week >= 1 && week <= 53 ? isoWeekStart(match[2] ? Number(match[2]) : year, week) : null;\n }\n const named = value\n .normalize(\"NFD\")\n .replace(/[\\u0300-\\u036f]/g, \"\")\n .replace(/\\.$/, \"\")\n .trim();\n const weekdays = [\n \"montag mo monday mon\",\n \"dienstag di tuesday tue tues\",\n \"mittwoch mi wednesday wed\",\n \"donnerstag do thursday thu thur thurs\",\n \"freitag fr friday fri\",\n \"samstag sa saturday sat\",\n \"sonntag so sunday sun\",\n ];\n match = /^(?:(am|on|nachste|nachsten|nachster|naechsten|kommende|kommenden|next)\\s+)?([a-z]+)$/.exec(named);\n if (match) {\n const name = match[2];\n const weekday = weekdays.findIndex((names) => names.split(\" \").includes(name ?? \"\"));\n if (weekday >= 0) {\n const date = new Date(Date.UTC(year, Number(today.slice(5, 7)) - 1, Number(today.slice(8, 10))));\n const todayWeekday = (date.getUTCDay() + 6) % 7;\n let diff = (weekday - todayWeekday + 7) % 7;\n if (match[1] && match[1] !== \"am\" && match[1] !== \"on\" && diff === 0) diff = 7;\n return addDayKeys(today, diff);\n }\n }\n const months = [\n \"januar jan january\",\n \"februar feb february\",\n \"marz maerz mar mrz march\",\n \"april apr\",\n \"mai may\",\n \"juni jun june\",\n \"juli jul july\",\n \"august aug\",\n \"september sep sept\",\n \"oktober okt october oct\",\n \"november nov\",\n \"dezember dez december dec\",\n ];\n const monthOf = (name: string | undefined) => months.findIndex((names) => names.split(\" \").includes(name ?? \"\")) + 1;\n match = /^(\\d{1,2})\\.?\\s+([a-z]+)\\.?(?:\\s+(\\d{4}))?$/.exec(named);\n if (match) return validKey(fullYear(match[3]), monthOf(match[2]), Number(match[1]));\n match = /^([a-z]+)\\.?\\s+(\\d{1,2})(?:,?\\s+(\\d{4}))?$/.exec(named);\n if (match) return validKey(fullYear(match[3]), monthOf(match[1]), Number(match[2]));\n match = /^([a-z]+)\\.?(?:\\s+(\\d{4}))?$/.exec(named);\n if (match) {\n const month = monthOf(match[1]);\n const monthYear = match[2] ? Number(match[2]) : year + (month < Number(today.slice(5, 7)) ? 1 : 0);\n return validKey(monthYear, month, 1);\n }\n return null;\n};\n\n/** Go to: a field that reads a date or a week number and names the day it found before the reader goes there. */\nexport const openCalendarGoTo = (props: {\n messages: CalendarMessages;\n today: string;\n describe: (key: string) => string;\n onGo: (key: string) => void;\n}) =>\n dialogCore\n .open<string>(\n (close) => {\n const [text, setText] = createSignal(\"\");\n const result = () => parseGoTo(text(), props.today);\n return (\n <form\n class=\"k2b-dialog__panel\"\n onSubmit={(event) => {\n event.preventDefault();\n const key = result();\n if (key) close(key);\n }}\n >\n <DialogHeader title={props.messages.calendarCommandGoTo} icon=\"ti ti-calendar-search\" close={() => close()} />\n <div class=\"k2b-dialog__body k2b-calendar-goto\">\n <input\n class=\"k2b-calendar-goto__input\"\n type=\"text\"\n autocomplete=\"off\"\n spellcheck={false}\n aria-label={props.messages.calendarCommandGoTo}\n aria-describedby=\"k2b-calendar-goto-hint\"\n placeholder={props.messages.calendarGoToPlaceholder}\n value={text()}\n onInput={(event) => setText(event.currentTarget.value)}\n />\n <p class=\"k2b-calendar-goto__preview\" id=\"k2b-calendar-goto-hint\" aria-live=\"polite\" data-ok={result() ? \"true\" : undefined}>\n <Show when={result()} fallback={text().trim() ? props.messages.calendarGoToUnknown : props.messages.calendarGoToHint}>\n {(key) => `→ ${props.describe(key())}`}\n </Show>\n </p>\n </div>\n <footer class=\"k2b-dialog__actions\">\n <button type=\"submit\" class=\"k2b-button\" data-variant=\"primary\" data-size=\"sm\" disabled={!result()}>\n {props.messages.calendarGoToGo}\n </button>\n </footer>\n </form>\n );\n },\n { panelClassName: \"k2b-dialog k2b-dialog--small\", ariaLabel: props.messages.calendarCommandGoTo, initialFocus: \"first-input\" },\n )\n .then((key) => {\n if (key) props.onGo(key);\n });\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":[],"sources":["content/calendar-dialogs.tsx"],"sourcesContent":["import { createSignal, For, Show } from \"solid-js\";\nimport { dialogCore } from \"../feedback/dialog-core\";\nimport { DialogHeader } from \"../feedback/prompts\";\nimport type { CalendarCommand } from \"./Calendar\";\nimport { addDayKeys } from \"./calendar-days\";\nimport type { CalendarMessages } from \"./calendar-messages\";\nimport { Kbd } from \"./Kbd\";\n\n/**\n * The calendar's shortcuts: the same list the host registers for its dispatcher and its help. `alternatives` names\n * other keys the calendar itself handles for a command, such as the arrow keys that page like J and K.\n */\nexport const openCalendarShortcuts = (\n commands: readonly CalendarCommand[],\n messages: CalendarMessages,\n alternatives: Readonly<Record<string, string>> = {},\n) =>\n dialogCore.open<void>(\n (close) => (\n <div class=\"k2b-dialog__panel\">\n <DialogHeader title={messages.calendarShortcuts} icon=\"ti ti-keyboard\" close={() => close()} />\n <div class=\"k2b-dialog__body\">\n <dl class=\"k2b-calendar-shortcuts\">\n <For each={commands.filter((command) => command.shortcut)}>\n {(command) => (\n <>\n <dt>\n <Kbd keys={command.shortcut!} />\n <Show when={alternatives[command.id]}>\n {(other) => (\n <>\n <span class=\"k2b-calendar-shortcuts__or\">/</span>\n <Kbd keys={other()} />\n </>\n )}\n </Show>\n </dt>\n <dd>{command.label}</dd>\n </>\n )}\n </For>\n </dl>\n <p class=\"k2b-calendar-shortcuts__note\">{messages.calendarShortcutsNote}</p>\n </div>\n </div>\n ),\n { panelClassName: \"k2b-dialog k2b-dialog--small\", ariaLabel: messages.calendarShortcuts },\n );\n\nconst pad = (value: number) => String(value).padStart(2, \"0\");\nconst validKey = (year: number, month: number, day: number) => {\n const date = new Date(Date.UTC(year, month - 1, day));\n return date.getUTCFullYear() === year && date.getUTCMonth() === month - 1 && date.getUTCDate() === day\n ? `${year}-${pad(month)}-${pad(day)}`\n : null;\n};\n/** The Monday of an ISO week of a year. */\nconst isoWeekStart = (year: number, week: number) => {\n const january4 = new Date(Date.UTC(year, 0, 4));\n const monday = new Date(january4.getTime() - ((january4.getUTCDay() || 7) - 1) * 86_400_000);\n return addDayKeys(monday.toISOString().slice(0, 10), (week - 1) * 7);\n};\n\n/**\n * Reads German and English dates, weekdays, months, week numbers, today, and tomorrow for Go to. Weekdays include\n * today unless preceded by next; a month alone uses the next year if it has passed. A date without a year is this\n * year's. Names ignore case and accents and allow a trailing dot. Returns a `YYYY-MM-DD` key or `null`.\n */\nexport const parseGoTo = (text: string, today: string): string | null => {\n const value = text.trim().toLowerCase();\n if (!value) return null;\n const year = Number(today.slice(0, 4));\n if (/^(heute|today)$/.test(value)) return today;\n if (/^(morgen|tomorrow)$/.test(value)) return addDayKeys(today, 1);\n const fullYear = (raw: string | undefined) => (raw ? (raw.length === 2 ? 2000 + Number(raw) : Number(raw)) : year);\n let match = /^(\\d{4})-(\\d{1,2})-(\\d{1,2})$/.exec(value);\n if (match) return validKey(Number(match[1]), Number(match[2]), Number(match[3]));\n match = /^(\\d{1,2})\\.(\\d{1,2})\\.?(\\d{2}|\\d{4})?$/.exec(value);\n if (match) return validKey(fullYear(match[3]), Number(match[2]), Number(match[1]));\n match = /^(\\d{1,2})\\/(\\d{1,2})(?:\\/(\\d{2}|\\d{4}))?$/.exec(value);\n if (match) return validKey(fullYear(match[3]), Number(match[1]), Number(match[2]));\n match = /^(?:kw|w|week|woche)\\s*(\\d{1,2})(?:\\s*\\/?\\s*(\\d{4}))?$/.exec(value);\n if (match) {\n const week = Number(match[1]);\n return week >= 1 && week <= 53 ? isoWeekStart(match[2] ? Number(match[2]) : year, week) : null;\n }\n const named = value\n .normalize(\"NFD\")\n .replace(/[\\u0300-\\u036f]/g, \"\")\n .replace(/\\.$/, \"\")\n .trim();\n const weekdays = [\n \"montag mo monday mon\",\n \"dienstag di tuesday tue tues\",\n \"mittwoch mi wednesday wed\",\n \"donnerstag do thursday thu thur thurs\",\n \"freitag fr friday fri\",\n \"samstag sa saturday sat\",\n \"sonntag so sunday sun\",\n ];\n match = /^(?:(am|on|nachste|nachsten|nachster|naechsten|kommende|kommenden|next)\\s+)?([a-z]+)$/.exec(named);\n if (match) {\n const name = match[2];\n const weekday = weekdays.findIndex((names) => names.split(\" \").includes(name ?? \"\"));\n if (weekday >= 0) {\n const date = new Date(Date.UTC(year, Number(today.slice(5, 7)) - 1, Number(today.slice(8, 10))));\n const todayWeekday = (date.getUTCDay() + 6) % 7;\n let diff = (weekday - todayWeekday + 7) % 7;\n if (match[1] && match[1] !== \"am\" && match[1] !== \"on\" && diff === 0) diff = 7;\n return addDayKeys(today, diff);\n }\n }\n const months = [\n \"januar jan january\",\n \"februar feb february\",\n \"marz maerz mar mrz march\",\n \"april apr\",\n \"mai may\",\n \"juni jun june\",\n \"juli jul july\",\n \"august aug\",\n \"september sep sept\",\n \"oktober okt october oct\",\n \"november nov\",\n \"dezember dez december dec\",\n ];\n const monthOf = (name: string | undefined) => months.findIndex((names) => names.split(\" \").includes(name ?? \"\")) + 1;\n match = /^(\\d{1,2})\\.?\\s+([a-z]+)\\.?(?:\\s+(\\d{4}))?$/.exec(named);\n if (match) return validKey(fullYear(match[3]), monthOf(match[2]), Number(match[1]));\n match = /^([a-z]+)\\.?\\s+(\\d{1,2})(?:,?\\s+(\\d{4}))?$/.exec(named);\n if (match) return validKey(fullYear(match[3]), monthOf(match[1]), Number(match[2]));\n match = /^([a-z]+)\\.?(?:\\s+(\\d{4}))?$/.exec(named);\n if (match) {\n const month = monthOf(match[1]);\n const monthYear = match[2] ? Number(match[2]) : year + (month < Number(today.slice(5, 7)) ? 1 : 0);\n return validKey(monthYear, month, 1);\n }\n return null;\n};\n\n/** Go to: a field that reads a date or a week number and names the day it found before the reader goes there. */\nexport const openCalendarGoTo = (props: {\n messages: CalendarMessages;\n today: string;\n describe: (key: string) => string;\n onGo: (key: string) => void;\n}) =>\n dialogCore\n .open<string>(\n (close) => {\n const [text, setText] = createSignal(\"\");\n const result = () => parseGoTo(text(), props.today);\n return (\n <form\n class=\"k2b-dialog__panel\"\n onSubmit={(event) => {\n event.preventDefault();\n const key = result();\n if (key) close(key);\n }}\n >\n <DialogHeader title={props.messages.calendarCommandGoTo} icon=\"ti ti-calendar-search\" close={() => close()} />\n <div class=\"k2b-dialog__body k2b-calendar-goto\">\n <input\n class=\"k2b-calendar-goto__input\"\n type=\"text\"\n autocomplete=\"off\"\n spellcheck={false}\n aria-label={props.messages.calendarCommandGoTo}\n aria-describedby=\"k2b-calendar-goto-hint\"\n placeholder={props.messages.calendarGoToPlaceholder}\n value={text()}\n onInput={(event) => setText(event.currentTarget.value)}\n />\n <p class=\"k2b-calendar-goto__preview\" id=\"k2b-calendar-goto-hint\" aria-live=\"polite\" data-ok={result() ? \"true\" : undefined}>\n <Show when={result()} fallback={text().trim() ? props.messages.calendarGoToUnknown : props.messages.calendarGoToHint}>\n {(key) => `→ ${props.describe(key())}`}\n </Show>\n </p>\n </div>\n <footer class=\"k2b-dialog__actions\">\n <button type=\"submit\" class=\"k2b-button\" data-variant=\"primary\" data-size=\"sm\" disabled={!result()}>\n {props.messages.calendarGoToGo}\n </button>\n </footer>\n </form>\n );\n },\n { panelClassName: \"k2b-dialog k2b-dialog--small\", ariaLabel: props.messages.calendarCommandGoTo, initialFocus: \"first-input\" },\n )\n .then((key) => {\n if (key) props.onGo(key);\n });\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scroll rules of the continuous month view, free of the DOM so they can be tested.
|
|
3
|
+
*
|
|
4
|
+
* Uniform week rows run below a sticky weekday header without stops. The center row names the month, and rows
|
|
5
|
+
* visible by more than half supply the host's dates. Calendar day keys keep week arithmetic independent of DST.
|
|
6
|
+
*/
|
|
7
|
+
import { addDayKeys, dayKeyNumber } from "./calendar-days";
|
|
8
|
+
export const MONTH_ROWS_IN_VIEW = 5;
|
|
9
|
+
export const MONTH_ROW_BLOCK = 8;
|
|
10
|
+
|
|
11
|
+
/** Whole weeks covering the loaded days, with an exclusive end and the date context's first weekday. */
|
|
12
|
+
export const monthWeekKeys = (first, to, firstDayOfWeek) => {
|
|
13
|
+
if (first >= to) return [];
|
|
14
|
+
const weekday = ((dayKeyNumber(first) + 4) % 7 + 7) % 7;
|
|
15
|
+
const start = addDayKeys(first, -((weekday - firstDayOfWeek + 7) % 7));
|
|
16
|
+
const count = Math.ceil((dayKeyNumber(to) - dayKeyNumber(start)) / 7);
|
|
17
|
+
return Array.from({
|
|
18
|
+
length: count
|
|
19
|
+
}, (_, index) => addDayKeys(start, index * 7));
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
/** The row at the center of the area below the weekday header, clamped to the loaded weeks. */
|
|
23
|
+
export const monthFocusRow = (top, viewHeight, rowHeight, total) => Math.max(0, Math.min(total - 1, rowHeight > 0 ? Math.floor((top + viewHeight / 2) / rowHeight) : 0));
|
|
24
|
+
|
|
25
|
+
/** The middle day of a week names its month: Thursday for Monday weeks, Wednesday for Sunday weeks. */
|
|
26
|
+
export const monthOfWeek = week => `${addDayKeys(week, 3).slice(0, 7)}-01`;
|
|
27
|
+
|
|
28
|
+
/** The loaded row containing a day, including the first of a month; absent outside the loaded weeks. */
|
|
29
|
+
export const monthRowOf = (weeks, key) => {
|
|
30
|
+
if (!weeks.length) return undefined;
|
|
31
|
+
const row = Math.floor((dayKeyNumber(key) - dayKeyNumber(weeks[0])) / 7);
|
|
32
|
+
return row >= 0 && row < weeks.length ? row : undefined;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/** The half-open interval of rows whose visible height exceeds half a row. */
|
|
36
|
+
export const monthVisibleRows = (top, viewHeight, rowHeight, total) => {
|
|
37
|
+
if (rowHeight <= 0 || total === 0) return {
|
|
38
|
+
first: 0,
|
|
39
|
+
end: 0
|
|
40
|
+
};
|
|
41
|
+
const first = Math.max(0, Math.min(total, Math.floor(top / rowHeight + 0.5)));
|
|
42
|
+
const end = Math.max(first, Math.min(total, Math.ceil((top + viewHeight) / rowHeight - 0.5)));
|
|
43
|
+
return {
|
|
44
|
+
first,
|
|
45
|
+
end
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/** One block above and below the visible rows' blocks; the window changes only at their block boundaries. */
|
|
50
|
+
export const monthRenderWindow = (top, viewHeight, rowHeight, total) => {
|
|
51
|
+
if (rowHeight <= 0 || total === 0) return {
|
|
52
|
+
first: 0,
|
|
53
|
+
end: 0
|
|
54
|
+
};
|
|
55
|
+
const {
|
|
56
|
+
first,
|
|
57
|
+
end
|
|
58
|
+
} = monthVisibleRows(top, viewHeight, rowHeight, total);
|
|
59
|
+
const last = Math.max(first, end - 1);
|
|
60
|
+
return {
|
|
61
|
+
first: Math.max(0, (Math.floor(first / MONTH_ROW_BLOCK) - 1) * MONTH_ROW_BLOCK),
|
|
62
|
+
end: Math.min(total, (Math.floor(last / MONTH_ROW_BLOCK) + 2) * MONTH_ROW_BLOCK)
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
/** The least movement that shows a row whole, or nothing when it is already fully in view. */
|
|
67
|
+
export const monthRevealTop = (row, top, viewHeight, rowHeight) => {
|
|
68
|
+
const start = row * rowHeight;
|
|
69
|
+
if (start < top) return start;
|
|
70
|
+
if (start + rowHeight > top + viewHeight) return Math.max(0, start + rowHeight - viewHeight);
|
|
71
|
+
return undefined;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
/** Today points up or down until more than half its row is visible. */
|
|
75
|
+
export const monthTodayDirection = (row, top, viewHeight, rowHeight) => {
|
|
76
|
+
const start = row * rowHeight;
|
|
77
|
+
const visible = Math.min(start + rowHeight, top + viewHeight) - Math.max(start, top);
|
|
78
|
+
return visible > rowHeight / 2 ? "" : start < top ? "up" : "down";
|
|
79
|
+
};
|
|
80
|
+
//# sourceMappingURL=calendar-month-scroll.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":[],"sources":["content/calendar-month-scroll.ts"],"sourcesContent":["/**\n * Scroll rules of the continuous month view, free of the DOM so they can be tested.\n *\n * Uniform week rows run below a sticky weekday header without stops. The center row names the month, and rows\n * visible by more than half supply the host's dates. Calendar day keys keep week arithmetic independent of DST.\n */\nimport { addDayKeys, dayKeyNumber } from \"./calendar-days\";\nimport type { TodayDirection } from \"./calendar-time-view\";\n\nexport const MONTH_ROWS_IN_VIEW = 5;\nexport const MONTH_ROW_BLOCK = 8;\n\n/** Whole weeks covering the loaded days, with an exclusive end and the date context's first weekday. */\nexport const monthWeekKeys = (first: string, to: string, firstDayOfWeek: 0 | 1): string[] => {\n if (first >= to) return [];\n const weekday = (((dayKeyNumber(first) + 4) % 7) + 7) % 7;\n const start = addDayKeys(first, -((weekday - firstDayOfWeek + 7) % 7));\n const count = Math.ceil((dayKeyNumber(to) - dayKeyNumber(start)) / 7);\n return Array.from({ length: count }, (_, index) => addDayKeys(start, index * 7));\n};\n\n/** The row at the center of the area below the weekday header, clamped to the loaded weeks. */\nexport const monthFocusRow = (top: number, viewHeight: number, rowHeight: number, total: number): number =>\n Math.max(0, Math.min(total - 1, rowHeight > 0 ? Math.floor((top + viewHeight / 2) / rowHeight) : 0));\n\n/** The middle day of a week names its month: Thursday for Monday weeks, Wednesday for Sunday weeks. */\nexport const monthOfWeek = (week: string): string => `${addDayKeys(week, 3).slice(0, 7)}-01`;\n\n/** The loaded row containing a day, including the first of a month; absent outside the loaded weeks. */\nexport const monthRowOf = (weeks: readonly string[], key: string): number | undefined => {\n if (!weeks.length) return undefined;\n const row = Math.floor((dayKeyNumber(key) - dayKeyNumber(weeks[0]!)) / 7);\n return row >= 0 && row < weeks.length ? row : undefined;\n};\n\n/** The half-open interval of rows whose visible height exceeds half a row. */\nexport const monthVisibleRows = (top: number, viewHeight: number, rowHeight: number, total: number): { first: number; end: number } => {\n if (rowHeight <= 0 || total === 0) return { first: 0, end: 0 };\n const first = Math.max(0, Math.min(total, Math.floor(top / rowHeight + 0.5)));\n const end = Math.max(first, Math.min(total, Math.ceil((top + viewHeight) / rowHeight - 0.5)));\n return { first, end };\n};\n\n/** One block above and below the visible rows' blocks; the window changes only at their block boundaries. */\nexport const monthRenderWindow = (top: number, viewHeight: number, rowHeight: number, total: number): { first: number; end: number } => {\n if (rowHeight <= 0 || total === 0) return { first: 0, end: 0 };\n const { first, end } = monthVisibleRows(top, viewHeight, rowHeight, total);\n const last = Math.max(first, end - 1);\n return {\n first: Math.max(0, (Math.floor(first / MONTH_ROW_BLOCK) - 1) * MONTH_ROW_BLOCK),\n end: Math.min(total, (Math.floor(last / MONTH_ROW_BLOCK) + 2) * MONTH_ROW_BLOCK),\n };\n};\n\n/** The least movement that shows a row whole, or nothing when it is already fully in view. */\nexport const monthRevealTop = (row: number, top: number, viewHeight: number, rowHeight: number): number | undefined => {\n const start = row * rowHeight;\n if (start < top) return start;\n if (start + rowHeight > top + viewHeight) return Math.max(0, start + rowHeight - viewHeight);\n return undefined;\n};\n\n/** Today points up or down until more than half its row is visible. */\nexport const monthTodayDirection = (row: number, top: number, viewHeight: number, rowHeight: number): TodayDirection => {\n const start = row * rowHeight;\n const visible = Math.min(start + rowHeight, top + viewHeight) - Math.max(start, top);\n return visible > rowHeight / 2 ? \"\" : start < top ? \"up\" : \"down\";\n};\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -15,15 +15,18 @@ export { FileBrowserPanel, openFileBrowser } from "./FileBrowser";
|
|
|
15
15
|
export { FileGrid } from "./FileGrid";
|
|
16
16
|
export { default as FileTree } from "./FileTree";
|
|
17
17
|
export { canPreviewFile, default as FileView, formatFileViewSize, getFileViewPreviewKind } from "./FileView";
|
|
18
|
+
export { Kbd } from "./Kbd";
|
|
19
|
+
export { LabelChip } from "./LabelChip";
|
|
18
20
|
export { default as Lightbox } from "./Lightbox";
|
|
19
21
|
export { default as LogEntriesTable } from "./LogEntriesTable";
|
|
20
22
|
export { default as MarkdownView, renderSafeMarkdown } from "./MarkdownView";
|
|
21
23
|
export { MessageRow, MessageSystemRow, startsMessageGroup } from "./MessageRow";
|
|
22
|
-
export { markdownInfoBlocks, renderMarkdownInfoBlock, scanMarkdownInfoBlock } from "./markdown-info-blocks";
|
|
24
|
+
export { MARKDOWN_CALLOUT_CLASSES, MARKDOWN_CALLOUT_ICON_ATTRIBUTES, markdownInfoBlocks, renderMarkdownInfoBlock, scanMarkdownInfoBlock } from "./markdown-info-blocks";
|
|
23
25
|
export { markdownLinkReference, markdownReferenceIcon, markdownReferenceType, markdownReferenceTypeLabel, markStandaloneLinks, renderMarkdownLink } from "./markdown-links";
|
|
24
26
|
export { Pagination } from "./Pagination";
|
|
25
27
|
export { default as PdfPreview } from "./PdfPreview";
|
|
26
28
|
export { default as RangePicker } from "./RangePicker";
|
|
29
|
+
export { Steps } from "./Steps";
|
|
27
30
|
export { default as StructuredDataPreview, isStructuredDataValue } from "./StructuredDataPreview";
|
|
28
31
|
export { default as Timeline } from "./Timeline";
|
|
29
32
|
export { VideoPlayer } from "./VideoPlayer";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["content/index.ts"],"sourcesContent":["export type {\n CalendarAttendee,\n CalendarCommand,\n CalendarController,\n CalendarCustomView,\n CalendarDayBadge,\n CalendarEvent,\n CalendarEventColor,\n CalendarEventRenderContext,\n CalendarEventTimeChange,\n CalendarExternalDrag,\n CalendarLabels,\n CalendarProps,\n CalendarQuickCreateControls,\n CalendarRange,\n CalendarRecurrence,\n CalendarResource,\n CalendarSelectionControls,\n CalendarView,\n} from \"./Calendar\";\nexport { default as Calendar } from \"./Calendar\";\n\nexport type { ChartKind, ChartLabels, ChartProps, ChartRenderOptions } from \"./Chart\";\nexport { default as Chart } from \"./Chart\";\nexport type { ChartExplorerColumn, ChartExplorerProps, ChartLegendEntry } from \"./ChartExplorer\";\nexport { ChartExplorer } from \"./ChartExplorer\";\nexport type { ChartExplorerControlsProps } from \"./ChartExplorerControls\";\nexport { ChartExplorerControls } from \"./ChartExplorerControls\";\nexport { ChartFilterControls, type ChartFilterControlsProps } from \"./ChartFilterControls\";\nexport { ChartSnapshotView } from \"./ChartSnapshotView\";\nexport type { CodeDisplayLanguage, CodeDisplayProps } from \"./CodeDisplay\";\nexport { default as CodeDisplay } from \"./CodeDisplay\";\nexport { type ChartCursor, createChartCursor } from \"./chart-cursor\";\nexport type {\n ChartExplorerCharts,\n ChartExplorerController,\n ChartExplorerData,\n ChartExplorerOptions,\n ChartExplorerRequest,\n ChartExplorerRow,\n ChartExplorerSnapshot,\n} from \"./chart-explorer\";\nexport { createChartExplorer } from \"./chart-explorer\";\nexport type { ChartDatumRef, ChartSelection, ChartTooltip, ChartTooltipFormatter } from \"./chart-inspection\";\nexport type { ChartSnapshot } from \"./chart-snapshot\";\nexport { prepareChartSnapshot } from \"./chart-snapshot\";\nexport type {\n StateTimelineChartOptions,\n StateTimelineDomain,\n StateTimelineInterval,\n StateTimelineRow,\n StateTimelineState,\n} from \"./chart-state-timeline\";\nexport { type CollectionSelection, createCollectionSelection, type SelectionModifiers } from \"./collection-selection\";\nexport type {\n DataTableColumn,\n DataTableControlsProps,\n DataTableFooter,\n DataTableHeaderProps,\n DataTablePanelFooterProps,\n DataTablePanelProps,\n DataTableProps,\n DataTableRenderCell,\n DataTableRenderHeader,\n DataTableSort,\n} from \"./DataTable\";\nexport { default as DataTable } from \"./DataTable\";\nexport type { DocCodeHighlighter, DocCodeProps, DocConcept, DocNoteVariant, DocRow } from \"./Docs\";\nexport { DocCode, DocConceptGrid, DocInlineCode, DocLead, DocNote, DocPage, DocRows, DocSection } from \"./Docs\";\nexport { FileBrowserPanel, type FileBrowserPanelProps, type FileSource, openFileBrowser } from \"./FileBrowser\";\nexport { FileGrid, type FileGridProps } from \"./FileGrid\";\nexport { default as FileTree, type FileTreeActions, type FileTreeEntry, type FileTreeProps } from \"./FileTree\";\nexport {\n canPreviewFile,\n default as FileView,\n type FileViewContent,\n type FileViewFile,\n type FileViewPreviewKind,\n type FileViewProps,\n type FileViewRenderer,\n type FileViewRendererProps,\n formatFileViewSize,\n getFileViewPreviewKind,\n} from \"./FileView\";\nexport type { LightboxAction, LightboxImage } from \"./Lightbox\";\nexport { default as Lightbox } from \"./Lightbox\";\nexport type { LogTableEntry } from \"./LogEntriesTable\";\nexport { default as LogEntriesTable } from \"./LogEntriesTable\";\nexport { default as MarkdownView, type MarkdownRenderOptions, type MarkdownViewProps, renderSafeMarkdown } from \"./MarkdownView\";\nexport type {\n MessageGroupEntry,\n MessageRowAction,\n MessageRowAttachment,\n MessageRowAuthor,\n MessageRowFile,\n MessageRowMedia,\n MessageRowProgress,\n MessageRowProps,\n MessageRowQuote,\n MessageRowReaction,\n MessageRowStatus,\n MessageRowThread,\n MessageSystemRowProps,\n} from \"./MessageRow\";\nexport { MessageRow, MessageSystemRow, startsMessageGroup } from \"./MessageRow\";\nexport {\n type MarkdownInfoBlock,\n type MarkdownInfoBlockRenderInput,\n type MarkdownInfoBlockType,\n markdownInfoBlocks,\n renderMarkdownInfoBlock,\n scanMarkdownInfoBlock,\n} from \"./markdown-info-blocks\";\nexport {\n type MarkdownLinkInput,\n type MarkdownReference,\n type MarkdownReferenceKind,\n type MarkdownReferenceType,\n markdownLinkReference,\n markdownReferenceIcon,\n markdownReferenceType,\n markdownReferenceTypeLabel,\n markStandaloneLinks,\n renderMarkdownLink,\n} from \"./markdown-links\";\nexport { Pagination, type PaginationProps } from \"./Pagination\";\nexport type { PdfPreviewProps, PdfPreviewRequest } from \"./PdfPreview\";\nexport { default as PdfPreview } from \"./PdfPreview\";\nexport type { RangeOption, RangePickerProps } from \"./RangePicker\";\nexport { default as RangePicker } from \"./RangePicker\";\nexport type { StructuredDataPreviewMode, StructuredDataPreviewProps, StructuredDataValue } from \"./StructuredDataPreview\";\nexport { default as StructuredDataPreview, isStructuredDataValue } from \"./StructuredDataPreview\";\nexport type { TimelineColor, TimelineController, TimelineItem, TimelineProps } from \"./Timeline\";\nexport { default as Timeline } from \"./Timeline\";\nexport { VideoPlayer, type VideoPlayerProps } from \"./VideoPlayer\";\nexport type { VirtualFeedController, VirtualFeedProps, VirtualFeedScrollOptions } from \"./VirtualFeed\";\nexport { VirtualFeed } from \"./VirtualFeed\";\nexport type { ZoomPanAction, ZoomPanFullscreen, ZoomPanViewportProps } from \"./ZoomPanViewport\";\nexport { ZoomPanViewport } from \"./ZoomPanViewport\";\n"],"mappings":"AAoBA,SAAS,OAAO,IAAI,QAAQ,QAAQ,YAAY;AAGhD,SAAS,OAAO,IAAI,KAAK,QAAQ,SAAS;AAE1C,SAAS,aAAa,QAAQ,iBAAiB;AAE/C,SAAS,qBAAqB,QAAQ,yBAAyB;AAC/D,SAAS,mBAAmB,QAAuC,uBAAuB;AAC1F,SAAS,iBAAiB,QAAQ,qBAAqB;AAEvD,SAAS,OAAO,IAAI,WAAW,QAAQ,eAAe;AACtD,SAA2B,iBAAiB,QAAQ,gBAAgB;AAUpE,SAAS,mBAAmB,QAAQ,kBAAkB;AAGtD,SAAS,oBAAoB,QAAQ,kBAAkB;AAQvD,SAAmC,yBAAyB,QAAiC,wBAAwB;AAarH,SAAS,OAAO,IAAI,SAAS,QAAQ,aAAa;AAElD,SAAS,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,QAAQ,QAAQ;AAC/G,SAAS,gBAAgB,EAA+C,eAAe,QAAQ,eAAe;AAC9G,SAAS,QAAQ,QAA4B,YAAY;AACzD,SAAS,OAAO,IAAI,QAAQ,QAAsE,YAAY;AAC9G,SACE,cAAc,EACd,OAAO,IAAI,QAAQ,EAOnB,kBAAkB,EAClB,sBAAsB,QACjB,YAAY;AAEnB,SAAS,OAAO,IAAI,QAAQ,QAAQ,YAAY;AAEhD,SAAS,OAAO,IAAI,eAAe,QAAQ,mBAAmB;AAC9D,SAAS,OAAO,IAAI,YAAY,EAAsD,kBAAkB,QAAQ,gBAAgB;AAgBhI,SAAS,UAAU,EAAE,gBAAgB,EAAE,kBAAkB,QAAQ,cAAc;AAC/E,
|
|
1
|
+
{"version":3,"names":[],"sources":["content/index.ts"],"sourcesContent":["export type {\n CalendarAttendee,\n CalendarCommand,\n CalendarController,\n CalendarCustomView,\n CalendarDayBadge,\n CalendarEvent,\n CalendarEventColor,\n CalendarEventRenderContext,\n CalendarEventTimeChange,\n CalendarExternalDrag,\n CalendarLabels,\n CalendarProps,\n CalendarQuickCreateControls,\n CalendarRange,\n CalendarRecurrence,\n CalendarResource,\n CalendarSelectionControls,\n CalendarView,\n} from \"./Calendar\";\nexport { default as Calendar } from \"./Calendar\";\n\nexport type { ChartKind, ChartLabels, ChartProps, ChartRenderOptions } from \"./Chart\";\nexport { default as Chart } from \"./Chart\";\nexport type { ChartExplorerColumn, ChartExplorerProps, ChartLegendEntry } from \"./ChartExplorer\";\nexport { ChartExplorer } from \"./ChartExplorer\";\nexport type { ChartExplorerControlsProps } from \"./ChartExplorerControls\";\nexport { ChartExplorerControls } from \"./ChartExplorerControls\";\nexport { ChartFilterControls, type ChartFilterControlsProps } from \"./ChartFilterControls\";\nexport { ChartSnapshotView } from \"./ChartSnapshotView\";\nexport type { CodeDisplayLanguage, CodeDisplayProps } from \"./CodeDisplay\";\nexport { default as CodeDisplay } from \"./CodeDisplay\";\nexport { type ChartCursor, createChartCursor } from \"./chart-cursor\";\nexport type {\n ChartExplorerCharts,\n ChartExplorerController,\n ChartExplorerData,\n ChartExplorerOptions,\n ChartExplorerRequest,\n ChartExplorerRow,\n ChartExplorerSnapshot,\n} from \"./chart-explorer\";\nexport { createChartExplorer } from \"./chart-explorer\";\nexport type { ChartDatumRef, ChartSelection, ChartTooltip, ChartTooltipFormatter } from \"./chart-inspection\";\nexport type { ChartSnapshot } from \"./chart-snapshot\";\nexport { prepareChartSnapshot } from \"./chart-snapshot\";\nexport type {\n StateTimelineChartOptions,\n StateTimelineDomain,\n StateTimelineInterval,\n StateTimelineRow,\n StateTimelineState,\n} from \"./chart-state-timeline\";\nexport { type CollectionSelection, createCollectionSelection, type SelectionModifiers } from \"./collection-selection\";\nexport type {\n DataTableColumn,\n DataTableControlsProps,\n DataTableFooter,\n DataTableHeaderProps,\n DataTablePanelFooterProps,\n DataTablePanelProps,\n DataTableProps,\n DataTableRenderCell,\n DataTableRenderHeader,\n DataTableSort,\n} from \"./DataTable\";\nexport { default as DataTable } from \"./DataTable\";\nexport type { DocCodeHighlighter, DocCodeProps, DocConcept, DocNoteVariant, DocRow } from \"./Docs\";\nexport { DocCode, DocConceptGrid, DocInlineCode, DocLead, DocNote, DocPage, DocRows, DocSection } from \"./Docs\";\nexport { FileBrowserPanel, type FileBrowserPanelProps, type FileSource, openFileBrowser } from \"./FileBrowser\";\nexport { FileGrid, type FileGridProps } from \"./FileGrid\";\nexport { default as FileTree, type FileTreeActions, type FileTreeEntry, type FileTreeProps } from \"./FileTree\";\nexport {\n canPreviewFile,\n default as FileView,\n type FileViewContent,\n type FileViewFile,\n type FileViewPreviewKind,\n type FileViewProps,\n type FileViewRenderer,\n type FileViewRendererProps,\n formatFileViewSize,\n getFileViewPreviewKind,\n} from \"./FileView\";\nexport type { KbdProps } from \"./Kbd\";\nexport { Kbd } from \"./Kbd\";\nexport type { LabelChipProps } from \"./LabelChip\";\nexport { LabelChip } from \"./LabelChip\";\nexport type { LightboxAction, LightboxImage } from \"./Lightbox\";\nexport { default as Lightbox } from \"./Lightbox\";\nexport type { LogTableEntry } from \"./LogEntriesTable\";\nexport { default as LogEntriesTable } from \"./LogEntriesTable\";\nexport { default as MarkdownView, type MarkdownRenderOptions, type MarkdownViewProps, renderSafeMarkdown } from \"./MarkdownView\";\nexport type {\n MessageGroupEntry,\n MessageRowAction,\n MessageRowAttachment,\n MessageRowAuthor,\n MessageRowFile,\n MessageRowMedia,\n MessageRowProgress,\n MessageRowProps,\n MessageRowQuote,\n MessageRowReaction,\n MessageRowStatus,\n MessageRowThread,\n MessageSystemRowProps,\n} from \"./MessageRow\";\nexport { MessageRow, MessageSystemRow, startsMessageGroup } from \"./MessageRow\";\nexport {\n MARKDOWN_CALLOUT_CLASSES,\n MARKDOWN_CALLOUT_ICON_ATTRIBUTES,\n type MarkdownInfoBlock,\n type MarkdownInfoBlockRenderInput,\n type MarkdownInfoBlockType,\n markdownInfoBlocks,\n renderMarkdownInfoBlock,\n scanMarkdownInfoBlock,\n} from \"./markdown-info-blocks\";\nexport {\n type MarkdownLinkInput,\n type MarkdownReference,\n type MarkdownReferenceKind,\n type MarkdownReferenceType,\n markdownLinkReference,\n markdownReferenceIcon,\n markdownReferenceType,\n markdownReferenceTypeLabel,\n markStandaloneLinks,\n renderMarkdownLink,\n} from \"./markdown-links\";\nexport { Pagination, type PaginationProps } from \"./Pagination\";\nexport type { PdfPreviewProps, PdfPreviewRequest } from \"./PdfPreview\";\nexport { default as PdfPreview } from \"./PdfPreview\";\nexport type { RangeOption, RangePickerProps } from \"./RangePicker\";\nexport { default as RangePicker } from \"./RangePicker\";\nexport type { StepsProps } from \"./Steps\";\nexport { Steps } from \"./Steps\";\nexport type { StructuredDataPreviewMode, StructuredDataPreviewProps, StructuredDataValue } from \"./StructuredDataPreview\";\nexport { default as StructuredDataPreview, isStructuredDataValue } from \"./StructuredDataPreview\";\nexport type { TimelineColor, TimelineController, TimelineItem, TimelineProps } from \"./Timeline\";\nexport { default as Timeline } from \"./Timeline\";\nexport { VideoPlayer, type VideoPlayerProps } from \"./VideoPlayer\";\nexport type { VirtualFeedController, VirtualFeedProps, VirtualFeedScrollOptions } from \"./VirtualFeed\";\nexport { VirtualFeed } from \"./VirtualFeed\";\nexport type { ZoomPanAction, ZoomPanFullscreen, ZoomPanViewportProps } from \"./ZoomPanViewport\";\nexport { ZoomPanViewport } from \"./ZoomPanViewport\";\n"],"mappings":"AAoBA,SAAS,OAAO,IAAI,QAAQ,QAAQ,YAAY;AAGhD,SAAS,OAAO,IAAI,KAAK,QAAQ,SAAS;AAE1C,SAAS,aAAa,QAAQ,iBAAiB;AAE/C,SAAS,qBAAqB,QAAQ,yBAAyB;AAC/D,SAAS,mBAAmB,QAAuC,uBAAuB;AAC1F,SAAS,iBAAiB,QAAQ,qBAAqB;AAEvD,SAAS,OAAO,IAAI,WAAW,QAAQ,eAAe;AACtD,SAA2B,iBAAiB,QAAQ,gBAAgB;AAUpE,SAAS,mBAAmB,QAAQ,kBAAkB;AAGtD,SAAS,oBAAoB,QAAQ,kBAAkB;AAQvD,SAAmC,yBAAyB,QAAiC,wBAAwB;AAarH,SAAS,OAAO,IAAI,SAAS,QAAQ,aAAa;AAElD,SAAS,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,QAAQ,QAAQ;AAC/G,SAAS,gBAAgB,EAA+C,eAAe,QAAQ,eAAe;AAC9G,SAAS,QAAQ,QAA4B,YAAY;AACzD,SAAS,OAAO,IAAI,QAAQ,QAAsE,YAAY;AAC9G,SACE,cAAc,EACd,OAAO,IAAI,QAAQ,EAOnB,kBAAkB,EAClB,sBAAsB,QACjB,YAAY;AAEnB,SAAS,GAAG,QAAQ,OAAO;AAE3B,SAAS,SAAS,QAAQ,aAAa;AAEvC,SAAS,OAAO,IAAI,QAAQ,QAAQ,YAAY;AAEhD,SAAS,OAAO,IAAI,eAAe,QAAQ,mBAAmB;AAC9D,SAAS,OAAO,IAAI,YAAY,EAAsD,kBAAkB,QAAQ,gBAAgB;AAgBhI,SAAS,UAAU,EAAE,gBAAgB,EAAE,kBAAkB,QAAQ,cAAc;AAC/E,SACE,wBAAwB,EACxB,gCAAgC,EAIhC,kBAAkB,EAClB,uBAAuB,EACvB,qBAAqB,QAChB,wBAAwB;AAC/B,SAKE,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,0BAA0B,EAC1B,mBAAmB,EACnB,kBAAkB,QACb,kBAAkB;AACzB,SAAS,UAAU,QAA8B,cAAc;AAE/D,SAAS,OAAO,IAAI,UAAU,QAAQ,cAAc;AAEpD,SAAS,OAAO,IAAI,WAAW,QAAQ,eAAe;AAEtD,SAAS,KAAK,QAAQ,SAAS;AAE/B,SAAS,OAAO,IAAI,qBAAqB,EAAE,qBAAqB,QAAQ,yBAAyB;AAEjG,SAAS,OAAO,IAAI,QAAQ,QAAQ,YAAY;AAChD,SAAS,WAAW,QAA+B,eAAe;AAElE,SAAS,WAAW,QAAQ,eAAe;AAE3C,SAAS,eAAe,QAAQ,mBAAmB","ignoreList":[]}
|
|
@@ -25,6 +25,33 @@ const TONES = {
|
|
|
25
25
|
warning: "warning",
|
|
26
26
|
danger: "danger"
|
|
27
27
|
};
|
|
28
|
+
|
|
29
|
+
// Tabler outline paths (@tabler/icons 3.48.0), without the transparent canvas path.
|
|
30
|
+
const ICON_PATHS = {
|
|
31
|
+
note: ["M13 20l7 -7", "M13 20v-6a1 1 0 0 1 1 -1h6v-7a2 2 0 0 0 -2 -2h-12a2 2 0 0 0 -2 2v12a2 2 0 0 0 2 2h7"],
|
|
32
|
+
info: ["M3 12a9 9 0 1 0 18 0a9 9 0 0 0 -18 0", "M12 9h.01", "M11 12h1v4h1"],
|
|
33
|
+
success: ["M3 12a9 9 0 1 0 18 0a9 9 0 1 0 -18 0", "M9 12l2 2l4 -4"],
|
|
34
|
+
warning: ["M12 9v4", "M10.363 3.591l-8.106 13.534a1.914 1.914 0 0 0 1.636 2.871h16.214a1.914 1.914 0 0 0 1.636 -2.87l-8.106 -13.536a1.914 1.914 0 0 0 -3.274 0", "M12 16h.01"],
|
|
35
|
+
danger: ["M12.802 2.165l5.575 2.389c.48 .206 .863 .589 1.07 1.07l2.388 5.574c.22 .512 .22 1.092 0 1.604l-2.389 5.575c-.206 .48 -.589 .863 -1.07 1.07l-5.574 2.388c-.512 .22 -1.092 .22 -1.604 0l-5.575 -2.389a2.036 2.036 0 0 1 -1.07 -1.07l-2.388 -5.574a2.036 2.036 0 0 1 0 -1.604l2.389 -5.575c.206 -.48 .589 -.863 1.07 -1.07l5.574 -2.388a2.036 2.036 0 0 1 1.604 0", "M12 8v4", "M12 16h.01"]
|
|
36
|
+
};
|
|
37
|
+
export const MARKDOWN_CALLOUT_CLASSES = {
|
|
38
|
+
root: "k2b-callout",
|
|
39
|
+
icon: "k2b-callout__icon"
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
/** Fixed attributes for decorative callout icons, including hosts with their own sanitizer. */
|
|
43
|
+
export const MARKDOWN_CALLOUT_ICON_ATTRIBUTES = {
|
|
44
|
+
class: MARKDOWN_CALLOUT_CLASSES.icon,
|
|
45
|
+
"aria-hidden": "true",
|
|
46
|
+
width: "20",
|
|
47
|
+
height: "20",
|
|
48
|
+
viewBox: "0 0 24 24",
|
|
49
|
+
fill: "none",
|
|
50
|
+
stroke: "currentColor",
|
|
51
|
+
"stroke-width": "2",
|
|
52
|
+
"stroke-linecap": "round",
|
|
53
|
+
"stroke-linejoin": "round"
|
|
54
|
+
};
|
|
28
55
|
const OPENER = /^( {0,3}):::(note|info|success|warning|danger)(?:[ \t]+(.*?))?[ \t]*$/i;
|
|
29
56
|
const START = /^ {0,3}:::(?:note|info|success|warning|danger)(?=[ \t\n]|$)/i;
|
|
30
57
|
const OPENERS = /(?<=^|\n) {0,3}:::(?:note|info|success|warning|danger)(?=[ \t\n]|$)/gi;
|
|
@@ -208,14 +235,15 @@ export const scanMarkdownInfoBlock = source => {
|
|
|
208
235
|
};
|
|
209
236
|
const renderBlock = (input, messages) => {
|
|
210
237
|
const name = input.title ? `<p class="${NOTICE_CARD_CLASSES.title}">${escapeHtml(input.title)}</p>` : `<span class="k2b-sr-only">${escapeHtml(LABELS[input.type](messages))}: </span>`;
|
|
211
|
-
|
|
238
|
+
const icon = `<svg ${Object.entries(MARKDOWN_CALLOUT_ICON_ATTRIBUTES).map(([name, value]) => `${name}="${value}"`).join(" ")}>${ICON_PATHS[input.type].map(d => `<path d="${d}"></path>`).join("")}</svg>`;
|
|
239
|
+
return `<aside class="${NOTICE_CARD_CLASSES.root} ${MARKDOWN_CALLOUT_CLASSES.root}" data-tone="${TONES[input.type]}" role="note">${icon}${name}<div class="${NOTICE_CARD_CLASSES.body}">${input.bodyHtml}</div></aside>`;
|
|
212
240
|
};
|
|
213
241
|
|
|
214
242
|
/**
|
|
215
|
-
* Renders
|
|
216
|
-
*
|
|
217
|
-
* and names the block; without one,
|
|
218
|
-
*
|
|
243
|
+
* Renders a callout on a tinted surface without a border. The decorative icon
|
|
244
|
+
* and title use the tone colour; body text stays neutral. A title is the
|
|
245
|
+
* visible heading and names the block; without one, screen readers hear the
|
|
246
|
+
* localized type name.
|
|
219
247
|
*/
|
|
220
248
|
export const renderMarkdownInfoBlock = input => renderBlock(input, resolveMarkdownInfoBlockMessages(input.locale));
|
|
221
249
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["content/markdown-info-blocks.ts"],"sourcesContent":["import { Lexer, type MarkedExtension, Tokenizer, type TokenizerAndRendererExtension } from \"marked\";\nimport { NOTICE_CARD_CLASSES, type NoticeTone } from \"../surfaces/NoticeCard\";\nimport { type MarkdownInfoBlockMessages, resolveMarkdownInfoBlockMessages } from \"./markdown-info-block-messages\";\n\n/**\n * Markdown info blocks: one grammar and one look for every Markdown surface.\n *\n * ```markdown\n * :::warning Before deleting\n * Deleting an item cannot be undone.\n * :::\n * ```\n *\n * The opening line holds `:::`, a type in any letter case, and an optional\n * plain-text title. The block ends at a line holding only `:::`, indented no\n * deeper than the opener; code, lists, quotes, and HTML inside the body cannot\n * end it. The body is ordinary Markdown. A block that is never closed stays\n * ordinary text.\n */\n\nconst TONES = {\n note: \"neutral\",\n info: \"info\",\n success: \"success\",\n warning: \"warning\",\n danger: \"danger\",\n} as const satisfies Record<string, NoticeTone>;\n\nexport type MarkdownInfoBlockType = keyof typeof TONES;\n\nexport type MarkdownInfoBlock = {\n type: MarkdownInfoBlockType;\n /** Plain-text title from the opening line. */\n title?: string;\n /** Raw Markdown between the opening and closing lines, with `\\n` line breaks. */\n body: string;\n /** Source length through the closing line, or the whole source when the block is not closed. */\n length: number;\n closed: boolean;\n};\n\nexport type MarkdownInfoBlockRenderInput = {\n type: MarkdownInfoBlockType;\n title?: string;\n /** Already rendered body HTML. The caller owns its sanitization. */\n bodyHtml: string;\n /** Locale for the screen-reader name of an untitled block. */\n locale?: string;\n};\n\nconst OPENER = /^( {0,3}):::(note|info|success|warning|danger)(?:[ \\t]+(.*?))?[ \\t]*$/i;\nconst START = /^ {0,3}:::(?:note|info|success|warning|danger)(?=[ \\t\\n]|$)/i;\nconst OPENERS = /(?<=^|\\n) {0,3}:::(?:note|info|success|warning|danger)(?=[ \\t\\n]|$)/gi;\nconst CLOSING = /^( {0,3}):::[ \\t]*$/;\nconst FENCE = /^( *)(`{3,}|~{3,})(.*)$/;\n\ntype ContainerKind = \"code\" | \"fences\" | \"list\" | \"blockquote\" | \"html\";\ntype ContainerToken = NonNullable<ReturnType<Tokenizer[ContainerKind]>>;\n\nconst LABELS: Record<MarkdownInfoBlockType, (t: MarkdownInfoBlockMessages) => string> = {\n note: (t) => t.infoBlockNote,\n info: (t) => t.infoBlockInfo,\n success: (t) => t.infoBlockSuccess,\n warning: (t) => t.infoBlockWarning,\n danger: (t) => t.infoBlockDanger,\n};\n\nconst escapeHtml = (value: string): string =>\n value.replaceAll(\"&\", \"&\").replaceAll(\"<\", \"<\").replaceAll(\">\", \">\").replaceAll('\"', \""\").replaceAll(\"'\", \"'\");\n\nconst lineEnd = (source: string, from: number): number => {\n const end = source.indexOf(\"\\n\", from);\n return end < 0 ? source.length : end;\n};\n\nconst closes = (line: string, indent: number): boolean => {\n const closing = CLOSING.exec(line);\n return !!closing && closing[1]!.length <= indent;\n};\n\n/** Column where a list item's text starts, as CommonMark counts it. */\nconst itemTextIndent = (raw: string): number => {\n const [, bullet = \"\", gap = \"\"] = /^( {0,3}(?:[-+*]|\\d{1,9}[.)]))( *)/.exec(raw) ?? [];\n return bullet.length + (gap.length >= 1 && gap.length <= 4 && raw[bullet.length + gap.length] !== \"\\n\" ? gap.length : 1);\n};\n\n/**\n * Offset of the block's closing line inside a list or quote, or -1. Lazy\n * paragraph lines may hold it; a list item's own fenced code cannot.\n */\nconst closingLineIn = (token: ContainerToken, indent: number): number => {\n if (token.type !== \"list\" && token.type !== \"blockquote\") return -1;\n const items = token.type === \"list\" ? token.items : [];\n let item = -1;\n let itemStart = 0;\n let itemEnd = 0;\n let text = 0;\n let fence = \"\";\n for (let from = 0; from < token.raw.length; ) {\n while (item + 1 < items.length && from >= itemEnd) {\n item++;\n itemStart = itemEnd;\n itemEnd += items[item]!.raw.length;\n text = itemTextIndent(items[item]!.raw);\n fence = \"\";\n }\n const end = lineEnd(token.raw, from);\n const line = token.raw.slice(from, end);\n // A line indented less than the item's text has left the item and its fence.\n if (fence && line.trim() && line.length - line.trimStart().length < text) fence = \"\";\n // The first line of an item carries its bullet where the text would be indented.\n const marker = items.length ? FENCE.exec(from === itemStart ? \" \".repeat(text) + line.slice(text) : line) : null;\n if (fence) {\n if (marker && marker[2]![0] === fence[0] && marker[2]!.length >= fence.length && !marker[3]!.trim()) fence = \"\";\n } else if (\n marker &&\n marker[1]!.length >= text &&\n marker[1]!.length <= text + 3 &&\n !(marker[2]![0] === \"`\" && marker[3]!.includes(\"`\"))\n ) {\n fence = marker[2]!;\n } else if (closes(line, indent)) {\n return from;\n }\n from = end + 1;\n }\n return -1;\n};\n\n/** Whether `line` starts a block of its own after a paragraph line instead of continuing the paragraph, as marked decides. */\nconst interruptsParagraph = (line: string): boolean => Lexer.rules.block.gfm.paragraph.exec(`x\\n${line}\\n`)?.[0] === \"x\";\n\n/**\n * Reads info blocks in one `\\n`-separated source. The opening line reads like\n * a paragraph line, so the body continues it: only a block that may interrupt\n * a paragraph, such as a fence, a list, a quote, or block HTML, hides its\n * lines from the closing line. A scan's only state is its line and whether a\n * paragraph is open there, so a later scan that reaches a line an earlier one\n * passed ends the same way; `outcomes` remembers that, which keeps reading\n * many openers of one document linear.\n */\nconst infoBlockReader = (source: string) => {\n const outcomes = new Map<number, number>();\n let tokenizer: Tokenizer | undefined;\n\n /** Code, lists, quotes, and HTML whose lines belong to the body even when one of them reads `:::`. */\n const container = (offset: number, line: string, paragraph: boolean): ContainerToken | undefined => {\n const kind: ContainerKind | undefined = /^(?: {4}| {0,3}\\t)/.test(line)\n ? \"code\"\n : /^ {0,3}(?:`{3,}|~{3,})/.test(line)\n ? \"fences\"\n : /^ {0,3}(?:[-+*][ \\t]|\\d{1,9}[.)][ \\t])/.test(line)\n ? \"list\"\n : /^ {0,3}>/.test(line)\n ? \"blockquote\"\n : /^ {0,3}</.test(line)\n ? \"html\"\n : undefined;\n if (!kind || (paragraph && !interruptsParagraph(line))) return undefined;\n if (!tokenizer) {\n // One tokenizer per document: its lexer queues inline work that nothing drains.\n tokenizer = new Tokenizer({ gfm: true });\n new Lexer({ gfm: true, tokenizer });\n }\n return tokenizer[kind](source.slice(offset));\n };\n\n /** Offset of the closing line for a body that starts at `start`, or -1 when the block never closes. */\n const closingLine = (start: number, indent: number): number => {\n const passed: number[] = [];\n let offset = start;\n let paragraph = true;\n let result = -1;\n while (offset < source.length) {\n const key = offset * 8 + indent * 2 + (paragraph ? 1 : 0);\n const known = outcomes.get(key);\n if (known !== undefined) {\n result = known;\n break;\n }\n passed.push(key);\n const end = lineEnd(source, offset);\n const line = source.slice(offset, end);\n if (closes(line, indent)) {\n result = offset;\n break;\n }\n const token = container(offset, line, paragraph);\n if (token) {\n const closing = closingLineIn(token, indent);\n const length = closing < 0 ? token.raw.length : closing;\n if (length > 0) {\n offset += length;\n paragraph = false;\n continue;\n }\n }\n // A blank line ends a paragraph; any other line continues or starts one.\n paragraph = line.trim() !== \"\";\n offset = Math.min(end + 1, source.length);\n }\n for (const key of passed) outcomes.set(key, result);\n return result;\n };\n\n return (offset: number): MarkdownInfoBlock | null => {\n const firstEnd = lineEnd(source, offset);\n const opener = OPENER.exec(source.slice(offset, firstEnd));\n if (!opener) return null;\n const indent = opener[1]!.length;\n const type = opener[2]!.toLowerCase() as MarkdownInfoBlockType;\n const title = opener[3]?.trim() || undefined;\n const bodyStart = Math.min(firstEnd + 1, source.length);\n const closing = closingLine(bodyStart, indent);\n if (closing < 0) return { type, title, body: source.slice(bodyStart), length: source.length - offset, closed: false };\n const body = source.slice(bodyStart, closing).replace(/\\n$/, \"\");\n return { type, title, body, length: Math.min(lineEnd(source, closing) + 1, source.length) - offset, closed: true };\n };\n};\n\n/**\n * Reads the info block that starts `source`. Returns `null` when the first\n * line is not an info-block opener. Applications with their own Markdown\n * pipeline use this to recognize exactly the blocks `MarkdownView` renders.\n * Any line endings are accepted; `length` counts `source` as given.\n */\nexport const scanMarkdownInfoBlock = (source: string): MarkdownInfoBlock | null => {\n const normalized = source.replace(/\\r\\n?/g, \"\\n\");\n const block = infoBlockReader(normalized)(0);\n if (!block || normalized.length === source.length) return block;\n // Only `\\r\\n` shortens the source; count each one twice up to the block's end.\n let length = 0;\n for (let index = 0; index < block.length; index++) length += source[length] === \"\\r\" && source[length + 1] === \"\\n\" ? 2 : 1;\n return { ...block, length };\n};\n\nconst renderBlock = (input: Omit<MarkdownInfoBlockRenderInput, \"locale\">, messages: MarkdownInfoBlockMessages): string => {\n const name = input.title\n ? `<p class=\"${NOTICE_CARD_CLASSES.title}\">${escapeHtml(input.title)}</p>`\n : `<span class=\"k2b-sr-only\">${escapeHtml(LABELS[input.type](messages))}: </span>`;\n return `<aside class=\"${NOTICE_CARD_CLASSES.root}\" data-tone=\"${TONES[input.type]}\" role=\"note\">${name}<div class=\"${NOTICE_CARD_CLASSES.body}\">${input.bodyHtml}</div></aside>`;\n};\n\n/**\n * Renders an info block as the calm `NoticeCard`: the tone tints the surface,\n * the text stays neutral, and there is no icon. A title is the visible heading\n * and names the block; without one, the localized type name is announced to\n * screen readers only.\n */\nexport const renderMarkdownInfoBlock = (input: MarkdownInfoBlockRenderInput): string =>\n renderBlock(input, resolveMarkdownInfoBlockMessages(input.locale));\n\n/**\n * What one `marked` lexer run knows about its document: the opening lines, the\n * blocks read so far, the length of the last top-level source, and the extent\n * of the last top-level paragraph `start` measured.\n */\ntype DocumentState = {\n source: string;\n read: (offset: number) => MarkdownInfoBlock | null;\n openers: number[];\n blocks: Map<number, MarkdownInfoBlock | null>;\n top: number;\n paragraph: { start: number; end: number };\n};\n\nconst documents = new WeakMap<object, DocumentState>();\n\n/** The closed block that starts at `offset`, read once per document. */\nconst closedBlockAt = (document: DocumentState, offset: number): MarkdownInfoBlock | null => {\n let block = document.blocks.get(offset);\n if (block === undefined) {\n const read = document.read(offset);\n block = read?.closed ? read : null;\n document.blocks.set(offset, block);\n }\n return block;\n};\n\n/** Index of the first of the ascending `offsets` at or after `from`. */\nconst firstAtOrAfter = (offsets: readonly number[], from: number): number => {\n let low = 0;\n let high = offsets.length;\n while (low < high) {\n const middle = (low + high) >> 1;\n if (offsets[middle]! < from) low = middle + 1;\n else high = middle;\n }\n return low;\n};\n\n/**\n * The first closed block after the top-level `position` inside the paragraph\n * that would start there. Openers further away cannot end that paragraph, and\n * a paragraph that starts inside the last measured one ends where it ends.\n */\nconst nextBlockStart = (document: DocumentState, position: number, rules: RegExp): number | undefined => {\n if (position < document.paragraph.start || position >= document.paragraph.end) {\n const extent = rules.exec(document.source.slice(position))?.[0].length ?? 0;\n document.paragraph = { start: position, end: position + extent };\n }\n for (let index = firstAtOrAfter(document.openers, position + 1); index < document.openers.length; index++) {\n const offset = document.openers[index]!;\n if (offset >= document.paragraph.end) return undefined;\n if (closedBlockAt(document, offset)) return offset;\n }\n return undefined;\n};\n\n/** The paragraph rule of the lexer's own flavour. */\nconst paragraphRule = (lexer: Lexer): RegExp =>\n Lexer.rules.block[lexer.options.pedantic ? \"pedantic\" : lexer.options.gfm ? \"gfm\" : \"normal\"].paragraph;\n\nconst createExtension = (messages: MarkdownInfoBlockMessages): MarkedExtension => {\n const extension: TokenizerAndRendererExtension = {\n name: \"markdownInfoBlock\",\n level: \"block\",\n // marked ends a top-level paragraph where `start` points. Only a block\n // that closes renders, so `start` points at the first one inside the\n // paragraph; a split anywhere else would only make marked lex the rest of\n // the document again.\n start(source) {\n const document = documents.get(this.lexer);\n // marked asks right after the tokenizer below ran at the same top-level position.\n if (!document || source.length + 1 !== document.top) return undefined;\n const position = document.source.length - source.length - 1;\n const next = nextBlockStart(document, position, paragraphRule(this.lexer));\n return next === undefined ? undefined : next - position - 1;\n },\n tokenizer(source, tokens) {\n let document = documents.get(this.lexer);\n if (tokens !== this.lexer.tokens) {\n // Nested sources are rewritten text, not the rest of the document.\n if (document) document.top = -1;\n return undefined;\n }\n // The first top-level call sees the whole document; later ones see what is left of it.\n if (!document) {\n document = {\n source,\n read: infoBlockReader(source),\n openers: Array.from(source.matchAll(OPENERS), (opener) => opener.index),\n blocks: new Map(),\n top: source.length,\n paragraph: { start: -1, end: -1 },\n };\n documents.set(this.lexer, document);\n }\n document.top = source.length;\n if (!START.test(source)) return undefined;\n const block = closedBlockAt(document, document.source.length - source.length);\n if (!block) return undefined;\n return {\n type: \"markdownInfoBlock\",\n raw: source.slice(0, block.length),\n blockType: block.type,\n title: block.title,\n tokens: this.lexer.blockTokens(block.body, []),\n };\n },\n renderer(token) {\n return renderBlock(\n {\n type: token.blockType as MarkdownInfoBlockType,\n title: token.title as string | undefined,\n bodyHtml: this.parser.parse(token.tokens ?? []),\n },\n messages,\n );\n },\n };\n return {\n extensions: [extension],\n tokenizer: {\n // A setext heading's text is a paragraph, so it ends before a block as\n // well; marked does not clip it at `start` itself.\n lheading(source) {\n const document = documents.get(this.lexer);\n if (!document || source.length !== document.top) return false;\n const position = document.source.length - source.length;\n const next = nextBlockStart(document, position, paragraphRule(this.lexer));\n return next === undefined ? false : Tokenizer.prototype.lheading.call(this, source.slice(0, next - position));\n },\n },\n };\n};\n\nconst extensions = new WeakMap<MarkdownInfoBlockMessages, MarkedExtension>();\n\n/**\n * `marked` extension for info blocks at the top level of a document. Blocks\n * inside lists, quotes, or another block stay ordinary text. The body goes\n * through the host's own Markdown renderer, so its escaping and link rules\n * apply unchanged. Locales that share a UI message catalog get the same\n * extension, so a host may cache one `marked` instance per extension.\n */\nexport const markdownInfoBlocks = (options: { locale?: string } = {}): MarkedExtension => {\n const messages = resolveMarkdownInfoBlockMessages(options.locale);\n const extension = extensions.get(messages) ?? createExtension(messages);\n extensions.set(messages, extension);\n return extension;\n};\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":[],"sources":["content/markdown-info-blocks.ts"],"sourcesContent":["import { Lexer, type MarkedExtension, Tokenizer, type TokenizerAndRendererExtension } from \"marked\";\nimport { NOTICE_CARD_CLASSES, type NoticeTone } from \"../surfaces/NoticeCard\";\nimport { type MarkdownInfoBlockMessages, resolveMarkdownInfoBlockMessages } from \"./markdown-info-block-messages\";\n\n/**\n * Markdown info blocks: one grammar and one look for every Markdown surface.\n *\n * ```markdown\n * :::warning Before deleting\n * Deleting an item cannot be undone.\n * :::\n * ```\n *\n * The opening line holds `:::`, a type in any letter case, and an optional\n * plain-text title. The block ends at a line holding only `:::`, indented no\n * deeper than the opener; code, lists, quotes, and HTML inside the body cannot\n * end it. The body is ordinary Markdown. A block that is never closed stays\n * ordinary text.\n */\n\nconst TONES = {\n note: \"neutral\",\n info: \"info\",\n success: \"success\",\n warning: \"warning\",\n danger: \"danger\",\n} as const satisfies Record<string, NoticeTone>;\n\n// Tabler outline paths (@tabler/icons 3.48.0), without the transparent canvas path.\nconst ICON_PATHS = {\n note: [\"M13 20l7 -7\", \"M13 20v-6a1 1 0 0 1 1 -1h6v-7a2 2 0 0 0 -2 -2h-12a2 2 0 0 0 -2 2v12a2 2 0 0 0 2 2h7\"],\n info: [\"M3 12a9 9 0 1 0 18 0a9 9 0 0 0 -18 0\", \"M12 9h.01\", \"M11 12h1v4h1\"],\n success: [\"M3 12a9 9 0 1 0 18 0a9 9 0 1 0 -18 0\", \"M9 12l2 2l4 -4\"],\n warning: [\n \"M12 9v4\",\n \"M10.363 3.591l-8.106 13.534a1.914 1.914 0 0 0 1.636 2.871h16.214a1.914 1.914 0 0 0 1.636 -2.87l-8.106 -13.536a1.914 1.914 0 0 0 -3.274 0\",\n \"M12 16h.01\",\n ],\n danger: [\n \"M12.802 2.165l5.575 2.389c.48 .206 .863 .589 1.07 1.07l2.388 5.574c.22 .512 .22 1.092 0 1.604l-2.389 5.575c-.206 .48 -.589 .863 -1.07 1.07l-5.574 2.388c-.512 .22 -1.092 .22 -1.604 0l-5.575 -2.389a2.036 2.036 0 0 1 -1.07 -1.07l-2.388 -5.574a2.036 2.036 0 0 1 0 -1.604l2.389 -5.575c.206 -.48 .589 -.863 1.07 -1.07l5.574 -2.388a2.036 2.036 0 0 1 1.604 0\",\n \"M12 8v4\",\n \"M12 16h.01\",\n ],\n} as const;\n\nexport const MARKDOWN_CALLOUT_CLASSES = { root: \"k2b-callout\", icon: \"k2b-callout__icon\" } as const;\n\n/** Fixed attributes for decorative callout icons, including hosts with their own sanitizer. */\nexport const MARKDOWN_CALLOUT_ICON_ATTRIBUTES = {\n class: MARKDOWN_CALLOUT_CLASSES.icon,\n \"aria-hidden\": \"true\",\n width: \"20\",\n height: \"20\",\n viewBox: \"0 0 24 24\",\n fill: \"none\",\n stroke: \"currentColor\",\n \"stroke-width\": \"2\",\n \"stroke-linecap\": \"round\",\n \"stroke-linejoin\": \"round\",\n} as const;\n\nexport type MarkdownInfoBlockType = keyof typeof TONES;\n\nexport type MarkdownInfoBlock = {\n type: MarkdownInfoBlockType;\n /** Plain-text title from the opening line. */\n title?: string;\n /** Raw Markdown between the opening and closing lines, with `\\n` line breaks. */\n body: string;\n /** Source length through the closing line, or the whole source when the block is not closed. */\n length: number;\n closed: boolean;\n};\n\nexport type MarkdownInfoBlockRenderInput = {\n type: MarkdownInfoBlockType;\n title?: string;\n /** Already rendered body HTML. The caller owns its sanitization. */\n bodyHtml: string;\n /** Locale for the screen-reader name of an untitled block. */\n locale?: string;\n};\n\nconst OPENER = /^( {0,3}):::(note|info|success|warning|danger)(?:[ \\t]+(.*?))?[ \\t]*$/i;\nconst START = /^ {0,3}:::(?:note|info|success|warning|danger)(?=[ \\t\\n]|$)/i;\nconst OPENERS = /(?<=^|\\n) {0,3}:::(?:note|info|success|warning|danger)(?=[ \\t\\n]|$)/gi;\nconst CLOSING = /^( {0,3}):::[ \\t]*$/;\nconst FENCE = /^( *)(`{3,}|~{3,})(.*)$/;\n\ntype ContainerKind = \"code\" | \"fences\" | \"list\" | \"blockquote\" | \"html\";\ntype ContainerToken = NonNullable<ReturnType<Tokenizer[ContainerKind]>>;\n\nconst LABELS: Record<MarkdownInfoBlockType, (t: MarkdownInfoBlockMessages) => string> = {\n note: (t) => t.infoBlockNote,\n info: (t) => t.infoBlockInfo,\n success: (t) => t.infoBlockSuccess,\n warning: (t) => t.infoBlockWarning,\n danger: (t) => t.infoBlockDanger,\n};\n\nconst escapeHtml = (value: string): string =>\n value.replaceAll(\"&\", \"&\").replaceAll(\"<\", \"<\").replaceAll(\">\", \">\").replaceAll('\"', \""\").replaceAll(\"'\", \"'\");\n\nconst lineEnd = (source: string, from: number): number => {\n const end = source.indexOf(\"\\n\", from);\n return end < 0 ? source.length : end;\n};\n\nconst closes = (line: string, indent: number): boolean => {\n const closing = CLOSING.exec(line);\n return !!closing && closing[1]!.length <= indent;\n};\n\n/** Column where a list item's text starts, as CommonMark counts it. */\nconst itemTextIndent = (raw: string): number => {\n const [, bullet = \"\", gap = \"\"] = /^( {0,3}(?:[-+*]|\\d{1,9}[.)]))( *)/.exec(raw) ?? [];\n return bullet.length + (gap.length >= 1 && gap.length <= 4 && raw[bullet.length + gap.length] !== \"\\n\" ? gap.length : 1);\n};\n\n/**\n * Offset of the block's closing line inside a list or quote, or -1. Lazy\n * paragraph lines may hold it; a list item's own fenced code cannot.\n */\nconst closingLineIn = (token: ContainerToken, indent: number): number => {\n if (token.type !== \"list\" && token.type !== \"blockquote\") return -1;\n const items = token.type === \"list\" ? token.items : [];\n let item = -1;\n let itemStart = 0;\n let itemEnd = 0;\n let text = 0;\n let fence = \"\";\n for (let from = 0; from < token.raw.length; ) {\n while (item + 1 < items.length && from >= itemEnd) {\n item++;\n itemStart = itemEnd;\n itemEnd += items[item]!.raw.length;\n text = itemTextIndent(items[item]!.raw);\n fence = \"\";\n }\n const end = lineEnd(token.raw, from);\n const line = token.raw.slice(from, end);\n // A line indented less than the item's text has left the item and its fence.\n if (fence && line.trim() && line.length - line.trimStart().length < text) fence = \"\";\n // The first line of an item carries its bullet where the text would be indented.\n const marker = items.length ? FENCE.exec(from === itemStart ? \" \".repeat(text) + line.slice(text) : line) : null;\n if (fence) {\n if (marker && marker[2]![0] === fence[0] && marker[2]!.length >= fence.length && !marker[3]!.trim()) fence = \"\";\n } else if (\n marker &&\n marker[1]!.length >= text &&\n marker[1]!.length <= text + 3 &&\n !(marker[2]![0] === \"`\" && marker[3]!.includes(\"`\"))\n ) {\n fence = marker[2]!;\n } else if (closes(line, indent)) {\n return from;\n }\n from = end + 1;\n }\n return -1;\n};\n\n/** Whether `line` starts a block of its own after a paragraph line instead of continuing the paragraph, as marked decides. */\nconst interruptsParagraph = (line: string): boolean => Lexer.rules.block.gfm.paragraph.exec(`x\\n${line}\\n`)?.[0] === \"x\";\n\n/**\n * Reads info blocks in one `\\n`-separated source. The opening line reads like\n * a paragraph line, so the body continues it: only a block that may interrupt\n * a paragraph, such as a fence, a list, a quote, or block HTML, hides its\n * lines from the closing line. A scan's only state is its line and whether a\n * paragraph is open there, so a later scan that reaches a line an earlier one\n * passed ends the same way; `outcomes` remembers that, which keeps reading\n * many openers of one document linear.\n */\nconst infoBlockReader = (source: string) => {\n const outcomes = new Map<number, number>();\n let tokenizer: Tokenizer | undefined;\n\n /** Code, lists, quotes, and HTML whose lines belong to the body even when one of them reads `:::`. */\n const container = (offset: number, line: string, paragraph: boolean): ContainerToken | undefined => {\n const kind: ContainerKind | undefined = /^(?: {4}| {0,3}\\t)/.test(line)\n ? \"code\"\n : /^ {0,3}(?:`{3,}|~{3,})/.test(line)\n ? \"fences\"\n : /^ {0,3}(?:[-+*][ \\t]|\\d{1,9}[.)][ \\t])/.test(line)\n ? \"list\"\n : /^ {0,3}>/.test(line)\n ? \"blockquote\"\n : /^ {0,3}</.test(line)\n ? \"html\"\n : undefined;\n if (!kind || (paragraph && !interruptsParagraph(line))) return undefined;\n if (!tokenizer) {\n // One tokenizer per document: its lexer queues inline work that nothing drains.\n tokenizer = new Tokenizer({ gfm: true });\n new Lexer({ gfm: true, tokenizer });\n }\n return tokenizer[kind](source.slice(offset));\n };\n\n /** Offset of the closing line for a body that starts at `start`, or -1 when the block never closes. */\n const closingLine = (start: number, indent: number): number => {\n const passed: number[] = [];\n let offset = start;\n let paragraph = true;\n let result = -1;\n while (offset < source.length) {\n const key = offset * 8 + indent * 2 + (paragraph ? 1 : 0);\n const known = outcomes.get(key);\n if (known !== undefined) {\n result = known;\n break;\n }\n passed.push(key);\n const end = lineEnd(source, offset);\n const line = source.slice(offset, end);\n if (closes(line, indent)) {\n result = offset;\n break;\n }\n const token = container(offset, line, paragraph);\n if (token) {\n const closing = closingLineIn(token, indent);\n const length = closing < 0 ? token.raw.length : closing;\n if (length > 0) {\n offset += length;\n paragraph = false;\n continue;\n }\n }\n // A blank line ends a paragraph; any other line continues or starts one.\n paragraph = line.trim() !== \"\";\n offset = Math.min(end + 1, source.length);\n }\n for (const key of passed) outcomes.set(key, result);\n return result;\n };\n\n return (offset: number): MarkdownInfoBlock | null => {\n const firstEnd = lineEnd(source, offset);\n const opener = OPENER.exec(source.slice(offset, firstEnd));\n if (!opener) return null;\n const indent = opener[1]!.length;\n const type = opener[2]!.toLowerCase() as MarkdownInfoBlockType;\n const title = opener[3]?.trim() || undefined;\n const bodyStart = Math.min(firstEnd + 1, source.length);\n const closing = closingLine(bodyStart, indent);\n if (closing < 0) return { type, title, body: source.slice(bodyStart), length: source.length - offset, closed: false };\n const body = source.slice(bodyStart, closing).replace(/\\n$/, \"\");\n return { type, title, body, length: Math.min(lineEnd(source, closing) + 1, source.length) - offset, closed: true };\n };\n};\n\n/**\n * Reads the info block that starts `source`. Returns `null` when the first\n * line is not an info-block opener. Applications with their own Markdown\n * pipeline use this to recognize exactly the blocks `MarkdownView` renders.\n * Any line endings are accepted; `length` counts `source` as given.\n */\nexport const scanMarkdownInfoBlock = (source: string): MarkdownInfoBlock | null => {\n const normalized = source.replace(/\\r\\n?/g, \"\\n\");\n const block = infoBlockReader(normalized)(0);\n if (!block || normalized.length === source.length) return block;\n // Only `\\r\\n` shortens the source; count each one twice up to the block's end.\n let length = 0;\n for (let index = 0; index < block.length; index++) length += source[length] === \"\\r\" && source[length + 1] === \"\\n\" ? 2 : 1;\n return { ...block, length };\n};\n\nconst renderBlock = (input: Omit<MarkdownInfoBlockRenderInput, \"locale\">, messages: MarkdownInfoBlockMessages): string => {\n const name = input.title\n ? `<p class=\"${NOTICE_CARD_CLASSES.title}\">${escapeHtml(input.title)}</p>`\n : `<span class=\"k2b-sr-only\">${escapeHtml(LABELS[input.type](messages))}: </span>`;\n const icon = `<svg ${Object.entries(MARKDOWN_CALLOUT_ICON_ATTRIBUTES)\n .map(([name, value]) => `${name}=\"${value}\"`)\n .join(\" \")}>${ICON_PATHS[input.type].map((d) => `<path d=\"${d}\"></path>`).join(\"\")}</svg>`;\n return `<aside class=\"${NOTICE_CARD_CLASSES.root} ${MARKDOWN_CALLOUT_CLASSES.root}\" data-tone=\"${TONES[input.type]}\" role=\"note\">${icon}${name}<div class=\"${NOTICE_CARD_CLASSES.body}\">${input.bodyHtml}</div></aside>`;\n};\n\n/**\n * Renders a callout on a tinted surface without a border. The decorative icon\n * and title use the tone colour; body text stays neutral. A title is the\n * visible heading and names the block; without one, screen readers hear the\n * localized type name.\n */\nexport const renderMarkdownInfoBlock = (input: MarkdownInfoBlockRenderInput): string =>\n renderBlock(input, resolveMarkdownInfoBlockMessages(input.locale));\n\n/**\n * What one `marked` lexer run knows about its document: the opening lines, the\n * blocks read so far, the length of the last top-level source, and the extent\n * of the last top-level paragraph `start` measured.\n */\ntype DocumentState = {\n source: string;\n read: (offset: number) => MarkdownInfoBlock | null;\n openers: number[];\n blocks: Map<number, MarkdownInfoBlock | null>;\n top: number;\n paragraph: { start: number; end: number };\n};\n\nconst documents = new WeakMap<object, DocumentState>();\n\n/** The closed block that starts at `offset`, read once per document. */\nconst closedBlockAt = (document: DocumentState, offset: number): MarkdownInfoBlock | null => {\n let block = document.blocks.get(offset);\n if (block === undefined) {\n const read = document.read(offset);\n block = read?.closed ? read : null;\n document.blocks.set(offset, block);\n }\n return block;\n};\n\n/** Index of the first of the ascending `offsets` at or after `from`. */\nconst firstAtOrAfter = (offsets: readonly number[], from: number): number => {\n let low = 0;\n let high = offsets.length;\n while (low < high) {\n const middle = (low + high) >> 1;\n if (offsets[middle]! < from) low = middle + 1;\n else high = middle;\n }\n return low;\n};\n\n/**\n * The first closed block after the top-level `position` inside the paragraph\n * that would start there. Openers further away cannot end that paragraph, and\n * a paragraph that starts inside the last measured one ends where it ends.\n */\nconst nextBlockStart = (document: DocumentState, position: number, rules: RegExp): number | undefined => {\n if (position < document.paragraph.start || position >= document.paragraph.end) {\n const extent = rules.exec(document.source.slice(position))?.[0].length ?? 0;\n document.paragraph = { start: position, end: position + extent };\n }\n for (let index = firstAtOrAfter(document.openers, position + 1); index < document.openers.length; index++) {\n const offset = document.openers[index]!;\n if (offset >= document.paragraph.end) return undefined;\n if (closedBlockAt(document, offset)) return offset;\n }\n return undefined;\n};\n\n/** The paragraph rule of the lexer's own flavour. */\nconst paragraphRule = (lexer: Lexer): RegExp =>\n Lexer.rules.block[lexer.options.pedantic ? \"pedantic\" : lexer.options.gfm ? \"gfm\" : \"normal\"].paragraph;\n\nconst createExtension = (messages: MarkdownInfoBlockMessages): MarkedExtension => {\n const extension: TokenizerAndRendererExtension = {\n name: \"markdownInfoBlock\",\n level: \"block\",\n // marked ends a top-level paragraph where `start` points. Only a block\n // that closes renders, so `start` points at the first one inside the\n // paragraph; a split anywhere else would only make marked lex the rest of\n // the document again.\n start(source) {\n const document = documents.get(this.lexer);\n // marked asks right after the tokenizer below ran at the same top-level position.\n if (!document || source.length + 1 !== document.top) return undefined;\n const position = document.source.length - source.length - 1;\n const next = nextBlockStart(document, position, paragraphRule(this.lexer));\n return next === undefined ? undefined : next - position - 1;\n },\n tokenizer(source, tokens) {\n let document = documents.get(this.lexer);\n if (tokens !== this.lexer.tokens) {\n // Nested sources are rewritten text, not the rest of the document.\n if (document) document.top = -1;\n return undefined;\n }\n // The first top-level call sees the whole document; later ones see what is left of it.\n if (!document) {\n document = {\n source,\n read: infoBlockReader(source),\n openers: Array.from(source.matchAll(OPENERS), (opener) => opener.index),\n blocks: new Map(),\n top: source.length,\n paragraph: { start: -1, end: -1 },\n };\n documents.set(this.lexer, document);\n }\n document.top = source.length;\n if (!START.test(source)) return undefined;\n const block = closedBlockAt(document, document.source.length - source.length);\n if (!block) return undefined;\n return {\n type: \"markdownInfoBlock\",\n raw: source.slice(0, block.length),\n blockType: block.type,\n title: block.title,\n tokens: this.lexer.blockTokens(block.body, []),\n };\n },\n renderer(token) {\n return renderBlock(\n {\n type: token.blockType as MarkdownInfoBlockType,\n title: token.title as string | undefined,\n bodyHtml: this.parser.parse(token.tokens ?? []),\n },\n messages,\n );\n },\n };\n return {\n extensions: [extension],\n tokenizer: {\n // A setext heading's text is a paragraph, so it ends before a block as\n // well; marked does not clip it at `start` itself.\n lheading(source) {\n const document = documents.get(this.lexer);\n if (!document || source.length !== document.top) return false;\n const position = document.source.length - source.length;\n const next = nextBlockStart(document, position, paragraphRule(this.lexer));\n return next === undefined ? false : Tokenizer.prototype.lheading.call(this, source.slice(0, next - position));\n },\n },\n };\n};\n\nconst extensions = new WeakMap<MarkdownInfoBlockMessages, MarkedExtension>();\n\n/**\n * `marked` extension for info blocks at the top level of a document. Blocks\n * inside lists, quotes, or another block stay ordinary text. The body goes\n * through the host's own Markdown renderer, so its escaping and link rules\n * apply unchanged. Locales that share a UI message catalog get the same\n * extension, so a host may cache one `marked` instance per extension.\n */\nexport const markdownInfoBlocks = (options: { locale?: string } = {}): MarkedExtension => {\n const messages = resolveMarkdownInfoBlockMessages(options.locale);\n const extension = extensions.get(messages) ?? createExtension(messages);\n extensions.set(messages, extension);\n return extension;\n};\n"],"mappings":"AAAA,SAAS,KAAK,EAAwB,SAAS,QAA4C,QAAQ;AACnG,SAAS,mBAAmB,QAAyB,wBAAwB;AAC7E,SAAyC,gCAAgC,QAAQ,gCAAgC;;AAEjH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,MAAM,KAAK,GAAG;EACZ,IAAI,EAAE,SAAS;EACf,IAAI,EAAE,MAAM;EACZ,OAAO,EAAE,SAAS;EAClB,OAAO,EAAE,SAAS;EAClB,MAAM,EAAE;AACV,CAA+C;;AAE/C;AACA,MAAM,UAAU,GAAG;EACjB,IAAI,EAAE,CAAC,aAAa,EAAE,qFAAqF,CAAC;EAC5G,IAAI,EAAE,CAAC,sCAAsC,EAAE,WAAW,EAAE,cAAc,CAAC;EAC3E,OAAO,EAAE,CAAC,sCAAsC,EAAE,gBAAgB,CAAC;EACnE,OAAO,EAAE,CACP,SAAS,EACT,0IAA0I,EAC1I,YAAY,CACb;EACD,MAAM,EAAE,CACN,gWAAgW,EAChW,SAAS,EACT,YAAY;AAEhB,CAAU;AAEV,OAAO,MAAM,wBAAwB,GAAG;EAAE,IAAI,EAAE,aAAa;EAAE,IAAI,EAAE;AAAoB,CAAU;;AAEnG;AACA,OAAO,MAAM,gCAAgC,GAAG;EAC9C,KAAK,EAAE,wBAAwB,CAAC,IAAI;EACpC,aAAa,EAAE,MAAM;EACrB,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,IAAI;EACZ,OAAO,EAAE,WAAW;EACpB,IAAI,EAAE,MAAM;EACZ,MAAM,EAAE,cAAc;EACtB,cAAc,EAAE,GAAG;EACnB,gBAAgB,EAAE,OAAO;EACzB,iBAAiB,EAAE;AACrB,CAAU;AAwBV,MAAM,MAAM,GAAG,wEAAwE;AACvF,MAAM,KAAK,GAAG,8DAA8D;AAC5E,MAAM,OAAO,GAAG,uEAAuE;AACvF,MAAM,OAAO,GAAG,qBAAqB;AACrC,MAAM,KAAK,GAAG,yBAAyB;AAKvC,MAAM,MAA+E,GAAG;EACtF,IAAI,EAAG,CAAC,IAAK,CAAC,CAAC,aAAa;EAC5B,IAAI,EAAG,CAAC,IAAK,CAAC,CAAC,aAAa;EAC5B,OAAO,EAAG,CAAC,IAAK,CAAC,CAAC,gBAAgB;EAClC,OAAO,EAAG,CAAC,IAAK,CAAC,CAAC,gBAAgB;EAClC,MAAM,EAAG,CAAC,IAAK,CAAC,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,GAAI,KAAa,IAC/B,KAAK,CAAC,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC;AAEnI,MAAM,OAAO,GAAG,CAAC,MAAc,EAAE,IAAY,KAAa;EACxD,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC;EACtC,OAAO,GAAG,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,GAAG,GAAG;AACtC,CAAC;AAED,MAAM,MAAM,GAAG,CAAC,IAAY,EAAE,MAAc,KAAc;EACxD,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;EAClC,OAAO,CAAC,CAAC,OAAO,IAAI,OAAO,CAAC,CAAC,CAAC,CAAE,MAAM,IAAI,MAAM;AAClD,CAAC;;AAED;AACA,MAAM,cAAc,GAAI,GAAW,IAAa;EAC9C,MAAM,GAAG,MAAM,GAAG,EAAE,EAAE,GAAG,GAAG,EAAE,CAAC,GAAG,oCAAoC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE;EACtF,OAAO,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,IAAI,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC;AAC1H,CAAC;;AAED;AACA;AACA;AACA;AACA,MAAM,aAAa,GAAG,CAAC,KAAqB,EAAE,MAAc,KAAa;EACvE,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,EAAE,OAAO,CAAC,CAAC;EACnE,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,KAAK,MAAM,GAAG,KAAK,CAAC,KAAK,GAAG,EAAE;EACtD,IAAI,IAAI,GAAG,CAAC,CAAC;EACb,IAAI,SAAS,GAAG,CAAC;EACjB,IAAI,OAAO,GAAG,CAAC;EACf,IAAI,IAAI,GAAG,CAAC;EACZ,IAAI,KAAK,GAAG,EAAE;EACd,KAAK,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,MAAM,GAAI;IAC5C,OAAO,IAAI,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,IAAI,IAAI,IAAI,OAAO,EAAE;MACjD,IAAI,EAAE;MACN,SAAS,GAAG,OAAO;MACnB,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC,CAAE,GAAG,CAAC,MAAM;MAClC,IAAI,GAAG,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,CAAE,GAAG,CAAC;MACvC,KAAK,GAAG,EAAE;IACZ;IACA,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC;IACpC,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,CAAC;IACvC;IACA,IAAI,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,GAAG,IAAI,EAAE,KAAK,GAAG,EAAE;IACpF;IACA,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI;IAChH,IAAI,KAAK,EAAE;MACT,IAAI,MAAM,IAAI,MAAM,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAE,MAAM,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAE,IAAI,CAAC,CAAC,EAAE,KAAK,GAAG,EAAE;IACjH,CAAC,MAAM,IACL,MAAM,IACN,MAAM,CAAC,CAAC,CAAC,CAAE,MAAM,IAAI,IAAI,IACzB,MAAM,CAAC,CAAC,CAAC,CAAE,MAAM,IAAI,IAAI,GAAG,CAAC,IAC7B,EAAE,MAAM,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,KAAK,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,CAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,EACpD;MACA,KAAK,GAAG,MAAM,CAAC,CAAC,CAAE;IACpB,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE;MAC/B,OAAO,IAAI;IACb;IACA,IAAI,GAAG,GAAG,GAAG,CAAC;EAChB;EACA,OAAO,CAAC,CAAC;AACX,CAAC;;AAED;AACA,MAAM,mBAAmB,GAAI,IAAY,IAAc,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG;;AAExH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,eAAe,GAAI,MAAc,IAAK;EAC1C,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAiB,CAAC;EAC1C,IAAI,SAAgC;;EAEpC;EACA,MAAM,SAAS,GAAG,CAAC,MAAc,EAAE,IAAY,EAAE,SAAkB,KAAiC;IAClG,MAAM,IAA+B,GAAG,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,GACnE,MAAM,GACN,wBAAwB,CAAC,IAAI,CAAC,IAAI,CAAC,GACjC,QAAQ,GACR,wCAAwC,CAAC,IAAI,CAAC,IAAI,CAAC,GACjD,MAAM,GACN,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GACnB,YAAY,GACZ,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GACnB,MAAM,GACN,SAAS;IACrB,IAAI,CAAC,IAAI,IAAK,SAAS,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAE,EAAE,OAAO,SAAS;IACxE,IAAI,CAAC,SAAS,EAAE;MACd;MACA,SAAS,GAAG,IAAI,SAAS,CAAC;QAAE,GAAG,EAAE;MAAK,CAAC,CAAC;MACxC,IAAI,KAAK,CAAC;QAAE,GAAG,EAAE,IAAI;QAAE;MAAU,CAAC,CAAC;IACrC;IACA,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;EAC9C,CAAC;;EAED;EACA,MAAM,WAAW,GAAG,CAAC,KAAa,EAAE,MAAc,KAAa;IAC7D,MAAM,MAAgB,GAAG,EAAE;IAC3B,IAAI,MAAM,GAAG,KAAK;IAClB,IAAI,SAAS,GAAG,IAAI;IACpB,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,OAAO,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE;MAC7B,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,GAAG,MAAM,GAAG,CAAC,IAAI,SAAS,GAAG,CAAC,GAAG,CAAC,CAAC;MACzD,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC;MAC/B,IAAI,KAAK,KAAK,SAAS,EAAE;QACvB,MAAM,GAAG,KAAK;QACd;MACF;MACA,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;MAChB,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC;MACnC,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,CAAC;MACtC,IAAI,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE;QACxB,MAAM,GAAG,MAAM;QACf;MACF;MACA,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,SAAS,CAAC;MAChD,IAAI,KAAK,EAAE;QACT,MAAM,OAAO,GAAG,aAAa,CAAC,KAAK,EAAE,MAAM,CAAC;QAC5C,MAAM,MAAM,GAAG,OAAO,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,MAAM,GAAG,OAAO;QACvD,IAAI,MAAM,GAAG,CAAC,EAAE;UACd,MAAM,IAAI,MAAM;UAChB,SAAS,GAAG,KAAK;UACjB;QACF;MACF;MACA;MACA,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE;MAC9B,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC;IAC3C;IACA,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC;IACnD,OAAO,MAAM;EACf,CAAC;EAED,OAAQ,MAAc,IAA+B;IACnD,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC;IACxC,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC1D,IAAI,CAAC,MAAM,EAAE,OAAO,IAAI;IACxB,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,CAAE,MAAM;IAChC,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,CAAE,WAAW,CAAC,CAA0B;IAC9D,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,IAAI,SAAS;IAC5C,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC;IACvD,MAAM,OAAO,GAAG,WAAW,CAAC,SAAS,EAAE,MAAM,CAAC;IAC9C,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO;MAAE,IAAI;MAAE,KAAK;MAAE,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC;MAAE,MAAM,EAAE,MAAM,CAAC,MAAM,GAAG,MAAM;MAAE,MAAM,EAAE;IAAM,CAAC;IACrH,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;IAChE,OAAO;MAAE,IAAI;MAAE,KAAK;MAAE,IAAI;MAAE,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM;MAAE,MAAM,EAAE;IAAK,CAAC;EACpH,CAAC;AACH,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAM,qBAAqB,GAAI,MAAc,IAA+B;EACjF,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC;EACjD,MAAM,KAAK,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;EAC5C,IAAI,CAAC,KAAK,IAAI,UAAU,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,KAAK;EAC/D;EACA,IAAI,MAAM,GAAG,CAAC;EACd,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,IAAI,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,IAAI,GAAG,CAAC,GAAG,CAAC;EAC3H,OAAO;IAAE,GAAG,KAAK;IAAE;EAAO,CAAC;AAC7B,CAAC;AAED,MAAM,WAAW,GAAG,CAAC,KAAmD,EAAE,QAAmC,KAAa;EACxH,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,GACpB,aAAa,mBAAmB,CAAC,KAAK,KAAK,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GACxE,6BAA6B,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,WAAW;EACpF,MAAM,IAAI,GAAG,QAAQ,MAAM,CAAC,OAAO,CAAC,gCAAgC,CAAC,CAClE,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,GAAG,IAAI,KAAK,KAAK,GAAG,CAAC,CAC5C,IAAI,CAAC,GAAG,CAAC,IAAI,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAE,CAAC,IAAK,YAAY,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ;EAC5F,OAAO,iBAAiB,mBAAmB,CAAC,IAAI,IAAI,wBAAwB,CAAC,IAAI,gBAAgB,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,iBAAiB,IAAI,GAAG,IAAI,eAAe,mBAAmB,CAAC,IAAI,KAAK,KAAK,CAAC,QAAQ,gBAAgB;AAC1N,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAM,uBAAuB,GAAI,KAAmC,IACzE,WAAW,CAAC,KAAK,EAAE,gCAAgC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;;AAEpE;AACA;AACA;AACA;AACA;;AAUA,MAAM,SAAS,GAAG,IAAI,OAAO,CAAwB,CAAC;;AAEtD;AACA,MAAM,aAAa,GAAG,CAAC,QAAuB,EAAE,MAAc,KAA+B;EAC3F,IAAI,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC;EACvC,IAAI,KAAK,KAAK,SAAS,EAAE;IACvB,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC;IAClC,KAAK,GAAG,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAClC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC;EACpC;EACA,OAAO,KAAK;AACd,CAAC;;AAED;AACA,MAAM,cAAc,GAAG,CAAC,OAA0B,EAAE,IAAY,KAAa;EAC3E,IAAI,GAAG,GAAG,CAAC;EACX,IAAI,IAAI,GAAG,OAAO,CAAC,MAAM;EACzB,OAAO,GAAG,GAAG,IAAI,EAAE;IACjB,MAAM,MAAM,GAAI,GAAG,GAAG,IAAI,IAAK,CAAC;IAChC,IAAI,OAAO,CAAC,MAAM,CAAC,GAAI,IAAI,EAAE,GAAG,GAAG,MAAM,GAAG,CAAC,CAAC,KACzC,IAAI,GAAG,MAAM;EACpB;EACA,OAAO,GAAG;AACZ,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA,MAAM,cAAc,GAAG,CAAC,QAAuB,EAAE,QAAgB,EAAE,KAAa,KAAyB;EACvG,IAAI,QAAQ,GAAG,QAAQ,CAAC,SAAS,CAAC,KAAK,IAAI,QAAQ,IAAI,QAAQ,CAAC,SAAS,CAAC,GAAG,EAAE;IAC7E,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC;IAC3E,QAAQ,CAAC,SAAS,GAAG;MAAE,KAAK,EAAE,QAAQ;MAAE,GAAG,EAAE,QAAQ,GAAG;IAAO,CAAC;EAClE;EACA,KAAK,IAAI,KAAK,GAAG,cAAc,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;IACzG,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAE;IACvC,IAAI,MAAM,IAAI,QAAQ,CAAC,SAAS,CAAC,GAAG,EAAE,OAAO,SAAS;IACtD,IAAI,aAAa,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE,OAAO,MAAM;EACpD;EACA,OAAO,SAAS;AAClB,CAAC;;AAED;AACA,MAAM,aAAa,GAAI,KAAY,IACjC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,GAAG,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,GAAG,KAAK,GAAG,QAAQ,CAAC,CAAC,SAAS;AAEzG,MAAM,eAAe,GAAI,QAAmC,IAAsB;EAChF,MAAM,SAAwC,GAAG;IAC/C,IAAI,EAAE,mBAAmB;IACzB,KAAK,EAAE,OAAO;IACd;IACA;IACA;IACA;IACA,KAAK,CAAC,MAAM,EAAE;MACZ,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC;MAC1C;MACA,IAAI,CAAC,QAAQ,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,KAAK,QAAQ,CAAC,GAAG,EAAE,OAAO,SAAS;MACrE,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC;MAC3D,MAAM,IAAI,GAAG,cAAc,CAAC,QAAQ,EAAE,QAAQ,EAAE,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;MAC1E,OAAO,IAAI,KAAK,SAAS,GAAG,SAAS,GAAG,IAAI,GAAG,QAAQ,GAAG,CAAC;IAC7D,CAAC;IACD,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE;MACxB,IAAI,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC;MACxC,IAAI,MAAM,KAAK,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE;QAChC;QACA,IAAI,QAAQ,EAAE,QAAQ,CAAC,GAAG,GAAG,CAAC,CAAC;QAC/B,OAAO,SAAS;MAClB;MACA;MACA,IAAI,CAAC,QAAQ,EAAE;QACb,QAAQ,GAAG;UACT,MAAM;UACN,IAAI,EAAE,eAAe,CAAC,MAAM,CAAC;UAC7B,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAG,MAAM,IAAK,MAAM,CAAC,KAAK,CAAC;UACvE,MAAM,EAAE,IAAI,GAAG,CAAC,CAAC;UACjB,GAAG,EAAE,MAAM,CAAC,MAAM;UAClB,SAAS,EAAE;YAAE,KAAK,EAAE,CAAC,CAAC;YAAE,GAAG,EAAE,CAAC;UAAE;QAClC,CAAC;QACD,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC;MACrC;MACA,QAAQ,CAAC,GAAG,GAAG,MAAM,CAAC,MAAM;MAC5B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,OAAO,SAAS;MACzC,MAAM,KAAK,GAAG,aAAa,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;MAC7E,IAAI,CAAC,KAAK,EAAE,OAAO,SAAS;MAC5B,OAAO;QACL,IAAI,EAAE,mBAAmB;QACzB,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC;QAClC,SAAS,EAAE,KAAK,CAAC,IAAI;QACrB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE;MAC/C,CAAC;IACH,CAAC;IACD,QAAQ,CAAC,KAAK,EAAE;MACd,OAAO,WAAW,CAChB;QACE,IAAI,EAAE,KAAK,CAAC,SAAkC;QAC9C,KAAK,EAAE,KAAK,CAAC,KAA2B;QACxC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,IAAI,EAAE;MAChD,CAAC,EACD,QACF,CAAC;IACH;EACF,CAAC;EACD,OAAO;IACL,UAAU,EAAE,CAAC,SAAS,CAAC;IACvB,SAAS,EAAE;MACT;MACA;MACA,QAAQ,CAAC,MAAM,EAAE;QACf,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC;QAC1C,IAAI,CAAC,QAAQ,IAAI,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,GAAG,EAAE,OAAO,KAAK;QAC7D,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM;QACvD,MAAM,IAAI,GAAG,cAAc,CAAC,QAAQ,EAAE,QAAQ,EAAE,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1E,OAAO,IAAI,KAAK,SAAS,GAAG,KAAK,GAAG,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,GAAG,QAAQ,CAAC,CAAC;MAC/G;IACF;EACF,CAAC;AACH,CAAC;AAED,MAAM,UAAU,GAAG,IAAI,OAAO,CAA6C,CAAC;;AAE5E;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAM,kBAAkB,GAAG,CAAC,OAA4B,GAAG,CAAC,CAAC,KAAsB;EACxF,MAAM,QAAQ,GAAG,gCAAgC,CAAC,OAAO,CAAC,MAAM,CAAC;EACjE,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,eAAe,CAAC,QAAQ,CAAC;EACvE,UAAU,CAAC,GAAG,CAAC,QAAQ,EAAE,SAAS,CAAC;EACnC,OAAO,SAAS;AAClB,CAAC","ignoreList":[]}
|