kempo-ui 0.4.4 → 0.4.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (185) hide show
  1. package/dist/components/Chat.js +201 -0
  2. package/dist/components/CodeEditor.js +21 -2
  3. package/dist/components/Dropdown.js +1 -1
  4. package/dist/components/HtmlEditor.js +42 -3
  5. package/dist/components/MarkdownEditor.js +173 -0
  6. package/dist/components/Resize.js +12 -2
  7. package/dist/components/TextToSpeech.js +4 -4
  8. package/dist/components/VoiceSelector.js +49 -0
  9. package/dist/components/markdownEditorControls/Bold.js +11 -0
  10. package/dist/components/markdownEditorControls/BulletList.js +11 -0
  11. package/dist/components/markdownEditorControls/Code.js +11 -0
  12. package/dist/components/markdownEditorControls/FormatBlock.js +30 -0
  13. package/dist/components/markdownEditorControls/Heading.js +11 -0
  14. package/dist/components/markdownEditorControls/Image.js +93 -0
  15. package/dist/components/markdownEditorControls/Italic.js +11 -0
  16. package/dist/components/markdownEditorControls/Link.js +11 -0
  17. package/dist/components/markdownEditorControls/MarkdownEditorControl.js +39 -0
  18. package/dist/components/markdownEditorControls/Menu.js +30 -0
  19. package/dist/components/markdownEditorControls/NumberedList.js +11 -0
  20. package/dist/components/markdownEditorControls/Quote.js +11 -0
  21. package/dist/components/markdownEditorControls/SpeechToText.js +16 -0
  22. package/dist/components/markdownEditorControls/Strikethrough.js +11 -0
  23. package/dist/components/markdownEditorControls/Table.js +80 -0
  24. package/dist/utils/marked.esm.js +1 -0
  25. package/dist/utils/renderMarkdown.js +1 -0
  26. package/dist/utils/sanitizeHtml.js +1 -0
  27. package/dist/utils/voice.js +1 -0
  28. package/docs/components/accordion.html +19 -0
  29. package/docs/components/aside.html +19 -0
  30. package/docs/components/calendar.html +19 -0
  31. package/docs/components/card.html +19 -0
  32. package/docs/components/chat.html +715 -0
  33. package/docs/components/code-editor.html +55 -0
  34. package/docs/components/color-picker.html +19 -0
  35. package/docs/components/combobox.html +19 -0
  36. package/docs/components/content-slider.html +19 -0
  37. package/docs/components/context.html +19 -0
  38. package/docs/components/dialog.html +19 -0
  39. package/docs/components/dropdown.html +19 -0
  40. package/docs/components/filter-list.html +19 -0
  41. package/docs/components/focus-capture.html +19 -0
  42. package/docs/components/html-editor.html +60 -0
  43. package/docs/components/hybrid-component.html +19 -0
  44. package/docs/components/icon.html +19 -0
  45. package/docs/components/import.html +19 -0
  46. package/docs/components/light-component.html +19 -0
  47. package/docs/components/markdown-editor.html +924 -0
  48. package/docs/components/nav-spacer.html +19 -0
  49. package/docs/components/nav.html +19 -0
  50. package/docs/components/photo-viewer.html +19 -0
  51. package/docs/components/progress.html +19 -0
  52. package/docs/components/resize.html +22 -0
  53. package/docs/components/rich-textarea.html +650 -0
  54. package/docs/components/shadow-component.html +19 -0
  55. package/docs/components/show-more.html +19 -0
  56. package/docs/components/slider.html +19 -0
  57. package/docs/components/sortable.html +19 -0
  58. package/docs/components/speech-to-text.html +19 -0
  59. package/docs/components/spinner.html +19 -0
  60. package/docs/components/split.html +19 -0
  61. package/docs/components/table.html +19 -0
  62. package/docs/components/tableControls.html +19 -0
  63. package/docs/components/tableCustomFields.html +19 -0
  64. package/docs/components/tableFetchRecords.html +19 -0
  65. package/docs/components/tableFieldSortHide.html +19 -0
  66. package/docs/components/tablePagination.html +19 -0
  67. package/docs/components/tablePlaceholder.html +19 -0
  68. package/docs/components/tableRecordEditing.html +19 -0
  69. package/docs/components/tableRecordFiltering.html +19 -0
  70. package/docs/components/tableRecordHiding.html +19 -0
  71. package/docs/components/tableRecordSearching.html +19 -0
  72. package/docs/components/tableRecordSelection.html +19 -0
  73. package/docs/components/tableRowControls.html +19 -0
  74. package/docs/components/tableServerSync.html +19 -0
  75. package/docs/components/tableSorting.html +19 -0
  76. package/docs/components/tabs.html +19 -0
  77. package/docs/components/tags.html +19 -0
  78. package/docs/components/text-to-speech.html +63 -1
  79. package/docs/components/theme-select.html +19 -0
  80. package/docs/components/theme-switcher.html +19 -0
  81. package/docs/components/time.html +19 -0
  82. package/docs/components/timestamp.html +19 -0
  83. package/docs/components/toast.html +19 -0
  84. package/docs/components/toggle.html +19 -0
  85. package/docs/components/tree.html +19 -0
  86. package/docs/components/voice-selector.html +610 -0
  87. package/docs/icons/done_all.svg +1 -0
  88. package/docs/icons/format_quote.svg +1 -0
  89. package/docs/icons/format_strikethrough.svg +1 -0
  90. package/docs/icons/send.svg +1 -0
  91. package/docs/icons/text_fields.svg +1 -0
  92. package/docs/index.html +49 -0
  93. package/docs/src/components/Chat.js +201 -0
  94. package/docs/src/components/CodeEditor.js +21 -2
  95. package/docs/src/components/Dropdown.js +1 -1
  96. package/docs/src/components/HtmlEditor.js +42 -3
  97. package/docs/src/components/MarkdownEditor.js +173 -0
  98. package/docs/src/components/Resize.js +12 -2
  99. package/docs/src/components/TextToSpeech.js +4 -4
  100. package/docs/src/components/VoiceSelector.js +49 -0
  101. package/docs/src/components/markdownEditorControls/Bold.js +11 -0
  102. package/docs/src/components/markdownEditorControls/BulletList.js +11 -0
  103. package/docs/src/components/markdownEditorControls/Code.js +11 -0
  104. package/docs/src/components/markdownEditorControls/FormatBlock.js +30 -0
  105. package/docs/src/components/markdownEditorControls/Heading.js +11 -0
  106. package/docs/src/components/markdownEditorControls/Image.js +93 -0
  107. package/docs/src/components/markdownEditorControls/Italic.js +11 -0
  108. package/docs/src/components/markdownEditorControls/Link.js +11 -0
  109. package/docs/src/components/markdownEditorControls/MarkdownEditorControl.js +39 -0
  110. package/docs/src/components/markdownEditorControls/Menu.js +30 -0
  111. package/docs/src/components/markdownEditorControls/NumberedList.js +11 -0
  112. package/docs/src/components/markdownEditorControls/Quote.js +11 -0
  113. package/docs/src/components/markdownEditorControls/SpeechToText.js +16 -0
  114. package/docs/src/components/markdownEditorControls/Strikethrough.js +11 -0
  115. package/docs/src/components/markdownEditorControls/Table.js +80 -0
  116. package/docs/src/utils/marked.esm.js +1 -0
  117. package/docs/src/utils/renderMarkdown.js +1 -0
  118. package/docs/src/utils/sanitizeHtml.js +1 -0
  119. package/docs/src/utils/voice.js +1 -0
  120. package/docs/utils/context.html +19 -0
  121. package/docs/utils/cookie.html +19 -0
  122. package/docs/utils/debounce.html +19 -0
  123. package/docs/utils/drag.html +19 -0
  124. package/docs/utils/elevation.html +23 -10
  125. package/docs/utils/formatTimestamp.html +19 -0
  126. package/docs/utils/object.html +19 -0
  127. package/docs/utils/propConverters.html +19 -0
  128. package/docs/utils/sanitizeHtml.html +555 -0
  129. package/docs/utils/string.html +19 -0
  130. package/docs/utils/theme.html +19 -0
  131. package/docs/utils/toTitleCase.html +19 -0
  132. package/docs/utils/type.html +19 -0
  133. package/docs/utils/voice.html +548 -0
  134. package/docs/utils/wait.html +19 -0
  135. package/docs-src/components/chat.page.html +230 -0
  136. package/docs-src/components/code-editor.page.html +36 -0
  137. package/docs-src/components/html-editor.page.html +41 -0
  138. package/docs-src/components/markdown-editor.page.html +439 -0
  139. package/docs-src/components/resize.page.html +3 -0
  140. package/docs-src/components/text-to-speech.page.html +44 -1
  141. package/docs-src/components/voice-selector.page.html +125 -0
  142. package/docs-src/index.page.html +30 -0
  143. package/docs-src/nav.fragment.html +19 -0
  144. package/docs-src/utils/elevation.page.html +4 -10
  145. package/docs-src/utils/sanitizeHtml.page.html +73 -0
  146. package/docs-src/utils/voice.page.html +66 -0
  147. package/icons/done_all.svg +1 -0
  148. package/icons/format_quote.svg +1 -0
  149. package/icons/format_strikethrough.svg +1 -0
  150. package/icons/send.svg +1 -0
  151. package/icons/text_fields.svg +1 -0
  152. package/llms.txt +7 -2
  153. package/package.json +3 -2
  154. package/src/components/Chat.js +435 -0
  155. package/src/components/CodeEditor.js +58 -2
  156. package/src/components/Dropdown.js +1 -1
  157. package/src/components/HtmlEditor.js +84 -4
  158. package/src/components/MarkdownEditor.js +654 -0
  159. package/src/components/Resize.js +17 -1
  160. package/src/components/TextToSpeech.js +13 -2
  161. package/src/components/VoiceSelector.js +271 -0
  162. package/src/components/markdownEditorControls/Bold.js +30 -0
  163. package/src/components/markdownEditorControls/BulletList.js +30 -0
  164. package/src/components/markdownEditorControls/Code.js +39 -0
  165. package/src/components/markdownEditorControls/FormatBlock.js +102 -0
  166. package/src/components/markdownEditorControls/Heading.js +45 -0
  167. package/src/components/markdownEditorControls/Image.js +250 -0
  168. package/src/components/markdownEditorControls/Italic.js +30 -0
  169. package/src/components/markdownEditorControls/Link.js +74 -0
  170. package/src/components/markdownEditorControls/MarkdownEditorControl.js +158 -0
  171. package/src/components/markdownEditorControls/Menu.js +86 -0
  172. package/src/components/markdownEditorControls/NumberedList.js +69 -0
  173. package/src/components/markdownEditorControls/Quote.js +30 -0
  174. package/src/components/markdownEditorControls/SpeechToText.js +65 -0
  175. package/src/components/markdownEditorControls/Strikethrough.js +35 -0
  176. package/src/components/markdownEditorControls/Table.js +164 -0
  177. package/src/utils/marked.esm.js +77 -0
  178. package/src/utils/renderMarkdown.js +29 -0
  179. package/src/utils/sanitizeHtml.js +137 -0
  180. package/src/utils/voice.js +103 -0
  181. package/tests/components/Chat.browser-test.js +540 -0
  182. package/tests/components/TextToSpeech.browser-test.js +150 -1
  183. package/tests/components/VoiceSelector.browser-test.js +374 -0
  184. package/tests/utils/sanitizeHtml.browser-test.js +179 -0
  185. package/tests/utils/voice.browser-test.js +128 -0
@@ -0,0 +1,65 @@
1
+ import MarkdownEditorControl from './MarkdownEditorControl.js';
2
+ import { html, css } from '../../lit-all.min.js';
3
+ import '../SpeechToText.js';
4
+
5
+ /*
6
+ Speech-to-text control. Reuses the standalone `<k-speech-to-text>`
7
+ component (which provides its own mic-button UI and handles the Web
8
+ Speech API) and just listens for its `end` event to drop the final
9
+ transcript into the editor at the cursor.
10
+ */
11
+ export default class MarkdownSpeechToText extends MarkdownEditorControl {
12
+ static properties = {
13
+ ...MarkdownEditorControl.properties,
14
+ language: { type: String, reflect: true },
15
+ continuous: { type: Boolean, reflect: true }
16
+ };
17
+
18
+ constructor() {
19
+ super();
20
+ this.label = 'Speech to text';
21
+ this.language = 'en-US';
22
+ this.continuous = false;
23
+ }
24
+
25
+ /*
26
+ The trigger button lives inside the embedded `<k-speech-to-text>`,
27
+ which handles its own click-to-listen logic. Our base-class
28
+ handleClick (which calls command()) is unused; the speech component
29
+ drives the lifecycle and we just react to the `end` event.
30
+ */
31
+ command() {}
32
+
33
+ handleEnd = (e) => {
34
+ const text = (e.detail?.text || '').trim();
35
+ if(!text) return;
36
+ // Trailing space so successive recordings don't run together.
37
+ this.editor?.replaceSelection(text + ' ', { selectInserted: false });
38
+ };
39
+
40
+ render() {
41
+ return html`
42
+ <k-speech-to-text
43
+ language=${this.language}
44
+ ?continuous=${this.continuous}
45
+ @end=${this.handleEnd}
46
+ ></k-speech-to-text>
47
+ `;
48
+ }
49
+
50
+ static styles = [
51
+ MarkdownEditorControl.styles,
52
+ css`
53
+ :host {
54
+ margin: var(--spacer_q);
55
+ }
56
+ k-speech-to-text {
57
+ /* Shrink the default 2.5rem circular mic button so it sits
58
+ comfortably alongside other toolbar controls. */
59
+ --btn_size: 2rem;
60
+ }
61
+ `
62
+ ];
63
+ }
64
+
65
+ customElements.define('k-md-speech-to-text', MarkdownSpeechToText);
@@ -0,0 +1,35 @@
1
+ import MarkdownEditorControl from './MarkdownEditorControl.js';
2
+ import { html } from '../../lit-all.min.js';
3
+ import '../Icon.js';
4
+
5
+ /*
6
+ GFM strikethrough — wraps the selection in `~~...~~`. marked renders this
7
+ to `<del>` (allowed by sanitizeHtml's default tag set), so it survives
8
+ the sanitize pass.
9
+ */
10
+ export default class MarkdownStrikethrough extends MarkdownEditorControl {
11
+ constructor() {
12
+ super();
13
+ this.label = 'Strikethrough';
14
+ }
15
+
16
+ command() {
17
+ this.wrapSelection('~~', '~~', 'strikethrough');
18
+ }
19
+
20
+ render() {
21
+ return html`
22
+ <button
23
+ type="button"
24
+ class=${this.btnClass}
25
+ title=${this.label}
26
+ aria-label=${this.label}
27
+ @click=${this.handleClick}
28
+ >
29
+ <k-icon name="format_strikethrough"></k-icon>
30
+ </button>
31
+ `;
32
+ }
33
+ }
34
+
35
+ customElements.define('k-md-strikethrough', MarkdownStrikethrough);
@@ -0,0 +1,164 @@
1
+ import MarkdownEditorControl from './MarkdownEditorControl.js';
2
+ import { html, css } from '../../lit-all.min.js';
3
+ import '../Icon.js';
4
+ import '../Dropdown.js';
5
+
6
+ /*
7
+ Table control. Opens a small dropdown with two number inputs (cols × rows)
8
+ and a Create button, then inserts a GFM markdown table with that many
9
+ empty cells at the cursor.
10
+ */
11
+ export default class MarkdownTable extends MarkdownEditorControl {
12
+ constructor() {
13
+ super();
14
+ this.label = 'Table';
15
+ }
16
+
17
+ /*
18
+ The trigger is wired to Dropdown's own click handling, so the
19
+ base-class handleClick (which calls command()) would fire on top and
20
+ create a feedback loop. command() is a no-op here; the Insert button
21
+ inside the dropdown drives insertion.
22
+ */
23
+ command() {}
24
+
25
+ handleDropdownOpened = () => {
26
+ requestAnimationFrame(() => {
27
+ const cols = this.shadowRoot?.querySelector('.tbl-cols');
28
+ if(cols){ cols.value = '3'; cols.select(); }
29
+ const rows = this.shadowRoot?.querySelector('.tbl-rows');
30
+ if(rows) rows.value = '2';
31
+ });
32
+ };
33
+
34
+ handleFormKeydown = (e) => {
35
+ if(e.key === 'Enter'){
36
+ e.preventDefault();
37
+ this.#submit();
38
+ } else if(e.key === 'Escape'){
39
+ this.shadowRoot?.querySelector('k-dropdown')?.close();
40
+ }
41
+ };
42
+
43
+ handleInsertClick = () => this.#submit();
44
+
45
+ #submit() {
46
+ const cols = this.#clamp(this.shadowRoot?.querySelector('.tbl-cols')?.value, 1, 20);
47
+ const rows = this.#clamp(this.shadowRoot?.querySelector('.tbl-rows')?.value, 1, 50);
48
+ if(!cols || !rows) return;
49
+ const editor = this.editor;
50
+ if(!editor) return;
51
+ editor.replaceSelection(this.#buildTable(cols, rows), { selectInserted: false });
52
+ this.shadowRoot?.querySelector('k-dropdown')?.close();
53
+ }
54
+
55
+ #clamp(raw, min, max) {
56
+ const n = parseInt(raw, 10);
57
+ if(!Number.isFinite(n)) return 0;
58
+ return Math.max(min, Math.min(max, n));
59
+ }
60
+
61
+ #buildTable(cols, rows) {
62
+ const headerCells = Array.from({ length: cols }, (_, i) => ` Header ${i + 1} `).join('|');
63
+ const separatorCells = Array.from({ length: cols }, () => ' --- ').join('|');
64
+ const bodyCells = Array.from({ length: cols }, () => ' ').join('|');
65
+ const lines = [
66
+ `|${headerCells}|`,
67
+ `|${separatorCells}|`,
68
+ ...Array.from({ length: rows }, () => `|${bodyCells}|`)
69
+ ];
70
+ // Surround with newlines so the table starts on its own line and the
71
+ // user's cursor lands on a fresh line below it.
72
+ return `\n${lines.join('\n')}\n`;
73
+ }
74
+
75
+ render() {
76
+ return html`
77
+ <k-dropdown @opened=${this.handleDropdownOpened}>
78
+ <button
79
+ slot="trigger"
80
+ type="button"
81
+ class=${this.btnClass}
82
+ title=${this.label}
83
+ aria-label=${this.label}
84
+ >
85
+ <k-icon name="table"></k-icon>
86
+ </button>
87
+ <div class="tbl-form" @keydown=${this.handleFormKeydown}>
88
+ <input
89
+ class="tbl-cols"
90
+ type="number"
91
+ min="1"
92
+ max="20"
93
+ inputmode="numeric"
94
+ aria-label="Columns"
95
+ value="3"
96
+ />
97
+ <span class="tbl-x" aria-hidden="true">×</span>
98
+ <input
99
+ class="tbl-rows"
100
+ type="number"
101
+ min="1"
102
+ max="50"
103
+ inputmode="numeric"
104
+ aria-label="Rows"
105
+ value="2"
106
+ />
107
+ <button type="button" class="primary" @click=${this.handleInsertClick}>Insert</button>
108
+ </div>
109
+ </k-dropdown>
110
+ `;
111
+ }
112
+
113
+ static styles = [
114
+ MarkdownEditorControl.styles,
115
+ css`
116
+ .tbl-form {
117
+ display: flex;
118
+ align-items: center;
119
+ gap: 0.4rem;
120
+ padding: 0.5rem;
121
+ }
122
+ .tbl-form input {
123
+ width: 2.5rem;
124
+ padding: 0.35rem 0.4rem;
125
+ border: 1px solid var(--c_border);
126
+ border-radius: var(--radius);
127
+ font: inherit;
128
+ background: var(--c_bg);
129
+ color: var(--tc);
130
+ text-align: center;
131
+ /* Hide the up/down spinner buttons that take up extra width. */
132
+ -moz-appearance: textfield;
133
+ }
134
+ .tbl-form input::-webkit-inner-spin-button,
135
+ .tbl-form input::-webkit-outer-spin-button {
136
+ -webkit-appearance: none;
137
+ margin: 0;
138
+ }
139
+ .tbl-form input:focus-visible {
140
+ outline: none;
141
+ box-shadow: var(--focus_shadow);
142
+ }
143
+ .tbl-x {
144
+ color: var(--tc_muted);
145
+ font-weight: bold;
146
+ }
147
+ .tbl-form button.primary {
148
+ padding: 0.4rem 0.8rem;
149
+ border: 1px solid var(--c_primary);
150
+ border-radius: var(--radius);
151
+ background: var(--c_primary);
152
+ color: white;
153
+ cursor: pointer;
154
+ font: inherit;
155
+ }
156
+ .tbl-form button.primary:focus-visible {
157
+ outline: none;
158
+ box-shadow: var(--focus_shadow);
159
+ }
160
+ `
161
+ ];
162
+ }
163
+
164
+ customElements.define('k-md-table', MarkdownTable);
@@ -0,0 +1,77 @@
1
+ /**
2
+ * marked v18.0.2 - a markdown parser
3
+ * Copyright (c) 2018-2026, MarkedJS. (MIT License)
4
+ * Copyright (c) 2011-2018, Christopher Jeffrey. (MIT License)
5
+ * https://github.com/markedjs/marked
6
+ */
7
+
8
+ /**
9
+ * DO NOT EDIT THIS FILE
10
+ * The code in this file is generated from files in ./src/
11
+ */
12
+
13
+ function z(){return{async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,pedantic:!1,renderer:null,silent:!1,tokenizer:null,walkTokens:null}}var T=z();function G(l){T=l}var _={exec:()=>null};function k(l,e=""){let t=typeof l=="string"?l:l.source,n={replace:(s,r)=>{let i=typeof r=="string"?r:r.source;return i=i.replace(m.caret,"$1"),t=t.replace(s,i),n},getRegex:()=>new RegExp(t,e)};return n}var Re=((l="")=>{try{return!!new RegExp("(?<=1)(?<!1)"+l)}catch{return!1}})(),m={codeRemoveIndent:/^(?: {1,4}| {0,3}\t)/gm,outputLinkReplace:/\\([\[\]])/g,indentCodeCompensation:/^(\s+)(?:```)/,beginningSpace:/^\s+/,endingHash:/#$/,startingSpaceChar:/^ /,endingSpaceChar:/ $/,nonSpaceChar:/[^ ]/,newLineCharGlobal:/\n/g,tabCharGlobal:/\t/g,multipleSpaceGlobal:/\s+/g,blankLine:/^[ \t]*$/,doubleBlankLine:/\n[ \t]*\n[ \t]*$/,blockquoteStart:/^ {0,3}>/,blockquoteSetextReplace:/\n {0,3}((?:=+|-+) *)(?=\n|$)/g,blockquoteSetextReplace2:/^ {0,3}>[ \t]?/gm,listReplaceNesting:/^ {1,4}(?=( {4})*[^ ])/g,listIsTask:/^\[[ xX]\] +\S/,listReplaceTask:/^\[[ xX]\] +/,listTaskCheckbox:/\[[ xX]\]/,anyLine:/\n.*\n/,hrefBrackets:/^<(.*)>$/,tableDelimiter:/[:|]/,tableAlignChars:/^\||\| *$/g,tableRowBlankLine:/\n[ \t]*$/,tableAlignRight:/^ *-+: *$/,tableAlignCenter:/^ *:-+: *$/,tableAlignLeft:/^ *:-+ *$/,startATag:/^<a /i,endATag:/^<\/a>/i,startPreScriptTag:/^<(pre|code|kbd|script)(\s|>)/i,endPreScriptTag:/^<\/(pre|code|kbd|script)(\s|>)/i,startAngleBracket:/^</,endAngleBracket:/>$/,pedanticHrefTitle:/^([^'"]*[^\s])\s+(['"])(.*)\2/,unicodeAlphaNumeric:/[\p{L}\p{N}]/u,escapeTest:/[&<>"']/,escapeReplace:/[&<>"']/g,escapeTestNoEncode:/[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/,escapeReplaceNoEncode:/[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/g,caret:/(^|[^\[])\^/g,percentDecode:/%25/g,findPipe:/\|/g,splitPipe:/ \|/,slashPipe:/\\\|/g,carriageReturn:/\r\n|\r/g,spaceLine:/^ +$/gm,notSpaceStart:/^\S*/,endingNewline:/\n$/,listItemRegex:l=>new RegExp(`^( {0,3}${l})((?:[ ][^\\n]*)?(?:\\n|$))`),nextBulletRegex:l=>new RegExp(`^ {0,${Math.min(3,l-1)}}(?:[*+-]|\\d{1,9}[.)])((?:[ ][^\\n]*)?(?:\\n|$))`),hrRegex:l=>new RegExp(`^ {0,${Math.min(3,l-1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`),fencesBeginRegex:l=>new RegExp(`^ {0,${Math.min(3,l-1)}}(?:\`\`\`|~~~)`),headingBeginRegex:l=>new RegExp(`^ {0,${Math.min(3,l-1)}}#`),htmlBeginRegex:l=>new RegExp(`^ {0,${Math.min(3,l-1)}}<(?:[a-z].*>|!--)`,"i"),blockquoteBeginRegex:l=>new RegExp(`^ {0,${Math.min(3,l-1)}}>`)},Te=/^(?:[ \t]*(?:\n|$))+/,Oe=/^((?: {4}| {0,3}\t)[^\n]+(?:\n(?:[ \t]*(?:\n|$))*)?)+/,we=/^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/,I=/^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/,ye=/^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,Q=/ {0,3}(?:[*+-]|\d{1,9}[.)])/,ie=/^(?!bull |blockCode|fences|blockquote|heading|html|table)((?:.|\n(?!\s*?\n|bull |blockCode|fences|blockquote|heading|html|table))+?)\n {0,3}(=+|-+) *(?:\n+|$)/,oe=k(ie).replace(/bull/g,Q).replace(/blockCode/g,/(?: {4}| {0,3}\t)/).replace(/fences/g,/ {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g,/ {0,3}>/).replace(/heading/g,/ {0,3}#{1,6}/).replace(/html/g,/ {0,3}<[^\n>]+>\n/).replace(/\|table/g,"").getRegex(),Pe=k(ie).replace(/bull/g,Q).replace(/blockCode/g,/(?: {4}| {0,3}\t)/).replace(/fences/g,/ {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g,/ {0,3}>/).replace(/heading/g,/ {0,3}#{1,6}/).replace(/html/g,/ {0,3}<[^\n>]+>\n/).replace(/table/g,/ {0,3}\|?(?:[:\- ]*\|)+[\:\- ]*\n/).getRegex(),j=/^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/,Se=/^[^\n]+/,F=/(?!\s*\])(?:\\[\s\S]|[^\[\]\\])+/,$e=k(/^ {0,3}\[(label)\]: *(?:\n[ \t]*)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n[ \t]*)?| *\n[ \t]*)(title))? *(?:\n+|$)/).replace("label",F).replace("title",/(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/).getRegex(),Le=k(/^(bull)([ \t][^\n]+?)?(?:\n|$)/).replace(/bull/g,Q).getRegex(),v="address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul",U=/<!--(?:-?>|[\s\S]*?(?:-->|$))/,_e=k("^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|<![A-Z][\\s\\S]*?(?:>\\n*|$)|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>\\n*|$)|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$))","i").replace("comment",U).replace("tag",v).replace("attribute",/ +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(),ae=k(j).replace("hr",I).replace("heading"," {0,3}#{1,6}(?:\\s|$)").replace("|lheading","").replace("|table","").replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)])[ \\t]").replace("html","</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag",v).getRegex(),Me=k(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/).replace("paragraph",ae).getRegex(),K={blockquote:Me,code:Oe,def:$e,fences:we,heading:ye,hr:I,html:_e,lheading:oe,list:Le,newline:Te,paragraph:ae,table:_,text:Se},re=k("^ *([^\\n ].*)\\n {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)").replace("hr",I).replace("heading"," {0,3}#{1,6}(?:\\s|$)").replace("blockquote"," {0,3}>").replace("code","(?: {4}| {0,3} )[^\\n]").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)])[ \\t]").replace("html","</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag",v).getRegex(),ze={...K,lheading:Pe,table:re,paragraph:k(j).replace("hr",I).replace("heading"," {0,3}#{1,6}(?:\\s|$)").replace("|lheading","").replace("table",re).replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)])[ \\t]").replace("html","</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag",v).getRegex()},Ee={...K,html:k(`^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)|<tag(?:"[^"]*"|'[^']*'|\\s[^'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))`).replace("comment",U).replace(/tag/g,"(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(),def:/^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,heading:/^(#{1,6})(.*)(?:\n+|$)/,fences:_,lheading:/^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,paragraph:k(j).replace("hr",I).replace("heading",` *#{1,6} *[^
14
+ ]`).replace("lheading",oe).replace("|table","").replace("blockquote"," {0,3}>").replace("|fences","").replace("|list","").replace("|html","").replace("|tag","").getRegex()},Ae=/^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,Ce=/^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,le=/^( {2,}|\\)\n(?!\s*$)/,Ie=/^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/,E=/[\p{P}\p{S}]/u,H=/[\s\p{P}\p{S}]/u,W=/[^\s\p{P}\p{S}]/u,Be=k(/^((?![*_])punctSpace)/,"u").replace(/punctSpace/g,H).getRegex(),ue=/(?!~)[\p{P}\p{S}]/u,De=/(?!~)[\s\p{P}\p{S}]/u,qe=/(?:[^\s\p{P}\p{S}]|~)/u,ve=k(/link|precode-code|html/,"g").replace("link",/\[(?:[^\[\]`]|(?<a>`+)[^`]+\k<a>(?!`))*?\]\((?:\\[\s\S]|[^\\\(\)]|\((?:\\[\s\S]|[^\\\(\)])*\))*\)/).replace("precode-",Re?"(?<!`)()":"(^^|[^`])").replace("code",/(?<b>`+)[^`]+\k<b>(?!`)/).replace("html",/<(?! )[^<>]*?>/).getRegex(),pe=/^(?:\*+(?:((?!\*)punct)|([^\s*]))?)|^_+(?:((?!_)punct)|([^\s_]))?/,He=k(pe,"u").replace(/punct/g,E).getRegex(),Ze=k(pe,"u").replace(/punct/g,ue).getRegex(),ce="^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\*)punct(\\*+)(?=[\\s]|$)|notPunctSpace(\\*+)(?!\\*)(?=punctSpace|$)|(?!\\*)punctSpace(\\*+)(?=notPunctSpace)|[\\s](\\*+)(?!\\*)(?=punct)|(?!\\*)punct(\\*+)(?!\\*)(?=punct)|notPunctSpace(\\*+)(?=notPunctSpace)",Ge=k(ce,"gu").replace(/notPunctSpace/g,W).replace(/punctSpace/g,H).replace(/punct/g,E).getRegex(),Ne=k(ce,"gu").replace(/notPunctSpace/g,qe).replace(/punctSpace/g,De).replace(/punct/g,ue).getRegex(),Qe=k("^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)|[^_]+(?=[^_])|(?!_)punct(_+)(?=[\\s]|$)|notPunctSpace(_+)(?!_)(?=punctSpace|$)|(?!_)punctSpace(_+)(?=notPunctSpace)|[\\s](_+)(?!_)(?=punct)|(?!_)punct(_+)(?!_)(?=punct)","gu").replace(/notPunctSpace/g,W).replace(/punctSpace/g,H).replace(/punct/g,E).getRegex(),je=k(/^~~?(?:((?!~)punct)|[^\s~])/,"u").replace(/punct/g,E).getRegex(),Fe="^[^~]+(?=[^~])|(?!~)punct(~~?)(?=[\\s]|$)|notPunctSpace(~~?)(?!~)(?=punctSpace|$)|(?!~)punctSpace(~~?)(?=notPunctSpace)|[\\s](~~?)(?!~)(?=punct)|(?!~)punct(~~?)(?!~)(?=punct)|notPunctSpace(~~?)(?=notPunctSpace)",Ue=k(Fe,"gu").replace(/notPunctSpace/g,W).replace(/punctSpace/g,H).replace(/punct/g,E).getRegex(),Ke=k(/\\(punct)/,"gu").replace(/punct/g,E).getRegex(),We=k(/^<(scheme:[^\s\x00-\x1f<>]*|email)>/).replace("scheme",/[a-zA-Z][a-zA-Z0-9+.-]{1,31}/).replace("email",/[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/).getRegex(),Xe=k(U).replace("(?:-->|$)","-->").getRegex(),Je=k("^comment|^</[a-zA-Z][\\w:-]*\\s*>|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^<![a-zA-Z]+\\s[\\s\\S]*?>|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>").replace("comment",Xe).replace("attribute",/\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/).getRegex(),q=/(?:\[(?:\\[\s\S]|[^\[\]\\])*\]|\\[\s\S]|`+(?!`)[^`]*?`+(?!`)|``+(?=\])|[^\[\]\\`])*?/,Ve=k(/^!?\[(label)\]\(\s*(href)(?:(?:[ \t]+(?:\n[ \t]*)?|\n[ \t]*)(title))?\s*\)/).replace("label",q).replace("href",/<(?:\\.|[^\n<>\\])+>|[^ \t\n\x00-\x1f]*/).replace("title",/"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/).getRegex(),he=k(/^!?\[(label)\]\[(ref)\]/).replace("label",q).replace("ref",F).getRegex(),ke=k(/^!?\[(ref)\](?:\[\])?/).replace("ref",F).getRegex(),Ye=k("reflink|nolink(?!\\()","g").replace("reflink",he).replace("nolink",ke).getRegex(),se=/[hH][tT][tT][pP][sS]?|[fF][tT][pP]/,X={_backpedal:_,anyPunctuation:Ke,autolink:We,blockSkip:ve,br:le,code:Ce,del:_,delLDelim:_,delRDelim:_,emStrongLDelim:He,emStrongRDelimAst:Ge,emStrongRDelimUnd:Qe,escape:Ae,link:Ve,nolink:ke,punctuation:Be,reflink:he,reflinkSearch:Ye,tag:Je,text:Ie,url:_},et={...X,link:k(/^!?\[(label)\]\((.*?)\)/).replace("label",q).getRegex(),reflink:k(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label",q).getRegex()},N={...X,emStrongRDelimAst:Ne,emStrongLDelim:Ze,delLDelim:je,delRDelim:Ue,url:k(/^((?:protocol):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/).replace("protocol",se).replace("email",/[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/).getRegex(),_backpedal:/(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/,del:/^(~~?)(?=[^\s~])((?:\\[\s\S]|[^\\])*?(?:\\[\s\S]|[^\s~\\]))\1(?=[^~]|$)/,text:k(/^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|protocol:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/).replace("protocol",se).getRegex()},tt={...N,br:k(le).replace("{2,}","*").getRegex(),text:k(N.text).replace("\\b_","\\b_| {2,}\\n").replace(/\{2,\}/g,"*").getRegex()},B={normal:K,gfm:ze,pedantic:Ee},A={normal:X,gfm:N,breaks:tt,pedantic:et};var nt={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"},de=l=>nt[l];function O(l,e){if(e){if(m.escapeTest.test(l))return l.replace(m.escapeReplace,de)}else if(m.escapeTestNoEncode.test(l))return l.replace(m.escapeReplaceNoEncode,de);return l}function J(l){try{l=encodeURI(l).replace(m.percentDecode,"%")}catch{return null}return l}function V(l,e){let t=l.replace(m.findPipe,(r,i,o)=>{let u=!1,a=i;for(;--a>=0&&o[a]==="\\";)u=!u;return u?"|":" |"}),n=t.split(m.splitPipe),s=0;if(n[0].trim()||n.shift(),n.length>0&&!n.at(-1)?.trim()&&n.pop(),e)if(n.length>e)n.splice(e);else for(;n.length<e;)n.push("");for(;s<n.length;s++)n[s]=n[s].trim().replace(m.slashPipe,"|");return n}function $(l,e,t){let n=l.length;if(n===0)return"";let s=0;for(;s<n;){let r=l.charAt(n-s-1);if(r===e&&!t)s++;else if(r!==e&&t)s++;else break}return l.slice(0,n-s)}function Y(l){let e=l.split(`
15
+ `),t=e.length-1;for(;t>=0&&m.blankLine.test(e[t]);)t--;return e.length-t<=2?l:e.slice(0,t+1).join(`
16
+ `)}function ge(l,e){if(l.indexOf(e[1])===-1)return-1;let t=0;for(let n=0;n<l.length;n++)if(l[n]==="\\")n++;else if(l[n]===e[0])t++;else if(l[n]===e[1]&&(t--,t<0))return n;return t>0?-2:-1}function fe(l,e=0){let t=e,n="";for(let s of l)if(s===" "){let r=4-t%4;n+=" ".repeat(r),t+=r}else n+=s,t++;return n}function me(l,e,t,n,s){let r=e.href,i=e.title||null,o=l[1].replace(s.other.outputLinkReplace,"$1");n.state.inLink=!0;let u={type:l[0].charAt(0)==="!"?"image":"link",raw:t,href:r,title:i,text:o,tokens:n.inlineTokens(o)};return n.state.inLink=!1,u}function rt(l,e,t){let n=l.match(t.other.indentCodeCompensation);if(n===null)return e;let s=n[1];return e.split(`
17
+ `).map(r=>{let i=r.match(t.other.beginningSpace);if(i===null)return r;let[o]=i;return o.length>=s.length?r.slice(s.length):r}).join(`
18
+ `)}var w=class{options;rules;lexer;constructor(e){this.options=e||T}space(e){let t=this.rules.block.newline.exec(e);if(t&&t[0].length>0)return{type:"space",raw:t[0]}}code(e){let t=this.rules.block.code.exec(e);if(t){let n=this.options.pedantic?t[0]:Y(t[0]),s=n.replace(this.rules.other.codeRemoveIndent,"");return{type:"code",raw:n,codeBlockStyle:"indented",text:s}}}fences(e){let t=this.rules.block.fences.exec(e);if(t){let n=t[0],s=rt(n,t[3]||"",this.rules);return{type:"code",raw:n,lang:t[2]?t[2].trim().replace(this.rules.inline.anyPunctuation,"$1"):t[2],text:s}}}heading(e){let t=this.rules.block.heading.exec(e);if(t){let n=t[2].trim();if(this.rules.other.endingHash.test(n)){let s=$(n,"#");(this.options.pedantic||!s||this.rules.other.endingSpaceChar.test(s))&&(n=s.trim())}return{type:"heading",raw:$(t[0],`
19
+ `),depth:t[1].length,text:n,tokens:this.lexer.inline(n)}}}hr(e){let t=this.rules.block.hr.exec(e);if(t)return{type:"hr",raw:$(t[0],`
20
+ `)}}blockquote(e){let t=this.rules.block.blockquote.exec(e);if(t){let n=$(t[0],`
21
+ `).split(`
22
+ `),s="",r="",i=[];for(;n.length>0;){let o=!1,u=[],a;for(a=0;a<n.length;a++)if(this.rules.other.blockquoteStart.test(n[a]))u.push(n[a]),o=!0;else if(!o)u.push(n[a]);else break;n=n.slice(a);let c=u.join(`
23
+ `),p=c.replace(this.rules.other.blockquoteSetextReplace,`
24
+ $1`).replace(this.rules.other.blockquoteSetextReplace2,"");s=s?`${s}
25
+ ${c}`:c,r=r?`${r}
26
+ ${p}`:p;let d=this.lexer.state.top;if(this.lexer.state.top=!0,this.lexer.blockTokens(p,i,!0),this.lexer.state.top=d,n.length===0)break;let h=i.at(-1);if(h?.type==="code")break;if(h?.type==="blockquote"){let R=h,f=R.raw+`
27
+ `+n.join(`
28
+ `),S=this.blockquote(f);i[i.length-1]=S,s=s.substring(0,s.length-R.raw.length)+S.raw,r=r.substring(0,r.length-R.text.length)+S.text;break}else if(h?.type==="list"){let R=h,f=R.raw+`
29
+ `+n.join(`
30
+ `),S=this.list(f);i[i.length-1]=S,s=s.substring(0,s.length-h.raw.length)+S.raw,r=r.substring(0,r.length-R.raw.length)+S.raw,n=f.substring(i.at(-1).raw.length).split(`
31
+ `);continue}}return{type:"blockquote",raw:s,tokens:i,text:r}}}list(e){let t=this.rules.block.list.exec(e);if(t){let n=t[1].trim(),s=n.length>1,r={type:"list",raw:"",ordered:s,start:s?+n.slice(0,-1):"",loose:!1,items:[]};n=s?`\\d{1,9}\\${n.slice(-1)}`:`\\${n}`,this.options.pedantic&&(n=s?n:"[*+-]");let i=this.rules.other.listItemRegex(n),o=!1;for(;e;){let a=!1,c="",p="";if(!(t=i.exec(e))||this.rules.block.hr.test(e))break;c=t[0],e=e.substring(c.length);let d=fe(t[2].split(`
32
+ `,1)[0],t[1].length),h=e.split(`
33
+ `,1)[0],R=!d.trim(),f=0;if(this.options.pedantic?(f=2,p=d.trimStart()):R?f=t[1].length+1:(f=d.search(this.rules.other.nonSpaceChar),f=f>4?1:f,p=d.slice(f),f+=t[1].length),R&&this.rules.other.blankLine.test(h)&&(c+=h+`
34
+ `,e=e.substring(h.length+1),a=!0),!a){let S=this.rules.other.nextBulletRegex(f),ee=this.rules.other.hrRegex(f),te=this.rules.other.fencesBeginRegex(f),ne=this.rules.other.headingBeginRegex(f),xe=this.rules.other.htmlBeginRegex(f),be=this.rules.other.blockquoteBeginRegex(f);for(;e;){let Z=e.split(`
35
+ `,1)[0],C;if(h=Z,this.options.pedantic?(h=h.replace(this.rules.other.listReplaceNesting," "),C=h):C=h.replace(this.rules.other.tabCharGlobal," "),te.test(h)||ne.test(h)||xe.test(h)||be.test(h)||S.test(h)||ee.test(h))break;if(C.search(this.rules.other.nonSpaceChar)>=f||!h.trim())p+=`
36
+ `+C.slice(f);else{if(R||d.replace(this.rules.other.tabCharGlobal," ").search(this.rules.other.nonSpaceChar)>=4||te.test(d)||ne.test(d)||ee.test(d))break;p+=`
37
+ `+h}R=!h.trim(),c+=Z+`
38
+ `,e=e.substring(Z.length+1),d=C.slice(f)}}r.loose||(o?r.loose=!0:this.rules.other.doubleBlankLine.test(c)&&(o=!0)),r.items.push({type:"list_item",raw:c,task:!!this.options.gfm&&this.rules.other.listIsTask.test(p),loose:!1,text:p,tokens:[]}),r.raw+=c}let u=r.items.at(-1);if(u)u.raw=u.raw.trimEnd(),u.text=u.text.trimEnd();else return;r.raw=r.raw.trimEnd();for(let a of r.items){if(this.lexer.state.top=!1,a.tokens=this.lexer.blockTokens(a.text,[]),a.task){if(a.text=a.text.replace(this.rules.other.listReplaceTask,""),a.tokens[0]?.type==="text"||a.tokens[0]?.type==="paragraph"){a.tokens[0].raw=a.tokens[0].raw.replace(this.rules.other.listReplaceTask,""),a.tokens[0].text=a.tokens[0].text.replace(this.rules.other.listReplaceTask,"");for(let p=this.lexer.inlineQueue.length-1;p>=0;p--)if(this.rules.other.listIsTask.test(this.lexer.inlineQueue[p].src)){this.lexer.inlineQueue[p].src=this.lexer.inlineQueue[p].src.replace(this.rules.other.listReplaceTask,"");break}}let c=this.rules.other.listTaskCheckbox.exec(a.raw);if(c){let p={type:"checkbox",raw:c[0]+" ",checked:c[0]!=="[ ]"};a.checked=p.checked,r.loose?a.tokens[0]&&["paragraph","text"].includes(a.tokens[0].type)&&"tokens"in a.tokens[0]&&a.tokens[0].tokens?(a.tokens[0].raw=p.raw+a.tokens[0].raw,a.tokens[0].text=p.raw+a.tokens[0].text,a.tokens[0].tokens.unshift(p)):a.tokens.unshift({type:"paragraph",raw:p.raw,text:p.raw,tokens:[p]}):a.tokens.unshift(p)}}if(!r.loose){let c=a.tokens.filter(d=>d.type==="space"),p=c.length>0&&c.some(d=>this.rules.other.anyLine.test(d.raw));r.loose=p}}if(r.loose)for(let a of r.items){a.loose=!0;for(let c of a.tokens)c.type==="text"&&(c.type="paragraph")}return r}}html(e){let t=this.rules.block.html.exec(e);if(t){let n=Y(t[0]);return{type:"html",block:!0,raw:n,pre:t[1]==="pre"||t[1]==="script"||t[1]==="style",text:n}}}def(e){let t=this.rules.block.def.exec(e);if(t){let n=t[1].toLowerCase().replace(this.rules.other.multipleSpaceGlobal," "),s=t[2]?t[2].replace(this.rules.other.hrefBrackets,"$1").replace(this.rules.inline.anyPunctuation,"$1"):"",r=t[3]?t[3].substring(1,t[3].length-1).replace(this.rules.inline.anyPunctuation,"$1"):t[3];return{type:"def",tag:n,raw:$(t[0],`
39
+ `),href:s,title:r}}}table(e){let t=this.rules.block.table.exec(e);if(!t||!this.rules.other.tableDelimiter.test(t[2]))return;let n=V(t[1]),s=t[2].replace(this.rules.other.tableAlignChars,"").split("|"),r=t[3]?.trim()?t[3].replace(this.rules.other.tableRowBlankLine,"").split(`
40
+ `):[],i={type:"table",raw:$(t[0],`
41
+ `),header:[],align:[],rows:[]};if(n.length===s.length){for(let o of s)this.rules.other.tableAlignRight.test(o)?i.align.push("right"):this.rules.other.tableAlignCenter.test(o)?i.align.push("center"):this.rules.other.tableAlignLeft.test(o)?i.align.push("left"):i.align.push(null);for(let o=0;o<n.length;o++)i.header.push({text:n[o],tokens:this.lexer.inline(n[o]),header:!0,align:i.align[o]});for(let o of r)i.rows.push(V(o,i.header.length).map((u,a)=>({text:u,tokens:this.lexer.inline(u),header:!1,align:i.align[a]})));return i}}lheading(e){let t=this.rules.block.lheading.exec(e);if(t){let n=t[1].trim();return{type:"heading",raw:$(t[0],`
42
+ `),depth:t[2].charAt(0)==="="?1:2,text:n,tokens:this.lexer.inline(n)}}}paragraph(e){let t=this.rules.block.paragraph.exec(e);if(t){let n=t[1].charAt(t[1].length-1)===`
43
+ `?t[1].slice(0,-1):t[1];return{type:"paragraph",raw:t[0],text:n,tokens:this.lexer.inline(n)}}}text(e){let t=this.rules.block.text.exec(e);if(t)return{type:"text",raw:t[0],text:t[0],tokens:this.lexer.inline(t[0])}}escape(e){let t=this.rules.inline.escape.exec(e);if(t)return{type:"escape",raw:t[0],text:t[1]}}tag(e){let t=this.rules.inline.tag.exec(e);if(t)return!this.lexer.state.inLink&&this.rules.other.startATag.test(t[0])?this.lexer.state.inLink=!0:this.lexer.state.inLink&&this.rules.other.endATag.test(t[0])&&(this.lexer.state.inLink=!1),!this.lexer.state.inRawBlock&&this.rules.other.startPreScriptTag.test(t[0])?this.lexer.state.inRawBlock=!0:this.lexer.state.inRawBlock&&this.rules.other.endPreScriptTag.test(t[0])&&(this.lexer.state.inRawBlock=!1),{type:"html",raw:t[0],inLink:this.lexer.state.inLink,inRawBlock:this.lexer.state.inRawBlock,block:!1,text:t[0]}}link(e){let t=this.rules.inline.link.exec(e);if(t){let n=t[2].trim();if(!this.options.pedantic&&this.rules.other.startAngleBracket.test(n)){if(!this.rules.other.endAngleBracket.test(n))return;let i=$(n.slice(0,-1),"\\");if((n.length-i.length)%2===0)return}else{let i=ge(t[2],"()");if(i===-2)return;if(i>-1){let u=(t[0].indexOf("!")===0?5:4)+t[1].length+i;t[2]=t[2].substring(0,i),t[0]=t[0].substring(0,u).trim(),t[3]=""}}let s=t[2],r="";if(this.options.pedantic){let i=this.rules.other.pedanticHrefTitle.exec(s);i&&(s=i[1],r=i[3])}else r=t[3]?t[3].slice(1,-1):"";return s=s.trim(),this.rules.other.startAngleBracket.test(s)&&(this.options.pedantic&&!this.rules.other.endAngleBracket.test(n)?s=s.slice(1):s=s.slice(1,-1)),me(t,{href:s&&s.replace(this.rules.inline.anyPunctuation,"$1"),title:r&&r.replace(this.rules.inline.anyPunctuation,"$1")},t[0],this.lexer,this.rules)}}reflink(e,t){let n;if((n=this.rules.inline.reflink.exec(e))||(n=this.rules.inline.nolink.exec(e))){let s=(n[2]||n[1]).replace(this.rules.other.multipleSpaceGlobal," "),r=t[s.toLowerCase()];if(!r){let i=n[0].charAt(0);return{type:"text",raw:i,text:i}}return me(n,r,n[0],this.lexer,this.rules)}}emStrong(e,t,n=""){let s=this.rules.inline.emStrongLDelim.exec(e);if(!s||!s[1]&&!s[2]&&!s[3]&&!s[4]||s[4]&&n.match(this.rules.other.unicodeAlphaNumeric))return;if(!(s[1]||s[3]||"")||!n||this.rules.inline.punctuation.exec(n)){let i=[...s[0]].length-1,o,u,a=i,c=0,p=s[0][0]==="*"?this.rules.inline.emStrongRDelimAst:this.rules.inline.emStrongRDelimUnd;for(p.lastIndex=0,t=t.slice(-1*e.length+i);(s=p.exec(t))!==null;){if(o=s[1]||s[2]||s[3]||s[4]||s[5]||s[6],!o)continue;if(u=[...o].length,s[3]||s[4]){a+=u;continue}else if((s[5]||s[6])&&i%3&&!((i+u)%3)){c+=u;continue}if(a-=u,a>0)continue;u=Math.min(u,u+a+c);let d=[...s[0]][0].length,h=e.slice(0,i+s.index+d+u);if(Math.min(i,u)%2){let f=h.slice(1,-1);return{type:"em",raw:h,text:f,tokens:this.lexer.inlineTokens(f)}}let R=h.slice(2,-2);return{type:"strong",raw:h,text:R,tokens:this.lexer.inlineTokens(R)}}}}codespan(e){let t=this.rules.inline.code.exec(e);if(t){let n=t[2].replace(this.rules.other.newLineCharGlobal," "),s=this.rules.other.nonSpaceChar.test(n),r=this.rules.other.startingSpaceChar.test(n)&&this.rules.other.endingSpaceChar.test(n);return s&&r&&(n=n.substring(1,n.length-1)),{type:"codespan",raw:t[0],text:n}}}br(e){let t=this.rules.inline.br.exec(e);if(t)return{type:"br",raw:t[0]}}del(e,t,n=""){let s=this.rules.inline.delLDelim.exec(e);if(!s)return;if(!(s[1]||"")||!n||this.rules.inline.punctuation.exec(n)){let i=[...s[0]].length-1,o,u,a=i,c=this.rules.inline.delRDelim;for(c.lastIndex=0,t=t.slice(-1*e.length+i);(s=c.exec(t))!==null;){if(o=s[1]||s[2]||s[3]||s[4]||s[5]||s[6],!o||(u=[...o].length,u!==i))continue;if(s[3]||s[4]){a+=u;continue}if(a-=u,a>0)continue;u=Math.min(u,u+a);let p=[...s[0]][0].length,d=e.slice(0,i+s.index+p+u),h=d.slice(i,-i);return{type:"del",raw:d,text:h,tokens:this.lexer.inlineTokens(h)}}}}autolink(e){let t=this.rules.inline.autolink.exec(e);if(t){let n,s;return t[2]==="@"?(n=t[1],s="mailto:"+n):(n=t[1],s=n),{type:"link",raw:t[0],text:n,href:s,tokens:[{type:"text",raw:n,text:n}]}}}url(e){let t;if(t=this.rules.inline.url.exec(e)){let n,s;if(t[2]==="@")n=t[0],s="mailto:"+n;else{let r;do r=t[0],t[0]=this.rules.inline._backpedal.exec(t[0])?.[0]??"";while(r!==t[0]);n=t[0],t[1]==="www."?s="http://"+t[0]:s=t[0]}return{type:"link",raw:t[0],text:n,href:s,tokens:[{type:"text",raw:n,text:n}]}}}inlineText(e){let t=this.rules.inline.text.exec(e);if(t){let n=this.lexer.state.inRawBlock;return{type:"text",raw:t[0],text:t[0],escaped:n}}}};var x=class l{tokens;options;state;inlineQueue;tokenizer;constructor(e){this.tokens=[],this.tokens.links=Object.create(null),this.options=e||T,this.options.tokenizer=this.options.tokenizer||new w,this.tokenizer=this.options.tokenizer,this.tokenizer.options=this.options,this.tokenizer.lexer=this,this.inlineQueue=[],this.state={inLink:!1,inRawBlock:!1,top:!0};let t={other:m,block:B.normal,inline:A.normal};this.options.pedantic?(t.block=B.pedantic,t.inline=A.pedantic):this.options.gfm&&(t.block=B.gfm,this.options.breaks?t.inline=A.breaks:t.inline=A.gfm),this.tokenizer.rules=t}static get rules(){return{block:B,inline:A}}static lex(e,t){return new l(t).lex(e)}static lexInline(e,t){return new l(t).inlineTokens(e)}lex(e){e=e.replace(m.carriageReturn,`
44
+ `),this.blockTokens(e,this.tokens);for(let t=0;t<this.inlineQueue.length;t++){let n=this.inlineQueue[t];this.inlineTokens(n.src,n.tokens)}return this.inlineQueue=[],this.tokens}blockTokens(e,t=[],n=!1){this.tokenizer.lexer=this,this.options.pedantic&&(e=e.replace(m.tabCharGlobal," ").replace(m.spaceLine,""));let s=1/0;for(;e;){if(e.length<s)s=e.length;else{this.infiniteLoopError(e.charCodeAt(0));break}let r;if(this.options.extensions?.block?.some(o=>(r=o.call({lexer:this},e,t))?(e=e.substring(r.raw.length),t.push(r),!0):!1))continue;if(r=this.tokenizer.space(e)){e=e.substring(r.raw.length);let o=t.at(-1);r.raw.length===1&&o!==void 0?o.raw+=`
45
+ `:t.push(r);continue}if(r=this.tokenizer.code(e)){e=e.substring(r.raw.length);let o=t.at(-1);o?.type==="paragraph"||o?.type==="text"?(o.raw+=(o.raw.endsWith(`
46
+ `)?"":`
47
+ `)+r.raw,o.text+=`
48
+ `+r.text,this.inlineQueue.at(-1).src=o.text):t.push(r);continue}if(r=this.tokenizer.fences(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.heading(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.hr(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.blockquote(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.list(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.html(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.def(e)){e=e.substring(r.raw.length);let o=t.at(-1);o?.type==="paragraph"||o?.type==="text"?(o.raw+=(o.raw.endsWith(`
49
+ `)?"":`
50
+ `)+r.raw,o.text+=`
51
+ `+r.raw,this.inlineQueue.at(-1).src=o.text):this.tokens.links[r.tag]||(this.tokens.links[r.tag]={href:r.href,title:r.title},t.push(r));continue}if(r=this.tokenizer.table(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.lheading(e)){e=e.substring(r.raw.length),t.push(r);continue}let i=e;if(this.options.extensions?.startBlock){let o=1/0,u=e.slice(1),a;this.options.extensions.startBlock.forEach(c=>{a=c.call({lexer:this},u),typeof a=="number"&&a>=0&&(o=Math.min(o,a))}),o<1/0&&o>=0&&(i=e.substring(0,o+1))}if(this.state.top&&(r=this.tokenizer.paragraph(i))){let o=t.at(-1);n&&o?.type==="paragraph"?(o.raw+=(o.raw.endsWith(`
52
+ `)?"":`
53
+ `)+r.raw,o.text+=`
54
+ `+r.text,this.inlineQueue.pop(),this.inlineQueue.at(-1).src=o.text):t.push(r),n=i.length!==e.length,e=e.substring(r.raw.length);continue}if(r=this.tokenizer.text(e)){e=e.substring(r.raw.length);let o=t.at(-1);o?.type==="text"?(o.raw+=(o.raw.endsWith(`
55
+ `)?"":`
56
+ `)+r.raw,o.text+=`
57
+ `+r.text,this.inlineQueue.pop(),this.inlineQueue.at(-1).src=o.text):t.push(r);continue}if(e){this.infiniteLoopError(e.charCodeAt(0));break}}return this.state.top=!0,t}inline(e,t=[]){return this.inlineQueue.push({src:e,tokens:t}),t}inlineTokens(e,t=[]){this.tokenizer.lexer=this;let n=e,s=null;if(this.tokens.links){let a=Object.keys(this.tokens.links);if(a.length>0)for(;(s=this.tokenizer.rules.inline.reflinkSearch.exec(n))!==null;)a.includes(s[0].slice(s[0].lastIndexOf("[")+1,-1))&&(n=n.slice(0,s.index)+"["+"a".repeat(s[0].length-2)+"]"+n.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex))}for(;(s=this.tokenizer.rules.inline.anyPunctuation.exec(n))!==null;)n=n.slice(0,s.index)+"++"+n.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex);let r;for(;(s=this.tokenizer.rules.inline.blockSkip.exec(n))!==null;)r=s[2]?s[2].length:0,n=n.slice(0,s.index+r)+"["+"a".repeat(s[0].length-r-2)+"]"+n.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);n=this.options.hooks?.emStrongMask?.call({lexer:this},n)??n;let i=!1,o="",u=1/0;for(;e;){if(e.length<u)u=e.length;else{this.infiniteLoopError(e.charCodeAt(0));break}i||(o=""),i=!1;let a;if(this.options.extensions?.inline?.some(p=>(a=p.call({lexer:this},e,t))?(e=e.substring(a.raw.length),t.push(a),!0):!1))continue;if(a=this.tokenizer.escape(e)){e=e.substring(a.raw.length),t.push(a);continue}if(a=this.tokenizer.tag(e)){e=e.substring(a.raw.length),t.push(a);continue}if(a=this.tokenizer.link(e)){e=e.substring(a.raw.length),t.push(a);continue}if(a=this.tokenizer.reflink(e,this.tokens.links)){e=e.substring(a.raw.length);let p=t.at(-1);a.type==="text"&&p?.type==="text"?(p.raw+=a.raw,p.text+=a.text):t.push(a);continue}if(a=this.tokenizer.emStrong(e,n,o)){e=e.substring(a.raw.length),t.push(a);continue}if(a=this.tokenizer.codespan(e)){e=e.substring(a.raw.length),t.push(a);continue}if(a=this.tokenizer.br(e)){e=e.substring(a.raw.length),t.push(a);continue}if(a=this.tokenizer.del(e,n,o)){e=e.substring(a.raw.length),t.push(a);continue}if(a=this.tokenizer.autolink(e)){e=e.substring(a.raw.length),t.push(a);continue}if(!this.state.inLink&&(a=this.tokenizer.url(e))){e=e.substring(a.raw.length),t.push(a);continue}let c=e;if(this.options.extensions?.startInline){let p=1/0,d=e.slice(1),h;this.options.extensions.startInline.forEach(R=>{h=R.call({lexer:this},d),typeof h=="number"&&h>=0&&(p=Math.min(p,h))}),p<1/0&&p>=0&&(c=e.substring(0,p+1))}if(a=this.tokenizer.inlineText(c)){e=e.substring(a.raw.length),a.raw.slice(-1)!=="_"&&(o=a.raw.slice(-1)),i=!0;let p=t.at(-1);p?.type==="text"?(p.raw+=a.raw,p.text+=a.text):t.push(a);continue}if(e){this.infiniteLoopError(e.charCodeAt(0));break}}return t}infiniteLoopError(e){let t="Infinite loop on byte: "+e;if(this.options.silent)console.error(t);else throw new Error(t)}};var y=class{options;parser;constructor(e){this.options=e||T}space(e){return""}code({text:e,lang:t,escaped:n}){let s=(t||"").match(m.notSpaceStart)?.[0],r=e.replace(m.endingNewline,"")+`
58
+ `;return s?'<pre><code class="language-'+O(s)+'">'+(n?r:O(r,!0))+`</code></pre>
59
+ `:"<pre><code>"+(n?r:O(r,!0))+`</code></pre>
60
+ `}blockquote({tokens:e}){return`<blockquote>
61
+ ${this.parser.parse(e)}</blockquote>
62
+ `}html({text:e}){return e}def(e){return""}heading({tokens:e,depth:t}){return`<h${t}>${this.parser.parseInline(e)}</h${t}>
63
+ `}hr(e){return`<hr>
64
+ `}list(e){let t=e.ordered,n=e.start,s="";for(let o=0;o<e.items.length;o++){let u=e.items[o];s+=this.listitem(u)}let r=t?"ol":"ul",i=t&&n!==1?' start="'+n+'"':"";return"<"+r+i+`>
65
+ `+s+"</"+r+`>
66
+ `}listitem(e){return`<li>${this.parser.parse(e.tokens)}</li>
67
+ `}checkbox({checked:e}){return"<input "+(e?'checked="" ':"")+'disabled="" type="checkbox"> '}paragraph({tokens:e}){return`<p>${this.parser.parseInline(e)}</p>
68
+ `}table(e){let t="",n="";for(let r=0;r<e.header.length;r++)n+=this.tablecell(e.header[r]);t+=this.tablerow({text:n});let s="";for(let r=0;r<e.rows.length;r++){let i=e.rows[r];n="";for(let o=0;o<i.length;o++)n+=this.tablecell(i[o]);s+=this.tablerow({text:n})}return s&&(s=`<tbody>${s}</tbody>`),`<table>
69
+ <thead>
70
+ `+t+`</thead>
71
+ `+s+`</table>
72
+ `}tablerow({text:e}){return`<tr>
73
+ ${e}</tr>
74
+ `}tablecell(e){let t=this.parser.parseInline(e.tokens),n=e.header?"th":"td";return(e.align?`<${n} align="${e.align}">`:`<${n}>`)+t+`</${n}>
75
+ `}strong({tokens:e}){return`<strong>${this.parser.parseInline(e)}</strong>`}em({tokens:e}){return`<em>${this.parser.parseInline(e)}</em>`}codespan({text:e}){return`<code>${O(e,!0)}</code>`}br(e){return"<br>"}del({tokens:e}){return`<del>${this.parser.parseInline(e)}</del>`}link({href:e,title:t,tokens:n}){let s=this.parser.parseInline(n),r=J(e);if(r===null)return s;e=r;let i='<a href="'+e+'"';return t&&(i+=' title="'+O(t)+'"'),i+=">"+s+"</a>",i}image({href:e,title:t,text:n,tokens:s}){s&&(n=this.parser.parseInline(s,this.parser.textRenderer));let r=J(e);if(r===null)return O(n);e=r;let i=`<img src="${e}" alt="${O(n)}"`;return t&&(i+=` title="${O(t)}"`),i+=">",i}text(e){return"tokens"in e&&e.tokens?this.parser.parseInline(e.tokens):"escaped"in e&&e.escaped?e.text:O(e.text)}};var L=class{strong({text:e}){return e}em({text:e}){return e}codespan({text:e}){return e}del({text:e}){return e}html({text:e}){return e}text({text:e}){return e}link({text:e}){return""+e}image({text:e}){return""+e}br(){return""}checkbox({raw:e}){return e}};var b=class l{options;renderer;textRenderer;constructor(e){this.options=e||T,this.options.renderer=this.options.renderer||new y,this.renderer=this.options.renderer,this.renderer.options=this.options,this.renderer.parser=this,this.textRenderer=new L}static parse(e,t){return new l(t).parse(e)}static parseInline(e,t){return new l(t).parseInline(e)}parse(e){this.renderer.parser=this;let t="";for(let n=0;n<e.length;n++){let s=e[n];if(this.options.extensions?.renderers?.[s.type]){let i=s,o=this.options.extensions.renderers[i.type].call({parser:this},i);if(o!==!1||!["space","hr","heading","code","table","blockquote","list","html","def","paragraph","text"].includes(i.type)){t+=o||"";continue}}let r=s;switch(r.type){case"space":{t+=this.renderer.space(r);break}case"hr":{t+=this.renderer.hr(r);break}case"heading":{t+=this.renderer.heading(r);break}case"code":{t+=this.renderer.code(r);break}case"table":{t+=this.renderer.table(r);break}case"blockquote":{t+=this.renderer.blockquote(r);break}case"list":{t+=this.renderer.list(r);break}case"checkbox":{t+=this.renderer.checkbox(r);break}case"html":{t+=this.renderer.html(r);break}case"def":{t+=this.renderer.def(r);break}case"paragraph":{t+=this.renderer.paragraph(r);break}case"text":{t+=this.renderer.text(r);break}default:{let i='Token with "'+r.type+'" type was not found.';if(this.options.silent)return console.error(i),"";throw new Error(i)}}}return t}parseInline(e,t=this.renderer){this.renderer.parser=this;let n="";for(let s=0;s<e.length;s++){let r=e[s];if(this.options.extensions?.renderers?.[r.type]){let o=this.options.extensions.renderers[r.type].call({parser:this},r);if(o!==!1||!["escape","html","link","image","strong","em","codespan","br","del","text"].includes(r.type)){n+=o||"";continue}}let i=r;switch(i.type){case"escape":{n+=t.text(i);break}case"html":{n+=t.html(i);break}case"link":{n+=t.link(i);break}case"image":{n+=t.image(i);break}case"checkbox":{n+=t.checkbox(i);break}case"strong":{n+=t.strong(i);break}case"em":{n+=t.em(i);break}case"codespan":{n+=t.codespan(i);break}case"br":{n+=t.br(i);break}case"del":{n+=t.del(i);break}case"text":{n+=t.text(i);break}default:{let o='Token with "'+i.type+'" type was not found.';if(this.options.silent)return console.error(o),"";throw new Error(o)}}}return n}};var P=class{options;block;constructor(e){this.options=e||T}static passThroughHooks=new Set(["preprocess","postprocess","processAllTokens","emStrongMask"]);static passThroughHooksRespectAsync=new Set(["preprocess","postprocess","processAllTokens"]);preprocess(e){return e}postprocess(e){return e}processAllTokens(e){return e}emStrongMask(e){return e}provideLexer(e=this.block){return e?x.lex:x.lexInline}provideParser(e=this.block){return e?b.parse:b.parseInline}};var D=class{defaults=z();options=this.setOptions;parse=this.parseMarkdown(!0);parseInline=this.parseMarkdown(!1);Parser=b;Renderer=y;TextRenderer=L;Lexer=x;Tokenizer=w;Hooks=P;constructor(...e){this.use(...e)}walkTokens(e,t){let n=[];for(let s of e)switch(n=n.concat(t.call(this,s)),s.type){case"table":{let r=s;for(let i of r.header)n=n.concat(this.walkTokens(i.tokens,t));for(let i of r.rows)for(let o of i)n=n.concat(this.walkTokens(o.tokens,t));break}case"list":{let r=s;n=n.concat(this.walkTokens(r.items,t));break}default:{let r=s;this.defaults.extensions?.childTokens?.[r.type]?this.defaults.extensions.childTokens[r.type].forEach(i=>{let o=r[i].flat(1/0);n=n.concat(this.walkTokens(o,t))}):r.tokens&&(n=n.concat(this.walkTokens(r.tokens,t)))}}return n}use(...e){let t=this.defaults.extensions||{renderers:{},childTokens:{}};return e.forEach(n=>{let s={...n};if(s.async=this.defaults.async||s.async||!1,n.extensions&&(n.extensions.forEach(r=>{if(!r.name)throw new Error("extension name required");if("renderer"in r){let i=t.renderers[r.name];i?t.renderers[r.name]=function(...o){let u=r.renderer.apply(this,o);return u===!1&&(u=i.apply(this,o)),u}:t.renderers[r.name]=r.renderer}if("tokenizer"in r){if(!r.level||r.level!=="block"&&r.level!=="inline")throw new Error("extension level must be 'block' or 'inline'");let i=t[r.level];i?i.unshift(r.tokenizer):t[r.level]=[r.tokenizer],r.start&&(r.level==="block"?t.startBlock?t.startBlock.push(r.start):t.startBlock=[r.start]:r.level==="inline"&&(t.startInline?t.startInline.push(r.start):t.startInline=[r.start]))}"childTokens"in r&&r.childTokens&&(t.childTokens[r.name]=r.childTokens)}),s.extensions=t),n.renderer){let r=this.defaults.renderer||new y(this.defaults);for(let i in n.renderer){if(!(i in r))throw new Error(`renderer '${i}' does not exist`);if(["options","parser"].includes(i))continue;let o=i,u=n.renderer[o],a=r[o];r[o]=(...c)=>{let p=u.apply(r,c);return p===!1&&(p=a.apply(r,c)),p||""}}s.renderer=r}if(n.tokenizer){let r=this.defaults.tokenizer||new w(this.defaults);for(let i in n.tokenizer){if(!(i in r))throw new Error(`tokenizer '${i}' does not exist`);if(["options","rules","lexer"].includes(i))continue;let o=i,u=n.tokenizer[o],a=r[o];r[o]=(...c)=>{let p=u.apply(r,c);return p===!1&&(p=a.apply(r,c)),p}}s.tokenizer=r}if(n.hooks){let r=this.defaults.hooks||new P;for(let i in n.hooks){if(!(i in r))throw new Error(`hook '${i}' does not exist`);if(["options","block"].includes(i))continue;let o=i,u=n.hooks[o],a=r[o];P.passThroughHooks.has(i)?r[o]=c=>{if(this.defaults.async&&P.passThroughHooksRespectAsync.has(i))return(async()=>{let d=await u.call(r,c);return a.call(r,d)})();let p=u.call(r,c);return a.call(r,p)}:r[o]=(...c)=>{if(this.defaults.async)return(async()=>{let d=await u.apply(r,c);return d===!1&&(d=await a.apply(r,c)),d})();let p=u.apply(r,c);return p===!1&&(p=a.apply(r,c)),p}}s.hooks=r}if(n.walkTokens){let r=this.defaults.walkTokens,i=n.walkTokens;s.walkTokens=function(o){let u=[];return u.push(i.call(this,o)),r&&(u=u.concat(r.call(this,o))),u}}this.defaults={...this.defaults,...s}}),this}setOptions(e){return this.defaults={...this.defaults,...e},this}lexer(e,t){return x.lex(e,t??this.defaults)}parser(e,t){return b.parse(e,t??this.defaults)}parseMarkdown(e){return(n,s)=>{let r={...s},i={...this.defaults,...r},o=this.onError(!!i.silent,!!i.async);if(this.defaults.async===!0&&r.async===!1)return o(new Error("marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise."));if(typeof n>"u"||n===null)return o(new Error("marked(): input parameter is undefined or null"));if(typeof n!="string")return o(new Error("marked(): input parameter is of type "+Object.prototype.toString.call(n)+", string expected"));if(i.hooks&&(i.hooks.options=i,i.hooks.block=e),i.async)return(async()=>{let u=i.hooks?await i.hooks.preprocess(n):n,c=await(i.hooks?await i.hooks.provideLexer(e):e?x.lex:x.lexInline)(u,i),p=i.hooks?await i.hooks.processAllTokens(c):c;i.walkTokens&&await Promise.all(this.walkTokens(p,i.walkTokens));let h=await(i.hooks?await i.hooks.provideParser(e):e?b.parse:b.parseInline)(p,i);return i.hooks?await i.hooks.postprocess(h):h})().catch(o);try{i.hooks&&(n=i.hooks.preprocess(n));let a=(i.hooks?i.hooks.provideLexer(e):e?x.lex:x.lexInline)(n,i);i.hooks&&(a=i.hooks.processAllTokens(a)),i.walkTokens&&this.walkTokens(a,i.walkTokens);let p=(i.hooks?i.hooks.provideParser(e):e?b.parse:b.parseInline)(a,i);return i.hooks&&(p=i.hooks.postprocess(p)),p}catch(u){return o(u)}}}onError(e,t){return n=>{if(n.message+=`
76
+ Please report this to https://github.com/markedjs/marked.`,e){let s="<p>An error occurred:</p><pre>"+O(n.message+"",!0)+"</pre>";return t?Promise.resolve(s):s}if(t)return Promise.reject(n);throw n}}};var M=new D;function g(l,e){return M.parse(l,e)}g.options=g.setOptions=function(l){return M.setOptions(l),g.defaults=M.defaults,G(g.defaults),g};g.getDefaults=z;g.defaults=T;g.use=function(...l){return M.use(...l),g.defaults=M.defaults,G(g.defaults),g};g.walkTokens=function(l,e){return M.walkTokens(l,e)};g.parseInline=M.parseInline;g.Parser=b;g.parser=b.parse;g.Renderer=y;g.TextRenderer=L;g.Lexer=x;g.lexer=x.lex;g.Tokenizer=w;g.Hooks=P;g.parse=g;var jt=g.options,Ft=g.setOptions,Ut=g.use,Kt=g.walkTokens,Wt=g.parseInline,Xt=g,Jt=b.parse,Vt=x.lex;export{P as Hooks,x as Lexer,D as Marked,b as Parser,y as Renderer,L as TextRenderer,w as Tokenizer,T as defaults,z as getDefaults,Vt as lexer,g as marked,jt as options,Xt as parse,Wt as parseInline,Jt as parser,Ft as setOptions,Ut as use,Kt as walkTokens};
77
+ //# sourceMappingURL=marked.esm.js.map
@@ -0,0 +1,29 @@
1
+ import { marked } from './marked.esm.js';
2
+
3
+ /*
4
+ renderMarkdown(md, options?): String
5
+
6
+ Thin wrapper around the vendored marked parser. marked is a full
7
+ CommonMark + GFM parser (~30KB minified, MIT-licensed) which gives us
8
+ tables, task lists, autolinks, inline HTML, fenced code with language
9
+ tags, etc. out of the box — no preprocessor hacks required.
10
+
11
+ marked emits raw user-typed inline HTML straight through; we rely on
12
+ sanitizeHtml downstream to enforce the allowed-tags policy. That means
13
+ every consumer should run the output through `sanitizeHtml` before
14
+ putting it into the DOM (MarkdownEditor's preview and Chat's bubble both
15
+ do this).
16
+
17
+ Options forwarded to marked:
18
+ breaks (default false) — true converts single newlines to <br>
19
+ (Slack/iMessage convention; useful for chat).
20
+ gfm (default true) — GitHub-flavoured features (tables, etc.).
21
+ */
22
+
23
+ export default function renderMarkdown(md, options = {}) {
24
+ return marked.parse(md || '', {
25
+ gfm: true,
26
+ breaks: false,
27
+ ...options
28
+ });
29
+ }
@@ -0,0 +1,137 @@
1
+ /*
2
+ sanitizeHtml Utility
3
+ - Whitelist-based HTML sanitizer for user-submitted rich text
4
+ - Strips <script>, <style>, <iframe>, event-handler attributes, and javascript: URLs
5
+ - Returns a string of safe HTML
6
+
7
+ IMPORTANT: This is a frontend defense, NOT a substitute for server-side
8
+ sanitization. ANY content you persist or rebroadcast must be sanitized again
9
+ on the server. A determined attacker can submit raw HTTP without ever loading
10
+ your client code.
11
+ */
12
+
13
+ const DEFAULT_TAGS = new Set([
14
+ 'A', 'B', 'STRONG', 'I', 'EM', 'U', 'S', 'STRIKE', 'DEL',
15
+ 'BR', 'HR', 'P', 'DIV', 'SPAN', 'IMG', 'INPUT',
16
+ 'UL', 'OL', 'LI', 'BLOCKQUOTE', 'CODE', 'PRE',
17
+ 'H1', 'H2', 'H3', 'H4', 'H5', 'H6',
18
+ 'TABLE', 'THEAD', 'TBODY', 'TFOOT', 'TR', 'TD', 'TH'
19
+ ]);
20
+
21
+ // Tags whose contents are also unsafe (e.g. <script>'s textContent is JS source,
22
+ // <style>'s textContent is CSS that could contain expressions). Remove the
23
+ // entire element including children.
24
+ const STRIP_COMPLETELY = new Set([
25
+ 'SCRIPT', 'STYLE', 'IFRAME', 'OBJECT', 'EMBED', 'LINK', 'META', 'BASE',
26
+ 'FRAME', 'FRAMESET', 'NOSCRIPT', 'SVG', 'MATH'
27
+ ]);
28
+
29
+ const DEFAULT_ATTRS_GLOBAL = new Set(['class']);
30
+ const DEFAULT_ATTRS_PER_TAG = {
31
+ A: new Set(['href', 'title', 'target', 'rel']),
32
+ IMG: new Set(['src', 'alt', 'title', 'width', 'height']),
33
+ // marked emits `<input type="checkbox" disabled>` for GFM task list items
34
+ // (`- [ ]` / `- [x]`). Only those three attributes are allowed; `disabled`
35
+ // means the user can't actually toggle them in rendered output.
36
+ INPUT: new Set(['type', 'checked', 'disabled']),
37
+ // marked uses the (deprecated but still browser-supported) `align` attr
38
+ // on table cells for column alignment from `:---` / `---:` separators.
39
+ TD: new Set(['colspan', 'rowspan', 'align']),
40
+ TH: new Set(['colspan', 'rowspan', 'scope', 'align'])
41
+ };
42
+
43
+ const SAFE_URL = /^(https?:|mailto:|tel:|\/|#|\.\.?\/)/i;
44
+
45
+ const sanitizeUrl = (value) => {
46
+ if(!value) return '';
47
+ const trimmed = String(value).trim();
48
+ // Reject any URL that doesn't match the safelist (this rejects javascript:,
49
+ // data:, vbscript:, etc.). Also reject anything that decodes weirdly.
50
+ return SAFE_URL.test(trimmed) ? trimmed : '';
51
+ };
52
+
53
+ const sanitizeNode = (node, allowedTags, allowedAttrsGlobal, allowedAttrsPerTag, stripCompletely) => {
54
+ // Iterate over a snapshot since we may remove children mid-loop
55
+ const children = [...node.childNodes];
56
+ for(const child of children){
57
+ if(child.nodeType === Node.ELEMENT_NODE){
58
+ const tagName = child.tagName;
59
+ if(stripCompletely.has(tagName)){
60
+ node.removeChild(child);
61
+ continue;
62
+ }
63
+ if(!allowedTags.has(tagName)){
64
+ // Replace the disallowed element with its sanitized children — this
65
+ // preserves user text but drops the unsafe wrapper.
66
+ sanitizeNode(child, allowedTags, allowedAttrsGlobal, allowedAttrsPerTag, stripCompletely);
67
+ while(child.firstChild) node.insertBefore(child.firstChild, child);
68
+ node.removeChild(child);
69
+ continue;
70
+ }
71
+ // Strip disallowed attributes
72
+ const tagSpecific = allowedAttrsPerTag[tagName] || new Set();
73
+ for(const attr of [...child.attributes]){
74
+ const name = attr.name.toLowerCase();
75
+ const isAllowed = (
76
+ allowedAttrsGlobal.has(name) ||
77
+ tagSpecific.has(name) ||
78
+ name.startsWith('data-')
79
+ );
80
+ if(!isAllowed){
81
+ child.removeAttribute(attr.name);
82
+ continue;
83
+ }
84
+ // URL attrs need extra scrutiny
85
+ if(name === 'href' || name === 'src'){
86
+ const safe = sanitizeUrl(attr.value);
87
+ if(!safe){
88
+ child.removeAttribute(attr.name);
89
+ } else {
90
+ child.setAttribute(attr.name, safe);
91
+ }
92
+ }
93
+ }
94
+ // For target=_blank links, force noopener/noreferrer
95
+ if(tagName === 'A' && child.getAttribute('target') === '_blank'){
96
+ child.setAttribute('rel', 'noopener noreferrer');
97
+ }
98
+ // Recurse into the (now-cleaned) element
99
+ sanitizeNode(child, allowedTags, allowedAttrsGlobal, allowedAttrsPerTag, stripCompletely);
100
+ } else if(child.nodeType === Node.COMMENT_NODE){
101
+ // Drop HTML comments (could carry conditional comments etc.)
102
+ node.removeChild(child);
103
+ }
104
+ // Text nodes pass through unchanged
105
+ }
106
+ };
107
+
108
+ /*
109
+ sanitizeHtml(html, options?)
110
+ - html: string of untrusted HTML
111
+ - options.allowedTags: Set<string> of UPPERCASE tag names (overrides default)
112
+ - options.allowedAttrs: Set<string> of attr names allowed on every tag
113
+ - options.allowedAttrsPerTag: { TAGNAME: Set<string> }
114
+ - options.stripCompletely: Set<string> of UPPERCASE tag names whose entire
115
+ subtree (element + content) is always removed regardless of
116
+ allowedTags. Defaults to STRIP_COMPLETELY (script/iframe/style/etc.).
117
+ Pass a narrowed set to opt back into one of these (e.g. SCRIPT) — but
118
+ only when you trust the input.
119
+ */
120
+ const sanitizeHtml = (html, options = {}) => {
121
+ if(html === null || html === undefined) return '';
122
+ const input = String(html);
123
+ if(!input) return '';
124
+ const allowedTags = options.allowedTags || DEFAULT_TAGS;
125
+ const allowedAttrsGlobal = options.allowedAttrs || DEFAULT_ATTRS_GLOBAL;
126
+ const allowedAttrsPerTag = options.allowedAttrsPerTag || DEFAULT_ATTRS_PER_TAG;
127
+ const stripCompletely = options.stripCompletely || STRIP_COMPLETELY;
128
+ // <template>.innerHTML parses without executing scripts, fetching images,
129
+ // etc., so this is safe for untrusted strings.
130
+ const tpl = document.createElement('template');
131
+ tpl.innerHTML = input;
132
+ sanitizeNode(tpl.content, allowedTags, allowedAttrsGlobal, allowedAttrsPerTag, stripCompletely);
133
+ return tpl.innerHTML;
134
+ };
135
+
136
+ export default sanitizeHtml;
137
+ export { sanitizeHtml, DEFAULT_TAGS, DEFAULT_ATTRS_GLOBAL, DEFAULT_ATTRS_PER_TAG, STRIP_COMPLETELY };